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

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

Issue 1732533002: Add an option to soft reset HW decoder. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc@master
Patch Set: Add TODO item Created 4 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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 // rtc::MessageHandler implementation. 92 // rtc::MessageHandler implementation.
93 void OnMessage(rtc::Message* msg) override; 93 void OnMessage(rtc::Message* msg) override;
94 94
95 const char* ImplementationName() const override; 95 const char* ImplementationName() const override;
96 96
97 private: 97 private:
98 // CHECK-fail if not running on |codec_thread_|. 98 // CHECK-fail if not running on |codec_thread_|.
99 void CheckOnCodecThread(); 99 void CheckOnCodecThread();
100 100
101 int32_t InitDecodeOnCodecThread(); 101 int32_t InitDecodeOnCodecThread();
102 int32_t SoftResetDecodeOnCodecThread();
102 int32_t ReleaseOnCodecThread(); 103 int32_t ReleaseOnCodecThread();
103 int32_t DecodeOnCodecThread(const EncodedImage& inputImage); 104 int32_t DecodeOnCodecThread(const EncodedImage& inputImage);
104 // Deliver any outputs pending in the MediaCodec to our |callback_| and return 105 // Deliver any outputs pending in the MediaCodec to our |callback_| and return
105 // true on success. 106 // true on success.
106 bool DeliverPendingOutputs(JNIEnv* jni, int dequeue_timeout_us); 107 bool DeliverPendingOutputs(JNIEnv* jni, int dequeue_timeout_us);
107 int32_t ProcessHWErrorOnCodecThread(); 108 int32_t ProcessHWErrorOnCodecThread();
108 void EnableFrameLogOnWarning(); 109 void EnableFrameLogOnWarning();
109 110
110 // Type of video codec. 111 // Type of video codec.
111 VideoCodecType codecType_; 112 VideoCodecType codecType_;
(...skipping 20 matching lines...) Expand all
132 int current_decoding_time_ms_; // Overall decoding time in the current second 133 int current_decoding_time_ms_; // Overall decoding time in the current second
133 int current_delay_time_ms_; // Overall delay time in the current second. 134 int current_delay_time_ms_; // Overall delay time in the current second.
134 uint32_t max_pending_frames_; // Maximum number of pending input frames. 135 uint32_t max_pending_frames_; // Maximum number of pending input frames.
135 136
136 // State that is constant for the lifetime of this object once the ctor 137 // State that is constant for the lifetime of this object once the ctor
137 // returns. 138 // returns.
138 scoped_ptr<Thread> codec_thread_; // Thread on which to operate MediaCodec. 139 scoped_ptr<Thread> codec_thread_; // Thread on which to operate MediaCodec.
139 ScopedGlobalRef<jclass> j_media_codec_video_decoder_class_; 140 ScopedGlobalRef<jclass> j_media_codec_video_decoder_class_;
140 ScopedGlobalRef<jobject> j_media_codec_video_decoder_; 141 ScopedGlobalRef<jobject> j_media_codec_video_decoder_;
141 jmethodID j_init_decode_method_; 142 jmethodID j_init_decode_method_;
143 jmethodID j_soft_reset_decode_method_;
142 jmethodID j_release_method_; 144 jmethodID j_release_method_;
143 jmethodID j_dequeue_input_buffer_method_; 145 jmethodID j_dequeue_input_buffer_method_;
144 jmethodID j_queue_input_buffer_method_; 146 jmethodID j_queue_input_buffer_method_;
145 jmethodID j_dequeue_byte_buffer_method_; 147 jmethodID j_dequeue_byte_buffer_method_;
146 jmethodID j_dequeue_texture_buffer_method_; 148 jmethodID j_dequeue_texture_buffer_method_;
147 jmethodID j_return_decoded_byte_buffer_method_; 149 jmethodID j_return_decoded_byte_buffer_method_;
148 // MediaCodecVideoDecoder fields. 150 // MediaCodecVideoDecoder fields.
149 jfieldID j_input_buffers_field_; 151 jfieldID j_input_buffers_field_;
150 jfieldID j_output_buffers_field_; 152 jfieldID j_output_buffers_field_;
151 jfieldID j_color_format_field_; 153 jfieldID j_color_format_field_;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 "<init>", 195 "<init>",
194 "()V"))) { 196 "()V"))) {
195 ScopedLocalRefFrame local_ref_frame(jni); 197 ScopedLocalRefFrame local_ref_frame(jni);
196 codec_thread_->SetName("MediaCodecVideoDecoder", NULL); 198 codec_thread_->SetName("MediaCodecVideoDecoder", NULL);
197 RTC_CHECK(codec_thread_->Start()) << "Failed to start MediaCodecVideoDecoder"; 199 RTC_CHECK(codec_thread_->Start()) << "Failed to start MediaCodecVideoDecoder";
198 200
199 j_init_decode_method_ = GetMethodID( 201 j_init_decode_method_ = GetMethodID(
200 jni, *j_media_codec_video_decoder_class_, "initDecode", 202 jni, *j_media_codec_video_decoder_class_, "initDecode",
201 "(Lorg/webrtc/MediaCodecVideoDecoder$VideoCodecType;" 203 "(Lorg/webrtc/MediaCodecVideoDecoder$VideoCodecType;"
202 "IILorg/webrtc/SurfaceTextureHelper;)Z"); 204 "IILorg/webrtc/SurfaceTextureHelper;)Z");
205 j_soft_reset_decode_method_ = GetMethodID(
206 jni, *j_media_codec_video_decoder_class_, "softResetDecode", "(II)V");
203 j_release_method_ = 207 j_release_method_ =
204 GetMethodID(jni, *j_media_codec_video_decoder_class_, "release", "()V"); 208 GetMethodID(jni, *j_media_codec_video_decoder_class_, "release", "()V");
205 j_dequeue_input_buffer_method_ = GetMethodID( 209 j_dequeue_input_buffer_method_ = GetMethodID(
206 jni, *j_media_codec_video_decoder_class_, "dequeueInputBuffer", "()I"); 210 jni, *j_media_codec_video_decoder_class_, "dequeueInputBuffer", "()I");
207 j_queue_input_buffer_method_ = GetMethodID( 211 j_queue_input_buffer_method_ = GetMethodID(
208 jni, *j_media_codec_video_decoder_class_, "queueInputBuffer", "(IIJJJ)Z"); 212 jni, *j_media_codec_video_decoder_class_, "queueInputBuffer", "(IIJJJ)Z");
209 j_dequeue_byte_buffer_method_ = GetMethodID( 213 j_dequeue_byte_buffer_method_ = GetMethodID(
210 jni, *j_media_codec_video_decoder_class_, "dequeueOutputBuffer", 214 jni, *j_media_codec_video_decoder_class_, "dequeueOutputBuffer",
211 "(I)Lorg/webrtc/MediaCodecVideoDecoder$DecodedOutputBuffer;"); 215 "(I)Lorg/webrtc/MediaCodecVideoDecoder$DecodedOutputBuffer;");
212 j_dequeue_texture_buffer_method_ = GetMethodID( 216 j_dequeue_texture_buffer_method_ = GetMethodID(
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 break; 369 break;
366 case kVideoCodecVP9: 370 case kVideoCodecVP9:
367 max_pending_frames_ = kMaxPendingFramesVp9; 371 max_pending_frames_ = kMaxPendingFramesVp9;
368 break; 372 break;
369 case kVideoCodecH264: 373 case kVideoCodecH264:
370 max_pending_frames_ = kMaxPendingFramesH264; 374 max_pending_frames_ = kMaxPendingFramesH264;
371 break; 375 break;
372 default: 376 default:
373 max_pending_frames_ = 0; 377 max_pending_frames_ = 0;
374 } 378 }
379 ALOGD << "Maximum amount of pending frames: " << max_pending_frames_;
380
375 start_time_ms_ = GetCurrentTimeMs(); 381 start_time_ms_ = GetCurrentTimeMs();
376 current_frames_ = 0; 382 current_frames_ = 0;
377 current_bytes_ = 0; 383 current_bytes_ = 0;
378 current_decoding_time_ms_ = 0; 384 current_decoding_time_ms_ = 0;
379 current_delay_time_ms_ = 0; 385 current_delay_time_ms_ = 0;
380 386
381 jobjectArray input_buffers = (jobjectArray)GetObjectField( 387 jobjectArray input_buffers = (jobjectArray)GetObjectField(
382 jni, *j_media_codec_video_decoder_, j_input_buffers_field_); 388 jni, *j_media_codec_video_decoder_, j_input_buffers_field_);
383 size_t num_input_buffers = jni->GetArrayLength(input_buffers); 389 size_t num_input_buffers = jni->GetArrayLength(input_buffers);
384 ALOGD << "Maximum amount of pending frames: " << max_pending_frames_;
385 input_buffers_.resize(num_input_buffers); 390 input_buffers_.resize(num_input_buffers);
386 for (size_t i = 0; i < num_input_buffers; ++i) { 391 for (size_t i = 0; i < num_input_buffers; ++i) {
387 input_buffers_[i] = 392 input_buffers_[i] =
388 jni->NewGlobalRef(jni->GetObjectArrayElement(input_buffers, i)); 393 jni->NewGlobalRef(jni->GetObjectArrayElement(input_buffers, i));
389 if (CheckException(jni)) { 394 if (CheckException(jni)) {
390 ALOGE << "NewGlobalRef error - fallback to SW codec."; 395 ALOGE << "NewGlobalRef error - fallback to SW codec.";
391 sw_fallback_required_ = true; 396 sw_fallback_required_ = true;
392 return WEBRTC_VIDEO_CODEC_ERROR; 397 return WEBRTC_VIDEO_CODEC_ERROR;
393 } 398 }
394 } 399 }
395 400
396 codec_thread_->PostDelayed(kMediaCodecPollMs, this); 401 codec_thread_->PostDelayed(kMediaCodecPollMs, this);
397 402
398 return WEBRTC_VIDEO_CODEC_OK; 403 return WEBRTC_VIDEO_CODEC_OK;
399 } 404 }
400 405
perkj_webrtc 2016/03/02 12:33:22 ResetDecodeOnCodecThread?
AlexG 2016/03/04 01:20:20 Done.
406 int32_t MediaCodecVideoDecoder::SoftResetDecodeOnCodecThread() {
407 CheckOnCodecThread();
408 JNIEnv* jni = AttachCurrentThreadIfNeeded();
409 ScopedLocalRefFrame local_ref_frame(jni);
410 ALOGD << "SoftResetDecodeOnCodecThread Type: " << (int)codecType_ << ". "
411 << codec_.width << " x " << codec_.height;
412 ALOGD << " Frames received: " << frames_received_ <<
413 ". Frames decoded: " << frames_decoded_;
414
415 inited_ = false;
416 rtc::MessageQueueManager::Clear(this);
417
418 // Always start with a complete key frame.
419 key_frame_required_ = true;
perkj_webrtc 2016/03/02 12:33:22 Move all these to a helper method and call from In
AlexG 2016/03/04 01:20:20 Done.
420 frames_received_ = 0;
421 frames_decoded_ = 0;
422 frames_decoded_logged_ = kMaxDecodedLogFrames;
423 start_time_ms_ = GetCurrentTimeMs();
424 current_frames_ = 0;
425 current_bytes_ = 0;
426 current_decoding_time_ms_ = 0;
427 current_delay_time_ms_ = 0;
428
429 jni->CallVoidMethod(
430 *j_media_codec_video_decoder_,
431 j_soft_reset_decode_method_,
432 codec_.width,
433 codec_.height);
434
435 if (CheckException(jni)) {
436 ALOGE << "Soft reset error - fallback to SW codec.";
437 sw_fallback_required_ = true;
438 return WEBRTC_VIDEO_CODEC_ERROR;
439 }
440 inited_ = true;
441
442 codec_thread_->PostDelayed(kMediaCodecPollMs, this);
443
444 return WEBRTC_VIDEO_CODEC_OK;
445 }
446
401 int32_t MediaCodecVideoDecoder::Release() { 447 int32_t MediaCodecVideoDecoder::Release() {
402 ALOGD << "DecoderRelease request"; 448 ALOGD << "DecoderRelease request";
403 return codec_thread_->Invoke<int32_t>( 449 return codec_thread_->Invoke<int32_t>(
404 Bind(&MediaCodecVideoDecoder::ReleaseOnCodecThread, this)); 450 Bind(&MediaCodecVideoDecoder::ReleaseOnCodecThread, this));
405 } 451 }
406 452
407 int32_t MediaCodecVideoDecoder::ReleaseOnCodecThread() { 453 int32_t MediaCodecVideoDecoder::ReleaseOnCodecThread() {
408 if (!inited_) { 454 if (!inited_) {
409 return WEBRTC_VIDEO_CODEC_OK; 455 return WEBRTC_VIDEO_CODEC_OK;
410 } 456 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 } 532 }
487 if (!inited_) { 533 if (!inited_) {
488 ALOGE << "Decode() - decoder is not initialized"; 534 ALOGE << "Decode() - decoder is not initialized";
489 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; 535 return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
490 } 536 }
491 537
492 // Check if encoded frame dimension has changed. 538 // Check if encoded frame dimension has changed.
493 if ((inputImage._encodedWidth * inputImage._encodedHeight > 0) && 539 if ((inputImage._encodedWidth * inputImage._encodedHeight > 0) &&
494 (inputImage._encodedWidth != codec_.width || 540 (inputImage._encodedWidth != codec_.width ||
495 inputImage._encodedHeight != codec_.height)) { 541 inputImage._encodedHeight != codec_.height)) {
542 ALOGW << "Input resolution changed from " <<
543 codec_.width << " x " << codec_.height << " to " <<
544 inputImage._encodedWidth << " x " << inputImage._encodedHeight;
496 codec_.width = inputImage._encodedWidth; 545 codec_.width = inputImage._encodedWidth;
497 codec_.height = inputImage._encodedHeight; 546 codec_.height = inputImage._encodedHeight;
498 int32_t ret = InitDecode(&codec_, 1); 547 int32_t ret;
548 if (use_surface_ && codecType_ == kVideoCodecVP8) {
549 // Soft codec reset - only for VP8 and surface decoding.
550 // TODO(glaznev): try to use similar approach for H.264.
551 ret = codec_thread_->Invoke<int32_t>(Bind(
552 &MediaCodecVideoDecoder::SoftResetDecodeOnCodecThread, this));
553 } else {
554 // Hard codec reset.
555 ret = InitDecode(&codec_, 1);
556 }
499 if (ret < 0) { 557 if (ret < 0) {
500 ALOGE << "InitDecode failure: " << ret << " - fallback to SW codec"; 558 ALOGE << "InitDecode failure: " << ret << " - fallback to SW codec";
501 sw_fallback_required_ = true; 559 sw_fallback_required_ = true;
502 return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; 560 return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
503 } 561 }
504 } 562 }
505 563
506 // Always start with a complete key frame. 564 // Always start with a complete key frame.
507 if (key_frame_required_) { 565 if (key_frame_required_) {
508 if (inputImage._frameType != webrtc::kVideoFrameKey) { 566 if (inputImage._frameType != webrtc::kVideoFrameKey) {
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
928 ALOGD << "Destroy video decoder."; 986 ALOGD << "Destroy video decoder.";
929 delete decoder; 987 delete decoder;
930 } 988 }
931 989
932 const char* MediaCodecVideoDecoder::ImplementationName() const { 990 const char* MediaCodecVideoDecoder::ImplementationName() const {
933 return "MediaCodec"; 991 return "MediaCodec";
934 } 992 }
935 993
936 } // namespace webrtc_jni 994 } // namespace webrtc_jni
937 995
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698