summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorqinmin@chromium.org <qinmin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-29 14:35:26 +0000
committerqinmin@chromium.org <qinmin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-29 14:35:26 +0000
commit6e206fadeaac18ef6fcf1a3cc924732aa08312bd (patch)
tree0279e6b4c3ac16af7f48d65830ceaccb2c1cb1fc /media
parent189c1a51ed7fa9f2d0bf35970cef48ebbd8c19b5 (diff)
downloadchromium_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.java15
-rw-r--r--media/base/android/media_codec_bridge.h1
-rw-r--r--media/base/android/media_source_player.cc20
-rw-r--r--media/base/android/media_source_player.h12
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.