1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2010 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker *
4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker *
8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker *
10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker */
16*ec779b8eSAndroid Build Coastguard Worker
17*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
18*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "HTTPLiveSource"
19*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
20*ec779b8eSAndroid Build Coastguard Worker
21*ec779b8eSAndroid Build Coastguard Worker #include "HTTPLiveSource.h"
22*ec779b8eSAndroid Build Coastguard Worker #include "LiveDataSource.h"
23*ec779b8eSAndroid Build Coastguard Worker
24*ec779b8eSAndroid Build Coastguard Worker #include <media/IMediaHTTPService.h>
25*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/ABuffer.h>
26*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/ADebug.h>
27*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/AMessage.h>
28*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/MediaErrors.h>
29*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/MetaData.h>
30*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/MediaDefs.h>
31*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/Utils.h>
32*ec779b8eSAndroid Build Coastguard Worker #include <mpeg2ts/AnotherPacketSource.h>
33*ec779b8eSAndroid Build Coastguard Worker
34*ec779b8eSAndroid Build Coastguard Worker // default buffer prepare/ready/underflow marks
35*ec779b8eSAndroid Build Coastguard Worker static const int kReadyMarkMs = 5000; // 5 seconds
36*ec779b8eSAndroid Build Coastguard Worker static const int kPrepareMarkMs = 1500; // 1.5 seconds
37*ec779b8eSAndroid Build Coastguard Worker
38*ec779b8eSAndroid Build Coastguard Worker namespace android {
39*ec779b8eSAndroid Build Coastguard Worker
HTTPLiveSource(const sp<AMessage> & notify,const sp<IMediaHTTPService> & httpService,const char * url,const KeyedVector<String8,String8> * headers)40*ec779b8eSAndroid Build Coastguard Worker NuPlayer::HTTPLiveSource::HTTPLiveSource(
41*ec779b8eSAndroid Build Coastguard Worker const sp<AMessage> ¬ify,
42*ec779b8eSAndroid Build Coastguard Worker const sp<IMediaHTTPService> &httpService,
43*ec779b8eSAndroid Build Coastguard Worker const char *url,
44*ec779b8eSAndroid Build Coastguard Worker const KeyedVector<String8, String8> *headers)
45*ec779b8eSAndroid Build Coastguard Worker : Source(notify),
46*ec779b8eSAndroid Build Coastguard Worker mHTTPService(httpService),
47*ec779b8eSAndroid Build Coastguard Worker mURL(url),
48*ec779b8eSAndroid Build Coastguard Worker mFlags(0),
49*ec779b8eSAndroid Build Coastguard Worker mFinalResult(OK),
50*ec779b8eSAndroid Build Coastguard Worker mOffset(0),
51*ec779b8eSAndroid Build Coastguard Worker mFetchSubtitleDataGeneration(0),
52*ec779b8eSAndroid Build Coastguard Worker mFetchMetaDataGeneration(0),
53*ec779b8eSAndroid Build Coastguard Worker mHasMetadata(false),
54*ec779b8eSAndroid Build Coastguard Worker mMetadataSelected(false) {
55*ec779b8eSAndroid Build Coastguard Worker mBufferingSettings.mInitialMarkMs = kPrepareMarkMs;
56*ec779b8eSAndroid Build Coastguard Worker mBufferingSettings.mResumePlaybackMarkMs = kReadyMarkMs;
57*ec779b8eSAndroid Build Coastguard Worker if (headers) {
58*ec779b8eSAndroid Build Coastguard Worker mExtraHeaders = *headers;
59*ec779b8eSAndroid Build Coastguard Worker
60*ec779b8eSAndroid Build Coastguard Worker ssize_t index =
61*ec779b8eSAndroid Build Coastguard Worker mExtraHeaders.indexOfKey(String8("x-hide-urls-from-log"));
62*ec779b8eSAndroid Build Coastguard Worker
63*ec779b8eSAndroid Build Coastguard Worker if (index >= 0) {
64*ec779b8eSAndroid Build Coastguard Worker mFlags |= kFlagIncognito;
65*ec779b8eSAndroid Build Coastguard Worker
66*ec779b8eSAndroid Build Coastguard Worker mExtraHeaders.removeItemsAt(index);
67*ec779b8eSAndroid Build Coastguard Worker }
68*ec779b8eSAndroid Build Coastguard Worker }
69*ec779b8eSAndroid Build Coastguard Worker }
70*ec779b8eSAndroid Build Coastguard Worker
~HTTPLiveSource()71*ec779b8eSAndroid Build Coastguard Worker NuPlayer::HTTPLiveSource::~HTTPLiveSource() {
72*ec779b8eSAndroid Build Coastguard Worker if (mLiveSession != NULL) {
73*ec779b8eSAndroid Build Coastguard Worker mLiveSession->disconnect();
74*ec779b8eSAndroid Build Coastguard Worker
75*ec779b8eSAndroid Build Coastguard Worker mLiveLooper->unregisterHandler(mLiveSession->id());
76*ec779b8eSAndroid Build Coastguard Worker mLiveLooper->unregisterHandler(id());
77*ec779b8eSAndroid Build Coastguard Worker mLiveLooper->stop();
78*ec779b8eSAndroid Build Coastguard Worker
79*ec779b8eSAndroid Build Coastguard Worker mLiveSession.clear();
80*ec779b8eSAndroid Build Coastguard Worker mLiveLooper.clear();
81*ec779b8eSAndroid Build Coastguard Worker }
82*ec779b8eSAndroid Build Coastguard Worker }
83*ec779b8eSAndroid Build Coastguard Worker
getBufferingSettings(BufferingSettings * buffering)84*ec779b8eSAndroid Build Coastguard Worker status_t NuPlayer::HTTPLiveSource::getBufferingSettings(
85*ec779b8eSAndroid Build Coastguard Worker BufferingSettings* buffering /* nonnull */) {
86*ec779b8eSAndroid Build Coastguard Worker *buffering = mBufferingSettings;
87*ec779b8eSAndroid Build Coastguard Worker
88*ec779b8eSAndroid Build Coastguard Worker return OK;
89*ec779b8eSAndroid Build Coastguard Worker }
90*ec779b8eSAndroid Build Coastguard Worker
setBufferingSettings(const BufferingSettings & buffering)91*ec779b8eSAndroid Build Coastguard Worker status_t NuPlayer::HTTPLiveSource::setBufferingSettings(const BufferingSettings& buffering) {
92*ec779b8eSAndroid Build Coastguard Worker mBufferingSettings = buffering;
93*ec779b8eSAndroid Build Coastguard Worker
94*ec779b8eSAndroid Build Coastguard Worker if (mLiveSession != NULL) {
95*ec779b8eSAndroid Build Coastguard Worker mLiveSession->setBufferingSettings(mBufferingSettings);
96*ec779b8eSAndroid Build Coastguard Worker }
97*ec779b8eSAndroid Build Coastguard Worker
98*ec779b8eSAndroid Build Coastguard Worker return OK;
99*ec779b8eSAndroid Build Coastguard Worker }
100*ec779b8eSAndroid Build Coastguard Worker
prepareAsync()101*ec779b8eSAndroid Build Coastguard Worker void NuPlayer::HTTPLiveSource::prepareAsync() {
102*ec779b8eSAndroid Build Coastguard Worker if (mLiveLooper == NULL) {
103*ec779b8eSAndroid Build Coastguard Worker mLiveLooper = new ALooper;
104*ec779b8eSAndroid Build Coastguard Worker mLiveLooper->setName("http live");
105*ec779b8eSAndroid Build Coastguard Worker mLiveLooper->start();
106*ec779b8eSAndroid Build Coastguard Worker
107*ec779b8eSAndroid Build Coastguard Worker mLiveLooper->registerHandler(this);
108*ec779b8eSAndroid Build Coastguard Worker }
109*ec779b8eSAndroid Build Coastguard Worker
110*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> notify = new AMessage(kWhatSessionNotify, this);
111*ec779b8eSAndroid Build Coastguard Worker
112*ec779b8eSAndroid Build Coastguard Worker mLiveSession = new LiveSession(
113*ec779b8eSAndroid Build Coastguard Worker notify,
114*ec779b8eSAndroid Build Coastguard Worker (mFlags & kFlagIncognito) ? LiveSession::kFlagIncognito : 0,
115*ec779b8eSAndroid Build Coastguard Worker mHTTPService);
116*ec779b8eSAndroid Build Coastguard Worker
117*ec779b8eSAndroid Build Coastguard Worker mLiveLooper->registerHandler(mLiveSession);
118*ec779b8eSAndroid Build Coastguard Worker
119*ec779b8eSAndroid Build Coastguard Worker mLiveSession->setBufferingSettings(mBufferingSettings);
120*ec779b8eSAndroid Build Coastguard Worker mLiveSession->connectAsync(
121*ec779b8eSAndroid Build Coastguard Worker mURL.c_str(), mExtraHeaders.isEmpty() ? NULL : &mExtraHeaders);
122*ec779b8eSAndroid Build Coastguard Worker }
123*ec779b8eSAndroid Build Coastguard Worker
start()124*ec779b8eSAndroid Build Coastguard Worker void NuPlayer::HTTPLiveSource::start() {
125*ec779b8eSAndroid Build Coastguard Worker }
126*ec779b8eSAndroid Build Coastguard Worker
getFormatMeta(bool audio)127*ec779b8eSAndroid Build Coastguard Worker sp<MetaData> NuPlayer::HTTPLiveSource::getFormatMeta(bool audio) {
128*ec779b8eSAndroid Build Coastguard Worker sp<MetaData> meta;
129*ec779b8eSAndroid Build Coastguard Worker if (mLiveSession != NULL) {
130*ec779b8eSAndroid Build Coastguard Worker mLiveSession->getStreamFormatMeta(
131*ec779b8eSAndroid Build Coastguard Worker audio ? LiveSession::STREAMTYPE_AUDIO
132*ec779b8eSAndroid Build Coastguard Worker : LiveSession::STREAMTYPE_VIDEO,
133*ec779b8eSAndroid Build Coastguard Worker &meta);
134*ec779b8eSAndroid Build Coastguard Worker }
135*ec779b8eSAndroid Build Coastguard Worker
136*ec779b8eSAndroid Build Coastguard Worker return meta;
137*ec779b8eSAndroid Build Coastguard Worker }
138*ec779b8eSAndroid Build Coastguard Worker
getFormat(bool audio)139*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> NuPlayer::HTTPLiveSource::getFormat(bool audio) {
140*ec779b8eSAndroid Build Coastguard Worker sp<MetaData> meta;
141*ec779b8eSAndroid Build Coastguard Worker status_t err = -EWOULDBLOCK;
142*ec779b8eSAndroid Build Coastguard Worker if (mLiveSession != NULL) {
143*ec779b8eSAndroid Build Coastguard Worker err = mLiveSession->getStreamFormatMeta(
144*ec779b8eSAndroid Build Coastguard Worker audio ? LiveSession::STREAMTYPE_AUDIO
145*ec779b8eSAndroid Build Coastguard Worker : LiveSession::STREAMTYPE_VIDEO,
146*ec779b8eSAndroid Build Coastguard Worker &meta);
147*ec779b8eSAndroid Build Coastguard Worker }
148*ec779b8eSAndroid Build Coastguard Worker
149*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> format;
150*ec779b8eSAndroid Build Coastguard Worker if (err == -EWOULDBLOCK) {
151*ec779b8eSAndroid Build Coastguard Worker format = new AMessage();
152*ec779b8eSAndroid Build Coastguard Worker format->setInt32("err", err);
153*ec779b8eSAndroid Build Coastguard Worker return format;
154*ec779b8eSAndroid Build Coastguard Worker }
155*ec779b8eSAndroid Build Coastguard Worker
156*ec779b8eSAndroid Build Coastguard Worker if (err != OK || convertMetaDataToMessage(meta, &format) != OK) {
157*ec779b8eSAndroid Build Coastguard Worker return NULL;
158*ec779b8eSAndroid Build Coastguard Worker }
159*ec779b8eSAndroid Build Coastguard Worker return format;
160*ec779b8eSAndroid Build Coastguard Worker }
161*ec779b8eSAndroid Build Coastguard Worker
feedMoreTSData()162*ec779b8eSAndroid Build Coastguard Worker status_t NuPlayer::HTTPLiveSource::feedMoreTSData() {
163*ec779b8eSAndroid Build Coastguard Worker return OK;
164*ec779b8eSAndroid Build Coastguard Worker }
165*ec779b8eSAndroid Build Coastguard Worker
dequeueAccessUnit(bool audio,sp<ABuffer> * accessUnit)166*ec779b8eSAndroid Build Coastguard Worker status_t NuPlayer::HTTPLiveSource::dequeueAccessUnit(
167*ec779b8eSAndroid Build Coastguard Worker bool audio, sp<ABuffer> *accessUnit) {
168*ec779b8eSAndroid Build Coastguard Worker return mLiveSession->dequeueAccessUnit(
169*ec779b8eSAndroid Build Coastguard Worker audio ? LiveSession::STREAMTYPE_AUDIO
170*ec779b8eSAndroid Build Coastguard Worker : LiveSession::STREAMTYPE_VIDEO,
171*ec779b8eSAndroid Build Coastguard Worker accessUnit);
172*ec779b8eSAndroid Build Coastguard Worker }
173*ec779b8eSAndroid Build Coastguard Worker
getDuration(int64_t * durationUs)174*ec779b8eSAndroid Build Coastguard Worker status_t NuPlayer::HTTPLiveSource::getDuration(int64_t *durationUs) {
175*ec779b8eSAndroid Build Coastguard Worker return mLiveSession->getDuration(durationUs);
176*ec779b8eSAndroid Build Coastguard Worker }
177*ec779b8eSAndroid Build Coastguard Worker
getTrackCount() const178*ec779b8eSAndroid Build Coastguard Worker size_t NuPlayer::HTTPLiveSource::getTrackCount() const {
179*ec779b8eSAndroid Build Coastguard Worker return mLiveSession->getTrackCount();
180*ec779b8eSAndroid Build Coastguard Worker }
181*ec779b8eSAndroid Build Coastguard Worker
getTrackInfo(size_t trackIndex) const182*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> NuPlayer::HTTPLiveSource::getTrackInfo(size_t trackIndex) const {
183*ec779b8eSAndroid Build Coastguard Worker return mLiveSession->getTrackInfo(trackIndex);
184*ec779b8eSAndroid Build Coastguard Worker }
185*ec779b8eSAndroid Build Coastguard Worker
getSelectedTrack(media_track_type type) const186*ec779b8eSAndroid Build Coastguard Worker ssize_t NuPlayer::HTTPLiveSource::getSelectedTrack(media_track_type type) const {
187*ec779b8eSAndroid Build Coastguard Worker if (mLiveSession == NULL) {
188*ec779b8eSAndroid Build Coastguard Worker return -1;
189*ec779b8eSAndroid Build Coastguard Worker } else if (type == MEDIA_TRACK_TYPE_METADATA) {
190*ec779b8eSAndroid Build Coastguard Worker // MEDIA_TRACK_TYPE_METADATA is always last track
191*ec779b8eSAndroid Build Coastguard Worker // mMetadataSelected can only be true when mHasMetadata is true
192*ec779b8eSAndroid Build Coastguard Worker return mMetadataSelected ? (mLiveSession->getTrackCount() - 1) : -1;
193*ec779b8eSAndroid Build Coastguard Worker } else {
194*ec779b8eSAndroid Build Coastguard Worker return mLiveSession->getSelectedTrack(type);
195*ec779b8eSAndroid Build Coastguard Worker }
196*ec779b8eSAndroid Build Coastguard Worker }
197*ec779b8eSAndroid Build Coastguard Worker
selectTrack(size_t trackIndex,bool select,int64_t)198*ec779b8eSAndroid Build Coastguard Worker status_t NuPlayer::HTTPLiveSource::selectTrack(size_t trackIndex, bool select, int64_t /*timeUs*/) {
199*ec779b8eSAndroid Build Coastguard Worker if (mLiveSession == NULL) {
200*ec779b8eSAndroid Build Coastguard Worker return INVALID_OPERATION;
201*ec779b8eSAndroid Build Coastguard Worker }
202*ec779b8eSAndroid Build Coastguard Worker
203*ec779b8eSAndroid Build Coastguard Worker status_t err = INVALID_OPERATION;
204*ec779b8eSAndroid Build Coastguard Worker bool postFetchMsg = false, isSub = false;
205*ec779b8eSAndroid Build Coastguard Worker if (!mHasMetadata || trackIndex != mLiveSession->getTrackCount() - 1) {
206*ec779b8eSAndroid Build Coastguard Worker err = mLiveSession->selectTrack(trackIndex, select);
207*ec779b8eSAndroid Build Coastguard Worker postFetchMsg = select;
208*ec779b8eSAndroid Build Coastguard Worker isSub = true;
209*ec779b8eSAndroid Build Coastguard Worker } else {
210*ec779b8eSAndroid Build Coastguard Worker // metadata track; i.e. (mHasMetadata && trackIndex == mLiveSession->getTrackCount() - 1)
211*ec779b8eSAndroid Build Coastguard Worker if (mMetadataSelected && !select) {
212*ec779b8eSAndroid Build Coastguard Worker err = OK;
213*ec779b8eSAndroid Build Coastguard Worker } else if (!mMetadataSelected && select) {
214*ec779b8eSAndroid Build Coastguard Worker postFetchMsg = true;
215*ec779b8eSAndroid Build Coastguard Worker err = OK;
216*ec779b8eSAndroid Build Coastguard Worker } else {
217*ec779b8eSAndroid Build Coastguard Worker err = BAD_VALUE; // behave as LiveSession::selectTrack
218*ec779b8eSAndroid Build Coastguard Worker }
219*ec779b8eSAndroid Build Coastguard Worker
220*ec779b8eSAndroid Build Coastguard Worker mMetadataSelected = select;
221*ec779b8eSAndroid Build Coastguard Worker }
222*ec779b8eSAndroid Build Coastguard Worker
223*ec779b8eSAndroid Build Coastguard Worker if (err == OK) {
224*ec779b8eSAndroid Build Coastguard Worker int32_t &generation = isSub ? mFetchSubtitleDataGeneration : mFetchMetaDataGeneration;
225*ec779b8eSAndroid Build Coastguard Worker generation++;
226*ec779b8eSAndroid Build Coastguard Worker if (postFetchMsg) {
227*ec779b8eSAndroid Build Coastguard Worker int32_t what = isSub ? kWhatFetchSubtitleData : kWhatFetchMetaData;
228*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> msg = new AMessage(what, this);
229*ec779b8eSAndroid Build Coastguard Worker msg->setInt32("generation", generation);
230*ec779b8eSAndroid Build Coastguard Worker msg->post();
231*ec779b8eSAndroid Build Coastguard Worker }
232*ec779b8eSAndroid Build Coastguard Worker }
233*ec779b8eSAndroid Build Coastguard Worker
234*ec779b8eSAndroid Build Coastguard Worker // LiveSession::selectTrack returns BAD_VALUE when selecting the currently
235*ec779b8eSAndroid Build Coastguard Worker // selected track, or unselecting a non-selected track. In this case it's an
236*ec779b8eSAndroid Build Coastguard Worker // no-op so we return OK.
237*ec779b8eSAndroid Build Coastguard Worker return (err == OK || err == BAD_VALUE) ? (status_t)OK : err;
238*ec779b8eSAndroid Build Coastguard Worker }
239*ec779b8eSAndroid Build Coastguard Worker
seekTo(int64_t seekTimeUs,MediaPlayerSeekMode mode)240*ec779b8eSAndroid Build Coastguard Worker status_t NuPlayer::HTTPLiveSource::seekTo(int64_t seekTimeUs, MediaPlayerSeekMode mode) {
241*ec779b8eSAndroid Build Coastguard Worker if (mLiveSession->isSeekable()) {
242*ec779b8eSAndroid Build Coastguard Worker return mLiveSession->seekTo(seekTimeUs, mode);
243*ec779b8eSAndroid Build Coastguard Worker } else {
244*ec779b8eSAndroid Build Coastguard Worker return INVALID_OPERATION;
245*ec779b8eSAndroid Build Coastguard Worker }
246*ec779b8eSAndroid Build Coastguard Worker }
247*ec779b8eSAndroid Build Coastguard Worker
pollForRawData(const sp<AMessage> & msg,int32_t currentGeneration,LiveSession::StreamType fetchType,int32_t pushWhat)248*ec779b8eSAndroid Build Coastguard Worker void NuPlayer::HTTPLiveSource::pollForRawData(
249*ec779b8eSAndroid Build Coastguard Worker const sp<AMessage> &msg, int32_t currentGeneration,
250*ec779b8eSAndroid Build Coastguard Worker LiveSession::StreamType fetchType, int32_t pushWhat) {
251*ec779b8eSAndroid Build Coastguard Worker
252*ec779b8eSAndroid Build Coastguard Worker int32_t generation;
253*ec779b8eSAndroid Build Coastguard Worker CHECK(msg->findInt32("generation", &generation));
254*ec779b8eSAndroid Build Coastguard Worker
255*ec779b8eSAndroid Build Coastguard Worker if (generation != currentGeneration) {
256*ec779b8eSAndroid Build Coastguard Worker return;
257*ec779b8eSAndroid Build Coastguard Worker }
258*ec779b8eSAndroid Build Coastguard Worker
259*ec779b8eSAndroid Build Coastguard Worker sp<ABuffer> buffer;
260*ec779b8eSAndroid Build Coastguard Worker while (mLiveSession->dequeueAccessUnit(fetchType, &buffer) == OK) {
261*ec779b8eSAndroid Build Coastguard Worker
262*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> notify = dupNotify();
263*ec779b8eSAndroid Build Coastguard Worker notify->setInt32("what", pushWhat);
264*ec779b8eSAndroid Build Coastguard Worker notify->setBuffer("buffer", buffer);
265*ec779b8eSAndroid Build Coastguard Worker
266*ec779b8eSAndroid Build Coastguard Worker int64_t timeUs, baseUs, delayUs;
267*ec779b8eSAndroid Build Coastguard Worker CHECK(buffer->meta()->findInt64("baseUs", &baseUs));
268*ec779b8eSAndroid Build Coastguard Worker CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
269*ec779b8eSAndroid Build Coastguard Worker delayUs = baseUs + timeUs - ALooper::GetNowUs();
270*ec779b8eSAndroid Build Coastguard Worker
271*ec779b8eSAndroid Build Coastguard Worker if (fetchType == LiveSession::STREAMTYPE_SUBTITLES) {
272*ec779b8eSAndroid Build Coastguard Worker notify->post();
273*ec779b8eSAndroid Build Coastguard Worker msg->post(delayUs > 0LL ? delayUs : 0LL);
274*ec779b8eSAndroid Build Coastguard Worker return;
275*ec779b8eSAndroid Build Coastguard Worker } else if (fetchType == LiveSession::STREAMTYPE_METADATA) {
276*ec779b8eSAndroid Build Coastguard Worker if (delayUs < -1000000LL) { // 1 second
277*ec779b8eSAndroid Build Coastguard Worker continue;
278*ec779b8eSAndroid Build Coastguard Worker }
279*ec779b8eSAndroid Build Coastguard Worker notify->post();
280*ec779b8eSAndroid Build Coastguard Worker // push all currently available metadata buffers in each invocation of pollForRawData
281*ec779b8eSAndroid Build Coastguard Worker // continue;
282*ec779b8eSAndroid Build Coastguard Worker } else {
283*ec779b8eSAndroid Build Coastguard Worker TRESPASS();
284*ec779b8eSAndroid Build Coastguard Worker }
285*ec779b8eSAndroid Build Coastguard Worker }
286*ec779b8eSAndroid Build Coastguard Worker
287*ec779b8eSAndroid Build Coastguard Worker // try again in 1 second
288*ec779b8eSAndroid Build Coastguard Worker msg->post(1000000LL);
289*ec779b8eSAndroid Build Coastguard Worker }
290*ec779b8eSAndroid Build Coastguard Worker
onMessageReceived(const sp<AMessage> & msg)291*ec779b8eSAndroid Build Coastguard Worker void NuPlayer::HTTPLiveSource::onMessageReceived(const sp<AMessage> &msg) {
292*ec779b8eSAndroid Build Coastguard Worker switch (msg->what()) {
293*ec779b8eSAndroid Build Coastguard Worker case kWhatSessionNotify:
294*ec779b8eSAndroid Build Coastguard Worker {
295*ec779b8eSAndroid Build Coastguard Worker onSessionNotify(msg);
296*ec779b8eSAndroid Build Coastguard Worker break;
297*ec779b8eSAndroid Build Coastguard Worker }
298*ec779b8eSAndroid Build Coastguard Worker
299*ec779b8eSAndroid Build Coastguard Worker case kWhatFetchSubtitleData:
300*ec779b8eSAndroid Build Coastguard Worker {
301*ec779b8eSAndroid Build Coastguard Worker pollForRawData(
302*ec779b8eSAndroid Build Coastguard Worker msg, mFetchSubtitleDataGeneration,
303*ec779b8eSAndroid Build Coastguard Worker /* fetch */ LiveSession::STREAMTYPE_SUBTITLES,
304*ec779b8eSAndroid Build Coastguard Worker /* push */ kWhatSubtitleData);
305*ec779b8eSAndroid Build Coastguard Worker
306*ec779b8eSAndroid Build Coastguard Worker break;
307*ec779b8eSAndroid Build Coastguard Worker }
308*ec779b8eSAndroid Build Coastguard Worker
309*ec779b8eSAndroid Build Coastguard Worker case kWhatFetchMetaData:
310*ec779b8eSAndroid Build Coastguard Worker {
311*ec779b8eSAndroid Build Coastguard Worker if (!mMetadataSelected) {
312*ec779b8eSAndroid Build Coastguard Worker break;
313*ec779b8eSAndroid Build Coastguard Worker }
314*ec779b8eSAndroid Build Coastguard Worker
315*ec779b8eSAndroid Build Coastguard Worker pollForRawData(
316*ec779b8eSAndroid Build Coastguard Worker msg, mFetchMetaDataGeneration,
317*ec779b8eSAndroid Build Coastguard Worker /* fetch */ LiveSession::STREAMTYPE_METADATA,
318*ec779b8eSAndroid Build Coastguard Worker /* push */ kWhatTimedMetaData);
319*ec779b8eSAndroid Build Coastguard Worker
320*ec779b8eSAndroid Build Coastguard Worker break;
321*ec779b8eSAndroid Build Coastguard Worker }
322*ec779b8eSAndroid Build Coastguard Worker
323*ec779b8eSAndroid Build Coastguard Worker default:
324*ec779b8eSAndroid Build Coastguard Worker Source::onMessageReceived(msg);
325*ec779b8eSAndroid Build Coastguard Worker break;
326*ec779b8eSAndroid Build Coastguard Worker }
327*ec779b8eSAndroid Build Coastguard Worker }
328*ec779b8eSAndroid Build Coastguard Worker
onSessionNotify(const sp<AMessage> & msg)329*ec779b8eSAndroid Build Coastguard Worker void NuPlayer::HTTPLiveSource::onSessionNotify(const sp<AMessage> &msg) {
330*ec779b8eSAndroid Build Coastguard Worker int32_t what;
331*ec779b8eSAndroid Build Coastguard Worker CHECK(msg->findInt32("what", &what));
332*ec779b8eSAndroid Build Coastguard Worker
333*ec779b8eSAndroid Build Coastguard Worker switch (what) {
334*ec779b8eSAndroid Build Coastguard Worker case LiveSession::kWhatPrepared:
335*ec779b8eSAndroid Build Coastguard Worker {
336*ec779b8eSAndroid Build Coastguard Worker // notify the current size here if we have it, otherwise report an initial size of (0,0)
337*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> format = getFormat(false /* audio */);
338*ec779b8eSAndroid Build Coastguard Worker int32_t width;
339*ec779b8eSAndroid Build Coastguard Worker int32_t height;
340*ec779b8eSAndroid Build Coastguard Worker if (format != NULL &&
341*ec779b8eSAndroid Build Coastguard Worker format->findInt32("width", &width) && format->findInt32("height", &height)) {
342*ec779b8eSAndroid Build Coastguard Worker notifyVideoSizeChanged(format);
343*ec779b8eSAndroid Build Coastguard Worker } else {
344*ec779b8eSAndroid Build Coastguard Worker notifyVideoSizeChanged();
345*ec779b8eSAndroid Build Coastguard Worker }
346*ec779b8eSAndroid Build Coastguard Worker
347*ec779b8eSAndroid Build Coastguard Worker uint32_t flags = 0;
348*ec779b8eSAndroid Build Coastguard Worker if (mLiveSession->isSeekable()) {
349*ec779b8eSAndroid Build Coastguard Worker flags |= FLAG_CAN_PAUSE;
350*ec779b8eSAndroid Build Coastguard Worker flags |= FLAG_CAN_SEEK;
351*ec779b8eSAndroid Build Coastguard Worker flags |= FLAG_CAN_SEEK_BACKWARD;
352*ec779b8eSAndroid Build Coastguard Worker flags |= FLAG_CAN_SEEK_FORWARD;
353*ec779b8eSAndroid Build Coastguard Worker }
354*ec779b8eSAndroid Build Coastguard Worker
355*ec779b8eSAndroid Build Coastguard Worker if (mLiveSession->hasDynamicDuration()) {
356*ec779b8eSAndroid Build Coastguard Worker flags |= FLAG_DYNAMIC_DURATION;
357*ec779b8eSAndroid Build Coastguard Worker }
358*ec779b8eSAndroid Build Coastguard Worker
359*ec779b8eSAndroid Build Coastguard Worker notifyFlagsChanged(flags);
360*ec779b8eSAndroid Build Coastguard Worker
361*ec779b8eSAndroid Build Coastguard Worker notifyPrepared();
362*ec779b8eSAndroid Build Coastguard Worker break;
363*ec779b8eSAndroid Build Coastguard Worker }
364*ec779b8eSAndroid Build Coastguard Worker
365*ec779b8eSAndroid Build Coastguard Worker case LiveSession::kWhatPreparationFailed:
366*ec779b8eSAndroid Build Coastguard Worker {
367*ec779b8eSAndroid Build Coastguard Worker status_t err;
368*ec779b8eSAndroid Build Coastguard Worker CHECK(msg->findInt32("err", &err));
369*ec779b8eSAndroid Build Coastguard Worker
370*ec779b8eSAndroid Build Coastguard Worker notifyPrepared(err);
371*ec779b8eSAndroid Build Coastguard Worker break;
372*ec779b8eSAndroid Build Coastguard Worker }
373*ec779b8eSAndroid Build Coastguard Worker
374*ec779b8eSAndroid Build Coastguard Worker case LiveSession::kWhatStreamsChanged:
375*ec779b8eSAndroid Build Coastguard Worker {
376*ec779b8eSAndroid Build Coastguard Worker uint32_t changedMask;
377*ec779b8eSAndroid Build Coastguard Worker CHECK(msg->findInt32(
378*ec779b8eSAndroid Build Coastguard Worker "changedMask", (int32_t *)&changedMask));
379*ec779b8eSAndroid Build Coastguard Worker
380*ec779b8eSAndroid Build Coastguard Worker bool audio = changedMask & LiveSession::STREAMTYPE_AUDIO;
381*ec779b8eSAndroid Build Coastguard Worker bool video = changedMask & LiveSession::STREAMTYPE_VIDEO;
382*ec779b8eSAndroid Build Coastguard Worker
383*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> reply;
384*ec779b8eSAndroid Build Coastguard Worker CHECK(msg->findMessage("reply", &reply));
385*ec779b8eSAndroid Build Coastguard Worker
386*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> notify = dupNotify();
387*ec779b8eSAndroid Build Coastguard Worker notify->setInt32("what", kWhatQueueDecoderShutdown);
388*ec779b8eSAndroid Build Coastguard Worker notify->setInt32("audio", audio);
389*ec779b8eSAndroid Build Coastguard Worker notify->setInt32("video", video);
390*ec779b8eSAndroid Build Coastguard Worker notify->setMessage("reply", reply);
391*ec779b8eSAndroid Build Coastguard Worker notify->post();
392*ec779b8eSAndroid Build Coastguard Worker break;
393*ec779b8eSAndroid Build Coastguard Worker }
394*ec779b8eSAndroid Build Coastguard Worker
395*ec779b8eSAndroid Build Coastguard Worker case LiveSession::kWhatBufferingStart:
396*ec779b8eSAndroid Build Coastguard Worker {
397*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> notify = dupNotify();
398*ec779b8eSAndroid Build Coastguard Worker notify->setInt32("what", kWhatPauseOnBufferingStart);
399*ec779b8eSAndroid Build Coastguard Worker notify->post();
400*ec779b8eSAndroid Build Coastguard Worker break;
401*ec779b8eSAndroid Build Coastguard Worker }
402*ec779b8eSAndroid Build Coastguard Worker
403*ec779b8eSAndroid Build Coastguard Worker case LiveSession::kWhatBufferingEnd:
404*ec779b8eSAndroid Build Coastguard Worker {
405*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> notify = dupNotify();
406*ec779b8eSAndroid Build Coastguard Worker notify->setInt32("what", kWhatResumeOnBufferingEnd);
407*ec779b8eSAndroid Build Coastguard Worker notify->post();
408*ec779b8eSAndroid Build Coastguard Worker break;
409*ec779b8eSAndroid Build Coastguard Worker }
410*ec779b8eSAndroid Build Coastguard Worker
411*ec779b8eSAndroid Build Coastguard Worker
412*ec779b8eSAndroid Build Coastguard Worker case LiveSession::kWhatBufferingUpdate:
413*ec779b8eSAndroid Build Coastguard Worker {
414*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> notify = dupNotify();
415*ec779b8eSAndroid Build Coastguard Worker int32_t percentage;
416*ec779b8eSAndroid Build Coastguard Worker CHECK(msg->findInt32("percentage", &percentage));
417*ec779b8eSAndroid Build Coastguard Worker notify->setInt32("what", kWhatBufferingUpdate);
418*ec779b8eSAndroid Build Coastguard Worker notify->setInt32("percentage", percentage);
419*ec779b8eSAndroid Build Coastguard Worker notify->post();
420*ec779b8eSAndroid Build Coastguard Worker break;
421*ec779b8eSAndroid Build Coastguard Worker }
422*ec779b8eSAndroid Build Coastguard Worker
423*ec779b8eSAndroid Build Coastguard Worker case LiveSession::kWhatMetadataDetected:
424*ec779b8eSAndroid Build Coastguard Worker {
425*ec779b8eSAndroid Build Coastguard Worker if (!mHasMetadata) {
426*ec779b8eSAndroid Build Coastguard Worker mHasMetadata = true;
427*ec779b8eSAndroid Build Coastguard Worker
428*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> notify = dupNotify();
429*ec779b8eSAndroid Build Coastguard Worker // notification without buffer triggers MEDIA_INFO_METADATA_UPDATE
430*ec779b8eSAndroid Build Coastguard Worker notify->setInt32("what", kWhatTimedMetaData);
431*ec779b8eSAndroid Build Coastguard Worker notify->post();
432*ec779b8eSAndroid Build Coastguard Worker }
433*ec779b8eSAndroid Build Coastguard Worker break;
434*ec779b8eSAndroid Build Coastguard Worker }
435*ec779b8eSAndroid Build Coastguard Worker
436*ec779b8eSAndroid Build Coastguard Worker case LiveSession::kWhatError:
437*ec779b8eSAndroid Build Coastguard Worker {
438*ec779b8eSAndroid Build Coastguard Worker break;
439*ec779b8eSAndroid Build Coastguard Worker }
440*ec779b8eSAndroid Build Coastguard Worker
441*ec779b8eSAndroid Build Coastguard Worker default:
442*ec779b8eSAndroid Build Coastguard Worker TRESPASS();
443*ec779b8eSAndroid Build Coastguard Worker }
444*ec779b8eSAndroid Build Coastguard Worker }
445*ec779b8eSAndroid Build Coastguard Worker
446*ec779b8eSAndroid Build Coastguard Worker } // namespace android
447*ec779b8eSAndroid Build Coastguard Worker
448