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), 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> ¶ms) { 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", ¶ms)); 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", ¬ifyComplete)); 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