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