1b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang/*
2b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang * Copyright (C) 2010 The Android Open Source Project
3b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang *
4b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang * Licensed under the Apache License, Version 2.0 (the "License");
5b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang * you may not use this file except in compliance with the License.
6b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang * You may obtain a copy of the License at
7b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang *
8b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang *      http://www.apache.org/licenses/LICENSE-2.0
9b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang *
10b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang * Unless required by applicable law or agreed to in writing, software
11b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang * distributed under the License is distributed on an "AS IS" BASIS,
12b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang * See the License for the specific language governing permissions and
14b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang * limitations under the License.
15b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang */
16b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang
17b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang#define LOG_TAG "WVMExtractor"
18b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang#include <utils/Log.h>
19b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang
20b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang#include "include/WVMExtractor.h"
21b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang
22b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang#include <arpa/inet.h>
23b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang#include <utils/String8.h>
24f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h>
25b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang#include <media/stagefright/Utils.h>
26b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang#include <media/stagefright/DataSource.h>
27b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang#include <media/stagefright/MediaSource.h>
28b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang#include <media/stagefright/MediaDefs.h>
29b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang#include <media/stagefright/MetaData.h>
30b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang#include <media/stagefright/MediaErrors.h>
31b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang#include <media/stagefright/MediaBuffer.h>
32b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang#include <dlfcn.h>
33b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang
34b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang#include <utils/Errors.h>
35b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang
36e301545a292987b6f7f3b316003eb8b76e3a5e2eJeff Tinker/* The extractor lifetime is short - just long enough to get
37e301545a292987b6f7f3b316003eb8b76e3a5e2eJeff Tinker * the media sources constructed - so the shared lib needs to remain open
38e301545a292987b6f7f3b316003eb8b76e3a5e2eJeff Tinker * beyond the lifetime of the extractor.  So keep the handle as a global
39e301545a292987b6f7f3b316003eb8b76e3a5e2eJeff Tinker * rather than a member of the extractor
40e301545a292987b6f7f3b316003eb8b76e3a5e2eJeff Tinker */
41e301545a292987b6f7f3b316003eb8b76e3a5e2eJeff Tinkervoid *gVendorLibHandle = NULL;
42e301545a292987b6f7f3b316003eb8b76e3a5e2eJeff Tinker
43b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wangnamespace android {
44b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang
45e301545a292987b6f7f3b316003eb8b76e3a5e2eJeff Tinkerstatic Mutex gWVMutex;
46b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang
47b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria WangWVMExtractor::WVMExtractor(const sp<DataSource> &source)
489d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong    : mDataSource(source)
499d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong{
509d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong    Mutex::Autolock autoLock(gWVMutex);
51b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang
529d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong    if (!getVendorLibHandle()) {
539d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong        return;
54b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang    }
55b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang
56cd0b0fe858a9f109281031717d5c0001953b9054Jeffrey Tinker    typedef WVMLoadableExtractor *(*GetInstanceFunc)(sp<DataSource>);
57b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang    GetInstanceFunc getInstanceFunc =
58e301545a292987b6f7f3b316003eb8b76e3a5e2eJeff Tinker        (GetInstanceFunc) dlsym(gVendorLibHandle,
59b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang                "_ZN7android11GetInstanceENS_2spINS_10DataSourceEEE");
60b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang
61b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang    if (getInstanceFunc) {
621608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        if (source->DrmInitialization(
631608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber                MEDIA_MIMETYPE_CONTAINER_WVM) != NULL) {
641608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber            mImpl = (*getInstanceFunc)(source);
651608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber            CHECK(mImpl != NULL);
661608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber            setDrmFlag(true);
671608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        } else {
681608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber            ALOGE("Drm manager failed to initialize.");
691608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        }
70b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang    } else {
7129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to locate GetInstance in libwvm.so");
72b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang    }
73b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang}
74b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang
759d2f386dd2885eaffa11fd494ae258bb09fe6397James Dongbool WVMExtractor::getVendorLibHandle()
769d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong{
779d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong    if (gVendorLibHandle == NULL) {
789d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong        gVendorLibHandle = dlopen("libwvm.so", RTLD_NOW);
799d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong    }
809d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong
819d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong    if (gVendorLibHandle == NULL) {
829d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong        ALOGE("Failed to open libwvm.so");
839d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong    }
849d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong
859d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong    return gVendorLibHandle != NULL;
869d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong}
879d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong
88b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria WangWVMExtractor::~WVMExtractor() {
89b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang}
90b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang
91b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wangsize_t WVMExtractor::countTracks() {
92b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang    return (mImpl != NULL) ? mImpl->countTracks() : 0;
93b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang}
94b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang
95b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wangsp<MediaSource> WVMExtractor::getTrack(size_t index) {
96b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang    if (mImpl == NULL) {
97b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang        return NULL;
98b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang    }
99b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang    return mImpl->getTrack(index);
100b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang}
101b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang
102b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wangsp<MetaData> WVMExtractor::getTrackMetaData(size_t index, uint32_t flags) {
103b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang    if (mImpl == NULL) {
104b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang        return NULL;
105b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang    }
106b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang    return mImpl->getTrackMetaData(index, flags);
107b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang}
108b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang
109b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wangsp<MetaData> WVMExtractor::getMetaData() {
110b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang    if (mImpl == NULL) {
111b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang        return NULL;
112b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang    }
113b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang    return mImpl->getMetaData();
114b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang}
115b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang
116681755fc0d0797506456f46a2a10555916d6be32Andreas Huberint64_t WVMExtractor::getCachedDurationUs(status_t *finalStatus) {
117cd0b0fe858a9f109281031717d5c0001953b9054Jeffrey Tinker    if (mImpl == NULL) {
118cd0b0fe858a9f109281031717d5c0001953b9054Jeffrey Tinker        return 0;
119cd0b0fe858a9f109281031717d5c0001953b9054Jeffrey Tinker    }
120681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
121cd0b0fe858a9f109281031717d5c0001953b9054Jeffrey Tinker    return mImpl->getCachedDurationUs(finalStatus);
122681755fc0d0797506456f46a2a10555916d6be32Andreas Huber}
123681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
124f10f36d34812bae602ff018fb503ad07eaf550b1Jeffrey Tinkerstatus_t WVMExtractor::getEstimatedBandwidthKbps(int32_t *kbps) {
125f10f36d34812bae602ff018fb503ad07eaf550b1Jeffrey Tinker    if (mImpl == NULL) {
126f10f36d34812bae602ff018fb503ad07eaf550b1Jeffrey Tinker        return UNKNOWN_ERROR;
127f10f36d34812bae602ff018fb503ad07eaf550b1Jeffrey Tinker    }
128f10f36d34812bae602ff018fb503ad07eaf550b1Jeffrey Tinker
129f10f36d34812bae602ff018fb503ad07eaf550b1Jeffrey Tinker    return mImpl->getEstimatedBandwidthKbps(kbps);
130f10f36d34812bae602ff018fb503ad07eaf550b1Jeffrey Tinker}
131f10f36d34812bae602ff018fb503ad07eaf550b1Jeffrey Tinker
132f10f36d34812bae602ff018fb503ad07eaf550b1Jeffrey Tinker
133681755fc0d0797506456f46a2a10555916d6be32Andreas Hubervoid WVMExtractor::setAdaptiveStreamingMode(bool adaptive) {
134cd0b0fe858a9f109281031717d5c0001953b9054Jeffrey Tinker    if (mImpl != NULL) {
135cd0b0fe858a9f109281031717d5c0001953b9054Jeffrey Tinker        mImpl->setAdaptiveStreamingMode(adaptive);
136cd0b0fe858a9f109281031717d5c0001953b9054Jeffrey Tinker    }
137681755fc0d0797506456f46a2a10555916d6be32Andreas Huber}
138681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
139ed709d00ead015b8a0de50ebc410073f6a078fd5Jeff Tinkervoid WVMExtractor::setCryptoPluginMode(bool cryptoPluginMode) {
140ed709d00ead015b8a0de50ebc410073f6a078fd5Jeff Tinker    if (mImpl != NULL) {
141ed709d00ead015b8a0de50ebc410073f6a078fd5Jeff Tinker        mImpl->setCryptoPluginMode(cryptoPluginMode);
142ed709d00ead015b8a0de50ebc410073f6a078fd5Jeff Tinker    }
143ed709d00ead015b8a0de50ebc410073f6a078fd5Jeff Tinker}
144ed709d00ead015b8a0de50ebc410073f6a078fd5Jeff Tinker
145dce4161f7d4d39498f69591e876f5fecdde95833Jeff Tinkervoid WVMExtractor::setUID(uid_t uid) {
146dce4161f7d4d39498f69591e876f5fecdde95833Jeff Tinker    if (mImpl != NULL) {
147dce4161f7d4d39498f69591e876f5fecdde95833Jeff Tinker        mImpl->setUID(uid);
148dce4161f7d4d39498f69591e876f5fecdde95833Jeff Tinker    }
149dce4161f7d4d39498f69591e876f5fecdde95833Jeff Tinker}
150dce4161f7d4d39498f69591e876f5fecdde95833Jeff Tinker
1518a74c9b8e2627560ae5a92d4261f0de4464490adEdwin Wongstatus_t WVMExtractor::getError() {
1528a74c9b8e2627560ae5a92d4261f0de4464490adEdwin Wong    if (mImpl == NULL) {
1538a74c9b8e2627560ae5a92d4261f0de4464490adEdwin Wong       return UNKNOWN_ERROR;
1548a74c9b8e2627560ae5a92d4261f0de4464490adEdwin Wong    }
1558a74c9b8e2627560ae5a92d4261f0de4464490adEdwin Wong
1568a74c9b8e2627560ae5a92d4261f0de4464490adEdwin Wong    return mImpl->getError();
1578a74c9b8e2627560ae5a92d4261f0de4464490adEdwin Wong}
1588a74c9b8e2627560ae5a92d4261f0de4464490adEdwin Wong
1598a74c9b8e2627560ae5a92d4261f0de4464490adEdwin Wongvoid WVMExtractor::setError(status_t err) {
1608a74c9b8e2627560ae5a92d4261f0de4464490adEdwin Wong    if (mImpl != NULL) {
1618a74c9b8e2627560ae5a92d4261f0de4464490adEdwin Wong        mImpl->setError(err);
1628a74c9b8e2627560ae5a92d4261f0de4464490adEdwin Wong    }
1638a74c9b8e2627560ae5a92d4261f0de4464490adEdwin Wong}
1648a74c9b8e2627560ae5a92d4261f0de4464490adEdwin Wong
1659d2f386dd2885eaffa11fd494ae258bb09fe6397James Dongbool SniffWVM(
1669d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong    const sp<DataSource> &source, String8 *mimeType, float *confidence,
1679d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong        sp<AMessage> *) {
1689d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong
1699d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong    Mutex::Autolock autoLock(gWVMutex);
1709d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong
1719d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong    if (!WVMExtractor::getVendorLibHandle()) {
1729d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong        return false;
1739d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong    }
1749d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong
1759d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong    typedef WVMLoadableExtractor *(*SnifferFunc)(const sp<DataSource>&);
1769d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong    SnifferFunc snifferFunc =
1779d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong        (SnifferFunc) dlsym(gVendorLibHandle,
1789d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong                            "_ZN7android15IsWidevineMediaERKNS_2spINS_10DataSourceEEE");
1799d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong
1809d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong    if (snifferFunc) {
1819d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong        if ((*snifferFunc)(source)) {
1829d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong            *mimeType = MEDIA_MIMETYPE_CONTAINER_WVM;
1839d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong            *confidence = 10.0f;
1849d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong            return true;
1859d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong        }
1869d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong    } else {
1879d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong        ALOGE("IsWidevineMedia not found in libwvm.so");
1889d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong    }
1899d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong
1909d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong    return false;
1919d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong}
1929d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong
193b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang} //namespace android
194b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang
195