diff options
Diffstat (limited to 'media/libmediaplayerservice/nuplayer')
5 files changed, 61 insertions, 15 deletions
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp index e7a26b6..dd79b50 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,25 @@ 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; + if (!mUri.empty()) { + // streaming, but the app forgot to specify widevine:// url + mWVMExtractor = static_cast<WVMExtractor *>(extractor.get()); + mWVMExtractor->setAdaptiveStreamingMode(true); + if (mUIDValid) { + mWVMExtractor->setUID(mUID); + } + } + } + } } int32_t totalBitrate = 0; @@ -208,7 +228,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 +283,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 +313,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 +336,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 +390,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 +507,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 +868,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 +1206,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 +1216,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 +1244,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 +1295,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 +1354,7 @@ void NuPlayer::GenericSource::readBuffer( seeking = true; } - if (mIsWidevine && trackType != MEDIA_TRACK_TYPE_AUDIO) { + if (mIsWidevine) { options.setNonBlocking(); } @@ -1348,7 +1385,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/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index d433a4d..a28591e 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -537,7 +537,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { sp<RefBase> obj; CHECK(msg->findObject("native-window", &obj)); - if (mSource->getFormat(false /* audio */) == NULL) { + if (mSource == NULL || mSource->getFormat(false /* audio */) == NULL) { performSetSurface(static_cast<NativeWindowWrapper *>(obj.get())); break; } @@ -1667,6 +1667,10 @@ void NuPlayer::onSourceNotify(const sp<AMessage> &msg) { sp<NuPlayerDriver> driver = mDriver.promote(); if (driver != NULL) { + if ((flags & NuPlayer::Source::FLAG_CAN_SEEK) == 0) { + driver->notifyListener( + MEDIA_INFO, MEDIA_INFO_NOT_SEEKABLE, 0); + } driver->notifyFlagsChanged(flags); } 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); |