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),
34e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan       mStats(new AMessage),
35202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung       mRequestInputBuffersPending(false) {
367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // Every decoder has its own looper because MediaCodec operations
377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // are blocking, but NuPlayer needs asynchronous operations.
387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDecoderLooper = new ALooper;
397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDecoderLooper->setName("NPDecoder");
407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDecoderLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong ZhangNuPlayer::DecoderBase::~DecoderBase() {
447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDecoderLooper->unregisterHandler(id());
457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDecoderLooper->stop();
467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatic
497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatus_t PostAndAwaitResponse(
507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        const sp<AMessage> &msg, sp<AMessage> *response) {
517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    status_t err = msg->postAndAwaitResponse(response);
527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (err != OK) {
547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        return err;
557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (!(*response)->findInt32("err", &err)) {
587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        err = OK;
597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return err;
627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::configure(const sp<AMessage> &format) {
651d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatConfigure, this);
667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    msg->setMessage("format", format);
677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    msg->post();
687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::init() {
717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDecoderLooper->registerHandler(this);
727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
748db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wuvoid NuPlayer::DecoderBase::setParameters(const sp<AMessage> &params) {
758db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
768db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    msg->setMessage("params", params);
778db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    msg->post();
788db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu}
798db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::setRenderer(const sp<Renderer> &renderer) {
811d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetRenderer, this);
827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    msg->setObject("renderer", renderer);
837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    msg->post();
847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatus_t NuPlayer::DecoderBase::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
871d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetInputBuffers, this);
887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    msg->setPointer("buffers", buffers);
897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<AMessage> response;
917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return PostAndAwaitResponse(msg, &response);
927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::signalFlush() {
951d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatFlush, this))->post();
967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
98f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::DecoderBase::signalResume(bool notifyComplete) {
991d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatResume, this);
100f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    msg->setInt32("notifyComplete", notifyComplete);
101f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    msg->post();
1027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
1037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::initiateShutdown() {
1051d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatShutdown, this))->post();
1067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
1077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::onRequestInputBuffers() {
1097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mRequestInputBuffersPending) {
1107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        return;
1117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
1127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1133b032b3865fd93173aadca0591eeea32853206f9Chong Zhang    // doRequestBuffers() return true if we should request more data
1143b032b3865fd93173aadca0591eeea32853206f9Chong Zhang    if (doRequestBuffers()) {
1153b032b3865fd93173aadca0591eeea32853206f9Chong Zhang        mRequestInputBuffersPending = true;
1167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1173b032b3865fd93173aadca0591eeea32853206f9Chong Zhang        sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, this);
1183b032b3865fd93173aadca0591eeea32853206f9Chong Zhang        msg->post(10 * 1000ll);
1197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
1207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
1217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::onMessageReceived(const sp<AMessage> &msg) {
1237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    switch (msg->what()) {
1257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatConfigure:
1267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            sp<AMessage> format;
1287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            CHECK(msg->findMessage("format", &format));
1297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            onConfigure(format);
1307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1338db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        case kWhatSetParameters:
1348db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        {
1358db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            sp<AMessage> params;
1368db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            CHECK(msg->findMessage("params", &params));
1378db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            onSetParameters(params);
1388db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            break;
1398db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        }
1408db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
1417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatSetRenderer:
1427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            sp<RefBase> obj;
1447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            CHECK(msg->findObject("renderer", &obj));
1457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            onSetRenderer(static_cast<Renderer *>(obj.get()));
1467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatGetInputBuffers:
1507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1513f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
1527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            CHECK(msg->senderAwaitsResponse(&replyID));
1537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            Vector<sp<ABuffer> > *dstBuffers;
1557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
1567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            onGetInputBuffers(dstBuffers);
1587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            (new AMessage)->postReply(replyID);
1607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatRequestInputBuffers:
1647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mRequestInputBuffersPending = false;
1667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            onRequestInputBuffers();
1677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatFlush:
1717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
17266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            onFlush();
1737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatResume:
1777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
178f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang            int32_t notifyComplete;
179f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang            CHECK(msg->findInt32("notifyComplete", &notifyComplete));
180f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
181f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang            onResume(notifyComplete);
1827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatShutdown:
1867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            onShutdown(true);
1887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        default:
1927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            TRESPASS();
1937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
1957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
1967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
197202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hungvoid NuPlayer::DecoderBase::handleError(int32_t err)
198202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung{
199202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    // We cannot immediately release the codec due to buffers still outstanding
200202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    // in the renderer.  We signal to the player the error so it can shutdown/release the
201202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    // decoder after flushing and increment the generation to discard unnecessary messages.
202202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung
203202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    ++mBufferGeneration;
204202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung
205202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    sp<AMessage> notify = mNotify->dup();
206202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    notify->setInt32("what", kWhatError);
207202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    notify->setInt32("err", err);
208202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    notify->post();
209202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung}
210202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung
2117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}  // namespace android
2127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
213