diff options
Diffstat (limited to 'media')
-rw-r--r-- | media/libmedia/AudioTrack.cpp | 6 | ||||
-rw-r--r-- | media/libmedia/AudioTrackShared.cpp | 2 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerFactory.cpp | 35 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/GenericSource.cpp | 58 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/GenericSource.h | 2 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp | 1 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp | 1 | ||||
-rw-r--r-- | media/libstagefright/ACodec.cpp | 7 |
8 files changed, 92 insertions, 20 deletions
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index 4a6df6d..e4c3c08 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -1226,7 +1226,11 @@ status_t AudioTrack::createTrack_l() mStaticProxy = new StaticAudioTrackClientProxy(cblk, buffers, frameCount, mFrameSizeAF); mProxy = mStaticProxy; } - mProxy->setVolumeLR(GAIN_MINIFLOAT_PACKED_UNITY); + + mProxy->setVolumeLR(gain_minifloat_pack( + gain_from_float(mVolume[AUDIO_INTERLEAVE_LEFT]), + gain_from_float(mVolume[AUDIO_INTERLEAVE_RIGHT]))); + mProxy->setSendLevel(mSendLevel); mProxy->setSampleRate(mSampleRate); mProxy->setMinimum(mNotificationFramesAct); diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libmedia/AudioTrackShared.cpp index 4a783b3..ff24475 100644 --- a/media/libmedia/AudioTrackShared.cpp +++ b/media/libmedia/AudioTrackShared.cpp @@ -307,6 +307,7 @@ void ClientProxy::binderDied() { audio_track_cblk_t* cblk = mCblk; if (!(android_atomic_or(CBLK_INVALID, &cblk->mFlags) & CBLK_INVALID)) { + android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex); // it seems that a FUTEX_WAKE_PRIVATE will not wake a FUTEX_WAIT, even within same process (void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE, 1); @@ -317,6 +318,7 @@ void ClientProxy::interrupt() { audio_track_cblk_t* cblk = mCblk; if (!(android_atomic_or(CBLK_INTERRUPT, &cblk->mFlags) & CBLK_INTERRUPT)) { + android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex); (void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE, 1); } diff --git a/media/libmediaplayerservice/MediaPlayerFactory.cpp b/media/libmediaplayerservice/MediaPlayerFactory.cpp index 3e0fc0d..aeefb4c 100644 --- a/media/libmediaplayerservice/MediaPlayerFactory.cpp +++ b/media/libmediaplayerservice/MediaPlayerFactory.cpp @@ -20,9 +20,12 @@ #include <cutils/properties.h> #include <media/IMediaPlayer.h> +#include <media/stagefright/DataSource.h> +#include <media/stagefright/FileSource.h> #include <media/stagefright/foundation/ADebug.h> #include <utils/Errors.h> #include <utils/misc.h> +#include <../libstagefright/include/WVMExtractor.h> #include "MediaPlayerFactory.h" @@ -179,10 +182,18 @@ class StagefrightPlayerFactory : virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, int fd, int64_t offset, - int64_t /*length*/, + int64_t length, float /*curScore*/) { - if (getDefaultPlayerType() - == STAGEFRIGHT_PLAYER) { + if (legacyDrm()) { + sp<DataSource> source = new FileSource(dup(fd), offset, length); + String8 mimeType; + float confidence; + if (SniffWVM(source, &mimeType, &confidence, NULL /* format */)) { + return 1.0; + } + } + + if (getDefaultPlayerType() == STAGEFRIGHT_PLAYER) { char buf[20]; lseek(fd, offset, SEEK_SET); read(fd, buf, sizeof(buf)); @@ -198,10 +209,28 @@ class StagefrightPlayerFactory : return 0.0; } + virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, + const char* url, + float /*curScore*/) { + if (legacyDrm() && !strncasecmp("widevine://", url, 11)) { + return 1.0; + } + return 0.0; + } + virtual sp<MediaPlayerBase> createPlayer() { ALOGV(" create StagefrightPlayer"); return new StagefrightPlayer(); } + private: + bool legacyDrm() { + char value[PROPERTY_VALUE_MAX]; + if (property_get("persist.sys.media.legacy-drm", value, NULL) + && (!strcmp("1", value) || !strcasecmp("true", value))) { + return true; + } + return false; + } }; class NuPlayerFactory : public MediaPlayerFactory::IFactory { diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp index e7a26b6..1af2713 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp +++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp @@ -54,6 +54,7 @@ NuPlayer::GenericSource::GenericSource( mDurationUs(0ll), mAudioIsVorbis(false), mIsWidevine(false), + mIsSecure(false), mUIDValid(uidValid), mUID(uid), mFd(-1), @@ -163,6 +164,17 @@ status_t NuPlayer::GenericSource::initFromDataSource() { if (mFileMeta->findInt64(kKeyDuration, &duration)) { mDurationUs = duration; } + + if (!mIsWidevine) { + // Check mime to see if we actually have a widevine source. + // If the data source is not URL-type (eg. file source), we + // won't be able to tell until now. + const char *fileMime; + if (mFileMeta->findCString(kKeyMIMEType, &fileMime) + && !strncasecmp(fileMime, "video/wvm", 9)) { + mIsWidevine = true; + } + } } int32_t totalBitrate = 0; @@ -208,7 +220,7 @@ status_t NuPlayer::GenericSource::initFromDataSource() { int32_t secure; if (meta->findInt32(kKeyRequiresSecureBuffers, &secure) && secure) { - mIsWidevine = true; + mIsSecure = true; if (mUIDValid) { extractor->setUID(mUID); } @@ -263,7 +275,7 @@ int64_t NuPlayer::GenericSource::getLastReadPosition() { status_t NuPlayer::GenericSource::setBuffers( bool audio, Vector<MediaBuffer *> &buffers) { - if (mIsWidevine && !audio) { + if (mIsSecure && !audio) { return mVideoTrack.mSource->setBuffers(buffers); } return INVALID_OPERATION; @@ -293,6 +305,10 @@ void NuPlayer::GenericSource::prepareAsync() { void NuPlayer::GenericSource::onPrepareAsync() { // delayed data source creation if (mDataSource == NULL) { + // set to false first, if the extractor + // comes back as secure, set it to true then. + mIsSecure = false; + if (!mUri.empty()) { const char* uri = mUri.c_str(); mIsWidevine = !strncasecmp(uri, "widevine://", 11); @@ -312,8 +328,6 @@ void NuPlayer::GenericSource::onPrepareAsync() { mHTTPService, uri, &mUriHeaders, &mContentType, static_cast<HTTPBase *>(mHttpSource.get())); } else { - // set to false first, if the extractor - // comes back as secure, set it to true then. mIsWidevine = false; mDataSource = new FileSource(mFd, mOffset, mLength); @@ -368,7 +382,7 @@ void NuPlayer::GenericSource::onPrepareAsync() { } notifyFlagsChanged( - (mIsWidevine ? FLAG_SECURE : 0) + (mIsSecure ? FLAG_SECURE : 0) | FLAG_CAN_PAUSE | FLAG_CAN_SEEK_BACKWARD | FLAG_CAN_SEEK_FORWARD @@ -485,8 +499,8 @@ void NuPlayer::GenericSource::stop() { // nothing to do, just account for DRM playback status setDrmPlaybackStatusIfNeeded(Playback::STOP, 0); mStarted = false; - if (mIsWidevine) { - // For a widevine source we need to prevent any further reads. + if (mIsWidevine || mIsSecure) { + // For widevine or secure sources we need to prevent any further reads. sp<AMessage> msg = new AMessage(kWhatStopWidevine, id()); sp<AMessage> response; (void) msg->postAndAwaitResponse(&response); @@ -846,7 +860,12 @@ status_t NuPlayer::GenericSource::dequeueAccessUnit( status_t finalResult; if (!track->mPackets->hasBufferAvailable(&finalResult)) { - return (finalResult == OK ? -EWOULDBLOCK : finalResult); + if (finalResult == OK) { + postReadBuffer( + audio ? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO); + return -EWOULDBLOCK; + } + return finalResult; } status_t result = track->mPackets->dequeueAccessUnit(accessUnit); @@ -1179,6 +1198,7 @@ status_t NuPlayer::GenericSource::doSeek(int64_t seekTimeUs) { sp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer( MediaBuffer* mb, media_track_type trackType, + int64_t /* seekTimeUs */, int64_t *actualTimeUs) { bool audio = trackType == MEDIA_TRACK_TYPE_AUDIO; size_t outLength = mb->range_length(); @@ -1188,7 +1208,7 @@ sp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer( } sp<ABuffer> ab; - if (mIsWidevine && !audio) { + if (mIsSecure && !audio) { // data is already provided in the buffer ab = new ABuffer(NULL, mb->range_length()); mb->add_ref(); @@ -1216,6 +1236,16 @@ sp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer( CHECK(mb->meta_data()->findInt64(kKeyTime, &timeUs)); meta->setInt64("timeUs", timeUs); +#if 0 + // Temporarily disable pre-roll till we have a full solution to handle + // both single seek and continous seek gracefully. + if (seekTimeUs > timeUs) { + sp<AMessage> extra = new AMessage; + extra->setInt64("resume-at-mediaTimeUs", seekTimeUs); + meta->setMessage("extra", extra); + } +#endif + if (trackType == MEDIA_TRACK_TYPE_TIMEDTEXT) { const char *mime; CHECK(mTimedTextTrack.mSource != NULL @@ -1257,14 +1287,13 @@ void NuPlayer::GenericSource::onReadBuffer(sp<AMessage> msg) { int32_t tmpType; CHECK(msg->findInt32("trackType", &tmpType)); media_track_type trackType = (media_track_type)tmpType; + readBuffer(trackType); { // only protect the variable change, as readBuffer may - // take considerable time. This may result in one extra - // read being processed, but that is benign. + // take considerable time. Mutex::Autolock _l(mReadBufferLock); mPendingReadBufferTypes &= ~(1 << trackType); } - readBuffer(trackType); } void NuPlayer::GenericSource::readBuffer( @@ -1317,7 +1346,7 @@ void NuPlayer::GenericSource::readBuffer( seeking = true; } - if (mIsWidevine && trackType != MEDIA_TRACK_TYPE_AUDIO) { + if (mIsWidevine) { options.setNonBlocking(); } @@ -1348,7 +1377,8 @@ void NuPlayer::GenericSource::readBuffer( track->mPackets->queueDiscontinuity( type, NULL, true /* discard */); } - sp<ABuffer> buffer = mediaBufferToABuffer(mbuf, trackType, actualTimeUs); + sp<ABuffer> buffer = mediaBufferToABuffer( + mbuf, trackType, seekTimeUs, actualTimeUs); track->mPackets->queueAccessUnit(buffer); formatChange = false; seeking = false; diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h index f2528a9..1b63a1f 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.h +++ b/media/libmediaplayerservice/nuplayer/GenericSource.h @@ -118,6 +118,7 @@ private: int64_t mDurationUs; bool mAudioIsVorbis; bool mIsWidevine; + bool mIsSecure; bool mUIDValid; uid_t mUID; sp<IMediaHTTPService> mHTTPService; @@ -182,6 +183,7 @@ private: sp<ABuffer> mediaBufferToABuffer( MediaBuffer *mbuf, media_track_type trackType, + int64_t seekTimeUs, int64_t *actualTimeUs = NULL); void postReadBuffer(media_track_type trackType); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp index 6ad28b5..2abd9d6 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp @@ -476,6 +476,7 @@ bool NuPlayer::Decoder::handleAnOutputBuffer() { buffer->meta()->setInt64("timeUs", timeUs); if (flags & MediaCodec::BUFFER_FLAG_EOS) { buffer->meta()->setInt32("eos", true); + notifyResumeCompleteIfNecessary(); } // we do not expect CODECCONFIG or SYNCFRAME for decoder diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index a1e1aec..21b74ee 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -771,6 +771,7 @@ void NuPlayer::Renderer::postDrainVideoQueue() { if (mAnchorTimeMediaUs < 0) { setAnchorTime(mediaTimeUs, nowUs); + mAnchorMaxMediaUs = mediaTimeUs; realTimeUs = nowUs; } else { realTimeUs = getRealTimeUs(mediaTimeUs, nowUs); diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 1413635..1a9b012 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -1158,7 +1158,7 @@ status_t ACodec::configureCodec( } sp<AMessage> inputFormat = new AMessage(); - sp<AMessage> outputFormat = new AMessage(); + sp<AMessage> outputFormat = mNotify->dup(); // will use this for kWhatOutputFormatChanged mIsEncoder = encoder; @@ -1543,6 +1543,8 @@ status_t ACodec::configureCodec( err = setMinBufferSize(kPortIndexInput, 8192); // XXX } + mBaseOutputFormat = outputFormat; + CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK); CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK); mInputFormat = inputFormat; @@ -3533,7 +3535,7 @@ status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> ¬ify) { } void ACodec::sendFormatChange(const sp<AMessage> &reply) { - sp<AMessage> notify = mNotify->dup(); + sp<AMessage> notify = mBaseOutputFormat->dup(); notify->setInt32("what", kWhatOutputFormatChanged); CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK); @@ -4648,6 +4650,7 @@ void ACodec::LoadedState::stateEntered() { mCodec->mRepeatFrameDelayUs = -1ll; mCodec->mInputFormat.clear(); mCodec->mOutputFormat.clear(); + mCodec->mBaseOutputFormat.clear(); if (mCodec->mShutdownInProgress) { bool keepComponentAllocated = mCodec->mKeepComponentAllocated; |