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