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 "AMPEG4ElementaryAssembler"
19 #include <utils/Log.h>
20
21 #include "AMPEG4ElementaryAssembler.h"
22
23 #include "ARTPSource.h"
24 #include "ASessionDescription.h"
25
26 #include <media/stagefright/foundation/ABitReader.h>
27 #include <media/stagefright/foundation/ABuffer.h>
28 #include <media/stagefright/foundation/ADebug.h>
29 #include <media/stagefright/foundation/AMessage.h>
30 #include <media/stagefright/foundation/ByteUtils.h>
31 #include <media/stagefright/foundation/hexdump.h>
32
33 #include <ctype.h>
34 #include <stdint.h>
35
36 namespace android {
37
GetAttribute(const char * s,const char * key,AString * value)38 static bool GetAttribute(const char *s, const char *key, AString *value) {
39 value->clear();
40
41 size_t keyLen = strlen(key);
42
43 for (;;) {
44 while (isspace(*s)) {
45 ++s;
46 }
47
48 const char *colonPos = strchr(s, ';');
49
50 size_t len =
51 (colonPos == NULL) ? strlen(s) : colonPos - s;
52
53 if (len >= keyLen + 1 && s[keyLen] == '='
54 && !strncasecmp(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
GetIntegerAttribute(const char * s,const char * key,unsigned * x)67 static bool GetIntegerAttribute(
68 const char *s, const char *key, unsigned *x) {
69 *x = 0;
70
71 AString val;
72 if (!GetAttribute(s, key, &val)) {
73 return false;
74 }
75
76 s = val.c_str();
77 char *end;
78 unsigned y = strtoul(s, &end, 10);
79
80 if (end == s || *end != '\0') {
81 return false;
82 }
83
84 *x = y;
85
86 return true;
87 }
88
GetSampleRateIndex(int32_t sampleRate,size_t * tableIndex)89 static bool GetSampleRateIndex(int32_t sampleRate, size_t *tableIndex) {
90 static const int32_t kSampleRateTable[] = {
91 96000, 88200, 64000, 48000, 44100, 32000,
92 24000, 22050, 16000, 12000, 11025, 8000
93 };
94 const size_t kNumSampleRates =
95 sizeof(kSampleRateTable) / sizeof(kSampleRateTable[0]);
96
97 *tableIndex = 0;
98 for (size_t index = 0; index < kNumSampleRates; ++index) {
99 if (sampleRate == kSampleRateTable[index]) {
100 *tableIndex = index;
101 return true;
102 }
103 }
104
105 return false;
106 }
107
108 // static
AMPEG4ElementaryAssembler(const sp<AMessage> & notify,const AString & desc,const AString & params)109 AMPEG4ElementaryAssembler::AMPEG4ElementaryAssembler(
110 const sp<AMessage> ¬ify, const AString &desc, const AString ¶ms)
111 : mNotifyMsg(notify),
112 mIsGeneric(false),
113 mParams(params),
114 mSizeLength(0),
115 mIndexLength(0),
116 mIndexDeltaLength(0),
117 mCTSDeltaLength(0),
118 mDTSDeltaLength(0),
119 mRandomAccessIndication(false),
120 mStreamStateIndication(0),
121 mAuxiliaryDataSizeLength(0),
122 mHasAUHeader(false),
123 mChannelConfig(0),
124 mSampleRateIndex(0),
125 mAccessUnitRTPTime(0),
126 mNextExpectedSeqNoValid(false),
127 mNextExpectedSeqNo(0),
128 mAccessUnitDamaged(false) {
129 mIsGeneric = !strncasecmp(desc.c_str(),"mpeg4-generic/", 14);
130
131 if (mIsGeneric) {
132 AString value;
133 CHECK(GetAttribute(params.c_str(), "mode", &value));
134
135 if (!GetIntegerAttribute(params.c_str(), "sizeLength", &mSizeLength)) {
136 mSizeLength = 0;
137 }
138
139 if (!GetIntegerAttribute(
140 params.c_str(), "indexLength", &mIndexLength)) {
141 mIndexLength = 0;
142 }
143
144 if (!GetIntegerAttribute(
145 params.c_str(), "indexDeltaLength", &mIndexDeltaLength)) {
146 mIndexDeltaLength = 0;
147 }
148
149 if (!GetIntegerAttribute(
150 params.c_str(), "CTSDeltaLength", &mCTSDeltaLength)) {
151 mCTSDeltaLength = 0;
152 }
153
154 if (!GetIntegerAttribute(
155 params.c_str(), "DTSDeltaLength", &mDTSDeltaLength)) {
156 mDTSDeltaLength = 0;
157 }
158
159 unsigned x;
160 if (!GetIntegerAttribute(
161 params.c_str(), "randomAccessIndication", &x)) {
162 mRandomAccessIndication = false;
163 } else {
164 CHECK(x == 0 || x == 1);
165 mRandomAccessIndication = (x != 0);
166 }
167
168 if (!GetIntegerAttribute(
169 params.c_str(), "streamStateIndication",
170 &mStreamStateIndication)) {
171 mStreamStateIndication = 0;
172 }
173
174 if (!GetIntegerAttribute(
175 params.c_str(), "auxiliaryDataSizeLength",
176 &mAuxiliaryDataSizeLength)) {
177 mAuxiliaryDataSizeLength = 0;
178 }
179
180 mHasAUHeader =
181 mSizeLength > 0
182 || mIndexLength > 0
183 || mIndexDeltaLength > 0
184 || mCTSDeltaLength > 0
185 || mDTSDeltaLength > 0
186 || mRandomAccessIndication
187 || mStreamStateIndication > 0;
188
189 int32_t sampleRate, numChannels;
190 ASessionDescription::ParseFormatDesc(
191 desc.c_str(), &sampleRate, &numChannels);
192
193 mChannelConfig = numChannels;
194 CHECK(GetSampleRateIndex(sampleRate, &mSampleRateIndex));
195 }
196 }
197
~AMPEG4ElementaryAssembler()198 AMPEG4ElementaryAssembler::~AMPEG4ElementaryAssembler() {
199 }
200
201 struct AUHeader {
202 unsigned mSize;
203 unsigned mSerial;
204 };
205
initCheck()206 bool AMPEG4ElementaryAssembler::initCheck() {
207 if(mSizeLength == 0 || mIndexLength == 0 || mIndexDeltaLength == 0) {
208 android_errorWriteLog(0x534e4554, "124777537");
209 return false;
210 }
211 return true;
212 }
213
addPacket(const sp<ARTPSource> & source)214 ARTPAssembler::AssemblyStatus AMPEG4ElementaryAssembler::addPacket(
215 const sp<ARTPSource> &source) {
216 List<sp<ABuffer> > *queue = source->queue();
217
218 if (queue->empty()) {
219 return NOT_ENOUGH_DATA;
220 }
221
222 if (mNextExpectedSeqNoValid) {
223 List<sp<ABuffer> >::iterator it = queue->begin();
224 while (it != queue->end()) {
225 if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
226 break;
227 }
228
229 it = queue->erase(it);
230 }
231
232 if (queue->empty()) {
233 return NOT_ENOUGH_DATA;
234 }
235 }
236
237 sp<ABuffer> buffer = *queue->begin();
238
239 if (!mNextExpectedSeqNoValid) {
240 mNextExpectedSeqNoValid = true;
241 mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
242 } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
243 ALOGV("Not the sequence number I expected");
244
245 return WRONG_SEQUENCE_NUMBER;
246 }
247
248 uint32_t rtpTime;
249 CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
250
251 if (mPackets.size() > 0 && rtpTime != mAccessUnitRTPTime) {
252 submitAccessUnit();
253 }
254 mAccessUnitRTPTime = rtpTime;
255
256 if (!mIsGeneric) {
257 mPackets.push_back(buffer);
258 } else {
259 // hexdump(buffer->data(), buffer->size());
260 if (buffer->size() < 2) {
261 android_errorWriteLog(0x534e4554, "124783982");
262 queue->erase(queue->begin());
263 return MALFORMED_PACKET;
264 }
265
266 unsigned AU_headers_length = U16_AT(buffer->data()); // in bits
267
268 if (buffer->size() < 2 + (AU_headers_length + 7) / 8) {
269 android_errorWriteLog(0x534e4554, "124783982");
270 queue->erase(queue->begin());
271 return MALFORMED_PACKET;
272 }
273
274 List<AUHeader> headers;
275
276 ABitReader bits(buffer->data() + 2, buffer->size() - 2);
277 unsigned numBitsLeft = AU_headers_length;
278
279 unsigned AU_serial = 0;
280 for (;;) {
281 if (numBitsLeft < mSizeLength) { break; }
282
283 unsigned AU_size = bits.getBits(mSizeLength);
284 numBitsLeft -= mSizeLength;
285
286 size_t n = headers.empty() ? mIndexLength : mIndexDeltaLength;
287 if (numBitsLeft < n) { break; }
288
289 unsigned AU_index = bits.getBits(n);
290 numBitsLeft -= n;
291
292 if (headers.empty()) {
293 AU_serial = AU_index;
294 } else {
295 AU_serial += 1 + AU_index;
296 }
297
298 if (mCTSDeltaLength > 0) {
299 if (numBitsLeft < 1) {
300 break;
301 }
302 --numBitsLeft;
303 if (bits.getBits(1)) {
304 if (numBitsLeft < mCTSDeltaLength) {
305 break;
306 }
307 bits.skipBits(mCTSDeltaLength);
308 numBitsLeft -= mCTSDeltaLength;
309 }
310 }
311
312 if (mDTSDeltaLength > 0) {
313 if (numBitsLeft < 1) {
314 break;
315 }
316 --numBitsLeft;
317 if (bits.getBits(1)) {
318 if (numBitsLeft < mDTSDeltaLength) {
319 break;
320 }
321 bits.skipBits(mDTSDeltaLength);
322 numBitsLeft -= mDTSDeltaLength;
323 }
324 }
325
326 if (mRandomAccessIndication) {
327 if (numBitsLeft < 1) {
328 break;
329 }
330 bits.skipBits(1);
331 --numBitsLeft;
332 }
333
334 if (mStreamStateIndication > 0) {
335 if (numBitsLeft < mStreamStateIndication) {
336 break;
337 }
338 bits.skipBits(mStreamStateIndication);
339 }
340
341 AUHeader header;
342 header.mSize = AU_size;
343 header.mSerial = AU_serial;
344 headers.push_back(header);
345 }
346
347 size_t offset = 2 + (AU_headers_length + 7) / 8;
348
349 if (mAuxiliaryDataSizeLength > 0) {
350 ABitReader bits(buffer->data() + offset, buffer->size() - offset);
351
352 unsigned auxSize = bits.getBits(mAuxiliaryDataSizeLength);
353 if (buffer->size() < auxSize) {
354 ALOGE("b/123940919 auxSize %u", auxSize);
355 android_errorWriteLog(0x534e4554, "123940919");
356 queue->erase(queue->begin());
357 return MALFORMED_PACKET;
358 }
359
360 offset += (mAuxiliaryDataSizeLength + auxSize + 7) / 8;
361 }
362
363 for (List<AUHeader>::iterator it = headers.begin();
364 it != headers.end(); ++it) {
365 const AUHeader &header = *it;
366
367 if (buffer->size() < header.mSize) {
368 ALOGE("b/123940919 AU_size %u", header.mSize);
369 android_errorWriteLog(0x534e4554, "123940919");
370 queue->erase(queue->begin());
371 return MALFORMED_PACKET;
372 }
373 if (buffer->size() < offset + header.mSize) {
374 android_errorWriteLog(0x534e4554, "124783982");
375 queue->erase(queue->begin());
376 return MALFORMED_PACKET;
377 }
378
379 sp<ABuffer> accessUnit = new ABuffer(header.mSize);
380 memcpy(accessUnit->data(), buffer->data() + offset, header.mSize);
381
382 offset += header.mSize;
383
384 CopyTimes(accessUnit, buffer);
385 mPackets.push_back(accessUnit);
386 }
387
388 if (offset != buffer->size()) {
389 ALOGW("potentially malformed packet (offset %zu, size %zu)",
390 offset, buffer->size());
391 }
392 }
393
394 queue->erase(queue->begin());
395 ++mNextExpectedSeqNo;
396
397 return OK;
398 }
399
submitAccessUnit()400 void AMPEG4ElementaryAssembler::submitAccessUnit() {
401 CHECK(!mPackets.empty());
402
403 ALOGV("Access unit complete (%zu nal units)", mPackets.size());
404
405 sp<ABuffer> accessUnit;
406
407 if (mIsGeneric) {
408 accessUnit = MakeADTSCompoundFromAACFrames(
409 OMX_AUDIO_AACObjectLC - 1,
410 mSampleRateIndex,
411 mChannelConfig,
412 mPackets);
413 } else {
414 accessUnit = MakeCompoundFromPackets(mPackets);
415 }
416
417 #if 0
418 printf(mAccessUnitDamaged ? "X" : ".");
419 fflush(stdout);
420 #endif
421
422 if (mAccessUnitDamaged) {
423 accessUnit->meta()->setInt32("damaged", true);
424 }
425
426 mPackets.clear();
427 mAccessUnitDamaged = false;
428
429 sp<AMessage> msg = mNotifyMsg->dup();
430 msg->setBuffer("access-unit", accessUnit);
431 msg->post();
432 }
433
assembleMore(const sp<ARTPSource> & source)434 ARTPAssembler::AssemblyStatus AMPEG4ElementaryAssembler::assembleMore(
435 const sp<ARTPSource> &source) {
436 AssemblyStatus status = addPacket(source);
437 if (status == MALFORMED_PACKET) {
438 ALOGI("access unit is damaged");
439 mAccessUnitDamaged = true;
440 }
441 return status;
442 }
443
packetLost()444 void AMPEG4ElementaryAssembler::packetLost() {
445 CHECK(mNextExpectedSeqNoValid);
446 ALOGV("packetLost (expected %d)", mNextExpectedSeqNo);
447
448 ++mNextExpectedSeqNo;
449
450 mAccessUnitDamaged = true;
451 }
452
onByeReceived()453 void AMPEG4ElementaryAssembler::onByeReceived() {
454 sp<AMessage> msg = mNotifyMsg->dup();
455 msg->setInt32("eos", true);
456 msg->post();
457 }
458
459 } // namespace android
460