StreamingSource.cpp revision f2f072e87718ecf6df40ba51b95e2a93bc68f720
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (C) 2010 The Android Open Source Project
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License");
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * you may not use this file except in compliance with the License.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * You may obtain a copy of the License at
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      http://www.apache.org/licenses/LICENSE-2.0
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Unless required by applicable law or agreed to in writing, software
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * distributed under the License is distributed on an "AS IS" BASIS,
129ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See the License for the specific language governing permissions and
1458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch * limitations under the License.
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) */
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//#define LOG_NDEBUG 0
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define LOG_TAG "StreamingSource"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <utils/Log.h>
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "StreamingSource.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ATSParser.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "AnotherPacketSource.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "NuPlayerStreamListener.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <media/stagefright/foundation/ABuffer.h>
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <media/stagefright/foundation/ADebug.h>
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <media/stagefright/foundation/AMessage.h>
30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <media/stagefright/MediaSource.h>
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <media/stagefright/MetaData.h>
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace android {
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochNuPlayer::StreamingSource::StreamingSource(
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const sp<AMessage> &notify,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const sp<IStreamSource> &source)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : Source(notify),
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mSource(source),
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mFinalResult(OK) {
41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NuPlayer::StreamingSource::~StreamingSource() {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NuPlayer::StreamingSource::prepareAsync() {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    notifyVideoSizeChanged();
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    notifyFlagsChanged(0);
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    notifyPrepared();
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NuPlayer::StreamingSource::start() {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mStreamListener = new NuPlayerStreamListener(mSource, 0);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32_t sourceFlags = mSource->flags();
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32_t parserFlags = ATSParser::TS_TIMESTAMPS_ARE_ABSOLUTE;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sourceFlags & IStreamSource::kFlagAlignedVideoData) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        parserFlags |= ATSParser::ALIGNED_VIDEO_DATA;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mTSParser = new ATSParser(parserFlags);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    mStreamListener->start();
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)status_t NuPlayer::StreamingSource::feedMoreTSData() {
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (mFinalResult != OK) {
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return mFinalResult;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    for (int32_t i = 0; i < 50; ++i) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        char buffer[188];
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sp<AMessage> extra;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ssize_t n = mStreamListener->read(buffer, sizeof(buffer), &extra);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (n == 0) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ALOGI("input data EOS reached.");
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mTSParser->signalEOS(ERROR_END_OF_STREAM);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mFinalResult = ERROR_END_OF_STREAM;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else if (n == INFO_DISCONTINUITY) {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            int32_t type = ATSParser::DISCONTINUITY_TIME;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            int32_t mask;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (extra != NULL
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    && extra->findInt32(
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        IStreamListener::kKeyDiscontinuityMask, &mask)) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (mask == 0) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    ALOGE("Client specified an illegal discontinuity type.");
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    return ERROR_UNSUPPORTED;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                type = mask;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mTSParser->signalDiscontinuity(
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    (ATSParser::DiscontinuityType)type, extra);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else if (n < 0) {
10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            CHECK_EQ(n, -EWOULDBLOCK);
101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            break;
10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        } else {
10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            if (buffer[0] == 0x00) {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                // XXX legacy
105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (extra == NULL) {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    extra = new AMessage;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                uint8_t type = buffer[1];
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (type & 2) {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    int64_t mediaTimeUs;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    memcpy(&mediaTimeUs, &buffer[2], sizeof(mediaTimeUs));
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    extra->setInt64(IStreamListener::kKeyMediaTimeUs, mediaTimeUs);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                mTSParser->signalDiscontinuity(
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        ((type & 1) == 0)
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            ? ATSParser::DISCONTINUITY_TIME
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            : ATSParser::DISCONTINUITY_FORMATCHANGE,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        extra);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                status_t err = mTSParser->feedTSPacket(buffer, sizeof(buffer));
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (err != OK) {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    ALOGE("TS Parser returned error %d", err);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    mTSParser->signalEOS(err);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    mFinalResult = err;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    break;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OK;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sp<MetaData> NuPlayer::StreamingSource::getFormatMeta(bool audio) {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ATSParser::SourceType type =
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        audio ? ATSParser::AUDIO : ATSParser::VIDEO;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sp<AnotherPacketSource> source =
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        static_cast<AnotherPacketSource *>(mTSParser->getSource(type).get());
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (source == NULL) {
149        return NULL;
150    }
151
152    return source->getFormat();
153}
154
155status_t NuPlayer::StreamingSource::dequeueAccessUnit(
156        bool audio, sp<ABuffer> *accessUnit) {
157    ATSParser::SourceType type =
158        audio ? ATSParser::AUDIO : ATSParser::VIDEO;
159
160    sp<AnotherPacketSource> source =
161        static_cast<AnotherPacketSource *>(mTSParser->getSource(type).get());
162
163    if (source == NULL) {
164        return -EWOULDBLOCK;
165    }
166
167    status_t finalResult;
168    if (!source->hasBufferAvailable(&finalResult)) {
169        return finalResult == OK ? -EWOULDBLOCK : finalResult;
170    }
171
172    status_t err = source->dequeueAccessUnit(accessUnit);
173
174#if !defined(LOG_NDEBUG) || LOG_NDEBUG == 0
175    if (err == OK) {
176        int64_t timeUs;
177        CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs));
178        ALOGV("dequeueAccessUnit timeUs=%lld us", timeUs);
179    }
180#endif
181
182    return err;
183}
184
185bool NuPlayer::StreamingSource::isRealTime() const {
186    return mSource->flags() & IStreamSource::kFlagIsRealTimeData;
187}
188
189}  // namespace android
190
191