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/foundation/ADebug.h> 27 #include <media/stagefright/Utils.h> 28 #include <media/stagefright/DataSource.h> 29 #include <media/stagefright/MediaSource.h> 30 #include <media/stagefright/MediaDefs.h> 31 #include <media/stagefright/MetaData.h> 32 #include <media/stagefright/MediaErrors.h> 33 #include <media/stagefright/MediaBuffer.h> 34 35 #include <drm/drm_framework_common.h> 36 #include <utils/Errors.h> 37 38 39 namespace android { 40 41 class DRMSource : public MediaSource { 42 public: 43 DRMSource(const sp<MediaSource> &mediaSource, 44 const sp<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 54 protected: 55 virtual ~DRMSource(); 56 57 private: 58 sp<MediaSource> mOriginalMediaSource; 59 sp<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 72 DRMSource::DRMSource(const sp<MediaSource> &mediaSource, 73 const sp<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 106 DRMSource::~DRMSource() { 107 Mutex::Autolock autoLock(mDRMLock); 108 mDrmManagerClient->finalizeDecryptUnit(mDecryptHandle, mTrackId); 109 } 110 111 status_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 123 status_t DRMSource::stop() { 124 return mOriginalMediaSource->stop(); 125 } 126 127 sp<MetaData> DRMSource::getFormat() { 128 return mOriginalMediaSource->getFormat(); 129 } 130 131 status_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)) != NO_ERROR) { 150 151 if (decryptedDrmBuffer.data) { 152 delete [] decryptedDrmBuffer.data; 153 decryptedDrmBuffer.data = NULL; 154 } 155 156 return err; 157 } 158 CHECK(pDecryptedDrmBuffer == &decryptedDrmBuffer); 159 160 const char *mime; 161 CHECK(getFormat()->findCString(kKeyMIMEType, &mime)); 162 163 if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) && !mWantsNALFragments) { 164 uint8_t *dstData = (uint8_t*)src; 165 size_t srcOffset = 0; 166 size_t dstOffset = 0; 167 168 len = decryptedDrmBuffer.length; 169 while (srcOffset < len) { 170 CHECK(srcOffset + mNALLengthSize <= len); 171 size_t nalLength = 0; 172 const uint8_t* data = (const uint8_t*)(&decryptedDrmBuffer.data[srcOffset]); 173 174 switch (mNALLengthSize) { 175 case 1: 176 nalLength = *data; 177 break; 178 case 2: 179 nalLength = U16_AT(data); 180 break; 181 case 3: 182 nalLength = ((size_t)data[0] << 16) | U16_AT(&data[1]); 183 break; 184 case 4: 185 nalLength = U32_AT(data); 186 break; 187 default: 188 CHECK(!"Should not be here."); 189 break; 190 } 191 192 srcOffset += mNALLengthSize; 193 194 if (srcOffset + nalLength > len) { 195 if (decryptedDrmBuffer.data) { 196 delete [] decryptedDrmBuffer.data; 197 decryptedDrmBuffer.data = NULL; 198 } 199 200 return ERROR_MALFORMED; 201 } 202 203 if (nalLength == 0) { 204 continue; 205 } 206 207 CHECK(dstOffset + 4 <= (*buffer)->size()); 208 209 dstData[dstOffset++] = 0; 210 dstData[dstOffset++] = 0; 211 dstData[dstOffset++] = 0; 212 dstData[dstOffset++] = 1; 213 memcpy(&dstData[dstOffset], &decryptedDrmBuffer.data[srcOffset], nalLength); 214 srcOffset += nalLength; 215 dstOffset += nalLength; 216 } 217 218 CHECK_EQ(srcOffset, len); 219 (*buffer)->set_range((*buffer)->range_offset(), dstOffset); 220 221 } else { 222 memcpy(src, decryptedDrmBuffer.data, decryptedDrmBuffer.length); 223 (*buffer)->set_range((*buffer)->range_offset(), decryptedDrmBuffer.length); 224 } 225 226 if (decryptedDrmBuffer.data) { 227 delete [] decryptedDrmBuffer.data; 228 decryptedDrmBuffer.data = NULL; 229 } 230 231 return OK; 232 } 233 234 //////////////////////////////////////////////////////////////////////////////// 235 236 DRMExtractor::DRMExtractor(const sp<DataSource> &source, const char* mime) 237 : mDataSource(source), 238 mDecryptHandle(NULL), 239 mDrmManagerClient(NULL) { 240 mOriginalExtractor = MediaExtractor::Create(source, mime); 241 mOriginalExtractor->setDrmFlag(true); 242 mOriginalExtractor->getMetaData()->setInt32(kKeyIsDRM, 1); 243 244 source->getDrmInfo(mDecryptHandle, &mDrmManagerClient); 245 } 246 247 DRMExtractor::~DRMExtractor() { 248 } 249 250 size_t DRMExtractor::countTracks() { 251 return mOriginalExtractor->countTracks(); 252 } 253 254 sp<MediaSource> DRMExtractor::getTrack(size_t index) { 255 sp<MediaSource> originalMediaSource = mOriginalExtractor->getTrack(index); 256 originalMediaSource->getFormat()->setInt32(kKeyIsDRM, 1); 257 258 int32_t trackID; 259 CHECK(getTrackMetaData(index, 0)->findInt32(kKeyTrackID, &trackID)); 260 261 DrmBuffer ipmpBox; 262 ipmpBox.data = mOriginalExtractor->getDrmTrackInfo(trackID, &(ipmpBox.length)); 263 CHECK(ipmpBox.length > 0); 264 265 return new DRMSource(originalMediaSource, mDecryptHandle, mDrmManagerClient, 266 trackID, &ipmpBox); 267 } 268 269 sp<MetaData> DRMExtractor::getTrackMetaData(size_t index, uint32_t flags) { 270 return mOriginalExtractor->getTrackMetaData(index, flags); 271 } 272 273 sp<MetaData> DRMExtractor::getMetaData() { 274 return mOriginalExtractor->getMetaData(); 275 } 276 277 bool SniffDRM( 278 const sp<DataSource> &source, String8 *mimeType, float *confidence, 279 sp<AMessage> *) { 280 sp<DecryptHandle> decryptHandle = source->DrmInitialization(); 281 282 if (decryptHandle != NULL) { 283 if (decryptHandle->decryptApiType == DecryptApiType::CONTAINER_BASED) { 284 *mimeType = String8("drm+container_based+") + decryptHandle->mimeType; 285 *confidence = 10.0f; 286 } else if (decryptHandle->decryptApiType == DecryptApiType::ELEMENTARY_STREAM_BASED) { 287 *mimeType = String8("drm+es_based+") + decryptHandle->mimeType; 288 *confidence = 10.0f; 289 } else { 290 return false; 291 } 292 293 return true; 294 } 295 296 return false; 297 } 298 } //namespace android 299 300