blob: 9d509bfbb9784b44fba658831d488fce8b723d54 [file] [log] [blame]
Chong Zhang7137ec72014-11-12 16:41:05 -08001/*
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
29namespace android {
30
Andy Hung202bce12014-12-03 11:47:36 -080031NuPlayer::DecoderBase::DecoderBase(const sp<AMessage> &notify)
32 : mNotify(notify),
33 mBufferGeneration(0),
34 mRequestInputBuffersPending(false) {
Chong Zhang7137ec72014-11-12 16:41:05 -080035 // Every decoder has its own looper because MediaCodec operations
36 // are blocking, but NuPlayer needs asynchronous operations.
37 mDecoderLooper = new ALooper;
38 mDecoderLooper->setName("NPDecoder");
39 mDecoderLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
40}
41
42NuPlayer::DecoderBase::~DecoderBase() {
43 mDecoderLooper->unregisterHandler(id());
44 mDecoderLooper->stop();
45}
46
47static
48status_t PostAndAwaitResponse(
49 const sp<AMessage> &msg, sp<AMessage> *response) {
50 status_t err = msg->postAndAwaitResponse(response);
51
52 if (err != OK) {
53 return err;
54 }
55
56 if (!(*response)->findInt32("err", &err)) {
57 err = OK;
58 }
59
60 return err;
61}
62
63void NuPlayer::DecoderBase::configure(const sp<AMessage> &format) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -080064 sp<AMessage> msg = new AMessage(kWhatConfigure, this);
Chong Zhang7137ec72014-11-12 16:41:05 -080065 msg->setMessage("format", format);
66 msg->post();
67}
68
69void NuPlayer::DecoderBase::init() {
70 mDecoderLooper->registerHandler(this);
71}
72
Ronghua Wu8db88132015-04-22 13:51:35 -070073void NuPlayer::DecoderBase::setParameters(const sp<AMessage> &params) {
74 sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
75 msg->setMessage("params", params);
76 msg->post();
77}
78
Chong Zhang7137ec72014-11-12 16:41:05 -080079void NuPlayer::DecoderBase::setRenderer(const sp<Renderer> &renderer) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -080080 sp<AMessage> msg = new AMessage(kWhatSetRenderer, this);
Chong Zhang7137ec72014-11-12 16:41:05 -080081 msg->setObject("renderer", renderer);
82 msg->post();
83}
84
85status_t NuPlayer::DecoderBase::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
Lajos Molnar1d15ab52015-03-04 16:46:34 -080086 sp<AMessage> msg = new AMessage(kWhatGetInputBuffers, this);
Chong Zhang7137ec72014-11-12 16:41:05 -080087 msg->setPointer("buffers", buffers);
88
89 sp<AMessage> response;
90 return PostAndAwaitResponse(msg, &response);
91}
92
93void NuPlayer::DecoderBase::signalFlush() {
Lajos Molnar1d15ab52015-03-04 16:46:34 -080094 (new AMessage(kWhatFlush, this))->post();
Chong Zhang7137ec72014-11-12 16:41:05 -080095}
96
Chong Zhangf8d71772014-11-26 15:08:34 -080097void NuPlayer::DecoderBase::signalResume(bool notifyComplete) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -080098 sp<AMessage> msg = new AMessage(kWhatResume, this);
Chong Zhangf8d71772014-11-26 15:08:34 -080099 msg->setInt32("notifyComplete", notifyComplete);
100 msg->post();
Chong Zhang7137ec72014-11-12 16:41:05 -0800101}
102
103void NuPlayer::DecoderBase::initiateShutdown() {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800104 (new AMessage(kWhatShutdown, this))->post();
Chong Zhang7137ec72014-11-12 16:41:05 -0800105}
106
107void NuPlayer::DecoderBase::onRequestInputBuffers() {
108 if (mRequestInputBuffersPending) {
109 return;
110 }
111
Chong Zhang3b032b32015-04-17 15:49:06 -0700112 // doRequestBuffers() return true if we should request more data
113 if (doRequestBuffers()) {
114 mRequestInputBuffersPending = true;
Chong Zhang7137ec72014-11-12 16:41:05 -0800115
Chong Zhang3b032b32015-04-17 15:49:06 -0700116 sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, this);
117 msg->post(10 * 1000ll);
Chong Zhang7137ec72014-11-12 16:41:05 -0800118 }
Chong Zhang7137ec72014-11-12 16:41:05 -0800119}
120
121void NuPlayer::DecoderBase::onMessageReceived(const sp<AMessage> &msg) {
122
123 switch (msg->what()) {
124 case kWhatConfigure:
125 {
126 sp<AMessage> format;
127 CHECK(msg->findMessage("format", &format));
128 onConfigure(format);
129 break;
130 }
131
Ronghua Wu8db88132015-04-22 13:51:35 -0700132 case kWhatSetParameters:
133 {
134 sp<AMessage> params;
135 CHECK(msg->findMessage("params", &params));
136 onSetParameters(params);
137 break;
138 }
139
Chong Zhang7137ec72014-11-12 16:41:05 -0800140 case kWhatSetRenderer:
141 {
142 sp<RefBase> obj;
143 CHECK(msg->findObject("renderer", &obj));
144 onSetRenderer(static_cast<Renderer *>(obj.get()));
145 break;
146 }
147
148 case kWhatGetInputBuffers:
149 {
Lajos Molnar3f274362015-03-05 14:35:41 -0800150 sp<AReplyToken> replyID;
Chong Zhang7137ec72014-11-12 16:41:05 -0800151 CHECK(msg->senderAwaitsResponse(&replyID));
152
153 Vector<sp<ABuffer> > *dstBuffers;
154 CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
155
156 onGetInputBuffers(dstBuffers);
157
158 (new AMessage)->postReply(replyID);
159 break;
160 }
161
162 case kWhatRequestInputBuffers:
163 {
164 mRequestInputBuffersPending = false;
165 onRequestInputBuffers();
166 break;
167 }
168
169 case kWhatFlush:
170 {
Chong Zhang66704af2015-03-03 19:32:35 -0800171 onFlush();
Chong Zhang7137ec72014-11-12 16:41:05 -0800172 break;
173 }
174
175 case kWhatResume:
176 {
Chong Zhangf8d71772014-11-26 15:08:34 -0800177 int32_t notifyComplete;
178 CHECK(msg->findInt32("notifyComplete", &notifyComplete));
179
180 onResume(notifyComplete);
Chong Zhang7137ec72014-11-12 16:41:05 -0800181 break;
182 }
183
184 case kWhatShutdown:
185 {
186 onShutdown(true);
187 break;
188 }
189
190 default:
191 TRESPASS();
192 break;
193 }
194}
195
Andy Hung202bce12014-12-03 11:47:36 -0800196void NuPlayer::DecoderBase::handleError(int32_t err)
197{
198 // We cannot immediately release the codec due to buffers still outstanding
199 // in the renderer. We signal to the player the error so it can shutdown/release the
200 // decoder after flushing and increment the generation to discard unnecessary messages.
201
202 ++mBufferGeneration;
203
204 sp<AMessage> notify = mNotify->dup();
205 notify->setInt32("what", kWhatError);
206 notify->setInt32("err", err);
207 notify->post();
208}
209
Chong Zhang7137ec72014-11-12 16:41:05 -0800210} // namespace android
211