From 6d387c0e92f033e31c8dd1efbf3f98bf159c6cf1 Mon Sep 17 00:00:00 2001 From: magjed Date: Wed, 14 Oct 2015 04:02:01 -0700 Subject: [PATCH] Android MediaCodecVideoDecoder: Limit max pending frames to number of input buffers This CL should reduce the number of timeouts for dequeueInputBuffer() which results in the log "MediaCodecVideo: dequeueInputBuffer error" followed by software fallback for VP8/VP9 and codec restart for H264. A timeout always happen for dequeueInputBuffer() when frames_received_ > frames_decoded_ + num_input_buffers. The following code tries to drain the decoder before enqueuing more input buffers: // Try to drain the decoder and wait until output is not too // much behind the input. if (frames_received_ > frames_decoded_ + max_pending_frames_) { ALOGV("Received: %d. Decoded: %d. Wait for output...", frames_received_, frames_decoded_); if (!DeliverPendingOutputs(jni, kMediaCodecTimeoutMs, true /* dropFrames */)) { ALOGE << "DeliverPendingOutputs error"; return ProcessHWErrorOnCodecThread(); } if (frames_received_ > frames_decoded_ + max_pending_frames_) { ALOGE << "Output buffer dequeue timeout"; return ProcessHWErrorOnCodecThread(); } ... } However, for H264, |max_pending_frames_| can currently be larger than the number of input buffers so that the code above is never executed. This CL limits |max_pending_frames_| to the number of input buffers. TBR=glaznev BUG=b/24867188,b/24864151 Review URL: https://codereview.webrtc.org/1394303005 Cr-Commit-Position: refs/heads/master@{#10273} --- talk/app/webrtc/java/jni/androidmediadecoder_jni.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/talk/app/webrtc/java/jni/androidmediadecoder_jni.cc b/talk/app/webrtc/java/jni/androidmediadecoder_jni.cc index 418afe26ca..ed5ba0b478 100644 --- a/talk/app/webrtc/java/jni/androidmediadecoder_jni.cc +++ b/talk/app/webrtc/java/jni/androidmediadecoder_jni.cc @@ -26,6 +26,7 @@ * */ +#include #include #include "talk/app/webrtc/java/jni/androidmediadecoder_jni.h" @@ -340,6 +341,8 @@ 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); + max_pending_frames_ = + std::min(max_pending_frames_, static_cast(num_input_buffers)); input_buffers_.resize(num_input_buffers); for (size_t i = 0; i < num_input_buffers; ++i) { input_buffers_[i] =