NuPlayerDecoderBase.cpp revision 66704af4d82c2b6303609b29402641f861fdcb19
17137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang/*
27137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang * Copyright (C) 2010 The Android Open Source Project
37137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang *
47137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang * Licensed under the Apache License, Version 2.0 (the "License");
57137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang * you may not use this file except in compliance with the License.
67137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang * You may obtain a copy of the License at
77137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang *
87137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang *      http://www.apache.org/licenses/LICENSE-2.0
97137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang *
107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang * Unless required by applicable law or agreed to in writing, software
117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang * distributed under the License is distributed on an "AS IS" BASIS,
127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang * See the License for the specific language governing permissions and
147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang * limitations under the License.
157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang */
167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang//#define LOG_NDEBUG 0
187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#define LOG_TAG "NuPlayerDecoderBase"
197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include <utils/Log.h>
207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include <inttypes.h>
217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "NuPlayerDecoderBase.h"
237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "NuPlayerRenderer.h"
257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include <media/stagefright/foundation/ADebug.h>
277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include <media/stagefright/foundation/AMessage.h>
287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangnamespace android {
307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
31202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy HungNuPlayer::DecoderBase::DecoderBase(const sp<AMessage> &notify)
32202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    :  mNotify(notify),
33202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung       mBufferGeneration(0),
34202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung       mRequestInputBuffersPending(false) {
357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // Every decoder has its own looper because MediaCodec operations
367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // are blocking, but NuPlayer needs asynchronous operations.
377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDecoderLooper = new ALooper;
387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDecoderLooper->setName("NPDecoder");
397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDecoderLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong ZhangNuPlayer::DecoderBase::~DecoderBase() {
437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDecoderLooper->unregisterHandler(id());
447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDecoderLooper->stop();
457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatic
487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatus_t PostAndAwaitResponse(
497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        const sp<AMessage> &msg, sp<AMessage> *response) {
507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    status_t err = msg->postAndAwaitResponse(response);
517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (err != OK) {
537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        return err;
547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (!(*response)->findInt32("err", &err)) {
577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        err = OK;
587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return err;
617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::configure(const sp<AMessage> &format) {
641d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatConfigure, this);
657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    msg->setMessage("format", format);
667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    msg->post();
677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::init() {
707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDecoderLooper->registerHandler(this);
717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::setRenderer(const sp<Renderer> &renderer) {
741d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetRenderer, this);
757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    msg->setObject("renderer", renderer);
767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    msg->post();
777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatus_t NuPlayer::DecoderBase::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
801d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetInputBuffers, this);
817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    msg->setPointer("buffers", buffers);
827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<AMessage> response;
847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return PostAndAwaitResponse(msg, &response);
857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::signalFlush() {
881d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatFlush, this))->post();
897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
91f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::DecoderBase::signalResume(bool notifyComplete) {
921d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatResume, this);
93f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    msg->setInt32("notifyComplete", notifyComplete);
94f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    msg->post();
957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::initiateShutdown() {
981d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatShutdown, this))->post();
997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
1007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::onRequestInputBuffers() {
1027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mRequestInputBuffersPending) {
1037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        return;
1047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
1057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    doRequestBuffers();
1077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
1087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::scheduleRequestBuffers() {
1107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mRequestInputBuffersPending) {
1117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        return;
1127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
1137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mRequestInputBuffersPending = true;
1141d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, this);
1157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    msg->post(10 * 1000ll);
1167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
1177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::onMessageReceived(const sp<AMessage> &msg) {
1197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    switch (msg->what()) {
1217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatConfigure:
1227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            sp<AMessage> format;
1247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            CHECK(msg->findMessage("format", &format));
1257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            onConfigure(format);
1267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatSetRenderer:
1307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            sp<RefBase> obj;
1327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            CHECK(msg->findObject("renderer", &obj));
1337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            onSetRenderer(static_cast<Renderer *>(obj.get()));
1347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatGetInputBuffers:
1387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            uint32_t replyID;
1407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            CHECK(msg->senderAwaitsResponse(&replyID));
1417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            Vector<sp<ABuffer> > *dstBuffers;
1437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
1447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            onGetInputBuffers(dstBuffers);
1467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            (new AMessage)->postReply(replyID);
1487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatRequestInputBuffers:
1527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mRequestInputBuffersPending = false;
1547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            onRequestInputBuffers();
1557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatFlush:
1597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
16066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            onFlush();
1617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatResume:
1657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
166f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang            int32_t notifyComplete;
167f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang            CHECK(msg->findInt32("notifyComplete", &notifyComplete));
168f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
169f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang            onResume(notifyComplete);
1707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatShutdown:
1747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            onShutdown(true);
1767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        default:
1807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            TRESPASS();
1817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
1837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
1847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
185202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hungvoid NuPlayer::DecoderBase::handleError(int32_t err)
186202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung{
187202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    // We cannot immediately release the codec due to buffers still outstanding
188202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    // in the renderer.  We signal to the player the error so it can shutdown/release the
189202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    // decoder after flushing and increment the generation to discard unnecessary messages.
190202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung
191202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    ++mBufferGeneration;
192202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung
193202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    sp<AMessage> notify = mNotify->dup();
194202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    notify->setInt32("what", kWhatError);
195202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    notify->setInt32("err", err);
196202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    notify->post();
197202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung}
198202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung
1997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}  // namespace android
2007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
201