xref: /aosp_15_r20/frameworks/av/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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> &notify)
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> &params) {
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", &params));
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", &notifyComplete));
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