blob: 89a5e698b5a34ef3d1fb5d210623f5a7f5c4fd3c [file] [log] [blame]
Andreas Huberf9334412010-12-15 15:17:42 -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 "DecoderWrapper"
19#include <utils/Log.h>
20
21#include "DecoderWrapper.h"
22
23#include "AACDecoder.h"
24
25#include <media/stagefright/foundation/hexdump.h>
26#include <media/stagefright/foundation/ABuffer.h>
27#include <media/stagefright/foundation/ADebug.h>
28#include <media/stagefright/foundation/AMessage.h>
29#include <media/stagefright/ACodec.h>
30#include <media/stagefright/MediaBuffer.h>
31#include <media/stagefright/MediaDefs.h>
32#include <media/stagefright/MediaSource.h>
33#include <media/stagefright/MetaData.h>
34
35namespace android {
36
37struct DecoderWrapper::WrapperSource : public MediaSource {
38 WrapperSource(
39 const sp<MetaData> &meta,
40 const sp<AMessage> &notify);
41
42 virtual status_t start(MetaData *params);
43 virtual status_t stop();
44 virtual sp<MetaData> getFormat();
45
46 virtual status_t read(
47 MediaBuffer **buffer, const ReadOptions *options);
48
49 void queueBuffer(const sp<ABuffer> &buffer);
50 void queueEOS(status_t finalResult);
51 void clear();
52
53protected:
54 virtual ~WrapperSource();
55
56private:
57 Mutex mLock;
58 Condition mCondition;
59
60 sp<MetaData> mMeta;
61 sp<AMessage> mNotify;
62
63 List<sp<ABuffer> > mQueue;
64 status_t mFinalResult;
65
66 DISALLOW_EVIL_CONSTRUCTORS(WrapperSource);
67};
68
69DecoderWrapper::WrapperSource::WrapperSource(
70 const sp<MetaData> &meta, const sp<AMessage> &notify)
71 : mMeta(meta),
72 mNotify(notify),
73 mFinalResult(OK) {
74}
75
76DecoderWrapper::WrapperSource::~WrapperSource() {
77}
78
79status_t DecoderWrapper::WrapperSource::start(MetaData *params) {
80 return OK;
81}
82
83status_t DecoderWrapper::WrapperSource::stop() {
84 return OK;
85}
86
87sp<MetaData> DecoderWrapper::WrapperSource::getFormat() {
88 return mMeta;
89}
90
91status_t DecoderWrapper::WrapperSource::read(
92 MediaBuffer **out, const ReadOptions *options) {
93 Mutex::Autolock autoLock(mLock);
94
95 bool requestedBuffer = false;
96
97 while (mQueue.empty() && mFinalResult == OK) {
98 if (!requestedBuffer) {
99 mNotify->dup()->post();
100 requestedBuffer = true;
101 }
102
103 mCondition.wait(mLock);
104 }
105
106 if (mQueue.empty()) {
107 return mFinalResult;
108 }
109
110 sp<ABuffer> src = *mQueue.begin();
111 mQueue.erase(mQueue.begin());
112
113 MediaBuffer *dst = new MediaBuffer(src->size());
114 memcpy(dst->data(), src->data(), src->size());
115
116 int64_t timeUs;
117 CHECK(src->meta()->findInt64("timeUs", &timeUs));
118
119 dst->meta_data()->setInt64(kKeyTime, timeUs);
120
121 *out = dst;
122
123 return OK;
124}
125
126void DecoderWrapper::WrapperSource::queueBuffer(const sp<ABuffer> &buffer) {
127 Mutex::Autolock autoLock(mLock);
128 mQueue.push_back(buffer);
129 mCondition.broadcast();
130}
131
132void DecoderWrapper::WrapperSource::queueEOS(status_t finalResult) {
133 CHECK_NE(finalResult, (status_t)OK);
134
135 Mutex::Autolock autoLock(mLock);
136 mFinalResult = finalResult;
137 mCondition.broadcast();
138}
139
140void DecoderWrapper::WrapperSource::clear() {
141 Mutex::Autolock autoLock(mLock);
142 mQueue.clear();
143 mFinalResult = OK;
144}
145
146////////////////////////////////////////////////////////////////////////////////
147
148struct DecoderWrapper::WrapperReader : public AHandler {
149 WrapperReader(
150 const sp<MediaSource> &decoder,
151 const sp<AMessage> &notify);
152
153 void start();
154 void readMore(bool flush = false);
155
156protected:
157 virtual ~WrapperReader();
158
159 virtual void onMessageReceived(const sp<AMessage> &msg);
160
161private:
162 enum {
163 kWhatRead
164 };
165
166 sp<MediaSource> mDecoder;
167 sp<AMessage> mNotify;
168 bool mEOS;
169
170 DISALLOW_EVIL_CONSTRUCTORS(WrapperReader);
171};
172
173DecoderWrapper::WrapperReader::WrapperReader(
174 const sp<MediaSource> &decoder, const sp<AMessage> &notify)
175 : mDecoder(decoder),
176 mNotify(notify),
177 mEOS(false) {
178}
179
180DecoderWrapper::WrapperReader::~WrapperReader() {
181}
182
183void DecoderWrapper::WrapperReader::start() {
184 CHECK_EQ(mDecoder->start(), (status_t)OK);
185 readMore();
186}
187
188void DecoderWrapper::WrapperReader::readMore(bool flush) {
189 if (!flush && mEOS) {
190 return;
191 }
192
193 sp<AMessage> msg = new AMessage(kWhatRead, id());
194 msg->setInt32("flush", static_cast<int32_t>(flush));
195 msg->post();
196}
197
198void DecoderWrapper::WrapperReader::onMessageReceived(
199 const sp<AMessage> &msg) {
200 switch (msg->what()) {
201 case kWhatRead:
202 {
203 int32_t flush;
204 CHECK(msg->findInt32("flush", &flush));
205
206 MediaSource::ReadOptions options;
207 if (flush) {
208 // Dummy seek
209 options.setSeekTo(0);
210 mEOS = false;
211 }
212
213 CHECK(!mEOS);
214
215 MediaBuffer *src;
216 status_t err = mDecoder->read(&src, &options);
217
218 sp<AMessage> notify = mNotify->dup();
219
220 sp<AMessage> realNotify;
221 CHECK(notify->findMessage("real-notify", &realNotify));
222
223 if (err == OK) {
224 realNotify->setInt32("what", ACodec::kWhatDrainThisBuffer);
225
226 sp<ABuffer> dst = new ABuffer(src->range_length());
227 memcpy(dst->data(),
228 (const uint8_t *)src->data() + src->range_offset(),
229 src->range_length());
230
231 int64_t timeUs;
232 CHECK(src->meta_data()->findInt64(kKeyTime, &timeUs));
233 src->release();
234 src = NULL;
235
236 dst->meta()->setInt64("timeUs", timeUs);
237
238 realNotify->setObject("buffer", dst);
239 } else {
240 realNotify->setInt32("what", ACodec::kWhatEOS);
241 mEOS = true;
242 }
243
244 notify->post();
245 break;
246 }
247
248 default:
249 TRESPASS();
250 break;
251 }
252}
253
254////////////////////////////////////////////////////////////////////////////////
255
256DecoderWrapper::DecoderWrapper()
257 : mNumOutstandingInputBuffers(0),
258 mNumOutstandingOutputBuffers(0),
259 mNumPendingDecodes(0),
260 mFlushing(false) {
261}
262
263DecoderWrapper::~DecoderWrapper() {
264}
265
266void DecoderWrapper::setNotificationMessage(const sp<AMessage> &msg) {
267 mNotify = msg;
268}
269
270void DecoderWrapper::initiateSetup(const sp<AMessage> &msg) {
271 msg->setWhat(kWhatSetup);
272 msg->setTarget(id());
273 msg->post();
274}
275
276void DecoderWrapper::initiateShutdown() {
277 (new AMessage(kWhatShutdown, id()))->post();
278}
279
280void DecoderWrapper::signalFlush() {
281 (new AMessage(kWhatFlush, id()))->post();
282}
283
284void DecoderWrapper::signalResume() {
285 (new AMessage(kWhatResume, id()))->post();
286}
287
288void DecoderWrapper::onMessageReceived(const sp<AMessage> &msg) {
289 switch (msg->what()) {
290 case kWhatSetup:
291 onSetup(msg);
292 break;
293
294 case kWhatInputDataRequested:
295 {
296 postFillBuffer();
297 ++mNumOutstandingInputBuffers;
298 break;
299 }
300
301 case kWhatInputBufferFilled:
302 {
303 CHECK_GT(mNumOutstandingInputBuffers, 0);
304 --mNumOutstandingInputBuffers;
305
306 if (mFlushing) {
307 mSource->queueEOS(INFO_DISCONTINUITY);
308
309 completeFlushIfPossible();
310 break;
311 }
312
313 sp<RefBase> obj;
314 if (!msg->findObject("buffer", &obj)) {
315 int32_t err = OK;
316 CHECK(msg->findInt32("err", &err));
317
318 mSource->queueEOS(err);
319 break;
320 }
321
322 sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
323
324 mSource->queueBuffer(buffer);
325 break;
326 }
327
328 case kWhatFillBufferDone:
329 {
330 CHECK_GT(mNumPendingDecodes, 0);
331 --mNumPendingDecodes;
332
333 if (mFlushing) {
334 completeFlushIfPossible();
335 break;
336 }
337
338 sp<AMessage> notify;
339 CHECK(msg->findMessage("real-notify", &notify));
340
341 sp<AMessage> reply =
342 new AMessage(kWhatOutputBufferDrained, id());
343
344 notify->setMessage("reply", reply);
345 notify->post();
346
347 ++mNumOutstandingOutputBuffers;
348 break;
349 }
350
351 case kWhatOutputBufferDrained:
352 {
353 CHECK_GT(mNumOutstandingOutputBuffers, 0);
354 --mNumOutstandingOutputBuffers;
355
356 if (mFlushing) {
357 completeFlushIfPossible();
358 break;
359 }
360
361 ++mNumPendingDecodes;
362 mReader->readMore();
363 break;
364 }
365
366 case kWhatFlush:
367 {
368 onFlush();
369 break;
370 }
371
372 case kWhatResume:
373 {
374 onResume();
375 break;
376 }
377
378 default:
379 TRESPASS();
380 break;
381 }
382}
383
384void DecoderWrapper::onSetup(const sp<AMessage> &msg) {
385 AString mime;
386 CHECK(msg->findString("mime", &mime));
387
388 CHECK(!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC));
389
390 int32_t numChannels, sampleRate;
391 CHECK(msg->findInt32("channel-count", &numChannels));
392 CHECK(msg->findInt32("sample-rate", &sampleRate));
393
394 sp<RefBase> obj;
395 CHECK(msg->findObject("esds", &obj));
396 sp<ABuffer> esds = static_cast<ABuffer *>(obj.get());
397
398 sp<MetaData> meta = new MetaData;
399 meta->setCString(kKeyMIMEType, mime.c_str());
400 meta->setInt32(kKeySampleRate, sampleRate);
401 meta->setInt32(kKeyChannelCount, numChannels);
402 meta->setData(kKeyESDS, 0, esds->data(), esds->size());
403
404 mSource = new WrapperSource(
405 meta, new AMessage(kWhatInputDataRequested, id()));
406
407 sp<MediaSource> decoder = new AACDecoder(mSource);
408
409 mReaderLooper = new ALooper;
410 mReaderLooper->setName("DecoderWrapper looper");
411
412 mReaderLooper->start(
413 false, /* runOnCallingThread */
414 false, /* canCallJava */
415 PRIORITY_AUDIO);
416
417 sp<AMessage> notify = new AMessage(kWhatFillBufferDone, id());
418 notify->setMessage("real-notify", mNotify);
419
420 mReader = new WrapperReader(decoder, notify);
421 mReaderLooper->registerHandler(mReader);
422
423 mReader->start();
424 ++mNumPendingDecodes;
425}
426
427void DecoderWrapper::postFillBuffer() {
428 sp<AMessage> notify = mNotify->dup();
429 notify->setInt32("what", ACodec::kWhatFillThisBuffer);
430 sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, id());
431 notify->setMessage("reply", reply);
432 notify->post();
433}
434
435void DecoderWrapper::onFlush() {
436 CHECK(!mFlushing);
437 mFlushing = true;
438
439 completeFlushIfPossible();
440}
441
442void DecoderWrapper::completeFlushIfPossible() {
443 CHECK(mFlushing);
444
445 if (mNumOutstandingInputBuffers > 0
446 || mNumOutstandingOutputBuffers > 0
447 || mNumPendingDecodes > 0) {
448 return;
449 }
450
451 mFlushing = false;
452
453 sp<AMessage> notify = mNotify->dup();
454 notify->setInt32("what", ACodec::kWhatFlushCompleted);
455 notify->post();
456}
457
458void DecoderWrapper::onResume() {
459 CHECK(!mFlushing);
460
461 ++mNumPendingDecodes;
462
463 mSource->clear();
464 mReader->readMore(true /* flush */);
465}
466
467} // namespace android