1dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang/*
2dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang * Copyright (C) 2010 The Android Open Source Project
3dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *
4dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang * Licensed under the Apache License, Version 2.0 (the "License");
5dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang * you may not use this file except in compliance with the License.
6dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang * You may obtain a copy of the License at
7dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *
8dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *      http://www.apache.org/licenses/LICENSE-2.0
9dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang *
10dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang * Unless required by applicable law or agreed to in writing, software
11dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang * distributed under the License is distributed on an "AS IS" BASIS,
12dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang * See the License for the specific language governing permissions and
14dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang * limitations under the License.
15dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang */
16dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
17dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang#include "include/DRMExtractor.h"
18dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
19dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang#include <arpa/inet.h>
20dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang#include <utils/String8.h>
21f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h>
22dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang#include <media/stagefright/Utils.h>
23dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang#include <media/stagefright/DataSource.h>
24dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang#include <media/stagefright/MediaSource.h>
25dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang#include <media/stagefright/MediaDefs.h>
26dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang#include <media/stagefright/MetaData.h>
27dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang#include <media/stagefright/MediaErrors.h>
28dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang#include <media/stagefright/MediaBuffer.h>
29dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
30dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang#include <drm/drm_framework_common.h>
31dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang#include <utils/Errors.h>
32dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
33dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
34dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangnamespace android {
35dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
36dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangclass DRMSource : public MediaSource {
37dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangpublic:
38dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    DRMSource(const sp<MediaSource> &mediaSource,
39b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang            const sp<DecryptHandle> &decryptHandle,
40889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang            DrmManagerClient *managerClient,
41889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang            int32_t trackId, DrmBuffer *ipmpBox);
42dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
43dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    virtual status_t start(MetaData *params = NULL);
44dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    virtual status_t stop();
45dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    virtual sp<MetaData> getFormat();
46dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    virtual status_t read(
47dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            MediaBuffer **buffer, const ReadOptions *options = NULL);
48dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
49dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangprotected:
50dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    virtual ~DRMSource();
51dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
52dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangprivate:
53dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    sp<MediaSource> mOriginalMediaSource;
54b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang    sp<DecryptHandle> mDecryptHandle;
55889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang    DrmManagerClient* mDrmManagerClient;
56dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    size_t mTrackId;
57dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    mutable Mutex mDRMLock;
58dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    size_t mNALLengthSize;
59dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    bool mWantsNALFragments;
60dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
61dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    DRMSource(const DRMSource &);
62dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    DRMSource &operator=(const DRMSource &);
63dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang};
64dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
65dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang////////////////////////////////////////////////////////////////////////////////
66dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
67dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria WangDRMSource::DRMSource(const sp<MediaSource> &mediaSource,
68b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang        const sp<DecryptHandle> &decryptHandle,
69889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang        DrmManagerClient *managerClient,
70889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang        int32_t trackId, DrmBuffer *ipmpBox)
71dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    : mOriginalMediaSource(mediaSource),
72dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mDecryptHandle(decryptHandle),
73889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang      mDrmManagerClient(managerClient),
74dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mTrackId(trackId),
75dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mNALLengthSize(0),
76dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mWantsNALFragments(false) {
778f64134f749e4f7861a08a3063450fc714c4651dGloria Wang    CHECK(mDrmManagerClient);
78889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang    mDrmManagerClient->initializeDecryptUnit(
79dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            mDecryptHandle, trackId, ipmpBox);
80dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
81dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    const char *mime;
82dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    bool success = getFormat()->findCString(kKeyMIMEType, &mime);
83dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    CHECK(success);
84dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
85dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
86dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        uint32_t type;
87dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        const void *data;
88dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        size_t size;
89dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        CHECK(getFormat()->findData(kKeyAVCC, &type, &data, &size));
90dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
91dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        const uint8_t *ptr = (const uint8_t *)data;
92dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
93dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        CHECK(size >= 7);
94dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        CHECK_EQ(ptr[0], 1);  // configurationVersion == 1
95dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
96dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        // The number of bytes used to encode the length of a NAL unit.
97dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        mNALLengthSize = 1 + (ptr[4] & 3);
98dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
99dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
100dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
101dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria WangDRMSource::~DRMSource() {
102dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    Mutex::Autolock autoLock(mDRMLock);
103889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang    mDrmManagerClient->finalizeDecryptUnit(mDecryptHandle, mTrackId);
104dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
105dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
106dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangstatus_t DRMSource::start(MetaData *params) {
107dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    int32_t val;
108dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (params && params->findInt32(kKeyWantsNALFragments, &val)
109dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        && val != 0) {
110dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        mWantsNALFragments = true;
111dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    } else {
112dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        mWantsNALFragments = false;
113dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
114dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
115dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang   return mOriginalMediaSource->start(params);
116dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
117dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
118dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangstatus_t DRMSource::stop() {
119dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    return mOriginalMediaSource->stop();
120dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
121dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
122dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangsp<MetaData> DRMSource::getFormat() {
123dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    return mOriginalMediaSource->getFormat();
124dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
125dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
126dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangstatus_t DRMSource::read(MediaBuffer **buffer, const ReadOptions *options) {
127dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    Mutex::Autolock autoLock(mDRMLock);
128dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    status_t err;
129dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if ((err = mOriginalMediaSource->read(buffer, options)) != OK) {
130dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return err;
131dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
132dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
133dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    size_t len = (*buffer)->range_length();
134dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
135dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    char *src = (char *)(*buffer)->data() + (*buffer)->range_offset();
136dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
137dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    DrmBuffer encryptedDrmBuffer(src, len);
138dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    DrmBuffer decryptedDrmBuffer;
139dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    decryptedDrmBuffer.length = len;
140dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    decryptedDrmBuffer.data = new char[len];
141dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    DrmBuffer *pDecryptedDrmBuffer = &decryptedDrmBuffer;
142dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
143889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang    if ((err = mDrmManagerClient->decrypt(mDecryptHandle, mTrackId,
1447340743ce30766af6334bbd9acf813eb66dd5a60Gloria Wang            &encryptedDrmBuffer, &pDecryptedDrmBuffer)) != NO_ERROR) {
145dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
146dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (decryptedDrmBuffer.data) {
147dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            delete [] decryptedDrmBuffer.data;
148dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            decryptedDrmBuffer.data = NULL;
149dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
150dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
1517340743ce30766af6334bbd9acf813eb66dd5a60Gloria Wang        return err;
152dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
153dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    CHECK(pDecryptedDrmBuffer == &decryptedDrmBuffer);
154dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
155dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    const char *mime;
156dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    CHECK(getFormat()->findCString(kKeyMIMEType, &mime));
157dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
158dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) && !mWantsNALFragments) {
159dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        uint8_t *dstData = (uint8_t*)src;
160dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        size_t srcOffset = 0;
161dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        size_t dstOffset = 0;
162dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
163dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        len = decryptedDrmBuffer.length;
164dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        while (srcOffset < len) {
165dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            CHECK(srcOffset + mNALLengthSize <= len);
166dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            size_t nalLength = 0;
167dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            const uint8_t* data = (const uint8_t*)(&decryptedDrmBuffer.data[srcOffset]);
168dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
169dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            switch (mNALLengthSize) {
170dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                case 1:
171dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    nalLength = *data;
172dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    break;
173dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                case 2:
174dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    nalLength = U16_AT(data);
175dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    break;
176dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                case 3:
177dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    nalLength = ((size_t)data[0] << 16) | U16_AT(&data[1]);
178dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    break;
179dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                case 4:
180dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    nalLength = U32_AT(data);
181dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    break;
182dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                default:
183dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    CHECK(!"Should not be here.");
184dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    break;
185dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
186dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
187dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            srcOffset += mNALLengthSize;
188dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
189dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            if (srcOffset + nalLength > len) {
190dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                if (decryptedDrmBuffer.data) {
191dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    delete [] decryptedDrmBuffer.data;
192dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    decryptedDrmBuffer.data = NULL;
193dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                }
194dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
195dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                return ERROR_MALFORMED;
196dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
197dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
198dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            if (nalLength == 0) {
199dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                continue;
200dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
201dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
202dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            CHECK(dstOffset + 4 <= (*buffer)->size());
203dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
204dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            dstData[dstOffset++] = 0;
205dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            dstData[dstOffset++] = 0;
206dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            dstData[dstOffset++] = 0;
207dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            dstData[dstOffset++] = 1;
208dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            memcpy(&dstData[dstOffset], &decryptedDrmBuffer.data[srcOffset], nalLength);
209dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            srcOffset += nalLength;
210dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            dstOffset += nalLength;
211dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
212dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
213dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        CHECK_EQ(srcOffset, len);
214dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        (*buffer)->set_range((*buffer)->range_offset(), dstOffset);
215dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
216dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    } else {
217dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        memcpy(src, decryptedDrmBuffer.data, decryptedDrmBuffer.length);
218dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        (*buffer)->set_range((*buffer)->range_offset(), decryptedDrmBuffer.length);
219dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
220dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
221dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (decryptedDrmBuffer.data) {
222dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        delete [] decryptedDrmBuffer.data;
223dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        decryptedDrmBuffer.data = NULL;
224dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
225dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
226dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    return OK;
227dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
228dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
229dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang////////////////////////////////////////////////////////////////////////////////
230dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
231dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria WangDRMExtractor::DRMExtractor(const sp<DataSource> &source, const char* mime)
232dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    : mDataSource(source),
233889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang      mDecryptHandle(NULL),
234889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang      mDrmManagerClient(NULL) {
235dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    mOriginalExtractor = MediaExtractor::Create(source, mime);
236dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    mOriginalExtractor->setDrmFlag(true);
2378ddeebb93cb41e7a8e9fe763afb6c6016b21fa61Glenn Kasten    mOriginalExtractor->getMetaData()->setInt32(kKeyIsDRM, 1);
238dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
239b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang    source->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
240dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
241dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
242dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria WangDRMExtractor::~DRMExtractor() {
243dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
244dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
245dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangsize_t DRMExtractor::countTracks() {
246dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    return mOriginalExtractor->countTracks();
247dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
248dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
249dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangsp<MediaSource> DRMExtractor::getTrack(size_t index) {
250dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    sp<MediaSource> originalMediaSource = mOriginalExtractor->getTrack(index);
251dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    originalMediaSource->getFormat()->setInt32(kKeyIsDRM, 1);
252dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
253dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    int32_t trackID;
254dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    CHECK(getTrackMetaData(index, 0)->findInt32(kKeyTrackID, &trackID));
255dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
256dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    DrmBuffer ipmpBox;
257dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    ipmpBox.data = mOriginalExtractor->getDrmTrackInfo(trackID, &(ipmpBox.length));
258dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    CHECK(ipmpBox.length > 0);
259dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
260889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang    return new DRMSource(originalMediaSource, mDecryptHandle, mDrmManagerClient,
261889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang            trackID, &ipmpBox);
262dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
263dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
264dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangsp<MetaData> DRMExtractor::getTrackMetaData(size_t index, uint32_t flags) {
265dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    return mOriginalExtractor->getTrackMetaData(index, flags);
266dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
267dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
268dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangsp<MetaData> DRMExtractor::getMetaData() {
269dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    return mOriginalExtractor->getMetaData();
270dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
271dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
272dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangbool SniffDRM(
273a9741a9232c81eaf59179acef91f5be46c42264eGloria Wang    const sp<DataSource> &source, String8 *mimeType, float *confidence,
274a9741a9232c81eaf59179acef91f5be46c42264eGloria Wang        sp<AMessage> *) {
275b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang    sp<DecryptHandle> decryptHandle = source->DrmInitialization();
276dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
277dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (decryptHandle != NULL) {
278dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (decryptHandle->decryptApiType == DecryptApiType::CONTAINER_BASED) {
279b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang            *mimeType = String8("drm+container_based+") + decryptHandle->mimeType;
2809d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong            *confidence = 10.0f;
281dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        } else if (decryptHandle->decryptApiType == DecryptApiType::ELEMENTARY_STREAM_BASED) {
282b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang            *mimeType = String8("drm+es_based+") + decryptHandle->mimeType;
2839d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong            *confidence = 10.0f;
2849d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong        } else {
2859d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong            return false;
286dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
287dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
288dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return true;
289dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
290dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
291dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    return false;
292dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
293dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang} //namespace android
294dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
295