MPEG2TSExtractor.cpp revision 5a1c3529e4fa2f8a11054181294e0ce79fff8dd3
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"
22cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
23cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/DataSource.h>
24cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MediaDefs.h>
25cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MediaErrors.h>
26cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MediaSource.h>
27cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MetaData.h>
28cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <utils/String8.h>
29cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
30cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "AnotherPacketSource.h"
31cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "ATSParser.h"
32cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
33cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubernamespace android {
34cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
35cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstruct MPEG2TSSource : public MediaSource {
36cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    MPEG2TSSource(
37cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            const sp<MPEG2TSExtractor> &extractor,
38cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            const sp<AnotherPacketSource> &impl);
39cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
40cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    virtual status_t start(MetaData *params = NULL);
41cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    virtual status_t stop();
42cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    virtual sp<MetaData> getFormat();
43cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
44cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    virtual status_t read(
45cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            MediaBuffer **buffer, const ReadOptions *options = NULL);
46cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
47cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberprivate:
48cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    sp<MPEG2TSExtractor> mExtractor;
49cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    sp<AnotherPacketSource> mImpl;
50cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
51cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(MPEG2TSSource);
52cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber};
53cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
54cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas HuberMPEG2TSSource::MPEG2TSSource(
55cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        const sp<MPEG2TSExtractor> &extractor,
56cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        const sp<AnotherPacketSource> &impl)
57cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    : mExtractor(extractor),
58cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber      mImpl(impl) {
59cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
60cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
61cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSSource::start(MetaData *params) {
62cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return mImpl->start(params);
63cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
64cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
65cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSSource::stop() {
66cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return mImpl->stop();
67cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
68cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
69cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MetaData> MPEG2TSSource::getFormat() {
70cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return mImpl->getFormat();
71cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
72cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
73cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSSource::read(
74cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        MediaBuffer **out, const ReadOptions *options) {
75cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    *out = NULL;
76cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
77cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    status_t finalResult;
78cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    while (!mImpl->hasBufferAvailable(&finalResult)) {
79cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (finalResult != OK) {
80cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            return ERROR_END_OF_STREAM;
81cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
82cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
83cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        status_t err = mExtractor->feedMore();
84cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (err != OK) {
85cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            mImpl->signalEOS(err);
86cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
87cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
88cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
89cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return mImpl->read(out, options);
90cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
91cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
92cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber////////////////////////////////////////////////////////////////////////////////
93cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
94cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas HuberMPEG2TSExtractor::MPEG2TSExtractor(const sp<DataSource> &source)
95cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    : mDataSource(source),
96cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber      mParser(new ATSParser),
97cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber      mOffset(0) {
98cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    init();
99cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
100cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
101cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersize_t MPEG2TSExtractor::countTracks() {
102cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return mSourceImpls.size();
103cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
104cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
105cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MediaSource> MPEG2TSExtractor::getTrack(size_t index) {
106cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    if (index >= mSourceImpls.size()) {
107cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        return NULL;
108cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
109cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
110cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return new MPEG2TSSource(this, mSourceImpls.editItemAt(index));
111cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
112cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
113cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MetaData> MPEG2TSExtractor::getTrackMetaData(
114cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        size_t index, uint32_t flags) {
115cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return index < mSourceImpls.size()
116cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        ? mSourceImpls.editItemAt(index)->getFormat() : NULL;
117cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
118cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
119cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MetaData> MPEG2TSExtractor::getMetaData() {
120cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    sp<MetaData> meta = new MetaData;
121cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG2TS);
122cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
123cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return meta;
124cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
125cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
126cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubervoid MPEG2TSExtractor::init() {
127cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    bool haveAudio = false;
128cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    bool haveVideo = false;
129cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
130cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    while (feedMore() == OK) {
131cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        ATSParser::SourceType type;
132cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (haveAudio && haveVideo) {
133cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            break;
134cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
135cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (haveVideo) {
136cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            type = ATSParser::MPEG2ADTS_AUDIO;
137cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        } else {
138cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            type = ATSParser::AVC_VIDEO;
139cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
140cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        sp<AnotherPacketSource> impl =
141cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            (AnotherPacketSource *)mParser->getSource(type).get();
142cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
143cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (impl != NULL) {
144cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            if (type == ATSParser::MPEG2ADTS_AUDIO) {
145cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber                haveAudio = true;
146cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            } else {
147cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber                haveVideo = true;
148cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            }
149cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            mSourceImpls.push(impl);
150cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
151cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
152cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
153cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    LOGI("haveAudio=%d, haveVideo=%d", haveAudio, haveVideo);
154cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
155cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
156cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSExtractor::feedMore() {
157cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    Mutex::Autolock autoLock(mLock);
158cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
159cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    static const size_t kTSPacketSize = 188;
160cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
161cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    uint8_t packet[kTSPacketSize];
162cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    ssize_t n = mDataSource->readAt(mOffset, packet, kTSPacketSize);
163cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
164cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    if (n < (ssize_t)kTSPacketSize) {
165cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        return (n < 0) ? (status_t)n : ERROR_END_OF_STREAM;
166cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
167cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
168cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    mOffset += kTSPacketSize;
169cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    mParser->feedTSPacket(packet, kTSPacketSize);
170cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
171cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return OK;
172cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
173cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
174cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber////////////////////////////////////////////////////////////////////////////////
175cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
176cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberbool SniffMPEG2TS(
1775a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence,
1785a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        sp<AMessage> *) {
179e71d10e7ad55ccbcb0756c007caef1c959090384Andreas Huber#if 0
180cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    char header;
181cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    if (source->readAt(0, &header, 1) != 1 || header != 0x47) {
182cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        return false;
183cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
184cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
185cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    *confidence = 0.05f;
186cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_MPEG2TS);
187cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
188cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return true;
189e71d10e7ad55ccbcb0756c007caef1c959090384Andreas Huber#else
190e71d10e7ad55ccbcb0756c007caef1c959090384Andreas Huber    // For now we're going to never identify this type of stream, since we'd
191e71d10e7ad55ccbcb0756c007caef1c959090384Andreas Huber    // just base our decision on a single byte...
192e71d10e7ad55ccbcb0756c007caef1c959090384Andreas Huber    // Instead you can instantiate an MPEG2TSExtractor by explicitly stating
193e71d10e7ad55ccbcb0756c007caef1c959090384Andreas Huber    // its proper mime type in the call to MediaExtractor::Create(...).
194e71d10e7ad55ccbcb0756c007caef1c959090384Andreas Huber    return false;
195e71d10e7ad55ccbcb0756c007caef1c959090384Andreas Huber#endif
196cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
197cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
198cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}  // namespace android
199