NuPlayerDecoderBase.cpp revision 7137ec7e005a5a6e3c0edb91cfacf16a31f4bf6a
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
317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong ZhangNuPlayer::DecoderBase::DecoderBase()
327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    : mRequestInputBuffersPending(false) {
337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // Every decoder has its own looper because MediaCodec operations
347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    // are blocking, but NuPlayer needs asynchronous operations.
357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDecoderLooper = new ALooper;
367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDecoderLooper->setName("NPDecoder");
377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDecoderLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong ZhangNuPlayer::DecoderBase::~DecoderBase() {
417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDecoderLooper->unregisterHandler(id());
427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDecoderLooper->stop();
437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatic
467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatus_t PostAndAwaitResponse(
477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        const sp<AMessage> &msg, sp<AMessage> *response) {
487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    status_t err = msg->postAndAwaitResponse(response);
497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (err != OK) {
517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        return err;
527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (!(*response)->findInt32("err", &err)) {
557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        err = OK;
567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return err;
597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::configure(const sp<AMessage> &format) {
627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<AMessage> msg = new AMessage(kWhatConfigure, id());
637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    msg->setMessage("format", format);
647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    msg->post();
657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::init() {
687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mDecoderLooper->registerHandler(this);
697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::setRenderer(const sp<Renderer> &renderer) {
727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<AMessage> msg = new AMessage(kWhatSetRenderer, id());
737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    msg->setObject("renderer", renderer);
747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    msg->post();
757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatus_t NuPlayer::DecoderBase::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<AMessage> msg = new AMessage(kWhatGetInputBuffers, id());
797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    msg->setPointer("buffers", buffers);
807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<AMessage> response;
827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    return PostAndAwaitResponse(msg, &response);
837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::signalFlush() {
867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    (new AMessage(kWhatFlush, id()))->post();
877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::signalResume() {
907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    (new AMessage(kWhatResume, id()))->post();
917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::initiateShutdown() {
947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    (new AMessage(kWhatShutdown, id()))->post();
957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::onRequestInputBuffers() {
987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mRequestInputBuffersPending) {
997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        return;
1007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
1017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    doRequestBuffers();
1037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
1047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::scheduleRequestBuffers() {
1067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    if (mRequestInputBuffersPending) {
1077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        return;
1087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
1097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    mRequestInputBuffersPending = true;
1107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, id());
1117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    msg->post(10 * 1000ll);
1127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
1137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::onMessageReceived(const sp<AMessage> &msg) {
1157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    switch (msg->what()) {
1177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatConfigure:
1187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            sp<AMessage> format;
1207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            CHECK(msg->findMessage("format", &format));
1217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            onConfigure(format);
1227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatSetRenderer:
1267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            sp<RefBase> obj;
1287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            CHECK(msg->findObject("renderer", &obj));
1297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            onSetRenderer(static_cast<Renderer *>(obj.get()));
1307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatGetInputBuffers:
1347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            uint32_t replyID;
1367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            CHECK(msg->senderAwaitsResponse(&replyID));
1377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            Vector<sp<ABuffer> > *dstBuffers;
1397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
1407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            onGetInputBuffers(dstBuffers);
1427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            (new AMessage)->postReply(replyID);
1447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatRequestInputBuffers:
1487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            mRequestInputBuffersPending = false;
1507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            onRequestInputBuffers();
1517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatFlush:
1557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            onFlush(true);
1577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatResume:
1617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            onResume();
1637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        case kWhatShutdown:
1677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        {
1687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            onShutdown(true);
1697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
1717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        default:
1737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            TRESPASS();
1747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            break;
1757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
1767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}
1777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
1787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang}  // namespace android
1797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang
180