/* * 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 #include "include/WVMExtractor.h" #include #include #include #include #include #include #include #include #include #include #include #include /* 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 &source) : mDataSource(source) { Mutex::Autolock autoLock(gWVMutex); if (!getVendorLibHandle()) { return; } typedef WVMLoadableExtractor *(*GetInstanceFunc)(sp); GetInstanceFunc getInstanceFunc = (GetInstanceFunc) dlsym(gVendorLibHandle, "_ZN7android11GetInstanceENS_2spINS_10DataSourceEEE"); if (getInstanceFunc) { if (source->DrmInitialization( MEDIA_MIMETYPE_CONTAINER_WVM) != NULL) { mImpl = (*getInstanceFunc)(source); CHECK(mImpl != NULL); setDrmFlag(true); } else { ALOGE("Drm manager failed to initialize."); } } else { ALOGE("Failed to locate GetInstance in libwvm.so"); } } static void init_routine() { gVendorLibHandle = dlopen("libwvm.so", RTLD_NOW); if (gVendorLibHandle == NULL) { ALOGE("Failed to open libwvm.so: %s", dlerror()); } } bool WVMExtractor::getVendorLibHandle() { static pthread_once_t sOnceControl = PTHREAD_ONCE_INIT; pthread_once(&sOnceControl, init_routine); return gVendorLibHandle != NULL; } WVMExtractor::~WVMExtractor() { } size_t WVMExtractor::countTracks() { return (mImpl != NULL) ? mImpl->countTracks() : 0; } sp WVMExtractor::getTrack(size_t index) { if (mImpl == NULL) { return NULL; } return mImpl->getTrack(index); } sp WVMExtractor::getTrackMetaData(size_t index, uint32_t flags) { if (mImpl == NULL) { return NULL; } return mImpl->getTrackMetaData(index, flags); } sp WVMExtractor::getMetaData() { if (mImpl == NULL) { return NULL; } return mImpl->getMetaData(); } int64_t WVMExtractor::getCachedDurationUs(status_t *finalStatus) { if (mImpl == NULL) { return 0; } return mImpl->getCachedDurationUs(finalStatus); } status_t WVMExtractor::getEstimatedBandwidthKbps(int32_t *kbps) { if (mImpl == NULL) { return UNKNOWN_ERROR; } return mImpl->getEstimatedBandwidthKbps(kbps); } void WVMExtractor::setAdaptiveStreamingMode(bool adaptive) { if (mImpl != NULL) { mImpl->setAdaptiveStreamingMode(adaptive); } } void WVMExtractor::setCryptoPluginMode(bool cryptoPluginMode) { if (mImpl != NULL) { mImpl->setCryptoPluginMode(cryptoPluginMode); } } void WVMExtractor::setUID(uid_t uid) { if (mImpl != NULL) { mImpl->setUID(uid); } } status_t WVMExtractor::getError() { if (mImpl == NULL) { return UNKNOWN_ERROR; } return mImpl->getError(); } void WVMExtractor::setError(status_t err) { if (mImpl != NULL) { mImpl->setError(err); } } bool SniffWVM( const sp &source, String8 *mimeType, float *confidence, sp *) { Mutex::Autolock autoLock(gWVMutex); if (!WVMExtractor::getVendorLibHandle()) { return false; } typedef WVMLoadableExtractor *(*SnifferFunc)(const sp&); SnifferFunc snifferFunc = (SnifferFunc) dlsym(gVendorLibHandle, "_ZN7android15IsWidevineMediaERKNS_2spINS_10DataSourceEEE"); if (snifferFunc) { if ((*snifferFunc)(source)) { *mimeType = MEDIA_MIMETYPE_CONTAINER_WVM; *confidence = 10.0f; return true; } } else { ALOGE("IsWidevineMedia not found in libwvm.so"); } return false; } } //namespace android