blob: c059a9df624a67d7ea9dc3bd9ae0959e09786fad [file] [log] [blame]
Andreas Huber20111aa2009-07-14 16:56:47 -07001/*
2 * Copyright (C) 2009 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 "OMXDecoder"
19#include <utils/Log.h>
20
21#undef NDEBUG
22#include <assert.h>
23
24#include <OMX_Component.h>
25
26#include <media/stagefright/ESDS.h>
27#include <media/stagefright/MetaData.h>
28#include <media/stagefright/OMXDecoder.h>
29
30namespace android {
31
32class OMXMediaBuffer : public MediaBuffer {
33public:
34 OMXMediaBuffer(IOMX::buffer_id buffer_id, const sp<IMemory> &mem)
35 : MediaBuffer(mem->pointer(),
36 mem->size()),
37 mBufferID(buffer_id),
38 mMem(mem) {
39 }
40
41 IOMX::buffer_id buffer_id() const { return mBufferID; }
42
43private:
44 IOMX::buffer_id mBufferID;
45 sp<IMemory> mMem;
46
47 OMXMediaBuffer(const OMXMediaBuffer &);
48 OMXMediaBuffer &operator=(const OMXMediaBuffer &);
49};
50
51struct CodecInfo {
52 const char *mime;
53 const char *codec;
54};
55
56static const CodecInfo kDecoderInfo[] = {
57 { "audio/mpeg", "OMX.PV.mp3dec" },
58 { "audio/3gpp", "OMX.PV.amrdec" },
59 { "audio/mp4a-latm", "OMX.PV.aacdec" },
60 { "video/mp4v-es", "OMX.qcom.video.decoder.mpeg4" },
61 { "video/mp4v-es", "OMX.PV.mpeg4dec" },
62 { "video/3gpp", "OMX.qcom.video.decoder.h263" },
63 { "video/3gpp", "OMX.PV.h263dec" },
64 { "video/avc", "OMX.qcom.video.decoder.avc" },
65 { "video/avc", "OMX.PV.avcdec" },
66};
67
68static const CodecInfo kEncoderInfo[] = {
69 { "audio/3gpp", "OMX.PV.amrencnb" },
70 { "audio/mp4a-latm", "OMX.PV.aacenc" },
71 { "video/mp4v-es", "OMX.qcom.video.encoder.mpeg4" },
72 { "video/mp4v-es", "OMX.PV.mpeg4enc" },
73 { "video/3gpp", "OMX.qcom.video.encoder.h263" },
74 { "video/3gpp", "OMX.PV.h263enc" },
75 { "video/avc", "OMX.PV.avcenc" },
76};
77
78static const char *GetCodec(const CodecInfo *info, size_t numInfos,
79 const char *mime, int index) {
80 assert(index >= 0);
81 for(size_t i = 0; i < numInfos; ++i) {
82 if (!strcasecmp(mime, info[i].mime)) {
83 if (index == 0) {
84 return info[i].codec;
85 }
86
87 --index;
88 }
89 }
90
91 return NULL;
92}
93
94// static
95OMXDecoder *OMXDecoder::Create(OMXClient *client, const sp<MetaData> &meta) {
96 const char *mime;
97 bool success = meta->findCString(kKeyMIMEType, &mime);
98 assert(success);
99
100 sp<IOMX> omx = client->interface();
101
102 const char *codec = NULL;
103 IOMX::node_id node = 0;
104 for (int index = 0;; ++index) {
105 codec = GetCodec(
106 kDecoderInfo, sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]),
107 mime, index);
108
109 if (!codec) {
110 return NULL;
111 }
112
113 LOGI("Attempting to allocate OMX node '%s'", codec);
114
115 status_t err = omx->allocate_node(codec, &node);
116 if (err == OK) {
117 break;
118 }
119 }
120
121 OMXDecoder *decoder = new OMXDecoder(client, node, mime, codec);
122
123 uint32_t type;
124 const void *data;
125 size_t size;
126 if (meta->findData(kKeyESDS, &type, &data, &size)) {
127 ESDS esds((const char *)data, size);
128 assert(esds.InitCheck() == OK);
129
130 const void *codec_specific_data;
131 size_t codec_specific_data_size;
132 esds.getCodecSpecificInfo(
133 &codec_specific_data, &codec_specific_data_size);
134
135 printf("found codec specific data of size %d\n",
136 codec_specific_data_size);
137
138 decoder->addCodecSpecificData(
139 codec_specific_data, codec_specific_data_size);
140 } else if (meta->findData(kKeyAVCC, &type, &data, &size)) {
141 printf("found avcc of size %d\n", size);
142
143 const uint8_t *ptr = (const uint8_t *)data + 6;
144 size -= 6;
145 while (size >= 2) {
146 size_t length = ptr[0] << 8 | ptr[1];
147
148 ptr += 2;
149 size -= 2;
150
151 // printf("length = %d, size = %d\n", length, size);
152
153 assert(size >= length);
154
155 decoder->addCodecSpecificData(ptr, length);
156
157 ptr += length;
158 size -= length;
159
160 if (size <= 1) {
161 break;
162 }
163
164 ptr++; // XXX skip trailing 0x01 byte???
165 --size;
166 }
167 }
168
169 return decoder;
170}
171
172// static
173OMXDecoder *OMXDecoder::CreateEncoder(
174 OMXClient *client, const sp<MetaData> &meta) {
175 const char *mime;
176 bool success = meta->findCString(kKeyMIMEType, &mime);
177 assert(success);
178
179 sp<IOMX> omx = client->interface();
180
181 const char *codec = NULL;
182 IOMX::node_id node = 0;
183 for (int index = 0;; ++index) {
184 codec = GetCodec(
185 kEncoderInfo, sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]),
186 mime, index);
187
188 if (!codec) {
189 return NULL;
190 }
191
192 LOGI("Attempting to allocate OMX node '%s'", codec);
193
194 status_t err = omx->allocate_node(codec, &node);
195 if (err == OK) {
196 break;
197 }
198 }
199
200 OMXDecoder *encoder = new OMXDecoder(client, node, mime, codec);
201
202 return encoder;
203}
204
205OMXDecoder::OMXDecoder(OMXClient *client, IOMX::node_id node,
206 const char *mime, const char *codec)
207 : mClient(client),
208 mOMX(mClient->interface()),
209 mNode(node),
210 mComponentName(strdup(codec)),
211 mIsMP3(!strcasecmp(mime, "audio/mpeg")),
212 mSource(NULL),
213 mCodecSpecificDataIterator(mCodecSpecificData.begin()),
214 mState(OMX_StateLoaded),
215 mPortStatusMask(kPortStatusActive << 2 | kPortStatusActive),
216 mShutdownInitiated(false),
217 mDealer(new MemoryDealer(3 * 1024 * 1024)),
218 mSeeking(false),
219 mStarted(false),
220 mErrorCondition(OK),
221 mReachedEndOfInput(false) {
222 mClient->registerObserver(mNode, this);
223
224 mBuffers.push(); // input buffers
225 mBuffers.push(); // output buffers
226}
227
228OMXDecoder::~OMXDecoder() {
229 if (mStarted) {
230 stop();
231 }
232
233 for (List<CodecSpecificData>::iterator it = mCodecSpecificData.begin();
234 it != mCodecSpecificData.end(); ++it) {
235 free((*it).data);
236 }
237 mCodecSpecificData.clear();
238
239 mClient->unregisterObserver(mNode);
240
241 status_t err = mOMX->free_node(mNode);
242 assert(err == OK);
243 mNode = 0;
244
245 free(mComponentName);
246 mComponentName = NULL;
247}
248
249void OMXDecoder::setSource(MediaSource *source) {
250 Mutex::Autolock autoLock(mLock);
251
252 assert(mSource == NULL);
253
254 mSource = source;
255 setup();
256}
257
258status_t OMXDecoder::start(MetaData *) {
259 assert(!mStarted);
260
261 // mDealer->dump("Decoder Dealer");
262
263 sp<MetaData> params = new MetaData;
264 if (!strcmp(mComponentName, "OMX.qcom.video.decoder.avc")) {
265 params->setInt32(kKeyNeedsNALFraming, true);
266 }
267
268 status_t err = mSource->start(params.get());
269
270 if (err != OK) {
271 return err;
272 }
273
274 postStart();
275
276 mStarted = true;
277
278 return OK;
279}
280
281status_t OMXDecoder::stop() {
282 assert(mStarted);
283
284 LOGI("Initiating OMX Node shutdown, busy polling.");
285 initiateShutdown();
286
287 // Important: initiateShutdown must be called first, _then_ release
288 // buffers we're holding onto.
289 while (!mOutputBuffers.empty()) {
290 MediaBuffer *buffer = *mOutputBuffers.begin();
291 mOutputBuffers.erase(mOutputBuffers.begin());
292
293 LOGV("releasing buffer %p.", buffer->data());
294
295 buffer->release();
296 buffer = NULL;
297 }
298
299 int attempt = 1;
300 while (mState != OMX_StateLoaded && attempt < 10) {
301 usleep(100000);
302
303 ++attempt;
304 }
305
306 if (mState != OMX_StateLoaded) {
307 LOGE("!!! OMX Node '%s' did NOT shutdown cleanly !!!", mComponentName);
308 } else {
309 LOGI("OMX Node '%s' has shutdown cleanly.", mComponentName);
310 }
311
312 mSource->stop();
313
314 mCodecSpecificDataIterator = mCodecSpecificData.begin();
315 mShutdownInitiated = false;
316 mSeeking = false;
317 mStarted = false;
318 mErrorCondition = OK;
319 mReachedEndOfInput = false;
320
321 return OK;
322}
323
324sp<MetaData> OMXDecoder::getFormat() {
325 return mOutputFormat;
326}
327
328status_t OMXDecoder::read(
329 MediaBuffer **out, const ReadOptions *options) {
330 assert(mStarted);
331
332 *out = NULL;
333
334 Mutex::Autolock autoLock(mLock);
335
336 if (mErrorCondition != OK && mErrorCondition != ERROR_END_OF_STREAM) {
337 // Errors are sticky.
338 return mErrorCondition;
339 }
340
341 int64_t seekTimeUs;
342 if (options && options->getSeekTo(&seekTimeUs)) {
343 LOGI("[%s] seeking to %lld us", mComponentName, seekTimeUs);
344
345 mErrorCondition = OK;
346 mReachedEndOfInput = false;
347
348 setPortStatus(kPortIndexInput, kPortStatusFlushing);
349 setPortStatus(kPortIndexOutput, kPortStatusFlushing);
350
351 mSeeking = true;
352 mSeekTimeUs = seekTimeUs;
353
354 while (!mOutputBuffers.empty()) {
355 OMXMediaBuffer *buffer =
356 static_cast<OMXMediaBuffer *>(*mOutputBuffers.begin());
357
358 // We could have used buffer->release() instead, but we're
359 // holding the lock and signalBufferReturned attempts to acquire
360 // the lock.
361 buffer->claim();
362 mBuffers.editItemAt(
363 kPortIndexOutput).push_back(buffer->buffer_id());
364 buffer = NULL;
365
366 mOutputBuffers.erase(mOutputBuffers.begin());
367 }
368
369 status_t err = mOMX->send_command(mNode, OMX_CommandFlush, -1);
370 assert(err == OK);
371
372 // Once flushing is completed buffers will again be scheduled to be
373 // filled/emptied.
374 }
375
376 while (mErrorCondition == OK && mOutputBuffers.empty()) {
377 mOutputBufferAvailable.wait(mLock);
378 }
379
380 if (!mOutputBuffers.empty()) {
381 MediaBuffer *buffer = *mOutputBuffers.begin();
382 mOutputBuffers.erase(mOutputBuffers.begin());
383
384 *out = buffer;
385
386 return OK;
387 } else {
388 assert(mErrorCondition != OK);
389 return mErrorCondition;
390 }
391}
392
393void OMXDecoder::addCodecSpecificData(const void *data, size_t size) {
394 CodecSpecificData specific;
395 specific.data = malloc(size);
396 memcpy(specific.data, data, size);
397 specific.size = size;
398
399 mCodecSpecificData.push_back(specific);
400 mCodecSpecificDataIterator = mCodecSpecificData.begin();
401}
402
403void OMXDecoder::onOMXMessage(const omx_message &msg) {
404 Mutex::Autolock autoLock(mLock);
405
406 switch (msg.type) {
407 case omx_message::START:
408 {
409 onStart();
410 break;
411 }
412
413 case omx_message::EVENT:
414 {
415 onEvent(msg.u.event_data.event, msg.u.event_data.data1,
416 msg.u.event_data.data2);
417 break;
418 }
419
420 case omx_message::EMPTY_BUFFER_DONE:
421 {
422 onEmptyBufferDone(msg.u.buffer_data.buffer);
423 break;
424 }
425
426 case omx_message::FILL_BUFFER_DONE:
427 case omx_message::INITIAL_FILL_BUFFER:
428 {
429 onFillBufferDone(msg);
430 break;
431 }
432
433 default:
434 LOGE("received unknown omx_message type %d", msg.type);
435 break;
436 }
437}
438
439void OMXDecoder::setAMRFormat() {
440 OMX_AUDIO_PARAM_AMRTYPE def;
441 def.nSize = sizeof(def);
442 def.nVersion.s.nVersionMajor = 1;
443 def.nVersion.s.nVersionMinor = 1;
444 def.nPortIndex = kPortIndexInput;
445
446 status_t err =
447 mOMX->get_parameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
448
449 assert(err == NO_ERROR);
450
451 def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
452 def.eAMRBandMode = OMX_AUDIO_AMRBandModeNB0;
453
454 err = mOMX->set_parameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
455 assert(err == NO_ERROR);
456}
457
458void OMXDecoder::setAACFormat() {
459 OMX_AUDIO_PARAM_AACPROFILETYPE def;
460 def.nSize = sizeof(def);
461 def.nVersion.s.nVersionMajor = 1;
462 def.nVersion.s.nVersionMinor = 1;
463 def.nPortIndex = kPortIndexInput;
464
465 status_t err =
466 mOMX->get_parameter(mNode, OMX_IndexParamAudioAac, &def, sizeof(def));
467 assert(err == NO_ERROR);
468
469 def.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
470
471 err = mOMX->set_parameter(mNode, OMX_IndexParamAudioAac, &def, sizeof(def));
472 assert(err == NO_ERROR);
473}
474
475void OMXDecoder::setVideoOutputFormat(OMX_U32 width, OMX_U32 height) {
476 LOGI("setVideoOutputFormat width=%ld, height=%ld", width, height);
477
478 OMX_PARAM_PORTDEFINITIONTYPE def;
479 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
480
481 bool is_encoder = strstr(mComponentName, ".encoder.") != NULL; // XXX
482
483 def.nSize = sizeof(def);
484 def.nVersion.s.nVersionMajor = 1;
485 def.nVersion.s.nVersionMinor = 1;
486 def.nPortIndex = is_encoder ? kPortIndexOutput : kPortIndexInput;
487
488 status_t err = mOMX->get_parameter(
489 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
490
491 assert(err == NO_ERROR);
492
493#if 1
494 // XXX Need a (much) better heuristic to compute input buffer sizes.
495 const size_t X = 64 * 1024;
496 if (def.nBufferSize < X) {
497 def.nBufferSize = X;
498 }
499#endif
500
501 assert(def.eDomain == OMX_PortDomainVideo);
502
503 video_def->nFrameWidth = width;
504 video_def->nFrameHeight = height;
505 // video_def.eCompressionFormat = OMX_VIDEO_CodingAVC;
506 video_def->eColorFormat = OMX_COLOR_FormatUnused;
507
508 err = mOMX->set_parameter(
509 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
510 assert(err == NO_ERROR);
511
512 ////////////////////////////////////////////////////////////////////////////
513
514 def.nSize = sizeof(def);
515 def.nVersion.s.nVersionMajor = 1;
516 def.nVersion.s.nVersionMinor = 1;
517 def.nPortIndex = is_encoder ? kPortIndexInput : kPortIndexOutput;
518
519 err = mOMX->get_parameter(
520 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
521 assert(err == NO_ERROR);
522
523 assert(def.eDomain == OMX_PortDomainVideo);
524
525 def.nBufferSize =
526 (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2; // YUV420
527
528 video_def->nFrameWidth = width;
529 video_def->nFrameHeight = height;
530 video_def->nStride = width;
531 // video_def->nSliceHeight = height;
532 video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
533// video_def->eColorFormat = OMX_COLOR_FormatYUV420Planar;
534
535 err = mOMX->set_parameter(
536 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
537 assert(err == NO_ERROR);
538}
539
540void OMXDecoder::setup() {
541 const sp<MetaData> &meta = mSource->getFormat();
542
543 const char *mime;
544 bool success = meta->findCString(kKeyMIMEType, &mime);
545 assert(success);
546
547 if (!strcasecmp(mime, "audio/3gpp")) {
548 setAMRFormat();
549 } else if (!strcasecmp(mime, "audio/mp4a-latm")) {
550 setAACFormat();
551 } else if (!strncasecmp(mime, "video/", 6)) {
552 int32_t width, height;
553 bool success = meta->findInt32(kKeyWidth, &width);
554 success = success && meta->findInt32(kKeyHeight, &height);
555 assert(success);
556
557 setVideoOutputFormat(width, height);
558 }
559
560 // dumpPortDefinition(0);
561 // dumpPortDefinition(1);
562
563 mOutputFormat = new MetaData;
564 mOutputFormat->setCString(kKeyDecoderComponent, mComponentName);
565
566 OMX_PARAM_PORTDEFINITIONTYPE def;
567 def.nSize = sizeof(def);
568 def.nVersion.s.nVersionMajor = 1;
569 def.nVersion.s.nVersionMinor = 1;
570 def.nPortIndex = kPortIndexOutput;
571
572 status_t err = mOMX->get_parameter(
573 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
574 assert(err == NO_ERROR);
575
576 switch (def.eDomain) {
577 case OMX_PortDomainAudio:
578 {
579 OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio;
580
581 assert(audio_def->eEncoding == OMX_AUDIO_CodingPCM);
582
583 OMX_AUDIO_PARAM_PCMMODETYPE params;
584 params.nSize = sizeof(params);
585 params.nVersion.s.nVersionMajor = 1;
586 params.nVersion.s.nVersionMinor = 1;
587 params.nPortIndex = kPortIndexOutput;
588
589 err = mOMX->get_parameter(
590 mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
591 assert(err == OK);
592
593 assert(params.eNumData == OMX_NumericalDataSigned);
594 assert(params.nBitPerSample == 16);
595 assert(params.ePCMMode == OMX_AUDIO_PCMModeLinear);
596
597 int32_t numChannels, sampleRate;
598 meta->findInt32(kKeyChannelCount, &numChannels);
599 meta->findInt32(kKeySampleRate, &sampleRate);
600
601 mOutputFormat->setCString(kKeyMIMEType, "audio/raw");
602 mOutputFormat->setInt32(kKeyChannelCount, numChannels);
603 mOutputFormat->setInt32(kKeySampleRate, sampleRate);
604 break;
605 }
606
607 case OMX_PortDomainVideo:
608 {
609 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
610
611 if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) {
612 mOutputFormat->setCString(kKeyMIMEType, "video/raw");
613 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) {
614 mOutputFormat->setCString(kKeyMIMEType, "video/mp4v-es");
615 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) {
616 mOutputFormat->setCString(kKeyMIMEType, "video/3gpp");
617 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) {
618 mOutputFormat->setCString(kKeyMIMEType, "video/avc");
619 } else {
620 assert(!"Unknown compression format.");
621 }
622
623 if (!strcmp(mComponentName, "OMX.PV.avcdec")) {
624 // This component appears to be lying to me.
625 mOutputFormat->setInt32(
626 kKeyWidth, (video_def->nFrameWidth + 15) & -16);
627 mOutputFormat->setInt32(
628 kKeyHeight, (video_def->nFrameHeight + 15) & -16);
629 } else {
630 mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth);
631 mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight);
632 }
633
634 mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat);
635 break;
636 }
637
638 default:
639 {
640 assert(!"should not be here, neither audio nor video.");
641 break;
642 }
643 }
644}
645
646void OMXDecoder::onStart() {
647 bool needs_qcom_hack =
648 !strncmp(mComponentName, "OMX.qcom.video.", 15);
649
650 if (!needs_qcom_hack) {
651 status_t err =
652 mOMX->send_command(mNode, OMX_CommandStateSet, OMX_StateIdle);
653 assert(err == NO_ERROR);
654 }
655
656 allocateBuffers(kPortIndexInput);
657 allocateBuffers(kPortIndexOutput);
658
659 if (needs_qcom_hack) {
660 // XXX this should happen before AllocateBuffers, but qcom's
661 // h264 vdec disagrees.
662 status_t err =
663 mOMX->send_command(mNode, OMX_CommandStateSet, OMX_StateIdle);
664 assert(err == NO_ERROR);
665 }
666}
667
668void OMXDecoder::allocateBuffers(OMX_U32 port_index) {
669 assert(mBuffers[port_index].empty());
670
671 OMX_U32 num_buffers;
672 OMX_U32 buffer_size;
673
674 OMX_PARAM_PORTDEFINITIONTYPE def;
675 def.nSize = sizeof(def);
676 def.nVersion.s.nVersionMajor = 1;
677 def.nVersion.s.nVersionMinor = 1;
678 def.nVersion.s.nRevision = 0;
679 def.nVersion.s.nStep = 0;
680 def.nPortIndex = port_index;
681
682 status_t err = mOMX->get_parameter(
683 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
684 assert(err == NO_ERROR);
685
686 num_buffers = def.nBufferCountActual;
687 buffer_size = def.nBufferSize;
688
689 LOGV("[%s] port %ld: allocating %ld buffers of size %ld each\n",
690 mComponentName, port_index, num_buffers, buffer_size);
691
692 for (OMX_U32 i = 0; i < num_buffers; ++i) {
693 sp<IMemory> mem = mDealer->allocate(buffer_size);
694 assert(mem.get() != NULL);
695
696 IOMX::buffer_id buffer;
697 status_t err;
698
699 if (port_index == kPortIndexInput
700 && !strncmp(mComponentName, "OMX.qcom.video.encoder.", 23)) {
701 // qcom's H.263 encoder appears to want to allocate its own input
702 // buffers.
703 err = mOMX->allocate_buffer_with_backup(mNode, port_index, mem, &buffer);
704 if (err != OK) {
705 LOGE("[%s] allocate_buffer_with_backup failed with error %d",
706 mComponentName, err);
707 }
708 } else if (port_index == kPortIndexOutput
709 && !strncmp(mComponentName, "OMX.qcom.video.decoder.", 23)) {
710#if 1
711 err = mOMX->allocate_buffer_with_backup(mNode, port_index, mem, &buffer);
712#else
713 // XXX This is fine as long as we are either running the player
714 // inside the media server process or we are using the
715 // QComHardwareRenderer to output the frames.
716 err = mOMX->allocate_buffer(mNode, port_index, buffer_size, &buffer);
717#endif
718 if (err != OK) {
719 LOGE("[%s] allocate_buffer_with_backup failed with error %d",
720 mComponentName, err);
721 }
722 } else {
723 err = mOMX->use_buffer(mNode, port_index, mem, &buffer);
724 if (err != OK) {
725 LOGE("[%s] use_buffer failed with error %d",
726 mComponentName, err);
727 }
728 }
729 assert(err == OK);
730
731 LOGV("allocated %s buffer %p.",
732 port_index == kPortIndexInput ? "INPUT" : "OUTPUT",
733 buffer);
734
735 mBuffers.editItemAt(port_index).push_back(buffer);
736 mBufferMap.add(buffer, mem);
737
738 if (port_index == kPortIndexOutput) {
739 OMXMediaBuffer *media_buffer = new OMXMediaBuffer(buffer, mem);
740 media_buffer->setObserver(this);
741
742 mMediaBufferMap.add(buffer, media_buffer);
743 }
744 }
745
746 LOGV("allocate %s buffers done.",
747 port_index == kPortIndexInput ? "INPUT" : "OUTPUT");
748}
749
750void OMXDecoder::onEvent(
751 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
752 LOGV("[%s] onEvent event=%d, data1=%ld, data2=%ld",
753 mComponentName, event, data1, data2);
754
755 switch (event) {
756 case OMX_EventCmdComplete: {
757 onEventCmdComplete(
758 static_cast<OMX_COMMANDTYPE>(data1), data2);
759
760 break;
761 }
762
763 case OMX_EventPortSettingsChanged: {
764 onEventPortSettingsChanged(data1);
765 break;
766 }
767
768 case OMX_EventBufferFlag: {
769 // initiateShutdown();
770 break;
771 }
772
773 default:
774 break;
775 }
776}
777
778void OMXDecoder::onEventCmdComplete(OMX_COMMANDTYPE type, OMX_U32 data) {
779 switch (type) {
780 case OMX_CommandStateSet: {
781 OMX_STATETYPE state = static_cast<OMX_STATETYPE>(data);
782 onStateChanged(state);
783 break;
784 }
785
786 case OMX_CommandPortDisable: {
787 OMX_U32 port_index = data;
788 assert(getPortStatus(port_index) == kPortStatusDisabled);
789
790 status_t err =
791 mOMX->send_command(mNode, OMX_CommandPortEnable, port_index);
792
793 allocateBuffers(port_index);
794
795 break;
796 }
797
798 case OMX_CommandPortEnable: {
799 OMX_U32 port_index = data;
800 assert(getPortStatus(port_index) ==kPortStatusDisabled);
801 setPortStatus(port_index, kPortStatusActive);
802
803 assert(port_index == kPortIndexOutput);
804
805 BufferList *obuffers = &mBuffers.editItemAt(kPortIndexOutput);
806 while (!obuffers->empty()) {
807 IOMX::buffer_id buffer = *obuffers->begin();
808 obuffers->erase(obuffers->begin());
809
810 status_t err = mClient->fillBuffer(mNode, buffer);
811 assert(err == NO_ERROR);
812 }
813
814 break;
815 }
816
817 case OMX_CommandFlush: {
818 OMX_U32 port_index = data;
819 LOGV("Port %ld flush complete.", port_index);
820 assert(getPortStatus(port_index) == kPortStatusFlushing);
821
822 setPortStatus(port_index, kPortStatusActive);
823 BufferList *buffers = &mBuffers.editItemAt(port_index);
824 while (!buffers->empty()) {
825 IOMX::buffer_id buffer = *buffers->begin();
826 buffers->erase(buffers->begin());
827
828 if (port_index == kPortIndexInput) {
829 postEmptyBufferDone(buffer);
830 } else {
831 postInitialFillBuffer(buffer);
832 }
833 }
834 break;
835 }
836
837 default:
838 break;
839 }
840}
841
842void OMXDecoder::onEventPortSettingsChanged(OMX_U32 port_index) {
843 assert(getPortStatus(port_index) == kPortStatusActive);
844 setPortStatus(port_index, kPortStatusDisabled);
845
846 status_t err =
847 mOMX->send_command(mNode, OMX_CommandPortDisable, port_index);
848 assert(err == NO_ERROR);
849}
850
851void OMXDecoder::onStateChanged(OMX_STATETYPE to) {
852 if (mState == OMX_StateLoaded) {
853 assert(to == OMX_StateIdle);
854
855 mState = to;
856
857 status_t err =
858 mOMX->send_command(mNode, OMX_CommandStateSet, OMX_StateExecuting);
859 assert(err == NO_ERROR);
860 } else if (mState == OMX_StateIdle) {
861 if (to == OMX_StateExecuting) {
862 mState = to;
863
864 BufferList *ibuffers = &mBuffers.editItemAt(kPortIndexInput);
865 while (!ibuffers->empty()) {
866 IOMX::buffer_id buffer = *ibuffers->begin();
867 ibuffers->erase(ibuffers->begin());
868
869 postEmptyBufferDone(buffer);
870 }
871
872 BufferList *obuffers = &mBuffers.editItemAt(kPortIndexOutput);
873 while (!obuffers->empty()) {
874 IOMX::buffer_id buffer = *obuffers->begin();
875 obuffers->erase(obuffers->begin());
876
877 postInitialFillBuffer(buffer);
878 }
879 } else {
880 assert(to == OMX_StateLoaded);
881
882 mState = to;
883
884 setPortStatus(kPortIndexInput, kPortStatusActive);
885 setPortStatus(kPortIndexOutput, kPortStatusActive);
886 }
887 } else if (mState == OMX_StateExecuting) {
888 assert(to == OMX_StateIdle);
889
890 mState = to;
891
892 LOGV("Executing->Idle complete, initiating Idle->Loaded");
893 status_t err =
894 mClient->send_command(mNode, OMX_CommandStateSet, OMX_StateLoaded);
895 assert(err == NO_ERROR);
896
897 BufferList *ibuffers = &mBuffers.editItemAt(kPortIndexInput);
898 for (BufferList::iterator it = ibuffers->begin();
899 it != ibuffers->end(); ++it) {
900 freeInputBuffer(*it);
901 }
902 ibuffers->clear();
903
904 BufferList *obuffers = &mBuffers.editItemAt(kPortIndexOutput);
905 for (BufferList::iterator it = obuffers->begin();
906 it != obuffers->end(); ++it) {
907 freeOutputBuffer(*it);
908 }
909 obuffers->clear();
910 }
911}
912
913void OMXDecoder::initiateShutdown() {
914 Mutex::Autolock autoLock(mLock);
915
916 if (mShutdownInitiated) {
917 return;
918 }
919
920 if (mState == OMX_StateLoaded) {
921 return;
922 }
923
924 assert(mState == OMX_StateExecuting);
925
926 mShutdownInitiated = true;
927
928 status_t err =
929 mClient->send_command(mNode, OMX_CommandStateSet, OMX_StateIdle);
930 assert(err == NO_ERROR);
931
932 setPortStatus(kPortIndexInput, kPortStatusShutdown);
933 setPortStatus(kPortIndexOutput, kPortStatusShutdown);
934}
935
936void OMXDecoder::setPortStatus(OMX_U32 port_index, PortStatus status) {
937 int shift = 2 * port_index;
938
939 mPortStatusMask &= ~(3 << shift);
940 mPortStatusMask |= status << shift;
941}
942
943OMXDecoder::PortStatus OMXDecoder::getPortStatus(
944 OMX_U32 port_index) const {
945 int shift = 2 * port_index;
946
947 return static_cast<PortStatus>((mPortStatusMask >> shift) & 3);
948}
949
950void OMXDecoder::onEmptyBufferDone(IOMX::buffer_id buffer) {
951 LOGV("[%s] onEmptyBufferDone (%p)", mComponentName, buffer);
952
953 status_t err;
954 switch (getPortStatus(kPortIndexInput)) {
955 case kPortStatusDisabled:
956 freeInputBuffer(buffer);
957 err = NO_ERROR;
958 break;
959
960 case kPortStatusShutdown:
961 LOGV("We're shutting down, enqueue INPUT buffer %p.", buffer);
962 mBuffers.editItemAt(kPortIndexInput).push_back(buffer);
963 err = NO_ERROR;
964 break;
965
966 case kPortStatusFlushing:
967 LOGV("We're currently flushing, enqueue INPUT buffer %p.", buffer);
968 mBuffers.editItemAt(kPortIndexInput).push_back(buffer);
969 err = NO_ERROR;
970 break;
971
972 default:
973 onRealEmptyBufferDone(buffer);
974 err = NO_ERROR;
975 break;
976 }
977 assert(err == NO_ERROR);
978}
979
980void OMXDecoder::onFillBufferDone(const omx_message &msg) {
981 IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
982
983 LOGV("[%s] onFillBufferDone (%p)", mComponentName, buffer);
984
985 status_t err;
986 switch (getPortStatus(kPortIndexOutput)) {
987 case kPortStatusDisabled:
988 freeOutputBuffer(buffer);
989 err = NO_ERROR;
990 break;
991 case kPortStatusShutdown:
992 LOGV("We're shutting down, enqueue OUTPUT buffer %p.", buffer);
993 mBuffers.editItemAt(kPortIndexOutput).push_back(buffer);
994 err = NO_ERROR;
995 break;
996
997 case kPortStatusFlushing:
998 LOGV("We're currently flushing, enqueue OUTPUT buffer %p.", buffer);
999 mBuffers.editItemAt(kPortIndexOutput).push_back(buffer);
1000 err = NO_ERROR;
1001 break;
1002
1003 default:
1004 {
1005 if (msg.type == omx_message::INITIAL_FILL_BUFFER) {
1006 err = mClient->fillBuffer(mNode, buffer);
1007 } else {
1008 LOGV("[%s] Filled OUTPUT buffer %p, flags=0x%08lx.",
1009 mComponentName, buffer, msg.u.extended_buffer_data.flags);
1010
1011 onRealFillBufferDone(msg);
1012 err = NO_ERROR;
1013 }
1014 break;
1015 }
1016 }
1017 assert(err == NO_ERROR);
1018}
1019
1020void OMXDecoder::onRealEmptyBufferDone(IOMX::buffer_id buffer) {
1021 if (mReachedEndOfInput) {
1022 // We already sent the EOS notification.
1023
1024 mBuffers.editItemAt(kPortIndexInput).push_back(buffer);
1025 return;
1026 }
1027
1028 const sp<IMemory> mem = mBufferMap.valueFor(buffer);
1029 assert(mem.get() != NULL);
1030
1031 static const uint8_t kNALStartCode[4] = { 0x00, 0x00, 0x00, 0x01 };
1032
1033 if (mCodecSpecificDataIterator != mCodecSpecificData.end()) {
1034 List<CodecSpecificData>::iterator it = mCodecSpecificDataIterator;
1035
1036 size_t range_length = 0;
1037
1038 if (!strcmp(mComponentName, "OMX.qcom.video.decoder.avc")) {
1039 assert((*mCodecSpecificDataIterator).size + 4 <= mem->size());
1040
1041 memcpy(mem->pointer(), kNALStartCode, 4);
1042
1043 memcpy((uint8_t *)mem->pointer() + 4, (*it).data, (*it).size);
1044 range_length = (*it).size + 4;
1045 } else {
1046 assert((*mCodecSpecificDataIterator).size <= mem->size());
1047
1048 memcpy((uint8_t *)mem->pointer(), (*it).data, (*it).size);
1049 range_length = (*it).size;
1050 }
1051
1052 ++mCodecSpecificDataIterator;
1053
1054 status_t err = mClient->emptyBuffer(
1055 mNode, buffer, 0, range_length,
1056 OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG,
1057 0);
1058
1059 assert(err == NO_ERROR);
1060
1061 return;
1062 }
1063
1064 LOGV("[%s] waiting for input data", mComponentName);
1065
1066 MediaBuffer *input_buffer;
1067 for (;;) {
1068 status_t err;
1069
1070 if (mSeeking) {
1071 MediaSource::ReadOptions options;
1072 options.setSeekTo(mSeekTimeUs);
1073
1074 mSeeking = false;
1075
1076 err = mSource->read(&input_buffer, &options);
1077 } else {
1078 err = mSource->read(&input_buffer);
1079 }
1080 assert((err == OK && input_buffer != NULL)
1081 || (err != OK && input_buffer == NULL));
1082
1083 if (err == ERROR_END_OF_STREAM) {
1084 LOGE("[%s] Reached end of stream.", mComponentName);
1085 mReachedEndOfInput = true;
1086 } else {
1087 LOGV("[%s] got input data", mComponentName);
1088 }
1089
1090 if (err != OK) {
1091 status_t err2 = mClient->emptyBuffer(
1092 mNode, buffer, 0, 0, OMX_BUFFERFLAG_EOS, 0);
1093
1094 assert(err2 == NO_ERROR);
1095 return;
1096 }
1097
1098 if (mSeeking) {
1099 input_buffer->release();
1100 input_buffer = NULL;
1101
1102 continue;
1103 }
1104
1105 break;
1106 }
1107
1108 const uint8_t *src_data =
1109 (const uint8_t *)input_buffer->data() + input_buffer->range_offset();
1110
1111 size_t src_length = input_buffer->range_length();
1112 if (src_length == 195840) {
1113 // When feeding the output of the AVC decoder into the H263 encoder,
1114 // buffer sizes mismatch if width % 16 != 0 || height % 16 != 0.
1115 src_length = 194400; // XXX HACK
1116 } else if (src_length == 115200) {
1117 src_length = 114240; // XXX HACK
1118 }
1119
1120 if (src_length > mem->size()) {
1121 LOGE("src_length=%d > mem->size() = %d\n",
1122 src_length, mem->size());
1123 }
1124
1125 assert(src_length <= mem->size());
1126 memcpy(mem->pointer(), src_data, src_length);
1127
1128 OMX_U32 flags = 0;
1129 if (!mIsMP3) {
1130 // Only mp3 audio data may be streamed, all other data is assumed
1131 // to be fed into the decoder at frame boundaries.
1132 flags |= OMX_BUFFERFLAG_ENDOFFRAME;
1133 }
1134
1135 int32_t units, scale;
1136 bool success =
1137 input_buffer->meta_data()->findInt32(kKeyTimeUnits, &units);
1138
1139 success = success &&
1140 input_buffer->meta_data()->findInt32(kKeyTimeScale, &scale);
1141
1142 OMX_TICKS timestamp = 0;
1143
1144 if (success) {
1145 // XXX units should be microseconds but PV treats them as milliseconds.
1146 timestamp = ((OMX_S64)units * 1000) / scale;
1147 }
1148
1149 input_buffer->release();
1150 input_buffer = NULL;
1151
1152 LOGV("[%s] Calling EmptyBuffer on buffer %p",
1153 mComponentName, buffer);
1154
1155 status_t err2 = mClient->emptyBuffer(
1156 mNode, buffer, 0, src_length, flags, timestamp);
1157 assert(err2 == OK);
1158}
1159
1160void OMXDecoder::onRealFillBufferDone(const omx_message &msg) {
1161 OMXMediaBuffer *media_buffer =
1162 mMediaBufferMap.valueFor(msg.u.extended_buffer_data.buffer);
1163
1164 media_buffer->set_range(
1165 msg.u.extended_buffer_data.range_offset,
1166 msg.u.extended_buffer_data.range_length);
1167
1168 media_buffer->add_ref();
1169
1170 media_buffer->meta_data()->clear();
1171
1172 media_buffer->meta_data()->setInt32(
1173 kKeyTimeUnits, msg.u.extended_buffer_data.timestamp);
1174 media_buffer->meta_data()->setInt32(kKeyTimeScale, 1000);
1175
1176 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) {
1177 media_buffer->meta_data()->setInt32(kKeyIsSyncFrame, true);
1178 }
1179
1180 media_buffer->meta_data()->setPointer(
1181 kKeyPlatformPrivate,
1182 msg.u.extended_buffer_data.platform_private);
1183
1184 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_EOS) {
1185 mErrorCondition = ERROR_END_OF_STREAM;
1186 }
1187
1188 mOutputBuffers.push_back(media_buffer);
1189 mOutputBufferAvailable.signal();
1190}
1191
1192void OMXDecoder::signalBufferReturned(MediaBuffer *_buffer) {
1193 Mutex::Autolock autoLock(mLock);
1194
1195 OMXMediaBuffer *media_buffer = static_cast<OMXMediaBuffer *>(_buffer);
1196
1197 IOMX::buffer_id buffer = media_buffer->buffer_id();
1198
1199 PortStatus outputStatus = getPortStatus(kPortIndexOutput);
1200 if (outputStatus == kPortStatusShutdown
1201 || outputStatus == kPortStatusFlushing) {
1202 mBuffers.editItemAt(kPortIndexOutput).push_back(buffer);
1203 } else {
1204 LOGV("[%s] Calling FillBuffer on buffer %p.", mComponentName, buffer);
1205
1206 status_t err = mClient->fillBuffer(mNode, buffer);
1207 assert(err == NO_ERROR);
1208 }
1209}
1210
1211void OMXDecoder::freeInputBuffer(IOMX::buffer_id buffer) {
1212 LOGV("freeInputBuffer %p", buffer);
1213
1214 status_t err = mOMX->free_buffer(mNode, kPortIndexInput, buffer);
1215 assert(err == NO_ERROR);
1216 mBufferMap.removeItem(buffer);
1217
1218 LOGV("freeInputBuffer %p done", buffer);
1219}
1220
1221void OMXDecoder::freeOutputBuffer(IOMX::buffer_id buffer) {
1222 LOGV("freeOutputBuffer %p", buffer);
1223
1224 status_t err = mOMX->free_buffer(mNode, kPortIndexOutput, buffer);
1225 assert(err == NO_ERROR);
1226 mBufferMap.removeItem(buffer);
1227
1228 ssize_t index = mMediaBufferMap.indexOfKey(buffer);
1229 assert(index >= 0);
1230 MediaBuffer *mbuffer = mMediaBufferMap.editValueAt(index);
1231 mMediaBufferMap.removeItemsAt(index);
1232 mbuffer->setObserver(NULL);
1233 mbuffer->release();
1234 mbuffer = NULL;
1235
1236 LOGV("freeOutputBuffer %p done", buffer);
1237}
1238
1239void OMXDecoder::dumpPortDefinition(OMX_U32 port_index) {
1240 OMX_PARAM_PORTDEFINITIONTYPE def;
1241 def.nSize = sizeof(def);
1242 def.nVersion.s.nVersionMajor = 1;
1243 def.nVersion.s.nVersionMinor = 1;
1244 def.nPortIndex = port_index;
1245
1246 status_t err = mOMX->get_parameter(
1247 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1248 assert(err == NO_ERROR);
1249
1250 LOGI("DumpPortDefinition on port %ld", port_index);
1251 LOGI("nBufferCountActual = %ld, nBufferCountMin = %ld, nBufferSize = %ld",
1252 def.nBufferCountActual, def.nBufferCountMin, def.nBufferSize);
1253 switch (def.eDomain) {
1254 case OMX_PortDomainAudio:
1255 {
1256 LOGI("eDomain = AUDIO");
1257
1258 if (port_index == kPortIndexOutput) {
1259 OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio;
1260 assert(audio_def->eEncoding == OMX_AUDIO_CodingPCM);
1261
1262 OMX_AUDIO_PARAM_PCMMODETYPE params;
1263 params.nSize = sizeof(params);
1264 params.nVersion.s.nVersionMajor = 1;
1265 params.nVersion.s.nVersionMinor = 1;
1266 params.nPortIndex = port_index;
1267
1268 err = mOMX->get_parameter(
1269 mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
1270 assert(err == OK);
1271
1272 assert(params.nChannels == 1 || params.bInterleaved);
1273 assert(params.eNumData == OMX_NumericalDataSigned);
1274 assert(params.nBitPerSample == 16);
1275 assert(params.ePCMMode == OMX_AUDIO_PCMModeLinear);
1276
1277 LOGI("nChannels = %ld, nSamplingRate = %ld",
1278 params.nChannels, params.nSamplingRate);
1279 }
1280
1281 break;
1282 }
1283
1284 case OMX_PortDomainVideo:
1285 {
1286 LOGI("eDomain = VIDEO");
1287
1288 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
1289 LOGI("nFrameWidth = %ld, nFrameHeight = %ld, nStride = %ld, "
1290 "nSliceHeight = %ld",
1291 video_def->nFrameWidth, video_def->nFrameHeight,
1292 video_def->nStride, video_def->nSliceHeight);
1293 LOGI("nBitrate = %ld, xFrameRate = %.2f",
1294 video_def->nBitrate, video_def->xFramerate / 65536.0f);
1295 LOGI("eCompressionFormat = %d, eColorFormat = %d",
1296 video_def->eCompressionFormat, video_def->eColorFormat);
1297
1298 break;
1299 }
1300
1301 default:
1302 LOGI("eDomain = UNKNOWN");
1303 break;
1304 }
1305}
1306
1307void OMXDecoder::postStart() {
1308 omx_message msg;
1309 msg.type = omx_message::START;
1310 postMessage(msg);
1311}
1312
1313void OMXDecoder::postEmptyBufferDone(IOMX::buffer_id buffer) {
1314 omx_message msg;
1315 msg.type = omx_message::EMPTY_BUFFER_DONE;
1316 msg.u.buffer_data.node = mNode;
1317 msg.u.buffer_data.buffer = buffer;
1318 postMessage(msg);
1319}
1320
1321void OMXDecoder::postInitialFillBuffer(IOMX::buffer_id buffer) {
1322 omx_message msg;
1323 msg.type = omx_message::INITIAL_FILL_BUFFER;
1324 msg.u.buffer_data.node = mNode;
1325 msg.u.buffer_data.buffer = buffer;
1326 postMessage(msg);
1327}
1328
1329} // namespace android