diff options
Diffstat (limited to 'media')
-rw-r--r-- | media/libmediaplayerservice/VideoFrameScheduler.cpp | 18 | ||||
-rw-r--r-- | media/libmediaplayerservice/VideoFrameScheduler.h | 3 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/GenericSource.cpp | 9 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp | 4 | ||||
-rw-r--r-- | media/libstagefright/ACodec.cpp | 21 | ||||
-rw-r--r-- | media/libstagefright/MediaCodec.cpp | 7 | ||||
-rw-r--r-- | media/libstagefright/NuCachedSource2.cpp | 16 | ||||
-rw-r--r-- | media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp | 20 | ||||
-rw-r--r-- | media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp | 14 | ||||
-rw-r--r-- | media/libstagefright/codecs/on2/h264dec/SoftAVC.h | 2 | ||||
-rw-r--r-- | media/libstagefright/data/media_codecs_google_video.xml | 12 | ||||
-rw-r--r-- | media/libstagefright/httplive/LiveSession.cpp | 27 | ||||
-rw-r--r-- | media/libstagefright/include/SoftVideoDecoderOMXComponent.h | 7 | ||||
-rw-r--r-- | media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp | 40 |
14 files changed, 151 insertions, 49 deletions
diff --git a/media/libmediaplayerservice/VideoFrameScheduler.cpp b/media/libmediaplayerservice/VideoFrameScheduler.cpp index 4251c4e..1a5f3e0 100644 --- a/media/libmediaplayerservice/VideoFrameScheduler.cpp +++ b/media/libmediaplayerservice/VideoFrameScheduler.cpp @@ -152,7 +152,7 @@ void VideoFrameScheduler::PLL::test() { #endif -void VideoFrameScheduler::PLL::fit( +bool VideoFrameScheduler::PLL::fit( nsecs_t phase, nsecs_t period, size_t numSamplesToUse, int64_t *a, int64_t *b, int64_t *err) { if (numSamplesToUse > mNumSamples) { @@ -187,6 +187,10 @@ void VideoFrameScheduler::PLL::fit( } int64_t div = numSamplesToUse * sumXX - sumX * sumX; + if (div == 0) { + return false; + } + int64_t a_nom = numSamplesToUse * sumXY - sumX * sumY; int64_t b_nom = sumXX * sumY - sumX * sumXY; *a = divRound(a_nom, div); @@ -198,6 +202,7 @@ void VideoFrameScheduler::PLL::fit( (long long)*a, (*a / (float)(1 << kPrecision)), (long long)*b, (*b / (float)(1 << kPrecision)), (long long)*err, (*err / (float)(1 << (kPrecision * 2)))); + return true; } void VideoFrameScheduler::PLL::prime(size_t numSamplesToUse) { @@ -226,7 +231,7 @@ void VideoFrameScheduler::PLL::prime(size_t numSamplesToUse) { deltas.sort(compare<nsecs_t>); size_t numDeltas = deltas.size(); if (numDeltas > 1) { - nsecs_t deltaMinLimit = min(deltas[0] / kMultiplesThresholdDiv, kMinPeriod); + nsecs_t deltaMinLimit = max(deltas[0] / kMultiplesThresholdDiv, kMinPeriod); nsecs_t deltaMaxLimit = deltas[numDeltas / 2] * kMultiplesThresholdDiv; for (size_t i = numDeltas / 2 + 1; i < numDeltas; ++i) { if (deltas[i] > deltaMaxLimit) { @@ -314,8 +319,15 @@ nsecs_t VideoFrameScheduler::PLL::addSample(nsecs_t time) { if (doFit) { int64_t a, b, err; + if (!fit(mPhase, mPeriod, kMaxSamplesToEstimatePeriod, &a, &b, &err)) { + // samples are not suitable for fitting. this means they are + // also not suitable for priming. + ALOGV("could not fit - keeping old period:%lld", (long long)mPeriod); + return mPeriod; + } + mRefitAt = time + kRefitRefreshPeriod; - fit(mPhase, mPeriod, kMaxSamplesToEstimatePeriod, &a, &b, &err); + mPhase += (mPeriod * b) >> kPrecision; mPeriod = (mPeriod * a) >> kPrecision; ALOGV("new phase:%lld period:%lld", (long long)mPhase, (long long)mPeriod); diff --git a/media/libmediaplayerservice/VideoFrameScheduler.h b/media/libmediaplayerservice/VideoFrameScheduler.h index 19f0787..84b27b4 100644 --- a/media/libmediaplayerservice/VideoFrameScheduler.h +++ b/media/libmediaplayerservice/VideoFrameScheduler.h @@ -71,7 +71,8 @@ private: nsecs_t mTimes[kHistorySize]; void test(); - void fit(nsecs_t phase, nsecs_t period, size_t numSamples, + // returns whether fit was successful + bool fit(nsecs_t phase, nsecs_t period, size_t numSamples, int64_t *a, int64_t *b, int64_t *err); void prime(size_t numSamples); }; diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp index bd75034..f84decd 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp +++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp @@ -1198,10 +1198,17 @@ void NuPlayer::GenericSource::readBuffer( switch (trackType) { case MEDIA_TRACK_TYPE_VIDEO: track = &mVideoTrack; + if (mIsWidevine) { + maxBuffers = 2; + } break; case MEDIA_TRACK_TYPE_AUDIO: track = &mAudioTrack; - maxBuffers = 64; + if (mIsWidevine) { + maxBuffers = 8; + } else { + maxBuffers = 64; + } break; case MEDIA_TRACK_TYPE_SUBTITLE: track = &mSubtitleTrack; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp index ed6f674..1a066b7 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp @@ -53,6 +53,10 @@ NuPlayer::Decoder::Decoder( } NuPlayer::Decoder::~Decoder() { + mDecoderLooper->unregisterHandler(id()); + mDecoderLooper->stop(); + + releaseAndResetMediaBuffers(); } static diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 3c04859..4589ed1 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -2933,13 +2933,6 @@ bool ACodec::describeDefaultColorFormat(DescribeColorFormatParams ¶ms) { image.mNumPlanes = 0; const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat; - // we need stride and slice-height to be non-zero - if (params.nStride == 0 || params.nSliceHeight == 0) { - ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u", - fmt, fmt, params.nStride, params.nSliceHeight); - return false; - } - image.mWidth = params.nFrameWidth; image.mHeight = params.nFrameHeight; @@ -2952,6 +2945,20 @@ bool ACodec::describeDefaultColorFormat(DescribeColorFormatParams ¶ms) { return false; } + // TEMPORARY FIX for some vendors that advertise sliceHeight as 0 + if (params.nStride != 0 && params.nSliceHeight == 0) { + ALOGW("using sliceHeight=%u instead of what codec advertised (=0)", + params.nFrameHeight); + params.nSliceHeight = params.nFrameHeight; + } + + // we need stride and slice-height to be non-zero + if (params.nStride == 0 || params.nSliceHeight == 0) { + ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u", + fmt, fmt, params.nStride, params.nSliceHeight); + return false; + } + // set-up YUV format image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV; image.mNumPlanes = 3; diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp index 6c98c52..b56819c 100644 --- a/media/libstagefright/MediaCodec.cpp +++ b/media/libstagefright/MediaCodec.cpp @@ -589,7 +589,12 @@ status_t MediaCodec::getBufferAndFormat( if (index < buffers->size()) { const BufferInfo &info = buffers->itemAt(index); if (info.mOwnedByClient) { - *buffer = info.mData; + // by the time buffers array is initialized, crypto is set + if (portIndex == kPortIndexInput && mCrypto != NULL) { + *buffer = info.mEncryptedData; + } else { + *buffer = info.mData; + } *format = info.mFormat; } } diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp index be2a873..f469d4d 100644 --- a/media/libstagefright/NuCachedSource2.cpp +++ b/media/libstagefright/NuCachedSource2.cpp @@ -254,6 +254,10 @@ void NuCachedSource2::disconnect() { // set mDisconnecting to true, if a fetch returns after // this, the source will be marked as EOS. mDisconnecting = true; + + // explicitly signal mCondition so that the pending readAt() + // will immediately return + mCondition.signal(); } // explicitly disconnect from the source, to allow any @@ -325,7 +329,11 @@ void NuCachedSource2::fetchInternal() { Mutex::Autolock autoLock(mLock); - if (err == ERROR_UNSUPPORTED || err == -EPIPE) { + if (mDisconnecting) { + mNumRetriesLeft = 0; + mFinalStatus = ERROR_END_OF_STREAM; + return; + } else if (err == ERROR_UNSUPPORTED || err == -EPIPE) { // These are errors that are not likely to go away even if we // retry, i.e. the server doesn't support range requests or similar. mNumRetriesLeft = 0; @@ -515,10 +523,14 @@ ssize_t NuCachedSource2::readAt(off64_t offset, void *data, size_t size) { CHECK(mAsyncResult == NULL); msg->post(); - while (mAsyncResult == NULL) { + while (mAsyncResult == NULL && !mDisconnecting) { mCondition.wait(mLock); } + if (mDisconnecting) { + return ERROR_END_OF_STREAM; + } + int32_t result; CHECK(mAsyncResult->findInt32("result", &result)); diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp index 5b2ab84..d98fa80 100644 --- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp +++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp @@ -295,19 +295,23 @@ bool SoftMPEG4::handlePortSettingsChange() { ALOGV("disp_width = %d, disp_height = %d, buf_width = %d, buf_height = %d", disp_width, disp_height, buf_width, buf_height); - bool cropChanged = false; - if (mCropWidth != disp_width || mCropHeight != disp_height) { - mCropLeft = 0; - mCropTop = 0; - mCropWidth = disp_width; - mCropHeight = disp_height; - cropChanged = true; + CropSettingsMode cropSettingsMode = kCropUnSet; + if (disp_width != buf_width || disp_height != buf_height) { + cropSettingsMode = kCropSet; + + if (mCropWidth != disp_width || mCropHeight != disp_height) { + mCropLeft = 0; + mCropTop = 0; + mCropWidth = disp_width; + mCropHeight = disp_height; + cropSettingsMode = kCropChanged; + } } bool portWillReset = false; const bool fakeStride = true; SoftVideoDecoderOMXComponent::handlePortSettingsChange( - &portWillReset, buf_width, buf_height, cropChanged, fakeStride); + &portWillReset, buf_width, buf_height, cropSettingsMode, fakeStride); if (portWillReset) { if (mMode == MODE_H263) { PVCleanUpVideoDecoder(mHandle); diff --git a/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp b/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp index cf3c3e3..168208f 100644 --- a/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp +++ b/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp @@ -160,10 +160,11 @@ void SoftAVC::onQueueFilled(OMX_U32 /* portIndex */) { H264SwDecInfo decoderInfo; CHECK(H264SwDecGetInfo(mHandle, &decoderInfo) == H264SWDEC_OK); - bool cropChanged = handleCropChange(decoderInfo); + SoftVideoDecoderOMXComponent::CropSettingsMode cropSettingsMode = + handleCropParams(decoderInfo); handlePortSettingsChange( &portWillReset, decoderInfo.picWidth, decoderInfo.picHeight, - cropChanged); + cropSettingsMode); } } else { if (portWillReset) { @@ -209,9 +210,10 @@ void SoftAVC::onQueueFilled(OMX_U32 /* portIndex */) { } } -bool SoftAVC::handleCropChange(const H264SwDecInfo& decInfo) { +SoftVideoDecoderOMXComponent::CropSettingsMode SoftAVC::handleCropParams( + const H264SwDecInfo& decInfo) { if (!decInfo.croppingFlag) { - return false; + return kCropUnSet; } const CropParams& crop = decInfo.cropParams; @@ -219,14 +221,14 @@ bool SoftAVC::handleCropChange(const H264SwDecInfo& decInfo) { mCropTop == crop.cropTopOffset && mCropWidth == crop.cropOutWidth && mCropHeight == crop.cropOutHeight) { - return false; + return kCropSet; } mCropLeft = crop.cropLeftOffset; mCropTop = crop.cropTopOffset; mCropWidth = crop.cropOutWidth; mCropHeight = crop.cropOutHeight; - return true; + return kCropChanged; } void SoftAVC::saveFirstOutputBuffer(int32_t picId, uint8_t *data) { diff --git a/media/libstagefright/codecs/on2/h264dec/SoftAVC.h b/media/libstagefright/codecs/on2/h264dec/SoftAVC.h index 253a406..069107d 100644 --- a/media/libstagefright/codecs/on2/h264dec/SoftAVC.h +++ b/media/libstagefright/codecs/on2/h264dec/SoftAVC.h @@ -73,7 +73,7 @@ private: void drainAllOutputBuffers(bool eos); void drainOneOutputBuffer(int32_t picId, uint8_t *data); void saveFirstOutputBuffer(int32_t pidId, uint8_t *data); - bool handleCropChange(const H264SwDecInfo& decInfo); + CropSettingsMode handleCropParams(const H264SwDecInfo& decInfo); DISALLOW_EVIL_CONSTRUCTORS(SoftAVC); }; diff --git a/media/libstagefright/data/media_codecs_google_video.xml b/media/libstagefright/data/media_codecs_google_video.xml index c97be28..1cbef39 100644 --- a/media/libstagefright/data/media_codecs_google_video.xml +++ b/media/libstagefright/data/media_codecs_google_video.xml @@ -73,22 +73,22 @@ <Encoders> <MediaCodec name="OMX.google.h263.encoder" type="video/3gpp"> <!-- profiles and levels: ProfileBaseline : Level45 --> - <Limit name="size" min="2x2" max="176x144" /> - <Limit name="alignment" value="2x2" /> + <Limit name="size" min="16x16" max="176x144" /> + <Limit name="alignment" value="16x16" /> <Limit name="bitrate" range="1-128000" /> </MediaCodec> <MediaCodec name="OMX.google.h264.encoder" type="video/avc"> <!-- profiles and levels: ProfileBaseline : Level2 --> - <Limit name="size" min="2x2" max="896x896" /> - <Limit name="alignment" value="2x2" /> + <Limit name="size" min="16x16" max="896x896" /> + <Limit name="alignment" value="16x16" /> <Limit name="block-size" value="16x16" /> <Limit name="blocks-per-second" range="1-11880" /> <Limit name="bitrate" range="1-2000000" /> </MediaCodec> <MediaCodec name="OMX.google.mpeg4.encoder" type="video/mp4v-es"> <!-- profiles and levels: ProfileCore : Level2 --> - <Limit name="size" min="2x2" max="176x144" /> - <Limit name="alignment" value="2x2" /> + <Limit name="size" min="16x16" max="176x144" /> + <Limit name="alignment" value="16x16" /> <Limit name="block-size" value="16x16" /> <Limit name="blocks-per-second" range="12-1485" /> <Limit name="bitrate" range="1-64000" /> diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp index a289637..7a9a1a3 100644 --- a/media/libstagefright/httplive/LiveSession.cpp +++ b/media/libstagefright/httplive/LiveSession.cpp @@ -353,10 +353,6 @@ status_t LiveSession::seekTo(int64_t timeUs) { sp<AMessage> response; status_t err = msg->postAndAwaitResponse(&response); - uint32_t replyID; - CHECK(response == mSeekReply && 0 != mSeekReplyID); - mSeekReply.clear(); - mSeekReplyID = 0; return err; } @@ -382,12 +378,16 @@ void LiveSession::onMessageReceived(const sp<AMessage> &msg) { case kWhatSeek: { - CHECK(msg->senderAwaitsResponse(&mSeekReplyID)); + uint32_t seekReplyID; + CHECK(msg->senderAwaitsResponse(&seekReplyID)); + mSeekReplyID = seekReplyID; + mSeekReply = new AMessage; status_t err = onSeek(msg); - mSeekReply = new AMessage; - mSeekReply->setInt32("err", err); + if (err != OK) { + msg->post(50000); + } break; } @@ -422,7 +422,10 @@ void LiveSession::onMessageReceived(const sp<AMessage> &msg) { if (mSeekReplyID != 0) { CHECK(mSeekReply != NULL); + mSeekReply->setInt32("err", OK); mSeekReply->postReply(mSeekReplyID); + mSeekReplyID = 0; + mSeekReply.clear(); } } } @@ -1094,10 +1097,11 @@ status_t LiveSession::onSeek(const sp<AMessage> &msg) { CHECK(msg->findInt64("timeUs", &timeUs)); if (!mReconfigurationInProgress) { - changeConfiguration(timeUs, getBandwidthIndex()); + changeConfiguration(timeUs, mCurBandwidthIndex); + return OK; + } else { + return -EWOULDBLOCK; } - - return OK; } status_t LiveSession::getDuration(int64_t *durationUs) const { @@ -1254,7 +1258,10 @@ void LiveSession::changeConfiguration( if (mSeekReplyID != 0) { CHECK(mSeekReply != NULL); + mSeekReply->setInt32("err", OK); mSeekReply->postReply(mSeekReplyID); + mSeekReplyID = 0; + mSeekReply.clear(); } } } diff --git a/media/libstagefright/include/SoftVideoDecoderOMXComponent.h b/media/libstagefright/include/SoftVideoDecoderOMXComponent.h index 37b1fe1..9e97ebd 100644 --- a/media/libstagefright/include/SoftVideoDecoderOMXComponent.h +++ b/media/libstagefright/include/SoftVideoDecoderOMXComponent.h @@ -68,9 +68,14 @@ protected: uint32_t outputBufferWidth(); uint32_t outputBufferHeight(); + enum CropSettingsMode { + kCropUnSet = 0, + kCropSet, + kCropChanged, + }; void handlePortSettingsChange( bool *portWillReset, uint32_t width, uint32_t height, - bool cropChanged = false, bool fakeStride = false); + CropSettingsMode cropSettingsMode = kCropUnSet, bool fakeStride = false); void copyYV12FrameToOutputBuffer( uint8_t *dst, const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV, diff --git a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp index 5853469..3d20a79 100644 --- a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp +++ b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp @@ -160,15 +160,17 @@ uint32_t SoftVideoDecoderOMXComponent::outputBufferHeight() { } void SoftVideoDecoderOMXComponent::handlePortSettingsChange( - bool *portWillReset, uint32_t width, uint32_t height, bool cropChanged, bool fakeStride) { + bool *portWillReset, uint32_t width, uint32_t height, + CropSettingsMode cropSettingsMode, bool fakeStride) { *portWillReset = false; bool sizeChanged = (width != mWidth || height != mHeight); + bool updateCrop = (cropSettingsMode == kCropUnSet); + bool cropChanged = (cropSettingsMode == kCropChanged); if (sizeChanged || cropChanged) { mWidth = width; mHeight = height; - bool updateCrop = !cropChanged; if ((sizeChanged && !mIsAdaptive) || width > mAdaptiveMaxWidth || height > mAdaptiveMaxHeight) { @@ -343,6 +345,40 @@ OMX_ERRORTYPE SoftVideoDecoderOMXComponent::internalSetParameter( return OMX_ErrorNone; } + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *newParams = + (OMX_PARAM_PORTDEFINITIONTYPE *)params; + OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &newParams->format.video; + OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(newParams->nPortIndex)->mDef; + + uint32_t oldWidth = def->format.video.nFrameWidth; + uint32_t oldHeight = def->format.video.nFrameHeight; + uint32_t newWidth = video_def->nFrameWidth; + uint32_t newHeight = video_def->nFrameHeight; + if (newWidth != oldWidth || newHeight != oldHeight) { + bool outputPort = (newParams->nPortIndex == kOutputPortIndex); + def->format.video.nFrameWidth = + (mIsAdaptive && outputPort) ? mAdaptiveMaxWidth : newWidth; + def->format.video.nFrameHeight = + (mIsAdaptive && outputPort) ? mAdaptiveMaxHeight : newHeight; + def->format.video.nStride = def->format.video.nFrameWidth; + def->format.video.nSliceHeight = def->format.video.nFrameHeight; + def->nBufferSize = + def->format.video.nFrameWidth * def->format.video.nFrameHeight * 3 / 2; + if (outputPort) { + mWidth = newWidth; + mHeight = newHeight; + mCropLeft = 0; + mCropTop = 0; + mCropWidth = newWidth; + mCropHeight = newHeight; + } + newParams->nBufferSize = def->nBufferSize; + } + return SimpleSoftOMXComponent::internalSetParameter(index, params); + } + default: return SimpleSoftOMXComponent::internalSetParameter(index, params); } |