diff options
author | Lajos Molnar <lajos@google.com> | 2014-07-17 14:29:51 -0700 |
---|---|---|
committer | Lajos Molnar <lajos@google.com> | 2014-07-17 21:14:52 -0700 |
commit | 095248375e29adde961ec2a44989ecb3a6dda6a2 (patch) | |
tree | 41c5e1378f8c7274b257837a4356efc54436d330 /media/libmediaplayerservice/nuplayer/NuPlayer.cpp | |
parent | cc227036b05f7c2f960a89c567a61f9decefe742 (diff) | |
download | frameworks_av-095248375e29adde961ec2a44989ecb3a6dda6a2.zip frameworks_av-095248375e29adde961ec2a44989ecb3a6dda6a2.tar.gz frameworks_av-095248375e29adde961ec2a44989ecb3a6dda6a2.tar.bz2 |
nuplayer: support widevine sources
- handle widevine:// scheme
- add separate looper for renderer (as it can block initial buffer
handling if all buffers are used)
- initiate secure codecs before source is started
- don't read secure buffers
- share ACodec's input buffers with Widevine source
on the decoder side
- keep track of mediabuffers released by widevine source
- keep track of dequeued input buffers (for safety)
- release mediabuffer when buffer is subsequently dequeued. (This
was hardcoded into OMXCodec to do this when buffer-empties message
was handled, but MediaCodec does not support such functionality.)
Bug: 15699665
Change-Id: I4a369443294e45c644be8b0257010e52db1d7c9b
Diffstat (limited to 'media/libmediaplayerservice/nuplayer/NuPlayer.cpp')
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 88c59bf..6ccd27a 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -36,6 +36,7 @@ #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> +#include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MediaDefs.h> #include <media/stagefright/MediaErrors.h> #include <media/stagefright/MetaData.h> @@ -221,6 +222,10 @@ void NuPlayer::setDataSourceAsync( || strstr(url, ".sdp?"))) { source = new RTSPSource( notify, httpService, url, headers, mUIDValid, mUID, true); + } else if ((!strncasecmp(url, "widevine://", 11))) { + source = new GenericSource(notify, httpService, url, headers, + true /* isWidevine */, mUIDValid, mUID); + mSourceFlags |= Source::FLAG_SECURE; } else { source = new GenericSource(notify, httpService, url, headers); } @@ -512,6 +517,17 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { mNumFramesDropped = 0; mStarted = true; + /* instantiate decoders now for secure playback */ + if (mSourceFlags & Source::FLAG_SECURE) { + if (mNativeWindow != NULL) { + instantiateDecoder(false, &mVideoDecoder); + } + + if (mAudioSink != NULL) { + instantiateDecoder(true, &mAudioDecoder); + } + } + mSource->start(); uint32_t flags = 0; @@ -540,7 +556,10 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { new AMessage(kWhatRendererNotify, id()), flags); - looper()->registerHandler(mRenderer); + mRendererLooper = new ALooper; + mRendererLooper->setName("NuPlayerRenderer"); + mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO); + mRendererLooper->registerHandler(mRenderer); postScanSources(); break; @@ -1055,6 +1074,10 @@ status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) { sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, id()); mCCDecoder = new CCDecoder(ccNotify); + + if (mSourceFlags & Source::FLAG_SECURE) { + format->setInt32("secure", true); + } } sp<AMessage> notify = @@ -1073,6 +1096,28 @@ status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) { (*decoder)->init(); (*decoder)->configure(format); + // allocate buffers to decrypt widevine source buffers + if (!audio && (mSourceFlags & Source::FLAG_SECURE)) { + Vector<sp<ABuffer> > inputBufs; + CHECK_EQ((*decoder)->getInputBuffers(&inputBufs), (status_t)OK); + + Vector<MediaBuffer *> mediaBufs; + for (size_t i = 0; i < inputBufs.size(); i++) { + const sp<ABuffer> &buffer = inputBufs[i]; + MediaBuffer *mbuf = new MediaBuffer(buffer->data(), buffer->size()); + mediaBufs.push(mbuf); + } + + status_t err = mSource->setBuffers(audio, mediaBufs); + if (err != OK) { + for (size_t i = 0; i < mediaBufs.size(); ++i) { + mediaBufs[i]->release(); + } + mediaBufs.clear(); + ALOGE("Secure source didn't support secure mediaBufs."); + return err; + } + } return OK; } @@ -1184,6 +1229,7 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { dropAccessUnit = false; if (!audio + && !(mSourceFlags & Source::FLAG_SECURE) && mVideoLateByUs > 100000ll && mVideoIsAVC && !IsAVCReferenceFrame(accessUnit)) { @@ -1497,6 +1543,13 @@ void NuPlayer::performReset() { ++mScanSourcesGeneration; mScanSourcesPending = false; + if (mRendererLooper != NULL) { + if (mRenderer != NULL) { + mRendererLooper->unregisterHandler(mRenderer->id()); + } + mRendererLooper->stop(); + mRendererLooper.clear(); + } mRenderer.clear(); if (mSource != NULL) { |