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