diff options
Diffstat (limited to 'media/libmediaplayerservice')
-rw-r--r-- | media/libmediaplayerservice/Crypto.cpp | 133 | ||||
-rw-r--r-- | media/libmediaplayerservice/Crypto.h | 44 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.cpp | 33 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.h | 11 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 36 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayer.h | 3 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp | 4 |
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() { |