blob: 11d9c220959c40173a76e735fddd5a06f82275f6 [file] [log] [blame]
Andreas Huber7a747b82010-06-07 15:19:40 -07001/*
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
Andreas Huber8c7c6dc2011-02-22 11:46:35 -080017//#define LOG_NDEBUG 0
18#define LOG_TAG "AMPEG4AudioAssembler"
19
Andreas Huber7a747b82010-06-07 15:19:40 -070020#include "AMPEG4AudioAssembler.h"
21
22#include "ARTPSource.h"
23
Andreas Huberb0d25a02010-10-27 13:59:59 -070024#include <media/stagefright/foundation/hexdump.h>
25#include <media/stagefright/foundation/ABitReader.h>
Andreas Huber7a747b82010-06-07 15:19:40 -070026#include <media/stagefright/foundation/ABuffer.h>
27#include <media/stagefright/foundation/ADebug.h>
28#include <media/stagefright/foundation/AMessage.h>
Andreas Huberb0d25a02010-10-27 13:59:59 -070029#include <media/stagefright/MediaErrors.h>
30
31#include <ctype.h>
Andreas Huber7a747b82010-06-07 15:19:40 -070032
33namespace android {
34
Andreas Huberb0d25a02010-10-27 13:59:59 -070035static 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
Andreas Huber8c7c6dc2011-02-22 11:46:35 -0800145static status_t parseAudioSpecificConfig(ABitReader *bits, sp<ABuffer> *asc) {
146 const uint8_t *dataStart = bits->data();
147 size_t totalNumBits = bits->numBitsLeft();
148
Andreas Huberb0d25a02010-10-27 13:59:59 -0700149 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
Andreas Huberb0d25a02010-10-27 13:59:59 -0700194 if (extensionAudioObjectType != 5 && bits->numBitsLeft() >= 16) {
Andreas Huber8c7c6dc2011-02-22 11:46:35 -0800195 size_t numBitsLeftAtStart = bits->numBitsLeft();
196
Andreas Huberb0d25a02010-10-27 13:59:59 -0700197 unsigned syncExtensionType = bits->getBits(11);
198 if (syncExtensionType == 0x2b7) {
Andreas Huber8c7c6dc2011-02-22 11:46:35 -0800199 LOGI("found syncExtension");
200
Andreas Huberb0d25a02010-10-27 13:59:59 -0700201 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 }
Andreas Huber8c7c6dc2011-02-22 11:46:35 -0800212
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 LOGI("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);
Andreas Huberb0d25a02010-10-27 13:59:59 -0700227 }
228 }
Andreas Huber8c7c6dc2011-02-22 11:46:35 -0800229
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 }
Andreas Huberb0d25a02010-10-27 13:59:59 -0700251
252 return OK;
253}
254
255static status_t parseStreamMuxConfig(
256 ABitReader *bits,
257 unsigned *numSubFrames,
258 unsigned *frameLengthType,
Andreas Huber8c7c6dc2011-02-22 11:46:35 -0800259 ssize_t *fixedFrameLength,
Andreas Huberb0d25a02010-10-27 13:59:59 -0700260 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
Andreas Huber8c7c6dc2011-02-22 11:46:35 -0800288 CHECK_EQ(parseAudioSpecificConfig(bits, NULL /* asc */), (status_t)OK);
Andreas Huberb0d25a02010-10-27 13:59:59 -0700289 } else {
290 TRESPASS(); // XXX to be implemented
291 }
292
293 *frameLengthType = bits->getBits(3);
Andreas Huber8c7c6dc2011-02-22 11:46:35 -0800294 *fixedFrameLength = -1;
295
Andreas Huberb0d25a02010-10-27 13:59:59 -0700296 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 {
Andreas Huber8c7c6dc2011-02-22 11:46:35 -0800308 *fixedFrameLength = bits->getBits(9);
309 break;
310 }
311
312 case 2:
313 {
314 // reserved
315 TRESPASS();
Andreas Huberb0d25a02010-10-27 13:59:59 -0700316 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
Andreas Huber8c7c6dc2011-02-22 11:46:35 -0800393 case 2:
394 {
395 // reserved
396
397 TRESPASS();
Andreas Huberb0d25a02010-10-27 13:59:59 -0700398 break;
Andreas Huber8c7c6dc2011-02-22 11:46:35 -0800399 }
400
401 default:
402 {
403 CHECK_GE(mFixedFrameLength, 0);
404
405 payloadLength = mFixedFrameLength;
406 break;
407 }
Andreas Huberb0d25a02010-10-27 13:59:59 -0700408 }
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
Andreas Huber0f535af2011-01-26 15:40:56 -0800426 if (offset < buffer->size()) {
427 LOGI("ignoring %d bytes of trailing data", buffer->size() - offset);
428 }
429 CHECK_LE(offset, buffer->size());
Andreas Huberb0d25a02010-10-27 13:59:59 -0700430
431 return out;
432}
433
434AMPEG4AudioAssembler::AMPEG4AudioAssembler(
435 const sp<AMessage> &notify, const AString &params)
Andreas Huber7a747b82010-06-07 15:19:40 -0700436 : mNotifyMsg(notify),
Andreas Huberb0d25a02010-10-27 13:59:59 -0700437 mMuxConfigPresent(false),
Andreas Huber7a747b82010-06-07 15:19:40 -0700438 mAccessUnitRTPTime(0),
439 mNextExpectedSeqNoValid(false),
440 mNextExpectedSeqNo(0),
441 mAccessUnitDamaged(false) {
Andreas Huberb0d25a02010-10-27 13:59:59 -0700442 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,
Andreas Huber8c7c6dc2011-02-22 11:46:35 -0800460 &mFixedFrameLength,
Andreas Huberb0d25a02010-10-27 13:59:59 -0700461 &mOtherDataPresent, &mOtherDataLenBits);
462
463 CHECK_EQ(err, (status_t)NO_ERROR);
Andreas Huber7a747b82010-06-07 15:19:40 -0700464}
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
Andreas Huber7a747b82010-06-07 15:19:40 -0700537 size_t totalSize = 0;
538 List<sp<ABuffer> >::iterator it = mPackets.begin();
539 while (it != mPackets.end()) {
540 const sp<ABuffer> &unit = *it;
541
Andreas Huberb0d25a02010-10-27 13:59:59 -0700542 totalSize += unit->size();
Andreas Huber7a747b82010-06-07 15:19:40 -0700543 ++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
Andreas Huber7a747b82010-06-07 15:19:40 -0700552 memcpy((uint8_t *)accessUnit->data() + offset,
Andreas Huberb0d25a02010-10-27 13:59:59 -0700553 unit->data(), unit->size());
Andreas Huber7a747b82010-06-07 15:19:40 -0700554
555 ++it;
556 }
557
Andreas Huberb0d25a02010-10-27 13:59:59 -0700558 accessUnit = removeLATMFraming(accessUnit);
Andreas Hubereeb97d92010-08-27 13:29:08 -0700559 CopyTimes(accessUnit, *mPackets.begin());
Andreas Huber7a747b82010-06-07 15:19:40 -0700560
Andreas Huber4e4173b2010-07-22 09:20:13 -0700561#if 0
562 printf(mAccessUnitDamaged ? "X" : ".");
563 fflush(stdout);
564#endif
565
Andreas Huber7a747b82010-06-07 15:19:40 -0700566 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
Andreas Huber57648e42010-08-04 10:14:30 -0700585void AMPEG4AudioAssembler::onByeReceived() {
586 sp<AMessage> msg = mNotifyMsg->dup();
587 msg->setInt32("eos", true);
588 msg->post();
589}
590
Andreas Huber7a747b82010-06-07 15:19:40 -0700591} // namespace android