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_NDEBUG 0
18 #define LOG_TAG "APacketSource"
19 #include <utils/Log.h>
20 
21 #include "APacketSource.h"
22 
23 #include "ARawAudioAssembler.h"
24 #include "ASessionDescription.h"
25 
26 #include <ctype.h>
27 
28 #include <media/stagefright/foundation/ABitReader.h>
29 #include <media/stagefright/foundation/ABuffer.h>
30 #include <media/stagefright/foundation/ADebug.h>
31 #include <media/stagefright/foundation/AMessage.h>
32 #include <media/stagefright/foundation/AString.h>
33 #include <media/stagefright/foundation/avc_utils.h>
34 #include <media/stagefright/foundation/base64.h>
35 #include <media/stagefright/foundation/hexdump.h>
36 #include <media/stagefright/MediaDefs.h>
37 #include <media/stagefright/MediaErrors.h>
38 #include <media/stagefright/MetaData.h>
39 #include <utils/Vector.h>
40 
41 namespace android {
42 
GetAttribute(const char * s,const char * key,AString * value)43 static bool GetAttribute(const char *s, const char *key, AString *value) {
44     value->clear();
45 
46     size_t keyLen = strlen(key);
47 
48     for (;;) {
49         while (isspace(*s)) {
50             ++s;
51         }
52 
53         const char *colonPos = strchr(s, ';');
54 
55         size_t len =
56             (colonPos == NULL) ? strlen(s) : colonPos - s;
57 
58         if (len >= keyLen + 1 && s[keyLen] == '=' && !strncmp(s, key, keyLen)) {
59             value->setTo(&s[keyLen + 1], len - keyLen - 1);
60             return true;
61         }
62 
63         if (colonPos == NULL) {
64             return false;
65         }
66 
67         s = colonPos + 1;
68     }
69 }
70 
decodeHex(const AString & s)71 static sp<ABuffer> decodeHex(const AString &s) {
72     if ((s.size() % 2) != 0) {
73         return NULL;
74     }
75 
76     size_t outLen = s.size() / 2;
77     sp<ABuffer> buffer = new ABuffer(outLen);
78     uint8_t *out = buffer->data();
79 
80     uint8_t accum = 0;
81     for (size_t i = 0; i < s.size(); ++i) {
82         char c = s.c_str()[i];
83         unsigned value;
84         if (c >= '0' && c <= '9') {
85             value = c - '0';
86         } else if (c >= 'a' && c <= 'f') {
87             value = c - 'a' + 10;
88         } else if (c >= 'A' && c <= 'F') {
89             value = c - 'A' + 10;
90         } else {
91             return NULL;
92         }
93 
94         accum = (accum << 4) | value;
95 
96         if (i & 1) {
97             *out++ = accum;
98 
99             accum = 0;
100         }
101     }
102 
103     return buffer;
104 }
105 
MakeAVCCodecSpecificData(const char * params,int32_t * width,int32_t * height)106 static sp<ABuffer> MakeAVCCodecSpecificData(
107         const char *params, int32_t *width, int32_t *height) {
108     *width = 0;
109     *height = 0;
110 
111     AString val;
112     sp<ABuffer> profileLevelID = NULL;
113     if (GetAttribute(params, "profile-level-id", &val)) {
114         profileLevelID = decodeHex(val);
115         if (profileLevelID != NULL && profileLevelID->size() != 3u) {
116             profileLevelID = NULL;
117         }
118     }
119 
120     Vector<sp<ABuffer> > paramSets;
121 
122     size_t numSeqParameterSets = 0;
123     size_t totalSeqParameterSetSize = 0;
124     size_t numPicParameterSets = 0;
125     size_t totalPicParameterSetSize = 0;
126 
127     if (!GetAttribute(params, "sprop-parameter-sets", &val)) {
128         return NULL;
129     }
130 
131     size_t start = 0;
132     for (;;) {
133         ssize_t commaPos = val.find(",", start);
134         size_t end = (commaPos < 0) ? val.size() : commaPos;
135 
136         AString nalString(val, start, end - start);
137         sp<ABuffer> nal = decodeBase64(nalString);
138         CHECK(nal != NULL);
139         CHECK_GT(nal->size(), 0u);
140         CHECK_LE(nal->size(), 65535u);
141 
142         uint8_t nalType = nal->data()[0] & 0x1f;
143         if (numSeqParameterSets == 0) {
144             CHECK_EQ((unsigned)nalType, 7u);
145         } else if (numPicParameterSets > 0) {
146             CHECK_EQ((unsigned)nalType, 8u);
147         }
148         if (nalType == 7) {
149             ++numSeqParameterSets;
150             totalSeqParameterSetSize += nal->size();
151         } else  {
152             CHECK_EQ((unsigned)nalType, 8u);
153             ++numPicParameterSets;
154             totalPicParameterSetSize += nal->size();
155         }
156 
157         paramSets.push(nal);
158 
159         if (commaPos < 0) {
160             break;
161         }
162 
163         start = commaPos + 1;
164     }
165 
166     CHECK_LT(numSeqParameterSets, 32u);
167     CHECK_LE(numPicParameterSets, 255u);
168 
169     size_t csdSize =
170         1 + 3 + 1 + 1
171         + 2 * numSeqParameterSets + totalSeqParameterSetSize
172         + 1 + 2 * numPicParameterSets + totalPicParameterSetSize;
173 
174     sp<ABuffer> csd = new ABuffer(csdSize);
175     uint8_t *out = csd->data();
176 
177     *out++ = 0x01;  // configurationVersion
178     if (profileLevelID != NULL) {
179         memcpy(out, profileLevelID->data(), 3);
180         out += 3;
181     } else {
182         *out++ = 0x42; // Baseline profile
183         *out++ = 0xE0; // Common subset for all profiles
184         *out++ = 0x0A; // Level 1
185     }
186 
187     *out++ = (0x3f << 2) | 1;  // lengthSize == 2 bytes
188     *out++ = 0xe0 | numSeqParameterSets;
189 
190     for (size_t i = 0; i < numSeqParameterSets; ++i) {
191         sp<ABuffer> nal = paramSets.editItemAt(i);
192 
193         *out++ = nal->size() >> 8;
194         *out++ = nal->size() & 0xff;
195 
196         memcpy(out, nal->data(), nal->size());
197 
198         out += nal->size();
199 
200         if (i == 0) {
201             FindAVCDimensions(nal, width, height);
202             ALOGI("dimensions %dx%d", *width, *height);
203         }
204     }
205 
206     *out++ = numPicParameterSets;
207 
208     for (size_t i = 0; i < numPicParameterSets; ++i) {
209         sp<ABuffer> nal = paramSets.editItemAt(i + numSeqParameterSets);
210 
211         *out++ = nal->size() >> 8;
212         *out++ = nal->size() & 0xff;
213 
214         memcpy(out, nal->data(), nal->size());
215 
216         out += nal->size();
217     }
218 
219     // hexdump(csd->data(), csd->size());
220 
221     return csd;
222 }
223 
MakeAACCodecSpecificData(const char * params)224 static sp<ABuffer> MakeAACCodecSpecificData(const char *params) {
225     AString val;
226     CHECK(GetAttribute(params, "config", &val));
227 
228     sp<ABuffer> config = decodeHex(val);
229     CHECK(config != NULL);
230     CHECK_GE(config->size(), 4u);
231 
232     const uint8_t *data = config->data();
233     uint32_t x = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
234     x = (x >> 1) & 0xffff;
235 
236     static const uint8_t kStaticESDS[] = {
237         0x03, 22,
238         0x00, 0x00,     // ES_ID
239         0x00,           // streamDependenceFlag, URL_Flag, OCRstreamFlag
240 
241         0x04, 17,
242         0x40,                       // Audio ISO/IEC 14496-3
243         0x00, 0x00, 0x00, 0x00,
244         0x00, 0x00, 0x00, 0x00,
245         0x00, 0x00, 0x00, 0x00,
246 
247         0x05, 2,
248         // AudioSpecificInfo follows
249     };
250 
251     sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + 2);
252     memcpy(csd->data(), kStaticESDS, sizeof(kStaticESDS));
253     csd->data()[sizeof(kStaticESDS)] = (x >> 8) & 0xff;
254     csd->data()[sizeof(kStaticESDS) + 1] = x & 0xff;
255 
256     // hexdump(csd->data(), csd->size());
257 
258     return csd;
259 }
260 
261 // From mpeg4-generic configuration data.
MakeAACCodecSpecificData2(const char * params)262 static sp<ABuffer> MakeAACCodecSpecificData2(const char *params) {
263     AString val;
264     unsigned long objectType;
265     if (GetAttribute(params, "objectType", &val)) {
266         const char *s = val.c_str();
267         char *end;
268         objectType = strtoul(s, &end, 10);
269         CHECK(end > s && *end == '\0');
270     } else {
271         objectType = 0x40;  // Audio ISO/IEC 14496-3
272     }
273 
274     CHECK(GetAttribute(params, "config", &val));
275 
276     sp<ABuffer> config = decodeHex(val);
277     CHECK(config != NULL);
278 
279     // Make sure size fits into a single byte and doesn't have to
280     // be encoded.
281     CHECK_LT(20 + config->size(), 128u);
282 
283     static const uint8_t kStaticESDS[] = {
284         0x03, 22,
285         0x00, 0x00,     // ES_ID
286         0x00,           // streamDependenceFlag, URL_Flag, OCRstreamFlag
287 
288         0x04, 17,
289         0x40,                       // Audio ISO/IEC 14496-3
290         0x00, 0x00, 0x00, 0x00,
291         0x00, 0x00, 0x00, 0x00,
292         0x00, 0x00, 0x00, 0x00,
293 
294         0x05, 2,
295         // AudioSpecificInfo follows
296     };
297 
298     sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + config->size());
299     uint8_t *dst = csd->data();
300     *dst++ = 0x03;
301     *dst++ = 20 + config->size();
302     *dst++ = 0x00;  // ES_ID
303     *dst++ = 0x00;
304     *dst++ = 0x00;  // streamDependenceFlag, URL_Flag, OCRstreamFlag
305     *dst++ = 0x04;
306     *dst++ = 15 + config->size();
307     *dst++ = objectType;
308     for (int i = 0; i < 12; ++i) { *dst++ = 0x00; }
309     *dst++ = 0x05;
310     *dst++ = config->size();
311     memcpy(dst, config->data(), config->size());
312 
313     // hexdump(csd->data(), csd->size());
314 
315     return csd;
316 }
317 
GetSizeWidth(size_t x)318 static size_t GetSizeWidth(size_t x) {
319     size_t n = 1;
320     while (x > 127) {
321         ++n;
322         x >>= 7;
323     }
324     return n;
325 }
326 
EncodeSize(uint8_t * dst,size_t x)327 static uint8_t *EncodeSize(uint8_t *dst, size_t x) {
328     while (x > 127) {
329         *dst++ = (x & 0x7f) | 0x80;
330         x >>= 7;
331     }
332     *dst++ = x;
333     return dst;
334 }
335 
ExtractDimensionsMPEG4Config(const sp<ABuffer> & config,int32_t * width,int32_t * height)336 static bool ExtractDimensionsMPEG4Config(
337         const sp<ABuffer> &config, int32_t *width, int32_t *height) {
338     *width = 0;
339     *height = 0;
340 
341     const uint8_t *ptr = config->data();
342     size_t offset = 0;
343     bool foundVOL = false;
344     while (offset + 3 < config->size()) {
345         if (memcmp("\x00\x00\x01", &ptr[offset], 3)
346                 || (ptr[offset + 3] & 0xf0) != 0x20) {
347             ++offset;
348             continue;
349         }
350 
351         foundVOL = true;
352         break;
353     }
354 
355     if (!foundVOL) {
356         return false;
357     }
358 
359     return ExtractDimensionsFromVOLHeader(
360             &ptr[offset], config->size() - offset, width, height);
361 }
362 
MakeMPEG4VideoCodecSpecificData(const char * params,int32_t * width,int32_t * height)363 static sp<ABuffer> MakeMPEG4VideoCodecSpecificData(
364         const char *params, int32_t *width, int32_t *height) {
365     *width = 0;
366     *height = 0;
367 
368     AString val;
369     CHECK(GetAttribute(params, "config", &val));
370 
371     sp<ABuffer> config = decodeHex(val);
372     CHECK(config != NULL);
373 
374     if (!ExtractDimensionsMPEG4Config(config, width, height)) {
375         return NULL;
376     }
377 
378     ALOGI("VOL dimensions = %dx%d", *width, *height);
379 
380     size_t len1 = config->size() + GetSizeWidth(config->size()) + 1;
381     size_t len2 = len1 + GetSizeWidth(len1 + 13) + 1 + 13;
382     size_t len3 = len2 + GetSizeWidth(len2 + 3) + 1 + 3;
383 
384     sp<ABuffer> csd = new ABuffer(len3);
385     uint8_t *dst = csd->data();
386     *dst++ = 0x03;
387     dst = EncodeSize(dst, len2 + 3);
388     *dst++ = 0x00;  // ES_ID
389     *dst++ = 0x00;
390     *dst++ = 0x00;  // streamDependenceFlag, URL_Flag, OCRstreamFlag
391 
392     *dst++ = 0x04;
393     dst = EncodeSize(dst, len1 + 13);
394     *dst++ = 0x01;  // Video ISO/IEC 14496-2 Simple Profile
395     for (size_t i = 0; i < 12; ++i) {
396         *dst++ = 0x00;
397     }
398 
399     *dst++ = 0x05;
400     dst = EncodeSize(dst, config->size());
401     memcpy(dst, config->data(), config->size());
402     dst += config->size();
403 
404     // hexdump(csd->data(), csd->size());
405 
406     return csd;
407 }
408 
APacketSource(const sp<ASessionDescription> & sessionDesc,size_t index)409 APacketSource::APacketSource(
410         const sp<ASessionDescription> &sessionDesc, size_t index)
411     : mInitCheck(NO_INIT),
412       mFormat(new MetaData) {
413     unsigned long PT;
414     AString desc;
415     AString params;
416     sessionDesc->getFormatType(index, &PT, &desc, &params);
417 
418     int64_t durationUs;
419     if (sessionDesc->getDurationUs(&durationUs)) {
420         mFormat->setInt64(kKeyDuration, durationUs);
421     } else {
422         mFormat->setInt64(kKeyDuration, -1LL);
423     }
424 
425     mInitCheck = OK;
426     if (!strncmp(desc.c_str(), "H264/", 5)) {
427         mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
428 
429         int32_t width, height;
430         if (!sessionDesc->getDimensions(index, PT, &width, &height)) {
431             width = -1;
432             height = -1;
433         }
434 
435         int32_t encWidth, encHeight;
436         sp<ABuffer> codecSpecificData =
437             MakeAVCCodecSpecificData(params.c_str(), &encWidth, &encHeight);
438 
439         if (codecSpecificData != NULL) {
440             if (width < 0) {
441                 // If no explicit width/height given in the sdp, use the dimensions
442                 // extracted from the first sequence parameter set.
443                 width = encWidth;
444                 height = encHeight;
445             }
446 
447             mFormat->setData(
448                     kKeyAVCC, 0,
449                     codecSpecificData->data(), codecSpecificData->size());
450         } else if (width < 0) {
451             mInitCheck = ERROR_UNSUPPORTED;
452             return;
453         }
454 
455         mFormat->setInt32(kKeyWidth, width);
456         mFormat->setInt32(kKeyHeight, height);
457     } else if (!strncmp(desc.c_str(), "H265/", 5)) {
458         mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_HEVC);
459 
460         int32_t width, height;
461         if (!sessionDesc->getDimensions(index, PT, &width, &height)) {
462             width = -1;
463             height = -1;
464         }
465 
466         mFormat->setInt32(kKeyWidth, width);
467         mFormat->setInt32(kKeyHeight, height);
468     } else if (!strncmp(desc.c_str(), "H263-2000/", 10)
469             || !strncmp(desc.c_str(), "H263-1998/", 10)) {
470         mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
471 
472         int32_t width, height;
473         if (!sessionDesc->getDimensions(index, PT, &width, &height)) {
474             mInitCheck = ERROR_UNSUPPORTED;
475             return;
476         }
477 
478         mFormat->setInt32(kKeyWidth, width);
479         mFormat->setInt32(kKeyHeight, height);
480     } else if (!strncmp(desc.c_str(), "MP4A-LATM/", 10)) {
481         mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
482 
483         int32_t sampleRate, numChannels;
484         ASessionDescription::ParseFormatDesc(
485                 desc.c_str(), &sampleRate, &numChannels);
486 
487         mFormat->setInt32(kKeySampleRate, sampleRate);
488         mFormat->setInt32(kKeyChannelCount, numChannels);
489 
490         sp<ABuffer> codecSpecificData =
491             MakeAACCodecSpecificData(params.c_str());
492 
493         mFormat->setData(
494                 kKeyESDS, 0,
495                 codecSpecificData->data(), codecSpecificData->size());
496     } else if (!strncmp(desc.c_str(), "AMR/", 4)) {
497         mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB);
498 
499         int32_t sampleRate, numChannels;
500         ASessionDescription::ParseFormatDesc(
501                 desc.c_str(), &sampleRate, &numChannels);
502 
503         mFormat->setInt32(kKeySampleRate, sampleRate);
504         mFormat->setInt32(kKeyChannelCount, numChannels);
505 
506         if (sampleRate != 8000 || numChannels != 1) {
507             mInitCheck = ERROR_UNSUPPORTED;
508         }
509     } else if (!strncmp(desc.c_str(), "AMR-WB/", 7)) {
510         mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB);
511 
512         int32_t sampleRate, numChannels;
513         ASessionDescription::ParseFormatDesc(
514                 desc.c_str(), &sampleRate, &numChannels);
515 
516         mFormat->setInt32(kKeySampleRate, sampleRate);
517         mFormat->setInt32(kKeyChannelCount, numChannels);
518 
519         if (sampleRate != 16000 || numChannels != 1) {
520             mInitCheck = ERROR_UNSUPPORTED;
521         }
522     } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)) {
523         mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
524 
525         int32_t width, height;
526         if (!sessionDesc->getDimensions(index, PT, &width, &height)) {
527             width = -1;
528             height = -1;
529         }
530 
531         int32_t encWidth, encHeight;
532         sp<ABuffer> codecSpecificData =
533             MakeMPEG4VideoCodecSpecificData(
534                     params.c_str(), &encWidth, &encHeight);
535 
536         if (codecSpecificData != NULL) {
537             mFormat->setData(
538                     kKeyESDS, 0,
539                     codecSpecificData->data(), codecSpecificData->size());
540 
541             if (width < 0) {
542                 width = encWidth;
543                 height = encHeight;
544             }
545         } else if (width < 0) {
546             mInitCheck = ERROR_UNSUPPORTED;
547             return;
548         }
549 
550         mFormat->setInt32(kKeyWidth, width);
551         mFormat->setInt32(kKeyHeight, height);
552     } else if (!strncasecmp(desc.c_str(), "mpeg4-generic/", 14)) {
553         AString val;
554         if (!GetAttribute(params.c_str(), "mode", &val)
555                 || (strcasecmp(val.c_str(), "AAC-lbr")
556                     && strcasecmp(val.c_str(), "AAC-hbr"))) {
557             mInitCheck = ERROR_UNSUPPORTED;
558             return;
559         }
560 
561         mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
562 
563         int32_t sampleRate, numChannels;
564         ASessionDescription::ParseFormatDesc(
565                 desc.c_str(), &sampleRate, &numChannels);
566 
567         mFormat->setInt32(kKeySampleRate, sampleRate);
568         mFormat->setInt32(kKeyChannelCount, numChannels);
569         mFormat->setInt32(kKeyIsADTS, true);
570 
571         sp<ABuffer> codecSpecificData =
572             MakeAACCodecSpecificData2(params.c_str());
573 
574         mFormat->setData(
575                 kKeyESDS, 0,
576                 codecSpecificData->data(), codecSpecificData->size());
577     } else if (ARawAudioAssembler::Supports(desc.c_str())) {
578         ARawAudioAssembler::MakeFormat(desc.c_str(), mFormat);
579     } else if (!strncasecmp("MP2T/", desc.c_str(), 5)) {
580         mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG2TS);
581     } else {
582         mInitCheck = ERROR_UNSUPPORTED;
583     }
584 }
585 
~APacketSource()586 APacketSource::~APacketSource() {
587 }
588 
initCheck() const589 status_t APacketSource::initCheck() const {
590     return mInitCheck;
591 }
592 
getFormat()593 sp<MetaData> APacketSource::getFormat() {
594     return mFormat;
595 }
596 
isVideo()597 bool APacketSource::isVideo() {
598     bool isVideo = false;
599 
600     const char *mime;
601     if (mFormat->findCString(kKeyMIMEType, &mime)) {
602         isVideo = !strncasecmp(mime, "video/", 6);
603     }
604 
605     return isVideo;
606 }
607 
608 }  // namespace android
609