blob: 802d1fb1b26361d577ad2e1e1582c60268883057 [file] [log] [blame]
Andreas Hubera1587462010-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 Huber41c3f742010-12-21 10:22:33 -0800154 void stop();
Andreas Hubera1587462010-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 Huber687b32d2010-12-15 17:18:20 -0800170 bool mSentFormat;
171
172 void sendFormatChange();
Andreas Hubera1587462010-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 Huber687b32d2010-12-15 17:18:20 -0800181 mEOS(false),
182 mSentFormat(false) {
Andreas Hubera1587462010-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 Huber41c3f742010-12-21 10:22:33 -0800193void DecoderWrapper::WrapperReader::stop() {
194 CHECK_EQ(mDecoder->stop(), (status_t)OK);
195}
196
Andreas Hubera1587462010-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 Hubera1587462010-12-15 15:17:42 -0800227 if (err == OK) {
Andreas Huber687b32d2010-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 Hubera1587462010-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 Huber687b32d2010-12-15 17:18:20 -0800253
254 notify->post();
255 } else if (err == INFO_FORMAT_CHANGED) {
256 sendFormatChange();
257
258 readMore(false /* flush */);
Andreas Hubera1587462010-12-15 15:17:42 -0800259 } else {
Andreas Huber687b32d2010-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 Hubera1587462010-12-15 15:17:42 -0800265 realNotify->setInt32("what", ACodec::kWhatEOS);
266 mEOS = true;
Andreas Hubera1587462010-12-15 15:17:42 -0800267
Andreas Huber687b32d2010-12-15 17:18:20 -0800268 notify->post();
269 }
Andreas Hubera1587462010-12-15 15:17:42 -0800270 break;
271 }
272
273 default:
274 TRESPASS();
275 break;
276 }
277}
278
Andreas Huber687b32d2010-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);
Andreas Huber7caa1302011-01-10 10:38:31 -0800312
313 int32_t cropLeft, cropTop, cropRight, cropBottom;
314 if (!meta->findRect(
315 kKeyCropRect,
316 &cropLeft, &cropTop, &cropRight, &cropBottom)) {
317 cropLeft = 0;
318 cropTop = 0;
319 cropRight = width - 1;
320 cropBottom = height - 1;
321 }
322
323 realNotify->setRect("crop", cropLeft, cropTop, cropRight, cropBottom);
Andreas Huber687b32d2010-12-15 17:18:20 -0800324 }
325
326 notify->post();
327
328 mSentFormat = true;
329}
330
Andreas Hubera1587462010-12-15 15:17:42 -0800331////////////////////////////////////////////////////////////////////////////////
332
333DecoderWrapper::DecoderWrapper()
334 : mNumOutstandingInputBuffers(0),
335 mNumOutstandingOutputBuffers(0),
336 mNumPendingDecodes(0),
337 mFlushing(false) {
338}
339
340DecoderWrapper::~DecoderWrapper() {
341}
342
343void DecoderWrapper::setNotificationMessage(const sp<AMessage> &msg) {
344 mNotify = msg;
345}
346
347void DecoderWrapper::initiateSetup(const sp<AMessage> &msg) {
348 msg->setWhat(kWhatSetup);
349 msg->setTarget(id());
350 msg->post();
351}
352
353void DecoderWrapper::initiateShutdown() {
354 (new AMessage(kWhatShutdown, id()))->post();
355}
356
357void DecoderWrapper::signalFlush() {
358 (new AMessage(kWhatFlush, id()))->post();
359}
360
361void DecoderWrapper::signalResume() {
362 (new AMessage(kWhatResume, id()))->post();
363}
364
365void DecoderWrapper::onMessageReceived(const sp<AMessage> &msg) {
366 switch (msg->what()) {
367 case kWhatSetup:
368 onSetup(msg);
369 break;
370
Andreas Huber41c3f742010-12-21 10:22:33 -0800371 case kWhatShutdown:
372 onShutdown();
373 break;
374
Andreas Hubera1587462010-12-15 15:17:42 -0800375 case kWhatInputDataRequested:
376 {
377 postFillBuffer();
378 ++mNumOutstandingInputBuffers;
379 break;
380 }
381
382 case kWhatInputBufferFilled:
383 {
384 CHECK_GT(mNumOutstandingInputBuffers, 0);
385 --mNumOutstandingInputBuffers;
386
387 if (mFlushing) {
388 mSource->queueEOS(INFO_DISCONTINUITY);
389
390 completeFlushIfPossible();
391 break;
392 }
393
394 sp<RefBase> obj;
395 if (!msg->findObject("buffer", &obj)) {
396 int32_t err = OK;
397 CHECK(msg->findInt32("err", &err));
398
399 mSource->queueEOS(err);
400 break;
401 }
402
403 sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
404
405 mSource->queueBuffer(buffer);
406 break;
407 }
408
409 case kWhatFillBufferDone:
410 {
Andreas Hubera1587462010-12-15 15:17:42 -0800411 sp<AMessage> notify;
412 CHECK(msg->findMessage("real-notify", &notify));
413
Andreas Huber687b32d2010-12-15 17:18:20 -0800414 int32_t what;
415 CHECK(notify->findInt32("what", &what));
Andreas Hubera1587462010-12-15 15:17:42 -0800416
Andreas Huber687b32d2010-12-15 17:18:20 -0800417 if (what == ACodec::kWhatDrainThisBuffer) {
418 CHECK_GT(mNumPendingDecodes, 0);
419 --mNumPendingDecodes;
420
421 sp<AMessage> reply =
422 new AMessage(kWhatOutputBufferDrained, id());
423
424 notify->setMessage("reply", reply);
425
426 ++mNumOutstandingOutputBuffers;
427 } else if (what == ACodec::kWhatEOS) {
428 CHECK_GT(mNumPendingDecodes, 0);
429 --mNumPendingDecodes;
430
431 if (mFlushing) {
432 completeFlushIfPossible();
433 break;
434 }
435 }
436
Andreas Hubera1587462010-12-15 15:17:42 -0800437 notify->post();
Andreas Hubera1587462010-12-15 15:17:42 -0800438 break;
439 }
440
441 case kWhatOutputBufferDrained:
442 {
443 CHECK_GT(mNumOutstandingOutputBuffers, 0);
444 --mNumOutstandingOutputBuffers;
445
446 if (mFlushing) {
447 completeFlushIfPossible();
448 break;
449 }
450
451 ++mNumPendingDecodes;
452 mReader->readMore();
453 break;
454 }
455
456 case kWhatFlush:
457 {
458 onFlush();
459 break;
460 }
461
462 case kWhatResume:
463 {
464 onResume();
465 break;
466 }
467
468 default:
469 TRESPASS();
470 break;
471 }
472}
473
474void DecoderWrapper::onSetup(const sp<AMessage> &msg) {
475 AString mime;
476 CHECK(msg->findString("mime", &mime));
477
478 CHECK(!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC));
479
480 int32_t numChannels, sampleRate;
481 CHECK(msg->findInt32("channel-count", &numChannels));
482 CHECK(msg->findInt32("sample-rate", &sampleRate));
483
484 sp<RefBase> obj;
485 CHECK(msg->findObject("esds", &obj));
486 sp<ABuffer> esds = static_cast<ABuffer *>(obj.get());
487
488 sp<MetaData> meta = new MetaData;
489 meta->setCString(kKeyMIMEType, mime.c_str());
490 meta->setInt32(kKeySampleRate, sampleRate);
491 meta->setInt32(kKeyChannelCount, numChannels);
492 meta->setData(kKeyESDS, 0, esds->data(), esds->size());
493
494 mSource = new WrapperSource(
495 meta, new AMessage(kWhatInputDataRequested, id()));
496
497 sp<MediaSource> decoder = new AACDecoder(mSource);
498
499 mReaderLooper = new ALooper;
500 mReaderLooper->setName("DecoderWrapper looper");
501
502 mReaderLooper->start(
503 false, /* runOnCallingThread */
504 false, /* canCallJava */
505 PRIORITY_AUDIO);
506
507 sp<AMessage> notify = new AMessage(kWhatFillBufferDone, id());
508 notify->setMessage("real-notify", mNotify);
509
510 mReader = new WrapperReader(decoder, notify);
511 mReaderLooper->registerHandler(mReader);
512
513 mReader->start();
514 ++mNumPendingDecodes;
515}
516
Andreas Huber41c3f742010-12-21 10:22:33 -0800517void DecoderWrapper::onShutdown() {
518 mReaderLooper->stop();
519 mReaderLooper.clear();
520
521 mReader->stop();
522 mReader.clear();
523
524 mSource.clear();
525
526 mNumOutstandingInputBuffers = 0;
527 mNumOutstandingOutputBuffers = 0;
528 mNumPendingDecodes = 0;
529 mFlushing = false;
530
531 sp<AMessage> notify = mNotify->dup();
532 notify->setInt32("what", ACodec::kWhatShutdownCompleted);
533 notify->post();
534}
535
Andreas Hubera1587462010-12-15 15:17:42 -0800536void DecoderWrapper::postFillBuffer() {
537 sp<AMessage> notify = mNotify->dup();
538 notify->setInt32("what", ACodec::kWhatFillThisBuffer);
539 sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, id());
540 notify->setMessage("reply", reply);
541 notify->post();
542}
543
544void DecoderWrapper::onFlush() {
545 CHECK(!mFlushing);
546 mFlushing = true;
547
548 completeFlushIfPossible();
549}
550
551void DecoderWrapper::completeFlushIfPossible() {
552 CHECK(mFlushing);
553
554 if (mNumOutstandingInputBuffers > 0
555 || mNumOutstandingOutputBuffers > 0
556 || mNumPendingDecodes > 0) {
557 return;
558 }
559
560 mFlushing = false;
561
562 sp<AMessage> notify = mNotify->dup();
563 notify->setInt32("what", ACodec::kWhatFlushCompleted);
564 notify->post();
565}
566
567void DecoderWrapper::onResume() {
568 CHECK(!mFlushing);
569
570 ++mNumPendingDecodes;
571
572 mSource->clear();
573 mReader->readMore(true /* flush */);
574}
575
576} // namespace android