Home | History | Annotate | Download | only in libstagefright
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "WVMExtractor"
     18 #include <utils/Log.h>
     19 
     20 #include "include/WVMExtractor.h"
     21 
     22 #include <arpa/inet.h>
     23 #include <utils/String8.h>
     24 #include <media/stagefright/foundation/ADebug.h>
     25 #include <media/stagefright/Utils.h>
     26 #include <media/stagefright/DataSource.h>
     27 #include <media/stagefright/MediaSource.h>
     28 #include <media/stagefright/MediaDefs.h>
     29 #include <media/stagefright/MetaData.h>
     30 #include <media/stagefright/MediaErrors.h>
     31 #include <media/stagefright/MediaBuffer.h>
     32 #include <dlfcn.h>
     33 
     34 #include <utils/Errors.h>
     35 
     36 /* The extractor lifetime is short - just long enough to get
     37  * the media sources constructed - so the shared lib needs to remain open
     38  * beyond the lifetime of the extractor.  So keep the handle as a global
     39  * rather than a member of the extractor
     40  */
     41 void *gVendorLibHandle = NULL;
     42 
     43 namespace android {
     44 
     45 static Mutex gWVMutex;
     46 
     47 WVMExtractor::WVMExtractor(const sp<DataSource> &source)
     48     : mDataSource(source)
     49 {
     50     Mutex::Autolock autoLock(gWVMutex);
     51 
     52     if (!getVendorLibHandle()) {
     53         return;
     54     }
     55 
     56     typedef WVMLoadableExtractor *(*GetInstanceFunc)(sp<DataSource>);
     57     GetInstanceFunc getInstanceFunc =
     58         (GetInstanceFunc) dlsym(gVendorLibHandle,
     59                 "_ZN7android11GetInstanceENS_2spINS_10DataSourceEEE");
     60 
     61     if (getInstanceFunc) {
     62         if (source->DrmInitialization(
     63                 MEDIA_MIMETYPE_CONTAINER_WVM) != NULL) {
     64             mImpl = (*getInstanceFunc)(source);
     65             CHECK(mImpl != NULL);
     66             setDrmFlag(true);
     67         } else {
     68             ALOGE("Drm manager failed to initialize.");
     69         }
     70     } else {
     71         ALOGE("Failed to locate GetInstance in libwvm.so");
     72     }
     73 }
     74 
     75 static void init_routine()
     76 {
     77     gVendorLibHandle = dlopen("libwvm.so", RTLD_NOW);
     78     if (gVendorLibHandle == NULL) {
     79         ALOGE("Failed to open libwvm.so: %s", dlerror());
     80     }
     81 }
     82 
     83 bool WVMExtractor::getVendorLibHandle()
     84 {
     85     static pthread_once_t sOnceControl = PTHREAD_ONCE_INIT;
     86     pthread_once(&sOnceControl, init_routine);
     87 
     88     return gVendorLibHandle != NULL;
     89 }
     90 
     91 WVMExtractor::~WVMExtractor() {
     92 }
     93 
     94 size_t WVMExtractor::countTracks() {
     95     return (mImpl != NULL) ? mImpl->countTracks() : 0;
     96 }
     97 
     98 sp<MediaSource> WVMExtractor::getTrack(size_t index) {
     99     if (mImpl == NULL) {
    100         return NULL;
    101     }
    102     return mImpl->getTrack(index);
    103 }
    104 
    105 sp<MetaData> WVMExtractor::getTrackMetaData(size_t index, uint32_t flags) {
    106     if (mImpl == NULL) {
    107         return NULL;
    108     }
    109     return mImpl->getTrackMetaData(index, flags);
    110 }
    111 
    112 sp<MetaData> WVMExtractor::getMetaData() {
    113     if (mImpl == NULL) {
    114         return NULL;
    115     }
    116     return mImpl->getMetaData();
    117 }
    118 
    119 int64_t WVMExtractor::getCachedDurationUs(status_t *finalStatus) {
    120     if (mImpl == NULL) {
    121         return 0;
    122     }
    123 
    124     return mImpl->getCachedDurationUs(finalStatus);
    125 }
    126 
    127 status_t WVMExtractor::getEstimatedBandwidthKbps(int32_t *kbps) {
    128     if (mImpl == NULL) {
    129         return UNKNOWN_ERROR;
    130     }
    131 
    132     return mImpl->getEstimatedBandwidthKbps(kbps);
    133 }
    134 
    135 
    136 void WVMExtractor::setAdaptiveStreamingMode(bool adaptive) {
    137     if (mImpl != NULL) {
    138         mImpl->setAdaptiveStreamingMode(adaptive);
    139     }
    140 }
    141 
    142 void WVMExtractor::setCryptoPluginMode(bool cryptoPluginMode) {
    143     if (mImpl != NULL) {
    144         mImpl->setCryptoPluginMode(cryptoPluginMode);
    145     }
    146 }
    147 
    148 void WVMExtractor::setUID(uid_t uid) {
    149     if (mImpl != NULL) {
    150         mImpl->setUID(uid);
    151     }
    152 }
    153 
    154 status_t WVMExtractor::getError() {
    155     if (mImpl == NULL) {
    156        return UNKNOWN_ERROR;
    157     }
    158 
    159     return mImpl->getError();
    160 }
    161 
    162 void WVMExtractor::setError(status_t err) {
    163     if (mImpl != NULL) {
    164         mImpl->setError(err);
    165     }
    166 }
    167 
    168 bool SniffWVM(
    169     const sp<DataSource> &source, String8 *mimeType, float *confidence,
    170         sp<AMessage> *) {
    171 
    172     Mutex::Autolock autoLock(gWVMutex);
    173 
    174     if (!WVMExtractor::getVendorLibHandle()) {
    175         return false;
    176     }
    177 
    178     typedef WVMLoadableExtractor *(*SnifferFunc)(const sp<DataSource>&);
    179     SnifferFunc snifferFunc =
    180         (SnifferFunc) dlsym(gVendorLibHandle,
    181                             "_ZN7android15IsWidevineMediaERKNS_2spINS_10DataSourceEEE");
    182 
    183     if (snifferFunc) {
    184         if ((*snifferFunc)(source)) {
    185             *mimeType = MEDIA_MIMETYPE_CONTAINER_WVM;
    186             *confidence = 10.0f;
    187             return true;
    188         }
    189     } else {
    190         ALOGE("IsWidevineMedia not found in libwvm.so");
    191     }
    192 
    193     return false;
    194 }
    195 
    196 } //namespace android
    197 
    198