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"); 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