blob: 4d4cd8dd807c02c9afaf57c1dce82353f11b31d5 [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();
Andreas Huber3831a062010-12-21 10:22:33 -0800154 void stop();
Andreas Huberf9334412010-12-15 15:17:42 -0800155 void readMore(bool flush = false);
156
157protected:
158 virtual ~WrapperReader();
159
160 virtual void onMessageReceived(const sp<AMessage> &msg);
161
162private:
163 enum {
164 kWhatRead
165 };
166
167 sp<MediaSource> mDecoder;
168 sp<AMessage> mNotify;
169 bool mEOS;
Andreas Huber2c2814b2010-12-15 17:18:20 -0800170 bool mSentFormat;
171
172 void sendFormatChange();
Andreas Huberf9334412010-12-15 15:17:42 -0800173
174 DISALLOW_EVIL_CONSTRUCTORS(WrapperReader);
175};
176
177DecoderWrapper::WrapperReader::WrapperReader(
178 const sp<MediaSource> &decoder, const sp<AMessage> &notify)
179 : mDecoder(decoder),
180 mNotify(notify),
Andreas Huber2c2814b2010-12-15 17:18:20 -0800181 mEOS(false),
182 mSentFormat(false) {
Andreas Huberf9334412010-12-15 15:17:42 -0800183}
184
185DecoderWrapper::WrapperReader::~WrapperReader() {
186}
187
188void DecoderWrapper::WrapperReader::start() {
189 CHECK_EQ(mDecoder->start(), (status_t)OK);
190 readMore();
191}
192
Andreas Huber3831a062010-12-21 10:22:33 -0800193void DecoderWrapper::WrapperReader::stop() {
194 CHECK_EQ(mDecoder->stop(), (status_t)OK);
195}
196
Andreas Huberf9334412010-12-15 15:17:42 -0800197void DecoderWrapper::WrapperReader::readMore(bool flush) {
198 if (!flush && mEOS) {
199 return;
200 }
201
202 sp<AMessage> msg = new AMessage(kWhatRead, id());
203 msg->setInt32("flush", static_cast<int32_t>(flush));
204 msg->post();
205}
206
207void DecoderWrapper::WrapperReader::onMessageReceived(
208 const sp<AMessage> &msg) {
209 switch (msg->what()) {
210 case kWhatRead:
211 {
212 int32_t flush;
213 CHECK(msg->findInt32("flush", &flush));
214
215 MediaSource::ReadOptions options;
216 if (flush) {
217 // Dummy seek
218 options.setSeekTo(0);
219 mEOS = false;
220 }
221
222 CHECK(!mEOS);
223
224 MediaBuffer *src;
225 status_t err = mDecoder->read(&src, &options);
226
Andreas Huberf9334412010-12-15 15:17:42 -0800227 if (err == OK) {
Andreas Huber2c2814b2010-12-15 17:18:20 -0800228 if (!mSentFormat) {
229 sendFormatChange();
230 mSentFormat = true;
231 }
232
233 sp<AMessage> notify = mNotify->dup();
234
235 sp<AMessage> realNotify;
236 CHECK(notify->findMessage("real-notify", &realNotify));
237
Andreas Huberf9334412010-12-15 15:17:42 -0800238 realNotify->setInt32("what", ACodec::kWhatDrainThisBuffer);
239
240 sp<ABuffer> dst = new ABuffer(src->range_length());
241 memcpy(dst->data(),
242 (const uint8_t *)src->data() + src->range_offset(),
243 src->range_length());
244
245 int64_t timeUs;
246 CHECK(src->meta_data()->findInt64(kKeyTime, &timeUs));
247 src->release();
248 src = NULL;
249
250 dst->meta()->setInt64("timeUs", timeUs);
251
252 realNotify->setObject("buffer", dst);
Andreas Huber2c2814b2010-12-15 17:18:20 -0800253
254 notify->post();
255 } else if (err == INFO_FORMAT_CHANGED) {
256 sendFormatChange();
257
258 readMore(false /* flush */);
Andreas Huberf9334412010-12-15 15:17:42 -0800259 } else {
Andreas Huber2c2814b2010-12-15 17:18:20 -0800260 sp<AMessage> notify = mNotify->dup();
261
262 sp<AMessage> realNotify;
263 CHECK(notify->findMessage("real-notify", &realNotify));
264
Andreas Huberf9334412010-12-15 15:17:42 -0800265 realNotify->setInt32("what", ACodec::kWhatEOS);
266 mEOS = true;
Andreas Huberf9334412010-12-15 15:17:42 -0800267
Andreas Huber2c2814b2010-12-15 17:18:20 -0800268 notify->post();
269 }
Andreas Huberf9334412010-12-15 15:17:42 -0800270 break;
271 }
272
273 default:
274 TRESPASS();
275 break;
276 }
277}
278
Andreas Huber2c2814b2010-12-15 17:18:20 -0800279void DecoderWrapper::WrapperReader::sendFormatChange() {
280 sp<AMessage> notify = mNotify->dup();
281
282 sp<AMessage> realNotify;
283 CHECK(notify->findMessage("real-notify", &realNotify));
284
285 realNotify->setInt32("what", ACodec::kWhatOutputFormatChanged);
286
287 sp<MetaData> meta = mDecoder->getFormat();
288
289 const char *mime;
290 CHECK(meta->findCString(kKeyMIMEType, &mime));
291
292 realNotify->setString("mime", mime);
293
294 if (!strncasecmp("audio/", mime, 6)) {
295 int32_t numChannels;
296 CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
297
298 int32_t sampleRate;
299 CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
300
301 realNotify->setInt32("channel-count", numChannels);
302 realNotify->setInt32("sample-rate", sampleRate);
303 } else {
304 CHECK(!strncasecmp("video/", mime, 6));
305
306 int32_t width, height;
307 CHECK(meta->findInt32(kKeyWidth, &width));
308 CHECK(meta->findInt32(kKeyHeight, &height));
309
310 realNotify->setInt32("width", width);
311 realNotify->setInt32("height", height);
312 }
313
314 notify->post();
315
316 mSentFormat = true;
317}
318
Andreas Huberf9334412010-12-15 15:17:42 -0800319////////////////////////////////////////////////////////////////////////////////
320
321DecoderWrapper::DecoderWrapper()
322 : mNumOutstandingInputBuffers(0),
323 mNumOutstandingOutputBuffers(0),
324 mNumPendingDecodes(0),
325 mFlushing(false) {
326}
327
328DecoderWrapper::~DecoderWrapper() {
329}
330
331void DecoderWrapper::setNotificationMessage(const sp<AMessage> &msg) {
332 mNotify = msg;
333}
334
335void DecoderWrapper::initiateSetup(const sp<AMessage> &msg) {
336 msg->setWhat(kWhatSetup);
337 msg->setTarget(id());
338 msg->post();
339}
340
341void DecoderWrapper::initiateShutdown() {
342 (new AMessage(kWhatShutdown, id()))->post();
343}
344
345void DecoderWrapper::signalFlush() {
346 (new AMessage(kWhatFlush, id()))->post();
347}
348
349void DecoderWrapper::signalResume() {
350 (new AMessage(kWhatResume, id()))->post();
351}
352
353void DecoderWrapper::onMessageReceived(const sp<AMessage> &msg) {
354 switch (msg->what()) {
355 case kWhatSetup:
356 onSetup(msg);
357 break;
358
Andreas Huber3831a062010-12-21 10:22:33 -0800359 case kWhatShutdown:
360 onShutdown();
361 break;
362
Andreas Huberf9334412010-12-15 15:17:42 -0800363 case kWhatInputDataRequested:
364 {
365 postFillBuffer();
366 ++mNumOutstandingInputBuffers;
367 break;
368 }
369
370 case kWhatInputBufferFilled:
371 {
372 CHECK_GT(mNumOutstandingInputBuffers, 0);
373 --mNumOutstandingInputBuffers;
374
375 if (mFlushing) {
376 mSource->queueEOS(INFO_DISCONTINUITY);
377
378 completeFlushIfPossible();
379 break;
380 }
381
382 sp<RefBase> obj;
383 if (!msg->findObject("buffer", &obj)) {
384 int32_t err = OK;
385 CHECK(msg->findInt32("err", &err));
386
387 mSource->queueEOS(err);
388 break;
389 }
390
391 sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
392
393 mSource->queueBuffer(buffer);
394 break;
395 }
396
397 case kWhatFillBufferDone:
398 {
Andreas Huberf9334412010-12-15 15:17:42 -0800399 sp<AMessage> notify;
400 CHECK(msg->findMessage("real-notify", &notify));
401
Andreas Huber2c2814b2010-12-15 17:18:20 -0800402 int32_t what;
403 CHECK(notify->findInt32("what", &what));
Andreas Huberf9334412010-12-15 15:17:42 -0800404
Andreas Huber2c2814b2010-12-15 17:18:20 -0800405 if (what == ACodec::kWhatDrainThisBuffer) {
406 CHECK_GT(mNumPendingDecodes, 0);
407 --mNumPendingDecodes;
408
409 sp<AMessage> reply =
410 new AMessage(kWhatOutputBufferDrained, id());
411
412 notify->setMessage("reply", reply);
413
414 ++mNumOutstandingOutputBuffers;
415 } else if (what == ACodec::kWhatEOS) {
416 CHECK_GT(mNumPendingDecodes, 0);
417 --mNumPendingDecodes;
418
419 if (mFlushing) {
420 completeFlushIfPossible();
421 break;
422 }
423 }
424
Andreas Huberf9334412010-12-15 15:17:42 -0800425 notify->post();
Andreas Huberf9334412010-12-15 15:17:42 -0800426 break;
427 }
428
429 case kWhatOutputBufferDrained:
430 {
431 CHECK_GT(mNumOutstandingOutputBuffers, 0);
432 --mNumOutstandingOutputBuffers;
433
434 if (mFlushing) {
435 completeFlushIfPossible();
436 break;
437 }
438
439 ++mNumPendingDecodes;
440 mReader->readMore();
441 break;
442 }
443
444 case kWhatFlush:
445 {
446 onFlush();
447 break;
448 }
449
450 case kWhatResume:
451 {
452 onResume();
453 break;
454 }
455
456 default:
457 TRESPASS();
458 break;
459 }
460}
461
462void DecoderWrapper::onSetup(const sp<AMessage> &msg) {
463 AString mime;
464 CHECK(msg->findString("mime", &mime));
465
466 CHECK(!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC));
467
468 int32_t numChannels, sampleRate;
469 CHECK(msg->findInt32("channel-count", &numChannels));
470 CHECK(msg->findInt32("sample-rate", &sampleRate));
471
472 sp<RefBase> obj;
473 CHECK(msg->findObject("esds", &obj));
474 sp<ABuffer> esds = static_cast<ABuffer *>(obj.get());
475
476 sp<MetaData> meta = new MetaData;
477 meta->setCString(kKeyMIMEType, mime.c_str());
478 meta->setInt32(kKeySampleRate, sampleRate);
479 meta->setInt32(kKeyChannelCount, numChannels);
480 meta->setData(kKeyESDS, 0, esds->data(), esds->size());
481
482 mSource = new WrapperSource(
483 meta, new AMessage(kWhatInputDataRequested, id()));
484
485 sp<MediaSource> decoder = new AACDecoder(mSource);
486
487 mReaderLooper = new ALooper;
488 mReaderLooper->setName("DecoderWrapper looper");
489
490 mReaderLooper->start(
491 false, /* runOnCallingThread */
492 false, /* canCallJava */
493 PRIORITY_AUDIO);
494
495 sp<AMessage> notify = new AMessage(kWhatFillBufferDone, id());
496 notify->setMessage("real-notify", mNotify);
497
498 mReader = new WrapperReader(decoder, notify);
499 mReaderLooper->registerHandler(mReader);
500
501 mReader->start();
502 ++mNumPendingDecodes;
503}
504
Andreas Huber3831a062010-12-21 10:22:33 -0800505void DecoderWrapper::onShutdown() {
506 mReaderLooper->stop();
507 mReaderLooper.clear();
508
509 mReader->stop();
510 mReader.clear();
511
512 mSource.clear();
513
514 mNumOutstandingInputBuffers = 0;
515 mNumOutstandingOutputBuffers = 0;
516 mNumPendingDecodes = 0;
517 mFlushing = false;
518
519 sp<AMessage> notify = mNotify->dup();
520 notify->setInt32("what", ACodec::kWhatShutdownCompleted);
521 notify->post();
522}
523
Andreas Huberf9334412010-12-15 15:17:42 -0800524void DecoderWrapper::postFillBuffer() {
525 sp<AMessage> notify = mNotify->dup();
526 notify->setInt32("what", ACodec::kWhatFillThisBuffer);
527 sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, id());
528 notify->setMessage("reply", reply);
529 notify->post();
530}
531
532void DecoderWrapper::onFlush() {
533 CHECK(!mFlushing);
534 mFlushing = true;
535
536 completeFlushIfPossible();
537}
538
539void DecoderWrapper::completeFlushIfPossible() {
540 CHECK(mFlushing);
541
542 if (mNumOutstandingInputBuffers > 0
543 || mNumOutstandingOutputBuffers > 0
544 || mNumPendingDecodes > 0) {
545 return;
546 }
547
548 mFlushing = false;
549
550 sp<AMessage> notify = mNotify->dup();
551 notify->setInt32("what", ACodec::kWhatFlushCompleted);
552 notify->post();
553}
554
555void DecoderWrapper::onResume() {
556 CHECK(!mFlushing);
557
558 ++mNumPendingDecodes;
559
560 mSource->clear();
561 mReader->readMore(true /* flush */);
562}
563
564} // namespace android