Loading include/media/stagefright/MediaErrors.h +1 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ enum { // Not technically an error. INFO_FORMAT_CHANGED = MEDIA_ERROR_BASE - 12, INFO_DISCONTINUITY = MEDIA_ERROR_BASE - 13, }; } // namespace android Loading include/media/stagefright/MetaData.h +2 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,8 @@ enum { kKeyAutoLoop = 'autL', // bool (int32_t) kKeyValidSamples = 'valD', // int32_t kKeyIsUnreadable = 'unre', // bool (int32_t) }; enum { Loading include/media/stagefright/OMXCodec.h +6 −3 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ struct OMXCodec : public MediaSource, public MediaBufferObserver { enum CreationFlags { kPreferSoftwareCodecs = 1, kIgnoreCodecSpecificData = 2 }; static sp<MediaSource> Create( const sp<IOMX> &omx, Loading Loading @@ -103,6 +104,7 @@ private: kSupportsMultipleFramesPerInputBuffer = 1024, kAvoidMemcopyInputRecordingFrames = 2048, kRequiresLargerEncoderOutputBuffer = 4096, kOutputBuffersAreUnreadable = 8192, }; struct BufferInfo { Loading Loading @@ -247,9 +249,10 @@ private: void dumpPortStatus(OMX_U32 portIndex); status_t configureCodec(const sp<MetaData> &meta); status_t configureCodec(const sp<MetaData> &meta, uint32_t flags); static uint32_t getComponentQuirks(const char *componentName); static uint32_t getComponentQuirks( const char *componentName, bool isEncoder); static void findMatchingCodecs( const char *mime, Loading media/libstagefright/AwesomePlayer.cpp +72 −17 Original line number Diff line number Diff line Loading @@ -561,6 +561,39 @@ void AwesomePlayer::onBufferingUpdate() { postBufferingEvent_l(); } void AwesomePlayer::partial_reset_l() { // Only reset the video renderer and shut down the video decoder. // Then instantiate a new video decoder and resume video playback. mVideoRenderer.clear(); if (mLastVideoBuffer) { mLastVideoBuffer->release(); mLastVideoBuffer = NULL; } if (mVideoBuffer) { mVideoBuffer->release(); mVideoBuffer = NULL; } { mVideoSource->stop(); // The following hack is necessary to ensure that the OMX // component is completely released by the time we may try // to instantiate it again. wp<MediaSource> tmp = mVideoSource; mVideoSource.clear(); while (tmp.promote() != NULL) { usleep(1000); } IPCThreadState::self()->flushCommands(); } CHECK_EQ(OK, initVideoDecoder(OMXCodec::kIgnoreCodecSpecificData)); } void AwesomePlayer::onStreamDone() { // Posted whenever any stream finishes playing. Loading @@ -570,7 +603,21 @@ void AwesomePlayer::onStreamDone() { } mStreamDoneEventPending = false; if (mStreamDoneStatus != ERROR_END_OF_STREAM) { if (mStreamDoneStatus == INFO_DISCONTINUITY) { // This special status is returned because an http live stream's // video stream switched to a different bandwidth at this point // and future data may have been encoded using different parameters. // This requires us to shutdown the video decoder and reinstantiate // a fresh one. LOGV("INFO_DISCONTINUITY"); CHECK(mVideoSource != NULL); partial_reset_l(); postVideoEvent_l(); return; } else if (mStreamDoneStatus != ERROR_END_OF_STREAM) { LOGV("MEDIA_ERROR %d", mStreamDoneStatus); notifyListener_l( Loading Loading @@ -939,8 +986,7 @@ void AwesomePlayer::setVideoSource(sp<MediaSource> source) { mVideoTrack = source; } status_t AwesomePlayer::initVideoDecoder() { uint32_t flags = 0; status_t AwesomePlayer::initVideoDecoder(uint32_t flags) { mVideoSource = OMXCodec::Create( mClient.interface(), mVideoTrack->getFormat(), false, // createEncoder Loading Loading @@ -1571,7 +1617,12 @@ status_t AwesomePlayer::suspend() { if (mLastVideoBuffer) { size_t size = mLastVideoBuffer->range_length(); if (size) { int32_t unreadable; if (!mLastVideoBuffer->meta_data()->findInt32( kKeyIsUnreadable, &unreadable) || unreadable == 0) { state->mLastVideoFrameSize = size; state->mLastVideoFrame = malloc(size); memcpy(state->mLastVideoFrame, Loading @@ -1586,6 +1637,10 @@ status_t AwesomePlayer::suspend() { 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."); } } } Loading media/libstagefright/OMXCodec.cpp +81 −67 Original line number Diff line number Diff line Loading @@ -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")) { Loading Loading @@ -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; } Loading Loading @@ -490,13 +498,13 @@ sp<MediaSource> OMXCodec::Create( LOGV("Successfully allocated OMX node '%s'", componentName); sp<OMXCodec> codec = new OMXCodec( omx, node, getComponentQuirks(componentName), omx, node, getComponentQuirks(componentName, createEncoder), createEncoder, mime, componentName, source); observer->setCodec(codec); err = codec->configureCodec(meta); err = codec->configureCodec(meta, flags); if (err == OK) { return codec; Loading @@ -509,7 +517,8 @@ sp<MediaSource> OMXCodec::Create( return NULL; } status_t OMXCodec::configureCodec(const sp<MetaData> &meta) { status_t OMXCodec::configureCodec(const sp<MetaData> &meta, uint32_t flags) { if (!(flags & kIgnoreCodecSpecificData)) { uint32_t type; const void *data; size_t size; Loading Loading @@ -598,6 +607,7 @@ status_t OMXCodec::configureCodec(const sp<MetaData> &meta) { return ERROR_UNSUPPORTED; } } } int32_t bitRate = 0; if (mIsEncoder) { Loading Loading @@ -1747,6 +1757,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); Loading Loading
include/media/stagefright/MediaErrors.h +1 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ enum { // Not technically an error. INFO_FORMAT_CHANGED = MEDIA_ERROR_BASE - 12, INFO_DISCONTINUITY = MEDIA_ERROR_BASE - 13, }; } // namespace android Loading
include/media/stagefright/MetaData.h +2 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,8 @@ enum { kKeyAutoLoop = 'autL', // bool (int32_t) kKeyValidSamples = 'valD', // int32_t kKeyIsUnreadable = 'unre', // bool (int32_t) }; enum { Loading
include/media/stagefright/OMXCodec.h +6 −3 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ struct OMXCodec : public MediaSource, public MediaBufferObserver { enum CreationFlags { kPreferSoftwareCodecs = 1, kIgnoreCodecSpecificData = 2 }; static sp<MediaSource> Create( const sp<IOMX> &omx, Loading Loading @@ -103,6 +104,7 @@ private: kSupportsMultipleFramesPerInputBuffer = 1024, kAvoidMemcopyInputRecordingFrames = 2048, kRequiresLargerEncoderOutputBuffer = 4096, kOutputBuffersAreUnreadable = 8192, }; struct BufferInfo { Loading Loading @@ -247,9 +249,10 @@ private: void dumpPortStatus(OMX_U32 portIndex); status_t configureCodec(const sp<MetaData> &meta); status_t configureCodec(const sp<MetaData> &meta, uint32_t flags); static uint32_t getComponentQuirks(const char *componentName); static uint32_t getComponentQuirks( const char *componentName, bool isEncoder); static void findMatchingCodecs( const char *mime, Loading
media/libstagefright/AwesomePlayer.cpp +72 −17 Original line number Diff line number Diff line Loading @@ -561,6 +561,39 @@ void AwesomePlayer::onBufferingUpdate() { postBufferingEvent_l(); } void AwesomePlayer::partial_reset_l() { // Only reset the video renderer and shut down the video decoder. // Then instantiate a new video decoder and resume video playback. mVideoRenderer.clear(); if (mLastVideoBuffer) { mLastVideoBuffer->release(); mLastVideoBuffer = NULL; } if (mVideoBuffer) { mVideoBuffer->release(); mVideoBuffer = NULL; } { mVideoSource->stop(); // The following hack is necessary to ensure that the OMX // component is completely released by the time we may try // to instantiate it again. wp<MediaSource> tmp = mVideoSource; mVideoSource.clear(); while (tmp.promote() != NULL) { usleep(1000); } IPCThreadState::self()->flushCommands(); } CHECK_EQ(OK, initVideoDecoder(OMXCodec::kIgnoreCodecSpecificData)); } void AwesomePlayer::onStreamDone() { // Posted whenever any stream finishes playing. Loading @@ -570,7 +603,21 @@ void AwesomePlayer::onStreamDone() { } mStreamDoneEventPending = false; if (mStreamDoneStatus != ERROR_END_OF_STREAM) { if (mStreamDoneStatus == INFO_DISCONTINUITY) { // This special status is returned because an http live stream's // video stream switched to a different bandwidth at this point // and future data may have been encoded using different parameters. // This requires us to shutdown the video decoder and reinstantiate // a fresh one. LOGV("INFO_DISCONTINUITY"); CHECK(mVideoSource != NULL); partial_reset_l(); postVideoEvent_l(); return; } else if (mStreamDoneStatus != ERROR_END_OF_STREAM) { LOGV("MEDIA_ERROR %d", mStreamDoneStatus); notifyListener_l( Loading Loading @@ -939,8 +986,7 @@ void AwesomePlayer::setVideoSource(sp<MediaSource> source) { mVideoTrack = source; } status_t AwesomePlayer::initVideoDecoder() { uint32_t flags = 0; status_t AwesomePlayer::initVideoDecoder(uint32_t flags) { mVideoSource = OMXCodec::Create( mClient.interface(), mVideoTrack->getFormat(), false, // createEncoder Loading Loading @@ -1571,7 +1617,12 @@ status_t AwesomePlayer::suspend() { if (mLastVideoBuffer) { size_t size = mLastVideoBuffer->range_length(); if (size) { int32_t unreadable; if (!mLastVideoBuffer->meta_data()->findInt32( kKeyIsUnreadable, &unreadable) || unreadable == 0) { state->mLastVideoFrameSize = size; state->mLastVideoFrame = malloc(size); memcpy(state->mLastVideoFrame, Loading @@ -1586,6 +1637,10 @@ status_t AwesomePlayer::suspend() { 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."); } } } Loading
media/libstagefright/OMXCodec.cpp +81 −67 Original line number Diff line number Diff line Loading @@ -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")) { Loading Loading @@ -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; } Loading Loading @@ -490,13 +498,13 @@ sp<MediaSource> OMXCodec::Create( LOGV("Successfully allocated OMX node '%s'", componentName); sp<OMXCodec> codec = new OMXCodec( omx, node, getComponentQuirks(componentName), omx, node, getComponentQuirks(componentName, createEncoder), createEncoder, mime, componentName, source); observer->setCodec(codec); err = codec->configureCodec(meta); err = codec->configureCodec(meta, flags); if (err == OK) { return codec; Loading @@ -509,7 +517,8 @@ sp<MediaSource> OMXCodec::Create( return NULL; } status_t OMXCodec::configureCodec(const sp<MetaData> &meta) { status_t OMXCodec::configureCodec(const sp<MetaData> &meta, uint32_t flags) { if (!(flags & kIgnoreCodecSpecificData)) { uint32_t type; const void *data; size_t size; Loading Loading @@ -598,6 +607,7 @@ status_t OMXCodec::configureCodec(const sp<MetaData> &meta) { return ERROR_UNSUPPORTED; } } } int32_t bitRate = 0; if (mIsEncoder) { Loading Loading @@ -1747,6 +1757,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); Loading