blob: 9c007ae4888292db7b8ec31ff840e1220de7c009 [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
Wonsik Kim7e34bf52016-08-23 00:09:18 +090026#include <media/MediaCodecBuffer.h>
Chong Zhang7137ec72014-11-12 16:41:05 -080027#include <media/stagefright/foundation/ADebug.h>
28#include <media/stagefright/foundation/AMessage.h>
29
30namespace android {
31
Andy Hung202bce12014-12-03 11:47:36 -080032NuPlayer::DecoderBase::DecoderBase(const sp<AMessage> &notify)
33 : mNotify(notify),
34 mBufferGeneration(0),
Wei Jia3bc66702015-11-18 15:45:06 -080035 mPaused(false),
Praveen Chavane1e5d7a2015-05-19 19:09:48 -070036 mStats(new AMessage),
Andy Hung202bce12014-12-03 11:47:36 -080037 mRequestInputBuffersPending(false) {
Chong Zhang7137ec72014-11-12 16:41:05 -080038 // Every decoder has its own looper because MediaCodec operations
39 // are blocking, but NuPlayer needs asynchronous operations.
40 mDecoderLooper = new ALooper;
41 mDecoderLooper->setName("NPDecoder");
42 mDecoderLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
43}
44
45NuPlayer::DecoderBase::~DecoderBase() {
46 mDecoderLooper->unregisterHandler(id());
47 mDecoderLooper->stop();
48}
49
50static
51status_t PostAndAwaitResponse(
52 const sp<AMessage> &msg, sp<AMessage> *response) {
53 status_t err = msg->postAndAwaitResponse(response);
54
55 if (err != OK) {
56 return err;
57 }
58
59 if (!(*response)->findInt32("err", &err)) {
60 err = OK;
61 }
62
63 return err;
64}
65
66void NuPlayer::DecoderBase::configure(const sp<AMessage> &format) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -080067 sp<AMessage> msg = new AMessage(kWhatConfigure, this);
Chong Zhang7137ec72014-11-12 16:41:05 -080068 msg->setMessage("format", format);
69 msg->post();
70}
71
72void NuPlayer::DecoderBase::init() {
73 mDecoderLooper->registerHandler(this);
74}
75
Ronghua Wu8db88132015-04-22 13:51:35 -070076void NuPlayer::DecoderBase::setParameters(const sp<AMessage> &params) {
77 sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
78 msg->setMessage("params", params);
79 msg->post();
80}
81
Chong Zhang7137ec72014-11-12 16:41:05 -080082void NuPlayer::DecoderBase::setRenderer(const sp<Renderer> &renderer) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -080083 sp<AMessage> msg = new AMessage(kWhatSetRenderer, this);
Chong Zhang7137ec72014-11-12 16:41:05 -080084 msg->setObject("renderer", renderer);
85 msg->post();
86}
87
Wei Jia3bc66702015-11-18 15:45:06 -080088void NuPlayer::DecoderBase::pause() {
89 sp<AMessage> msg = new AMessage(kWhatPause, this);
90
91 sp<AMessage> response;
92 PostAndAwaitResponse(msg, &response);
93}
94
Wonsik Kim7e34bf52016-08-23 00:09:18 +090095status_t NuPlayer::DecoderBase::getInputBuffers(Vector<sp<MediaCodecBuffer> > *buffers) const {
Lajos Molnar1d15ab52015-03-04 16:46:34 -080096 sp<AMessage> msg = new AMessage(kWhatGetInputBuffers, this);
Chong Zhang7137ec72014-11-12 16:41:05 -080097 msg->setPointer("buffers", buffers);
98
99 sp<AMessage> response;
100 return PostAndAwaitResponse(msg, &response);
101}
102
103void NuPlayer::DecoderBase::signalFlush() {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800104 (new AMessage(kWhatFlush, this))->post();
Chong Zhang7137ec72014-11-12 16:41:05 -0800105}
106
Chong Zhangf8d71772014-11-26 15:08:34 -0800107void NuPlayer::DecoderBase::signalResume(bool notifyComplete) {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800108 sp<AMessage> msg = new AMessage(kWhatResume, this);
Chong Zhangf8d71772014-11-26 15:08:34 -0800109 msg->setInt32("notifyComplete", notifyComplete);
110 msg->post();
Chong Zhang7137ec72014-11-12 16:41:05 -0800111}
112
113void NuPlayer::DecoderBase::initiateShutdown() {
Lajos Molnar1d15ab52015-03-04 16:46:34 -0800114 (new AMessage(kWhatShutdown, this))->post();
Chong Zhang7137ec72014-11-12 16:41:05 -0800115}
116
117void NuPlayer::DecoderBase::onRequestInputBuffers() {
118 if (mRequestInputBuffersPending) {
119 return;
120 }
121
Chong Zhang3b032b32015-04-17 15:49:06 -0700122 // doRequestBuffers() return true if we should request more data
123 if (doRequestBuffers()) {
124 mRequestInputBuffersPending = true;
Chong Zhang7137ec72014-11-12 16:41:05 -0800125
Chong Zhang3b032b32015-04-17 15:49:06 -0700126 sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, this);
127 msg->post(10 * 1000ll);
Chong Zhang7137ec72014-11-12 16:41:05 -0800128 }
Chong Zhang7137ec72014-11-12 16:41:05 -0800129}
130
131void NuPlayer::DecoderBase::onMessageReceived(const sp<AMessage> &msg) {
132
133 switch (msg->what()) {
134 case kWhatConfigure:
135 {
136 sp<AMessage> format;
137 CHECK(msg->findMessage("format", &format));
138 onConfigure(format);
139 break;
140 }
141
Ronghua Wu8db88132015-04-22 13:51:35 -0700142 case kWhatSetParameters:
143 {
144 sp<AMessage> params;
145 CHECK(msg->findMessage("params", &params));
146 onSetParameters(params);
147 break;
148 }
149
Chong Zhang7137ec72014-11-12 16:41:05 -0800150 case kWhatSetRenderer:
151 {
152 sp<RefBase> obj;
153 CHECK(msg->findObject("renderer", &obj));
154 onSetRenderer(static_cast<Renderer *>(obj.get()));
155 break;
156 }
157
Wei Jia3bc66702015-11-18 15:45:06 -0800158 case kWhatPause:
159 {
160 sp<AReplyToken> replyID;
161 CHECK(msg->senderAwaitsResponse(&replyID));
162
163 mPaused = true;
164
165 (new AMessage)->postReply(replyID);
166 break;
167 }
168
Chong Zhang7137ec72014-11-12 16:41:05 -0800169 case kWhatGetInputBuffers:
170 {
Lajos Molnar3f274362015-03-05 14:35:41 -0800171 sp<AReplyToken> replyID;
Chong Zhang7137ec72014-11-12 16:41:05 -0800172 CHECK(msg->senderAwaitsResponse(&replyID));
173
Wonsik Kim7e34bf52016-08-23 00:09:18 +0900174 Vector<sp<MediaCodecBuffer> > *dstBuffers;
Chong Zhang7137ec72014-11-12 16:41:05 -0800175 CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
176
177 onGetInputBuffers(dstBuffers);
178
179 (new AMessage)->postReply(replyID);
180 break;
181 }
182
183 case kWhatRequestInputBuffers:
184 {
185 mRequestInputBuffersPending = false;
186 onRequestInputBuffers();
187 break;
188 }
189
190 case kWhatFlush:
191 {
Chong Zhang66704af2015-03-03 19:32:35 -0800192 onFlush();
Chong Zhang7137ec72014-11-12 16:41:05 -0800193 break;
194 }
195
196 case kWhatResume:
197 {
Chong Zhangf8d71772014-11-26 15:08:34 -0800198 int32_t notifyComplete;
199 CHECK(msg->findInt32("notifyComplete", &notifyComplete));
200
201 onResume(notifyComplete);
Chong Zhang7137ec72014-11-12 16:41:05 -0800202 break;
203 }
204
205 case kWhatShutdown:
206 {
207 onShutdown(true);
208 break;
209 }
210
211 default:
212 TRESPASS();
213 break;
214 }
215}
216
Andy Hung202bce12014-12-03 11:47:36 -0800217void NuPlayer::DecoderBase::handleError(int32_t err)
218{
219 // We cannot immediately release the codec due to buffers still outstanding
220 // in the renderer. We signal to the player the error so it can shutdown/release the
221 // decoder after flushing and increment the generation to discard unnecessary messages.
222
223 ++mBufferGeneration;
224
225 sp<AMessage> notify = mNotify->dup();
226 notify->setInt32("what", kWhatError);
227 notify->setInt32("err", err);
228 notify->post();
229}
230
Chong Zhang7137ec72014-11-12 16:41:05 -0800231} // namespace android
232