blob: ab7906abba558e0d95dbbc5f87c0a9f17a1b6362 [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
33static const int kMaxPendingBuffers = 10;
Chong Zhangde01afb2014-08-13 13:48:10 -070034static const int kMaxCachedBytes = 200000;
Wei Jiabc2fb722014-07-08 16:37:57 -070035
36NuPlayer::DecoderPassThrough::DecoderPassThrough(
37 const sp<AMessage> &notify)
38 : Decoder(notify),
39 mNotify(notify),
40 mBufferGeneration(0),
41 mReachedEOS(true),
42 mPendingBuffers(0),
Chong Zhangde01afb2014-08-13 13:48:10 -070043 mCachedBytes(0),
Wei Jiabc2fb722014-07-08 16:37:57 -070044 mComponentName("pass through decoder") {
45 mDecoderLooper = new ALooper;
46 mDecoderLooper->setName("NuPlayerDecoderPassThrough");
47 mDecoderLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
48}
49
50NuPlayer::DecoderPassThrough::~DecoderPassThrough() {
51}
52
53void NuPlayer::DecoderPassThrough::configure(const sp<AMessage> &format) {
54 sp<AMessage> msg = new AMessage(kWhatConfigure, id());
55 msg->setMessage("format", format);
56 msg->post();
57}
58
59void NuPlayer::DecoderPassThrough::init() {
60 mDecoderLooper->registerHandler(this);
61}
62
63void NuPlayer::DecoderPassThrough::signalFlush() {
64 (new AMessage(kWhatFlush, id()))->post();
65}
66
67void NuPlayer::DecoderPassThrough::signalResume() {
68 (new AMessage(kWhatResume, id()))->post();
69}
70
71void NuPlayer::DecoderPassThrough::initiateShutdown() {
72 (new AMessage(kWhatShutdown, id()))->post();
73}
74
75bool NuPlayer::DecoderPassThrough::supportsSeamlessFormatChange(
76 const sp<AMessage> & /* targetFormat */) const {
77 return true;
78}
79
80void NuPlayer::DecoderPassThrough::onConfigure(const sp<AMessage> &format) {
81 ALOGV("[%s] onConfigure", mComponentName.c_str());
82 mPendingBuffers = 0;
Chong Zhangde01afb2014-08-13 13:48:10 -070083 mCachedBytes = 0;
Wei Jiabc2fb722014-07-08 16:37:57 -070084 mReachedEOS = false;
85 ++mBufferGeneration;
86
87 requestABuffer();
88
89 sp<AMessage> notify = mNotify->dup();
90 notify->setInt32("what", kWhatOutputFormatChanged);
91 notify->setMessage("format", format);
92 notify->post();
93}
94
95bool NuPlayer::DecoderPassThrough::isStaleReply(const sp<AMessage> &msg) {
96 int32_t generation;
97 CHECK(msg->findInt32("generation", &generation));
98 return generation != mBufferGeneration;
99}
100
101void NuPlayer::DecoderPassThrough::requestABuffer() {
Chong Zhangde01afb2014-08-13 13:48:10 -0700102 if (mCachedBytes >= kMaxCachedBytes || mReachedEOS) {
Wei Jiabc2fb722014-07-08 16:37:57 -0700103 ALOGV("[%s] mReachedEOS=%d, max pending buffers(%d:%d)",
104 mComponentName.c_str(), (mReachedEOS ? 1 : 0),
105 mPendingBuffers, kMaxPendingBuffers);
106 return;
107 }
108
109 sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, id());
110 reply->setInt32("generation", mBufferGeneration);
111
112 sp<AMessage> notify = mNotify->dup();
113 notify->setInt32("what", kWhatFillThisBuffer);
114 notify->setMessage("reply", reply);
115 notify->post();
116 mPendingBuffers++;
117
Lajos Molnar178e5062014-09-09 20:08:39 -0700118 // pending buffers will already result in requestABuffer
119 if (mPendingBuffers < kMaxPendingBuffers) {
120 sp<AMessage> message = new AMessage(kWhatRequestABuffer, id());
121 message->setInt32("generation", mBufferGeneration);
122 message->post();
123 }
Wei Jiabc2fb722014-07-08 16:37:57 -0700124 return;
125}
126
127void android::NuPlayer::DecoderPassThrough::onInputBufferFilled(
128 const sp<AMessage> &msg) {
129 if (mReachedEOS) {
130 return;
131 }
132
133 sp<ABuffer> buffer;
134 msg->findBuffer("buffer", &buffer);
135 if (buffer == NULL) {
136 mReachedEOS = true;
137
138 sp<AMessage> notify = mNotify->dup();
139 notify->setInt32("what", kWhatEOS);
140 notify->setInt32("err", ERROR_END_OF_STREAM);
141 notify->post();
142 return;
143 }
144
Chong Zhangde01afb2014-08-13 13:48:10 -0700145 mCachedBytes += buffer->size();
146
Wei Jiabc2fb722014-07-08 16:37:57 -0700147 sp<AMessage> reply = new AMessage(kWhatBufferConsumed, id());
148 reply->setInt32("generation", mBufferGeneration);
Chong Zhangde01afb2014-08-13 13:48:10 -0700149 reply->setInt32("size", buffer->size());
Wei Jiabc2fb722014-07-08 16:37:57 -0700150
151 sp<AMessage> notify = mNotify->dup();
152 notify->setInt32("what", kWhatDrainThisBuffer);
153 notify->setBuffer("buffer", buffer);
154 notify->setMessage("reply", reply);
155 notify->post();
156}
157
Chong Zhangde01afb2014-08-13 13:48:10 -0700158void NuPlayer::DecoderPassThrough::onBufferConsumed(int32_t size) {
Wei Jiabc2fb722014-07-08 16:37:57 -0700159 mPendingBuffers--;
Chong Zhangde01afb2014-08-13 13:48:10 -0700160 mCachedBytes -= size;
Lajos Molnar178e5062014-09-09 20:08:39 -0700161 requestABuffer();
Wei Jiabc2fb722014-07-08 16:37:57 -0700162}
163
164void NuPlayer::DecoderPassThrough::onFlush() {
165 ++mBufferGeneration;
166
167 sp<AMessage> notify = mNotify->dup();
168 notify->setInt32("what", kWhatFlushCompleted);
169 notify->post();
170 mPendingBuffers = 0;
Chong Zhangde01afb2014-08-13 13:48:10 -0700171 mCachedBytes = 0;
Wei Jiabc2fb722014-07-08 16:37:57 -0700172 mReachedEOS = false;
173}
174
175void NuPlayer::DecoderPassThrough::onShutdown() {
176 ++mBufferGeneration;
177
178 sp<AMessage> notify = mNotify->dup();
179 notify->setInt32("what", kWhatShutdownCompleted);
180 notify->post();
181 mReachedEOS = true;
182}
183
184void NuPlayer::DecoderPassThrough::onMessageReceived(const sp<AMessage> &msg) {
185 ALOGV("[%s] onMessage: %s", mComponentName.c_str(),
186 msg->debugString().c_str());
187
188 switch (msg->what()) {
189 case kWhatConfigure:
190 {
191 sp<AMessage> format;
192 CHECK(msg->findMessage("format", &format));
193 onConfigure(format);
194 break;
195 }
196
197 case kWhatRequestABuffer:
198 {
199 if (!isStaleReply(msg)) {
200 requestABuffer();
201 }
202
203 break;
204 }
205
206 case kWhatInputBufferFilled:
207 {
208 if (!isStaleReply(msg)) {
209 onInputBufferFilled(msg);
210 }
211 break;
212 }
213
214 case kWhatBufferConsumed:
215 {
216 if (!isStaleReply(msg)) {
Chong Zhangde01afb2014-08-13 13:48:10 -0700217 int32_t size;
218 CHECK(msg->findInt32("size", &size));
219 onBufferConsumed(size);
Wei Jiabc2fb722014-07-08 16:37:57 -0700220 }
221 break;
222 }
223
224 case kWhatFlush:
225 {
226 onFlush();
227 break;
228 }
229
230 case kWhatResume:
231 {
232 requestABuffer();
233 break;
234 }
235
236 case kWhatShutdown:
237 {
238 onShutdown();
239 break;
240 }
241
242 default:
243 TRESPASS();
244 break;
245 }
246}
247
248} // namespace android