Chromium Code Reviews| Index: webrtc/api/java/jni/androidmediaencoder_jni.cc |
| diff --git a/webrtc/api/java/jni/androidmediaencoder_jni.cc b/webrtc/api/java/jni/androidmediaencoder_jni.cc |
| index 0e36aa1b7463dba4b60b3b7a488d452d85c3982a..31c4c3399237608e59ae1390a5abf940957b06e0 100644 |
| --- a/webrtc/api/java/jni/androidmediaencoder_jni.cc |
| +++ b/webrtc/api/java/jni/androidmediaencoder_jni.cc |
| @@ -223,10 +223,14 @@ class MediaCodecVideoEncoder : public webrtc::VideoEncoder, |
| int current_frames_; // Number of frames in the current statistics interval. |
| int current_bytes_; // Encoded bytes in the current statistics interval. |
| int current_acc_qp_; // Accumulated QP in the current statistics interval. |
| + // Number of DeliverPendingOuputs calls in the current statistics interval. |
| + int deliver_pending_outputs_calls_; |
| int current_encoding_time_ms_; // Overall encoding time in the current second |
| int64_t last_input_timestamp_ms_; // Timestamp of last received yuv frame. |
| int64_t last_output_timestamp_ms_; // Timestamp of last encoded frame. |
| - bool output_delivery_loop_running_; // Is the onMessage loop running |
| + // Is the onMessage loop running at regular polling rate. If false, it is |
| + // running at lower poll rate of kMediaCodecStatisticsIntervalMs. |
| + bool output_delivery_loop_running_; |
| struct InputFrameInfo { |
| InputFrameInfo(int64_t encode_start_time, |
| @@ -307,7 +311,6 @@ MediaCodecVideoEncoder::MediaCodecVideoEncoder( |
| inited_(false), |
| use_surface_(false), |
| picture_id_(0), |
| - output_delivery_loop_running_(false), |
| egl_context_(egl_context) { |
| ScopedLocalRefFrame local_ref_frame(jni); |
| // It would be nice to avoid spinning up a new thread per MediaCodec, and |
| @@ -479,9 +482,15 @@ void MediaCodecVideoEncoder::OnMessage(rtc::Message* msg) { |
| // If there aren't more frames to deliver, we can stop the loop |
| if (!input_frame_infos_.empty()) { |
| codec_thread_->PostDelayed(kMediaCodecPollMs, this); |
| + output_delivery_loop_running_ = true; |
| } else { |
| + codec_thread_->PostDelayed(kMediaCodecStatisticsIntervalMs, this); |
| output_delivery_loop_running_ = false; |
| } |
| + |
| + // Call log statistics here so it's called even if no frames are being |
| + // delivered. |
| + LogStatistics(false); |
| } |
| bool MediaCodecVideoEncoder::ResetCodecOnCodecThread() { |
| @@ -529,9 +538,11 @@ int32_t MediaCodecVideoEncoder::InitEncodeOnCodecThread( |
| current_frames_ = 0; |
| current_bytes_ = 0; |
| current_acc_qp_ = 0; |
| + deliver_pending_outputs_calls_ = 0; |
| current_encoding_time_ms_ = 0; |
| last_input_timestamp_ms_ = -1; |
| last_output_timestamp_ms_ = -1; |
| + output_delivery_loop_running_ = false; |
| output_timestamp_ = 0; |
| output_render_time_ms_ = 0; |
| input_frame_infos_.clear(); |
| @@ -595,6 +606,7 @@ int32_t MediaCodecVideoEncoder::InitEncodeOnCodecThread( |
| } |
| inited_ = true; |
| + codec_thread_->PostDelayed(kMediaCodecStatisticsIntervalMs, this); |
| return WEBRTC_VIDEO_CODEC_OK; |
| } |
| @@ -741,8 +753,9 @@ int32_t MediaCodecVideoEncoder::EncodeOnCodecThread( |
| current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_; |
| if (!output_delivery_loop_running_) { |
| - output_delivery_loop_running_ = true; |
| + codec_thread_->Clear(this); |
| codec_thread_->PostDelayed(kMediaCodecPollMs, this); |
| + output_delivery_loop_running_ = true; |
| } |
| if (!DeliverPendingOutputs(jni)) { |
| @@ -926,6 +939,8 @@ jlong MediaCodecVideoEncoder::GetOutputBufferInfoPresentationTimestampUs( |
| bool MediaCodecVideoEncoder::DeliverPendingOutputs(JNIEnv* jni) { |
| RTC_DCHECK(codec_thread_checker_.CalledOnValidThread()); |
| + deliver_pending_outputs_calls_++; |
| + |
| while (true) { |
| jobject j_output_buffer_info = jni->CallObjectMethod( |
| *j_media_codec_video_encoder_, j_dequeue_output_buffer_method_); |
| @@ -1121,8 +1136,11 @@ bool MediaCodecVideoEncoder::DeliverPendingOutputs(JNIEnv* jni) { |
| void MediaCodecVideoEncoder::LogStatistics(bool force_log) { |
| int statistic_time_ms = rtc::TimeMillis() - stat_start_time_ms_; |
| - if ((statistic_time_ms >= kMediaCodecStatisticsIntervalMs || force_log) && |
| - current_frames_ > 0 && statistic_time_ms > 0) { |
| + if ((statistic_time_ms >= kMediaCodecStatisticsIntervalMs || force_log) |
| + && statistic_time_ms > 0) { |
| + // Prevent division by zero |
| + int current_frames_divider = current_frames_ != 0 ? current_frames_ : 1; |
| + |
| int current_bitrate = current_bytes_ * 8 / statistic_time_ms; |
| int current_fps = |
| (current_frames_ * 1000 + statistic_time_ms / 2) / statistic_time_ms; |
| @@ -1130,13 +1148,15 @@ void MediaCodecVideoEncoder::LogStatistics(bool force_log) { |
| ". Bitrate: " << current_bitrate << |
| ", target: " << last_set_bitrate_kbps_ << " kbps" << |
| ", fps: " << current_fps << |
| - ", encTime: " << (current_encoding_time_ms_ / current_frames_) << |
| - ". QP: " << (current_acc_qp_ / current_frames_) << |
| + ", encTime: " << (current_encoding_time_ms_ / current_frames_divider) << |
| + ". QP: " << (current_acc_qp_ / current_frames_divider) << |
| + ", DeliverPendingOutputs: " << deliver_pending_outputs_calls_ << |
|
perkj_webrtc
2016/06/10 11:37:48
I don't think we care about how many times Deliver
|
| " for last " << statistic_time_ms << " ms."; |
| stat_start_time_ms_ = rtc::TimeMillis(); |
| current_frames_ = 0; |
| current_bytes_ = 0; |
| current_acc_qp_ = 0; |
| + deliver_pending_outputs_calls_ = 0; |
|
perkj_webrtc
2016/06/10 11:37:48
And remove DeliverPendingOutputs.
|
| current_encoding_time_ms_ = 0; |
| } |
| } |