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> ¬ify) 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) { 647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> msg = new AMessage(kWhatConfigure, id()); 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) { 747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> msg = new AMessage(kWhatSetRenderer, id()); 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 { 807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> msg = new AMessage(kWhatGetInputBuffers, id()); 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() { 887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang (new AMessage(kWhatFlush, id()))->post(); 897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 91f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::DecoderBase::signalResume(bool notifyComplete) { 92f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang sp<AMessage> msg = new AMessage(kWhatResume, id()); 93f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang msg->setInt32("notifyComplete", notifyComplete); 94f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang msg->post(); 957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::DecoderBase::initiateShutdown() { 987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang (new AMessage(kWhatShutdown, id()))->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; 1147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, id()); 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 { 1607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang onFlush(true); 1617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 1627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 1647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang case kWhatResume: 1657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang { 166f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang int32_t notifyComplete; 167f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang CHECK(msg->findInt32("notifyComplete", ¬ifyComplete)); 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