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