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"
22a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include "include/LiveSession.h"
23bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber#include "include/NuCachedSource2.h"
24cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
25f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h>
26cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/DataSource.h>
27cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MediaDefs.h>
28cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MediaErrors.h>
29cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MediaSource.h>
30cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MetaData.h>
31cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <utils/String8.h>
32cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
33cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "AnotherPacketSource.h"
34cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "ATSParser.h"
35cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
36cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubernamespace android {
37cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
380da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huberstatic const size_t kTSPacketSize = 188;
390da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
40cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstruct MPEG2TSSource : public MediaSource {
41cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    MPEG2TSSource(
42cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            const sp<MPEG2TSExtractor> &extractor,
43bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber            const sp<AnotherPacketSource> &impl,
44bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber            bool seekable);
45cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
46cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    virtual status_t start(MetaData *params = NULL);
47cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    virtual status_t stop();
48cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    virtual sp<MetaData> getFormat();
49cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
50cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    virtual status_t read(
51cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            MediaBuffer **buffer, const ReadOptions *options = NULL);
52cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
53cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberprivate:
54cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    sp<MPEG2TSExtractor> mExtractor;
55cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    sp<AnotherPacketSource> mImpl;
56cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
57bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    // If there are both audio and video streams, only the video stream
58bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    // will be seekable, otherwise the single stream will be seekable.
59bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    bool mSeekable;
60bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
61cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(MPEG2TSSource);
62cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber};
63cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
64cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas HuberMPEG2TSSource::MPEG2TSSource(
65cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        const sp<MPEG2TSExtractor> &extractor,
66bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber        const sp<AnotherPacketSource> &impl,
67bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber        bool seekable)
68cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    : mExtractor(extractor),
69bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber      mImpl(impl),
70bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber      mSeekable(seekable) {
71cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
72cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
73cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSSource::start(MetaData *params) {
74cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return mImpl->start(params);
75cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
76cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
77cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSSource::stop() {
78cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return mImpl->stop();
79cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
80cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
81cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MetaData> MPEG2TSSource::getFormat() {
82bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    sp<MetaData> meta = mImpl->getFormat();
83bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
84bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    int64_t durationUs;
85a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    if (mExtractor->mLiveSession != NULL
86a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            && mExtractor->mLiveSession->getDuration(&durationUs) == OK) {
87bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber        meta->setInt64(kKeyDuration, durationUs);
88bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    }
89bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
90bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    return meta;
91cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
92cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
93cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSSource::read(
94cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        MediaBuffer **out, const ReadOptions *options) {
95cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    *out = NULL;
96cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
97bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    int64_t seekTimeUs;
98bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    ReadOptions::SeekMode seekMode;
99bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    if (mSeekable && options && options->getSeekTo(&seekTimeUs, &seekMode)) {
100bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber        mExtractor->seekTo(seekTimeUs);
101bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    }
102bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
103cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    status_t finalResult;
104cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    while (!mImpl->hasBufferAvailable(&finalResult)) {
105cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (finalResult != OK) {
106cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            return ERROR_END_OF_STREAM;
107cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
108cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
109cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        status_t err = mExtractor->feedMore();
110cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (err != OK) {
111cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            mImpl->signalEOS(err);
112cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
113cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
114cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
115cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return mImpl->read(out, options);
116cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
117cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
118cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber////////////////////////////////////////////////////////////////////////////////
119cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
120cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas HuberMPEG2TSExtractor::MPEG2TSExtractor(const sp<DataSource> &source)
121cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    : mDataSource(source),
122cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber      mParser(new ATSParser),
123cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber      mOffset(0) {
124cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    init();
125cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
126cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
127cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersize_t MPEG2TSExtractor::countTracks() {
128cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return mSourceImpls.size();
129cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
130cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
131cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MediaSource> MPEG2TSExtractor::getTrack(size_t index) {
132cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    if (index >= mSourceImpls.size()) {
133cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        return NULL;
134cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
135cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
136bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    bool seekable = true;
137bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    if (mSourceImpls.size() > 1) {
138bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber        CHECK_EQ(mSourceImpls.size(), 2u);
139bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
140bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber        sp<MetaData> meta = mSourceImpls.editItemAt(index)->getFormat();
141bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber        const char *mime;
142bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber        CHECK(meta->findCString(kKeyMIMEType, &mime));
143bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
144bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber        if (!strncasecmp("audio/", mime, 6)) {
145bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber            seekable = false;
146bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber        }
147bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    }
148bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
149bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    return new MPEG2TSSource(this, mSourceImpls.editItemAt(index), seekable);
150cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
151cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
152cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MetaData> MPEG2TSExtractor::getTrackMetaData(
153cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        size_t index, uint32_t flags) {
154cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return index < mSourceImpls.size()
155cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        ? mSourceImpls.editItemAt(index)->getFormat() : NULL;
156cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
157cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
158cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MetaData> MPEG2TSExtractor::getMetaData() {
159cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    sp<MetaData> meta = new MetaData;
160cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG2TS);
161cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
162cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return meta;
163cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
164cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
165cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubervoid MPEG2TSExtractor::init() {
166cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    bool haveAudio = false;
167cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    bool haveVideo = false;
1680da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    int numPacketsParsed = 0;
169cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
170cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    while (feedMore() == OK) {
171cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        ATSParser::SourceType type;
172cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (haveAudio && haveVideo) {
173cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            break;
174cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
1750da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        if (!haveVideo) {
1760da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            sp<AnotherPacketSource> impl =
1770da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                (AnotherPacketSource *)mParser->getSource(
178386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                        ATSParser::VIDEO).get();
1790da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
1800da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            if (impl != NULL) {
1810da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                haveVideo = true;
1820da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                mSourceImpls.push(impl);
1830da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            }
184cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
185cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1860da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        if (!haveAudio) {
1870da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            sp<AnotherPacketSource> impl =
1880da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                (AnotherPacketSource *)mParser->getSource(
189386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                        ATSParser::AUDIO).get();
1900da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
1910da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            if (impl != NULL) {
192cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber                haveAudio = true;
1930da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                mSourceImpls.push(impl);
194cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            }
1950da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        }
1960da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
197386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        if (++numPacketsParsed > 10000) {
1980da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            break;
199cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
200cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
201cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
202df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("haveAudio=%d, haveVideo=%d", haveAudio, haveVideo);
203cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
204cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
205cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSExtractor::feedMore() {
206cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    Mutex::Autolock autoLock(mLock);
207cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
208cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    uint8_t packet[kTSPacketSize];
209cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    ssize_t n = mDataSource->readAt(mOffset, packet, kTSPacketSize);
210cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
211ed8d14f6a934072cd012992c4ef16990a54baa9aAndreas Huber    if (n < (ssize_t)kTSPacketSize) {
212cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        return (n < 0) ? (status_t)n : ERROR_END_OF_STREAM;
213cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
214cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
2152a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber    mOffset += n;
21606528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber    return mParser->feedTSPacket(packet, kTSPacketSize);
217cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
218cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
219a44153c1a57202fb538659eb50706e60454d6273Andreas Hubervoid MPEG2TSExtractor::setLiveSession(const sp<LiveSession> &liveSession) {
220bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    Mutex::Autolock autoLock(mLock);
221bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
222a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    mLiveSession = liveSession;
223bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber}
224bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
225bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Hubervoid MPEG2TSExtractor::seekTo(int64_t seekTimeUs) {
226bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    Mutex::Autolock autoLock(mLock);
227bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
228a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    if (mLiveSession == NULL) {
229bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber        return;
230bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    }
231bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
232a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    mLiveSession->seekTo(seekTimeUs);
233bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber}
234bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
235bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huberuint32_t MPEG2TSExtractor::flags() const {
236bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    Mutex::Autolock autoLock(mLock);
237bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
238bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    uint32_t flags = CAN_PAUSE;
239bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
240a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    if (mLiveSession != NULL && mLiveSession->isSeekable()) {
241bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber        flags |= CAN_SEEK_FORWARD | CAN_SEEK_BACKWARD | CAN_SEEK;
242bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    }
243bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
244bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    return flags;
245bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber}
246bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
247cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber////////////////////////////////////////////////////////////////////////////////
248cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
249cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberbool SniffMPEG2TS(
2505a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence,
2515a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        sp<AMessage> *) {
2520da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    for (int i = 0; i < 5; ++i) {
2530da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        char header;
2540da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        if (source->readAt(kTSPacketSize * i, &header, 1) != 1
2550da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                || header != 0x47) {
2560da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            return false;
2570da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        }
258cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
259cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
2600da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *confidence = 0.1f;
261cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_MPEG2TS);
262cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
263cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return true;
264cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
265cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
266cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}  // namespace android
267