summaryrefslogtreecommitdiffstats
path: root/media/libmediaplayerservice
diff options
context:
space:
mode:
Diffstat (limited to 'media/libmediaplayerservice')
-rw-r--r--media/libmediaplayerservice/Crypto.cpp133
-rw-r--r--media/libmediaplayerservice/Crypto.h44
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp33
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h11
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp36
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.h3
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp4
7 files changed, 211 insertions, 53 deletions
diff --git a/media/libmediaplayerservice/Crypto.cpp b/media/libmediaplayerservice/Crypto.cpp
index e02035f..4491f2b 100644
--- a/media/libmediaplayerservice/Crypto.cpp
+++ b/media/libmediaplayerservice/Crypto.cpp
@@ -20,46 +20,137 @@
#include "Crypto.h"
+#include <media/hardware/CryptoAPI.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/MediaErrors.h>
+#include <dlfcn.h>
+
namespace android {
-Crypto::Crypto() {
+Crypto::Crypto()
+ : mInitCheck(NO_INIT),
+ mLibHandle(NULL),
+ mPlugin(NULL) {
+ mInitCheck = init();
}
Crypto::~Crypto() {
+ delete mPlugin;
+ mPlugin = NULL;
+
+ delete mFactory;
+ mFactory = NULL;
+
+ if (mLibHandle != NULL) {
+ dlclose(mLibHandle);
+ mLibHandle = NULL;
+ }
}
-status_t Crypto::initialize() {
- return ERROR_UNSUPPORTED;
+status_t Crypto::initCheck() const {
+ return mInitCheck;
}
-status_t Crypto::terminate() {
- return ERROR_UNSUPPORTED;
+status_t Crypto::init() {
+ mLibHandle = dlopen("libdrmdecrypt.so", RTLD_NOW);
+
+ if (mLibHandle == NULL) {
+ return ERROR_UNSUPPORTED;
+ }
+
+ typedef CryptoFactory *(*CreateCryptoFactoryFunc)();
+ CreateCryptoFactoryFunc createCryptoFactory =
+ (CreateCryptoFactoryFunc)dlsym(mLibHandle, "createCryptoFactory");
+
+ if (createCryptoFactory == NULL
+ || ((mFactory = createCryptoFactory()) == NULL)) {
+ dlclose(mLibHandle);
+ mLibHandle = NULL;
+
+ return ERROR_UNSUPPORTED;
+ }
+
+ return OK;
}
-status_t Crypto::setEntitlementKey(
- const void *key, size_t keyLength) {
- return ERROR_UNSUPPORTED;
+bool Crypto::isCryptoSchemeSupported(const uint8_t uuid[16]) const {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mInitCheck != OK) {
+ return false;
+ }
+
+ return mFactory->isCryptoSchemeSupported(uuid);
}
-status_t Crypto::setEntitlementControlMessage(
- const void *msg, size_t msgLength) {
- return ERROR_UNSUPPORTED;
+status_t Crypto::createPlugin(
+ const uint8_t uuid[16], const void *data, size_t size) {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mInitCheck != OK) {
+ return mInitCheck;
+ }
+
+ if (mPlugin != NULL) {
+ return -EINVAL;
+ }
+
+ return mFactory->createPlugin(uuid, data, size, &mPlugin);
}
-ssize_t Crypto::decryptVideo(
- const void *iv, size_t ivLength,
- const void *srcData, size_t srcDataSize,
- void *dstData, size_t dstDataOffset) {
- return ERROR_UNSUPPORTED;
+status_t Crypto::destroyPlugin() {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mInitCheck != OK) {
+ return mInitCheck;
+ }
+
+ if (mPlugin == NULL) {
+ return -EINVAL;
+ }
+
+ delete mPlugin;
+ mPlugin = NULL;
+
+ return OK;
+}
+
+bool Crypto::requiresSecureDecoderComponent(const char *mime) const {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mInitCheck != OK) {
+ return mInitCheck;
+ }
+
+ if (mPlugin == NULL) {
+ return -EINVAL;
+ }
+
+ return mPlugin->requiresSecureDecoderComponent(mime);
}
-ssize_t Crypto::decryptAudio(
- const void *iv, size_t ivLength,
- const void *srcData, size_t srcDataSize,
- void *dstData, size_t dstDataSize) {
- return ERROR_UNSUPPORTED;
+status_t Crypto::decrypt(
+ bool secure,
+ const uint8_t key[16],
+ const uint8_t iv[16],
+ CryptoPlugin::Mode mode,
+ const void *srcPtr,
+ const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
+ void *dstPtr) {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mInitCheck != OK) {
+ return mInitCheck;
+ }
+
+ if (mPlugin == NULL) {
+ return -EINVAL;
+ }
+
+ return mPlugin->decrypt(
+ secure, key, iv, mode, srcPtr, subSamples, numSubSamples, dstPtr);
}
} // namespace android
diff --git a/media/libmediaplayerservice/Crypto.h b/media/libmediaplayerservice/Crypto.h
index 9855496..74de2b5 100644
--- a/media/libmediaplayerservice/Crypto.h
+++ b/media/libmediaplayerservice/Crypto.h
@@ -23,32 +23,44 @@
namespace android {
+struct CryptoFactory;
+struct CryptoPlugin;
+
struct Crypto : public BnCrypto {
Crypto();
+ virtual ~Crypto();
- virtual status_t initialize();
- virtual status_t terminate();
+ virtual status_t initCheck() const;
- virtual status_t setEntitlementKey(
- const void *key, size_t keyLength);
+ virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) const;
- virtual status_t setEntitlementControlMessage(
- const void *msg, size_t msgLength);
+ virtual status_t createPlugin(
+ const uint8_t uuid[16], const void *data, size_t size);
- virtual ssize_t decryptVideo(
- const void *iv, size_t ivLength,
- const void *srcData, size_t srcDataSize,
- void *dstData, size_t dstDataOffset);
+ virtual status_t destroyPlugin();
- virtual ssize_t decryptAudio(
- const void *iv, size_t ivLength,
- const void *srcData, size_t srcDataSize,
- void *dstData, size_t dstDataSize);
+ virtual bool requiresSecureDecoderComponent(
+ const char *mime) const;
-protected:
- virtual ~Crypto();
+ virtual status_t decrypt(
+ bool secure,
+ const uint8_t key[16],
+ const uint8_t iv[16],
+ CryptoPlugin::Mode mode,
+ const void *srcPtr,
+ const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
+ void *dstPtr);
private:
+ mutable Mutex mLock;
+
+ status_t mInitCheck;
+ void *mLibHandle;
+ CryptoFactory *mFactory;
+ CryptoPlugin *mPlugin;
+
+ status_t init();
+
DISALLOW_EVIL_CONSTRUCTORS(Crypto);
};
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index cc3138d..7c3fb0d 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -294,13 +294,7 @@ sp<IOMX> MediaPlayerService::getOMX() {
}
sp<ICrypto> MediaPlayerService::makeCrypto() {
- Mutex::Autolock autoLock(mLock);
-
- if (mCrypto == NULL) {
- mCrypto = new Crypto;
- }
-
- return mCrypto;
+ return new Crypto;
}
status_t MediaPlayerService::AudioCache::dump(int fd, const Vector<String16>& args) const
@@ -1417,6 +1411,7 @@ MediaPlayerService::AudioOutput::AudioOutput(int sessionId)
: mCallback(NULL),
mCallbackCookie(NULL),
mCallbackData(NULL),
+ mBytesWritten(0),
mSessionId(sessionId) {
ALOGV("AudioOutput(%d)", sessionId);
mTrack = 0;
@@ -1495,12 +1490,19 @@ float MediaPlayerService::AudioOutput::msecsPerFrame() const
return mMsecsPerFrame;
}
-status_t MediaPlayerService::AudioOutput::getPosition(uint32_t *position)
+status_t MediaPlayerService::AudioOutput::getPosition(uint32_t *position) const
{
if (mTrack == 0) return NO_INIT;
return mTrack->getPosition(position);
}
+status_t MediaPlayerService::AudioOutput::getFramesWritten(uint32_t *frameswritten) const
+{
+ if (mTrack == 0) return NO_INIT;
+ *frameswritten = mBytesWritten / frameSize();
+ return OK;
+}
+
status_t MediaPlayerService::AudioOutput::open(
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
audio_format_t format, int bufferCount,
@@ -1656,6 +1658,7 @@ void MediaPlayerService::AudioOutput::switchToNextOutput() {
mTrack = NULL;
mNextOutput->mSampleRateHz = mSampleRateHz;
mNextOutput->mMsecsPerFrame = mMsecsPerFrame;
+ mNextOutput->mBytesWritten = mBytesWritten;
}
}
@@ -1666,6 +1669,7 @@ ssize_t MediaPlayerService::AudioOutput::write(const void* buffer, size_t size)
//ALOGV("write(%p, %u)", buffer, size);
if (mTrack) {
ssize_t ret = mTrack->write(buffer, size);
+ mBytesWritten += ret;
return ret;
}
return NO_INIT;
@@ -1777,7 +1781,7 @@ void MediaPlayerService::AudioOutput::CallbackWrapper(
data->unlock();
}
-int MediaPlayerService::AudioOutput::getSessionId()
+int MediaPlayerService::AudioOutput::getSessionId() const
{
return mSessionId;
}
@@ -1802,13 +1806,20 @@ float MediaPlayerService::AudioCache::msecsPerFrame() const
return mMsecsPerFrame;
}
-status_t MediaPlayerService::AudioCache::getPosition(uint32_t *position)
+status_t MediaPlayerService::AudioCache::getPosition(uint32_t *position) const
{
if (position == 0) return BAD_VALUE;
*position = mSize;
return NO_ERROR;
}
+status_t MediaPlayerService::AudioCache::getFramesWritten(uint32_t *written) const
+{
+ if (written == 0) return BAD_VALUE;
+ *written = mSize;
+ return NO_ERROR;
+}
+
////////////////////////////////////////////////////////////////////////////////
struct CallbackThread : public Thread {
@@ -1971,7 +1982,7 @@ void MediaPlayerService::AudioCache::notify(
p->mSignal.signal();
}
-int MediaPlayerService::AudioCache::getSessionId()
+int MediaPlayerService::AudioCache::getSessionId() const
{
return 0;
}
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index b08dd6c..2a8cfd2 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -84,8 +84,9 @@ class MediaPlayerService : public BnMediaPlayerService
virtual ssize_t frameSize() const;
virtual uint32_t latency() const;
virtual float msecsPerFrame() const;
- virtual status_t getPosition(uint32_t *position);
- virtual int getSessionId();
+ virtual status_t getPosition(uint32_t *position) const;
+ virtual status_t getFramesWritten(uint32_t *frameswritten) const;
+ virtual int getSessionId() const;
virtual status_t open(
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
@@ -122,6 +123,7 @@ class MediaPlayerService : public BnMediaPlayerService
AudioCallback mCallback;
void * mCallbackCookie;
CallbackData * mCallbackData;
+ uint64_t mBytesWritten;
audio_stream_type_t mStreamType;
float mLeftVolume;
float mRightVolume;
@@ -181,8 +183,9 @@ class MediaPlayerService : public BnMediaPlayerService
virtual ssize_t frameSize() const { return ssize_t(mChannelCount * ((mFormat == AUDIO_FORMAT_PCM_16_BIT)?sizeof(int16_t):sizeof(u_int8_t))); }
virtual uint32_t latency() const;
virtual float msecsPerFrame() const;
- virtual status_t getPosition(uint32_t *position);
- virtual int getSessionId();
+ virtual status_t getPosition(uint32_t *position) const;
+ virtual status_t getFramesWritten(uint32_t *frameswritten) const;
+ virtual int getSessionId() const;
virtual status_t open(
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 544d501..11cea3b 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -39,6 +39,7 @@
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
+#include <media/stagefright/SkipCutBuffer.h>
#include <gui/ISurfaceTexture.h>
#include "avc_utils.h"
@@ -63,10 +64,13 @@ NuPlayer::NuPlayer()
mSkipRenderingVideoUntilMediaTimeUs(-1ll),
mVideoLateByUs(0ll),
mNumFramesTotal(0ll),
- mNumFramesDropped(0ll) {
+ mNumFramesDropped(0ll),
+ mSkipCutBuffer(NULL) {
}
NuPlayer::~NuPlayer() {
+ delete mSkipCutBuffer;
+ mSkipCutBuffer = NULL;
}
void NuPlayer::setUID(uid_t uid) {
@@ -234,6 +238,32 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
mSource->start();
+ sp<MetaData> meta = mSource->getFormat(true /* audio */);
+ if (meta != NULL) {
+ int32_t delay = 0;
+ if (!meta->findInt32(kKeyEncoderDelay, &delay)) {
+ delay = 0;
+ }
+ int32_t padding = 0;
+ if (!meta->findInt32(kKeyEncoderPadding, &padding)) {
+ padding = 0;
+ }
+ int32_t numchannels = 0;
+ if (delay + padding) {
+ if (meta->findInt32(kKeyChannelCount, &numchannels)) {
+ size_t frameSize = numchannels * sizeof(int16_t);
+ if (mSkipCutBuffer) {
+ size_t prevbuffersize = mSkipCutBuffer->size();
+ if (prevbuffersize != 0) {
+ ALOGW("Replacing SkipCutBuffer holding %d bytes", prevbuffersize);
+ }
+ delete mSkipCutBuffer;
+ }
+ mSkipCutBuffer = new SkipCutBuffer(delay * frameSize, padding * frameSize);
+ }
+ }
+ }
+
mRenderer = new Renderer(
mAudioSink,
new AMessage(kWhatRendererNotify, id()));
@@ -844,6 +874,10 @@ void NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) {
skipUntilMediaTimeUs = -1;
}
+ if (audio && mSkipCutBuffer) {
+ mSkipCutBuffer->submit(buffer);
+ }
+
mRenderer->queueBuffer(audio, buffer, reply);
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 25766e0..f917f64 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -27,6 +27,7 @@ namespace android {
struct ACodec;
struct MetaData;
struct NuPlayerDriver;
+class SkipCutBuffer;
struct NuPlayer : public AHandler {
NuPlayer();
@@ -128,6 +129,8 @@ private:
int64_t mVideoLateByUs;
int64_t mNumFramesTotal, mNumFramesDropped;
+ SkipCutBuffer *mSkipCutBuffer;
+
status_t instantiateDecoder(bool audio, sp<Decoder> *decoder);
status_t feedDecoderInputData(bool audio, const sp<AMessage> &msg);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index ecbc428..1f13955 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -591,6 +591,10 @@ bool NuPlayer::Renderer::dropBufferWhileFlushing(
void NuPlayer::Renderer::onAudioSinkChanged() {
CHECK(!mDrainAudioQueuePending);
mNumFramesWritten = 0;
+ uint32_t written;
+ if (mAudioSink->getFramesWritten(&written) == OK) {
+ mNumFramesWritten = written;
+ }
}
void NuPlayer::Renderer::notifyPosition() {