MPEG2TSExtractor.cpp revision be9634d071e79b72a42a4504f64eda9e2a0bceb8
1cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber/*
2cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * Copyright (C) 2010 The Android Open Source Project
3cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber *
4cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * you may not use this file except in compliance with the License.
6cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * You may obtain a copy of the License at
7cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber *
8cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber *
10cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * Unless required by applicable law or agreed to in writing, software
11cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * See the License for the specific language governing permissions and
14cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * limitations under the License.
15cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber */
16cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
17cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber//#define LOG_NDEBUG 0
18cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#define LOG_TAG "MPEG2TSExtractor"
19cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <utils/Log.h>
20cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
21cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "include/MPEG2TSExtractor.h"
22bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber#include "include/NuCachedSource2.h"
23cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
24f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h>
25cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/DataSource.h>
26cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MediaDefs.h>
27cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MediaErrors.h>
28cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MediaSource.h>
29cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MetaData.h>
30cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <utils/String8.h>
31cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
32cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "AnotherPacketSource.h"
33cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "ATSParser.h"
34cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
35cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubernamespace android {
36cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
370da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huberstatic const size_t kTSPacketSize = 188;
380da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
39cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstruct MPEG2TSSource : public MediaSource {
40cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    MPEG2TSSource(
41cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            const sp<MPEG2TSExtractor> &extractor,
42bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber            const sp<AnotherPacketSource> &impl,
43bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber            bool seekable);
44cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
45cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    virtual status_t start(MetaData *params = NULL);
46cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    virtual status_t stop();
47cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    virtual sp<MetaData> getFormat();
48cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
49cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    virtual status_t read(
50cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            MediaBuffer **buffer, const ReadOptions *options = NULL);
51cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
52cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberprivate:
53cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    sp<MPEG2TSExtractor> mExtractor;
54cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    sp<AnotherPacketSource> mImpl;
55cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
56bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    // If there are both audio and video streams, only the video stream
57bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    // will be seekable, otherwise the single stream will be seekable.
58bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    bool mSeekable;
59bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
60cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(MPEG2TSSource);
61cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber};
62cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
63cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas HuberMPEG2TSSource::MPEG2TSSource(
64cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        const sp<MPEG2TSExtractor> &extractor,
65bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber        const sp<AnotherPacketSource> &impl,
66bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber        bool seekable)
67cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    : mExtractor(extractor),
68bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber      mImpl(impl),
69bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber      mSeekable(seekable) {
70cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
71cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
72cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSSource::start(MetaData *params) {
73cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return mImpl->start(params);
74cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
75cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
76cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSSource::stop() {
77cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return mImpl->stop();
78cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
79cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
80cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MetaData> MPEG2TSSource::getFormat() {
8114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    return mImpl->getFormat();
82cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
83cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
84cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSSource::read(
85cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        MediaBuffer **out, const ReadOptions *options) {
86cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    *out = NULL;
87cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
88cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    status_t finalResult;
89cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    while (!mImpl->hasBufferAvailable(&finalResult)) {
90cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (finalResult != OK) {
91cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            return ERROR_END_OF_STREAM;
92cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
93cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
94cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        status_t err = mExtractor->feedMore();
95cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (err != OK) {
96cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            mImpl->signalEOS(err);
97cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
98cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
99cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1005d7c3eef1985ff15a56920c548cc4e41d6c9627aMarco Nelissen    int64_t seekTimeUs;
1015d7c3eef1985ff15a56920c548cc4e41d6c9627aMarco Nelissen    ReadOptions::SeekMode seekMode;
1025d7c3eef1985ff15a56920c548cc4e41d6c9627aMarco Nelissen    if (mSeekable && options && options->getSeekTo(&seekTimeUs, &seekMode)) {
1035d7c3eef1985ff15a56920c548cc4e41d6c9627aMarco Nelissen        // A seek was requested, but we don't actually support seeking and so can only "seek" to
1045d7c3eef1985ff15a56920c548cc4e41d6c9627aMarco Nelissen        // the current position
1055d7c3eef1985ff15a56920c548cc4e41d6c9627aMarco Nelissen        int64_t nextBufTimeUs;
1065d7c3eef1985ff15a56920c548cc4e41d6c9627aMarco Nelissen        if (mImpl->nextBufferTime(&nextBufTimeUs) != OK || seekTimeUs != nextBufTimeUs) {
1075d7c3eef1985ff15a56920c548cc4e41d6c9627aMarco Nelissen            return ERROR_UNSUPPORTED;
1085d7c3eef1985ff15a56920c548cc4e41d6c9627aMarco Nelissen        }
1095d7c3eef1985ff15a56920c548cc4e41d6c9627aMarco Nelissen    }
1105d7c3eef1985ff15a56920c548cc4e41d6c9627aMarco Nelissen
111cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return mImpl->read(out, options);
112cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
113cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
114cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber////////////////////////////////////////////////////////////////////////////////
115cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
116cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas HuberMPEG2TSExtractor::MPEG2TSExtractor(const sp<DataSource> &source)
117cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    : mDataSource(source),
118cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber      mParser(new ATSParser),
119cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber      mOffset(0) {
120cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    init();
121cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
122cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
123cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersize_t MPEG2TSExtractor::countTracks() {
124cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return mSourceImpls.size();
125cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
126cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
127cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MediaSource> MPEG2TSExtractor::getTrack(size_t index) {
128cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    if (index >= mSourceImpls.size()) {
129cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        return NULL;
130cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
131cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
132bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    bool seekable = true;
133bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    if (mSourceImpls.size() > 1) {
134bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber        CHECK_EQ(mSourceImpls.size(), 2u);
135bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
136bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber        sp<MetaData> meta = mSourceImpls.editItemAt(index)->getFormat();
137bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber        const char *mime;
138bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber        CHECK(meta->findCString(kKeyMIMEType, &mime));
139bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
140bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber        if (!strncasecmp("audio/", mime, 6)) {
141bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber            seekable = false;
142bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber        }
143bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    }
144bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
145bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    return new MPEG2TSSource(this, mSourceImpls.editItemAt(index), seekable);
146cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
147cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
148cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MetaData> MPEG2TSExtractor::getTrackMetaData(
149d411b4ca2945cd8974a3a78199fce94646950128Andreas Huber        size_t index, uint32_t /* flags */) {
150cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return index < mSourceImpls.size()
151cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        ? mSourceImpls.editItemAt(index)->getFormat() : NULL;
152cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
153cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
154cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MetaData> MPEG2TSExtractor::getMetaData() {
155cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    sp<MetaData> meta = new MetaData;
156cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG2TS);
157cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
158cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return meta;
159cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
160cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
161cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubervoid MPEG2TSExtractor::init() {
162cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    bool haveAudio = false;
163cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    bool haveVideo = false;
1640da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    int numPacketsParsed = 0;
165cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
166cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    while (feedMore() == OK) {
167cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (haveAudio && haveVideo) {
168cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            break;
169cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
1700da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        if (!haveVideo) {
1710da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            sp<AnotherPacketSource> impl =
1720da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                (AnotherPacketSource *)mParser->getSource(
173386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                        ATSParser::VIDEO).get();
1740da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
1750da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            if (impl != NULL) {
1760da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                haveVideo = true;
1770da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                mSourceImpls.push(impl);
1780da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            }
179cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
180cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1810da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        if (!haveAudio) {
1820da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            sp<AnotherPacketSource> impl =
1830da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                (AnotherPacketSource *)mParser->getSource(
184386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                        ATSParser::AUDIO).get();
1850da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
1860da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            if (impl != NULL) {
187cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber                haveAudio = true;
1880da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                mSourceImpls.push(impl);
189cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            }
1900da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        }
1910da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
192386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        if (++numPacketsParsed > 10000) {
1930da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            break;
194cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
195cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
196cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
197df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("haveAudio=%d, haveVideo=%d", haveAudio, haveVideo);
198cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
199cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
200cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSExtractor::feedMore() {
201cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    Mutex::Autolock autoLock(mLock);
202cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
203cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    uint8_t packet[kTSPacketSize];
204cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    ssize_t n = mDataSource->readAt(mOffset, packet, kTSPacketSize);
205cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
206ed8d14f6a934072cd012992c4ef16990a54baa9aAndreas Huber    if (n < (ssize_t)kTSPacketSize) {
207be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen        if (n >= 0) {
208be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen            mParser->signalEOS(ERROR_END_OF_STREAM);
209be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen        }
210cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        return (n < 0) ? (status_t)n : ERROR_END_OF_STREAM;
211cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
212cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
2132a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber    mOffset += n;
21406528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber    return mParser->feedTSPacket(packet, kTSPacketSize);
215cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
216cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
217bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huberuint32_t MPEG2TSExtractor::flags() const {
21814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    return CAN_PAUSE;
219bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber}
220bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
221cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber////////////////////////////////////////////////////////////////////////////////
222cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
223cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberbool SniffMPEG2TS(
2245a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence,
2255a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        sp<AMessage> *) {
2260da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    for (int i = 0; i < 5; ++i) {
2270da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        char header;
2280da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        if (source->readAt(kTSPacketSize * i, &header, 1) != 1
2290da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                || header != 0x47) {
2300da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            return false;
2310da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        }
232cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
233cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
2340da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *confidence = 0.1f;
235cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_MPEG2TS);
236cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
237cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return true;
238cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
239cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
240cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}  // namespace android
241