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