1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2010 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker *
4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker *
8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker *
10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker */
16*ec779b8eSAndroid Build Coastguard Worker
17*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
18*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "NuPlayerDecoderBase"
19*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
20*ec779b8eSAndroid Build Coastguard Worker #include <inttypes.h>
21*ec779b8eSAndroid Build Coastguard Worker
22*ec779b8eSAndroid Build Coastguard Worker #include "NuPlayerDecoderBase.h"
23*ec779b8eSAndroid Build Coastguard Worker
24*ec779b8eSAndroid Build Coastguard Worker #include "NuPlayerRenderer.h"
25*ec779b8eSAndroid Build Coastguard Worker
26*ec779b8eSAndroid Build Coastguard Worker #include <media/MediaCodecBuffer.h>
27*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/ADebug.h>
28*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/AMessage.h>
29*ec779b8eSAndroid Build Coastguard Worker
30*ec779b8eSAndroid Build Coastguard Worker #define ATRACE_TAG ATRACE_TAG_AUDIO
31*ec779b8eSAndroid Build Coastguard Worker #include <utils/Trace.h>
32*ec779b8eSAndroid Build Coastguard Worker
33*ec779b8eSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
34*ec779b8eSAndroid Build Coastguard Worker using ::android::base::StringPrintf;
35*ec779b8eSAndroid Build Coastguard Worker
36*ec779b8eSAndroid Build Coastguard Worker namespace android {
37*ec779b8eSAndroid Build Coastguard Worker
DecoderBase(const sp<AMessage> & notify)38*ec779b8eSAndroid Build Coastguard Worker NuPlayer::DecoderBase::DecoderBase(const sp<AMessage> ¬ify)
39*ec779b8eSAndroid Build Coastguard Worker : mNotify(notify),
40*ec779b8eSAndroid Build Coastguard Worker mBufferGeneration(0),
41*ec779b8eSAndroid Build Coastguard Worker mPaused(false),
42*ec779b8eSAndroid Build Coastguard Worker mStats(new AMessage),
43*ec779b8eSAndroid Build Coastguard Worker mRequestInputBuffersPending(false) {
44*ec779b8eSAndroid Build Coastguard Worker // Every decoder has its own looper because MediaCodec operations
45*ec779b8eSAndroid Build Coastguard Worker // are blocking, but NuPlayer needs asynchronous operations.
46*ec779b8eSAndroid Build Coastguard Worker mDecoderLooper = new ALooper;
47*ec779b8eSAndroid Build Coastguard Worker mDecoderLooper->setName("NPDecoder");
48*ec779b8eSAndroid Build Coastguard Worker mDecoderLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
49*ec779b8eSAndroid Build Coastguard Worker }
50*ec779b8eSAndroid Build Coastguard Worker
~DecoderBase()51*ec779b8eSAndroid Build Coastguard Worker NuPlayer::DecoderBase::~DecoderBase() {
52*ec779b8eSAndroid Build Coastguard Worker stopLooper();
53*ec779b8eSAndroid Build Coastguard Worker }
54*ec779b8eSAndroid Build Coastguard Worker
55*ec779b8eSAndroid Build Coastguard Worker static
PostAndAwaitResponse(const sp<AMessage> & msg,sp<AMessage> * response)56*ec779b8eSAndroid Build Coastguard Worker status_t PostAndAwaitResponse(
57*ec779b8eSAndroid Build Coastguard Worker const sp<AMessage> &msg, sp<AMessage> *response) {
58*ec779b8eSAndroid Build Coastguard Worker status_t err = msg->postAndAwaitResponse(response);
59*ec779b8eSAndroid Build Coastguard Worker
60*ec779b8eSAndroid Build Coastguard Worker if (err != OK) {
61*ec779b8eSAndroid Build Coastguard Worker return err;
62*ec779b8eSAndroid Build Coastguard Worker }
63*ec779b8eSAndroid Build Coastguard Worker
64*ec779b8eSAndroid Build Coastguard Worker if (!(*response)->findInt32("err", &err)) {
65*ec779b8eSAndroid Build Coastguard Worker err = OK;
66*ec779b8eSAndroid Build Coastguard Worker }
67*ec779b8eSAndroid Build Coastguard Worker
68*ec779b8eSAndroid Build Coastguard Worker return err;
69*ec779b8eSAndroid Build Coastguard Worker }
70*ec779b8eSAndroid Build Coastguard Worker
configure(const sp<AMessage> & format)71*ec779b8eSAndroid Build Coastguard Worker void NuPlayer::DecoderBase::configure(const sp<AMessage> &format) {
72*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> msg = new AMessage(kWhatConfigure, this);
73*ec779b8eSAndroid Build Coastguard Worker msg->setMessage("format", format);
74*ec779b8eSAndroid Build Coastguard Worker msg->post();
75*ec779b8eSAndroid Build Coastguard Worker }
76*ec779b8eSAndroid Build Coastguard Worker
init()77*ec779b8eSAndroid Build Coastguard Worker void NuPlayer::DecoderBase::init() {
78*ec779b8eSAndroid Build Coastguard Worker mDecoderLooper->registerHandler(this);
79*ec779b8eSAndroid Build Coastguard Worker }
80*ec779b8eSAndroid Build Coastguard Worker
stopLooper()81*ec779b8eSAndroid Build Coastguard Worker void NuPlayer::DecoderBase::stopLooper() {
82*ec779b8eSAndroid Build Coastguard Worker mDecoderLooper->unregisterHandler(id());
83*ec779b8eSAndroid Build Coastguard Worker mDecoderLooper->stop();
84*ec779b8eSAndroid Build Coastguard Worker }
85*ec779b8eSAndroid Build Coastguard Worker
setParameters(const sp<AMessage> & params)86*ec779b8eSAndroid Build Coastguard Worker void NuPlayer::DecoderBase::setParameters(const sp<AMessage> ¶ms) {
87*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
88*ec779b8eSAndroid Build Coastguard Worker msg->setMessage("params", params);
89*ec779b8eSAndroid Build Coastguard Worker msg->post();
90*ec779b8eSAndroid Build Coastguard Worker }
91*ec779b8eSAndroid Build Coastguard Worker
setRenderer(const sp<Renderer> & renderer)92*ec779b8eSAndroid Build Coastguard Worker void NuPlayer::DecoderBase::setRenderer(const sp<Renderer> &renderer) {
93*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> msg = new AMessage(kWhatSetRenderer, this);
94*ec779b8eSAndroid Build Coastguard Worker msg->setObject("renderer", renderer);
95*ec779b8eSAndroid Build Coastguard Worker msg->post();
96*ec779b8eSAndroid Build Coastguard Worker }
97*ec779b8eSAndroid Build Coastguard Worker
pause()98*ec779b8eSAndroid Build Coastguard Worker void NuPlayer::DecoderBase::pause() {
99*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> msg = new AMessage(kWhatPause, this);
100*ec779b8eSAndroid Build Coastguard Worker
101*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> response;
102*ec779b8eSAndroid Build Coastguard Worker PostAndAwaitResponse(msg, &response);
103*ec779b8eSAndroid Build Coastguard Worker }
104*ec779b8eSAndroid Build Coastguard Worker
signalFlush()105*ec779b8eSAndroid Build Coastguard Worker void NuPlayer::DecoderBase::signalFlush() {
106*ec779b8eSAndroid Build Coastguard Worker (new AMessage(kWhatFlush, this))->post();
107*ec779b8eSAndroid Build Coastguard Worker }
108*ec779b8eSAndroid Build Coastguard Worker
signalResume(bool notifyComplete)109*ec779b8eSAndroid Build Coastguard Worker void NuPlayer::DecoderBase::signalResume(bool notifyComplete) {
110*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> msg = new AMessage(kWhatResume, this);
111*ec779b8eSAndroid Build Coastguard Worker msg->setInt32("notifyComplete", notifyComplete);
112*ec779b8eSAndroid Build Coastguard Worker msg->post();
113*ec779b8eSAndroid Build Coastguard Worker }
114*ec779b8eSAndroid Build Coastguard Worker
initiateShutdown()115*ec779b8eSAndroid Build Coastguard Worker void NuPlayer::DecoderBase::initiateShutdown() {
116*ec779b8eSAndroid Build Coastguard Worker (new AMessage(kWhatShutdown, this))->post();
117*ec779b8eSAndroid Build Coastguard Worker }
118*ec779b8eSAndroid Build Coastguard Worker
onRequestInputBuffers()119*ec779b8eSAndroid Build Coastguard Worker void NuPlayer::DecoderBase::onRequestInputBuffers() {
120*ec779b8eSAndroid Build Coastguard Worker if (mRequestInputBuffersPending) {
121*ec779b8eSAndroid Build Coastguard Worker return;
122*ec779b8eSAndroid Build Coastguard Worker }
123*ec779b8eSAndroid Build Coastguard Worker
124*ec779b8eSAndroid Build Coastguard Worker // doRequestBuffers() return true if we should request more data
125*ec779b8eSAndroid Build Coastguard Worker if (doRequestBuffers()) {
126*ec779b8eSAndroid Build Coastguard Worker mRequestInputBuffersPending = true;
127*ec779b8eSAndroid Build Coastguard Worker
128*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, this);
129*ec779b8eSAndroid Build Coastguard Worker msg->post(10 * 1000LL);
130*ec779b8eSAndroid Build Coastguard Worker }
131*ec779b8eSAndroid Build Coastguard Worker }
132*ec779b8eSAndroid Build Coastguard Worker
onMessageReceived(const sp<AMessage> & msg)133*ec779b8eSAndroid Build Coastguard Worker void NuPlayer::DecoderBase::onMessageReceived(const sp<AMessage> &msg) {
134*ec779b8eSAndroid Build Coastguard Worker
135*ec779b8eSAndroid Build Coastguard Worker switch (msg->what()) {
136*ec779b8eSAndroid Build Coastguard Worker case kWhatConfigure:
137*ec779b8eSAndroid Build Coastguard Worker {
138*ec779b8eSAndroid Build Coastguard Worker ATRACE_BEGIN("NuPlayer::DecoderBase::onConfigure");
139*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> format;
140*ec779b8eSAndroid Build Coastguard Worker CHECK(msg->findMessage("format", &format));
141*ec779b8eSAndroid Build Coastguard Worker onConfigure(format);
142*ec779b8eSAndroid Build Coastguard Worker ATRACE_END();
143*ec779b8eSAndroid Build Coastguard Worker break;
144*ec779b8eSAndroid Build Coastguard Worker }
145*ec779b8eSAndroid Build Coastguard Worker
146*ec779b8eSAndroid Build Coastguard Worker case kWhatSetParameters:
147*ec779b8eSAndroid Build Coastguard Worker {
148*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> params;
149*ec779b8eSAndroid Build Coastguard Worker CHECK(msg->findMessage("params", ¶ms));
150*ec779b8eSAndroid Build Coastguard Worker onSetParameters(params);
151*ec779b8eSAndroid Build Coastguard Worker break;
152*ec779b8eSAndroid Build Coastguard Worker }
153*ec779b8eSAndroid Build Coastguard Worker
154*ec779b8eSAndroid Build Coastguard Worker case kWhatSetRenderer:
155*ec779b8eSAndroid Build Coastguard Worker {
156*ec779b8eSAndroid Build Coastguard Worker sp<RefBase> obj;
157*ec779b8eSAndroid Build Coastguard Worker CHECK(msg->findObject("renderer", &obj));
158*ec779b8eSAndroid Build Coastguard Worker onSetRenderer(static_cast<Renderer *>(obj.get()));
159*ec779b8eSAndroid Build Coastguard Worker break;
160*ec779b8eSAndroid Build Coastguard Worker }
161*ec779b8eSAndroid Build Coastguard Worker
162*ec779b8eSAndroid Build Coastguard Worker case kWhatPause:
163*ec779b8eSAndroid Build Coastguard Worker {
164*ec779b8eSAndroid Build Coastguard Worker sp<AReplyToken> replyID;
165*ec779b8eSAndroid Build Coastguard Worker CHECK(msg->senderAwaitsResponse(&replyID));
166*ec779b8eSAndroid Build Coastguard Worker
167*ec779b8eSAndroid Build Coastguard Worker mPaused = true;
168*ec779b8eSAndroid Build Coastguard Worker
169*ec779b8eSAndroid Build Coastguard Worker (new AMessage)->postReply(replyID);
170*ec779b8eSAndroid Build Coastguard Worker break;
171*ec779b8eSAndroid Build Coastguard Worker }
172*ec779b8eSAndroid Build Coastguard Worker
173*ec779b8eSAndroid Build Coastguard Worker case kWhatRequestInputBuffers:
174*ec779b8eSAndroid Build Coastguard Worker {
175*ec779b8eSAndroid Build Coastguard Worker mRequestInputBuffersPending = false;
176*ec779b8eSAndroid Build Coastguard Worker onRequestInputBuffers();
177*ec779b8eSAndroid Build Coastguard Worker break;
178*ec779b8eSAndroid Build Coastguard Worker }
179*ec779b8eSAndroid Build Coastguard Worker
180*ec779b8eSAndroid Build Coastguard Worker case kWhatFlush:
181*ec779b8eSAndroid Build Coastguard Worker {
182*ec779b8eSAndroid Build Coastguard Worker onFlush();
183*ec779b8eSAndroid Build Coastguard Worker break;
184*ec779b8eSAndroid Build Coastguard Worker }
185*ec779b8eSAndroid Build Coastguard Worker
186*ec779b8eSAndroid Build Coastguard Worker case kWhatResume:
187*ec779b8eSAndroid Build Coastguard Worker {
188*ec779b8eSAndroid Build Coastguard Worker int32_t notifyComplete;
189*ec779b8eSAndroid Build Coastguard Worker CHECK(msg->findInt32("notifyComplete", ¬ifyComplete));
190*ec779b8eSAndroid Build Coastguard Worker
191*ec779b8eSAndroid Build Coastguard Worker onResume(notifyComplete);
192*ec779b8eSAndroid Build Coastguard Worker break;
193*ec779b8eSAndroid Build Coastguard Worker }
194*ec779b8eSAndroid Build Coastguard Worker
195*ec779b8eSAndroid Build Coastguard Worker case kWhatShutdown:
196*ec779b8eSAndroid Build Coastguard Worker {
197*ec779b8eSAndroid Build Coastguard Worker onShutdown(true);
198*ec779b8eSAndroid Build Coastguard Worker break;
199*ec779b8eSAndroid Build Coastguard Worker }
200*ec779b8eSAndroid Build Coastguard Worker
201*ec779b8eSAndroid Build Coastguard Worker default:
202*ec779b8eSAndroid Build Coastguard Worker TRESPASS();
203*ec779b8eSAndroid Build Coastguard Worker break;
204*ec779b8eSAndroid Build Coastguard Worker }
205*ec779b8eSAndroid Build Coastguard Worker }
206*ec779b8eSAndroid Build Coastguard Worker
handleError(int32_t err)207*ec779b8eSAndroid Build Coastguard Worker void NuPlayer::DecoderBase::handleError(int32_t err)
208*ec779b8eSAndroid Build Coastguard Worker {
209*ec779b8eSAndroid Build Coastguard Worker // We cannot immediately release the codec due to buffers still outstanding
210*ec779b8eSAndroid Build Coastguard Worker // in the renderer. We signal to the player the error so it can shutdown/release the
211*ec779b8eSAndroid Build Coastguard Worker // decoder after flushing and increment the generation to discard unnecessary messages.
212*ec779b8eSAndroid Build Coastguard Worker
213*ec779b8eSAndroid Build Coastguard Worker ++mBufferGeneration;
214*ec779b8eSAndroid Build Coastguard Worker
215*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> notify = mNotify->dup();
216*ec779b8eSAndroid Build Coastguard Worker notify->setInt32("what", kWhatError);
217*ec779b8eSAndroid Build Coastguard Worker notify->setInt32("err", err);
218*ec779b8eSAndroid Build Coastguard Worker notify->post();
219*ec779b8eSAndroid Build Coastguard Worker }
220*ec779b8eSAndroid Build Coastguard Worker
221*ec779b8eSAndroid Build Coastguard Worker } // namespace android
222*ec779b8eSAndroid Build Coastguard Worker
223