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