Index: webrtc/api/java/jni/androidmediadecoder_jni.cc |
diff --git a/webrtc/api/java/jni/androidmediadecoder_jni.cc b/webrtc/api/java/jni/androidmediadecoder_jni.cc |
index 7c303e8fc311eeefb0a8bb4610047230e74cba42..7deeb4d6ef61ec8f411d83f935e6842b49bd0d51 100644 |
--- a/webrtc/api/java/jni/androidmediadecoder_jni.cc |
+++ b/webrtc/api/java/jni/androidmediadecoder_jni.cc |
@@ -99,6 +99,7 @@ class MediaCodecVideoDecoder : public webrtc::VideoDecoder, |
void CheckOnCodecThread(); |
int32_t InitDecodeOnCodecThread(); |
+ int32_t SoftResetDecodeOnCodecThread(); |
int32_t ReleaseOnCodecThread(); |
int32_t DecodeOnCodecThread(const EncodedImage& inputImage); |
// Deliver any outputs pending in the MediaCodec to our |callback_| and return |
@@ -139,6 +140,7 @@ class MediaCodecVideoDecoder : public webrtc::VideoDecoder, |
ScopedGlobalRef<jclass> j_media_codec_video_decoder_class_; |
ScopedGlobalRef<jobject> j_media_codec_video_decoder_; |
jmethodID j_init_decode_method_; |
+ jmethodID j_soft_reset_decode_method_; |
jmethodID j_release_method_; |
jmethodID j_dequeue_input_buffer_method_; |
jmethodID j_queue_input_buffer_method_; |
@@ -200,6 +202,8 @@ MediaCodecVideoDecoder::MediaCodecVideoDecoder( |
jni, *j_media_codec_video_decoder_class_, "initDecode", |
"(Lorg/webrtc/MediaCodecVideoDecoder$VideoCodecType;" |
"IILorg/webrtc/SurfaceTextureHelper;)Z"); |
+ j_soft_reset_decode_method_ = GetMethodID( |
+ jni, *j_media_codec_video_decoder_class_, "softResetDecode", "(II)V"); |
j_release_method_ = |
GetMethodID(jni, *j_media_codec_video_decoder_class_, "release", "()V"); |
j_dequeue_input_buffer_method_ = GetMethodID( |
@@ -372,6 +376,8 @@ int32_t MediaCodecVideoDecoder::InitDecodeOnCodecThread() { |
default: |
max_pending_frames_ = 0; |
} |
+ ALOGD << "Maximum amount of pending frames: " << max_pending_frames_; |
+ |
start_time_ms_ = GetCurrentTimeMs(); |
current_frames_ = 0; |
current_bytes_ = 0; |
@@ -381,7 +387,6 @@ int32_t MediaCodecVideoDecoder::InitDecodeOnCodecThread() { |
jobjectArray input_buffers = (jobjectArray)GetObjectField( |
jni, *j_media_codec_video_decoder_, j_input_buffers_field_); |
size_t num_input_buffers = jni->GetArrayLength(input_buffers); |
- ALOGD << "Maximum amount of pending frames: " << max_pending_frames_; |
input_buffers_.resize(num_input_buffers); |
for (size_t i = 0; i < num_input_buffers; ++i) { |
input_buffers_[i] = |
@@ -398,6 +403,47 @@ int32_t MediaCodecVideoDecoder::InitDecodeOnCodecThread() { |
return WEBRTC_VIDEO_CODEC_OK; |
} |
perkj_webrtc
2016/03/02 12:33:22
ResetDecodeOnCodecThread?
AlexG
2016/03/04 01:20:20
Done.
|
+int32_t MediaCodecVideoDecoder::SoftResetDecodeOnCodecThread() { |
+ CheckOnCodecThread(); |
+ JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
+ ScopedLocalRefFrame local_ref_frame(jni); |
+ ALOGD << "SoftResetDecodeOnCodecThread Type: " << (int)codecType_ << ". " |
+ << codec_.width << " x " << codec_.height; |
+ ALOGD << " Frames received: " << frames_received_ << |
+ ". Frames decoded: " << frames_decoded_; |
+ |
+ inited_ = false; |
+ rtc::MessageQueueManager::Clear(this); |
+ |
+ // Always start with a complete key frame. |
+ 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.
|
+ frames_received_ = 0; |
+ frames_decoded_ = 0; |
+ frames_decoded_logged_ = kMaxDecodedLogFrames; |
+ start_time_ms_ = GetCurrentTimeMs(); |
+ current_frames_ = 0; |
+ current_bytes_ = 0; |
+ current_decoding_time_ms_ = 0; |
+ current_delay_time_ms_ = 0; |
+ |
+ jni->CallVoidMethod( |
+ *j_media_codec_video_decoder_, |
+ j_soft_reset_decode_method_, |
+ codec_.width, |
+ codec_.height); |
+ |
+ if (CheckException(jni)) { |
+ ALOGE << "Soft reset error - fallback to SW codec."; |
+ sw_fallback_required_ = true; |
+ return WEBRTC_VIDEO_CODEC_ERROR; |
+ } |
+ inited_ = true; |
+ |
+ codec_thread_->PostDelayed(kMediaCodecPollMs, this); |
+ |
+ return WEBRTC_VIDEO_CODEC_OK; |
+} |
+ |
int32_t MediaCodecVideoDecoder::Release() { |
ALOGD << "DecoderRelease request"; |
return codec_thread_->Invoke<int32_t>( |
@@ -493,9 +539,21 @@ int32_t MediaCodecVideoDecoder::Decode( |
if ((inputImage._encodedWidth * inputImage._encodedHeight > 0) && |
(inputImage._encodedWidth != codec_.width || |
inputImage._encodedHeight != codec_.height)) { |
+ ALOGW << "Input resolution changed from " << |
+ codec_.width << " x " << codec_.height << " to " << |
+ inputImage._encodedWidth << " x " << inputImage._encodedHeight; |
codec_.width = inputImage._encodedWidth; |
codec_.height = inputImage._encodedHeight; |
- int32_t ret = InitDecode(&codec_, 1); |
+ int32_t ret; |
+ if (use_surface_ && codecType_ == kVideoCodecVP8) { |
+ // Soft codec reset - only for VP8 and surface decoding. |
+ // TODO(glaznev): try to use similar approach for H.264. |
+ ret = codec_thread_->Invoke<int32_t>(Bind( |
+ &MediaCodecVideoDecoder::SoftResetDecodeOnCodecThread, this)); |
+ } else { |
+ // Hard codec reset. |
+ ret = InitDecode(&codec_, 1); |
+ } |
if (ret < 0) { |
ALOGE << "InitDecode failure: " << ret << " - fallback to SW codec"; |
sw_fallback_required_ = true; |