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
267e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim#include <media/MediaCodecBuffer.h>
277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include <media/stagefright/foundation/ADebug.h>
287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include <media/stagefright/foundation/AMessage.h>
297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangnamespace android {
317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
32202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy HungNuPlayer::DecoderBase::DecoderBase(const sp<AMessage> &notify)
33202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    :  mNotify(notify),
34202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung       mBufferGeneration(0),
353bc667014875aba35102941b3997d242c303aa0dWei Jia       mPaused(false),
36e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan       mStats(new AMessage),
37202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung       mRequestInputBuffersPending(false) {
387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // Every decoder has its own looper because MediaCodec operations
397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // are blocking, but NuPlayer needs asynchronous operations.
407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDecoderLooper = new ALooper;
417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDecoderLooper->setName("NPDecoder");
427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDecoderLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong ZhangNuPlayer::DecoderBase::~DecoderBase() {
4637ff0e6639e90ca49d4f0386a76c09437b459efdWei Jia    stopLooper();
477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatic
507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatus_t PostAndAwaitResponse(
517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        const sp<AMessage> &msg, sp<AMessage> *response) {
527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    status_t err = msg->postAndAwaitResponse(response);
537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (err != OK) {
557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        return err;
567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (!(*response)->findInt32("err", &err)) {
597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        err = OK;
607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return err;
637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::configure(const sp<AMessage> &format) {
661d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatConfigure, this);
677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    msg->setMessage("format", format);
687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    msg->post();
697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::init() {
727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDecoderLooper->registerHandler(this);
737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
7537ff0e6639e90ca49d4f0386a76c09437b459efdWei Jiavoid NuPlayer::DecoderBase::stopLooper() {
7637ff0e6639e90ca49d4f0386a76c09437b459efdWei Jia    mDecoderLooper->unregisterHandler(id());
7737ff0e6639e90ca49d4f0386a76c09437b459efdWei Jia    mDecoderLooper->stop();
7837ff0e6639e90ca49d4f0386a76c09437b459efdWei Jia}
7937ff0e6639e90ca49d4f0386a76c09437b459efdWei Jia
808db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wuvoid NuPlayer::DecoderBase::setParameters(const sp<AMessage> &params) {
818db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
828db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    msg->setMessage("params", params);
838db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    msg->post();
848db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu}
858db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::setRenderer(const sp<Renderer> &renderer) {
871d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetRenderer, this);
887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    msg->setObject("renderer", renderer);
897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    msg->post();
907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
923bc667014875aba35102941b3997d242c303aa0dWei Jiavoid NuPlayer::DecoderBase::pause() {
933bc667014875aba35102941b3997d242c303aa0dWei Jia    sp<AMessage> msg = new AMessage(kWhatPause, this);
943bc667014875aba35102941b3997d242c303aa0dWei Jia
953bc667014875aba35102941b3997d242c303aa0dWei Jia    sp<AMessage> response;
963bc667014875aba35102941b3997d242c303aa0dWei Jia    PostAndAwaitResponse(msg, &response);
973bc667014875aba35102941b3997d242c303aa0dWei Jia}
983bc667014875aba35102941b3997d242c303aa0dWei Jia
997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::signalFlush() {
1001d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatFlush, this))->post();
1017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
1027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
103f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::DecoderBase::signalResume(bool notifyComplete) {
1041d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatResume, this);
105f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    msg->setInt32("notifyComplete", notifyComplete);
106f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang    msg->post();
1077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
1087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::initiateShutdown() {
1101d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatShutdown, this))->post();
1117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
1127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::onRequestInputBuffers() {
1147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mRequestInputBuffersPending) {
1157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        return;
1167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
1177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1183b032b3865fd93173aadca0591eeea32853206f9Chong Zhang    // doRequestBuffers() return true if we should request more data
1193b032b3865fd93173aadca0591eeea32853206f9Chong Zhang    if (doRequestBuffers()) {
1203b032b3865fd93173aadca0591eeea32853206f9Chong Zhang        mRequestInputBuffersPending = true;
1217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1223b032b3865fd93173aadca0591eeea32853206f9Chong Zhang        sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, this);
1233b032b3865fd93173aadca0591eeea32853206f9Chong Zhang        msg->post(10 * 1000ll);
1247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
1257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
1267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::onMessageReceived(const sp<AMessage> &msg) {
1287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    switch (msg->what()) {
1307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatConfigure:
1317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            sp<AMessage> format;
1337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            CHECK(msg->findMessage("format", &format));
1347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            onConfigure(format);
1357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1388db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        case kWhatSetParameters:
1398db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        {
1408db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            sp<AMessage> params;
1418db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            CHECK(msg->findMessage("params", &params));
1428db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            onSetParameters(params);
1438db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            break;
1448db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        }
1458db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
1467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatSetRenderer:
1477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            sp<RefBase> obj;
1497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            CHECK(msg->findObject("renderer", &obj));
1507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            onSetRenderer(static_cast<Renderer *>(obj.get()));
1517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1543bc667014875aba35102941b3997d242c303aa0dWei Jia        case kWhatPause:
1553bc667014875aba35102941b3997d242c303aa0dWei Jia        {
1563bc667014875aba35102941b3997d242c303aa0dWei Jia            sp<AReplyToken> replyID;
1573bc667014875aba35102941b3997d242c303aa0dWei Jia            CHECK(msg->senderAwaitsResponse(&replyID));
1583bc667014875aba35102941b3997d242c303aa0dWei Jia
1593bc667014875aba35102941b3997d242c303aa0dWei Jia            mPaused = true;
1603bc667014875aba35102941b3997d242c303aa0dWei Jia
1613bc667014875aba35102941b3997d242c303aa0dWei Jia            (new AMessage)->postReply(replyID);
1623bc667014875aba35102941b3997d242c303aa0dWei Jia            break;
1633bc667014875aba35102941b3997d242c303aa0dWei Jia        }
1643bc667014875aba35102941b3997d242c303aa0dWei Jia
1657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatRequestInputBuffers:
1667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mRequestInputBuffersPending = false;
1687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            onRequestInputBuffers();
1697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatFlush:
1737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
17466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang            onFlush();
1757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatResume:
1797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
180f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang            int32_t notifyComplete;
181f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang            CHECK(msg->findInt32("notifyComplete", &notifyComplete));
182f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang
183f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang            onResume(notifyComplete);
1847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatShutdown:
1887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            onShutdown(true);
1907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        default:
1947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            TRESPASS();
1957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
1977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
1987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
199202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hungvoid NuPlayer::DecoderBase::handleError(int32_t err)
200202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung{
201202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    // We cannot immediately release the codec due to buffers still outstanding
202202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    // in the renderer.  We signal to the player the error so it can shutdown/release the
203202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    // decoder after flushing and increment the generation to discard unnecessary messages.
204202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung
205202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    ++mBufferGeneration;
206202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung
207202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    sp<AMessage> notify = mNotify->dup();
208202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    notify->setInt32("what", kWhatError);
209202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    notify->setInt32("err", err);
210202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    notify->post();
211202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung}
212202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung
2137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}  // namespace android
2147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
215