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