summaryrefslogtreecommitdiffstats
path: root/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
diff options
context:
space:
mode:
authorLajos Molnar <lajos@google.com>2014-07-17 14:29:51 -0700
committerLajos Molnar <lajos@google.com>2014-07-17 21:14:52 -0700
commit095248375e29adde961ec2a44989ecb3a6dda6a2 (patch)
tree41c5e1378f8c7274b257837a4356efc54436d330 /media/libmediaplayerservice/nuplayer/NuPlayer.cpp
parentcc227036b05f7c2f960a89c567a61f9decefe742 (diff)
downloadframeworks_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.cpp55
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) {