diff options
Diffstat (limited to 'media')
-rw-r--r-- | media/libmedia/AudioTrack.cpp | 3 | ||||
-rw-r--r-- | media/libstagefright/ACodec.cpp | 41 | ||||
-rw-r--r-- | media/libstagefright/MediaCodec.cpp | 12 | ||||
-rwxr-xr-x | media/libstagefright/OMXCodec.cpp | 36 | ||||
-rw-r--r-- | media/libstagefright/StagefrightMetadataRetriever.cpp | 37 | ||||
-rw-r--r-- | media/libstagefright/wifi-display/source/Converter.cpp | 21 | ||||
-rw-r--r-- | media/libstagefright/wifi-display/source/Converter.h | 6 | ||||
-rw-r--r-- | media/libstagefright/wifi-display/source/PlaybackSession.cpp | 8 | ||||
-rw-r--r-- | media/libstagefright/wifi-display/source/PlaybackSession.h | 2 | ||||
-rw-r--r-- | media/libstagefright/wifi-display/source/WifiDisplaySource.cpp | 3 |
10 files changed, 158 insertions, 11 deletions
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index d9d8aee..362d022 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -279,8 +279,7 @@ status_t AudioTrack::set( mCbf = cbf; if (cbf != NULL) { - //FIXME ignoring threadCanCallJava to work around track recreation issue - mAudioTrackThread = new AudioTrackThread(*this, true /*threadCanCallJava*/); + mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava); mAudioTrackThread->run("AudioTrack", ANDROID_PRIORITY_AUDIO, 0 /*stack*/); } diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 3dd5d60..8190498 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -34,6 +34,8 @@ #include <OMX_Component.h> +#include "include/avc_utils.h" + namespace android { template<class T> @@ -401,6 +403,10 @@ void ACodec::initiateShutdown(bool keepComponentAllocated) { msg->post(); } +void ACodec::signalRequestIDRFrame() { + (new AMessage(kWhatRequestIDRFrame, id()))->post(); +} + status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) { CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); @@ -2284,6 +2290,24 @@ error: ACodec::PortDescription::PortDescription() { } +status_t ACodec::requestIDRFrame() { + if (!mIsEncoder) { + return ERROR_UNSUPPORTED; + } + + OMX_CONFIG_INTRAREFRESHVOPTYPE params; + InitOMXParams(¶ms); + + params.nPortIndex = kPortIndexOutput; + params.IntraRefreshVOP = OMX_TRUE; + + return mOMX->setConfig( + mNode, + OMX_IndexConfigVideoIntraVOPRefresh, + ¶ms, + sizeof(params)); +} + void ACodec::PortDescription::addBuffer( IOMX::buffer_id id, const sp<ABuffer> &buffer) { mBufferIDs.push_back(id); @@ -2737,6 +2761,12 @@ bool ACodec::BaseState::onOMXFillBufferDone( if (mCodec->mNativeWindow == NULL) { info->mData->setRange(rangeOffset, rangeLength); + +#if 0 + if (IsIDR(info->mData)) { + ALOGI("IDR frame"); + } +#endif } if (mCodec->mSkipCutBuffer != NULL) { @@ -3400,6 +3430,17 @@ bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) { break; } + case kWhatRequestIDRFrame: + { + status_t err = mCodec->requestIDRFrame(); + if (err != OK) { + ALOGW("Requesting an IDR frame failed."); + } + + handled = true; + break; + } + default: handled = BaseState::onMessageReceived(msg); break; diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp index 2060699..7f97430 100644 --- a/media/libstagefright/MediaCodec.cpp +++ b/media/libstagefright/MediaCodec.cpp @@ -327,6 +327,12 @@ status_t MediaCodec::flush() { return PostAndAwaitResponse(msg, &response); } +status_t MediaCodec::requestIDRFrame() { + (new AMessage(kWhatRequestIDRFrame, id()))->post(); + + return OK; +} + //////////////////////////////////////////////////////////////////////////////// void MediaCodec::cancelPendingDequeueOperations() { @@ -1133,6 +1139,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { break; } + case kWhatRequestIDRFrame: + { + mCodec->signalRequestIDRFrame(); + break; + } + default: TRESPASS(); } diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index d0e306c..07f92c7 100755 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -546,12 +546,8 @@ status_t OMXCodec::configureCodec(const sp<MetaData> &meta) { if (mIsEncoder) { setVideoInputFormat(mMIME, meta); } else { - int32_t width, height; - bool success = meta->findInt32(kKeyWidth, &width); - success = success && meta->findInt32(kKeyHeight, &height); - CHECK(success); status_t err = setVideoOutputFormat( - mMIME, width, height); + mMIME, meta); if (err != OK) { return err; @@ -894,7 +890,7 @@ static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) { } else if (iFramesInterval == 0) { return 0; } - OMX_U32 ret = frameRate * iFramesInterval; + OMX_U32 ret = frameRate * iFramesInterval - 1; CHECK(ret > 1); return ret; } @@ -1172,7 +1168,13 @@ status_t OMXCodec::setupAVCEncoderParameters(const sp<MetaData>& meta) { } status_t OMXCodec::setVideoOutputFormat( - const char *mime, OMX_U32 width, OMX_U32 height) { + const char *mime, const sp<MetaData>& meta) { + + int32_t width, height; + bool success = meta->findInt32(kKeyWidth, &width); + success = success && meta->findInt32(kKeyHeight, &height); + CHECK(success); + CODEC_LOGV("setVideoOutputFormat width=%ld, height=%ld", width, height); OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused; @@ -1218,6 +1220,26 @@ status_t OMXCodec::setVideoOutputFormat( || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar || format.eColorFormat == OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka); + int32_t colorFormat; + if (meta->findInt32(kKeyColorFormat, &colorFormat) + && colorFormat != OMX_COLOR_FormatUnused + && colorFormat != format.eColorFormat) { + + while (OMX_ErrorNoMore != err) { + format.nIndex++; + err = mOMX->getParameter( + mNode, OMX_IndexParamVideoPortFormat, + &format, sizeof(format)); + if (format.eColorFormat == colorFormat) { + break; + } + } + if (format.eColorFormat != colorFormat) { + CODEC_LOGE("Color format %d is not supported", colorFormat); + return ERROR_UNSUPPORTED; + } + } + err = mOMX->setParameter( mNode, OMX_IndexParamVideoPortFormat, &format, sizeof(format)); diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp index c9ef4d9..a2f3f13 100644 --- a/media/libstagefright/StagefrightMetadataRetriever.cpp +++ b/media/libstagefright/StagefrightMetadataRetriever.cpp @@ -110,6 +110,31 @@ status_t StagefrightMetadataRetriever::setDataSource( return OK; } +static bool isYUV420PlanarSupported( + OMXClient *client, + const sp<MetaData> &trackMeta) { + + const char *mime; + CHECK(trackMeta->findCString(kKeyMIMEType, &mime)); + + Vector<CodecCapabilities> caps; + if (QueryCodecs(client->interface(), mime, + true, /* queryDecoders */ + true, /* hwCodecOnly */ + &caps) == OK) { + + for (size_t j = 0; j < caps.size(); ++j) { + CodecCapabilities cap = caps[j]; + for (size_t i = 0; i < cap.mColorFormats.size(); ++i) { + if (cap.mColorFormats[i] == OMX_COLOR_FormatYUV420Planar) { + return true; + } + } + } + } + return false; +} + static VideoFrame *extractVideoFrameWithCodecFlags( OMXClient *client, const sp<MetaData> &trackMeta, @@ -117,9 +142,19 @@ static VideoFrame *extractVideoFrameWithCodecFlags( uint32_t flags, int64_t frameTimeUs, int seekMode) { + + sp<MetaData> format = source->getFormat(); + + // XXX: + // Once all vendors support OMX_COLOR_FormatYUV420Planar, we can + // remove this check and always set the decoder output color format + if (isYUV420PlanarSupported(client, trackMeta)) { + format->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420Planar); + } + sp<MediaSource> decoder = OMXCodec::Create( - client->interface(), source->getFormat(), false, source, + client->interface(), format, false, source, NULL, flags | OMXCodec::kClientNeedsFramebuffer); if (decoder.get() == NULL) { diff --git a/media/libstagefright/wifi-display/source/Converter.cpp b/media/libstagefright/wifi-display/source/Converter.cpp index c4845e3..390b2e2 100644 --- a/media/libstagefright/wifi-display/source/Converter.cpp +++ b/media/libstagefright/wifi-display/source/Converter.cpp @@ -40,7 +40,15 @@ Converter::Converter( mNotify(notify), mCodecLooper(codecLooper), mInputFormat(format), + mIsVideo(false), mDoMoreWorkPending(false) { + AString mime; + CHECK(mInputFormat->findString("mime", &mime)); + + if (!strncasecmp("video/", mime.c_str(), 6)) { + mIsVideo = true; + } + mInitCheck = initEncoder(); } @@ -202,6 +210,15 @@ void Converter::onMessageReceived(const sp<AMessage> &msg) { break; } + case kWhatRequestIDRFrame: + { + if (mIsVideo) { + ALOGI("requesting IDR frame"); + mEncoder->requestIDRFrame(); + } + break; + } + default: TRESPASS(); } @@ -306,5 +323,9 @@ status_t Converter::doMoreWork() { return err; } +void Converter::requestIDRFrame() { + (new AMessage(kWhatRequestIDRFrame, id()))->post(); +} + } // namespace android diff --git a/media/libstagefright/wifi-display/source/Converter.h b/media/libstagefright/wifi-display/source/Converter.h index 67471c7..901ae2e 100644 --- a/media/libstagefright/wifi-display/source/Converter.h +++ b/media/libstagefright/wifi-display/source/Converter.h @@ -43,6 +43,8 @@ struct Converter : public AHandler { void feedAccessUnit(const sp<ABuffer> &accessUnit); void signalEOS(); + void requestIDRFrame(); + enum { kWhatAccessUnit, kWhatEOS, @@ -57,13 +59,15 @@ private: enum { kWhatFeedAccessUnit, kWhatInputEOS, - kWhatDoMoreWork + kWhatDoMoreWork, + kWhatRequestIDRFrame, }; status_t mInitCheck; sp<AMessage> mNotify; sp<ALooper> mCodecLooper; sp<AMessage> mInputFormat; + bool mIsVideo; sp<AMessage> mOutputFormat; sp<MediaCodec> mEncoder; diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp index c38a300..f6f7030 100644 --- a/media/libstagefright/wifi-display/source/PlaybackSession.cpp +++ b/media/libstagefright/wifi-display/source/PlaybackSession.cpp @@ -1164,5 +1164,13 @@ status_t WifiDisplaySource::PlaybackSession::parseTSFB( return OK; } +void WifiDisplaySource::PlaybackSession::requestIDRFrame() { + for (size_t i = 0; i < mTracks.size(); ++i) { + const sp<Track> &track = mTracks.valueAt(i); + + track->converter()->requestIDRFrame(); + } +} + } // namespace android diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.h b/media/libstagefright/wifi-display/source/PlaybackSession.h index 88f6ea9..8b6ddee 100644 --- a/media/libstagefright/wifi-display/source/PlaybackSession.h +++ b/media/libstagefright/wifi-display/source/PlaybackSession.h @@ -58,6 +58,8 @@ struct WifiDisplaySource::PlaybackSession : public AHandler { int32_t width() const; int32_t height() const; + void requestIDRFrame(); + enum { kWhatSessionDead, kWhatBinaryData, diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp index aeefcf3..53adb87 100644 --- a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp +++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp @@ -984,6 +984,9 @@ void WifiDisplaySource::onSetParameterRequest( } #endif + // XXX check that the parameter is about that. + playbackSession->requestIDRFrame(); + playbackSession->updateLiveness(); AString response = "RTSP/1.0 200 OK\r\n"; |