• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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