HTTPLiveSource.cpp revision 43c3e6ce02215ca99d506458f596cb1211639f29
17c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar/*
27c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar * Copyright (C) 2010 The Android Open Source Project
37c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar *
47c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar * Licensed under the Apache License, Version 2.0 (the "License");
57c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar * you may not use this file except in compliance with the License.
67c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar * You may obtain a copy of the License at
77c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar *
87c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar *      http://www.apache.org/licenses/LICENSE-2.0
97c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar *
107c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar * Unless required by applicable law or agreed to in writing, software
117c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar * distributed under the License is distributed on an "AS IS" BASIS,
127c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar * See the License for the specific language governing permissions and
147c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar * limitations under the License.
157c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar */
167c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
177c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar//#define LOG_NDEBUG 0
187c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar#define LOG_TAG "HTTPLiveSource"
197c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar#include <utils/Log.h>
207c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
217c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar#include "HTTPLiveSource.h"
227c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
237c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar#include "ATSParser.h"
247c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar#include "AnotherPacketSource.h"
257c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar#include "LiveDataSource.h"
267c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar#include "LiveSession.h"
277c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
287c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar#include <media/stagefright/foundation/ABuffer.h>
297c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar#include <media/stagefright/foundation/ADebug.h>
307c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar#include <media/stagefright/foundation/AMessage.h>
317c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar#include <media/stagefright/MediaErrors.h>
327c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar#include <media/stagefright/MetaData.h>
337c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
347c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnarnamespace android {
357c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
367c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos MolnarNuPlayer::HTTPLiveSource::HTTPLiveSource(const char *url)
377c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    : mURL(url),
387c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar      mEOS(false),
397c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar      mOffset(0) {
407c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar}
417c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
427c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos MolnarNuPlayer::HTTPLiveSource::~HTTPLiveSource() {
437c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    mLiveSession->disconnect();
447c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    mLiveLooper->stop();
457c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar}
467c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
477c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnarvoid NuPlayer::HTTPLiveSource::start() {
487c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    mLiveLooper = new ALooper;
497c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    mLiveLooper->setName("http live");
507c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    mLiveLooper->start();
517c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
527c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    mLiveSession = new LiveSession;
537c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    mLiveLooper->registerHandler(mLiveSession);
547c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
557c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    mLiveSession->connect(mURL.c_str());
567c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
577c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    mTSParser = new ATSParser;
587c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar}
597c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
60b4e0bce8404071958366573c2029a205336b6de2Lajos Molnarsp<MetaData> NuPlayer::HTTPLiveSource::getFormat(bool audio) {
617c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    ATSParser::SourceType type =
627c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar        audio ? ATSParser::MPEG2ADTS_AUDIO : ATSParser::AVC_VIDEO;
637c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
647c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    sp<AnotherPacketSource> source =
657c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar        static_cast<AnotherPacketSource *>(mTSParser->getSource(type).get());
667c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
677c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    if (source == NULL) {
687c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar        return NULL;
697c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    }
707c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
717c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    return source->getFormat();
727c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar}
737c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
747c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnarbool NuPlayer::HTTPLiveSource::feedMoreTSData() {
757c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    if (mEOS) {
767c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar        return false;
777c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    }
787c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
797c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    sp<LiveDataSource> source =
807c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar        static_cast<LiveDataSource *>(mLiveSession->getDataSource().get());
817c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
827c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    for (int32_t i = 0; i < 10; ++i) {
837c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar        char buffer[188];
847c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar        ssize_t n = source->readAtNonBlocking(mOffset, buffer, sizeof(buffer));
857c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
867c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar        if (n == -EWOULDBLOCK) {
877c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar            break;
88b4e0bce8404071958366573c2029a205336b6de2Lajos Molnar        } else if (n < 0) {
897c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar            LOGI("input data EOS reached.");
907c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar            mTSParser->signalEOS(n);
917c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar            mEOS = true;
927c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar            break;
937c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar        } else {
947c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar            if (buffer[0] == 0x00) {
957c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar                // XXX legacy
967c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar                mTSParser->signalDiscontinuity(
977c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar                        buffer[1] == 0x00
987c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar                            ? ATSParser::DISCONTINUITY_SEEK
997c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar                            : ATSParser::DISCONTINUITY_FORMATCHANGE);
1007c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar            } else {
101b4e0bce8404071958366573c2029a205336b6de2Lajos Molnar                mTSParser->feedTSPacket(buffer, sizeof(buffer));
102b4e0bce8404071958366573c2029a205336b6de2Lajos Molnar            }
103b4e0bce8404071958366573c2029a205336b6de2Lajos Molnar
1047c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar            mOffset += n;
1057c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar        }
1067c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    }
1077c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
1087c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    return true;
1097c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar}
1107c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
1117c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnarstatus_t NuPlayer::HTTPLiveSource::dequeueAccessUnit(
1127c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar        bool audio, sp<ABuffer> *accessUnit) {
113b4e0bce8404071958366573c2029a205336b6de2Lajos Molnar    ATSParser::SourceType type =
1147c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar        audio ? ATSParser::MPEG2ADTS_AUDIO : ATSParser::AVC_VIDEO;
1157c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
1167c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    sp<AnotherPacketSource> source =
1177c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar        static_cast<AnotherPacketSource *>(mTSParser->getSource(type).get());
1187c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
1197c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    if (source == NULL) {
1207c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar        return -EWOULDBLOCK;
1217c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    }
1227c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
1237c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    status_t finalResult;
1247c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    if (!source->hasBufferAvailable(&finalResult)) {
1257c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar        return finalResult == OK ? -EWOULDBLOCK : finalResult;
1267c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    }
1277c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
1287c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    return source->dequeueAccessUnit(accessUnit);
1297c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar}
1307c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
1317c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnarstatus_t NuPlayer::HTTPLiveSource::getDuration(int64_t *durationUs) {
1327c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    return mLiveSession->getDuration(durationUs);
1337c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar}
1347c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
1357c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnarstatus_t NuPlayer::HTTPLiveSource::seekTo(int64_t seekTimeUs) {
1367c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    // We need to make sure we're not seeking until we have seen the very first
1377c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    // PTS timestamp in the whole stream (from the beginning of the stream).
1387c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    while (!mTSParser->PTSTimeDeltaEstablished() && feedMoreTSData()) {
1397c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar        usleep(100000);
1407c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    }
1417c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
1427c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    mLiveSession->seekTo(seekTimeUs);
1437c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
1447c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    return OK;
1457c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar}
1467c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
1477c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnarbool NuPlayer::HTTPLiveSource::isSeekable() {
1487c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar    return mLiveSession->isSeekable();
1497c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar}
1507c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
1517c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar}  // namespace android
1527c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar
1537c357a75991d6b0ae260d9e2b730bcfe7181f899Lajos Molnar