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
WVMExtractor(const sp<DataSource> & source)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
init_routine()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
getVendorLibHandle()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
~WVMExtractor()91 WVMExtractor::~WVMExtractor() {
92 }
93
countTracks()94 size_t WVMExtractor::countTracks() {
95 return (mImpl != NULL) ? mImpl->countTracks() : 0;
96 }
97
getTrack(size_t index)98 sp<MediaSource> WVMExtractor::getTrack(size_t index) {
99 if (mImpl == NULL) {
100 return NULL;
101 }
102 return mImpl->getTrack(index);
103 }
104
getTrackMetaData(size_t index,uint32_t flags)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
getMetaData()112 sp<MetaData> WVMExtractor::getMetaData() {
113 if (mImpl == NULL) {
114 return NULL;
115 }
116 return mImpl->getMetaData();
117 }
118
getCachedDurationUs(status_t * finalStatus)119 int64_t WVMExtractor::getCachedDurationUs(status_t *finalStatus) {
120 if (mImpl == NULL) {
121 return 0;
122 }
123
124 return mImpl->getCachedDurationUs(finalStatus);
125 }
126
getEstimatedBandwidthKbps(int32_t * kbps)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
setAdaptiveStreamingMode(bool adaptive)136 void WVMExtractor::setAdaptiveStreamingMode(bool adaptive) {
137 if (mImpl != NULL) {
138 mImpl->setAdaptiveStreamingMode(adaptive);
139 }
140 }
141
setCryptoPluginMode(bool cryptoPluginMode)142 void WVMExtractor::setCryptoPluginMode(bool cryptoPluginMode) {
143 if (mImpl != NULL) {
144 mImpl->setCryptoPluginMode(cryptoPluginMode);
145 }
146 }
147
setUID(uid_t uid)148 void WVMExtractor::setUID(uid_t uid) {
149 if (mImpl != NULL) {
150 mImpl->setUID(uid);
151 }
152 }
153
getError()154 status_t WVMExtractor::getError() {
155 if (mImpl == NULL) {
156 return UNKNOWN_ERROR;
157 }
158
159 return mImpl->getError();
160 }
161
setError(status_t err)162 void WVMExtractor::setError(status_t err) {
163 if (mImpl != NULL) {
164 mImpl->setError(err);
165 }
166 }
167
SniffWVM(const sp<DataSource> & source,String8 * mimeType,float * confidence,sp<AMessage> *)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