max_number_of_repeated_buffers_in_a_row_(
ComputeMaxNumOfRepeatedBuffes(max_unacked_frames)),
key_frame_requested_(true),
- timestamp_(0),
+ first_frame_received_(false),
last_encoded_frame_id_(kStartFrameId),
number_of_repeated_buffers_(0) {
// TODO(pwestin): we need to figure out how to synchronize the acking with the
acked_frame_buffers_[i] = true;
used_buffers_frame_id_[i] = kStartFrameId;
}
- InitEncode(cast_config_.number_of_cores);
+ InitEncode(cast_config_.number_of_encode_threads);
}
-void Vp8Encoder::InitEncode(int number_of_cores) {
+void Vp8Encoder::InitEncode(int number_of_encode_threads) {
DCHECK(thread_checker_.CalledOnValidThread());
// Populate encoder configuration with default values.
if (vpx_codec_enc_config_default(vpx_codec_vp8_cx(), config_.get(), 0)) {
// codec requirements.
config_->g_error_resilient = 1;
}
-
- if (cast_config_.width * cast_config_.height > 640 * 480 &&
- number_of_cores >= 2) {
- config_->g_threads = 2; // 2 threads for qHD/HD.
- } else {
- config_->g_threads = 1; // 1 thread for VGA or less.
- }
+ config_->g_threads = number_of_encode_threads;
// Rate control settings.
- // TODO(pwestin): revisit these constants. Currently identical to webrtc.
- config_->rc_dropframe_thresh = 30;
+ // Never allow the encoder to drop frame internally.
+ config_->rc_dropframe_thresh = 0;
config_->rc_end_usage = VPX_CBR;
config_->g_pass = VPX_RC_ONE_PASS;
config_->rc_resize_allowed = 0;
// set the maximum target size of any key-frame.
uint32 rc_max_intra_target = MaxIntraTarget(config_->rc_buf_optimal_sz);
vpx_codec_flags_t flags = 0;
- // TODO(mikhal): Tune settings.
if (vpx_codec_enc_init(
encoder_.get(), vpx_codec_vp8_cx(), config_.get(), flags)) {
DCHECK(false) << "vpx_codec_enc_init() failed.";
// Note: The duration does not reflect the real time between frames. This is
// done to keep the encoder happy.
+ //
+ // TODO(miu): This is a semi-hack. We should consider using
+ // |video_frame->timestamp()| instead.
uint32 duration = kVideoFrequency / cast_config_.max_frame_rate;
+
+ // Note: Timestamp here is used for bitrate calculation. The absolute value
+ // is not important.
+ if (!first_frame_received_) {
+ first_frame_received_ = true;
+ first_frame_timestamp_ = video_frame->timestamp();
+ }
+
+ vpx_codec_pts_t timestamp =
+ (video_frame->timestamp() - first_frame_timestamp_).InMicroseconds() *
+ kVideoFrequency / base::Time::kMicrosecondsPerSecond;
+
if (vpx_codec_encode(encoder_.get(),
raw_image_,
- timestamp_,
+ timestamp,
duration,
flags,
- VPX_DL_REALTIME)) {
+ VPX_DL_REALTIME) != VPX_CODEC_OK) {
+ LOG(ERROR) << "Failed to encode for once.";
return false;
}
- timestamp_ += duration;
// Get encoded frame.
const vpx_codec_cx_pkt_t* pkt = NULL;
}
Vp8Encoder::Vp8Buffers Vp8Encoder::GetNextBufferToUpdate() {
+ if (!use_multiple_video_buffers_)
+ return kNoBuffer;
+
// Update at most one buffer, except for key-frames.
- Vp8Buffers buffer_to_update;
+ Vp8Buffers buffer_to_update = kNoBuffer;
if (number_of_repeated_buffers_ < max_number_of_repeated_buffers_in_a_row_) {
// TODO(pwestin): experiment with this. The issue with only this change is
// that we can end up with only 4 frames in flight when we expect 6.