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