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 "ESQueue"
19 #include <media/stagefright/foundation/ADebug.h>
20
21 #include "ESQueue.h"
22
23 #include <media/stagefright/foundation/hexdump.h>
24 #include <media/stagefright/foundation/ABitReader.h>
25 #include <media/stagefright/foundation/ABuffer.h>
26 #include <media/stagefright/foundation/AMessage.h>
27 #include <media/stagefright/MediaErrors.h>
28 #include <media/stagefright/MediaDefs.h>
29 #include <media/stagefright/MetaData.h>
30 #include <media/stagefright/Utils.h>
31
32 #include "include/avc_utils.h"
33
34 #include <netinet/in.h>
35
36 namespace android {
37
ElementaryStreamQueue(Mode mode,uint32_t flags)38 ElementaryStreamQueue::ElementaryStreamQueue(Mode mode, uint32_t flags)
39 : mMode(mode),
40 mFlags(flags) {
41 }
42
getFormat()43 sp<MetaData> ElementaryStreamQueue::getFormat() {
44 return mFormat;
45 }
46
clear(bool clearFormat)47 void ElementaryStreamQueue::clear(bool clearFormat) {
48 if (mBuffer != NULL) {
49 mBuffer->setRange(0, 0);
50 }
51
52 mRangeInfos.clear();
53
54 if (clearFormat) {
55 mFormat.clear();
56 }
57 }
58
IsSeeminglyValidADTSHeader(const uint8_t * ptr,size_t size)59 static bool IsSeeminglyValidADTSHeader(const uint8_t *ptr, size_t size) {
60 if (size < 3) {
61 // Not enough data to verify header.
62 return false;
63 }
64
65 if (ptr[0] != 0xff || (ptr[1] >> 4) != 0x0f) {
66 return false;
67 }
68
69 unsigned layer = (ptr[1] >> 1) & 3;
70
71 if (layer != 0) {
72 return false;
73 }
74
75 unsigned ID = (ptr[1] >> 3) & 1;
76 unsigned profile_ObjectType = ptr[2] >> 6;
77
78 if (ID == 1 && profile_ObjectType == 3) {
79 // MPEG-2 profile 3 is reserved.
80 return false;
81 }
82
83 return true;
84 }
85
IsSeeminglyValidMPEGAudioHeader(const uint8_t * ptr,size_t size)86 static bool IsSeeminglyValidMPEGAudioHeader(const uint8_t *ptr, size_t size) {
87 if (size < 3) {
88 // Not enough data to verify header.
89 return false;
90 }
91
92 if (ptr[0] != 0xff || (ptr[1] >> 5) != 0x07) {
93 return false;
94 }
95
96 unsigned ID = (ptr[1] >> 3) & 3;
97
98 if (ID == 1) {
99 return false; // reserved
100 }
101
102 unsigned layer = (ptr[1] >> 1) & 3;
103
104 if (layer == 0) {
105 return false; // reserved
106 }
107
108 unsigned bitrateIndex = (ptr[2] >> 4);
109
110 if (bitrateIndex == 0x0f) {
111 return false; // reserved
112 }
113
114 unsigned samplingRateIndex = (ptr[2] >> 2) & 3;
115
116 if (samplingRateIndex == 3) {
117 return false; // reserved
118 }
119
120 return true;
121 }
122
appendData(const void * data,size_t size,int64_t timeUs)123 status_t ElementaryStreamQueue::appendData(
124 const void *data, size_t size, int64_t timeUs) {
125 if (mBuffer == NULL || mBuffer->size() == 0) {
126 switch (mMode) {
127 case H264:
128 case MPEG_VIDEO:
129 {
130 #if 0
131 if (size < 4 || memcmp("\x00\x00\x00\x01", data, 4)) {
132 return ERROR_MALFORMED;
133 }
134 #else
135 uint8_t *ptr = (uint8_t *)data;
136
137 ssize_t startOffset = -1;
138 for (size_t i = 0; i + 3 < size; ++i) {
139 if (!memcmp("\x00\x00\x00\x01", &ptr[i], 4)) {
140 startOffset = i;
141 break;
142 }
143 }
144
145 if (startOffset < 0) {
146 return ERROR_MALFORMED;
147 }
148
149 if (startOffset > 0) {
150 ALOGI("found something resembling an H.264/MPEG syncword "
151 "at offset %d",
152 startOffset);
153 }
154
155 data = &ptr[startOffset];
156 size -= startOffset;
157 #endif
158 break;
159 }
160
161 case MPEG4_VIDEO:
162 {
163 #if 0
164 if (size < 3 || memcmp("\x00\x00\x01", data, 3)) {
165 return ERROR_MALFORMED;
166 }
167 #else
168 uint8_t *ptr = (uint8_t *)data;
169
170 ssize_t startOffset = -1;
171 for (size_t i = 0; i + 2 < size; ++i) {
172 if (!memcmp("\x00\x00\x01", &ptr[i], 3)) {
173 startOffset = i;
174 break;
175 }
176 }
177
178 if (startOffset < 0) {
179 return ERROR_MALFORMED;
180 }
181
182 if (startOffset > 0) {
183 ALOGI("found something resembling an H.264/MPEG syncword "
184 "at offset %d",
185 startOffset);
186 }
187
188 data = &ptr[startOffset];
189 size -= startOffset;
190 #endif
191 break;
192 }
193
194 case AAC:
195 {
196 uint8_t *ptr = (uint8_t *)data;
197
198 #if 0
199 if (size < 2 || ptr[0] != 0xff || (ptr[1] >> 4) != 0x0f) {
200 return ERROR_MALFORMED;
201 }
202 #else
203 ssize_t startOffset = -1;
204 for (size_t i = 0; i < size; ++i) {
205 if (IsSeeminglyValidADTSHeader(&ptr[i], size - i)) {
206 startOffset = i;
207 break;
208 }
209 }
210
211 if (startOffset < 0) {
212 return ERROR_MALFORMED;
213 }
214
215 if (startOffset > 0) {
216 ALOGI("found something resembling an AAC syncword at "
217 "offset %d",
218 startOffset);
219 }
220
221 data = &ptr[startOffset];
222 size -= startOffset;
223 #endif
224 break;
225 }
226
227 case MPEG_AUDIO:
228 {
229 uint8_t *ptr = (uint8_t *)data;
230
231 ssize_t startOffset = -1;
232 for (size_t i = 0; i < size; ++i) {
233 if (IsSeeminglyValidMPEGAudioHeader(&ptr[i], size - i)) {
234 startOffset = i;
235 break;
236 }
237 }
238
239 if (startOffset < 0) {
240 return ERROR_MALFORMED;
241 }
242
243 if (startOffset > 0) {
244 ALOGI("found something resembling an MPEG audio "
245 "syncword at offset %d",
246 startOffset);
247 }
248
249 data = &ptr[startOffset];
250 size -= startOffset;
251 break;
252 }
253
254 case PCM_AUDIO:
255 {
256 break;
257 }
258
259 default:
260 TRESPASS();
261 break;
262 }
263 }
264
265 size_t neededSize = (mBuffer == NULL ? 0 : mBuffer->size()) + size;
266 if (mBuffer == NULL || neededSize > mBuffer->capacity()) {
267 neededSize = (neededSize + 65535) & ~65535;
268
269 ALOGV("resizing buffer to size %d", neededSize);
270
271 sp<ABuffer> buffer = new ABuffer(neededSize);
272 if (mBuffer != NULL) {
273 memcpy(buffer->data(), mBuffer->data(), mBuffer->size());
274 buffer->setRange(0, mBuffer->size());
275 } else {
276 buffer->setRange(0, 0);
277 }
278
279 mBuffer = buffer;
280 }
281
282 memcpy(mBuffer->data() + mBuffer->size(), data, size);
283 mBuffer->setRange(0, mBuffer->size() + size);
284
285 RangeInfo info;
286 info.mLength = size;
287 info.mTimestampUs = timeUs;
288 mRangeInfos.push_back(info);
289
290 #if 0
291 if (mMode == AAC) {
292 ALOGI("size = %d, timeUs = %.2f secs", size, timeUs / 1E6);
293 hexdump(data, size);
294 }
295 #endif
296
297 return OK;
298 }
299
dequeueAccessUnit()300 sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnit() {
301 if ((mFlags & kFlag_AlignedData) && mMode == H264) {
302 if (mRangeInfos.empty()) {
303 return NULL;
304 }
305
306 RangeInfo info = *mRangeInfos.begin();
307 mRangeInfos.erase(mRangeInfos.begin());
308
309 sp<ABuffer> accessUnit = new ABuffer(info.mLength);
310 memcpy(accessUnit->data(), mBuffer->data(), info.mLength);
311 accessUnit->meta()->setInt64("timeUs", info.mTimestampUs);
312
313 memmove(mBuffer->data(),
314 mBuffer->data() + info.mLength,
315 mBuffer->size() - info.mLength);
316
317 mBuffer->setRange(0, mBuffer->size() - info.mLength);
318
319 if (mFormat == NULL) {
320 mFormat = MakeAVCCodecSpecificData(accessUnit);
321 }
322
323 return accessUnit;
324 }
325
326 switch (mMode) {
327 case H264:
328 return dequeueAccessUnitH264();
329 case AAC:
330 return dequeueAccessUnitAAC();
331 case MPEG_VIDEO:
332 return dequeueAccessUnitMPEGVideo();
333 case MPEG4_VIDEO:
334 return dequeueAccessUnitMPEG4Video();
335 case PCM_AUDIO:
336 return dequeueAccessUnitPCMAudio();
337 default:
338 CHECK_EQ((unsigned)mMode, (unsigned)MPEG_AUDIO);
339 return dequeueAccessUnitMPEGAudio();
340 }
341 }
342
dequeueAccessUnitPCMAudio()343 sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitPCMAudio() {
344 if (mBuffer->size() < 4) {
345 return NULL;
346 }
347
348 ABitReader bits(mBuffer->data(), 4);
349 CHECK_EQ(bits.getBits(8), 0xa0);
350 unsigned numAUs = bits.getBits(8);
351 bits.skipBits(8);
352 unsigned quantization_word_length = bits.getBits(2);
353 unsigned audio_sampling_frequency = bits.getBits(3);
354 unsigned num_channels = bits.getBits(3);
355
356 CHECK_EQ(audio_sampling_frequency, 2); // 48kHz
357 CHECK_EQ(num_channels, 1u); // stereo!
358
359 if (mFormat == NULL) {
360 mFormat = new MetaData;
361 mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
362 mFormat->setInt32(kKeyChannelCount, 2);
363 mFormat->setInt32(kKeySampleRate, 48000);
364 }
365
366 static const size_t kFramesPerAU = 80;
367 size_t frameSize = 2 /* numChannels */ * sizeof(int16_t);
368
369 size_t payloadSize = numAUs * frameSize * kFramesPerAU;
370
371 if (mBuffer->size() < 4 + payloadSize) {
372 return NULL;
373 }
374
375 sp<ABuffer> accessUnit = new ABuffer(payloadSize);
376 memcpy(accessUnit->data(), mBuffer->data() + 4, payloadSize);
377
378 int64_t timeUs = fetchTimestamp(payloadSize + 4);
379 CHECK_GE(timeUs, 0ll);
380 accessUnit->meta()->setInt64("timeUs", timeUs);
381
382 int16_t *ptr = (int16_t *)accessUnit->data();
383 for (size_t i = 0; i < payloadSize / sizeof(int16_t); ++i) {
384 ptr[i] = ntohs(ptr[i]);
385 }
386
387 memmove(
388 mBuffer->data(),
389 mBuffer->data() + 4 + payloadSize,
390 mBuffer->size() - 4 - payloadSize);
391
392 mBuffer->setRange(0, mBuffer->size() - 4 - payloadSize);
393
394 return accessUnit;
395 }
396
dequeueAccessUnitAAC()397 sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitAAC() {
398 if (mBuffer->size() == 0) {
399 return NULL;
400 }
401
402 CHECK(!mRangeInfos.empty());
403
404 const RangeInfo &info = *mRangeInfos.begin();
405 if (mBuffer->size() < info.mLength) {
406 return NULL;
407 }
408
409 CHECK_GE(info.mTimestampUs, 0ll);
410
411 // The idea here is consume all AAC frames starting at offsets before
412 // info.mLength so we can assign a meaningful timestamp without
413 // having to interpolate.
414 // The final AAC frame may well extend into the next RangeInfo but
415 // that's ok.
416 size_t offset = 0;
417 while (offset < info.mLength) {
418 if (offset + 7 > mBuffer->size()) {
419 return NULL;
420 }
421
422 ABitReader bits(mBuffer->data() + offset, mBuffer->size() - offset);
423
424 // adts_fixed_header
425
426 CHECK_EQ(bits.getBits(12), 0xfffu);
427 bits.skipBits(3); // ID, layer
428 bool protection_absent = bits.getBits(1) != 0;
429
430 if (mFormat == NULL) {
431 unsigned profile = bits.getBits(2);
432 CHECK_NE(profile, 3u);
433 unsigned sampling_freq_index = bits.getBits(4);
434 bits.getBits(1); // private_bit
435 unsigned channel_configuration = bits.getBits(3);
436 CHECK_NE(channel_configuration, 0u);
437 bits.skipBits(2); // original_copy, home
438
439 mFormat = MakeAACCodecSpecificData(
440 profile, sampling_freq_index, channel_configuration);
441
442 mFormat->setInt32(kKeyIsADTS, true);
443
444 int32_t sampleRate;
445 int32_t numChannels;
446 CHECK(mFormat->findInt32(kKeySampleRate, &sampleRate));
447 CHECK(mFormat->findInt32(kKeyChannelCount, &numChannels));
448
449 ALOGI("found AAC codec config (%d Hz, %d channels)",
450 sampleRate, numChannels);
451 } else {
452 // profile_ObjectType, sampling_frequency_index, private_bits,
453 // channel_configuration, original_copy, home
454 bits.skipBits(12);
455 }
456
457 // adts_variable_header
458
459 // copyright_identification_bit, copyright_identification_start
460 bits.skipBits(2);
461
462 unsigned aac_frame_length = bits.getBits(13);
463
464 bits.skipBits(11); // adts_buffer_fullness
465
466 unsigned number_of_raw_data_blocks_in_frame = bits.getBits(2);
467
468 if (number_of_raw_data_blocks_in_frame != 0) {
469 // To be implemented.
470 TRESPASS();
471 }
472
473 if (offset + aac_frame_length > mBuffer->size()) {
474 return NULL;
475 }
476
477 size_t headerSize = protection_absent ? 7 : 9;
478
479 offset += aac_frame_length;
480 }
481
482 int64_t timeUs = fetchTimestamp(offset);
483
484 sp<ABuffer> accessUnit = new ABuffer(offset);
485 memcpy(accessUnit->data(), mBuffer->data(), offset);
486
487 memmove(mBuffer->data(), mBuffer->data() + offset,
488 mBuffer->size() - offset);
489 mBuffer->setRange(0, mBuffer->size() - offset);
490
491 accessUnit->meta()->setInt64("timeUs", timeUs);
492
493 return accessUnit;
494 }
495
fetchTimestamp(size_t size)496 int64_t ElementaryStreamQueue::fetchTimestamp(size_t size) {
497 int64_t timeUs = -1;
498 bool first = true;
499
500 while (size > 0) {
501 CHECK(!mRangeInfos.empty());
502
503 RangeInfo *info = &*mRangeInfos.begin();
504
505 if (first) {
506 timeUs = info->mTimestampUs;
507 }
508
509 if (info->mLength > size) {
510 info->mLength -= size;
511
512 if (first) {
513 info->mTimestampUs = -1;
514 }
515
516 size = 0;
517 } else {
518 size -= info->mLength;
519
520 mRangeInfos.erase(mRangeInfos.begin());
521 info = NULL;
522 }
523
524 first = false;
525 }
526
527 if (timeUs == 0ll) {
528 ALOGV("Returning 0 timestamp");
529 }
530
531 return timeUs;
532 }
533
534 struct NALPosition {
535 size_t nalOffset;
536 size_t nalSize;
537 };
538
dequeueAccessUnitH264()539 sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitH264() {
540 const uint8_t *data = mBuffer->data();
541
542 size_t size = mBuffer->size();
543 Vector<NALPosition> nals;
544
545 size_t totalSize = 0;
546
547 status_t err;
548 const uint8_t *nalStart;
549 size_t nalSize;
550 bool foundSlice = false;
551 while ((err = getNextNALUnit(&data, &size, &nalStart, &nalSize)) == OK) {
552 if (nalSize == 0) continue;
553
554 unsigned nalType = nalStart[0] & 0x1f;
555 bool flush = false;
556
557 if (nalType == 1 || nalType == 5) {
558 if (foundSlice) {
559 ABitReader br(nalStart + 1, nalSize);
560 unsigned first_mb_in_slice = parseUE(&br);
561
562 if (first_mb_in_slice == 0) {
563 // This slice starts a new frame.
564
565 flush = true;
566 }
567 }
568
569 foundSlice = true;
570 } else if ((nalType == 9 || nalType == 7) && foundSlice) {
571 // Access unit delimiter and SPS will be associated with the
572 // next frame.
573
574 flush = true;
575 }
576
577 if (flush) {
578 // The access unit will contain all nal units up to, but excluding
579 // the current one, separated by 0x00 0x00 0x00 0x01 startcodes.
580
581 size_t auSize = 4 * nals.size() + totalSize;
582 sp<ABuffer> accessUnit = new ABuffer(auSize);
583
584 #if !LOG_NDEBUG
585 AString out;
586 #endif
587
588 size_t dstOffset = 0;
589 for (size_t i = 0; i < nals.size(); ++i) {
590 const NALPosition &pos = nals.itemAt(i);
591
592 unsigned nalType = mBuffer->data()[pos.nalOffset] & 0x1f;
593
594 #if !LOG_NDEBUG
595 char tmp[128];
596 sprintf(tmp, "0x%02x", nalType);
597 if (i > 0) {
598 out.append(", ");
599 }
600 out.append(tmp);
601 #endif
602
603 memcpy(accessUnit->data() + dstOffset, "\x00\x00\x00\x01", 4);
604
605 memcpy(accessUnit->data() + dstOffset + 4,
606 mBuffer->data() + pos.nalOffset,
607 pos.nalSize);
608
609 dstOffset += pos.nalSize + 4;
610 }
611
612 ALOGV("accessUnit contains nal types %s", out.c_str());
613
614 const NALPosition &pos = nals.itemAt(nals.size() - 1);
615 size_t nextScan = pos.nalOffset + pos.nalSize;
616
617 memmove(mBuffer->data(),
618 mBuffer->data() + nextScan,
619 mBuffer->size() - nextScan);
620
621 mBuffer->setRange(0, mBuffer->size() - nextScan);
622
623 int64_t timeUs = fetchTimestamp(nextScan);
624 CHECK_GE(timeUs, 0ll);
625
626 accessUnit->meta()->setInt64("timeUs", timeUs);
627
628 if (mFormat == NULL) {
629 mFormat = MakeAVCCodecSpecificData(accessUnit);
630 }
631
632 return accessUnit;
633 }
634
635 NALPosition pos;
636 pos.nalOffset = nalStart - mBuffer->data();
637 pos.nalSize = nalSize;
638
639 nals.push(pos);
640
641 totalSize += nalSize;
642 }
643 CHECK_EQ(err, (status_t)-EAGAIN);
644
645 return NULL;
646 }
647
dequeueAccessUnitMPEGAudio()648 sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGAudio() {
649 const uint8_t *data = mBuffer->data();
650 size_t size = mBuffer->size();
651
652 if (size < 4) {
653 return NULL;
654 }
655
656 uint32_t header = U32_AT(data);
657
658 size_t frameSize;
659 int samplingRate, numChannels, bitrate, numSamples;
660 CHECK(GetMPEGAudioFrameSize(
661 header, &frameSize, &samplingRate, &numChannels,
662 &bitrate, &numSamples));
663
664 if (size < frameSize) {
665 return NULL;
666 }
667
668 unsigned layer = 4 - ((header >> 17) & 3);
669
670 sp<ABuffer> accessUnit = new ABuffer(frameSize);
671 memcpy(accessUnit->data(), data, frameSize);
672
673 memmove(mBuffer->data(),
674 mBuffer->data() + frameSize,
675 mBuffer->size() - frameSize);
676
677 mBuffer->setRange(0, mBuffer->size() - frameSize);
678
679 int64_t timeUs = fetchTimestamp(frameSize);
680 CHECK_GE(timeUs, 0ll);
681
682 accessUnit->meta()->setInt64("timeUs", timeUs);
683
684 if (mFormat == NULL) {
685 mFormat = new MetaData;
686
687 switch (layer) {
688 case 1:
689 mFormat->setCString(
690 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I);
691 break;
692 case 2:
693 mFormat->setCString(
694 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II);
695 break;
696 case 3:
697 mFormat->setCString(
698 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
699 break;
700 default:
701 TRESPASS();
702 }
703
704 mFormat->setInt32(kKeySampleRate, samplingRate);
705 mFormat->setInt32(kKeyChannelCount, numChannels);
706 }
707
708 return accessUnit;
709 }
710
EncodeSize14(uint8_t ** _ptr,size_t size)711 static void EncodeSize14(uint8_t **_ptr, size_t size) {
712 CHECK_LE(size, 0x3fff);
713
714 uint8_t *ptr = *_ptr;
715
716 *ptr++ = 0x80 | (size >> 7);
717 *ptr++ = size & 0x7f;
718
719 *_ptr = ptr;
720 }
721
MakeMPEGVideoESDS(const sp<ABuffer> & csd)722 static sp<ABuffer> MakeMPEGVideoESDS(const sp<ABuffer> &csd) {
723 sp<ABuffer> esds = new ABuffer(csd->size() + 25);
724
725 uint8_t *ptr = esds->data();
726 *ptr++ = 0x03;
727 EncodeSize14(&ptr, 22 + csd->size());
728
729 *ptr++ = 0x00; // ES_ID
730 *ptr++ = 0x00;
731
732 *ptr++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag
733
734 *ptr++ = 0x04;
735 EncodeSize14(&ptr, 16 + csd->size());
736
737 *ptr++ = 0x40; // Audio ISO/IEC 14496-3
738
739 for (size_t i = 0; i < 12; ++i) {
740 *ptr++ = 0x00;
741 }
742
743 *ptr++ = 0x05;
744 EncodeSize14(&ptr, csd->size());
745
746 memcpy(ptr, csd->data(), csd->size());
747
748 return esds;
749 }
750
dequeueAccessUnitMPEGVideo()751 sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGVideo() {
752 const uint8_t *data = mBuffer->data();
753 size_t size = mBuffer->size();
754
755 bool sawPictureStart = false;
756 int pprevStartCode = -1;
757 int prevStartCode = -1;
758 int currentStartCode = -1;
759
760 size_t offset = 0;
761 while (offset + 3 < size) {
762 if (memcmp(&data[offset], "\x00\x00\x01", 3)) {
763 ++offset;
764 continue;
765 }
766
767 pprevStartCode = prevStartCode;
768 prevStartCode = currentStartCode;
769 currentStartCode = data[offset + 3];
770
771 if (currentStartCode == 0xb3 && mFormat == NULL) {
772 memmove(mBuffer->data(), mBuffer->data() + offset, size - offset);
773 size -= offset;
774 (void)fetchTimestamp(offset);
775 offset = 0;
776 mBuffer->setRange(0, size);
777 }
778
779 if ((prevStartCode == 0xb3 && currentStartCode != 0xb5)
780 || (pprevStartCode == 0xb3 && prevStartCode == 0xb5)) {
781 // seqHeader without/with extension
782
783 if (mFormat == NULL) {
784 CHECK_GE(size, 7u);
785
786 unsigned width =
787 (data[4] << 4) | data[5] >> 4;
788
789 unsigned height =
790 ((data[5] & 0x0f) << 8) | data[6];
791
792 mFormat = new MetaData;
793 mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2);
794 mFormat->setInt32(kKeyWidth, width);
795 mFormat->setInt32(kKeyHeight, height);
796
797 ALOGI("found MPEG2 video codec config (%d x %d)", width, height);
798
799 sp<ABuffer> csd = new ABuffer(offset);
800 memcpy(csd->data(), data, offset);
801
802 memmove(mBuffer->data(),
803 mBuffer->data() + offset,
804 mBuffer->size() - offset);
805
806 mBuffer->setRange(0, mBuffer->size() - offset);
807 size -= offset;
808 (void)fetchTimestamp(offset);
809 offset = 0;
810
811 // hexdump(csd->data(), csd->size());
812
813 sp<ABuffer> esds = MakeMPEGVideoESDS(csd);
814 mFormat->setData(
815 kKeyESDS, kTypeESDS, esds->data(), esds->size());
816
817 return NULL;
818 }
819 }
820
821 if (mFormat != NULL && currentStartCode == 0x00) {
822 // Picture start
823
824 if (!sawPictureStart) {
825 sawPictureStart = true;
826 } else {
827 sp<ABuffer> accessUnit = new ABuffer(offset);
828 memcpy(accessUnit->data(), data, offset);
829
830 memmove(mBuffer->data(),
831 mBuffer->data() + offset,
832 mBuffer->size() - offset);
833
834 mBuffer->setRange(0, mBuffer->size() - offset);
835
836 int64_t timeUs = fetchTimestamp(offset);
837 CHECK_GE(timeUs, 0ll);
838
839 offset = 0;
840
841 accessUnit->meta()->setInt64("timeUs", timeUs);
842
843 ALOGV("returning MPEG video access unit at time %lld us",
844 timeUs);
845
846 // hexdump(accessUnit->data(), accessUnit->size());
847
848 return accessUnit;
849 }
850 }
851
852 ++offset;
853 }
854
855 return NULL;
856 }
857
getNextChunkSize(const uint8_t * data,size_t size)858 static ssize_t getNextChunkSize(
859 const uint8_t *data, size_t size) {
860 static const char kStartCode[] = "\x00\x00\x01";
861
862 if (size < 3) {
863 return -EAGAIN;
864 }
865
866 if (memcmp(kStartCode, data, 3)) {
867 TRESPASS();
868 }
869
870 size_t offset = 3;
871 while (offset + 2 < size) {
872 if (!memcmp(&data[offset], kStartCode, 3)) {
873 return offset;
874 }
875
876 ++offset;
877 }
878
879 return -EAGAIN;
880 }
881
dequeueAccessUnitMPEG4Video()882 sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEG4Video() {
883 uint8_t *data = mBuffer->data();
884 size_t size = mBuffer->size();
885
886 enum {
887 SKIP_TO_VISUAL_OBJECT_SEQ_START,
888 EXPECT_VISUAL_OBJECT_START,
889 EXPECT_VO_START,
890 EXPECT_VOL_START,
891 WAIT_FOR_VOP_START,
892 SKIP_TO_VOP_START,
893
894 } state;
895
896 if (mFormat == NULL) {
897 state = SKIP_TO_VISUAL_OBJECT_SEQ_START;
898 } else {
899 state = SKIP_TO_VOP_START;
900 }
901
902 int32_t width = -1, height = -1;
903
904 size_t offset = 0;
905 ssize_t chunkSize;
906 while ((chunkSize = getNextChunkSize(
907 &data[offset], size - offset)) > 0) {
908 bool discard = false;
909
910 unsigned chunkType = data[offset + 3];
911
912 switch (state) {
913 case SKIP_TO_VISUAL_OBJECT_SEQ_START:
914 {
915 if (chunkType == 0xb0) {
916 // Discard anything before this marker.
917
918 state = EXPECT_VISUAL_OBJECT_START;
919 } else {
920 discard = true;
921 }
922 break;
923 }
924
925 case EXPECT_VISUAL_OBJECT_START:
926 {
927 CHECK_EQ(chunkType, 0xb5);
928 state = EXPECT_VO_START;
929 break;
930 }
931
932 case EXPECT_VO_START:
933 {
934 CHECK_LE(chunkType, 0x1f);
935 state = EXPECT_VOL_START;
936 break;
937 }
938
939 case EXPECT_VOL_START:
940 {
941 CHECK((chunkType & 0xf0) == 0x20);
942
943 CHECK(ExtractDimensionsFromVOLHeader(
944 &data[offset], chunkSize,
945 &width, &height));
946
947 state = WAIT_FOR_VOP_START;
948 break;
949 }
950
951 case WAIT_FOR_VOP_START:
952 {
953 if (chunkType == 0xb3 || chunkType == 0xb6) {
954 // group of VOP or VOP start.
955
956 mFormat = new MetaData;
957 mFormat->setCString(
958 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
959
960 mFormat->setInt32(kKeyWidth, width);
961 mFormat->setInt32(kKeyHeight, height);
962
963 ALOGI("found MPEG4 video codec config (%d x %d)",
964 width, height);
965
966 sp<ABuffer> csd = new ABuffer(offset);
967 memcpy(csd->data(), data, offset);
968
969 // hexdump(csd->data(), csd->size());
970
971 sp<ABuffer> esds = MakeMPEGVideoESDS(csd);
972 mFormat->setData(
973 kKeyESDS, kTypeESDS,
974 esds->data(), esds->size());
975
976 discard = true;
977 state = SKIP_TO_VOP_START;
978 }
979
980 break;
981 }
982
983 case SKIP_TO_VOP_START:
984 {
985 if (chunkType == 0xb6) {
986 offset += chunkSize;
987
988 sp<ABuffer> accessUnit = new ABuffer(offset);
989 memcpy(accessUnit->data(), data, offset);
990
991 memmove(data, &data[offset], size - offset);
992 size -= offset;
993 mBuffer->setRange(0, size);
994
995 int64_t timeUs = fetchTimestamp(offset);
996 CHECK_GE(timeUs, 0ll);
997
998 offset = 0;
999
1000 accessUnit->meta()->setInt64("timeUs", timeUs);
1001
1002 ALOGV("returning MPEG4 video access unit at time %lld us",
1003 timeUs);
1004
1005 // hexdump(accessUnit->data(), accessUnit->size());
1006
1007 return accessUnit;
1008 } else if (chunkType != 0xb3) {
1009 offset += chunkSize;
1010 discard = true;
1011 }
1012
1013 break;
1014 }
1015
1016 default:
1017 TRESPASS();
1018 }
1019
1020 if (discard) {
1021 (void)fetchTimestamp(offset);
1022 memmove(data, &data[offset], size - offset);
1023 size -= offset;
1024 offset = 0;
1025 mBuffer->setRange(0, size);
1026 } else {
1027 offset += chunkSize;
1028 }
1029 }
1030
1031 return NULL;
1032 }
1033
1034 } // namespace android
1035