Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(211)

Side by Side Diff: webrtc/api/java/jni/androidmediaencoder_jni.cc

Issue 2051403002: Always on statistics for AndroidMediaEncoder. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Rebase Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/api/java/jni/androidmediacodeccommon.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright 2015 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 int frames_dropped_media_encoder_; // Number of frames dropped by encoder. 219 int frames_dropped_media_encoder_; // Number of frames dropped by encoder.
220 // Number of dropped frames caused by full queue. 220 // Number of dropped frames caused by full queue.
221 int consecutive_full_queue_frame_drops_; 221 int consecutive_full_queue_frame_drops_;
222 int64_t stat_start_time_ms_; // Start time for statistics. 222 int64_t stat_start_time_ms_; // Start time for statistics.
223 int current_frames_; // Number of frames in the current statistics interval. 223 int current_frames_; // Number of frames in the current statistics interval.
224 int current_bytes_; // Encoded bytes in the current statistics interval. 224 int current_bytes_; // Encoded bytes in the current statistics interval.
225 int current_acc_qp_; // Accumulated QP in the current statistics interval. 225 int current_acc_qp_; // Accumulated QP in the current statistics interval.
226 int current_encoding_time_ms_; // Overall encoding time in the current second 226 int current_encoding_time_ms_; // Overall encoding time in the current second
227 int64_t last_input_timestamp_ms_; // Timestamp of last received yuv frame. 227 int64_t last_input_timestamp_ms_; // Timestamp of last received yuv frame.
228 int64_t last_output_timestamp_ms_; // Timestamp of last encoded frame. 228 int64_t last_output_timestamp_ms_; // Timestamp of last encoded frame.
229 bool output_delivery_loop_running_; // Is the onMessage loop running
230 229
231 struct InputFrameInfo { 230 struct InputFrameInfo {
232 InputFrameInfo(int64_t encode_start_time, 231 InputFrameInfo(int64_t encode_start_time,
233 int32_t frame_timestamp, 232 int32_t frame_timestamp,
234 int64_t frame_render_time_ms, 233 int64_t frame_render_time_ms,
235 webrtc::VideoRotation rotation) 234 webrtc::VideoRotation rotation)
236 : encode_start_time(encode_start_time), 235 : encode_start_time(encode_start_time),
237 frame_timestamp(frame_timestamp), 236 frame_timestamp(frame_timestamp),
238 frame_render_time_ms(frame_render_time_ms), 237 frame_render_time_ms(frame_render_time_ms),
239 rotation(rotation) {} 238 rotation(rotation) {}
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 j_media_codec_video_encoder_( 299 j_media_codec_video_encoder_(
301 jni, 300 jni,
302 jni->NewObject(*j_media_codec_video_encoder_class_, 301 jni->NewObject(*j_media_codec_video_encoder_class_,
303 GetMethodID(jni, 302 GetMethodID(jni,
304 *j_media_codec_video_encoder_class_, 303 *j_media_codec_video_encoder_class_,
305 "<init>", 304 "<init>",
306 "()V"))), 305 "()V"))),
307 inited_(false), 306 inited_(false),
308 use_surface_(false), 307 use_surface_(false),
309 picture_id_(0), 308 picture_id_(0),
310 output_delivery_loop_running_(false),
311 egl_context_(egl_context) { 309 egl_context_(egl_context) {
312 ScopedLocalRefFrame local_ref_frame(jni); 310 ScopedLocalRefFrame local_ref_frame(jni);
313 // It would be nice to avoid spinning up a new thread per MediaCodec, and 311 // It would be nice to avoid spinning up a new thread per MediaCodec, and
314 // instead re-use e.g. the PeerConnectionFactory's |worker_thread_|, but bug 312 // instead re-use e.g. the PeerConnectionFactory's |worker_thread_|, but bug
315 // 2732 means that deadlocks abound. This class synchronously trampolines 313 // 2732 means that deadlocks abound. This class synchronously trampolines
316 // to |codec_thread_|, so if anything else can be coming to _us_ from 314 // to |codec_thread_|, so if anything else can be coming to _us_ from
317 // |codec_thread_|, or from any thread holding the |_sendCritSect| described 315 // |codec_thread_|, or from any thread holding the |_sendCritSect| described
318 // in the bug, we have a problem. For now work around that with a dedicated 316 // in the bug, we have a problem. For now work around that with a dedicated
319 // thread. 317 // thread.
320 codec_thread_->SetName("MediaCodecVideoEncoder", NULL); 318 codec_thread_->SetName("MediaCodecVideoEncoder", NULL);
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 RTC_CHECK(!msg->pdata) << "Unexpected message!"; 463 RTC_CHECK(!msg->pdata) << "Unexpected message!";
466 if (!inited_) { 464 if (!inited_) {
467 return; 465 return;
468 } 466 }
469 467
470 // It would be nice to recover from a failure here if one happened, but it's 468 // It would be nice to recover from a failure here if one happened, but it's
471 // unclear how to signal such a failure to the app, so instead we stay silent 469 // unclear how to signal such a failure to the app, so instead we stay silent
472 // about it and let the next app-called API method reveal the borkedness. 470 // about it and let the next app-called API method reveal the borkedness.
473 DeliverPendingOutputs(jni); 471 DeliverPendingOutputs(jni);
474 472
475 // If there aren't more frames to deliver, we can stop the loop 473 // If there aren't more frames to deliver, we can start polling at lower rate.
476 if (!input_frame_infos_.empty()) { 474 if (input_frame_infos_.empty()) {
475 codec_thread_->PostDelayed(RTC_FROM_HERE, kMediaCodecPollNoFramesMs, this);
476 } else {
477 codec_thread_->PostDelayed(RTC_FROM_HERE, kMediaCodecPollMs, this); 477 codec_thread_->PostDelayed(RTC_FROM_HERE, kMediaCodecPollMs, this);
478 } else {
479 output_delivery_loop_running_ = false;
480 } 478 }
479
480 // Call log statistics here so it's called even if no frames are being
481 // delivered.
482 LogStatistics(false);
481 } 483 }
482 484
483 bool MediaCodecVideoEncoder::ResetCodecOnCodecThread() { 485 bool MediaCodecVideoEncoder::ResetCodecOnCodecThread() {
484 RTC_DCHECK(codec_thread_checker_.CalledOnValidThread()); 486 RTC_DCHECK(codec_thread_checker_.CalledOnValidThread());
485 ALOGE << "ResetOnCodecThread"; 487 ALOGE << "ResetOnCodecThread";
486 if (ReleaseOnCodecThread() != WEBRTC_VIDEO_CODEC_OK || 488 if (ReleaseOnCodecThread() != WEBRTC_VIDEO_CODEC_OK ||
487 InitEncodeOnCodecThread(width_, height_, 0, 0, false) != 489 InitEncodeOnCodecThread(width_, height_, 0, 0, false) !=
488 WEBRTC_VIDEO_CODEC_OK) { 490 WEBRTC_VIDEO_CODEC_OK) {
489 // TODO(fischman): wouldn't it be nice if there was a way to gracefully 491 // TODO(fischman): wouldn't it be nice if there was a way to gracefully
490 // degrade to a SW encoder at this point? There isn't one AFAICT :( 492 // degrade to a SW encoder at this point? There isn't one AFAICT :(
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 // Save input image timestamps for later output. 732 // Save input image timestamps for later output.
731 input_frame_infos_.emplace_back( 733 input_frame_infos_.emplace_back(
732 time_before_calling_encode, input_frame.timestamp(), 734 time_before_calling_encode, input_frame.timestamp(),
733 input_frame.render_time_ms(), input_frame.rotation()); 735 input_frame.render_time_ms(), input_frame.rotation());
734 736
735 last_input_timestamp_ms_ = 737 last_input_timestamp_ms_ =
736 current_timestamp_us_ / rtc::kNumMicrosecsPerMillisec; 738 current_timestamp_us_ / rtc::kNumMicrosecsPerMillisec;
737 739
738 current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_; 740 current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_;
739 741
740 if (!output_delivery_loop_running_) { 742 codec_thread_->Clear(this);
741 output_delivery_loop_running_ = true; 743 codec_thread_->PostDelayed(RTC_FROM_HERE, kMediaCodecPollMs, this);
742 codec_thread_->PostDelayed(RTC_FROM_HERE, kMediaCodecPollMs, this);
743 }
744 744
745 if (!DeliverPendingOutputs(jni)) { 745 if (!DeliverPendingOutputs(jni)) {
746 ALOGE << "Failed deliver pending outputs."; 746 ALOGE << "Failed deliver pending outputs.";
747 ResetCodecOnCodecThread(); 747 ResetCodecOnCodecThread();
748 return WEBRTC_VIDEO_CODEC_ERROR; 748 return WEBRTC_VIDEO_CODEC_ERROR;
749 } 749 }
750 return WEBRTC_VIDEO_CODEC_OK; 750 return WEBRTC_VIDEO_CODEC_OK;
751 } 751 }
752 752
753 bool MediaCodecVideoEncoder::MaybeReconfigureEncoderOnCodecThread( 753 bool MediaCodecVideoEncoder::MaybeReconfigureEncoderOnCodecThread(
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
852 ". Dropped: " << frames_dropped_media_encoder_; 852 ". Dropped: " << frames_dropped_media_encoder_;
853 ScopedLocalRefFrame local_ref_frame(jni); 853 ScopedLocalRefFrame local_ref_frame(jni);
854 for (size_t i = 0; i < input_buffers_.size(); ++i) 854 for (size_t i = 0; i < input_buffers_.size(); ++i)
855 jni->DeleteGlobalRef(input_buffers_[i]); 855 jni->DeleteGlobalRef(input_buffers_[i]);
856 input_buffers_.clear(); 856 input_buffers_.clear();
857 jni->CallVoidMethod(*j_media_codec_video_encoder_, j_release_method_); 857 jni->CallVoidMethod(*j_media_codec_video_encoder_, j_release_method_);
858 CHECK_EXCEPTION(jni); 858 CHECK_EXCEPTION(jni);
859 rtc::MessageQueueManager::Clear(this); 859 rtc::MessageQueueManager::Clear(this);
860 inited_ = false; 860 inited_ = false;
861 use_surface_ = false; 861 use_surface_ = false;
862 output_delivery_loop_running_ = false;
863 ALOGD << "EncoderReleaseOnCodecThread done."; 862 ALOGD << "EncoderReleaseOnCodecThread done.";
864 return WEBRTC_VIDEO_CODEC_OK; 863 return WEBRTC_VIDEO_CODEC_OK;
865 } 864 }
866 865
867 int32_t MediaCodecVideoEncoder::SetRatesOnCodecThread(uint32_t new_bit_rate, 866 int32_t MediaCodecVideoEncoder::SetRatesOnCodecThread(uint32_t new_bit_rate,
868 uint32_t frame_rate) { 867 uint32_t frame_rate) {
869 RTC_DCHECK(codec_thread_checker_.CalledOnValidThread()); 868 RTC_DCHECK(codec_thread_checker_.CalledOnValidThread());
870 frame_rate = (frame_rate < MAX_ALLOWED_VIDEO_FPS) ? 869 frame_rate = (frame_rate < MAX_ALLOWED_VIDEO_FPS) ?
871 frame_rate : MAX_ALLOWED_VIDEO_FPS; 870 frame_rate : MAX_ALLOWED_VIDEO_FPS;
872 if (last_set_bitrate_kbps_ == new_bit_rate && 871 if (last_set_bitrate_kbps_ == new_bit_rate &&
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
916 915
917 jlong MediaCodecVideoEncoder::GetOutputBufferInfoPresentationTimestampUs( 916 jlong MediaCodecVideoEncoder::GetOutputBufferInfoPresentationTimestampUs(
918 JNIEnv* jni, 917 JNIEnv* jni,
919 jobject j_output_buffer_info) { 918 jobject j_output_buffer_info) {
920 return GetLongField( 919 return GetLongField(
921 jni, j_output_buffer_info, j_info_presentation_timestamp_us_field_); 920 jni, j_output_buffer_info, j_info_presentation_timestamp_us_field_);
922 } 921 }
923 922
924 bool MediaCodecVideoEncoder::DeliverPendingOutputs(JNIEnv* jni) { 923 bool MediaCodecVideoEncoder::DeliverPendingOutputs(JNIEnv* jni) {
925 RTC_DCHECK(codec_thread_checker_.CalledOnValidThread()); 924 RTC_DCHECK(codec_thread_checker_.CalledOnValidThread());
925
926 while (true) { 926 while (true) {
927 jobject j_output_buffer_info = jni->CallObjectMethod( 927 jobject j_output_buffer_info = jni->CallObjectMethod(
928 *j_media_codec_video_encoder_, j_dequeue_output_buffer_method_); 928 *j_media_codec_video_encoder_, j_dequeue_output_buffer_method_);
929 CHECK_EXCEPTION(jni); 929 CHECK_EXCEPTION(jni);
930 if (IsNull(jni, j_output_buffer_info)) { 930 if (IsNull(jni, j_output_buffer_info)) {
931 break; 931 break;
932 } 932 }
933 933
934 int output_buffer_index = 934 int output_buffer_index =
935 GetOutputBufferInfoIndex(jni, j_output_buffer_info); 935 GetOutputBufferInfoIndex(jni, j_output_buffer_info);
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 drop_next_input_frame_ = true; 1111 drop_next_input_frame_ = true;
1112 // Theoretically could handle callback_status<0 here, but unclear what 1112 // Theoretically could handle callback_status<0 here, but unclear what
1113 // that would mean for us. 1113 // that would mean for us.
1114 } 1114 }
1115 } 1115 }
1116 return true; 1116 return true;
1117 } 1117 }
1118 1118
1119 void MediaCodecVideoEncoder::LogStatistics(bool force_log) { 1119 void MediaCodecVideoEncoder::LogStatistics(bool force_log) {
1120 int statistic_time_ms = rtc::TimeMillis() - stat_start_time_ms_; 1120 int statistic_time_ms = rtc::TimeMillis() - stat_start_time_ms_;
1121 if ((statistic_time_ms >= kMediaCodecStatisticsIntervalMs || force_log) && 1121 if ((statistic_time_ms >= kMediaCodecStatisticsIntervalMs || force_log)
1122 current_frames_ > 0 && statistic_time_ms > 0) { 1122 && statistic_time_ms > 0) {
1123 // Prevent division by zero.
1124 int current_frames_divider = current_frames_ != 0 ? current_frames_ : 1;
1125
1123 int current_bitrate = current_bytes_ * 8 / statistic_time_ms; 1126 int current_bitrate = current_bytes_ * 8 / statistic_time_ms;
1124 int current_fps = 1127 int current_fps =
1125 (current_frames_ * 1000 + statistic_time_ms / 2) / statistic_time_ms; 1128 (current_frames_ * 1000 + statistic_time_ms / 2) / statistic_time_ms;
1126 ALOGD << "Encoded frames: " << frames_encoded_ << 1129 ALOGD << "Encoded frames: " << frames_encoded_ <<
1127 ". Bitrate: " << current_bitrate << 1130 ". Bitrate: " << current_bitrate <<
1128 ", target: " << last_set_bitrate_kbps_ << " kbps" << 1131 ", target: " << last_set_bitrate_kbps_ << " kbps" <<
1129 ", fps: " << current_fps << 1132 ", fps: " << current_fps <<
1130 ", encTime: " << (current_encoding_time_ms_ / current_frames_) << 1133 ", encTime: " << (current_encoding_time_ms_ / current_frames_divider) <<
1131 ". QP: " << (current_acc_qp_ / current_frames_) << 1134 ". QP: " << (current_acc_qp_ / current_frames_divider) <<
1132 " for last " << statistic_time_ms << " ms."; 1135 " for last " << statistic_time_ms << " ms.";
1133 stat_start_time_ms_ = rtc::TimeMillis(); 1136 stat_start_time_ms_ = rtc::TimeMillis();
1134 current_frames_ = 0; 1137 current_frames_ = 0;
1135 current_bytes_ = 0; 1138 current_bytes_ = 0;
1136 current_acc_qp_ = 0; 1139 current_acc_qp_ = 0;
1137 current_encoding_time_ms_ = 0; 1140 current_encoding_time_ms_ = 0;
1138 } 1141 }
1139 } 1142 }
1140 1143
1141 int32_t MediaCodecVideoEncoder::NextNaluPosition( 1144 int32_t MediaCodecVideoEncoder::NextNaluPosition(
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1273 return supported_codecs_; 1276 return supported_codecs_;
1274 } 1277 }
1275 1278
1276 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder( 1279 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder(
1277 webrtc::VideoEncoder* encoder) { 1280 webrtc::VideoEncoder* encoder) {
1278 ALOGD << "Destroy video encoder."; 1281 ALOGD << "Destroy video encoder.";
1279 delete encoder; 1282 delete encoder;
1280 } 1283 }
1281 1284
1282 } // namespace webrtc_jni 1285 } // namespace webrtc_jni
OLDNEW
« no previous file with comments | « webrtc/api/java/jni/androidmediacodeccommon.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698