blob: 9738e331f9365ccabe05eea0e89e9369b0213164 [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;
Andreas Huber2c2814b2010-12-15 17:18:20 -0800169 bool mSentFormat;
170
171 void sendFormatChange();
Andreas Huberf9334412010-12-15 15:17:42 -0800172
173 DISALLOW_EVIL_CONSTRUCTORS(WrapperReader);
174};
175
176DecoderWrapper::WrapperReader::WrapperReader(
177 const sp<MediaSource> &decoder, const sp<AMessage> &notify)
178 : mDecoder(decoder),
179 mNotify(notify),
Andreas Huber2c2814b2010-12-15 17:18:20 -0800180 mEOS(false),
181 mSentFormat(false) {
Andreas Huberf9334412010-12-15 15:17:42 -0800182}
183
184DecoderWrapper::WrapperReader::~WrapperReader() {
185}
186
187void DecoderWrapper::WrapperReader::start() {
188 CHECK_EQ(mDecoder->start(), (status_t)OK);
189 readMore();
190}
191
192void DecoderWrapper::WrapperReader::readMore(bool flush) {
193 if (!flush && mEOS) {
194 return;
195 }
196
197 sp<AMessage> msg = new AMessage(kWhatRead, id());
198 msg->setInt32("flush", static_cast<int32_t>(flush));
199 msg->post();
200}
201
202void DecoderWrapper::WrapperReader::onMessageReceived(
203 const sp<AMessage> &msg) {
204 switch (msg->what()) {
205 case kWhatRead:
206 {
207 int32_t flush;
208 CHECK(msg->findInt32("flush", &flush));
209
210 MediaSource::ReadOptions options;
211 if (flush) {
212 // Dummy seek
213 options.setSeekTo(0);
214 mEOS = false;
215 }
216
217 CHECK(!mEOS);
218
219 MediaBuffer *src;
220 status_t err = mDecoder->read(&src, &options);
221
Andreas Huberf9334412010-12-15 15:17:42 -0800222 if (err == OK) {
Andreas Huber2c2814b2010-12-15 17:18:20 -0800223 if (!mSentFormat) {
224 sendFormatChange();
225 mSentFormat = true;
226 }
227
228 sp<AMessage> notify = mNotify->dup();
229
230 sp<AMessage> realNotify;
231 CHECK(notify->findMessage("real-notify", &realNotify));
232
Andreas Huberf9334412010-12-15 15:17:42 -0800233 realNotify->setInt32("what", ACodec::kWhatDrainThisBuffer);
234
235 sp<ABuffer> dst = new ABuffer(src->range_length());
236 memcpy(dst->data(),
237 (const uint8_t *)src->data() + src->range_offset(),
238 src->range_length());
239
240 int64_t timeUs;
241 CHECK(src->meta_data()->findInt64(kKeyTime, &timeUs));
242 src->release();
243 src = NULL;
244
245 dst->meta()->setInt64("timeUs", timeUs);
246
247 realNotify->setObject("buffer", dst);
Andreas Huber2c2814b2010-12-15 17:18:20 -0800248
249 notify->post();
250 } else if (err == INFO_FORMAT_CHANGED) {
251 sendFormatChange();
252
253 readMore(false /* flush */);
Andreas Huberf9334412010-12-15 15:17:42 -0800254 } else {
Andreas Huber2c2814b2010-12-15 17:18:20 -0800255 sp<AMessage> notify = mNotify->dup();
256
257 sp<AMessage> realNotify;
258 CHECK(notify->findMessage("real-notify", &realNotify));
259
Andreas Huberf9334412010-12-15 15:17:42 -0800260 realNotify->setInt32("what", ACodec::kWhatEOS);
261 mEOS = true;
Andreas Huberf9334412010-12-15 15:17:42 -0800262
Andreas Huber2c2814b2010-12-15 17:18:20 -0800263 notify->post();
264 }
Andreas Huberf9334412010-12-15 15:17:42 -0800265 break;
266 }
267
268 default:
269 TRESPASS();
270 break;
271 }
272}
273
Andreas Huber2c2814b2010-12-15 17:18:20 -0800274void DecoderWrapper::WrapperReader::sendFormatChange() {
275 sp<AMessage> notify = mNotify->dup();
276
277 sp<AMessage> realNotify;
278 CHECK(notify->findMessage("real-notify", &realNotify));
279
280 realNotify->setInt32("what", ACodec::kWhatOutputFormatChanged);
281
282 sp<MetaData> meta = mDecoder->getFormat();
283
284 const char *mime;
285 CHECK(meta->findCString(kKeyMIMEType, &mime));
286
287 realNotify->setString("mime", mime);
288
289 if (!strncasecmp("audio/", mime, 6)) {
290 int32_t numChannels;
291 CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
292
293 int32_t sampleRate;
294 CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
295
296 realNotify->setInt32("channel-count", numChannels);
297 realNotify->setInt32("sample-rate", sampleRate);
298 } else {
299 CHECK(!strncasecmp("video/", mime, 6));
300
301 int32_t width, height;
302 CHECK(meta->findInt32(kKeyWidth, &width));
303 CHECK(meta->findInt32(kKeyHeight, &height));
304
305 realNotify->setInt32("width", width);
306 realNotify->setInt32("height", height);
307 }
308
309 notify->post();
310
311 mSentFormat = true;
312}
313
Andreas Huberf9334412010-12-15 15:17:42 -0800314////////////////////////////////////////////////////////////////////////////////
315
316DecoderWrapper::DecoderWrapper()
317 : mNumOutstandingInputBuffers(0),
318 mNumOutstandingOutputBuffers(0),
319 mNumPendingDecodes(0),
320 mFlushing(false) {
321}
322
323DecoderWrapper::~DecoderWrapper() {
324}
325
326void DecoderWrapper::setNotificationMessage(const sp<AMessage> &msg) {
327 mNotify = msg;
328}
329
330void DecoderWrapper::initiateSetup(const sp<AMessage> &msg) {
331 msg->setWhat(kWhatSetup);
332 msg->setTarget(id());
333 msg->post();
334}
335
336void DecoderWrapper::initiateShutdown() {
337 (new AMessage(kWhatShutdown, id()))->post();
338}
339
340void DecoderWrapper::signalFlush() {
341 (new AMessage(kWhatFlush, id()))->post();
342}
343
344void DecoderWrapper::signalResume() {
345 (new AMessage(kWhatResume, id()))->post();
346}
347
348void DecoderWrapper::onMessageReceived(const sp<AMessage> &msg) {
349 switch (msg->what()) {
350 case kWhatSetup:
351 onSetup(msg);
352 break;
353
354 case kWhatInputDataRequested:
355 {
356 postFillBuffer();
357 ++mNumOutstandingInputBuffers;
358 break;
359 }
360
361 case kWhatInputBufferFilled:
362 {
363 CHECK_GT(mNumOutstandingInputBuffers, 0);
364 --mNumOutstandingInputBuffers;
365
366 if (mFlushing) {
367 mSource->queueEOS(INFO_DISCONTINUITY);
368
369 completeFlushIfPossible();
370 break;
371 }
372
373 sp<RefBase> obj;
374 if (!msg->findObject("buffer", &obj)) {
375 int32_t err = OK;
376 CHECK(msg->findInt32("err", &err));
377
378 mSource->queueEOS(err);
379 break;
380 }
381
382 sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
383
384 mSource->queueBuffer(buffer);
385 break;
386 }
387
388 case kWhatFillBufferDone:
389 {
Andreas Huberf9334412010-12-15 15:17:42 -0800390 sp<AMessage> notify;
391 CHECK(msg->findMessage("real-notify", &notify));
392
Andreas Huber2c2814b2010-12-15 17:18:20 -0800393 int32_t what;
394 CHECK(notify->findInt32("what", &what));
Andreas Huberf9334412010-12-15 15:17:42 -0800395
Andreas Huber2c2814b2010-12-15 17:18:20 -0800396 if (what == ACodec::kWhatDrainThisBuffer) {
397 CHECK_GT(mNumPendingDecodes, 0);
398 --mNumPendingDecodes;
399
400 sp<AMessage> reply =
401 new AMessage(kWhatOutputBufferDrained, id());
402
403 notify->setMessage("reply", reply);
404
405 ++mNumOutstandingOutputBuffers;
406 } else if (what == ACodec::kWhatEOS) {
407 CHECK_GT(mNumPendingDecodes, 0);
408 --mNumPendingDecodes;
409
410 if (mFlushing) {
411 completeFlushIfPossible();
412 break;
413 }
414 }
415
Andreas Huberf9334412010-12-15 15:17:42 -0800416 notify->post();
Andreas Huberf9334412010-12-15 15:17:42 -0800417 break;
418 }
419
420 case kWhatOutputBufferDrained:
421 {
422 CHECK_GT(mNumOutstandingOutputBuffers, 0);
423 --mNumOutstandingOutputBuffers;
424
425 if (mFlushing) {
426 completeFlushIfPossible();
427 break;
428 }
429
430 ++mNumPendingDecodes;
431 mReader->readMore();
432 break;
433 }
434
435 case kWhatFlush:
436 {
437 onFlush();
438 break;
439 }
440
441 case kWhatResume:
442 {
443 onResume();
444 break;
445 }
446
447 default:
448 TRESPASS();
449 break;
450 }
451}
452
453void DecoderWrapper::onSetup(const sp<AMessage> &msg) {
454 AString mime;
455 CHECK(msg->findString("mime", &mime));
456
457 CHECK(!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC));
458
459 int32_t numChannels, sampleRate;
460 CHECK(msg->findInt32("channel-count", &numChannels));
461 CHECK(msg->findInt32("sample-rate", &sampleRate));
462
463 sp<RefBase> obj;
464 CHECK(msg->findObject("esds", &obj));
465 sp<ABuffer> esds = static_cast<ABuffer *>(obj.get());
466
467 sp<MetaData> meta = new MetaData;
468 meta->setCString(kKeyMIMEType, mime.c_str());
469 meta->setInt32(kKeySampleRate, sampleRate);
470 meta->setInt32(kKeyChannelCount, numChannels);
471 meta->setData(kKeyESDS, 0, esds->data(), esds->size());
472
473 mSource = new WrapperSource(
474 meta, new AMessage(kWhatInputDataRequested, id()));
475
476 sp<MediaSource> decoder = new AACDecoder(mSource);
477
478 mReaderLooper = new ALooper;
479 mReaderLooper->setName("DecoderWrapper looper");
480
481 mReaderLooper->start(
482 false, /* runOnCallingThread */
483 false, /* canCallJava */
484 PRIORITY_AUDIO);
485
486 sp<AMessage> notify = new AMessage(kWhatFillBufferDone, id());
487 notify->setMessage("real-notify", mNotify);
488
489 mReader = new WrapperReader(decoder, notify);
490 mReaderLooper->registerHandler(mReader);
491
492 mReader->start();
493 ++mNumPendingDecodes;
494}
495
496void DecoderWrapper::postFillBuffer() {
497 sp<AMessage> notify = mNotify->dup();
498 notify->setInt32("what", ACodec::kWhatFillThisBuffer);
499 sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, id());
500 notify->setMessage("reply", reply);
501 notify->post();
502}
503
504void DecoderWrapper::onFlush() {
505 CHECK(!mFlushing);
506 mFlushing = true;
507
508 completeFlushIfPossible();
509}
510
511void DecoderWrapper::completeFlushIfPossible() {
512 CHECK(mFlushing);
513
514 if (mNumOutstandingInputBuffers > 0
515 || mNumOutstandingOutputBuffers > 0
516 || mNumPendingDecodes > 0) {
517 return;
518 }
519
520 mFlushing = false;
521
522 sp<AMessage> notify = mNotify->dup();
523 notify->setInt32("what", ACodec::kWhatFlushCompleted);
524 notify->post();
525}
526
527void DecoderWrapper::onResume() {
528 CHECK(!mFlushing);
529
530 ++mNumPendingDecodes;
531
532 mSource->clear();
533 mReader->readMore(true /* flush */);
534}
535
536} // namespace android