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

Side by Side Diff: talk/app/webrtc/java/jni/androidmediaencoder_jni.cc

Issue 1653523003: Extra logging for HW codec. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc@master
Patch Set: Created 4 years, 10 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
OLDNEW
1 /* 1 /*
2 * libjingle 2 * libjingle
3 * Copyright 2015 Google Inc. 3 * Copyright 2015 Google Inc.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright notice, 8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer. 9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 jlong GetOutputBufferInfoPresentationTimestampUs( 181 jlong GetOutputBufferInfoPresentationTimestampUs(
182 JNIEnv* jni, jobject j_output_buffer_info); 182 JNIEnv* jni, jobject j_output_buffer_info);
183 183
184 // Deliver any outputs pending in the MediaCodec to our |callback_| and return 184 // Deliver any outputs pending in the MediaCodec to our |callback_| and return
185 // true on success. 185 // true on success.
186 bool DeliverPendingOutputs(JNIEnv* jni); 186 bool DeliverPendingOutputs(JNIEnv* jni);
187 187
188 // Search for H.264 start codes. 188 // Search for H.264 start codes.
189 int32_t NextNaluPosition(uint8_t *buffer, size_t buffer_size); 189 int32_t NextNaluPosition(uint8_t *buffer, size_t buffer_size);
190 190
191 // Displays encoder statistics.
192 void LogStatistics(bool force_log);
193
191 // Type of video codec. 194 // Type of video codec.
192 VideoCodecType codecType_; 195 VideoCodecType codecType_;
193 196
194 // Valid all the time since RegisterEncodeCompleteCallback() Invoke()s to 197 // Valid all the time since RegisterEncodeCompleteCallback() Invoke()s to
195 // |codec_thread_| synchronously. 198 // |codec_thread_| synchronously.
196 webrtc::EncodedImageCallback* callback_; 199 webrtc::EncodedImageCallback* callback_;
197 200
198 // State that is constant for the lifetime of this object once the ctor 201 // State that is constant for the lifetime of this object once the ctor
199 // returns. 202 // returns.
200 scoped_ptr<Thread> codec_thread_; // Thread on which to operate MediaCodec. 203 scoped_ptr<Thread> codec_thread_; // Thread on which to operate MediaCodec.
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 const std::vector<webrtc::FrameType>* frame_types) { 598 const std::vector<webrtc::FrameType>* frame_types) {
596 RTC_DCHECK(codec_thread_checker_.CalledOnValidThread()); 599 RTC_DCHECK(codec_thread_checker_.CalledOnValidThread());
597 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 600 JNIEnv* jni = AttachCurrentThreadIfNeeded();
598 ScopedLocalRefFrame local_ref_frame(jni); 601 ScopedLocalRefFrame local_ref_frame(jni);
599 602
600 if (!inited_) { 603 if (!inited_) {
601 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; 604 return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
602 } 605 }
603 606
604 bool send_key_frame = false; 607 bool send_key_frame = false;
605 if (codecType_ == kVideoCodecVP8 && codec_mode_ == webrtc::kRealtimeVideo) { 608 if ((codecType_ == kVideoCodecVP8 || codecType_ == kVideoCodecH264)
perkj_webrtc 2016/02/01 09:20:53 remove check for codectType_ ? Always do this rega
AlexG 2016/02/01 20:13:35 Done.
609 && codec_mode_ == webrtc::kRealtimeVideo) {
606 ++frames_received_since_last_key_; 610 ++frames_received_since_last_key_;
607 int64_t now_ms = GetCurrentTimeMs(); 611 int64_t now_ms = GetCurrentTimeMs();
608 if (last_frame_received_ms_ != -1 && 612 if (last_frame_received_ms_ != -1 &&
609 (now_ms - last_frame_received_ms_) > kFrameDiffThresholdMs) { 613 (now_ms - last_frame_received_ms_) > kFrameDiffThresholdMs) {
610 // Add limit to prevent triggering a key for every frame for very low 614 // Add limit to prevent triggering a key for every frame for very low
611 // framerates (e.g. if frame diff > kFrameDiffThresholdMs). 615 // framerates (e.g. if frame diff > kFrameDiffThresholdMs).
612 if (frames_received_since_last_key_ > kMinKeyFrameInterval) { 616 if (frames_received_since_last_key_ > kMinKeyFrameInterval) {
613 ALOGD << "Send key, frame diff: " << (now_ms - last_frame_received_ms_); 617 ALOGD << "Send key, frame diff: " << (now_ms - last_frame_received_ms_);
614 send_key_frame = true; 618 send_key_frame = true;
615 } 619 }
(...skipping 25 matching lines...) Expand all
641 RTC_CHECK(frame_types->size() == 1) << "Unexpected stream count"; 645 RTC_CHECK(frame_types->size() == 1) << "Unexpected stream count";
642 646
643 // Check if we accumulated too many frames in encoder input buffers 647 // Check if we accumulated too many frames in encoder input buffers
644 // or the encoder latency exceeds 70 ms and drop frame if so. 648 // or the encoder latency exceeds 70 ms and drop frame if so.
645 if (frames_in_queue_ > 0 && last_input_timestamp_ms_ >= 0) { 649 if (frames_in_queue_ > 0 && last_input_timestamp_ms_ >= 0) {
646 int encoder_latency_ms = last_input_timestamp_ms_ - 650 int encoder_latency_ms = last_input_timestamp_ms_ -
647 last_output_timestamp_ms_; 651 last_output_timestamp_ms_;
648 if (frames_in_queue_ > MAX_ENCODER_Q_SIZE || 652 if (frames_in_queue_ > MAX_ENCODER_Q_SIZE ||
649 encoder_latency_ms > MAX_ENCODER_LATENCY_MS) { 653 encoder_latency_ms > MAX_ENCODER_LATENCY_MS) {
650 ALOGD << "Drop frame - encoder is behind by " << encoder_latency_ms << 654 ALOGD << "Drop frame - encoder is behind by " << encoder_latency_ms <<
651 " ms. Q size: " << frames_in_queue_ << ". Consecutive drops: " << 655 " ms. Q size: " << frames_in_queue_ << ". TS: " <<
652 consecutive_full_queue_frame_drops_; 656 (int)(current_timestamp_us_ / 1000) << ". Fps: " << last_set_fps_ <<
657 ". Consecutive drops: " << consecutive_full_queue_frame_drops_ ;
653 current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_; 658 current_timestamp_us_ += rtc::kNumMicrosecsPerSec / last_set_fps_;
654 consecutive_full_queue_frame_drops_++; 659 consecutive_full_queue_frame_drops_++;
655 if (consecutive_full_queue_frame_drops_ >= 660 if (consecutive_full_queue_frame_drops_ >=
656 ENCODER_STALL_FRAMEDROP_THRESHOLD) { 661 ENCODER_STALL_FRAMEDROP_THRESHOLD) {
657 ALOGE << "Encoder got stuck. Reset."; 662 ALOGE << "Encoder got stuck. Reset.";
658 ResetCodecOnCodecThread(); 663 ResetCodecOnCodecThread();
659 return WEBRTC_VIDEO_CODEC_ERROR; 664 return WEBRTC_VIDEO_CODEC_ERROR;
660 } 665 }
661 frames_dropped_media_encoder_++; 666 frames_dropped_media_encoder_++;
662 OnDroppedFrame(); 667 OnDroppedFrame();
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
751 const bool is_texture_frame = frame.native_handle() != nullptr; 756 const bool is_texture_frame = frame.native_handle() != nullptr;
752 const bool reconfigure_due_to_format = is_texture_frame != use_surface_; 757 const bool reconfigure_due_to_format = is_texture_frame != use_surface_;
753 const bool reconfigure_due_to_size = 758 const bool reconfigure_due_to_size =
754 frame.width() != width_ || frame.height() != height_; 759 frame.width() != width_ || frame.height() != height_;
755 760
756 if (reconfigure_due_to_format) { 761 if (reconfigure_due_to_format) {
757 ALOGD << "Reconfigure encoder due to format change. " 762 ALOGD << "Reconfigure encoder due to format change. "
758 << (use_surface_ ? 763 << (use_surface_ ?
759 "Reconfiguring to encode from byte buffer." : 764 "Reconfiguring to encode from byte buffer." :
760 "Reconfiguring to encode from texture."); 765 "Reconfiguring to encode from texture.");
766 LogStatistics(true);
761 } 767 }
762 if (reconfigure_due_to_size) { 768 if (reconfigure_due_to_size) {
763 ALOGD << "Reconfigure encoder due to frame resolution change from " 769 ALOGW << "Reconfigure encoder due to frame resolution change from "
764 << width_ << " x " << height_ << " to " << frame.width() << " x " 770 << width_ << " x " << height_ << " to " << frame.width() << " x "
765 << frame.height(); 771 << frame.height();
772 LogStatistics(true);
766 width_ = frame.width(); 773 width_ = frame.width();
767 height_ = frame.height(); 774 height_ = frame.height();
768 } 775 }
769 776
770 if (!reconfigure_due_to_format && !reconfigure_due_to_size) 777 if (!reconfigure_due_to_format && !reconfigure_due_to_size)
771 return true; 778 return true;
772 779
773 ReleaseOnCodecThread(); 780 ReleaseOnCodecThread();
774 781
775 return InitEncodeOnCodecThread(width_, height_, 0, 0 , is_texture_frame) == 782 return InitEncodeOnCodecThread(width_, height_, 0, 0 , is_texture_frame) ==
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 if (!success) { 1089 if (!success) {
1083 ResetCodecOnCodecThread(); 1090 ResetCodecOnCodecThread();
1084 return false; 1091 return false;
1085 } 1092 }
1086 1093
1087 // Calculate and print encoding statistics - every 3 seconds. 1094 // Calculate and print encoding statistics - every 3 seconds.
1088 frames_encoded_++; 1095 frames_encoded_++;
1089 current_frames_++; 1096 current_frames_++;
1090 current_bytes_ += payload_size; 1097 current_bytes_ += payload_size;
1091 current_encoding_time_ms_ += frame_encoding_time_ms; 1098 current_encoding_time_ms_ += frame_encoding_time_ms;
1092 int statistic_time_ms = GetCurrentTimeMs() - start_time_ms_; 1099 LogStatistics(false);
1093 if (statistic_time_ms >= kMediaCodecStatisticsIntervalMs &&
1094 current_frames_ > 0) {
1095 ALOGD << "Encoded frames: " << frames_encoded_ << ". Bitrate: " <<
1096 (current_bytes_ * 8 / statistic_time_ms) <<
1097 ", target: " << last_set_bitrate_kbps_ << " kbps, fps: " <<
1098 ((current_frames_ * 1000 + statistic_time_ms / 2) / statistic_time_ms)
1099 << ", encTime: " <<
1100 (current_encoding_time_ms_ / current_frames_) << ". QP: " <<
1101 (current_acc_qp_ / current_frames_) << " for last " <<
1102 statistic_time_ms << " ms.";
1103 start_time_ms_ = GetCurrentTimeMs();
1104 current_frames_ = 0;
1105 current_bytes_ = 0;
1106 current_acc_qp_ = 0;
1107 current_encoding_time_ms_ = 0;
1108 }
1109 1100
1110 if (callback_status > 0) { 1101 if (callback_status > 0) {
1111 drop_next_input_frame_ = true; 1102 drop_next_input_frame_ = true;
1112 // Theoretically could handle callback_status<0 here, but unclear what 1103 // Theoretically could handle callback_status<0 here, but unclear what
1113 // that would mean for us. 1104 // that would mean for us.
1114 } 1105 }
1115 } 1106 }
1107 return true;
1108 }
1116 1109
1117 return true; 1110 void MediaCodecVideoEncoder::LogStatistics(bool force_log) {
1111 int statistic_time_ms = GetCurrentTimeMs() - start_time_ms_;
1112 if ((statistic_time_ms >= kMediaCodecStatisticsIntervalMs || force_log) &&
1113 current_frames_ > 0 && statistic_time_ms > 0) {
1114 ALOGD << "Encoded frames: " << frames_encoded_ << ". Bitrate: " <<
1115 (current_bytes_ * 8 / statistic_time_ms) <<
1116 ", target: " << last_set_bitrate_kbps_ << " kbps, fps: " <<
1117 ((current_frames_ * 1000 + statistic_time_ms / 2) / statistic_time_ms)
1118 << ", encTime: " <<
perkj_webrtc 2016/02/01 09:20:53 Can this be aligned in a more readable way.
AlexG 2016/02/01 20:13:35 Done. And for other similar logs in encoder and de
1119 (current_encoding_time_ms_ / current_frames_) << ". QP: " <<
1120 (current_acc_qp_ / current_frames_) << " for last " <<
1121 statistic_time_ms << " ms.";
1122 start_time_ms_ = GetCurrentTimeMs();
perkj_webrtc 2016/02/01 09:20:53 change name of start_time_ms_ to something more d
AlexG 2016/02/01 20:13:35 Done.
1123 current_frames_ = 0;
1124 current_bytes_ = 0;
1125 current_acc_qp_ = 0;
1126 current_encoding_time_ms_ = 0;
1127 }
1118 } 1128 }
1119 1129
1120 int32_t MediaCodecVideoEncoder::NextNaluPosition( 1130 int32_t MediaCodecVideoEncoder::NextNaluPosition(
1121 uint8_t *buffer, size_t buffer_size) { 1131 uint8_t *buffer, size_t buffer_size) {
1122 if (buffer_size < H264_SC_LENGTH) { 1132 if (buffer_size < H264_SC_LENGTH) {
1123 return -1; 1133 return -1;
1124 } 1134 }
1125 uint8_t *head = buffer; 1135 uint8_t *head = buffer;
1126 // Set end buffer pointer to 4 bytes before actual buffer end so we can 1136 // Set end buffer pointer to 4 bytes before actual buffer end so we can
1127 // access head[1], head[2] and head[3] in a loop without buffer overrun. 1137 // access head[1], head[2] and head[3] in a loop without buffer overrun.
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1237 } 1247 }
1238 1248
1239 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder( 1249 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder(
1240 webrtc::VideoEncoder* encoder) { 1250 webrtc::VideoEncoder* encoder) {
1241 ALOGD << "Destroy video encoder."; 1251 ALOGD << "Destroy video encoder.";
1242 delete encoder; 1252 delete encoder;
1243 } 1253 }
1244 1254
1245 } // namespace webrtc_jni 1255 } // namespace webrtc_jni
1246 1256
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698