diff options
author | qinmin@chromium.org <qinmin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-29 14:35:26 +0000 |
---|---|---|
committer | qinmin@chromium.org <qinmin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-29 14:35:26 +0000 |
commit | 6e206fadeaac18ef6fcf1a3cc924732aa08312bd (patch) | |
tree | 0279e6b4c3ac16af7f48d65830ceaccb2c1cb1fc /media | |
parent | 189c1a51ed7fa9f2d0bf35970cef48ebbd8c19b5 (diff) | |
download | chromium_src-6e206fadeaac18ef6fcf1a3cc924732aa08312bd.zip chromium_src-6e206fadeaac18ef6fcf1a3cc924732aa08312bd.tar.gz chromium_src-6e206fadeaac18ef6fcf1a3cc924732aa08312bd.tar.bz2 |
add error handling if MediaCodec fails to decode data
If MediaCodec fails, we need to report the error to WMPA.
BUG=233420
R=acolwell@chromium.org
Review URL: https://codereview.chromium.org/15822006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@202868 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r-- | media/base/android/java/src/org/chromium/media/MediaCodecBridge.java | 15 | ||||
-rw-r--r-- | media/base/android/media_codec_bridge.h | 1 | ||||
-rw-r--r-- | media/base/android/media_source_player.cc | 20 | ||||
-rw-r--r-- | media/base/android/media_source_player.h | 12 |
4 files changed, 36 insertions, 12 deletions
diff --git a/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java b/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java index 13b9334..399ae27 100644 --- a/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java +++ b/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java @@ -27,6 +27,10 @@ class MediaCodecBridge { private static final String TAG = "MediaCodecBridge"; + // Error code for MediaCodecBridge. Keep this value in sync with + // INFO_MEDIA_CODEC_ERROR in media_codec_bridge.h. + private static final int MEDIA_CODEC_ERROR = -1000; + private ByteBuffer[] mInputBuffers; private ByteBuffer[] mOutputBuffers; @@ -41,8 +45,8 @@ class MediaCodecBridge { private final long mPresentationTimeMicroseconds; private final int mNumBytes; - private DequeueOutputResult( - int index, int flags, int offset, long presentationTimeMicroseconds, int numBytes) { + private DequeueOutputResult(int index, int flags, int offset, + long presentationTimeMicroseconds, int numBytes) { mIndex = index; mFlags = flags; mOffset = offset; @@ -149,7 +153,12 @@ class MediaCodecBridge { @CalledByNative private DequeueOutputResult dequeueOutputBuffer(long timeoutUs) { MediaCodec.BufferInfo info = new MediaCodec.BufferInfo(); - int index = mMediaCodec.dequeueOutputBuffer(info, timeoutUs); + int index = MEDIA_CODEC_ERROR; + try { + index = mMediaCodec.dequeueOutputBuffer(info, timeoutUs); + } catch(IllegalStateException e) { + Log.e(TAG, "Cannot dequeue output buffer " + e.toString()); + } return new DequeueOutputResult( index, info.flags, info.offset, info.presentationTimeUs, info.size); } diff --git a/media/base/android/media_codec_bridge.h b/media/base/android/media_codec_bridge.h index 7bea7b6..b8a30a8 100644 --- a/media/base/android/media_codec_bridge.h +++ b/media/base/android/media_codec_bridge.h @@ -28,6 +28,7 @@ class MEDIA_EXPORT MediaCodecBridge { INFO_OUTPUT_BUFFERS_CHANGED = -3, INFO_OUTPUT_FORMAT_CHANGED = -2, INFO_TRY_AGAIN_LATER = -1, + INFO_MEDIA_CODEC_ERROR = -1000, }; static const base::TimeDelta kTimeOutInfinity; diff --git a/media/base/android/media_source_player.cc b/media/base/android/media_source_player.cc index 193c1a3..7ca6c70 100644 --- a/media/base/android/media_source_player.cc +++ b/media/base/android/media_source_player.cc @@ -91,6 +91,7 @@ void MediaDecoderJob::DecodeInternal( size_t size = 0; base::TimeDelta presentation_timestamp; bool end_of_stream = false; + bool decode_succeeded = true; int outputBufferIndex = media_codec_bridge_->DequeueOutputBuffer( timeout, &offset, &size, &presentation_timestamp, &end_of_stream); @@ -103,6 +104,9 @@ void MediaDecoderJob::DecodeInternal( break; case MediaCodecBridge::INFO_TRY_AGAIN_LATER: break; + case MediaCodecBridge::INFO_MEDIA_CODEC_ERROR: + decode_succeeded = false; + break; default: DCHECK_LE(0, outputBufferIndex); if (size == 0 && end_of_stream) @@ -130,8 +134,8 @@ void MediaDecoderJob::DecodeInternal( return; } message_loop_->PostTask(FROM_HERE, base::Bind( - callback, start_presentation_timestamp, start_wallclock_time, - end_of_stream)); + callback, decode_succeeded, start_presentation_timestamp, + start_wallclock_time, end_of_stream)); } void MediaDecoderJob::ReleaseOutputBuffer( @@ -146,7 +150,8 @@ void MediaDecoderJob::ReleaseOutputBuffer( } media_codec_bridge_->ReleaseOutputBuffer(outputBufferIndex, !is_audio_); message_loop_->PostTask(FROM_HERE, base::Bind( - callback, presentation_timestamp, base::Time::Now(), end_of_stream)); + callback, true, presentation_timestamp, base::Time::Now(), + end_of_stream)); } void MediaDecoderJob::Flush() { @@ -421,11 +426,18 @@ void MediaSourcePlayer::ProcessPendingEvents() { } void MediaSourcePlayer::MediaDecoderCallback( - bool is_audio, const base::TimeDelta& presentation_timestamp, + bool is_audio, bool decode_succeeded, + const base::TimeDelta& presentation_timestamp, const base::Time& wallclock_time, bool end_of_stream) { if (active_decoding_tasks_ > 0) active_decoding_tasks_--; + if (!decode_succeeded) { + Release(); + OnMediaError(MEDIA_ERROR_DECODE); + return; + } + if (pending_event_ != NO_EVENT_PENDING) { ProcessPendingEvents(); return; diff --git a/media/base/android/media_source_player.h b/media/base/android/media_source_player.h index 27b7b0c..2b6628f 100644 --- a/media/base/android/media_source_player.h +++ b/media/base/android/media_source_player.h @@ -36,10 +36,11 @@ class MediaDecoderJob { public: virtual ~MediaDecoderJob(); - // Callback when a decoder job finishes its work. Args: presentation time, - // timestamp when the data is rendered, whether decoder is reaching EOS. - typedef base::Callback<void(const base::TimeDelta&, const base::Time&, bool)> - DecoderCallback; + // Callback when a decoder job finishes its work. Args: whether decode + // finished successfully, presentation time, timestamp when the data is + // rendered, whether decoder is reaching EOS. + typedef base::Callback<void(bool, const base::TimeDelta&, + const base::Time&, bool)> DecoderCallback; // Called by MediaSourcePlayer to decode some data. void Decode( @@ -155,7 +156,8 @@ class MEDIA_EXPORT MediaSourcePlayer : public MediaPlayerAndroid { // Called when the decoder finishes its task. void MediaDecoderCallback( - bool is_audio, const base::TimeDelta& presentation_timestamp, + bool is_audio, bool decode_succeeded, + const base::TimeDelta& presentation_timestamp, const base::Time& wallclock_time, bool end_of_stream); // Handle pending events when all the decoder jobs finished. |