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

Side by Side Diff: webrtc/sdk/android/src/jni/androidmediaencoder_jni.cc

Issue 2764143002: Add field trial to update quality scaler QP thresholds for Android HW encoder. (Closed)
Patch Set: Created 3 years, 9 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 * 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 #endif 79 #endif
80 #define ALOGD LOG_TAG(rtc::LS_INFO, TAG_ENCODER) 80 #define ALOGD LOG_TAG(rtc::LS_INFO, TAG_ENCODER)
81 #define ALOGW LOG_TAG(rtc::LS_WARNING, TAG_ENCODER) 81 #define ALOGW LOG_TAG(rtc::LS_WARNING, TAG_ENCODER)
82 #define ALOGE LOG_TAG(rtc::LS_ERROR, TAG_ENCODER) 82 #define ALOGE LOG_TAG(rtc::LS_ERROR, TAG_ENCODER)
83 83
84 namespace { 84 namespace {
85 // Maximum time limit between incoming frames before requesting a key frame. 85 // Maximum time limit between incoming frames before requesting a key frame.
86 const size_t kFrameDiffThresholdMs = 350; 86 const size_t kFrameDiffThresholdMs = 350;
87 const int kMinKeyFrameInterval = 6; 87 const int kMinKeyFrameInterval = 6;
88 const char kH264HighProfileFieldTrial[] = "WebRTC-H264HighProfile"; 88 const char kH264HighProfileFieldTrial[] = "WebRTC-H264HighProfile";
89 const char kCustomQPThresholdsFieldTrial[] = "WebRTC-CustomQPThresholds";
89 } // namespace 90 } // namespace
90 91
91 // MediaCodecVideoEncoder is a webrtc::VideoEncoder implementation that uses 92 // MediaCodecVideoEncoder is a webrtc::VideoEncoder implementation that uses
92 // Android's MediaCodec SDK API behind the scenes to implement (hopefully) 93 // Android's MediaCodec SDK API behind the scenes to implement (hopefully)
93 // HW-backed video encode. This C++ class is implemented as a very thin shim, 94 // HW-backed video encode. This C++ class is implemented as a very thin shim,
94 // delegating all of the interesting work to org.webrtc.MediaCodecVideoEncoder. 95 // delegating all of the interesting work to org.webrtc.MediaCodecVideoEncoder.
95 // MediaCodecVideoEncoder must be operated on a single task queue, currently 96 // MediaCodecVideoEncoder must be operated on a single task queue, currently
96 // this is the encoder queue from ViE encoder. 97 // this is the encoder queue from ViE encoder.
97 class MediaCodecVideoEncoder : public webrtc::VideoEncoder { 98 class MediaCodecVideoEncoder : public webrtc::VideoEncoder {
98 public: 99 public:
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 174
174 // Deliver any outputs pending in the MediaCodec to our |callback_| and return 175 // Deliver any outputs pending in the MediaCodec to our |callback_| and return
175 // true on success. 176 // true on success.
176 bool DeliverPendingOutputs(JNIEnv* jni); 177 bool DeliverPendingOutputs(JNIEnv* jni);
177 178
178 VideoEncoder::ScalingSettings GetScalingSettings() const override; 179 VideoEncoder::ScalingSettings GetScalingSettings() const override;
179 180
180 // Displays encoder statistics. 181 // Displays encoder statistics.
181 void LogStatistics(bool force_log); 182 void LogStatistics(bool force_log);
182 183
184 VideoCodecType GetCodecType() const;
kthelgason 2017/03/22 07:38:58 Thanks for cleaning this up!
185
183 #if RTC_DCHECK_IS_ON 186 #if RTC_DCHECK_IS_ON
184 // Mutex for protecting inited_. It is only used for correctness checking on 187 // Mutex for protecting inited_. It is only used for correctness checking on
185 // debug build. It is used for checking that encoder has been released in the 188 // debug build. It is used for checking that encoder has been released in the
186 // destructor. Because this might happen on a different thread, we need a 189 // destructor. Because this might happen on a different thread, we need a
187 // mutex. 190 // mutex.
188 rtc::CriticalSection inited_crit_; 191 rtc::CriticalSection inited_crit_;
189 #endif 192 #endif
190 193
191 // Type of video codec. 194 // Type of video codec.
192 const cricket::VideoCodec codec_; 195 const cricket::VideoCodec codec_;
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 int32_t MediaCodecVideoEncoder::InitEncode( 380 int32_t MediaCodecVideoEncoder::InitEncode(
378 const webrtc::VideoCodec* codec_settings, 381 const webrtc::VideoCodec* codec_settings,
379 int32_t /* number_of_cores */, 382 int32_t /* number_of_cores */,
380 size_t /* max_payload_size */) { 383 size_t /* max_payload_size */) {
381 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); 384 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_);
382 if (codec_settings == NULL) { 385 if (codec_settings == NULL) {
383 ALOGE << "NULL VideoCodec instance"; 386 ALOGE << "NULL VideoCodec instance";
384 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 387 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
385 } 388 }
386 // Factory should guard against other codecs being used with us. 389 // Factory should guard against other codecs being used with us.
387 const VideoCodecType codec_type = webrtc::PayloadNameToCodecType(codec_.name) 390 const VideoCodecType codec_type = GetCodecType();
388 .value_or(webrtc::kVideoCodecUnknown);
389 RTC_CHECK(codec_settings->codecType == codec_type) 391 RTC_CHECK(codec_settings->codecType == codec_type)
390 << "Unsupported codec " << codec_settings->codecType << " for " 392 << "Unsupported codec " << codec_settings->codecType << " for "
391 << codec_type; 393 << codec_type;
392 if (sw_fallback_required_) { 394 if (sw_fallback_required_) {
393 return WEBRTC_VIDEO_CODEC_OK; 395 return WEBRTC_VIDEO_CODEC_OK;
394 } 396 }
395 codec_mode_ = codec_settings->mode; 397 codec_mode_ = codec_settings->mode;
396 int init_width = codec_settings->width; 398 int init_width = codec_settings->width;
397 int init_height = codec_settings->height; 399 int init_height = codec_settings->height;
398 // Scaling is disabled for VP9, but optionally enabled for VP8. 400 // Scaling is disabled for VP9, but optionally enabled for VP8.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 } 493 }
492 return false; 494 return false;
493 } 495 }
494 496
495 int32_t MediaCodecVideoEncoder::ProcessHWErrorOnEncode() { 497 int32_t MediaCodecVideoEncoder::ProcessHWErrorOnEncode() {
496 ProcessHWError(true /* reset_if_fallback_unavailable */); 498 ProcessHWError(true /* reset_if_fallback_unavailable */);
497 return sw_fallback_required_ ? WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE 499 return sw_fallback_required_ ? WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE
498 : WEBRTC_VIDEO_CODEC_ERROR; 500 : WEBRTC_VIDEO_CODEC_ERROR;
499 } 501 }
500 502
503 VideoCodecType MediaCodecVideoEncoder::GetCodecType() const {
504 return webrtc::PayloadNameToCodecType(codec_.name)
505 .value_or(webrtc::kVideoCodecUnknown);
506 }
507
501 int32_t MediaCodecVideoEncoder::InitEncodeInternal(int width, 508 int32_t MediaCodecVideoEncoder::InitEncodeInternal(int width,
502 int height, 509 int height,
503 int kbps, 510 int kbps,
504 int fps, 511 int fps,
505 bool use_surface) { 512 bool use_surface) {
506 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); 513 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_);
507 if (sw_fallback_required_) { 514 if (sw_fallback_required_) {
508 return WEBRTC_VIDEO_CODEC_OK; 515 return WEBRTC_VIDEO_CODEC_OK;
509 } 516 }
510 RTC_CHECK(!use_surface || egl_context_ != nullptr) << "EGL context not set."; 517 RTC_CHECK(!use_surface || egl_context_ != nullptr) << "EGL context not set.";
511 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 518 JNIEnv* jni = AttachCurrentThreadIfNeeded();
512 ScopedLocalRefFrame local_ref_frame(jni); 519 ScopedLocalRefFrame local_ref_frame(jni);
513 520
514 const VideoCodecType codec_type = webrtc::PayloadNameToCodecType(codec_.name) 521 const VideoCodecType codec_type = GetCodecType();
515 .value_or(webrtc::kVideoCodecUnknown);
516 ALOGD << "InitEncodeInternal Type: " << (int)codec_type << ", " << width 522 ALOGD << "InitEncodeInternal Type: " << (int)codec_type << ", " << width
517 << " x " << height << ". Bitrate: " << kbps << " kbps. Fps: " << fps; 523 << " x " << height << ". Bitrate: " << kbps << " kbps. Fps: " << fps;
518 if (kbps == 0) { 524 if (kbps == 0) {
519 kbps = last_set_bitrate_kbps_; 525 kbps = last_set_bitrate_kbps_;
520 } 526 }
521 if (fps == 0) { 527 if (fps == 0) {
522 fps = MAX_VIDEO_FPS; 528 fps = MAX_VIDEO_FPS;
523 } 529 }
524 530
525 width_ = width; 531 width_ = width;
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 size_t payload_size = jni->GetDirectBufferCapacity(j_output_buffer); 1021 size_t payload_size = jni->GetDirectBufferCapacity(j_output_buffer);
1016 uint8_t* payload = reinterpret_cast<uint8_t*>( 1022 uint8_t* payload = reinterpret_cast<uint8_t*>(
1017 jni->GetDirectBufferAddress(j_output_buffer)); 1023 jni->GetDirectBufferAddress(j_output_buffer));
1018 if (CheckException(jni)) { 1024 if (CheckException(jni)) {
1019 ALOGE << "Exception in get direct buffer address."; 1025 ALOGE << "Exception in get direct buffer address.";
1020 ProcessHWError(true /* reset_if_fallback_unavailable */); 1026 ProcessHWError(true /* reset_if_fallback_unavailable */);
1021 return WEBRTC_VIDEO_CODEC_ERROR; 1027 return WEBRTC_VIDEO_CODEC_ERROR;
1022 } 1028 }
1023 1029
1024 // Callback - return encoded frame. 1030 // Callback - return encoded frame.
1025 const VideoCodecType codec_type = 1031 const VideoCodecType codec_type = GetCodecType();
1026 webrtc::PayloadNameToCodecType(codec_.name)
1027 .value_or(webrtc::kVideoCodecUnknown);
1028 webrtc::EncodedImageCallback::Result callback_result( 1032 webrtc::EncodedImageCallback::Result callback_result(
1029 webrtc::EncodedImageCallback::Result::OK); 1033 webrtc::EncodedImageCallback::Result::OK);
1030 if (callback_) { 1034 if (callback_) {
1031 std::unique_ptr<webrtc::EncodedImage> image( 1035 std::unique_ptr<webrtc::EncodedImage> image(
1032 new webrtc::EncodedImage(payload, payload_size, payload_size)); 1036 new webrtc::EncodedImage(payload, payload_size, payload_size));
1033 image->_encodedWidth = width_; 1037 image->_encodedWidth = width_;
1034 image->_encodedHeight = height_; 1038 image->_encodedHeight = height_;
1035 image->_timeStamp = output_timestamp_; 1039 image->_timeStamp = output_timestamp_;
1036 image->capture_time_ms_ = output_render_time_ms_; 1040 image->capture_time_ms_ = output_render_time_ms_;
1037 image->rotation_ = output_rotation_; 1041 image->rotation_ = output_rotation_;
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1179 stat_start_time_ms_ = rtc::TimeMillis(); 1183 stat_start_time_ms_ = rtc::TimeMillis();
1180 current_frames_ = 0; 1184 current_frames_ = 0;
1181 current_bytes_ = 0; 1185 current_bytes_ = 0;
1182 current_acc_qp_ = 0; 1186 current_acc_qp_ = 0;
1183 current_encoding_time_ms_ = 0; 1187 current_encoding_time_ms_ = 0;
1184 } 1188 }
1185 } 1189 }
1186 1190
1187 webrtc::VideoEncoder::ScalingSettings 1191 webrtc::VideoEncoder::ScalingSettings
1188 MediaCodecVideoEncoder::GetScalingSettings() const { 1192 MediaCodecVideoEncoder::GetScalingSettings() const {
1193 if (webrtc::field_trial::IsEnabled(kCustomQPThresholdsFieldTrial)) {
1194 const VideoCodecType codec_type = GetCodecType();
1195 std::string experiment_string =
1196 webrtc::field_trial::FindFullName(kCustomQPThresholdsFieldTrial);
1197 ALOGD << "QP custom thresholds: " << experiment_string << " for codec "
stefan-webrtc 2017/03/23 17:58:04 LOG(LS_INFO) or similar?
AlexG 2017/03/23 19:25:08 ALOGD is used now for all logging in this file - t
1198 << codec_type;
1199 int lowVp8QpThreshold;
1200 int highVp8QpThreshold;
1201 int lowH264QpThreshold;
1202 int highH264QpThreshold;
stefan-webrtc 2017/03/23 17:58:04 No camelCase
AlexG 2017/03/23 19:25:08 Done.
1203 int parsed_values = sscanf(experiment_string.c_str(), "Enabled-%u,%u,%u,%u",
1204 &lowVp8QpThreshold, &highVp8QpThreshold,
1205 &lowH264QpThreshold, &highH264QpThreshold);
1206 if (parsed_values == 4) {
1207 RTC_CHECK_GT(highVp8QpThreshold, lowVp8QpThreshold);
1208 RTC_CHECK_GT(lowVp8QpThreshold, 0);
1209 RTC_CHECK_GT(highH264QpThreshold, lowH264QpThreshold);
1210 RTC_CHECK_GT(lowH264QpThreshold, 0);
1211 if (codec_type == kVideoCodecVP8) {
1212 return VideoEncoder::ScalingSettings(scale_, lowVp8QpThreshold,
1213 highVp8QpThreshold);
1214 } else if (codec_type == kVideoCodecH264) {
1215 return VideoEncoder::ScalingSettings(scale_, lowH264QpThreshold,
1216 highH264QpThreshold);
1217 }
1218 }
1219 }
1189 return VideoEncoder::ScalingSettings(scale_); 1220 return VideoEncoder::ScalingSettings(scale_);
1190 } 1221 }
1191 1222
1192 const char* MediaCodecVideoEncoder::ImplementationName() const { 1223 const char* MediaCodecVideoEncoder::ImplementationName() const {
1193 return "MediaCodec"; 1224 return "MediaCodec";
1194 } 1225 }
1195 1226
1196 MediaCodecVideoEncoderFactory::MediaCodecVideoEncoderFactory() 1227 MediaCodecVideoEncoderFactory::MediaCodecVideoEncoderFactory()
1197 : egl_context_(nullptr) { 1228 : egl_context_(nullptr) {
1198 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 1229 JNIEnv* jni = AttachCurrentThreadIfNeeded();
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1311 } 1342 }
1312 } 1343 }
1313 1344
1314 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder( 1345 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder(
1315 webrtc::VideoEncoder* encoder) { 1346 webrtc::VideoEncoder* encoder) {
1316 ALOGD << "Destroy video encoder."; 1347 ALOGD << "Destroy video encoder.";
1317 delete encoder; 1348 delete encoder;
1318 } 1349 }
1319 1350
1320 } // namespace webrtc_jni 1351 } // namespace webrtc_jni
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698