blob: f7aacdd7513962318ac304d116aaba327ad411c9 [file] [log] [blame]
Wei Jiabc2fb722014-07-08 16:37:57 -07001/*
2 * Copyright (C) 2014 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 "NuPlayerDecoderPassThrough"
19#include <utils/Log.h>
20#include <inttypes.h>
21
22#include "NuPlayerDecoderPassThrough.h"
23
24#include <media/ICrypto.h>
25#include <media/stagefright/foundation/ABuffer.h>
26#include <media/stagefright/foundation/ADebug.h>
27#include <media/stagefright/foundation/AMessage.h>
28#include <media/stagefright/MediaDefs.h>
29#include <media/stagefright/MediaErrors.h>
30
31namespace android {
32
Phil Burkc5cc2e22014-09-09 20:08:39 -070033static const size_t kMaxCachedBytes = 200000;
34// The buffers will contain a bit less than kAggregateBufferSizeBytes.
35// So we can start off with just enough buffers to keep the cache full.
36static const size_t kMaxPendingBuffers = 1 + (kMaxCachedBytes / NuPlayer::kAggregateBufferSizeBytes);
Wei Jiabc2fb722014-07-08 16:37:57 -070037
38NuPlayer::DecoderPassThrough::DecoderPassThrough(
39 const sp<AMessage> &notify)
40 : Decoder(notify),
41 mNotify(notify),
42 mBufferGeneration(0),
43 mReachedEOS(true),
Phil Burkc5cc2e22014-09-09 20:08:39 -070044 mPendingBuffersToFill(0),
45 mPendingBuffersToDrain(0),
Chong Zhangde01afb2014-08-13 13:48:10 -070046 mCachedBytes(0),
Wei Jiabc2fb722014-07-08 16:37:57 -070047 mComponentName("pass through decoder") {
48 mDecoderLooper = new ALooper;
49 mDecoderLooper->setName("NuPlayerDecoderPassThrough");
50 mDecoderLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
51}
52
53NuPlayer::DecoderPassThrough::~DecoderPassThrough() {
54}
55
56void NuPlayer::DecoderPassThrough::configure(const sp<AMessage> &format) {
57 sp<AMessage> msg = new AMessage(kWhatConfigure, id());
58 msg->setMessage("format", format);
59 msg->post();
60}
61
62void NuPlayer::DecoderPassThrough::init() {
63 mDecoderLooper->registerHandler(this);
64}
65
66void NuPlayer::DecoderPassThrough::signalFlush() {
67 (new AMessage(kWhatFlush, id()))->post();
68}
69
70void NuPlayer::DecoderPassThrough::signalResume() {
71 (new AMessage(kWhatResume, id()))->post();
72}
73
74void NuPlayer::DecoderPassThrough::initiateShutdown() {
75 (new AMessage(kWhatShutdown, id()))->post();
76}
77
78bool NuPlayer::DecoderPassThrough::supportsSeamlessFormatChange(
79 const sp<AMessage> & /* targetFormat */) const {
80 return true;
81}
82
83void NuPlayer::DecoderPassThrough::onConfigure(const sp<AMessage> &format) {
84 ALOGV("[%s] onConfigure", mComponentName.c_str());
Chong Zhangde01afb2014-08-13 13:48:10 -070085 mCachedBytes = 0;
Phil Burkc5cc2e22014-09-09 20:08:39 -070086 mPendingBuffersToFill = 0;
87 mPendingBuffersToDrain = 0;
Wei Jiabc2fb722014-07-08 16:37:57 -070088 mReachedEOS = false;
89 ++mBufferGeneration;
90
Phil Burkc5cc2e22014-09-09 20:08:39 -070091 requestMaxBuffers();
Wei Jiabc2fb722014-07-08 16:37:57 -070092
93 sp<AMessage> notify = mNotify->dup();
94 notify->setInt32("what", kWhatOutputFormatChanged);
95 notify->setMessage("format", format);
96 notify->post();
97}
98
99bool NuPlayer::DecoderPassThrough::isStaleReply(const sp<AMessage> &msg) {
100 int32_t generation;
101 CHECK(msg->findInt32("generation", &generation));
102 return generation != mBufferGeneration;
103}
104
Phil Burkc5cc2e22014-09-09 20:08:39 -0700105bool NuPlayer::DecoderPassThrough::requestABuffer() {
106 if (mCachedBytes >= kMaxCachedBytes) {
107 ALOGV("[%s] mCachedBytes = %zu",
108 mComponentName.c_str(), mCachedBytes);
109 return false;
110 }
111 if (mReachedEOS) {
112 ALOGV("[%s] reached EOS", mComponentName.c_str());
113 return false;
Wei Jiabc2fb722014-07-08 16:37:57 -0700114 }
115
116 sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, id());
117 reply->setInt32("generation", mBufferGeneration);
118
119 sp<AMessage> notify = mNotify->dup();
120 notify->setInt32("what", kWhatFillThisBuffer);
121 notify->setMessage("reply", reply);
122 notify->post();
Phil Burkc5cc2e22014-09-09 20:08:39 -0700123 mPendingBuffersToFill++;
124 ALOGV("requestABuffer: #ToFill = %zu, #ToDrain = %zu", mPendingBuffersToFill,
125 mPendingBuffersToDrain);
Wei Jiabc2fb722014-07-08 16:37:57 -0700126
Phil Burkc5cc2e22014-09-09 20:08:39 -0700127 return true;
Wei Jiabc2fb722014-07-08 16:37:57 -0700128}
129
130void android::NuPlayer::DecoderPassThrough::onInputBufferFilled(
131 const sp<AMessage> &msg) {
Phil Burkc5cc2e22014-09-09 20:08:39 -0700132 --mPendingBuffersToFill;
Wei Jiabc2fb722014-07-08 16:37:57 -0700133 if (mReachedEOS) {
134 return;
135 }
136
137 sp<ABuffer> buffer;
138 msg->findBuffer("buffer", &buffer);
139 if (buffer == NULL) {
140 mReachedEOS = true;
141
142 sp<AMessage> notify = mNotify->dup();
143 notify->setInt32("what", kWhatEOS);
144 notify->setInt32("err", ERROR_END_OF_STREAM);
145 notify->post();
146 return;
147 }
148
Chong Zhangde01afb2014-08-13 13:48:10 -0700149 mCachedBytes += buffer->size();
150
Wei Jiabc2fb722014-07-08 16:37:57 -0700151 sp<AMessage> reply = new AMessage(kWhatBufferConsumed, id());
152 reply->setInt32("generation", mBufferGeneration);
Chong Zhangde01afb2014-08-13 13:48:10 -0700153 reply->setInt32("size", buffer->size());
Wei Jiabc2fb722014-07-08 16:37:57 -0700154
155 sp<AMessage> notify = mNotify->dup();
156 notify->setInt32("what", kWhatDrainThisBuffer);
157 notify->setBuffer("buffer", buffer);
158 notify->setMessage("reply", reply);
159 notify->post();
Phil Burkc5cc2e22014-09-09 20:08:39 -0700160 ++mPendingBuffersToDrain;
161 ALOGV("onInputBufferFilled: #ToFill = %zu, #ToDrain = %zu, cachedBytes = %zu",
162 mPendingBuffersToFill, mPendingBuffersToDrain, mCachedBytes);
Wei Jiabc2fb722014-07-08 16:37:57 -0700163}
164
Chong Zhangde01afb2014-08-13 13:48:10 -0700165void NuPlayer::DecoderPassThrough::onBufferConsumed(int32_t size) {
Phil Burkc5cc2e22014-09-09 20:08:39 -0700166 --mPendingBuffersToDrain;
Chong Zhangde01afb2014-08-13 13:48:10 -0700167 mCachedBytes -= size;
Phil Burkc5cc2e22014-09-09 20:08:39 -0700168 ALOGV("onBufferConsumed: #ToFill = %zu, #ToDrain = %zu, cachedBytes = %zu",
169 mPendingBuffersToFill, mPendingBuffersToDrain, mCachedBytes);
Lajos Molnar178e5062014-09-09 20:08:39 -0700170 requestABuffer();
Wei Jiabc2fb722014-07-08 16:37:57 -0700171}
172
173void NuPlayer::DecoderPassThrough::onFlush() {
174 ++mBufferGeneration;
175
176 sp<AMessage> notify = mNotify->dup();
177 notify->setInt32("what", kWhatFlushCompleted);
178 notify->post();
Phil Burkc5cc2e22014-09-09 20:08:39 -0700179 mPendingBuffersToFill = 0;
180 mPendingBuffersToDrain = 0;
Chong Zhangde01afb2014-08-13 13:48:10 -0700181 mCachedBytes = 0;
Wei Jiabc2fb722014-07-08 16:37:57 -0700182 mReachedEOS = false;
183}
184
Phil Burkc5cc2e22014-09-09 20:08:39 -0700185void NuPlayer::DecoderPassThrough::requestMaxBuffers() {
186 for (size_t i = 0; i < kMaxPendingBuffers; i++) {
187 if (!requestABuffer()) {
188 break;
189 }
190 }
191}
192
Wei Jiabc2fb722014-07-08 16:37:57 -0700193void NuPlayer::DecoderPassThrough::onShutdown() {
194 ++mBufferGeneration;
195
196 sp<AMessage> notify = mNotify->dup();
197 notify->setInt32("what", kWhatShutdownCompleted);
198 notify->post();
199 mReachedEOS = true;
200}
201
202void NuPlayer::DecoderPassThrough::onMessageReceived(const sp<AMessage> &msg) {
203 ALOGV("[%s] onMessage: %s", mComponentName.c_str(),
204 msg->debugString().c_str());
205
206 switch (msg->what()) {
207 case kWhatConfigure:
208 {
209 sp<AMessage> format;
210 CHECK(msg->findMessage("format", &format));
211 onConfigure(format);
212 break;
213 }
214
215 case kWhatRequestABuffer:
216 {
217 if (!isStaleReply(msg)) {
218 requestABuffer();
219 }
220
221 break;
222 }
223
224 case kWhatInputBufferFilled:
225 {
226 if (!isStaleReply(msg)) {
227 onInputBufferFilled(msg);
228 }
229 break;
230 }
231
232 case kWhatBufferConsumed:
233 {
234 if (!isStaleReply(msg)) {
Chong Zhangde01afb2014-08-13 13:48:10 -0700235 int32_t size;
236 CHECK(msg->findInt32("size", &size));
237 onBufferConsumed(size);
Wei Jiabc2fb722014-07-08 16:37:57 -0700238 }
239 break;
240 }
241
242 case kWhatFlush:
243 {
244 onFlush();
245 break;
246 }
247
248 case kWhatResume:
249 {
Phil Burkc5cc2e22014-09-09 20:08:39 -0700250 requestMaxBuffers();
Wei Jiabc2fb722014-07-08 16:37:57 -0700251 break;
252 }
253
254 case kWhatShutdown:
255 {
256 onShutdown();
257 break;
258 }
259
260 default:
261 TRESPASS();
262 break;
263 }
264}
265
266} // namespace android