• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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 "MPEG2PSExtractor"
19 #include <utils/Log.h>
20 
21 #include "MPEG2PSExtractor.h"
22 
23 #include "mpeg2ts/AnotherPacketSource.h"
24 #include "mpeg2ts/ESQueue.h"
25 
26 #include <media/DataSourceBase.h>
27 #include <media/stagefright/foundation/ABitReader.h>
28 #include <media/stagefright/foundation/ABuffer.h>
29 #include <media/stagefright/foundation/ADebug.h>
30 #include <media/stagefright/foundation/AMessage.h>
31 #include <media/stagefright/foundation/ByteUtils.h>
32 #include <media/stagefright/foundation/hexdump.h>
33 #include <media/stagefright/MediaDefs.h>
34 #include <media/stagefright/MediaErrors.h>
35 #include <media/stagefright/MetaData.h>
36 #include <media/stagefright/Utils.h>
37 #include <utils/String8.h>
38 
39 #include <inttypes.h>
40 
41 namespace android {
42 
43 struct MPEG2PSExtractor::Track : public MediaTrackHelper {
44     Track(MPEG2PSExtractor *extractor,
45           unsigned stream_id, unsigned stream_type);
46 
47     virtual media_status_t start();
48     virtual media_status_t stop();
49     virtual media_status_t getFormat(AMediaFormat *);
50 
51     virtual media_status_t read(
52             MediaBufferHelper **buffer, const ReadOptions *options);
53 
54 protected:
55     virtual ~Track();
56 
57 private:
58     friend struct MPEG2PSExtractor;
59 
60     MPEG2PSExtractor *mExtractor;
61 
62     unsigned mStreamID;
63     unsigned mStreamType;
64     ElementaryStreamQueue *mQueue;
65     sp<AnotherPacketSource> mSource;
66 
67     status_t appendPESData(
68             unsigned PTS_DTS_flags,
69             uint64_t PTS, uint64_t DTS,
70             const uint8_t *data, size_t size);
71 
72     DISALLOW_EVIL_CONSTRUCTORS(Track);
73 };
74 
75 struct MPEG2PSExtractor::WrappedTrack : public MediaTrackHelper {
76     WrappedTrack(MPEG2PSExtractor *extractor, Track *track);
77 
78     virtual media_status_t start();
79     virtual media_status_t stop();
80     virtual media_status_t getFormat(AMediaFormat *);
81 
82     virtual media_status_t read(
83             MediaBufferHelper **buffer, const ReadOptions *options);
84 
85 protected:
86     virtual ~WrappedTrack();
87 
88 private:
89     MPEG2PSExtractor *mExtractor;
90     MPEG2PSExtractor::Track *mTrack;
91 
92     DISALLOW_EVIL_CONSTRUCTORS(WrappedTrack);
93 };
94 
95 ////////////////////////////////////////////////////////////////////////////////
96 
MPEG2PSExtractor(DataSourceHelper * source)97 MPEG2PSExtractor::MPEG2PSExtractor(DataSourceHelper *source)
98     : mDataSource(source),
99       mOffset(0),
100       mFinalResult(OK),
101       mBuffer(new ABuffer(0)),
102       mScanning(true),
103       mProgramStreamMapValid(false) {
104     for (size_t i = 0; i < 500; ++i) {
105         if (feedMore() != OK) {
106             break;
107         }
108     }
109 
110     // Remove all tracks that were unable to determine their format.
111     AMediaFormat *meta = AMediaFormat_new();
112     for (size_t i = mTracks.size(); i > 0;) {
113         i--;
114         if (mTracks.valueAt(i)->getFormat(meta) != AMEDIA_OK) {
115             mTracks.removeItemsAt(i);
116         }
117     }
118     AMediaFormat_delete(meta);
119 
120     mScanning = false;
121 }
122 
~MPEG2PSExtractor()123 MPEG2PSExtractor::~MPEG2PSExtractor() {
124     delete mDataSource;
125 }
126 
countTracks()127 size_t MPEG2PSExtractor::countTracks() {
128     return mTracks.size();
129 }
130 
getTrack(size_t index)131 MediaTrackHelper *MPEG2PSExtractor::getTrack(size_t index) {
132     if (index >= mTracks.size()) {
133         return NULL;
134     }
135 
136     return new WrappedTrack(this, mTracks.valueAt(index));
137 }
138 
getTrackMetaData(AMediaFormat * meta,size_t index,uint32_t)139 media_status_t MPEG2PSExtractor::getTrackMetaData(
140         AMediaFormat *meta,
141         size_t index, uint32_t /* flags */) {
142     if (index >= mTracks.size()) {
143         return AMEDIA_ERROR_UNKNOWN;
144     }
145 
146     return mTracks.valueAt(index)->getFormat(meta);
147 }
148 
getMetaData(AMediaFormat * meta)149 media_status_t MPEG2PSExtractor::getMetaData(AMediaFormat *meta) {
150     AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_CONTAINER_MPEG2PS);
151 
152     return AMEDIA_OK;
153 }
154 
flags() const155 uint32_t MPEG2PSExtractor::flags() const {
156     return CAN_PAUSE;
157 }
158 
feedMore()159 status_t MPEG2PSExtractor::feedMore() {
160     Mutex::Autolock autoLock(mLock);
161 
162     // How much data we're reading at a time
163     static const size_t kChunkSize = 8192;
164 
165     for (;;) {
166         status_t err = dequeueChunk();
167 
168         if (err == -EAGAIN && mFinalResult == OK) {
169             memmove(mBuffer->base(), mBuffer->data(), mBuffer->size());
170             mBuffer->setRange(0, mBuffer->size());
171 
172             if (mBuffer->size() + kChunkSize > mBuffer->capacity()) {
173                 size_t newCapacity = mBuffer->capacity() + kChunkSize;
174                 sp<ABuffer> newBuffer = new ABuffer(newCapacity);
175                 memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size());
176                 newBuffer->setRange(0, mBuffer->size());
177                 mBuffer = newBuffer;
178             }
179 
180             ssize_t n = mDataSource->readAt(
181                     mOffset, mBuffer->data() + mBuffer->size(), kChunkSize);
182 
183             if (n < (ssize_t)kChunkSize) {
184                 mFinalResult = (n < 0) ? (status_t)n : ERROR_END_OF_STREAM;
185                 return mFinalResult;
186             }
187 
188             mBuffer->setRange(mBuffer->offset(), mBuffer->size() + n);
189             mOffset += n;
190         } else if (err != OK) {
191             mFinalResult = err;
192             return err;
193         } else {
194             return OK;
195         }
196     }
197 }
198 
dequeueChunk()199 status_t MPEG2PSExtractor::dequeueChunk() {
200     if (mBuffer->size() < 4) {
201         return -EAGAIN;
202     }
203 
204     if (memcmp("\x00\x00\x01", mBuffer->data(), 3)) {
205         return ERROR_MALFORMED;
206     }
207 
208     unsigned chunkType = mBuffer->data()[3];
209 
210     ssize_t res;
211 
212     switch (chunkType) {
213         case 0xba:
214         {
215             res = dequeuePack();
216             break;
217         }
218 
219         case 0xbb:
220         {
221             res = dequeueSystemHeader();
222             break;
223         }
224 
225         default:
226         {
227             res = dequeuePES();
228             break;
229         }
230     }
231 
232     if (res > 0) {
233         if (mBuffer->size() < (size_t)res) {
234             return -EAGAIN;
235         }
236 
237         mBuffer->setRange(mBuffer->offset() + res, mBuffer->size() - res);
238         res = OK;
239     }
240 
241     return res;
242 }
243 
dequeuePack()244 ssize_t MPEG2PSExtractor::dequeuePack() {
245     // 32 + 2 + 3 + 1 + 15 + 1 + 15+ 1 + 9 + 1 + 22 + 1 + 1 | +5
246 
247     if (mBuffer->size() < 14) {
248         return -EAGAIN;
249     }
250 
251     unsigned pack_stuffing_length = mBuffer->data()[13] & 7;
252 
253     return pack_stuffing_length + 14;
254 }
255 
dequeueSystemHeader()256 ssize_t MPEG2PSExtractor::dequeueSystemHeader() {
257     if (mBuffer->size() < 6) {
258         return -EAGAIN;
259     }
260 
261     unsigned header_length = U16_AT(mBuffer->data() + 4);
262 
263     return header_length + 6;
264 }
265 
dequeuePES()266 ssize_t MPEG2PSExtractor::dequeuePES() {
267     if (mBuffer->size() < 6) {
268         return -EAGAIN;
269     }
270 
271     unsigned PES_packet_length = U16_AT(mBuffer->data() + 4);
272     if (PES_packet_length == 0u) {
273         ALOGE("PES_packet_length is 0");
274         return -EAGAIN;
275     }
276 
277     size_t n = PES_packet_length + 6;
278 
279     if (mBuffer->size() < n) {
280         return -EAGAIN;
281     }
282 
283     ABitReader br(mBuffer->data(), n);
284 
285     unsigned packet_startcode_prefix = br.getBits(24);
286 
287     ALOGV("packet_startcode_prefix = 0x%08x", packet_startcode_prefix);
288 
289     if (packet_startcode_prefix != 1) {
290         ALOGV("Supposedly payload_unit_start=1 unit does not start "
291              "with startcode.");
292 
293         return ERROR_MALFORMED;
294     }
295 
296     if (packet_startcode_prefix != 0x000001u) {
297         ALOGE("Wrong PES prefix");
298         return ERROR_MALFORMED;
299     }
300 
301     unsigned stream_id = br.getBits(8);
302     ALOGV("stream_id = 0x%02x", stream_id);
303 
304     /* unsigned PES_packet_length = */br.getBits(16);
305 
306     if (stream_id == 0xbc) {
307         // program_stream_map
308 
309         if (!mScanning) {
310             return n;
311         }
312 
313         mStreamTypeByESID.clear();
314 
315         /* unsigned current_next_indicator = */br.getBits(1);
316         /* unsigned reserved = */br.getBits(2);
317         /* unsigned program_stream_map_version = */br.getBits(5);
318         /* unsigned reserved = */br.getBits(7);
319         /* unsigned marker_bit = */br.getBits(1);
320         unsigned program_stream_info_length = br.getBits(16);
321 
322         size_t offset = 0;
323         while (offset < program_stream_info_length) {
324             if (offset + 2 > program_stream_info_length) {
325                 return ERROR_MALFORMED;
326             }
327 
328             unsigned descriptor_tag = br.getBits(8);
329             unsigned descriptor_length = br.getBits(8);
330 
331             ALOGI("found descriptor tag 0x%02x of length %u",
332                  descriptor_tag, descriptor_length);
333 
334             if (offset + 2 + descriptor_length > program_stream_info_length) {
335                 return ERROR_MALFORMED;
336             }
337 
338             br.skipBits(8 * descriptor_length);
339 
340             offset += 2 + descriptor_length;
341         }
342 
343         unsigned elementary_stream_map_length = br.getBits(16);
344 
345         offset = 0;
346         while (offset < elementary_stream_map_length) {
347             if (offset + 4 > elementary_stream_map_length) {
348                 return ERROR_MALFORMED;
349             }
350 
351             unsigned stream_type = br.getBits(8);
352             unsigned elementary_stream_id = br.getBits(8);
353 
354             ALOGI("elementary stream id 0x%02x has stream type 0x%02x",
355                  elementary_stream_id, stream_type);
356 
357             mStreamTypeByESID.add(elementary_stream_id, stream_type);
358 
359             unsigned elementary_stream_info_length = br.getBits(16);
360 
361             if (offset + 4 + elementary_stream_info_length
362                     > elementary_stream_map_length) {
363                 return ERROR_MALFORMED;
364             }
365 
366             offset += 4 + elementary_stream_info_length;
367         }
368 
369         /* unsigned CRC32 = */br.getBits(32);
370 
371         mProgramStreamMapValid = true;
372     } else if (stream_id != 0xbe  // padding_stream
373             && stream_id != 0xbf  // private_stream_2
374             && stream_id != 0xf0  // ECM
375             && stream_id != 0xf1  // EMM
376             && stream_id != 0xff  // program_stream_directory
377             && stream_id != 0xf2  // DSMCC
378             && stream_id != 0xf8) {  // H.222.1 type E
379         /* unsigned PES_marker_bits = */br.getBits(2);  // should be 0x2(hex)
380         /* unsigned PES_scrambling_control = */br.getBits(2);
381         /* unsigned PES_priority = */br.getBits(1);
382         /* unsigned data_alignment_indicator = */br.getBits(1);
383         /* unsigned copyright = */br.getBits(1);
384         /* unsigned original_or_copy = */br.getBits(1);
385 
386         unsigned PTS_DTS_flags = br.getBits(2);
387         ALOGV("PTS_DTS_flags = %u", PTS_DTS_flags);
388 
389         unsigned ESCR_flag = br.getBits(1);
390         ALOGV("ESCR_flag = %u", ESCR_flag);
391 
392         unsigned ES_rate_flag = br.getBits(1);
393         ALOGV("ES_rate_flag = %u", ES_rate_flag);
394 
395         unsigned DSM_trick_mode_flag = br.getBits(1);
396         ALOGV("DSM_trick_mode_flag = %u", DSM_trick_mode_flag);
397 
398         unsigned additional_copy_info_flag = br.getBits(1);
399         ALOGV("additional_copy_info_flag = %u", additional_copy_info_flag);
400 
401         /* unsigned PES_CRC_flag = */br.getBits(1);
402         /* PES_extension_flag = */br.getBits(1);
403 
404         unsigned PES_header_data_length = br.getBits(8);
405         ALOGV("PES_header_data_length = %u", PES_header_data_length);
406 
407         unsigned optional_bytes_remaining = PES_header_data_length;
408 
409         uint64_t PTS = 0, DTS = 0;
410 
411         if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {
412             if (optional_bytes_remaining < 5u) {
413                 return ERROR_MALFORMED;
414             }
415 
416             if (br.getBits(4) != PTS_DTS_flags) {
417                 return ERROR_MALFORMED;
418             }
419 
420             PTS = ((uint64_t)br.getBits(3)) << 30;
421             if (br.getBits(1) != 1u) {
422                 return ERROR_MALFORMED;
423             }
424             PTS |= ((uint64_t)br.getBits(15)) << 15;
425             if (br.getBits(1) != 1u) {
426                 return ERROR_MALFORMED;
427             }
428             PTS |= br.getBits(15);
429             if (br.getBits(1) != 1u) {
430                 return ERROR_MALFORMED;
431             }
432 
433             ALOGV("PTS = %" PRIu64, PTS);
434             // ALOGI("PTS = %.2f secs", PTS / 90000.0f);
435 
436             optional_bytes_remaining -= 5;
437 
438             if (PTS_DTS_flags == 3) {
439                 if (optional_bytes_remaining < 5u) {
440                     return ERROR_MALFORMED;
441                 }
442 
443                 if (br.getBits(4) != 1u) {
444                     return ERROR_MALFORMED;
445                 }
446 
447                 DTS = ((uint64_t)br.getBits(3)) << 30;
448                 if (br.getBits(1) != 1u) {
449                     return ERROR_MALFORMED;
450                 }
451                 DTS |= ((uint64_t)br.getBits(15)) << 15;
452                 if (br.getBits(1) != 1u) {
453                     return ERROR_MALFORMED;
454                 }
455                 DTS |= br.getBits(15);
456                 if (br.getBits(1) != 1u) {
457                     return ERROR_MALFORMED;
458                 }
459 
460                 ALOGV("DTS = %" PRIu64, DTS);
461 
462                 optional_bytes_remaining -= 5;
463             }
464         }
465 
466         if (ESCR_flag) {
467             if (optional_bytes_remaining < 6u) {
468                 return ERROR_MALFORMED;
469             }
470 
471             br.getBits(2);
472 
473             uint64_t ESCR = ((uint64_t)br.getBits(3)) << 30;
474             if (br.getBits(1) != 1u) {
475                 return ERROR_MALFORMED;
476             }
477             ESCR |= ((uint64_t)br.getBits(15)) << 15;
478             if (br.getBits(1) != 1u) {
479                 return ERROR_MALFORMED;
480             }
481             ESCR |= br.getBits(15);
482             if (br.getBits(1) != 1u) {
483                 return ERROR_MALFORMED;
484             }
485 
486             ALOGV("ESCR = %" PRIu64, ESCR);
487             /* unsigned ESCR_extension = */br.getBits(9);
488 
489             if (br.getBits(1) != 1u) {
490                 return ERROR_MALFORMED;
491             }
492 
493             optional_bytes_remaining -= 6;
494         }
495 
496         if (ES_rate_flag) {
497             if (optional_bytes_remaining < 3u) {
498                 return ERROR_MALFORMED;
499             }
500 
501             if (br.getBits(1) != 1u) {
502                 return ERROR_MALFORMED;
503             }
504             /* unsigned ES_rate = */br.getBits(22);
505             if (br.getBits(1) != 1u) {
506                 return ERROR_MALFORMED;
507             }
508 
509             optional_bytes_remaining -= 3;
510         }
511 
512         if (br.numBitsLeft() < optional_bytes_remaining * 8) {
513             return ERROR_MALFORMED;
514         }
515 
516         br.skipBits(optional_bytes_remaining * 8);
517 
518         // ES data follows.
519 
520         if (PES_packet_length < PES_header_data_length + 3) {
521             return ERROR_MALFORMED;
522         }
523 
524         unsigned dataLength =
525             PES_packet_length - 3 - PES_header_data_length;
526 
527         if (br.numBitsLeft() < dataLength * 8) {
528             ALOGE("PES packet does not carry enough data to contain "
529                  "payload. (numBitsLeft = %zu, required = %u)",
530                  br.numBitsLeft(), dataLength * 8);
531 
532             return ERROR_MALFORMED;
533         }
534 
535         if (br.numBitsLeft() < dataLength * 8) {
536             return ERROR_MALFORMED;
537         }
538 
539         ssize_t index = mTracks.indexOfKey(stream_id);
540         if (index < 0 && mScanning) {
541             unsigned streamType;
542 
543             ssize_t streamTypeIndex;
544             if (mProgramStreamMapValid
545                     && (streamTypeIndex =
546                             mStreamTypeByESID.indexOfKey(stream_id)) >= 0) {
547                 streamType = mStreamTypeByESID.valueAt(streamTypeIndex);
548             } else if ((stream_id & ~0x1f) == 0xc0) {
549                 // ISO/IEC 13818-3 or ISO/IEC 11172-3 or ISO/IEC 13818-7
550                 // or ISO/IEC 14496-3 audio
551                 streamType = ATSParser::STREAMTYPE_MPEG2_AUDIO;
552             } else if ((stream_id & ~0x0f) == 0xe0) {
553                 // ISO/IEC 13818-2 or ISO/IEC 11172-2 or ISO/IEC 14496-2 video
554                 streamType = ATSParser::STREAMTYPE_MPEG2_VIDEO;
555             } else {
556                 streamType = ATSParser::STREAMTYPE_RESERVED;
557             }
558 
559             index = mTracks.add(
560                     stream_id, new Track(this, stream_id, streamType));
561         }
562 
563         status_t err = OK;
564 
565         if (index >= 0) {
566             err =
567                 mTracks.editValueAt(index)->appendPESData(
568                     PTS_DTS_flags, PTS, DTS, br.data(), dataLength);
569         }
570 
571         br.skipBits(dataLength * 8);
572 
573         if (err != OK) {
574             return err;
575         }
576     } else if (stream_id == 0xbe) {  // padding_stream
577         if (PES_packet_length == 0u) {
578             return ERROR_MALFORMED;
579         }
580         br.skipBits(PES_packet_length * 8);
581     } else {
582         if (PES_packet_length == 0u) {
583             return ERROR_MALFORMED;
584         }
585         br.skipBits(PES_packet_length * 8);
586     }
587 
588     return n;
589 }
590 
591 ////////////////////////////////////////////////////////////////////////////////
592 
Track(MPEG2PSExtractor * extractor,unsigned stream_id,unsigned stream_type)593 MPEG2PSExtractor::Track::Track(
594         MPEG2PSExtractor *extractor, unsigned stream_id, unsigned stream_type)
595     : mExtractor(extractor),
596       mStreamID(stream_id),
597       mStreamType(stream_type),
598       mQueue(NULL) {
599     bool supported = true;
600     ElementaryStreamQueue::Mode mode;
601 
602     switch (mStreamType) {
603         case ATSParser::STREAMTYPE_H264:
604             mode = ElementaryStreamQueue::H264;
605             break;
606         case ATSParser::STREAMTYPE_MPEG2_AUDIO_ADTS:
607             mode = ElementaryStreamQueue::AAC;
608             break;
609         case ATSParser::STREAMTYPE_MPEG1_AUDIO:
610         case ATSParser::STREAMTYPE_MPEG2_AUDIO:
611             mode = ElementaryStreamQueue::MPEG_AUDIO;
612             break;
613 
614         case ATSParser::STREAMTYPE_MPEG1_VIDEO:
615         case ATSParser::STREAMTYPE_MPEG2_VIDEO:
616             mode = ElementaryStreamQueue::MPEG_VIDEO;
617             break;
618 
619         case ATSParser::STREAMTYPE_MPEG4_VIDEO:
620             mode = ElementaryStreamQueue::MPEG4_VIDEO;
621             break;
622 
623         default:
624             supported = false;
625             break;
626     }
627 
628     if (supported) {
629         mQueue = new ElementaryStreamQueue(mode);
630     } else {
631         ALOGI("unsupported stream ID 0x%02x", stream_id);
632     }
633 }
634 
~Track()635 MPEG2PSExtractor::Track::~Track() {
636     delete mQueue;
637     mQueue = NULL;
638 }
639 
start()640 media_status_t MPEG2PSExtractor::Track::start() {
641     if (mSource == NULL) {
642         return AMEDIA_ERROR_UNKNOWN;
643     }
644 
645     // initialize with one small buffer, but allow growth
646     mBufferGroup->init(1 /* one buffer */, 256 /* buffer size */, 64 /* max number of buffers */);
647 
648     if (mSource->start(NULL) == OK) { // AnotherPacketSource::start doesn't use its argument
649         return AMEDIA_OK;
650     }
651     return AMEDIA_ERROR_UNKNOWN;
652 }
653 
stop()654 media_status_t MPEG2PSExtractor::Track::stop() {
655     if (mSource == NULL) {
656         return AMEDIA_ERROR_UNKNOWN;
657     }
658 
659     if (mSource->stop() == OK) {
660         return AMEDIA_OK;
661     }
662     return AMEDIA_ERROR_UNKNOWN;
663 }
664 
665 void copyAMessageToAMediaFormat(AMediaFormat *format, sp<AMessage> msg);
666 
getFormat(AMediaFormat * meta)667 media_status_t MPEG2PSExtractor::Track::getFormat(AMediaFormat *meta) {
668     if (mSource == NULL) {
669         return AMEDIA_ERROR_UNKNOWN;
670     }
671 
672     sp<MetaData> sourceMeta = mSource->getFormat();
673     sp<AMessage> msg;
674     convertMetaDataToMessage(sourceMeta, &msg);
675     copyAMessageToAMediaFormat(meta, msg);
676     return AMEDIA_OK;
677 }
678 
read(MediaBufferHelper ** buffer,const ReadOptions * options)679 media_status_t MPEG2PSExtractor::Track::read(
680         MediaBufferHelper **buffer, const ReadOptions *options) {
681     if (mSource == NULL) {
682         return AMEDIA_ERROR_UNKNOWN;
683     }
684 
685     status_t finalResult;
686     while (!mSource->hasBufferAvailable(&finalResult)) {
687         if (finalResult != OK) {
688             return AMEDIA_ERROR_END_OF_STREAM;
689         }
690 
691         status_t err = mExtractor->feedMore();
692 
693         if (err != OK) {
694             mSource->signalEOS(err);
695         }
696     }
697 
698     MediaBufferBase *mbuf;
699     mSource->read(&mbuf, (MediaTrack::ReadOptions*) options);
700     size_t length = mbuf->range_length();
701     MediaBufferHelper *outbuf;
702     mBufferGroup->acquire_buffer(&outbuf, false, length);
703     memcpy(outbuf->data(), mbuf->data(), length);
704     outbuf->set_range(0, length);
705     *buffer = outbuf;
706     MetaDataBase &inMeta = mbuf->meta_data();
707     AMediaFormat *outMeta = outbuf->meta_data();
708     int64_t val64;
709     if (inMeta.findInt64(kKeyTime, &val64)) {
710         AMediaFormat_setInt64(outMeta, AMEDIAFORMAT_KEY_TIME_US, val64);
711     }
712     int32_t val32;
713     if (inMeta.findInt32(kKeyIsSyncFrame, &val32)) {
714         AMediaFormat_setInt32(outMeta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, val32);
715     }
716     if (inMeta.findInt32(kKeyCryptoMode, &val32)) {
717         AMediaFormat_setInt32(outMeta, AMEDIAFORMAT_KEY_CRYPTO_MODE, val32);
718     }
719     uint32_t bufType;
720     const void *bufData;
721     size_t bufSize;
722     if (inMeta.findData(kKeyCryptoIV, &bufType, &bufData, &bufSize)) {
723         AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_IV, bufData, bufSize);
724     }
725     if (inMeta.findData(kKeyCryptoKey, &bufType, &bufData, &bufSize)) {
726         AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_KEY, bufData, bufSize);
727     }
728     if (inMeta.findData(kKeyPlainSizes, &bufType, &bufData, &bufSize)) {
729         AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES, bufData, bufSize);
730     }
731     if (inMeta.findData(kKeyEncryptedSizes, &bufType, &bufData, &bufSize)) {
732         AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES, bufData, bufSize);
733     }
734     if (inMeta.findData(kKeySEI, &bufType, &bufData, &bufSize)) {
735         AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_SEI, bufData, bufSize);
736     }
737     if (inMeta.findData(kKeyAudioPresentationInfo, &bufType, &bufData, &bufSize)) {
738         AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO, bufData, bufSize);
739     }
740     mbuf->release();
741     return AMEDIA_OK;
742 }
743 
appendPESData(unsigned PTS_DTS_flags,uint64_t PTS,uint64_t,const uint8_t * data,size_t size)744 status_t MPEG2PSExtractor::Track::appendPESData(
745         unsigned PTS_DTS_flags,
746         uint64_t PTS, uint64_t /* DTS */,
747         const uint8_t *data, size_t size) {
748     if (mQueue == NULL) {
749         return OK;
750     }
751 
752     int64_t timeUs;
753     if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {
754         timeUs = (PTS * 100) / 9;
755     } else {
756         timeUs = 0;
757     }
758 
759     status_t err = mQueue->appendData(data, size, timeUs);
760 
761     if (err != OK) {
762         return err;
763     }
764 
765     sp<ABuffer> accessUnit;
766     while ((accessUnit = mQueue->dequeueAccessUnit()) != NULL) {
767         if (mSource == NULL) {
768             sp<MetaData> meta = mQueue->getFormat();
769 
770             if (meta != NULL) {
771                 ALOGV("Stream ID 0x%02x now has data.", mStreamID);
772 
773                 mSource = new AnotherPacketSource(meta);
774                 mSource->queueAccessUnit(accessUnit);
775             }
776         } else if (mQueue->getFormat() != NULL) {
777             mSource->queueAccessUnit(accessUnit);
778         }
779     }
780 
781     return OK;
782 }
783 
784 ////////////////////////////////////////////////////////////////////////////////
785 
WrappedTrack(MPEG2PSExtractor * extractor,Track * track)786 MPEG2PSExtractor::WrappedTrack::WrappedTrack(
787         MPEG2PSExtractor *extractor, Track *track)
788     : mExtractor(extractor),
789       mTrack(track) {
790 }
791 
~WrappedTrack()792 MPEG2PSExtractor::WrappedTrack::~WrappedTrack() {
793 }
794 
start()795 media_status_t MPEG2PSExtractor::WrappedTrack::start() {
796     mTrack->mBufferGroup = mBufferGroup;
797     return mTrack->start();
798 }
799 
stop()800 media_status_t MPEG2PSExtractor::WrappedTrack::stop() {
801     return mTrack->stop();
802 }
803 
getFormat(AMediaFormat * meta)804 media_status_t MPEG2PSExtractor::WrappedTrack::getFormat(AMediaFormat *meta) {
805     return mTrack->getFormat(meta);
806 }
807 
read(MediaBufferHelper ** buffer,const ReadOptions * options)808 media_status_t MPEG2PSExtractor::WrappedTrack::read(
809         MediaBufferHelper **buffer, const ReadOptions *options) {
810     return mTrack->read(buffer, options);
811 }
812 
813 ////////////////////////////////////////////////////////////////////////////////
814 
SniffMPEG2PS(DataSourceHelper * source,float * confidence)815 bool SniffMPEG2PS(
816         DataSourceHelper *source, float *confidence) {
817     uint8_t header[5];
818     if (source->readAt(0, header, sizeof(header)) < (ssize_t)sizeof(header)) {
819         return false;
820     }
821 
822     if (memcmp("\x00\x00\x01\xba", header, 4) || (header[4] >> 6) != 1) {
823         return false;
824     }
825 
826     *confidence = 0.25f;  // Slightly larger than .mp3 extractor's confidence
827 
828     return true;
829 }
830 
831 }  // namespace android
832