1 /*
2 * Copyright (C) 2010 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 "StreamingSource"
19 #include <utils/Log.h>
20
21 #include "StreamingSource.h"
22
23 #include "ATSParser.h"
24 #include "AnotherPacketSource.h"
25 #include "NuPlayerStreamListener.h"
26
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/MediaSource.h>
31 #include <media/stagefright/MetaData.h>
32
33 namespace android {
34
StreamingSource(const sp<IStreamSource> & source)35 NuPlayer::StreamingSource::StreamingSource(const sp<IStreamSource> &source)
36 : mSource(source),
37 mFinalResult(OK) {
38 }
39
~StreamingSource()40 NuPlayer::StreamingSource::~StreamingSource() {
41 }
42
start()43 void NuPlayer::StreamingSource::start() {
44 mStreamListener = new NuPlayerStreamListener(mSource, 0);
45 mTSParser = new ATSParser(ATSParser::TS_TIMESTAMPS_ARE_ABSOLUTE);
46
47 mStreamListener->start();
48 }
49
feedMoreTSData()50 status_t NuPlayer::StreamingSource::feedMoreTSData() {
51 if (mFinalResult != OK) {
52 return mFinalResult;
53 }
54
55 for (int32_t i = 0; i < 50; ++i) {
56 char buffer[188];
57 sp<AMessage> extra;
58 ssize_t n = mStreamListener->read(buffer, sizeof(buffer), &extra);
59
60 if (n == 0) {
61 LOGI("input data EOS reached.");
62 mTSParser->signalEOS(ERROR_END_OF_STREAM);
63 mFinalResult = ERROR_END_OF_STREAM;
64 break;
65 } else if (n == INFO_DISCONTINUITY) {
66 ATSParser::DiscontinuityType type = ATSParser::DISCONTINUITY_SEEK;
67
68 int32_t formatChange;
69 if (extra != NULL
70 && extra->findInt32(
71 IStreamListener::kKeyFormatChange, &formatChange)
72 && formatChange != 0) {
73 type = ATSParser::DISCONTINUITY_FORMATCHANGE;
74 }
75
76 mTSParser->signalDiscontinuity(type, extra);
77 } else if (n < 0) {
78 CHECK_EQ(n, -EWOULDBLOCK);
79 break;
80 } else {
81 if (buffer[0] == 0x00) {
82 // XXX legacy
83 mTSParser->signalDiscontinuity(
84 buffer[1] == 0x00
85 ? ATSParser::DISCONTINUITY_SEEK
86 : ATSParser::DISCONTINUITY_FORMATCHANGE,
87 extra);
88 } else {
89 status_t err = mTSParser->feedTSPacket(buffer, sizeof(buffer));
90
91 if (err != OK) {
92 LOGE("TS Parser returned error %d", err);
93
94 mTSParser->signalEOS(err);
95 mFinalResult = err;
96 break;
97 }
98 }
99 }
100 }
101
102 return OK;
103 }
104
getFormat(bool audio)105 sp<MetaData> NuPlayer::StreamingSource::getFormat(bool audio) {
106 ATSParser::SourceType type =
107 audio ? ATSParser::AUDIO : ATSParser::VIDEO;
108
109 sp<AnotherPacketSource> source =
110 static_cast<AnotherPacketSource *>(mTSParser->getSource(type).get());
111
112 if (source == NULL) {
113 return NULL;
114 }
115
116 return source->getFormat();
117 }
118
dequeueAccessUnit(bool audio,sp<ABuffer> * accessUnit)119 status_t NuPlayer::StreamingSource::dequeueAccessUnit(
120 bool audio, sp<ABuffer> *accessUnit) {
121 ATSParser::SourceType type =
122 audio ? ATSParser::AUDIO : ATSParser::VIDEO;
123
124 sp<AnotherPacketSource> source =
125 static_cast<AnotherPacketSource *>(mTSParser->getSource(type).get());
126
127 if (source == NULL) {
128 return -EWOULDBLOCK;
129 }
130
131 status_t finalResult;
132 if (!source->hasBufferAvailable(&finalResult)) {
133 return finalResult == OK ? -EWOULDBLOCK : finalResult;
134 }
135
136 return source->dequeueAccessUnit(accessUnit);
137 }
138
139 } // namespace android
140
141