Add support for WV DRM

Change-Id: I0408c5e0a488f112a84337b21b0cd4613a4da461
This commit is contained in:
Gloria Wang
2010-11-01 15:53:16 -07:00
parent a25c0305bc
commit c2c22e7e20
14 changed files with 245 additions and 11 deletions

View File

@@ -44,6 +44,8 @@ extern const char *MEDIA_MIMETYPE_CONTAINER_OGG;
extern const char *MEDIA_MIMETYPE_CONTAINER_MATROSKA;
extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG2TS;
extern const char *MEDIA_MIMETYPE_CONTAINER_WVM;
} // namespace android
#endif // MEDIA_DEFS_H_

View File

@@ -45,6 +45,7 @@ LOCAL_SRC_FILES:= \
TimedEventQueue.cpp \
Utils.cpp \
WAVExtractor.cpp \
WVMExtractor.cpp \
avc_utils.cpp \
string.cpp

View File

@@ -416,6 +416,7 @@ void AwesomePlayer::reset_l() {
if (mDecryptHandle != NULL) {
mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
Playback::STOP, 0);
mDrmManagerClient->closeDecryptSession(mDecryptHandle);
mDecryptHandle = NULL;
mDrmManagerClient = NULL;
}
@@ -1667,9 +1668,15 @@ status_t AwesomePlayer::finishSetDataSource_l() {
}
dataSource->getDrmInfo(&mDecryptHandle, &mDrmManagerClient);
if (mDecryptHandle != NULL
&& RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_NO_LICENSE);
if (mDecryptHandle != NULL) {
if (RightsStatus::RIGHTS_VALID == mDecryptHandle->status) {
if (DecryptApiType::WV_BASED == mDecryptHandle->decryptApiType) {
LOGD("Setting mCachedSource to NULL for WVM\n");
mCachedSource.clear();
}
} else {
notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_NO_LICENSE);
}
}
return setDataSource_l(extractor);

View File

@@ -280,18 +280,23 @@ bool SniffDRM(
if (gDrmManagerClient == NULL) {
gDrmManagerClient = new DrmManagerClient();
}
if (gDrmManagerClient == NULL) {
return false;
}
}
DecryptHandle *decryptHandle = source->DrmInitialization(gDrmManagerClient);
if (decryptHandle != NULL) {
if (decryptHandle->decryptApiType == DecryptApiType::CONTAINER_BASED) {
*mimeType = String8("drm+container_based+");
*mimeType = String8("drm+container_based+") + decryptHandle->mimeType;
} else if (decryptHandle->decryptApiType == DecryptApiType::ELEMENTARY_STREAM_BASED) {
*mimeType = String8("drm+es_based+");
*mimeType = String8("drm+es_based+") + decryptHandle->mimeType;
} else if (decryptHandle->decryptApiType == DecryptApiType::WV_BASED) {
*mimeType = MEDIA_MIMETYPE_CONTAINER_WVM;
LOGW("SniffWVM: found match\n");
}
*mimeType += decryptHandle->mimeType;
*confidence = 10.0f;
return true;

View File

@@ -55,9 +55,6 @@ FileSource::~FileSource() {
delete[] mDrmBuf;
mDrmBuf = NULL;
}
if (mDecryptHandle != NULL) {
mDrmManagerClient->closeDecryptSession(mDecryptHandle);
}
}
status_t FileSource::initCheck() const {
@@ -113,7 +110,11 @@ status_t FileSource::getSize(off_t *size) {
}
DecryptHandle* FileSource::DrmInitialization(DrmManagerClient* client) {
if (client == NULL) {
return NULL;
}
mDrmManagerClient = client;
if (mDecryptHandle == NULL) {
mDecryptHandle = mDrmManagerClient->openDecryptSession(
mFd, mOffset, mLength);

View File

@@ -42,4 +42,6 @@ const char *MEDIA_MIMETYPE_CONTAINER_OGG = "application/ogg";
const char *MEDIA_MIMETYPE_CONTAINER_MATROSKA = "video/x-matroska";
const char *MEDIA_MIMETYPE_CONTAINER_MPEG2TS = "video/mp2ts";
const char *MEDIA_MIMETYPE_CONTAINER_WVM = "video/wvm";
} // namespace android

View File

@@ -25,6 +25,7 @@
#include "include/OggExtractor.h"
#include "include/MPEG2TSExtractor.h"
#include "include/DRMExtractor.h"
#include "include/WVMExtractor.h"
#include "matroska/MatroskaExtractor.h"
@@ -92,6 +93,8 @@ sp<MediaExtractor> MediaExtractor::Create(
return new MatroskaExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {
return new MPEG2TSExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WVM)) {
return new WVMExtractor(source);
}
return NULL;

View File

@@ -510,5 +510,13 @@ void NuCachedSource2::onSuspend() {
mSuspended = true;
}
DecryptHandle* NuCachedSource2::DrmInitialization(DrmManagerClient* client) {
return mSource->DrmInitialization(client);
}
void NuCachedSource2::getDrmInfo(DecryptHandle **handle, DrmManagerClient **client) {
mSource->getDrmInfo(handle, client);
}
} // namespace android

View File

@@ -67,7 +67,9 @@ NuHTTPDataSource::NuHTTPDataSource()
mPort(0),
mOffset(0),
mContentLength(0),
mContentLengthValid(false) {
mContentLengthValid(false),
mDecryptHandle(NULL),
mDrmManagerClient(NULL) {
}
NuHTTPDataSource::~NuHTTPDataSource() {
@@ -89,6 +91,9 @@ status_t NuHTTPDataSource::connect(
off_t offset) {
String8 host, path;
unsigned port;
mUri = uri;
if (!ParseURL(uri, &host, &port, &path)) {
return ERROR_MALFORMED;
}
@@ -340,4 +345,30 @@ void NuHTTPDataSource::applyTimeoutResponse() {
}
}
DecryptHandle* NuHTTPDataSource::DrmInitialization(DrmManagerClient* client) {
if (client == NULL) {
return NULL;
}
mDrmManagerClient = client;
if (mDecryptHandle == NULL) {
/* Note if redirect occurs, mUri is the redirect uri instead of the
* original one
*/
mDecryptHandle = mDrmManagerClient->openDecryptSession(mUri);
}
if (mDecryptHandle == NULL) {
mDrmManagerClient = NULL;
}
return mDecryptHandle;
}
void NuHTTPDataSource::getDrmInfo(DecryptHandle **handle, DrmManagerClient **client) {
*handle = mDecryptHandle;
*client = mDrmManagerClient;
}
} // namespace android

View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "WVMExtractor"
#include <utils/Log.h>
#include "include/WVMExtractor.h"
#include <arpa/inet.h>
#include <utils/String8.h>
#include <media/stagefright/Utils.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaDebug.h>
#include <dlfcn.h>
#include <utils/Errors.h>
/* The extractor lifetime is short - just long enough to get
* the media sources constructed - so the shared lib needs to remain open
* beyond the lifetime of the extractor. So keep the handle as a global
* rather than a member of the extractor
*/
void *gVendorLibHandle = NULL;
namespace android {
static Mutex gWVMutex;
WVMExtractor::WVMExtractor(const sp<DataSource> &source)
: mDataSource(source) {
{
Mutex::Autolock autoLock(gWVMutex);
if (gVendorLibHandle == NULL) {
gVendorLibHandle = dlopen("libwvm.so", RTLD_NOW);
}
if (gVendorLibHandle == NULL) {
LOGE("Failed to open libwvm.so");
return;
}
}
typedef MediaExtractor *(*GetInstanceFunc)(sp<DataSource>);
GetInstanceFunc getInstanceFunc =
(GetInstanceFunc) dlsym(gVendorLibHandle,
"_ZN7android11GetInstanceENS_2spINS_10DataSourceEEE");
if (getInstanceFunc) {
LOGD("Calling GetInstanceFunc");
mImpl = (*getInstanceFunc)(source);
CHECK(mImpl != NULL);
} else {
LOGE("Failed to locate GetInstance in libwvm.so");
}
}
WVMExtractor::~WVMExtractor() {
}
size_t WVMExtractor::countTracks() {
return (mImpl != NULL) ? mImpl->countTracks() : 0;
}
sp<MediaSource> WVMExtractor::getTrack(size_t index) {
if (mImpl == NULL) {
return NULL;
}
return mImpl->getTrack(index);
}
sp<MetaData> WVMExtractor::getTrackMetaData(size_t index, uint32_t flags) {
if (mImpl == NULL) {
return NULL;
}
return mImpl->getTrackMetaData(index, flags);
}
sp<MetaData> WVMExtractor::getMetaData() {
if (mImpl == NULL) {
return NULL;
}
return mImpl->getMetaData();
}
} //namespace android

View File

@@ -37,6 +37,8 @@ struct NuCachedSource2 : public DataSource {
virtual status_t getSize(off_t *size);
virtual uint32_t flags();
virtual DecryptHandle* DrmInitialization(DrmManagerClient *client);
virtual void getDrmInfo(DecryptHandle **handle, DrmManagerClient **client);
////////////////////////////////////////////////////////////////////////////
size_t cachedSize();

View File

@@ -26,6 +26,9 @@ struct NuHTTPDataSource : public DataSource {
virtual status_t getSize(off_t *size);
virtual uint32_t flags();
virtual DecryptHandle* DrmInitialization(DrmManagerClient *client);
virtual void getDrmInfo(DecryptHandle **handle, DrmManagerClient **client);
protected:
virtual ~NuHTTPDataSource();
@@ -44,12 +47,16 @@ private:
unsigned mPort;
String8 mPath;
String8 mHeaders;
String8 mUri;
HTTPStream mHTTP;
off_t mOffset;
off_t mContentLength;
bool mContentLengthValid;
DecryptHandle *mDecryptHandle;
DrmManagerClient *mDrmManagerClient;
status_t connect(
const char *uri, const String8 &headers, off_t offset);

View File

@@ -0,0 +1,51 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef WVM_EXTRACTOR_H_
#define WVM_EXTRACTOR_H_
#include <media/stagefright/MediaExtractor.h>
namespace android {
class DataSource;
class WVMExtractor : public MediaExtractor {
public:
WVMExtractor(const sp<DataSource> &source);
virtual size_t countTracks();
virtual sp<MediaSource> getTrack(size_t index);
virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
virtual sp<MetaData> getMetaData();
protected:
virtual ~WVMExtractor();
private:
sp<DataSource> mDataSource;
sp<MediaExtractor> mImpl;
WVMExtractor(const WVMExtractor &);
WVMExtractor &operator=(const WVMExtractor &);
};
} // namespace android
#endif // DRM_EXTRACTOR_H_

10
media/libwvm/Android.mk Normal file
View File

@@ -0,0 +1,10 @@
# create an empty mk for libwvm
# for integration purpose
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libwvm
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)