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/stagefright/foundation/ADebug.h>
27 #include <media/stagefright/foundation/AMessage.h>
28
29 namespace android {
30
DecoderBase(const sp<AMessage> & notify)31 NuPlayer::DecoderBase::DecoderBase(const sp<AMessage> ¬ify)
32 : mNotify(notify),
33 mBufferGeneration(0),
34 mPaused(false),
35 mStats(new AMessage),
36 mRequestInputBuffersPending(false) {
37 // Every decoder has its own looper because MediaCodec operations
38 // are blocking, but NuPlayer needs asynchronous operations.
39 mDecoderLooper = new ALooper;
40 mDecoderLooper->setName("NPDecoder");
41 mDecoderLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
42 }
43
~DecoderBase()44 NuPlayer::DecoderBase::~DecoderBase() {
45 mDecoderLooper->unregisterHandler(id());
46 mDecoderLooper->stop();
47 }
48
49 static
PostAndAwaitResponse(const sp<AMessage> & msg,sp<AMessage> * response)50 status_t PostAndAwaitResponse(
51 const sp<AMessage> &msg, sp<AMessage> *response) {
52 status_t err = msg->postAndAwaitResponse(response);
53
54 if (err != OK) {
55 return err;
56 }
57
58 if (!(*response)->findInt32("err", &err)) {
59 err = OK;
60 }
61
62 return err;
63 }
64
configure(const sp<AMessage> & format)65 void NuPlayer::DecoderBase::configure(const sp<AMessage> &format) {
66 sp<AMessage> msg = new AMessage(kWhatConfigure, this);
67 msg->setMessage("format", format);
68 msg->post();
69 }
70
init()71 void NuPlayer::DecoderBase::init() {
72 mDecoderLooper->registerHandler(this);
73 }
74
setParameters(const sp<AMessage> & params)75 void NuPlayer::DecoderBase::setParameters(const sp<AMessage> ¶ms) {
76 sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
77 msg->setMessage("params", params);
78 msg->post();
79 }
80
setRenderer(const sp<Renderer> & renderer)81 void NuPlayer::DecoderBase::setRenderer(const sp<Renderer> &renderer) {
82 sp<AMessage> msg = new AMessage(kWhatSetRenderer, this);
83 msg->setObject("renderer", renderer);
84 msg->post();
85 }
86
pause()87 void NuPlayer::DecoderBase::pause() {
88 sp<AMessage> msg = new AMessage(kWhatPause, this);
89
90 sp<AMessage> response;
91 PostAndAwaitResponse(msg, &response);
92 }
93
getInputBuffers(Vector<sp<ABuffer>> * buffers) const94 status_t NuPlayer::DecoderBase::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
95 sp<AMessage> msg = new AMessage(kWhatGetInputBuffers, this);
96 msg->setPointer("buffers", buffers);
97
98 sp<AMessage> response;
99 return PostAndAwaitResponse(msg, &response);
100 }
101
signalFlush()102 void NuPlayer::DecoderBase::signalFlush() {
103 (new AMessage(kWhatFlush, this))->post();
104 }
105
signalResume(bool notifyComplete)106 void NuPlayer::DecoderBase::signalResume(bool notifyComplete) {
107 sp<AMessage> msg = new AMessage(kWhatResume, this);
108 msg->setInt32("notifyComplete", notifyComplete);
109 msg->post();
110 }
111
initiateShutdown()112 void NuPlayer::DecoderBase::initiateShutdown() {
113 (new AMessage(kWhatShutdown, this))->post();
114 }
115
onRequestInputBuffers()116 void NuPlayer::DecoderBase::onRequestInputBuffers() {
117 if (mRequestInputBuffersPending) {
118 return;
119 }
120
121 // doRequestBuffers() return true if we should request more data
122 if (doRequestBuffers()) {
123 mRequestInputBuffersPending = true;
124
125 sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, this);
126 msg->post(10 * 1000ll);
127 }
128 }
129
onMessageReceived(const sp<AMessage> & msg)130 void NuPlayer::DecoderBase::onMessageReceived(const sp<AMessage> &msg) {
131
132 switch (msg->what()) {
133 case kWhatConfigure:
134 {
135 sp<AMessage> format;
136 CHECK(msg->findMessage("format", &format));
137 onConfigure(format);
138 break;
139 }
140
141 case kWhatSetParameters:
142 {
143 sp<AMessage> params;
144 CHECK(msg->findMessage("params", ¶ms));
145 onSetParameters(params);
146 break;
147 }
148
149 case kWhatSetRenderer:
150 {
151 sp<RefBase> obj;
152 CHECK(msg->findObject("renderer", &obj));
153 onSetRenderer(static_cast<Renderer *>(obj.get()));
154 break;
155 }
156
157 case kWhatPause:
158 {
159 sp<AReplyToken> replyID;
160 CHECK(msg->senderAwaitsResponse(&replyID));
161
162 mPaused = true;
163
164 (new AMessage)->postReply(replyID);
165 break;
166 }
167
168 case kWhatGetInputBuffers:
169 {
170 sp<AReplyToken> replyID;
171 CHECK(msg->senderAwaitsResponse(&replyID));
172
173 Vector<sp<ABuffer> > *dstBuffers;
174 CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
175
176 onGetInputBuffers(dstBuffers);
177
178 (new AMessage)->postReply(replyID);
179 break;
180 }
181
182 case kWhatRequestInputBuffers:
183 {
184 mRequestInputBuffersPending = false;
185 onRequestInputBuffers();
186 break;
187 }
188
189 case kWhatFlush:
190 {
191 onFlush();
192 break;
193 }
194
195 case kWhatResume:
196 {
197 int32_t notifyComplete;
198 CHECK(msg->findInt32("notifyComplete", ¬ifyComplete));
199
200 onResume(notifyComplete);
201 break;
202 }
203
204 case kWhatShutdown:
205 {
206 onShutdown(true);
207 break;
208 }
209
210 default:
211 TRESPASS();
212 break;
213 }
214 }
215
handleError(int32_t err)216 void NuPlayer::DecoderBase::handleError(int32_t err)
217 {
218 // We cannot immediately release the codec due to buffers still outstanding
219 // in the renderer. We signal to the player the error so it can shutdown/release the
220 // decoder after flushing and increment the generation to discard unnecessary messages.
221
222 ++mBufferGeneration;
223
224 sp<AMessage> notify = mNotify->dup();
225 notify->setInt32("what", kWhatError);
226 notify->setInt32("err", err);
227 notify->post();
228 }
229
230 } // namespace android
231
232