AMPEG4AudioAssembler.cpp revision df64d15042bbd5e0e4933ac49bf3c177dd94752c
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 "AMPEG4AudioAssembler"
19
20#include "AMPEG4AudioAssembler.h"
21
22#include "ARTPSource.h"
23
24#include <media/stagefright/foundation/hexdump.h>
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/MediaErrors.h>
30
31#include <ctype.h>
32
33namespace android {
34
35static bool GetAttribute(const char *s, const char *key, AString *value) {
36    value->clear();
37
38    size_t keyLen = strlen(key);
39
40    for (;;) {
41        while (isspace(*s)) {
42            ++s;
43        }
44
45        const char *colonPos = strchr(s, ';');
46
47        size_t len =
48            (colonPos == NULL) ? strlen(s) : colonPos - s;
49
50        if (len >= keyLen + 1 && s[keyLen] == '=' && !strncmp(s, key, keyLen)) {
51            value->setTo(&s[keyLen + 1], len - keyLen - 1);
52            return true;
53        }
54
55        if (colonPos == NULL) {
56            return false;
57        }
58
59        s = colonPos + 1;
60    }
61}
62
63static sp<ABuffer> decodeHex(const AString &s) {
64    if ((s.size() % 2) != 0) {
65        return NULL;
66    }
67
68    size_t outLen = s.size() / 2;
69    sp<ABuffer> buffer = new ABuffer(outLen);
70    uint8_t *out = buffer->data();
71
72    uint8_t accum = 0;
73    for (size_t i = 0; i < s.size(); ++i) {
74        char c = s.c_str()[i];
75        unsigned value;
76        if (c >= '0' && c <= '9') {
77            value = c - '0';
78        } else if (c >= 'a' && c <= 'f') {
79            value = c - 'a' + 10;
80        } else if (c >= 'A' && c <= 'F') {
81            value = c - 'A' + 10;
82        } else {
83            return NULL;
84        }
85
86        accum = (accum << 4) | value;
87
88        if (i & 1) {
89            *out++ = accum;
90
91            accum = 0;
92        }
93    }
94
95    return buffer;
96}
97
98static status_t parseAudioObjectType(
99        ABitReader *bits, unsigned *audioObjectType) {
100    *audioObjectType = bits->getBits(5);
101    if ((*audioObjectType) == 31) {
102        *audioObjectType = 32 + bits->getBits(6);
103    }
104
105    return OK;
106}
107
108static status_t parseGASpecificConfig(
109        ABitReader *bits,
110        unsigned audioObjectType, unsigned channelConfiguration) {
111    unsigned frameLengthFlag = bits->getBits(1);
112    unsigned dependsOnCoreCoder = bits->getBits(1);
113    if (dependsOnCoreCoder) {
114        /* unsigned coreCoderDelay = */bits->getBits(1);
115    }
116    unsigned extensionFlag = bits->getBits(1);
117
118    if (!channelConfiguration) {
119        // program_config_element
120        return ERROR_UNSUPPORTED;  // XXX to be implemented
121    }
122
123    if (audioObjectType == 6 || audioObjectType == 20) {
124        /* unsigned layerNr = */bits->getBits(3);
125    }
126
127    if (extensionFlag) {
128        if (audioObjectType == 22) {
129            /* unsigned numOfSubFrame = */bits->getBits(5);
130            /* unsigned layerLength = */bits->getBits(11);
131        } else if (audioObjectType == 17 || audioObjectType == 19
132                || audioObjectType == 20 || audioObjectType == 23) {
133            /* unsigned aacSectionDataResilienceFlag = */bits->getBits(1);
134            /* unsigned aacScalefactorDataResilienceFlag = */bits->getBits(1);
135            /* unsigned aacSpectralDataResilienceFlag = */bits->getBits(1);
136        }
137
138        unsigned extensionFlag3 = bits->getBits(1);
139        CHECK_EQ(extensionFlag3, 0u);  // TBD in version 3
140    }
141
142    return OK;
143}
144
145static status_t parseAudioSpecificConfig(ABitReader *bits, sp<ABuffer> *asc) {
146    const uint8_t *dataStart = bits->data();
147    size_t totalNumBits = bits->numBitsLeft();
148
149    unsigned audioObjectType;
150    CHECK_EQ(parseAudioObjectType(bits, &audioObjectType), (status_t)OK);
151
152    unsigned samplingFreqIndex = bits->getBits(4);
153    if (samplingFreqIndex == 0x0f) {
154        /* unsigned samplingFrequency = */bits->getBits(24);
155    }
156
157    unsigned channelConfiguration = bits->getBits(4);
158
159    unsigned extensionAudioObjectType = 0;
160    unsigned sbrPresent = 0;
161
162    if (audioObjectType == 5) {
163        extensionAudioObjectType = audioObjectType;
164        sbrPresent = 1;
165        unsigned extensionSamplingFreqIndex = bits->getBits(4);
166        if (extensionSamplingFreqIndex == 0x0f) {
167            /* unsigned extensionSamplingFrequency = */bits->getBits(24);
168        }
169        CHECK_EQ(parseAudioObjectType(bits, &audioObjectType), (status_t)OK);
170    }
171
172    CHECK((audioObjectType >= 1 && audioObjectType <= 4)
173        || (audioObjectType >= 6 && audioObjectType <= 7)
174        || audioObjectType == 17
175        || (audioObjectType >= 19 && audioObjectType <= 23));
176
177    CHECK_EQ(parseGASpecificConfig(
178                bits, audioObjectType, channelConfiguration), (status_t)OK);
179
180    if (audioObjectType == 17
181            || (audioObjectType >= 19 && audioObjectType <= 27)) {
182        unsigned epConfig = bits->getBits(2);
183        if (epConfig == 2 || epConfig == 3) {
184            // ErrorProtectionSpecificConfig
185            return ERROR_UNSUPPORTED;  // XXX to be implemented
186
187            if (epConfig == 3) {
188                unsigned directMapping = bits->getBits(1);
189                CHECK_EQ(directMapping, 1u);
190            }
191        }
192    }
193
194    if (extensionAudioObjectType != 5 && bits->numBitsLeft() >= 16) {
195        size_t numBitsLeftAtStart = bits->numBitsLeft();
196
197        unsigned syncExtensionType = bits->getBits(11);
198        if (syncExtensionType == 0x2b7) {
199            ALOGI("found syncExtension");
200
201            CHECK_EQ(parseAudioObjectType(bits, &extensionAudioObjectType),
202                     (status_t)OK);
203
204            sbrPresent = bits->getBits(1);
205
206            if (sbrPresent == 1) {
207                unsigned extensionSamplingFreqIndex = bits->getBits(4);
208                if (extensionSamplingFreqIndex == 0x0f) {
209                    /* unsigned extensionSamplingFrequency = */bits->getBits(24);
210                }
211            }
212
213            size_t numBitsInExtension =
214                numBitsLeftAtStart - bits->numBitsLeft();
215
216            if (numBitsInExtension & 7) {
217                // Apparently an extension is always considered an even
218                // multiple of 8 bits long.
219
220                ALOGI("Skipping %d bits after sync extension",
221                     8 - (numBitsInExtension & 7));
222
223                bits->skipBits(8 - (numBitsInExtension & 7));
224            }
225        } else {
226            bits->putBits(syncExtensionType, 11);
227        }
228    }
229
230    if (asc != NULL) {
231        size_t bitpos = totalNumBits & 7;
232
233        ABitReader bs(dataStart, (totalNumBits + 7) / 8);
234
235        totalNumBits -= bits->numBitsLeft();
236
237        size_t numBytes = (totalNumBits + 7) / 8;
238
239        *asc = new ABuffer(numBytes);
240
241        if (bitpos & 7) {
242            bs.skipBits(8 - (bitpos & 7));
243        }
244
245        uint8_t *dstPtr = (*asc)->data();
246        while (numBytes > 0) {
247            *dstPtr++ = bs.getBits(8);
248            --numBytes;
249        }
250    }
251
252    return OK;
253}
254
255static status_t parseStreamMuxConfig(
256        ABitReader *bits,
257        unsigned *numSubFrames,
258        unsigned *frameLengthType,
259        ssize_t *fixedFrameLength,
260        bool *otherDataPresent,
261        unsigned *otherDataLenBits) {
262    unsigned audioMuxVersion = bits->getBits(1);
263
264    unsigned audioMuxVersionA = 0;
265    if (audioMuxVersion == 1) {
266        audioMuxVersionA = bits->getBits(1);
267    }
268
269    CHECK_EQ(audioMuxVersionA, 0u);  // otherwise future spec
270
271    if (audioMuxVersion != 0) {
272        return ERROR_UNSUPPORTED;  // XXX to be implemented;
273    }
274    CHECK_EQ(audioMuxVersion, 0u);  // XXX to be implemented
275
276    unsigned allStreamsSameTimeFraming = bits->getBits(1);
277    CHECK_EQ(allStreamsSameTimeFraming, 1u);  // There's only one stream.
278
279    *numSubFrames = bits->getBits(6);
280    unsigned numProgram = bits->getBits(4);
281    CHECK_EQ(numProgram, 0u);  // disabled in RTP LATM
282
283    unsigned numLayer = bits->getBits(3);
284    CHECK_EQ(numLayer, 0u);  // disabled in RTP LATM
285
286    if (audioMuxVersion == 0) {
287        // AudioSpecificConfig
288        CHECK_EQ(parseAudioSpecificConfig(bits, NULL /* asc */), (status_t)OK);
289    } else {
290        TRESPASS();  // XXX to be implemented
291    }
292
293    *frameLengthType = bits->getBits(3);
294    *fixedFrameLength = -1;
295
296    switch (*frameLengthType) {
297        case 0:
298        {
299            /* unsigned bufferFullness = */bits->getBits(8);
300
301            // The "coreFrameOffset" does not apply since there's only
302            // a single layer.
303            break;
304        }
305
306        case 1:
307        {
308            *fixedFrameLength = bits->getBits(9);
309            break;
310        }
311
312        case 2:
313        {
314            // reserved
315            TRESPASS();
316            break;
317        }
318
319        case 3:
320        case 4:
321        case 5:
322        {
323            /* unsigned CELPframeLengthTableIndex = */bits->getBits(6);
324            break;
325        }
326
327        case 6:
328        case 7:
329        {
330            /* unsigned HVXCframeLengthTableIndex = */bits->getBits(1);
331            break;
332        }
333
334        default:
335            break;
336    }
337
338    *otherDataPresent = bits->getBits(1);
339    *otherDataLenBits = 0;
340    if (*otherDataPresent) {
341        if (audioMuxVersion == 1) {
342            TRESPASS();  // XXX to be implemented
343        } else {
344            *otherDataLenBits = 0;
345
346            unsigned otherDataLenEsc;
347            do {
348                (*otherDataLenBits) <<= 8;
349                otherDataLenEsc = bits->getBits(1);
350                unsigned otherDataLenTmp = bits->getBits(8);
351                (*otherDataLenBits) += otherDataLenTmp;
352            } while (otherDataLenEsc);
353        }
354    }
355
356    unsigned crcCheckPresent = bits->getBits(1);
357    if (crcCheckPresent) {
358        /* unsigned crcCheckSum = */bits->getBits(8);
359    }
360
361    return OK;
362}
363
364sp<ABuffer> AMPEG4AudioAssembler::removeLATMFraming(const sp<ABuffer> &buffer) {
365    CHECK(!mMuxConfigPresent);  // XXX to be implemented
366
367    sp<ABuffer> out = new ABuffer(buffer->size());
368    out->setRange(0, 0);
369
370    size_t offset = 0;
371    uint8_t *ptr = buffer->data();
372
373    for (size_t i = 0; i <= mNumSubFrames; ++i) {
374        // parse PayloadLengthInfo
375
376        unsigned payloadLength = 0;
377
378        switch (mFrameLengthType) {
379            case 0:
380            {
381                unsigned muxSlotLengthBytes = 0;
382                unsigned tmp;
383                do {
384                    CHECK_LT(offset, buffer->size());
385                    tmp = ptr[offset++];
386                    muxSlotLengthBytes += tmp;
387                } while (tmp == 0xff);
388
389                payloadLength = muxSlotLengthBytes;
390                break;
391            }
392
393            case 2:
394            {
395                // reserved
396
397                TRESPASS();
398                break;
399            }
400
401            default:
402            {
403                CHECK_GE(mFixedFrameLength, 0);
404
405                payloadLength = mFixedFrameLength;
406                break;
407            }
408        }
409
410        CHECK_LE(offset + payloadLength, buffer->size());
411
412        memcpy(out->data() + out->size(), &ptr[offset], payloadLength);
413        out->setRange(0, out->size() + payloadLength);
414
415        offset += payloadLength;
416
417        if (mOtherDataPresent) {
418            // We want to stay byte-aligned.
419
420            CHECK((mOtherDataLenBits % 8) == 0);
421            CHECK_LE(offset + (mOtherDataLenBits / 8), buffer->size());
422            offset += mOtherDataLenBits / 8;
423        }
424    }
425
426    if (offset < buffer->size()) {
427        ALOGI("ignoring %d bytes of trailing data", buffer->size() - offset);
428    }
429    CHECK_LE(offset, buffer->size());
430
431    return out;
432}
433
434AMPEG4AudioAssembler::AMPEG4AudioAssembler(
435        const sp<AMessage> &notify, const AString &params)
436    : mNotifyMsg(notify),
437      mMuxConfigPresent(false),
438      mAccessUnitRTPTime(0),
439      mNextExpectedSeqNoValid(false),
440      mNextExpectedSeqNo(0),
441      mAccessUnitDamaged(false) {
442    AString val;
443    if (!GetAttribute(params.c_str(), "cpresent", &val)) {
444        mMuxConfigPresent = true;
445    } else if (val == "0") {
446        mMuxConfigPresent = false;
447    } else {
448        CHECK(val == "1");
449        mMuxConfigPresent = true;
450    }
451
452    CHECK(GetAttribute(params.c_str(), "config", &val));
453
454    sp<ABuffer> config = decodeHex(val);
455    CHECK(config != NULL);
456
457    ABitReader bits(config->data(), config->size());
458    status_t err = parseStreamMuxConfig(
459            &bits, &mNumSubFrames, &mFrameLengthType,
460            &mFixedFrameLength,
461            &mOtherDataPresent, &mOtherDataLenBits);
462
463    CHECK_EQ(err, (status_t)NO_ERROR);
464}
465
466AMPEG4AudioAssembler::~AMPEG4AudioAssembler() {
467}
468
469ARTPAssembler::AssemblyStatus AMPEG4AudioAssembler::assembleMore(
470        const sp<ARTPSource> &source) {
471    AssemblyStatus status = addPacket(source);
472    if (status == MALFORMED_PACKET) {
473        mAccessUnitDamaged = true;
474    }
475    return status;
476}
477
478ARTPAssembler::AssemblyStatus AMPEG4AudioAssembler::addPacket(
479        const sp<ARTPSource> &source) {
480    List<sp<ABuffer> > *queue = source->queue();
481
482    if (queue->empty()) {
483        return NOT_ENOUGH_DATA;
484    }
485
486    if (mNextExpectedSeqNoValid) {
487        List<sp<ABuffer> >::iterator it = queue->begin();
488        while (it != queue->end()) {
489            if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
490                break;
491            }
492
493            it = queue->erase(it);
494        }
495
496        if (queue->empty()) {
497            return NOT_ENOUGH_DATA;
498        }
499    }
500
501    sp<ABuffer> buffer = *queue->begin();
502
503    if (!mNextExpectedSeqNoValid) {
504        mNextExpectedSeqNoValid = true;
505        mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
506    } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
507#if VERBOSE
508        LOG(VERBOSE) << "Not the sequence number I expected";
509#endif
510
511        return WRONG_SEQUENCE_NUMBER;
512    }
513
514    uint32_t rtpTime;
515    CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
516
517    if (mPackets.size() > 0 && rtpTime != mAccessUnitRTPTime) {
518        submitAccessUnit();
519    }
520    mAccessUnitRTPTime = rtpTime;
521
522    mPackets.push_back(buffer);
523
524    queue->erase(queue->begin());
525    ++mNextExpectedSeqNo;
526
527    return OK;
528}
529
530void AMPEG4AudioAssembler::submitAccessUnit() {
531    CHECK(!mPackets.empty());
532
533#if VERBOSE
534    LOG(VERBOSE) << "Access unit complete (" << mPackets.size() << " packets)";
535#endif
536
537    size_t totalSize = 0;
538    List<sp<ABuffer> >::iterator it = mPackets.begin();
539    while (it != mPackets.end()) {
540        const sp<ABuffer> &unit = *it;
541
542        totalSize += unit->size();
543        ++it;
544    }
545
546    sp<ABuffer> accessUnit = new ABuffer(totalSize);
547    size_t offset = 0;
548    it = mPackets.begin();
549    while (it != mPackets.end()) {
550        const sp<ABuffer> &unit = *it;
551
552        memcpy((uint8_t *)accessUnit->data() + offset,
553               unit->data(), unit->size());
554
555        ++it;
556    }
557
558    accessUnit = removeLATMFraming(accessUnit);
559    CopyTimes(accessUnit, *mPackets.begin());
560
561#if 0
562    printf(mAccessUnitDamaged ? "X" : ".");
563    fflush(stdout);
564#endif
565
566    if (mAccessUnitDamaged) {
567        accessUnit->meta()->setInt32("damaged", true);
568    }
569
570    mPackets.clear();
571    mAccessUnitDamaged = false;
572
573    sp<AMessage> msg = mNotifyMsg->dup();
574    msg->setObject("access-unit", accessUnit);
575    msg->post();
576}
577
578void AMPEG4AudioAssembler::packetLost() {
579    CHECK(mNextExpectedSeqNoValid);
580    ++mNextExpectedSeqNo;
581
582    mAccessUnitDamaged = true;
583}
584
585void AMPEG4AudioAssembler::onByeReceived() {
586    sp<AMessage> msg = mNotifyMsg->dup();
587    msg->setInt32("eos", true);
588    msg->post();
589}
590
591}  // namespace android
592