DRMExtractor.cpp revision adc4d9c86d45376a3936a67616c2a302f08b5f21
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#include "include/DRMExtractor.h"
18#include "include/AMRExtractor.h"
19#include "include/MP3Extractor.h"
20#include "include/MPEG4Extractor.h"
21#include "include/WAVExtractor.h"
22#include "include/OggExtractor.h"
23
24#include <arpa/inet.h>
25#include <utils/String8.h>
26#include <media/stagefright/Utils.h>
27#include <media/stagefright/DataSource.h>
28#include <media/stagefright/MediaSource.h>
29#include <media/stagefright/MediaDefs.h>
30#include <media/stagefright/MetaData.h>
31#include <media/stagefright/MediaErrors.h>
32#include <media/stagefright/MediaBuffer.h>
33#include <media/stagefright/MediaDebug.h>
34
35#include <drm/drm_framework_common.h>
36#include <utils/Errors.h>
37
38
39namespace android {
40
41class DRMSource : public MediaSource {
42public:
43    DRMSource(const sp<MediaSource> &mediaSource,
44            DecryptHandle *decryptHandle,
45            DrmManagerClient *managerClient,
46            int32_t trackId, DrmBuffer *ipmpBox);
47
48    virtual status_t start(MetaData *params = NULL);
49    virtual status_t stop();
50    virtual sp<MetaData> getFormat();
51    virtual status_t read(
52            MediaBuffer **buffer, const ReadOptions *options = NULL);
53
54protected:
55    virtual ~DRMSource();
56
57private:
58    sp<MediaSource> mOriginalMediaSource;
59    DecryptHandle* mDecryptHandle;
60    DrmManagerClient* mDrmManagerClient;
61    size_t mTrackId;
62    mutable Mutex mDRMLock;
63    size_t mNALLengthSize;
64    bool mWantsNALFragments;
65
66    DRMSource(const DRMSource &);
67    DRMSource &operator=(const DRMSource &);
68};
69
70////////////////////////////////////////////////////////////////////////////////
71
72DRMSource::DRMSource(const sp<MediaSource> &mediaSource,
73        DecryptHandle *decryptHandle,
74        DrmManagerClient *managerClient,
75        int32_t trackId, DrmBuffer *ipmpBox)
76    : mOriginalMediaSource(mediaSource),
77      mDecryptHandle(decryptHandle),
78      mDrmManagerClient(managerClient),
79      mTrackId(trackId),
80      mNALLengthSize(0),
81      mWantsNALFragments(false) {
82    CHECK(mDrmManagerClient);
83    mDrmManagerClient->initializeDecryptUnit(
84            mDecryptHandle, trackId, ipmpBox);
85
86    const char *mime;
87    bool success = getFormat()->findCString(kKeyMIMEType, &mime);
88    CHECK(success);
89
90    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
91        uint32_t type;
92        const void *data;
93        size_t size;
94        CHECK(getFormat()->findData(kKeyAVCC, &type, &data, &size));
95
96        const uint8_t *ptr = (const uint8_t *)data;
97
98        CHECK(size >= 7);
99        CHECK_EQ(ptr[0], 1);  // configurationVersion == 1
100
101        // The number of bytes used to encode the length of a NAL unit.
102        mNALLengthSize = 1 + (ptr[4] & 3);
103    }
104}
105
106DRMSource::~DRMSource() {
107    Mutex::Autolock autoLock(mDRMLock);
108    mDrmManagerClient->finalizeDecryptUnit(mDecryptHandle, mTrackId);
109}
110
111status_t DRMSource::start(MetaData *params) {
112    int32_t val;
113    if (params && params->findInt32(kKeyWantsNALFragments, &val)
114        && val != 0) {
115        mWantsNALFragments = true;
116    } else {
117        mWantsNALFragments = false;
118    }
119
120   return mOriginalMediaSource->start(params);
121}
122
123status_t DRMSource::stop() {
124    return mOriginalMediaSource->stop();
125}
126
127sp<MetaData> DRMSource::getFormat() {
128    return mOriginalMediaSource->getFormat();
129}
130
131status_t DRMSource::read(MediaBuffer **buffer, const ReadOptions *options) {
132    Mutex::Autolock autoLock(mDRMLock);
133    status_t err;
134    if ((err = mOriginalMediaSource->read(buffer, options)) != OK) {
135        return err;
136    }
137
138    size_t len = (*buffer)->range_length();
139
140    char *src = (char *)(*buffer)->data() + (*buffer)->range_offset();
141
142    DrmBuffer encryptedDrmBuffer(src, len);
143    DrmBuffer decryptedDrmBuffer;
144    decryptedDrmBuffer.length = len;
145    decryptedDrmBuffer.data = new char[len];
146    DrmBuffer *pDecryptedDrmBuffer = &decryptedDrmBuffer;
147
148    if ((err = mDrmManagerClient->decrypt(mDecryptHandle, mTrackId,
149            &encryptedDrmBuffer, &pDecryptedDrmBuffer)) != DRM_NO_ERROR) {
150
151        if (decryptedDrmBuffer.data) {
152            delete [] decryptedDrmBuffer.data;
153            decryptedDrmBuffer.data = NULL;
154        }
155
156        if (err == DRM_ERROR_LICENSE_EXPIRED) {
157            return ERROR_NO_LICENSE;
158        } else {
159            return ERROR_IO;
160        }
161    }
162    CHECK(pDecryptedDrmBuffer == &decryptedDrmBuffer);
163
164    const char *mime;
165    CHECK(getFormat()->findCString(kKeyMIMEType, &mime));
166
167    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) && !mWantsNALFragments) {
168        uint8_t *dstData = (uint8_t*)src;
169        size_t srcOffset = 0;
170        size_t dstOffset = 0;
171
172        len = decryptedDrmBuffer.length;
173        while (srcOffset < len) {
174            CHECK(srcOffset + mNALLengthSize <= len);
175            size_t nalLength = 0;
176            const uint8_t* data = (const uint8_t*)(&decryptedDrmBuffer.data[srcOffset]);
177
178            switch (mNALLengthSize) {
179                case 1:
180                    nalLength = *data;
181                    break;
182                case 2:
183                    nalLength = U16_AT(data);
184                    break;
185                case 3:
186                    nalLength = ((size_t)data[0] << 16) | U16_AT(&data[1]);
187                    break;
188                case 4:
189                    nalLength = U32_AT(data);
190                    break;
191                default:
192                    CHECK(!"Should not be here.");
193                    break;
194            }
195
196            srcOffset += mNALLengthSize;
197
198            if (srcOffset + nalLength > len) {
199                if (decryptedDrmBuffer.data) {
200                    delete [] decryptedDrmBuffer.data;
201                    decryptedDrmBuffer.data = NULL;
202                }
203
204                return ERROR_MALFORMED;
205            }
206
207            if (nalLength == 0) {
208                continue;
209            }
210
211            CHECK(dstOffset + 4 <= (*buffer)->size());
212
213            dstData[dstOffset++] = 0;
214            dstData[dstOffset++] = 0;
215            dstData[dstOffset++] = 0;
216            dstData[dstOffset++] = 1;
217            memcpy(&dstData[dstOffset], &decryptedDrmBuffer.data[srcOffset], nalLength);
218            srcOffset += nalLength;
219            dstOffset += nalLength;
220        }
221
222        CHECK_EQ(srcOffset, len);
223        (*buffer)->set_range((*buffer)->range_offset(), dstOffset);
224
225    } else {
226        memcpy(src, decryptedDrmBuffer.data, decryptedDrmBuffer.length);
227        (*buffer)->set_range((*buffer)->range_offset(), decryptedDrmBuffer.length);
228    }
229
230    if (decryptedDrmBuffer.data) {
231        delete [] decryptedDrmBuffer.data;
232        decryptedDrmBuffer.data = NULL;
233    }
234
235    return OK;
236}
237
238////////////////////////////////////////////////////////////////////////////////
239
240DRMExtractor::DRMExtractor(const sp<DataSource> &source, const char* mime)
241    : mDataSource(source),
242      mDecryptHandle(NULL),
243      mDrmManagerClient(NULL) {
244    mOriginalExtractor = MediaExtractor::Create(source, mime);
245    mOriginalExtractor->setDrmFlag(true);
246
247    source->getDrmInfo(&mDecryptHandle, &mDrmManagerClient);
248}
249
250DRMExtractor::~DRMExtractor() {
251}
252
253size_t DRMExtractor::countTracks() {
254    return mOriginalExtractor->countTracks();
255}
256
257sp<MediaSource> DRMExtractor::getTrack(size_t index) {
258    sp<MediaSource> originalMediaSource = mOriginalExtractor->getTrack(index);
259    originalMediaSource->getFormat()->setInt32(kKeyIsDRM, 1);
260
261    int32_t trackID;
262    CHECK(getTrackMetaData(index, 0)->findInt32(kKeyTrackID, &trackID));
263
264    DrmBuffer ipmpBox;
265    ipmpBox.data = mOriginalExtractor->getDrmTrackInfo(trackID, &(ipmpBox.length));
266    CHECK(ipmpBox.length > 0);
267
268    return new DRMSource(originalMediaSource, mDecryptHandle, mDrmManagerClient,
269            trackID, &ipmpBox);
270}
271
272sp<MetaData> DRMExtractor::getTrackMetaData(size_t index, uint32_t flags) {
273    return mOriginalExtractor->getTrackMetaData(index, flags);
274}
275
276sp<MetaData> DRMExtractor::getMetaData() {
277    return mOriginalExtractor->getMetaData();
278}
279
280bool SniffDRM(
281    const sp<DataSource> &source, String8 *mimeType, float *confidence,
282        sp<AMessage> *) {
283    DecryptHandle *decryptHandle = source->DrmInitialization();
284
285    if (decryptHandle != NULL) {
286        if (decryptHandle->decryptApiType == DecryptApiType::CONTAINER_BASED) {
287            *mimeType = String8("drm+container_based+") + decryptHandle->mimeType;
288        } else if (decryptHandle->decryptApiType == DecryptApiType::ELEMENTARY_STREAM_BASED) {
289            *mimeType = String8("drm+es_based+") + decryptHandle->mimeType;
290        } else if (decryptHandle->decryptApiType == DecryptApiType::WV_BASED) {
291            *mimeType = MEDIA_MIMETYPE_CONTAINER_WVM;
292            LOGW("SniffWVM: found match\n");
293        }
294        *confidence = 10.0f;
295
296        return true;
297    }
298
299    return false;
300}
301} //namespace android
302
303