From 2b82e9652ba049e754c2cc74e381282f231d5fbf Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Wed, 6 Oct 2010 16:43:57 -0700 Subject: On this particular device the hardware video decoder spits out buffers that don't actually contain our video data, so we cannot use them to restore the video frame after suspend/resume. Change-Id: I1b8fe68c1766299844fe84ebbff49cb8b3e4cc7c related-to-bug: 3070094 --- media/libstagefright/AwesomePlayer.cpp | 37 ++++++++++++++-------- media/libstagefright/OMXCodec.cpp | 16 ++++++++-- .../StagefrightMetadataRetriever.cpp | 14 ++++++++ 3 files changed, 51 insertions(+), 16 deletions(-) (limited to 'media') diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index bfc23d4..3d0d108 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -1571,21 +1571,30 @@ status_t AwesomePlayer::suspend() { if (mLastVideoBuffer) { size_t size = mLastVideoBuffer->range_length(); + if (size) { - state->mLastVideoFrameSize = size; - state->mLastVideoFrame = malloc(size); - memcpy(state->mLastVideoFrame, - (const uint8_t *)mLastVideoBuffer->data() - + mLastVideoBuffer->range_offset(), - size); - - state->mVideoWidth = mVideoWidth; - state->mVideoHeight = mVideoHeight; - - sp meta = mVideoSource->getFormat(); - CHECK(meta->findInt32(kKeyColorFormat, &state->mColorFormat)); - CHECK(meta->findInt32(kKeyWidth, &state->mDecodedWidth)); - CHECK(meta->findInt32(kKeyHeight, &state->mDecodedHeight)); + int32_t unreadable; + if (!mLastVideoBuffer->meta_data()->findInt32( + kKeyIsUnreadable, &unreadable) + || unreadable == 0) { + state->mLastVideoFrameSize = size; + state->mLastVideoFrame = malloc(size); + memcpy(state->mLastVideoFrame, + (const uint8_t *)mLastVideoBuffer->data() + + mLastVideoBuffer->range_offset(), + size); + + state->mVideoWidth = mVideoWidth; + state->mVideoHeight = mVideoHeight; + + sp meta = mVideoSource->getFormat(); + CHECK(meta->findInt32(kKeyColorFormat, &state->mColorFormat)); + CHECK(meta->findInt32(kKeyWidth, &state->mDecodedWidth)); + CHECK(meta->findInt32(kKeyHeight, &state->mDecodedHeight)); + } else { + LOGV("Unable to save last video frame, we have no access to " + "the decoded video data."); + } } } diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index 76c8870..e6cdac1 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -346,7 +346,8 @@ static int CompareSoftwareCodecsFirst( } // static -uint32_t OMXCodec::getComponentQuirks(const char *componentName) { +uint32_t OMXCodec::getComponentQuirks( + const char *componentName, bool isEncoder) { uint32_t quirks = 0; if (!strcmp(componentName, "OMX.PV.avcdec")) { @@ -404,6 +405,13 @@ uint32_t OMXCodec::getComponentQuirks(const char *componentName) { quirks |= kInputBufferSizesAreBogus; } + if (!strncmp(componentName, "OMX.SEC.", 8) && !isEncoder) { + // These output buffers contain no video data, just some + // opaque information that allows the overlay to display their + // contents. + quirks |= kOutputBuffersAreUnreadable; + } + return quirks; } @@ -490,7 +498,7 @@ sp OMXCodec::Create( LOGV("Successfully allocated OMX node '%s'", componentName); sp codec = new OMXCodec( - omx, node, getComponentQuirks(componentName), + omx, node, getComponentQuirks(componentName, createEncoder), createEncoder, mime, componentName, source); @@ -1747,6 +1755,10 @@ void OMXCodec::on_message(const omx_message &msg) { buffer->meta_data()->setInt32(kKeyIsCodecConfig, true); } + if (mQuirks & kOutputBuffersAreUnreadable) { + buffer->meta_data()->setInt32(kKeyIsUnreadable, true); + } + buffer->meta_data()->setPointer( kKeyPlatformPrivate, msg.u.extended_buffer_data.platform_private); diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp index 9d89c20..af9c70c 100644 --- a/media/libstagefright/StagefrightMetadataRetriever.cpp +++ b/media/libstagefright/StagefrightMetadataRetriever.cpp @@ -159,6 +159,20 @@ static VideoFrame *extractVideoFrameWithCodecFlags( LOGV("successfully decoded video frame."); + int32_t unreadable; + if (buffer->meta_data()->findInt32(kKeyIsUnreadable, &unreadable) + && unreadable != 0) { + LOGV("video frame is unreadable, decoder does not give us access " + "to the video data."); + + buffer->release(); + buffer = NULL; + + decoder->stop(); + + return NULL; + } + int64_t timeUs; CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs)); if (thumbNailTime >= 0) { -- cgit v1.1