1 /*
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 "OMXCodec"
19 #include <utils/Log.h>
20
21 #include "include/AACEncoder.h"
22
23 #include "include/ESDS.h"
24
25 #include <binder/IServiceManager.h>
26 #include <binder/MemoryDealer.h>
27 #include <binder/ProcessState.h>
28 #include <HardwareAPI.h>
29 #include <media/stagefright/foundation/ADebug.h>
30 #include <media/IMediaPlayerService.h>
31 #include <media/stagefright/MediaBuffer.h>
32 #include <media/stagefright/MediaBufferGroup.h>
33 #include <media/stagefright/MediaDefs.h>
34 #include <media/stagefright/MediaCodecList.h>
35 #include <media/stagefright/MediaExtractor.h>
36 #include <media/stagefright/MetaData.h>
37 #include <media/stagefright/OMXCodec.h>
38 #include <media/stagefright/Utils.h>
39 #include <media/stagefright/SkipCutBuffer.h>
40 #include <utils/Vector.h>
41
42 #include <OMX_Audio.h>
43 #include <OMX_Component.h>
44
45 #include "include/avc_utils.h"
46
47 namespace android {
48
49 // Treat time out as an error if we have not received any output
50 // buffers after 3 seconds.
51 const static int64_t kBufferFilledEventTimeOutNs = 3000000000LL;
52
53 // OMX Spec defines less than 50 color formats. If the query for
54 // color format is executed for more than kMaxColorFormatSupported,
55 // the query will fail to avoid looping forever.
56 // 1000 is more than enough for us to tell whether the omx
57 // component in question is buggy or not.
58 const static uint32_t kMaxColorFormatSupported = 1000;
59
60 #define FACTORY_CREATE_ENCODER(name) \
61 static sp<MediaSource> Make##name(const sp<MediaSource> &source, const sp<MetaData> &meta) { \
62 return new name(source, meta); \
63 }
64
65 #define FACTORY_REF(name) { #name, Make##name },
66
FACTORY_CREATE_ENCODER(AACEncoder)67 FACTORY_CREATE_ENCODER(AACEncoder)
68
69 static sp<MediaSource> InstantiateSoftwareEncoder(
70 const char *name, const sp<MediaSource> &source,
71 const sp<MetaData> &meta) {
72 struct FactoryInfo {
73 const char *name;
74 sp<MediaSource> (*CreateFunc)(const sp<MediaSource> &, const sp<MetaData> &);
75 };
76
77 static const FactoryInfo kFactoryInfo[] = {
78 FACTORY_REF(AACEncoder)
79 };
80 for (size_t i = 0;
81 i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) {
82 if (!strcmp(name, kFactoryInfo[i].name)) {
83 return (*kFactoryInfo[i].CreateFunc)(source, meta);
84 }
85 }
86
87 return NULL;
88 }
89
90 #undef FACTORY_CREATE_ENCODER
91 #undef FACTORY_REF
92
93 #define CODEC_LOGI(x, ...) ALOGI("[%s] "x, mComponentName, ##__VA_ARGS__)
94 #define CODEC_LOGV(x, ...) ALOGV("[%s] "x, mComponentName, ##__VA_ARGS__)
95 #define CODEC_LOGE(x, ...) ALOGE("[%s] "x, mComponentName, ##__VA_ARGS__)
96
97 struct OMXCodecObserver : public BnOMXObserver {
OMXCodecObserverandroid::OMXCodecObserver98 OMXCodecObserver() {
99 }
100
setCodecandroid::OMXCodecObserver101 void setCodec(const sp<OMXCodec> &target) {
102 mTarget = target;
103 }
104
105 // from IOMXObserver
onMessageandroid::OMXCodecObserver106 virtual void onMessage(const omx_message &msg) {
107 sp<OMXCodec> codec = mTarget.promote();
108
109 if (codec.get() != NULL) {
110 Mutex::Autolock autoLock(codec->mLock);
111 codec->on_message(msg);
112 codec.clear();
113 }
114 }
115
116 protected:
~OMXCodecObserverandroid::OMXCodecObserver117 virtual ~OMXCodecObserver() {}
118
119 private:
120 wp<OMXCodec> mTarget;
121
122 OMXCodecObserver(const OMXCodecObserver &);
123 OMXCodecObserver &operator=(const OMXCodecObserver &);
124 };
125
126 template<class T>
InitOMXParams(T * params)127 static void InitOMXParams(T *params) {
128 params->nSize = sizeof(T);
129 params->nVersion.s.nVersionMajor = 1;
130 params->nVersion.s.nVersionMinor = 0;
131 params->nVersion.s.nRevision = 0;
132 params->nVersion.s.nStep = 0;
133 }
134
IsSoftwareCodec(const char * componentName)135 static bool IsSoftwareCodec(const char *componentName) {
136 if (!strncmp("OMX.google.", componentName, 11)) {
137 return true;
138 }
139
140 if (!strncmp("OMX.", componentName, 4)) {
141 return false;
142 }
143
144 return true;
145 }
146
147 // A sort order in which OMX software codecs are first, followed
148 // by other (non-OMX) software codecs, followed by everything else.
CompareSoftwareCodecsFirst(const String8 * elem1,const String8 * elem2)149 static int CompareSoftwareCodecsFirst(
150 const String8 *elem1, const String8 *elem2) {
151 bool isOMX1 = !strncmp(elem1->string(), "OMX.", 4);
152 bool isOMX2 = !strncmp(elem2->string(), "OMX.", 4);
153
154 bool isSoftwareCodec1 = IsSoftwareCodec(elem1->string());
155 bool isSoftwareCodec2 = IsSoftwareCodec(elem2->string());
156
157 if (isSoftwareCodec1) {
158 if (!isSoftwareCodec2) { return -1; }
159
160 if (isOMX1) {
161 if (isOMX2) { return 0; }
162
163 return -1;
164 } else {
165 if (isOMX2) { return 0; }
166
167 return 1;
168 }
169
170 return -1;
171 }
172
173 if (isSoftwareCodec2) {
174 return 1;
175 }
176
177 return 0;
178 }
179
180 // static
findMatchingCodecs(const char * mime,bool createEncoder,const char * matchComponentName,uint32_t flags,Vector<String8> * matchingCodecs,Vector<uint32_t> * matchingCodecQuirks)181 void OMXCodec::findMatchingCodecs(
182 const char *mime,
183 bool createEncoder, const char *matchComponentName,
184 uint32_t flags,
185 Vector<String8> *matchingCodecs,
186 Vector<uint32_t> *matchingCodecQuirks) {
187 matchingCodecs->clear();
188
189 if (matchingCodecQuirks) {
190 matchingCodecQuirks->clear();
191 }
192
193 const MediaCodecList *list = MediaCodecList::getInstance();
194 if (list == NULL) {
195 return;
196 }
197
198 size_t index = 0;
199 for (;;) {
200 ssize_t matchIndex =
201 list->findCodecByType(mime, createEncoder, index);
202
203 if (matchIndex < 0) {
204 break;
205 }
206
207 index = matchIndex + 1;
208
209 const char *componentName = list->getCodecName(matchIndex);
210
211 // If a specific codec is requested, skip the non-matching ones.
212 if (matchComponentName && strcmp(componentName, matchComponentName)) {
213 continue;
214 }
215
216 // When requesting software-only codecs, only push software codecs
217 // When requesting hardware-only codecs, only push hardware codecs
218 // When there is request neither for software-only nor for
219 // hardware-only codecs, push all codecs
220 if (((flags & kSoftwareCodecsOnly) && IsSoftwareCodec(componentName)) ||
221 ((flags & kHardwareCodecsOnly) && !IsSoftwareCodec(componentName)) ||
222 (!(flags & (kSoftwareCodecsOnly | kHardwareCodecsOnly)))) {
223
224 matchingCodecs->push(String8(componentName));
225
226 if (matchingCodecQuirks) {
227 matchingCodecQuirks->push(getComponentQuirks(list, matchIndex));
228 }
229 }
230 }
231
232 if (flags & kPreferSoftwareCodecs) {
233 matchingCodecs->sort(CompareSoftwareCodecsFirst);
234 }
235 }
236
237 // static
getComponentQuirks(const MediaCodecList * list,size_t index)238 uint32_t OMXCodec::getComponentQuirks(
239 const MediaCodecList *list, size_t index) {
240 uint32_t quirks = 0;
241 if (list->codecHasQuirk(
242 index, "requires-allocate-on-input-ports")) {
243 quirks |= kRequiresAllocateBufferOnInputPorts;
244 }
245 if (list->codecHasQuirk(
246 index, "requires-allocate-on-output-ports")) {
247 quirks |= kRequiresAllocateBufferOnOutputPorts;
248 }
249 if (list->codecHasQuirk(
250 index, "output-buffers-are-unreadable")) {
251 quirks |= kOutputBuffersAreUnreadable;
252 }
253
254 return quirks;
255 }
256
257 // static
findCodecQuirks(const char * componentName,uint32_t * quirks)258 bool OMXCodec::findCodecQuirks(const char *componentName, uint32_t *quirks) {
259 const MediaCodecList *list = MediaCodecList::getInstance();
260
261 if (list == NULL) {
262 return false;
263 }
264
265 ssize_t index = list->findCodecByName(componentName);
266
267 if (index < 0) {
268 return false;
269 }
270
271 *quirks = getComponentQuirks(list, index);
272
273 return true;
274 }
275
276 // static
Create(const sp<IOMX> & omx,const sp<MetaData> & meta,bool createEncoder,const sp<MediaSource> & source,const char * matchComponentName,uint32_t flags,const sp<ANativeWindow> & nativeWindow)277 sp<MediaSource> OMXCodec::Create(
278 const sp<IOMX> &omx,
279 const sp<MetaData> &meta, bool createEncoder,
280 const sp<MediaSource> &source,
281 const char *matchComponentName,
282 uint32_t flags,
283 const sp<ANativeWindow> &nativeWindow) {
284 int32_t requiresSecureBuffers;
285 if (source->getFormat()->findInt32(
286 kKeyRequiresSecureBuffers,
287 &requiresSecureBuffers)
288 && requiresSecureBuffers) {
289 flags |= kIgnoreCodecSpecificData;
290 flags |= kUseSecureInputBuffers;
291 }
292
293 const char *mime;
294 bool success = meta->findCString(kKeyMIMEType, &mime);
295 CHECK(success);
296
297 Vector<String8> matchingCodecs;
298 Vector<uint32_t> matchingCodecQuirks;
299 findMatchingCodecs(
300 mime, createEncoder, matchComponentName, flags,
301 &matchingCodecs, &matchingCodecQuirks);
302
303 if (matchingCodecs.isEmpty()) {
304 return NULL;
305 }
306
307 sp<OMXCodecObserver> observer = new OMXCodecObserver;
308 IOMX::node_id node = 0;
309
310 for (size_t i = 0; i < matchingCodecs.size(); ++i) {
311 const char *componentNameBase = matchingCodecs[i].string();
312 uint32_t quirks = matchingCodecQuirks[i];
313 const char *componentName = componentNameBase;
314
315 AString tmp;
316 if (flags & kUseSecureInputBuffers) {
317 tmp = componentNameBase;
318 tmp.append(".secure");
319
320 componentName = tmp.c_str();
321 }
322
323 if (createEncoder) {
324 sp<MediaSource> softwareCodec =
325 InstantiateSoftwareEncoder(componentName, source, meta);
326
327 if (softwareCodec != NULL) {
328 ALOGV("Successfully allocated software codec '%s'", componentName);
329
330 return softwareCodec;
331 }
332 }
333
334 ALOGV("Attempting to allocate OMX node '%s'", componentName);
335
336 if (!createEncoder
337 && (quirks & kOutputBuffersAreUnreadable)
338 && (flags & kClientNeedsFramebuffer)) {
339 if (strncmp(componentName, "OMX.SEC.", 8)) {
340 // For OMX.SEC.* decoders we can enable a special mode that
341 // gives the client access to the framebuffer contents.
342
343 ALOGW("Component '%s' does not give the client access to "
344 "the framebuffer contents. Skipping.",
345 componentName);
346
347 continue;
348 }
349 }
350
351 status_t err = omx->allocateNode(componentName, observer, &node);
352 if (err == OK) {
353 ALOGV("Successfully allocated OMX node '%s'", componentName);
354
355 sp<OMXCodec> codec = new OMXCodec(
356 omx, node, quirks, flags,
357 createEncoder, mime, componentName,
358 source, nativeWindow);
359
360 observer->setCodec(codec);
361
362 err = codec->configureCodec(meta);
363
364 if (err == OK) {
365 if (!strcmp("OMX.Nvidia.mpeg2v.decode", componentName)) {
366 codec->mFlags |= kOnlySubmitOneInputBufferAtOneTime;
367 }
368
369 return codec;
370 }
371
372 ALOGV("Failed to configure codec '%s'", componentName);
373 }
374 }
375
376 return NULL;
377 }
378
parseAVCCodecSpecificData(const void * data,size_t size,unsigned * profile,unsigned * level)379 status_t OMXCodec::parseAVCCodecSpecificData(
380 const void *data, size_t size,
381 unsigned *profile, unsigned *level) {
382 const uint8_t *ptr = (const uint8_t *)data;
383
384 // verify minimum size and configurationVersion == 1.
385 if (size < 7 || ptr[0] != 1) {
386 return ERROR_MALFORMED;
387 }
388
389 *profile = ptr[1];
390 *level = ptr[3];
391
392 // There is decodable content out there that fails the following
393 // assertion, let's be lenient for now...
394 // CHECK((ptr[4] >> 2) == 0x3f); // reserved
395
396 size_t lengthSize = 1 + (ptr[4] & 3);
397
398 // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
399 // violates it...
400 // CHECK((ptr[5] >> 5) == 7); // reserved
401
402 size_t numSeqParameterSets = ptr[5] & 31;
403
404 ptr += 6;
405 size -= 6;
406
407 for (size_t i = 0; i < numSeqParameterSets; ++i) {
408 if (size < 2) {
409 return ERROR_MALFORMED;
410 }
411
412 size_t length = U16_AT(ptr);
413
414 ptr += 2;
415 size -= 2;
416
417 if (size < length) {
418 return ERROR_MALFORMED;
419 }
420
421 addCodecSpecificData(ptr, length);
422
423 ptr += length;
424 size -= length;
425 }
426
427 if (size < 1) {
428 return ERROR_MALFORMED;
429 }
430
431 size_t numPictureParameterSets = *ptr;
432 ++ptr;
433 --size;
434
435 for (size_t i = 0; i < numPictureParameterSets; ++i) {
436 if (size < 2) {
437 return ERROR_MALFORMED;
438 }
439
440 size_t length = U16_AT(ptr);
441
442 ptr += 2;
443 size -= 2;
444
445 if (size < length) {
446 return ERROR_MALFORMED;
447 }
448
449 addCodecSpecificData(ptr, length);
450
451 ptr += length;
452 size -= length;
453 }
454
455 return OK;
456 }
457
configureCodec(const sp<MetaData> & meta)458 status_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
459 ALOGV("configureCodec protected=%d",
460 (mFlags & kEnableGrallocUsageProtected) ? 1 : 0);
461
462 if (!(mFlags & kIgnoreCodecSpecificData)) {
463 uint32_t type;
464 const void *data;
465 size_t size;
466 if (meta->findData(kKeyESDS, &type, &data, &size)) {
467 ESDS esds((const char *)data, size);
468 CHECK_EQ(esds.InitCheck(), (status_t)OK);
469
470 const void *codec_specific_data;
471 size_t codec_specific_data_size;
472 esds.getCodecSpecificInfo(
473 &codec_specific_data, &codec_specific_data_size);
474
475 addCodecSpecificData(
476 codec_specific_data, codec_specific_data_size);
477 } else if (meta->findData(kKeyAVCC, &type, &data, &size)) {
478 // Parse the AVCDecoderConfigurationRecord
479
480 unsigned profile, level;
481 status_t err;
482 if ((err = parseAVCCodecSpecificData(
483 data, size, &profile, &level)) != OK) {
484 ALOGE("Malformed AVC codec specific data.");
485 return err;
486 }
487
488 CODEC_LOGI(
489 "AVC profile = %u (%s), level = %u",
490 profile, AVCProfileToString(profile), level);
491 } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
492 addCodecSpecificData(data, size);
493
494 CHECK(meta->findData(kKeyVorbisBooks, &type, &data, &size));
495 addCodecSpecificData(data, size);
496 }
497 }
498
499 int32_t bitRate = 0;
500 if (mIsEncoder) {
501 CHECK(meta->findInt32(kKeyBitRate, &bitRate));
502 }
503 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mMIME)) {
504 setAMRFormat(false /* isWAMR */, bitRate);
505 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mMIME)) {
506 setAMRFormat(true /* isWAMR */, bitRate);
507 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mMIME)) {
508 int32_t numChannels, sampleRate, aacProfile;
509 CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
510 CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
511
512 if (!meta->findInt32(kKeyAACProfile, &aacProfile)) {
513 aacProfile = OMX_AUDIO_AACObjectNull;
514 }
515
516 int32_t isADTS;
517 if (!meta->findInt32(kKeyIsADTS, &isADTS)) {
518 isADTS = false;
519 }
520
521 status_t err = setAACFormat(numChannels, sampleRate, bitRate, aacProfile, isADTS);
522 if (err != OK) {
523 CODEC_LOGE("setAACFormat() failed (err = %d)", err);
524 return err;
525 }
526 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_ALAW, mMIME)
527 || !strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_MLAW, mMIME)) {
528 // These are PCM-like formats with a fixed sample rate but
529 // a variable number of channels.
530
531 int32_t numChannels;
532 CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
533
534 setG711Format(numChannels);
535 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, mMIME)) {
536 CHECK(!mIsEncoder);
537
538 int32_t numChannels, sampleRate;
539 CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
540 CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
541
542 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
543 }
544
545 if (!strncasecmp(mMIME, "video/", 6)) {
546
547 if (mIsEncoder) {
548 setVideoInputFormat(mMIME, meta);
549 } else {
550 int32_t width, height;
551 bool success = meta->findInt32(kKeyWidth, &width);
552 success = success && meta->findInt32(kKeyHeight, &height);
553 CHECK(success);
554 status_t err = setVideoOutputFormat(
555 mMIME, width, height);
556
557 if (err != OK) {
558 return err;
559 }
560 }
561 }
562
563 int32_t maxInputSize;
564 if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
565 setMinBufferSize(kPortIndexInput, (OMX_U32)maxInputSize);
566 }
567
568 initOutputFormat(meta);
569
570 if ((mFlags & kClientNeedsFramebuffer)
571 && !strncmp(mComponentName, "OMX.SEC.", 8)) {
572 OMX_INDEXTYPE index;
573
574 status_t err =
575 mOMX->getExtensionIndex(
576 mNode,
577 "OMX.SEC.index.ThumbnailMode",
578 &index);
579
580 if (err != OK) {
581 return err;
582 }
583
584 OMX_BOOL enable = OMX_TRUE;
585 err = mOMX->setConfig(mNode, index, &enable, sizeof(enable));
586
587 if (err != OK) {
588 CODEC_LOGE("setConfig('OMX.SEC.index.ThumbnailMode') "
589 "returned error 0x%08x", err);
590
591 return err;
592 }
593
594 mQuirks &= ~kOutputBuffersAreUnreadable;
595 }
596
597 if (mNativeWindow != NULL
598 && !mIsEncoder
599 && !strncasecmp(mMIME, "video/", 6)
600 && !strncmp(mComponentName, "OMX.", 4)) {
601 status_t err = initNativeWindow();
602 if (err != OK) {
603 return err;
604 }
605 }
606
607 return OK;
608 }
609
setMinBufferSize(OMX_U32 portIndex,OMX_U32 size)610 void OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) {
611 OMX_PARAM_PORTDEFINITIONTYPE def;
612 InitOMXParams(&def);
613 def.nPortIndex = portIndex;
614
615 status_t err = mOMX->getParameter(
616 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
617 CHECK_EQ(err, (status_t)OK);
618
619 if ((portIndex == kPortIndexInput && (mQuirks & kInputBufferSizesAreBogus))
620 || (def.nBufferSize < size)) {
621 def.nBufferSize = size;
622 }
623
624 err = mOMX->setParameter(
625 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
626 CHECK_EQ(err, (status_t)OK);
627
628 err = mOMX->getParameter(
629 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
630 CHECK_EQ(err, (status_t)OK);
631
632 // Make sure the setting actually stuck.
633 if (portIndex == kPortIndexInput
634 && (mQuirks & kInputBufferSizesAreBogus)) {
635 CHECK_EQ(def.nBufferSize, size);
636 } else {
637 CHECK(def.nBufferSize >= size);
638 }
639 }
640
setVideoPortFormatType(OMX_U32 portIndex,OMX_VIDEO_CODINGTYPE compressionFormat,OMX_COLOR_FORMATTYPE colorFormat)641 status_t OMXCodec::setVideoPortFormatType(
642 OMX_U32 portIndex,
643 OMX_VIDEO_CODINGTYPE compressionFormat,
644 OMX_COLOR_FORMATTYPE colorFormat) {
645 OMX_VIDEO_PARAM_PORTFORMATTYPE format;
646 InitOMXParams(&format);
647 format.nPortIndex = portIndex;
648 format.nIndex = 0;
649 bool found = false;
650
651 OMX_U32 index = 0;
652 for (;;) {
653 format.nIndex = index;
654 status_t err = mOMX->getParameter(
655 mNode, OMX_IndexParamVideoPortFormat,
656 &format, sizeof(format));
657
658 if (err != OK) {
659 return err;
660 }
661
662 // The following assertion is violated by TI's video decoder.
663 // CHECK_EQ(format.nIndex, index);
664
665 #if 1
666 CODEC_LOGV("portIndex: %ld, index: %ld, eCompressionFormat=%d eColorFormat=%d",
667 portIndex,
668 index, format.eCompressionFormat, format.eColorFormat);
669 #endif
670
671 if (format.eCompressionFormat == compressionFormat
672 && format.eColorFormat == colorFormat) {
673 found = true;
674 break;
675 }
676
677 ++index;
678 if (index >= kMaxColorFormatSupported) {
679 CODEC_LOGE("color format %d or compression format %d is not supported",
680 colorFormat, compressionFormat);
681 return UNKNOWN_ERROR;
682 }
683 }
684
685 if (!found) {
686 return UNKNOWN_ERROR;
687 }
688
689 CODEC_LOGV("found a match.");
690 status_t err = mOMX->setParameter(
691 mNode, OMX_IndexParamVideoPortFormat,
692 &format, sizeof(format));
693
694 return err;
695 }
696
getFrameSize(OMX_COLOR_FORMATTYPE colorFormat,int32_t width,int32_t height)697 static size_t getFrameSize(
698 OMX_COLOR_FORMATTYPE colorFormat, int32_t width, int32_t height) {
699 switch (colorFormat) {
700 case OMX_COLOR_FormatYCbYCr:
701 case OMX_COLOR_FormatCbYCrY:
702 return width * height * 2;
703
704 case OMX_COLOR_FormatYUV420Planar:
705 case OMX_COLOR_FormatYUV420SemiPlanar:
706 case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
707 /*
708 * FIXME: For the Opaque color format, the frame size does not
709 * need to be (w*h*3)/2. It just needs to
710 * be larger than certain minimum buffer size. However,
711 * currently, this opaque foramt has been tested only on
712 * YUV420 formats. If that is changed, then we need to revisit
713 * this part in the future
714 */
715 case OMX_COLOR_FormatAndroidOpaque:
716 return (width * height * 3) / 2;
717
718 default:
719 CHECK(!"Should not be here. Unsupported color format.");
720 break;
721 }
722 }
723
findTargetColorFormat(const sp<MetaData> & meta,OMX_COLOR_FORMATTYPE * colorFormat)724 status_t OMXCodec::findTargetColorFormat(
725 const sp<MetaData>& meta, OMX_COLOR_FORMATTYPE *colorFormat) {
726 ALOGV("findTargetColorFormat");
727 CHECK(mIsEncoder);
728
729 *colorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
730 int32_t targetColorFormat;
731 if (meta->findInt32(kKeyColorFormat, &targetColorFormat)) {
732 *colorFormat = (OMX_COLOR_FORMATTYPE) targetColorFormat;
733 }
734
735 // Check whether the target color format is supported.
736 return isColorFormatSupported(*colorFormat, kPortIndexInput);
737 }
738
isColorFormatSupported(OMX_COLOR_FORMATTYPE colorFormat,int portIndex)739 status_t OMXCodec::isColorFormatSupported(
740 OMX_COLOR_FORMATTYPE colorFormat, int portIndex) {
741 ALOGV("isColorFormatSupported: %d", static_cast<int>(colorFormat));
742
743 // Enumerate all the color formats supported by
744 // the omx component to see whether the given
745 // color format is supported.
746 OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
747 InitOMXParams(&portFormat);
748 portFormat.nPortIndex = portIndex;
749 OMX_U32 index = 0;
750 portFormat.nIndex = index;
751 while (true) {
752 if (OMX_ErrorNone != mOMX->getParameter(
753 mNode, OMX_IndexParamVideoPortFormat,
754 &portFormat, sizeof(portFormat))) {
755 break;
756 }
757 // Make sure that omx component does not overwrite
758 // the incremented index (bug 2897413).
759 CHECK_EQ(index, portFormat.nIndex);
760 if (portFormat.eColorFormat == colorFormat) {
761 CODEC_LOGV("Found supported color format: %d", portFormat.eColorFormat);
762 return OK; // colorFormat is supported!
763 }
764 ++index;
765 portFormat.nIndex = index;
766
767 if (index >= kMaxColorFormatSupported) {
768 CODEC_LOGE("More than %ld color formats are supported???", index);
769 break;
770 }
771 }
772
773 CODEC_LOGE("color format %d is not supported", colorFormat);
774 return UNKNOWN_ERROR;
775 }
776
setVideoInputFormat(const char * mime,const sp<MetaData> & meta)777 void OMXCodec::setVideoInputFormat(
778 const char *mime, const sp<MetaData>& meta) {
779
780 int32_t width, height, frameRate, bitRate, stride, sliceHeight;
781 bool success = meta->findInt32(kKeyWidth, &width);
782 success = success && meta->findInt32(kKeyHeight, &height);
783 success = success && meta->findInt32(kKeyFrameRate, &frameRate);
784 success = success && meta->findInt32(kKeyBitRate, &bitRate);
785 success = success && meta->findInt32(kKeyStride, &stride);
786 success = success && meta->findInt32(kKeySliceHeight, &sliceHeight);
787 CHECK(success);
788 CHECK(stride != 0);
789
790 OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
791 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
792 compressionFormat = OMX_VIDEO_CodingAVC;
793 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
794 compressionFormat = OMX_VIDEO_CodingMPEG4;
795 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
796 compressionFormat = OMX_VIDEO_CodingH263;
797 } else {
798 ALOGE("Not a supported video mime type: %s", mime);
799 CHECK(!"Should not be here. Not a supported video mime type.");
800 }
801
802 OMX_COLOR_FORMATTYPE colorFormat;
803 CHECK_EQ((status_t)OK, findTargetColorFormat(meta, &colorFormat));
804
805 status_t err;
806 OMX_PARAM_PORTDEFINITIONTYPE def;
807 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
808
809 //////////////////////// Input port /////////////////////////
810 CHECK_EQ(setVideoPortFormatType(
811 kPortIndexInput, OMX_VIDEO_CodingUnused,
812 colorFormat), (status_t)OK);
813
814 InitOMXParams(&def);
815 def.nPortIndex = kPortIndexInput;
816
817 err = mOMX->getParameter(
818 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
819 CHECK_EQ(err, (status_t)OK);
820
821 def.nBufferSize = getFrameSize(colorFormat,
822 stride > 0? stride: -stride, sliceHeight);
823
824 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
825
826 video_def->nFrameWidth = width;
827 video_def->nFrameHeight = height;
828 video_def->nStride = stride;
829 video_def->nSliceHeight = sliceHeight;
830 video_def->xFramerate = (frameRate << 16); // Q16 format
831 video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
832 video_def->eColorFormat = colorFormat;
833
834 err = mOMX->setParameter(
835 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
836 CHECK_EQ(err, (status_t)OK);
837
838 //////////////////////// Output port /////////////////////////
839 CHECK_EQ(setVideoPortFormatType(
840 kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused),
841 (status_t)OK);
842 InitOMXParams(&def);
843 def.nPortIndex = kPortIndexOutput;
844
845 err = mOMX->getParameter(
846 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
847
848 CHECK_EQ(err, (status_t)OK);
849 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
850
851 video_def->nFrameWidth = width;
852 video_def->nFrameHeight = height;
853 video_def->xFramerate = 0; // No need for output port
854 video_def->nBitrate = bitRate; // Q16 format
855 video_def->eCompressionFormat = compressionFormat;
856 video_def->eColorFormat = OMX_COLOR_FormatUnused;
857 if (mQuirks & kRequiresLargerEncoderOutputBuffer) {
858 // Increases the output buffer size
859 def.nBufferSize = ((def.nBufferSize * 3) >> 1);
860 }
861
862 err = mOMX->setParameter(
863 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
864 CHECK_EQ(err, (status_t)OK);
865
866 /////////////////// Codec-specific ////////////////////////
867 switch (compressionFormat) {
868 case OMX_VIDEO_CodingMPEG4:
869 {
870 CHECK_EQ(setupMPEG4EncoderParameters(meta), (status_t)OK);
871 break;
872 }
873
874 case OMX_VIDEO_CodingH263:
875 CHECK_EQ(setupH263EncoderParameters(meta), (status_t)OK);
876 break;
877
878 case OMX_VIDEO_CodingAVC:
879 {
880 CHECK_EQ(setupAVCEncoderParameters(meta), (status_t)OK);
881 break;
882 }
883
884 default:
885 CHECK(!"Support for this compressionFormat to be implemented.");
886 break;
887 }
888 }
889
setPFramesSpacing(int32_t iFramesInterval,int32_t frameRate)890 static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
891 if (iFramesInterval < 0) {
892 return 0xFFFFFFFF;
893 } else if (iFramesInterval == 0) {
894 return 0;
895 }
896 OMX_U32 ret = frameRate * iFramesInterval;
897 CHECK(ret > 1);
898 return ret;
899 }
900
setupErrorCorrectionParameters()901 status_t OMXCodec::setupErrorCorrectionParameters() {
902 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
903 InitOMXParams(&errorCorrectionType);
904 errorCorrectionType.nPortIndex = kPortIndexOutput;
905
906 status_t err = mOMX->getParameter(
907 mNode, OMX_IndexParamVideoErrorCorrection,
908 &errorCorrectionType, sizeof(errorCorrectionType));
909 if (err != OK) {
910 ALOGW("Error correction param query is not supported");
911 return OK; // Optional feature. Ignore this failure
912 }
913
914 errorCorrectionType.bEnableHEC = OMX_FALSE;
915 errorCorrectionType.bEnableResync = OMX_TRUE;
916 errorCorrectionType.nResynchMarkerSpacing = 256;
917 errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
918 errorCorrectionType.bEnableRVLC = OMX_FALSE;
919
920 err = mOMX->setParameter(
921 mNode, OMX_IndexParamVideoErrorCorrection,
922 &errorCorrectionType, sizeof(errorCorrectionType));
923 if (err != OK) {
924 ALOGW("Error correction param configuration is not supported");
925 }
926
927 // Optional feature. Ignore the failure.
928 return OK;
929 }
930
setupBitRate(int32_t bitRate)931 status_t OMXCodec::setupBitRate(int32_t bitRate) {
932 OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
933 InitOMXParams(&bitrateType);
934 bitrateType.nPortIndex = kPortIndexOutput;
935
936 status_t err = mOMX->getParameter(
937 mNode, OMX_IndexParamVideoBitrate,
938 &bitrateType, sizeof(bitrateType));
939 CHECK_EQ(err, (status_t)OK);
940
941 bitrateType.eControlRate = OMX_Video_ControlRateVariable;
942 bitrateType.nTargetBitrate = bitRate;
943
944 err = mOMX->setParameter(
945 mNode, OMX_IndexParamVideoBitrate,
946 &bitrateType, sizeof(bitrateType));
947 CHECK_EQ(err, (status_t)OK);
948 return OK;
949 }
950
getVideoProfileLevel(const sp<MetaData> & meta,const CodecProfileLevel & defaultProfileLevel,CodecProfileLevel & profileLevel)951 status_t OMXCodec::getVideoProfileLevel(
952 const sp<MetaData>& meta,
953 const CodecProfileLevel& defaultProfileLevel,
954 CodecProfileLevel &profileLevel) {
955 CODEC_LOGV("Default profile: %ld, level %ld",
956 defaultProfileLevel.mProfile, defaultProfileLevel.mLevel);
957
958 // Are the default profile and level overwriten?
959 int32_t profile, level;
960 if (!meta->findInt32(kKeyVideoProfile, &profile)) {
961 profile = defaultProfileLevel.mProfile;
962 }
963 if (!meta->findInt32(kKeyVideoLevel, &level)) {
964 level = defaultProfileLevel.mLevel;
965 }
966 CODEC_LOGV("Target profile: %d, level: %d", profile, level);
967
968 // Are the target profile and level supported by the encoder?
969 OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
970 InitOMXParams(¶m);
971 param.nPortIndex = kPortIndexOutput;
972 for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
973 status_t err = mOMX->getParameter(
974 mNode, OMX_IndexParamVideoProfileLevelQuerySupported,
975 ¶m, sizeof(param));
976
977 if (err != OK) break;
978
979 int32_t supportedProfile = static_cast<int32_t>(param.eProfile);
980 int32_t supportedLevel = static_cast<int32_t>(param.eLevel);
981 CODEC_LOGV("Supported profile: %d, level %d",
982 supportedProfile, supportedLevel);
983
984 if (profile == supportedProfile &&
985 level <= supportedLevel) {
986 // We can further check whether the level is a valid
987 // value; but we will leave that to the omx encoder component
988 // via OMX_SetParameter call.
989 profileLevel.mProfile = profile;
990 profileLevel.mLevel = level;
991 return OK;
992 }
993 }
994
995 CODEC_LOGE("Target profile (%d) and level (%d) is not supported",
996 profile, level);
997 return BAD_VALUE;
998 }
999
setupH263EncoderParameters(const sp<MetaData> & meta)1000 status_t OMXCodec::setupH263EncoderParameters(const sp<MetaData>& meta) {
1001 int32_t iFramesInterval, frameRate, bitRate;
1002 bool success = meta->findInt32(kKeyBitRate, &bitRate);
1003 success = success && meta->findInt32(kKeyFrameRate, &frameRate);
1004 success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
1005 CHECK(success);
1006 OMX_VIDEO_PARAM_H263TYPE h263type;
1007 InitOMXParams(&h263type);
1008 h263type.nPortIndex = kPortIndexOutput;
1009
1010 status_t err = mOMX->getParameter(
1011 mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
1012 CHECK_EQ(err, (status_t)OK);
1013
1014 h263type.nAllowedPictureTypes =
1015 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
1016
1017 h263type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate);
1018 if (h263type.nPFrames == 0) {
1019 h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
1020 }
1021 h263type.nBFrames = 0;
1022
1023 // Check profile and level parameters
1024 CodecProfileLevel defaultProfileLevel, profileLevel;
1025 defaultProfileLevel.mProfile = h263type.eProfile;
1026 defaultProfileLevel.mLevel = h263type.eLevel;
1027 err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel);
1028 if (err != OK) return err;
1029 h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profileLevel.mProfile);
1030 h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(profileLevel.mLevel);
1031
1032 h263type.bPLUSPTYPEAllowed = OMX_FALSE;
1033 h263type.bForceRoundingTypeToZero = OMX_FALSE;
1034 h263type.nPictureHeaderRepetition = 0;
1035 h263type.nGOBHeaderInterval = 0;
1036
1037 err = mOMX->setParameter(
1038 mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
1039 CHECK_EQ(err, (status_t)OK);
1040
1041 CHECK_EQ(setupBitRate(bitRate), (status_t)OK);
1042 CHECK_EQ(setupErrorCorrectionParameters(), (status_t)OK);
1043
1044 return OK;
1045 }
1046
setupMPEG4EncoderParameters(const sp<MetaData> & meta)1047 status_t OMXCodec::setupMPEG4EncoderParameters(const sp<MetaData>& meta) {
1048 int32_t iFramesInterval, frameRate, bitRate;
1049 bool success = meta->findInt32(kKeyBitRate, &bitRate);
1050 success = success && meta->findInt32(kKeyFrameRate, &frameRate);
1051 success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
1052 CHECK(success);
1053 OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
1054 InitOMXParams(&mpeg4type);
1055 mpeg4type.nPortIndex = kPortIndexOutput;
1056
1057 status_t err = mOMX->getParameter(
1058 mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
1059 CHECK_EQ(err, (status_t)OK);
1060
1061 mpeg4type.nSliceHeaderSpacing = 0;
1062 mpeg4type.bSVH = OMX_FALSE;
1063 mpeg4type.bGov = OMX_FALSE;
1064
1065 mpeg4type.nAllowedPictureTypes =
1066 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
1067
1068 mpeg4type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate);
1069 if (mpeg4type.nPFrames == 0) {
1070 mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
1071 }
1072 mpeg4type.nBFrames = 0;
1073 mpeg4type.nIDCVLCThreshold = 0;
1074 mpeg4type.bACPred = OMX_TRUE;
1075 mpeg4type.nMaxPacketSize = 256;
1076 mpeg4type.nTimeIncRes = 1000;
1077 mpeg4type.nHeaderExtension = 0;
1078 mpeg4type.bReversibleVLC = OMX_FALSE;
1079
1080 // Check profile and level parameters
1081 CodecProfileLevel defaultProfileLevel, profileLevel;
1082 defaultProfileLevel.mProfile = mpeg4type.eProfile;
1083 defaultProfileLevel.mLevel = mpeg4type.eLevel;
1084 err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel);
1085 if (err != OK) return err;
1086 mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profileLevel.mProfile);
1087 mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(profileLevel.mLevel);
1088
1089 err = mOMX->setParameter(
1090 mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
1091 CHECK_EQ(err, (status_t)OK);
1092
1093 CHECK_EQ(setupBitRate(bitRate), (status_t)OK);
1094 CHECK_EQ(setupErrorCorrectionParameters(), (status_t)OK);
1095
1096 return OK;
1097 }
1098
setupAVCEncoderParameters(const sp<MetaData> & meta)1099 status_t OMXCodec::setupAVCEncoderParameters(const sp<MetaData>& meta) {
1100 int32_t iFramesInterval, frameRate, bitRate;
1101 bool success = meta->findInt32(kKeyBitRate, &bitRate);
1102 success = success && meta->findInt32(kKeyFrameRate, &frameRate);
1103 success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
1104 CHECK(success);
1105
1106 OMX_VIDEO_PARAM_AVCTYPE h264type;
1107 InitOMXParams(&h264type);
1108 h264type.nPortIndex = kPortIndexOutput;
1109
1110 status_t err = mOMX->getParameter(
1111 mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
1112 CHECK_EQ(err, (status_t)OK);
1113
1114 h264type.nAllowedPictureTypes =
1115 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
1116
1117 // Check profile and level parameters
1118 CodecProfileLevel defaultProfileLevel, profileLevel;
1119 defaultProfileLevel.mProfile = h264type.eProfile;
1120 defaultProfileLevel.mLevel = h264type.eLevel;
1121 err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel);
1122 if (err != OK) return err;
1123 h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profileLevel.mProfile);
1124 h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(profileLevel.mLevel);
1125
1126 // XXX
1127 if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
1128 ALOGW("Use baseline profile instead of %d for AVC recording",
1129 h264type.eProfile);
1130 h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
1131 }
1132
1133 if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
1134 h264type.nSliceHeaderSpacing = 0;
1135 h264type.bUseHadamard = OMX_TRUE;
1136 h264type.nRefFrames = 1;
1137 h264type.nBFrames = 0;
1138 h264type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate);
1139 if (h264type.nPFrames == 0) {
1140 h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
1141 }
1142 h264type.nRefIdx10ActiveMinus1 = 0;
1143 h264type.nRefIdx11ActiveMinus1 = 0;
1144 h264type.bEntropyCodingCABAC = OMX_FALSE;
1145 h264type.bWeightedPPrediction = OMX_FALSE;
1146 h264type.bconstIpred = OMX_FALSE;
1147 h264type.bDirect8x8Inference = OMX_FALSE;
1148 h264type.bDirectSpatialTemporal = OMX_FALSE;
1149 h264type.nCabacInitIdc = 0;
1150 }
1151
1152 if (h264type.nBFrames != 0) {
1153 h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
1154 }
1155
1156 h264type.bEnableUEP = OMX_FALSE;
1157 h264type.bEnableFMO = OMX_FALSE;
1158 h264type.bEnableASO = OMX_FALSE;
1159 h264type.bEnableRS = OMX_FALSE;
1160 h264type.bFrameMBsOnly = OMX_TRUE;
1161 h264type.bMBAFF = OMX_FALSE;
1162 h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
1163
1164 err = mOMX->setParameter(
1165 mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
1166 CHECK_EQ(err, (status_t)OK);
1167
1168 CHECK_EQ(setupBitRate(bitRate), (status_t)OK);
1169
1170 return OK;
1171 }
1172
setVideoOutputFormat(const char * mime,OMX_U32 width,OMX_U32 height)1173 status_t OMXCodec::setVideoOutputFormat(
1174 const char *mime, OMX_U32 width, OMX_U32 height) {
1175 CODEC_LOGV("setVideoOutputFormat width=%ld, height=%ld", width, height);
1176
1177 OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
1178 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
1179 compressionFormat = OMX_VIDEO_CodingAVC;
1180 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
1181 compressionFormat = OMX_VIDEO_CodingMPEG4;
1182 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
1183 compressionFormat = OMX_VIDEO_CodingH263;
1184 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VPX, mime)) {
1185 compressionFormat = OMX_VIDEO_CodingVPX;
1186 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG2, mime)) {
1187 compressionFormat = OMX_VIDEO_CodingMPEG2;
1188 } else {
1189 ALOGE("Not a supported video mime type: %s", mime);
1190 CHECK(!"Should not be here. Not a supported video mime type.");
1191 }
1192
1193 status_t err = setVideoPortFormatType(
1194 kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1195
1196 if (err != OK) {
1197 return err;
1198 }
1199
1200 #if 1
1201 {
1202 OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1203 InitOMXParams(&format);
1204 format.nPortIndex = kPortIndexOutput;
1205 format.nIndex = 0;
1206
1207 status_t err = mOMX->getParameter(
1208 mNode, OMX_IndexParamVideoPortFormat,
1209 &format, sizeof(format));
1210 CHECK_EQ(err, (status_t)OK);
1211 CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1212
1213 CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
1214 || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
1215 || format.eColorFormat == OMX_COLOR_FormatCbYCrY
1216 || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar
1217 || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar);
1218
1219 err = mOMX->setParameter(
1220 mNode, OMX_IndexParamVideoPortFormat,
1221 &format, sizeof(format));
1222
1223 if (err != OK) {
1224 return err;
1225 }
1226 }
1227 #endif
1228
1229 OMX_PARAM_PORTDEFINITIONTYPE def;
1230 InitOMXParams(&def);
1231 def.nPortIndex = kPortIndexInput;
1232
1233 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
1234
1235 err = mOMX->getParameter(
1236 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1237
1238 CHECK_EQ(err, (status_t)OK);
1239
1240 #if 1
1241 // XXX Need a (much) better heuristic to compute input buffer sizes.
1242 const size_t X = 64 * 1024;
1243 if (def.nBufferSize < X) {
1244 def.nBufferSize = X;
1245 }
1246 #endif
1247
1248 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
1249
1250 video_def->nFrameWidth = width;
1251 video_def->nFrameHeight = height;
1252
1253 video_def->eCompressionFormat = compressionFormat;
1254 video_def->eColorFormat = OMX_COLOR_FormatUnused;
1255
1256 err = mOMX->setParameter(
1257 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1258
1259 if (err != OK) {
1260 return err;
1261 }
1262
1263 ////////////////////////////////////////////////////////////////////////////
1264
1265 InitOMXParams(&def);
1266 def.nPortIndex = kPortIndexOutput;
1267
1268 err = mOMX->getParameter(
1269 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1270 CHECK_EQ(err, (status_t)OK);
1271 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
1272
1273 #if 0
1274 def.nBufferSize =
1275 (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2; // YUV420
1276 #endif
1277
1278 video_def->nFrameWidth = width;
1279 video_def->nFrameHeight = height;
1280
1281 err = mOMX->setParameter(
1282 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1283
1284 return err;
1285 }
1286
OMXCodec(const sp<IOMX> & omx,IOMX::node_id node,uint32_t quirks,uint32_t flags,bool isEncoder,const char * mime,const char * componentName,const sp<MediaSource> & source,const sp<ANativeWindow> & nativeWindow)1287 OMXCodec::OMXCodec(
1288 const sp<IOMX> &omx, IOMX::node_id node,
1289 uint32_t quirks, uint32_t flags,
1290 bool isEncoder,
1291 const char *mime,
1292 const char *componentName,
1293 const sp<MediaSource> &source,
1294 const sp<ANativeWindow> &nativeWindow)
1295 : mOMX(omx),
1296 mOMXLivesLocally(omx->livesLocally(node, getpid())),
1297 mNode(node),
1298 mQuirks(quirks),
1299 mFlags(flags),
1300 mIsEncoder(isEncoder),
1301 mIsVideo(!strncasecmp("video/", mime, 6)),
1302 mMIME(strdup(mime)),
1303 mComponentName(strdup(componentName)),
1304 mSource(source),
1305 mCodecSpecificDataIndex(0),
1306 mState(LOADED),
1307 mInitialBufferSubmit(true),
1308 mSignalledEOS(false),
1309 mNoMoreOutputData(false),
1310 mOutputPortSettingsHaveChanged(false),
1311 mSeekTimeUs(-1),
1312 mSeekMode(ReadOptions::SEEK_CLOSEST_SYNC),
1313 mTargetTimeUs(-1),
1314 mOutputPortSettingsChangedPending(false),
1315 mSkipCutBuffer(NULL),
1316 mLeftOverBuffer(NULL),
1317 mPaused(false),
1318 mNativeWindow(
1319 (!strncmp(componentName, "OMX.google.", 11)
1320 || !strcmp(componentName, "OMX.Nvidia.mpeg2v.decode"))
1321 ? NULL : nativeWindow) {
1322 mPortStatus[kPortIndexInput] = ENABLED;
1323 mPortStatus[kPortIndexOutput] = ENABLED;
1324
1325 setComponentRole();
1326 }
1327
1328 // static
setComponentRole(const sp<IOMX> & omx,IOMX::node_id node,bool isEncoder,const char * mime)1329 void OMXCodec::setComponentRole(
1330 const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder,
1331 const char *mime) {
1332 struct MimeToRole {
1333 const char *mime;
1334 const char *decoderRole;
1335 const char *encoderRole;
1336 };
1337
1338 static const MimeToRole kMimeToRole[] = {
1339 { MEDIA_MIMETYPE_AUDIO_MPEG,
1340 "audio_decoder.mp3", "audio_encoder.mp3" },
1341 { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
1342 "audio_decoder.mp1", "audio_encoder.mp1" },
1343 { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
1344 "audio_decoder.mp2", "audio_encoder.mp2" },
1345 { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1346 "audio_decoder.amrnb", "audio_encoder.amrnb" },
1347 { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1348 "audio_decoder.amrwb", "audio_encoder.amrwb" },
1349 { MEDIA_MIMETYPE_AUDIO_AAC,
1350 "audio_decoder.aac", "audio_encoder.aac" },
1351 { MEDIA_MIMETYPE_AUDIO_VORBIS,
1352 "audio_decoder.vorbis", "audio_encoder.vorbis" },
1353 { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1354 "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1355 { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1356 "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1357 { MEDIA_MIMETYPE_VIDEO_AVC,
1358 "video_decoder.avc", "video_encoder.avc" },
1359 { MEDIA_MIMETYPE_VIDEO_MPEG4,
1360 "video_decoder.mpeg4", "video_encoder.mpeg4" },
1361 { MEDIA_MIMETYPE_VIDEO_H263,
1362 "video_decoder.h263", "video_encoder.h263" },
1363 { MEDIA_MIMETYPE_VIDEO_VPX,
1364 "video_decoder.vpx", "video_encoder.vpx" },
1365 { MEDIA_MIMETYPE_AUDIO_RAW,
1366 "audio_decoder.raw", "audio_encoder.raw" },
1367 { MEDIA_MIMETYPE_AUDIO_FLAC,
1368 "audio_decoder.flac", "audio_encoder.flac" },
1369 };
1370
1371 static const size_t kNumMimeToRole =
1372 sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1373
1374 size_t i;
1375 for (i = 0; i < kNumMimeToRole; ++i) {
1376 if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1377 break;
1378 }
1379 }
1380
1381 if (i == kNumMimeToRole) {
1382 return;
1383 }
1384
1385 const char *role =
1386 isEncoder ? kMimeToRole[i].encoderRole
1387 : kMimeToRole[i].decoderRole;
1388
1389 if (role != NULL) {
1390 OMX_PARAM_COMPONENTROLETYPE roleParams;
1391 InitOMXParams(&roleParams);
1392
1393 strncpy((char *)roleParams.cRole,
1394 role, OMX_MAX_STRINGNAME_SIZE - 1);
1395
1396 roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1397
1398 status_t err = omx->setParameter(
1399 node, OMX_IndexParamStandardComponentRole,
1400 &roleParams, sizeof(roleParams));
1401
1402 if (err != OK) {
1403 ALOGW("Failed to set standard component role '%s'.", role);
1404 }
1405 }
1406 }
1407
setComponentRole()1408 void OMXCodec::setComponentRole() {
1409 setComponentRole(mOMX, mNode, mIsEncoder, mMIME);
1410 }
1411
~OMXCodec()1412 OMXCodec::~OMXCodec() {
1413 mSource.clear();
1414
1415 CHECK(mState == LOADED || mState == ERROR || mState == LOADED_TO_IDLE);
1416
1417 status_t err = mOMX->freeNode(mNode);
1418 CHECK_EQ(err, (status_t)OK);
1419
1420 mNode = NULL;
1421 setState(DEAD);
1422
1423 clearCodecSpecificData();
1424
1425 free(mComponentName);
1426 mComponentName = NULL;
1427
1428 free(mMIME);
1429 mMIME = NULL;
1430 }
1431
init()1432 status_t OMXCodec::init() {
1433 // mLock is held.
1434
1435 CHECK_EQ((int)mState, (int)LOADED);
1436
1437 status_t err;
1438 if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) {
1439 err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
1440 CHECK_EQ(err, (status_t)OK);
1441 setState(LOADED_TO_IDLE);
1442 }
1443
1444 err = allocateBuffers();
1445 if (err != (status_t)OK) {
1446 return err;
1447 }
1448
1449 if (mQuirks & kRequiresLoadedToIdleAfterAllocation) {
1450 err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
1451 CHECK_EQ(err, (status_t)OK);
1452
1453 setState(LOADED_TO_IDLE);
1454 }
1455
1456 while (mState != EXECUTING && mState != ERROR) {
1457 mAsyncCompletion.wait(mLock);
1458 }
1459
1460 return mState == ERROR ? UNKNOWN_ERROR : OK;
1461 }
1462
1463 // static
isIntermediateState(State state)1464 bool OMXCodec::isIntermediateState(State state) {
1465 return state == LOADED_TO_IDLE
1466 || state == IDLE_TO_EXECUTING
1467 || state == EXECUTING_TO_IDLE
1468 || state == IDLE_TO_LOADED
1469 || state == RECONFIGURING;
1470 }
1471
allocateBuffers()1472 status_t OMXCodec::allocateBuffers() {
1473 status_t err = allocateBuffersOnPort(kPortIndexInput);
1474
1475 if (err != OK) {
1476 return err;
1477 }
1478
1479 return allocateBuffersOnPort(kPortIndexOutput);
1480 }
1481
allocateBuffersOnPort(OMX_U32 portIndex)1482 status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
1483 if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
1484 return allocateOutputBuffersFromNativeWindow();
1485 }
1486
1487 if ((mFlags & kEnableGrallocUsageProtected) && portIndex == kPortIndexOutput) {
1488 ALOGE("protected output buffers must be stent to an ANativeWindow");
1489 return PERMISSION_DENIED;
1490 }
1491
1492 status_t err = OK;
1493 if ((mFlags & kStoreMetaDataInVideoBuffers)
1494 && portIndex == kPortIndexInput) {
1495 err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1496 if (err != OK) {
1497 ALOGE("Storing meta data in video buffers is not supported");
1498 return err;
1499 }
1500 }
1501
1502 OMX_PARAM_PORTDEFINITIONTYPE def;
1503 InitOMXParams(&def);
1504 def.nPortIndex = portIndex;
1505
1506 err = mOMX->getParameter(
1507 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1508
1509 if (err != OK) {
1510 return err;
1511 }
1512
1513 CODEC_LOGV("allocating %lu buffers of size %lu on %s port",
1514 def.nBufferCountActual, def.nBufferSize,
1515 portIndex == kPortIndexInput ? "input" : "output");
1516
1517 size_t totalSize = def.nBufferCountActual * def.nBufferSize;
1518 mDealer[portIndex] = new MemoryDealer(totalSize, "OMXCodec");
1519
1520 for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
1521 sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
1522 CHECK(mem.get() != NULL);
1523
1524 BufferInfo info;
1525 info.mData = NULL;
1526 info.mSize = def.nBufferSize;
1527
1528 IOMX::buffer_id buffer;
1529 if (portIndex == kPortIndexInput
1530 && ((mQuirks & kRequiresAllocateBufferOnInputPorts)
1531 || (mFlags & kUseSecureInputBuffers))) {
1532 if (mOMXLivesLocally) {
1533 mem.clear();
1534
1535 err = mOMX->allocateBuffer(
1536 mNode, portIndex, def.nBufferSize, &buffer,
1537 &info.mData);
1538 } else {
1539 err = mOMX->allocateBufferWithBackup(
1540 mNode, portIndex, mem, &buffer);
1541 }
1542 } else if (portIndex == kPortIndexOutput
1543 && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) {
1544 if (mOMXLivesLocally) {
1545 mem.clear();
1546
1547 err = mOMX->allocateBuffer(
1548 mNode, portIndex, def.nBufferSize, &buffer,
1549 &info.mData);
1550 } else {
1551 err = mOMX->allocateBufferWithBackup(
1552 mNode, portIndex, mem, &buffer);
1553 }
1554 } else {
1555 err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
1556 }
1557
1558 if (err != OK) {
1559 ALOGE("allocate_buffer_with_backup failed");
1560 return err;
1561 }
1562
1563 if (mem != NULL) {
1564 info.mData = mem->pointer();
1565 }
1566
1567 info.mBuffer = buffer;
1568 info.mStatus = OWNED_BY_US;
1569 info.mMem = mem;
1570 info.mMediaBuffer = NULL;
1571
1572 if (portIndex == kPortIndexOutput) {
1573 if (!(mOMXLivesLocally
1574 && (mQuirks & kRequiresAllocateBufferOnOutputPorts)
1575 && (mQuirks & kDefersOutputBufferAllocation))) {
1576 // If the node does not fill in the buffer ptr at this time,
1577 // we will defer creating the MediaBuffer until receiving
1578 // the first FILL_BUFFER_DONE notification instead.
1579 info.mMediaBuffer = new MediaBuffer(info.mData, info.mSize);
1580 info.mMediaBuffer->setObserver(this);
1581 }
1582 }
1583
1584 mPortBuffers[portIndex].push(info);
1585
1586 CODEC_LOGV("allocated buffer %p on %s port", buffer,
1587 portIndex == kPortIndexInput ? "input" : "output");
1588 }
1589
1590 if (portIndex == kPortIndexOutput) {
1591
1592 sp<MetaData> meta = mSource->getFormat();
1593 int32_t delay = 0;
1594 if (!meta->findInt32(kKeyEncoderDelay, &delay)) {
1595 delay = 0;
1596 }
1597 int32_t padding = 0;
1598 if (!meta->findInt32(kKeyEncoderPadding, &padding)) {
1599 padding = 0;
1600 }
1601 int32_t numchannels = 0;
1602 if (delay + padding) {
1603 if (mOutputFormat->findInt32(kKeyChannelCount, &numchannels)) {
1604 size_t frameSize = numchannels * sizeof(int16_t);
1605 if (mSkipCutBuffer != NULL) {
1606 size_t prevbuffersize = mSkipCutBuffer->size();
1607 if (prevbuffersize != 0) {
1608 ALOGW("Replacing SkipCutBuffer holding %d bytes", prevbuffersize);
1609 }
1610 }
1611 mSkipCutBuffer = new SkipCutBuffer(delay * frameSize, padding * frameSize);
1612 }
1613 }
1614 }
1615
1616 // dumpPortStatus(portIndex);
1617
1618 if (portIndex == kPortIndexInput && (mFlags & kUseSecureInputBuffers)) {
1619 Vector<MediaBuffer *> buffers;
1620 for (size_t i = 0; i < def.nBufferCountActual; ++i) {
1621 const BufferInfo &info = mPortBuffers[kPortIndexInput].itemAt(i);
1622
1623 MediaBuffer *mbuf = new MediaBuffer(info.mData, info.mSize);
1624 buffers.push(mbuf);
1625 }
1626
1627 status_t err = mSource->setBuffers(buffers);
1628
1629 if (err != OK) {
1630 for (size_t i = 0; i < def.nBufferCountActual; ++i) {
1631 buffers.editItemAt(i)->release();
1632 }
1633 buffers.clear();
1634
1635 CODEC_LOGE(
1636 "Codec requested to use secure input buffers but "
1637 "upstream source didn't support that.");
1638
1639 return err;
1640 }
1641 }
1642
1643 return OK;
1644 }
1645
applyRotation()1646 status_t OMXCodec::applyRotation() {
1647 sp<MetaData> meta = mSource->getFormat();
1648
1649 int32_t rotationDegrees;
1650 if (!meta->findInt32(kKeyRotation, &rotationDegrees)) {
1651 rotationDegrees = 0;
1652 }
1653
1654 uint32_t transform;
1655 switch (rotationDegrees) {
1656 case 0: transform = 0; break;
1657 case 90: transform = HAL_TRANSFORM_ROT_90; break;
1658 case 180: transform = HAL_TRANSFORM_ROT_180; break;
1659 case 270: transform = HAL_TRANSFORM_ROT_270; break;
1660 default: transform = 0; break;
1661 }
1662
1663 status_t err = OK;
1664
1665 if (transform) {
1666 err = native_window_set_buffers_transform(
1667 mNativeWindow.get(), transform);
1668 }
1669
1670 return err;
1671 }
1672
allocateOutputBuffersFromNativeWindow()1673 status_t OMXCodec::allocateOutputBuffersFromNativeWindow() {
1674 // Get the number of buffers needed.
1675 OMX_PARAM_PORTDEFINITIONTYPE def;
1676 InitOMXParams(&def);
1677 def.nPortIndex = kPortIndexOutput;
1678
1679 status_t err = mOMX->getParameter(
1680 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1681 if (err != OK) {
1682 return err;
1683 }
1684
1685 err = native_window_set_buffers_geometry(
1686 mNativeWindow.get(),
1687 def.format.video.nFrameWidth,
1688 def.format.video.nFrameHeight,
1689 def.format.video.eColorFormat);
1690
1691 if (err != 0) {
1692 ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
1693 strerror(-err), -err);
1694 return err;
1695 }
1696
1697 err = applyRotation();
1698 if (err != OK) {
1699 return err;
1700 }
1701
1702 // Set up the native window.
1703 OMX_U32 usage = 0;
1704 err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
1705 if (err != 0) {
1706 ALOGW("querying usage flags from OMX IL component failed: %d", err);
1707 // XXX: Currently this error is logged, but not fatal.
1708 usage = 0;
1709 }
1710 if (mFlags & kEnableGrallocUsageProtected) {
1711 usage |= GRALLOC_USAGE_PROTECTED;
1712 }
1713
1714 // Make sure to check whether either Stagefright or the video decoder
1715 // requested protected buffers.
1716 if (usage & GRALLOC_USAGE_PROTECTED) {
1717 // Verify that the ANativeWindow sends images directly to
1718 // SurfaceFlinger.
1719 int queuesToNativeWindow = 0;
1720 err = mNativeWindow->query(
1721 mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
1722 &queuesToNativeWindow);
1723 if (err != 0) {
1724 ALOGE("error authenticating native window: %d", err);
1725 return err;
1726 }
1727 if (queuesToNativeWindow != 1) {
1728 ALOGE("native window could not be authenticated");
1729 return PERMISSION_DENIED;
1730 }
1731 }
1732
1733 ALOGV("native_window_set_usage usage=0x%lx", usage);
1734 err = native_window_set_usage(
1735 mNativeWindow.get(), usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
1736 if (err != 0) {
1737 ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
1738 return err;
1739 }
1740
1741 int minUndequeuedBufs = 0;
1742 err = mNativeWindow->query(mNativeWindow.get(),
1743 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
1744 if (err != 0) {
1745 ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
1746 strerror(-err), -err);
1747 return err;
1748 }
1749
1750 // XXX: Is this the right logic to use? It's not clear to me what the OMX
1751 // buffer counts refer to - how do they account for the renderer holding on
1752 // to buffers?
1753 if (def.nBufferCountActual < def.nBufferCountMin + minUndequeuedBufs) {
1754 OMX_U32 newBufferCount = def.nBufferCountMin + minUndequeuedBufs;
1755 def.nBufferCountActual = newBufferCount;
1756 err = mOMX->setParameter(
1757 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1758 if (err != OK) {
1759 CODEC_LOGE("setting nBufferCountActual to %lu failed: %d",
1760 newBufferCount, err);
1761 return err;
1762 }
1763 }
1764
1765 err = native_window_set_buffer_count(
1766 mNativeWindow.get(), def.nBufferCountActual);
1767 if (err != 0) {
1768 ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
1769 -err);
1770 return err;
1771 }
1772
1773 CODEC_LOGV("allocating %lu buffers from a native window of size %lu on "
1774 "output port", def.nBufferCountActual, def.nBufferSize);
1775
1776 // Dequeue buffers and send them to OMX
1777 for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
1778 ANativeWindowBuffer* buf;
1779 err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf);
1780 if (err != 0) {
1781 ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1782 break;
1783 }
1784
1785 sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
1786 BufferInfo info;
1787 info.mData = NULL;
1788 info.mSize = def.nBufferSize;
1789 info.mStatus = OWNED_BY_US;
1790 info.mMem = NULL;
1791 info.mMediaBuffer = new MediaBuffer(graphicBuffer);
1792 info.mMediaBuffer->setObserver(this);
1793 mPortBuffers[kPortIndexOutput].push(info);
1794
1795 IOMX::buffer_id bufferId;
1796 err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
1797 &bufferId);
1798 if (err != 0) {
1799 CODEC_LOGE("registering GraphicBuffer with OMX IL component "
1800 "failed: %d", err);
1801 break;
1802 }
1803
1804 mPortBuffers[kPortIndexOutput].editItemAt(i).mBuffer = bufferId;
1805
1806 CODEC_LOGV("registered graphic buffer with ID %p (pointer = %p)",
1807 bufferId, graphicBuffer.get());
1808 }
1809
1810 OMX_U32 cancelStart;
1811 OMX_U32 cancelEnd;
1812 if (err != 0) {
1813 // If an error occurred while dequeuing we need to cancel any buffers
1814 // that were dequeued.
1815 cancelStart = 0;
1816 cancelEnd = mPortBuffers[kPortIndexOutput].size();
1817 } else {
1818 // Return the last two buffers to the native window.
1819 cancelStart = def.nBufferCountActual - minUndequeuedBufs;
1820 cancelEnd = def.nBufferCountActual;
1821 }
1822
1823 for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
1824 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(i);
1825 cancelBufferToNativeWindow(info);
1826 }
1827
1828 return err;
1829 }
1830
cancelBufferToNativeWindow(BufferInfo * info)1831 status_t OMXCodec::cancelBufferToNativeWindow(BufferInfo *info) {
1832 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
1833 CODEC_LOGV("Calling cancelBuffer on buffer %p", info->mBuffer);
1834 int err = mNativeWindow->cancelBuffer(
1835 mNativeWindow.get(), info->mMediaBuffer->graphicBuffer().get());
1836 if (err != 0) {
1837 CODEC_LOGE("cancelBuffer failed w/ error 0x%08x", err);
1838
1839 setState(ERROR);
1840 return err;
1841 }
1842 info->mStatus = OWNED_BY_NATIVE_WINDOW;
1843 return OK;
1844 }
1845
dequeueBufferFromNativeWindow()1846 OMXCodec::BufferInfo* OMXCodec::dequeueBufferFromNativeWindow() {
1847 // Dequeue the next buffer from the native window.
1848 ANativeWindowBuffer* buf;
1849 int err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf);
1850 if (err != 0) {
1851 CODEC_LOGE("dequeueBuffer failed w/ error 0x%08x", err);
1852
1853 setState(ERROR);
1854 return 0;
1855 }
1856
1857 // Determine which buffer we just dequeued.
1858 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
1859 BufferInfo *bufInfo = 0;
1860 for (size_t i = 0; i < buffers->size(); i++) {
1861 sp<GraphicBuffer> graphicBuffer = buffers->itemAt(i).
1862 mMediaBuffer->graphicBuffer();
1863 if (graphicBuffer->handle == buf->handle) {
1864 bufInfo = &buffers->editItemAt(i);
1865 break;
1866 }
1867 }
1868
1869 if (bufInfo == 0) {
1870 CODEC_LOGE("dequeued unrecognized buffer: %p", buf);
1871
1872 setState(ERROR);
1873 return 0;
1874 }
1875
1876 // The native window no longer owns the buffer.
1877 CHECK_EQ((int)bufInfo->mStatus, (int)OWNED_BY_NATIVE_WINDOW);
1878 bufInfo->mStatus = OWNED_BY_US;
1879
1880 return bufInfo;
1881 }
1882
pushBlankBuffersToNativeWindow()1883 status_t OMXCodec::pushBlankBuffersToNativeWindow() {
1884 status_t err = NO_ERROR;
1885 ANativeWindowBuffer* anb = NULL;
1886 int numBufs = 0;
1887 int minUndequeuedBufs = 0;
1888
1889 // We need to reconnect to the ANativeWindow as a CPU client to ensure that
1890 // no frames get dropped by SurfaceFlinger assuming that these are video
1891 // frames.
1892 err = native_window_api_disconnect(mNativeWindow.get(),
1893 NATIVE_WINDOW_API_MEDIA);
1894 if (err != NO_ERROR) {
1895 ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
1896 strerror(-err), -err);
1897 return err;
1898 }
1899
1900 err = native_window_api_connect(mNativeWindow.get(),
1901 NATIVE_WINDOW_API_CPU);
1902 if (err != NO_ERROR) {
1903 ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
1904 strerror(-err), -err);
1905 return err;
1906 }
1907
1908 err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
1909 HAL_PIXEL_FORMAT_RGBX_8888);
1910 if (err != NO_ERROR) {
1911 ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
1912 strerror(-err), -err);
1913 goto error;
1914 }
1915
1916 err = native_window_set_usage(mNativeWindow.get(),
1917 GRALLOC_USAGE_SW_WRITE_OFTEN);
1918 if (err != NO_ERROR) {
1919 ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
1920 strerror(-err), -err);
1921 goto error;
1922 }
1923
1924 err = native_window_set_scaling_mode(mNativeWindow.get(),
1925 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
1926 if (err != OK) {
1927 ALOGE("error pushing blank frames: set_scaling_mode failed: %s (%d)",
1928 strerror(-err), -err);
1929 goto error;
1930 }
1931
1932 err = mNativeWindow->query(mNativeWindow.get(),
1933 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
1934 if (err != NO_ERROR) {
1935 ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
1936 "failed: %s (%d)", strerror(-err), -err);
1937 goto error;
1938 }
1939
1940 numBufs = minUndequeuedBufs + 1;
1941 err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
1942 if (err != NO_ERROR) {
1943 ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
1944 strerror(-err), -err);
1945 goto error;
1946 }
1947
1948 // We push numBufs + 1 buffers to ensure that we've drawn into the same
1949 // buffer twice. This should guarantee that the buffer has been displayed
1950 // on the screen and then been replaced, so an previous video frames are
1951 // guaranteed NOT to be currently displayed.
1952 for (int i = 0; i < numBufs + 1; i++) {
1953 err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &anb);
1954 if (err != NO_ERROR) {
1955 ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
1956 strerror(-err), -err);
1957 goto error;
1958 }
1959
1960 sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
1961 err = mNativeWindow->lockBuffer(mNativeWindow.get(),
1962 buf->getNativeBuffer());
1963 if (err != NO_ERROR) {
1964 ALOGE("error pushing blank frames: lockBuffer failed: %s (%d)",
1965 strerror(-err), -err);
1966 goto error;
1967 }
1968
1969 // Fill the buffer with the a 1x1 checkerboard pattern ;)
1970 uint32_t* img = NULL;
1971 err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
1972 if (err != NO_ERROR) {
1973 ALOGE("error pushing blank frames: lock failed: %s (%d)",
1974 strerror(-err), -err);
1975 goto error;
1976 }
1977
1978 *img = 0;
1979
1980 err = buf->unlock();
1981 if (err != NO_ERROR) {
1982 ALOGE("error pushing blank frames: unlock failed: %s (%d)",
1983 strerror(-err), -err);
1984 goto error;
1985 }
1986
1987 err = mNativeWindow->queueBuffer(mNativeWindow.get(),
1988 buf->getNativeBuffer());
1989 if (err != NO_ERROR) {
1990 ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
1991 strerror(-err), -err);
1992 goto error;
1993 }
1994
1995 anb = NULL;
1996 }
1997
1998 error:
1999
2000 if (err != NO_ERROR) {
2001 // Clean up after an error.
2002 if (anb != NULL) {
2003 mNativeWindow->cancelBuffer(mNativeWindow.get(), anb);
2004 }
2005
2006 native_window_api_disconnect(mNativeWindow.get(),
2007 NATIVE_WINDOW_API_CPU);
2008 native_window_api_connect(mNativeWindow.get(),
2009 NATIVE_WINDOW_API_MEDIA);
2010
2011 return err;
2012 } else {
2013 // Clean up after success.
2014 err = native_window_api_disconnect(mNativeWindow.get(),
2015 NATIVE_WINDOW_API_CPU);
2016 if (err != NO_ERROR) {
2017 ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2018 strerror(-err), -err);
2019 return err;
2020 }
2021
2022 err = native_window_api_connect(mNativeWindow.get(),
2023 NATIVE_WINDOW_API_MEDIA);
2024 if (err != NO_ERROR) {
2025 ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2026 strerror(-err), -err);
2027 return err;
2028 }
2029
2030 return NO_ERROR;
2031 }
2032 }
2033
getDecodingTimeUs()2034 int64_t OMXCodec::getDecodingTimeUs() {
2035 CHECK(mIsEncoder && mIsVideo);
2036
2037 if (mDecodingTimeList.empty()) {
2038 CHECK(mSignalledEOS || mNoMoreOutputData);
2039 // No corresponding input frame available.
2040 // This could happen when EOS is reached.
2041 return 0;
2042 }
2043
2044 List<int64_t>::iterator it = mDecodingTimeList.begin();
2045 int64_t timeUs = *it;
2046 mDecodingTimeList.erase(it);
2047 return timeUs;
2048 }
2049
on_message(const omx_message & msg)2050 void OMXCodec::on_message(const omx_message &msg) {
2051 if (mState == ERROR) {
2052 ALOGW("Dropping OMX message - we're in ERROR state.");
2053 return;
2054 }
2055
2056 switch (msg.type) {
2057 case omx_message::EVENT:
2058 {
2059 onEvent(
2060 msg.u.event_data.event, msg.u.event_data.data1,
2061 msg.u.event_data.data2);
2062
2063 break;
2064 }
2065
2066 case omx_message::EMPTY_BUFFER_DONE:
2067 {
2068 IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
2069
2070 CODEC_LOGV("EMPTY_BUFFER_DONE(buffer: %p)", buffer);
2071
2072 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
2073 size_t i = 0;
2074 while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
2075 ++i;
2076 }
2077
2078 CHECK(i < buffers->size());
2079 if ((*buffers)[i].mStatus != OWNED_BY_COMPONENT) {
2080 ALOGW("We already own input buffer %p, yet received "
2081 "an EMPTY_BUFFER_DONE.", buffer);
2082 }
2083
2084 BufferInfo* info = &buffers->editItemAt(i);
2085 info->mStatus = OWNED_BY_US;
2086
2087 // Buffer could not be released until empty buffer done is called.
2088 if (info->mMediaBuffer != NULL) {
2089 if (mIsEncoder &&
2090 (mQuirks & kAvoidMemcopyInputRecordingFrames)) {
2091 // If zero-copy mode is enabled this will send the
2092 // input buffer back to the upstream source.
2093 restorePatchedDataPointer(info);
2094 }
2095
2096 info->mMediaBuffer->release();
2097 info->mMediaBuffer = NULL;
2098 }
2099
2100 if (mPortStatus[kPortIndexInput] == DISABLING) {
2101 CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
2102
2103 status_t err = freeBuffer(kPortIndexInput, i);
2104 CHECK_EQ(err, (status_t)OK);
2105 } else if (mState != ERROR
2106 && mPortStatus[kPortIndexInput] != SHUTTING_DOWN) {
2107 CHECK_EQ((int)mPortStatus[kPortIndexInput], (int)ENABLED);
2108
2109 if (mFlags & kUseSecureInputBuffers) {
2110 drainAnyInputBuffer();
2111 } else {
2112 drainInputBuffer(&buffers->editItemAt(i));
2113 }
2114 }
2115 break;
2116 }
2117
2118 case omx_message::FILL_BUFFER_DONE:
2119 {
2120 IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
2121 OMX_U32 flags = msg.u.extended_buffer_data.flags;
2122
2123 CODEC_LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx, timestamp: %lld us (%.2f secs))",
2124 buffer,
2125 msg.u.extended_buffer_data.range_length,
2126 flags,
2127 msg.u.extended_buffer_data.timestamp,
2128 msg.u.extended_buffer_data.timestamp / 1E6);
2129
2130 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
2131 size_t i = 0;
2132 while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
2133 ++i;
2134 }
2135
2136 CHECK(i < buffers->size());
2137 BufferInfo *info = &buffers->editItemAt(i);
2138
2139 if (info->mStatus != OWNED_BY_COMPONENT) {
2140 ALOGW("We already own output buffer %p, yet received "
2141 "a FILL_BUFFER_DONE.", buffer);
2142 }
2143
2144 info->mStatus = OWNED_BY_US;
2145
2146 if (mPortStatus[kPortIndexOutput] == DISABLING) {
2147 CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
2148
2149 status_t err = freeBuffer(kPortIndexOutput, i);
2150 CHECK_EQ(err, (status_t)OK);
2151
2152 #if 0
2153 } else if (mPortStatus[kPortIndexOutput] == ENABLED
2154 && (flags & OMX_BUFFERFLAG_EOS)) {
2155 CODEC_LOGV("No more output data.");
2156 mNoMoreOutputData = true;
2157 mBufferFilled.signal();
2158 #endif
2159 } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) {
2160 CHECK_EQ((int)mPortStatus[kPortIndexOutput], (int)ENABLED);
2161
2162 if (info->mMediaBuffer == NULL) {
2163 CHECK(mOMXLivesLocally);
2164 CHECK(mQuirks & kRequiresAllocateBufferOnOutputPorts);
2165 CHECK(mQuirks & kDefersOutputBufferAllocation);
2166
2167 // The qcom video decoders on Nexus don't actually allocate
2168 // output buffer memory on a call to OMX_AllocateBuffer
2169 // the "pBuffer" member of the OMX_BUFFERHEADERTYPE
2170 // structure is only filled in later.
2171
2172 info->mMediaBuffer = new MediaBuffer(
2173 msg.u.extended_buffer_data.data_ptr,
2174 info->mSize);
2175 info->mMediaBuffer->setObserver(this);
2176 }
2177
2178 MediaBuffer *buffer = info->mMediaBuffer;
2179 bool isGraphicBuffer = buffer->graphicBuffer() != NULL;
2180
2181 if (!isGraphicBuffer
2182 && msg.u.extended_buffer_data.range_offset
2183 + msg.u.extended_buffer_data.range_length
2184 > buffer->size()) {
2185 CODEC_LOGE(
2186 "Codec lied about its buffer size requirements, "
2187 "sending a buffer larger than the originally "
2188 "advertised size in FILL_BUFFER_DONE!");
2189 }
2190 buffer->set_range(
2191 msg.u.extended_buffer_data.range_offset,
2192 msg.u.extended_buffer_data.range_length);
2193
2194 buffer->meta_data()->clear();
2195
2196 buffer->meta_data()->setInt64(
2197 kKeyTime, msg.u.extended_buffer_data.timestamp);
2198
2199 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) {
2200 buffer->meta_data()->setInt32(kKeyIsSyncFrame, true);
2201 }
2202 bool isCodecSpecific = false;
2203 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_CODECCONFIG) {
2204 buffer->meta_data()->setInt32(kKeyIsCodecConfig, true);
2205 isCodecSpecific = true;
2206 }
2207
2208 if (isGraphicBuffer || mQuirks & kOutputBuffersAreUnreadable) {
2209 buffer->meta_data()->setInt32(kKeyIsUnreadable, true);
2210 }
2211
2212 buffer->meta_data()->setPointer(
2213 kKeyPlatformPrivate,
2214 msg.u.extended_buffer_data.platform_private);
2215
2216 buffer->meta_data()->setPointer(
2217 kKeyBufferID,
2218 msg.u.extended_buffer_data.buffer);
2219
2220 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_EOS) {
2221 CODEC_LOGV("No more output data.");
2222 mNoMoreOutputData = true;
2223 }
2224
2225 if (mIsEncoder && mIsVideo) {
2226 int64_t decodingTimeUs = isCodecSpecific? 0: getDecodingTimeUs();
2227 buffer->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs);
2228 }
2229
2230 if (mTargetTimeUs >= 0) {
2231 CHECK(msg.u.extended_buffer_data.timestamp <= mTargetTimeUs);
2232
2233 if (msg.u.extended_buffer_data.timestamp < mTargetTimeUs) {
2234 CODEC_LOGV(
2235 "skipping output buffer at timestamp %lld us",
2236 msg.u.extended_buffer_data.timestamp);
2237
2238 fillOutputBuffer(info);
2239 break;
2240 }
2241
2242 CODEC_LOGV(
2243 "returning output buffer at target timestamp "
2244 "%lld us",
2245 msg.u.extended_buffer_data.timestamp);
2246
2247 mTargetTimeUs = -1;
2248 }
2249
2250 mFilledBuffers.push_back(i);
2251 mBufferFilled.signal();
2252 if (mIsEncoder) {
2253 sched_yield();
2254 }
2255 }
2256
2257 break;
2258 }
2259
2260 default:
2261 {
2262 CHECK(!"should not be here.");
2263 break;
2264 }
2265 }
2266 }
2267
2268 // Has the format changed in any way that the client would have to be aware of?
formatHasNotablyChanged(const sp<MetaData> & from,const sp<MetaData> & to)2269 static bool formatHasNotablyChanged(
2270 const sp<MetaData> &from, const sp<MetaData> &to) {
2271 if (from.get() == NULL && to.get() == NULL) {
2272 return false;
2273 }
2274
2275 if ((from.get() == NULL && to.get() != NULL)
2276 || (from.get() != NULL && to.get() == NULL)) {
2277 return true;
2278 }
2279
2280 const char *mime_from, *mime_to;
2281 CHECK(from->findCString(kKeyMIMEType, &mime_from));
2282 CHECK(to->findCString(kKeyMIMEType, &mime_to));
2283
2284 if (strcasecmp(mime_from, mime_to)) {
2285 return true;
2286 }
2287
2288 if (!strcasecmp(mime_from, MEDIA_MIMETYPE_VIDEO_RAW)) {
2289 int32_t colorFormat_from, colorFormat_to;
2290 CHECK(from->findInt32(kKeyColorFormat, &colorFormat_from));
2291 CHECK(to->findInt32(kKeyColorFormat, &colorFormat_to));
2292
2293 if (colorFormat_from != colorFormat_to) {
2294 return true;
2295 }
2296
2297 int32_t width_from, width_to;
2298 CHECK(from->findInt32(kKeyWidth, &width_from));
2299 CHECK(to->findInt32(kKeyWidth, &width_to));
2300
2301 if (width_from != width_to) {
2302 return true;
2303 }
2304
2305 int32_t height_from, height_to;
2306 CHECK(from->findInt32(kKeyHeight, &height_from));
2307 CHECK(to->findInt32(kKeyHeight, &height_to));
2308
2309 if (height_from != height_to) {
2310 return true;
2311 }
2312
2313 int32_t left_from, top_from, right_from, bottom_from;
2314 CHECK(from->findRect(
2315 kKeyCropRect,
2316 &left_from, &top_from, &right_from, &bottom_from));
2317
2318 int32_t left_to, top_to, right_to, bottom_to;
2319 CHECK(to->findRect(
2320 kKeyCropRect,
2321 &left_to, &top_to, &right_to, &bottom_to));
2322
2323 if (left_to != left_from || top_to != top_from
2324 || right_to != right_from || bottom_to != bottom_from) {
2325 return true;
2326 }
2327 } else if (!strcasecmp(mime_from, MEDIA_MIMETYPE_AUDIO_RAW)) {
2328 int32_t numChannels_from, numChannels_to;
2329 CHECK(from->findInt32(kKeyChannelCount, &numChannels_from));
2330 CHECK(to->findInt32(kKeyChannelCount, &numChannels_to));
2331
2332 if (numChannels_from != numChannels_to) {
2333 return true;
2334 }
2335
2336 int32_t sampleRate_from, sampleRate_to;
2337 CHECK(from->findInt32(kKeySampleRate, &sampleRate_from));
2338 CHECK(to->findInt32(kKeySampleRate, &sampleRate_to));
2339
2340 if (sampleRate_from != sampleRate_to) {
2341 return true;
2342 }
2343 }
2344
2345 return false;
2346 }
2347
onEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)2348 void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2349 switch (event) {
2350 case OMX_EventCmdComplete:
2351 {
2352 onCmdComplete((OMX_COMMANDTYPE)data1, data2);
2353 break;
2354 }
2355
2356 case OMX_EventError:
2357 {
2358 CODEC_LOGE("ERROR(0x%08lx, %ld)", data1, data2);
2359
2360 setState(ERROR);
2361 break;
2362 }
2363
2364 case OMX_EventPortSettingsChanged:
2365 {
2366 CODEC_LOGV("OMX_EventPortSettingsChanged(port=%ld, data2=0x%08lx)",
2367 data1, data2);
2368
2369 if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
2370 // There is no need to check whether mFilledBuffers is empty or not
2371 // when the OMX_EventPortSettingsChanged is not meant for reallocating
2372 // the output buffers.
2373 if (data1 == kPortIndexOutput) {
2374 CHECK(mFilledBuffers.empty());
2375 }
2376 onPortSettingsChanged(data1);
2377 } else if (data1 == kPortIndexOutput &&
2378 (data2 == OMX_IndexConfigCommonOutputCrop ||
2379 data2 == OMX_IndexConfigCommonScale)) {
2380
2381 sp<MetaData> oldOutputFormat = mOutputFormat;
2382 initOutputFormat(mSource->getFormat());
2383
2384 if (data2 == OMX_IndexConfigCommonOutputCrop &&
2385 formatHasNotablyChanged(oldOutputFormat, mOutputFormat)) {
2386 mOutputPortSettingsHaveChanged = true;
2387
2388 } else if (data2 == OMX_IndexConfigCommonScale) {
2389 OMX_CONFIG_SCALEFACTORTYPE scale;
2390 InitOMXParams(&scale);
2391 scale.nPortIndex = kPortIndexOutput;
2392
2393 // Change display dimension only when necessary.
2394 if (OK == mOMX->getConfig(
2395 mNode,
2396 OMX_IndexConfigCommonScale,
2397 &scale, sizeof(scale))) {
2398 int32_t left, top, right, bottom;
2399 CHECK(mOutputFormat->findRect(kKeyCropRect,
2400 &left, &top,
2401 &right, &bottom));
2402
2403 // The scale is in 16.16 format.
2404 // scale 1.0 = 0x010000. When there is no
2405 // need to change the display, skip it.
2406 ALOGV("Get OMX_IndexConfigScale: 0x%lx/0x%lx",
2407 scale.xWidth, scale.xHeight);
2408
2409 if (scale.xWidth != 0x010000) {
2410 mOutputFormat->setInt32(kKeyDisplayWidth,
2411 ((right - left + 1) * scale.xWidth) >> 16);
2412 mOutputPortSettingsHaveChanged = true;
2413 }
2414
2415 if (scale.xHeight != 0x010000) {
2416 mOutputFormat->setInt32(kKeyDisplayHeight,
2417 ((bottom - top + 1) * scale.xHeight) >> 16);
2418 mOutputPortSettingsHaveChanged = true;
2419 }
2420 }
2421 }
2422 }
2423 break;
2424 }
2425
2426 #if 0
2427 case OMX_EventBufferFlag:
2428 {
2429 CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1);
2430
2431 if (data1 == kPortIndexOutput) {
2432 mNoMoreOutputData = true;
2433 }
2434 break;
2435 }
2436 #endif
2437
2438 default:
2439 {
2440 CODEC_LOGV("EVENT(%d, %ld, %ld)", event, data1, data2);
2441 break;
2442 }
2443 }
2444 }
2445
onCmdComplete(OMX_COMMANDTYPE cmd,OMX_U32 data)2446 void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) {
2447 switch (cmd) {
2448 case OMX_CommandStateSet:
2449 {
2450 onStateChange((OMX_STATETYPE)data);
2451 break;
2452 }
2453
2454 case OMX_CommandPortDisable:
2455 {
2456 OMX_U32 portIndex = data;
2457 CODEC_LOGV("PORT_DISABLED(%ld)", portIndex);
2458
2459 CHECK(mState == EXECUTING || mState == RECONFIGURING);
2460 CHECK_EQ((int)mPortStatus[portIndex], (int)DISABLING);
2461 CHECK_EQ(mPortBuffers[portIndex].size(), 0u);
2462
2463 mPortStatus[portIndex] = DISABLED;
2464
2465 if (mState == RECONFIGURING) {
2466 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
2467
2468 sp<MetaData> oldOutputFormat = mOutputFormat;
2469 initOutputFormat(mSource->getFormat());
2470
2471 // Don't notify clients if the output port settings change
2472 // wasn't of importance to them, i.e. it may be that just the
2473 // number of buffers has changed and nothing else.
2474 bool formatChanged = formatHasNotablyChanged(oldOutputFormat, mOutputFormat);
2475 if (!mOutputPortSettingsHaveChanged) {
2476 mOutputPortSettingsHaveChanged = formatChanged;
2477 }
2478
2479 status_t err = enablePortAsync(portIndex);
2480 if (err != OK) {
2481 CODEC_LOGE("enablePortAsync(%ld) failed (err = %d)", portIndex, err);
2482 setState(ERROR);
2483 } else {
2484 err = allocateBuffersOnPort(portIndex);
2485 if (err != OK) {
2486 CODEC_LOGE("allocateBuffersOnPort (%s) failed "
2487 "(err = %d)",
2488 portIndex == kPortIndexInput
2489 ? "input" : "output",
2490 err);
2491
2492 setState(ERROR);
2493 }
2494 }
2495 }
2496 break;
2497 }
2498
2499 case OMX_CommandPortEnable:
2500 {
2501 OMX_U32 portIndex = data;
2502 CODEC_LOGV("PORT_ENABLED(%ld)", portIndex);
2503
2504 CHECK(mState == EXECUTING || mState == RECONFIGURING);
2505 CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLING);
2506
2507 mPortStatus[portIndex] = ENABLED;
2508
2509 if (mState == RECONFIGURING) {
2510 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
2511
2512 setState(EXECUTING);
2513
2514 fillOutputBuffers();
2515 }
2516 break;
2517 }
2518
2519 case OMX_CommandFlush:
2520 {
2521 OMX_U32 portIndex = data;
2522
2523 CODEC_LOGV("FLUSH_DONE(%ld)", portIndex);
2524
2525 CHECK_EQ((int)mPortStatus[portIndex], (int)SHUTTING_DOWN);
2526 mPortStatus[portIndex] = ENABLED;
2527
2528 CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]),
2529 mPortBuffers[portIndex].size());
2530
2531 if (mSkipCutBuffer != NULL && mPortStatus[kPortIndexOutput] == ENABLED) {
2532 mSkipCutBuffer->clear();
2533 }
2534
2535 if (mState == RECONFIGURING) {
2536 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
2537
2538 disablePortAsync(portIndex);
2539 } else if (mState == EXECUTING_TO_IDLE) {
2540 if (mPortStatus[kPortIndexInput] == ENABLED
2541 && mPortStatus[kPortIndexOutput] == ENABLED) {
2542 CODEC_LOGV("Finished flushing both ports, now completing "
2543 "transition from EXECUTING to IDLE.");
2544
2545 mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
2546 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
2547
2548 status_t err =
2549 mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
2550 CHECK_EQ(err, (status_t)OK);
2551 }
2552 } else {
2553 // We're flushing both ports in preparation for seeking.
2554
2555 if (mPortStatus[kPortIndexInput] == ENABLED
2556 && mPortStatus[kPortIndexOutput] == ENABLED) {
2557 CODEC_LOGV("Finished flushing both ports, now continuing from"
2558 " seek-time.");
2559
2560 // We implicitly resume pulling on our upstream source.
2561 mPaused = false;
2562
2563 drainInputBuffers();
2564 fillOutputBuffers();
2565 }
2566
2567 if (mOutputPortSettingsChangedPending) {
2568 CODEC_LOGV(
2569 "Honoring deferred output port settings change.");
2570
2571 mOutputPortSettingsChangedPending = false;
2572 onPortSettingsChanged(kPortIndexOutput);
2573 }
2574 }
2575
2576 break;
2577 }
2578
2579 default:
2580 {
2581 CODEC_LOGV("CMD_COMPLETE(%d, %ld)", cmd, data);
2582 break;
2583 }
2584 }
2585 }
2586
onStateChange(OMX_STATETYPE newState)2587 void OMXCodec::onStateChange(OMX_STATETYPE newState) {
2588 CODEC_LOGV("onStateChange %d", newState);
2589
2590 switch (newState) {
2591 case OMX_StateIdle:
2592 {
2593 CODEC_LOGV("Now Idle.");
2594 if (mState == LOADED_TO_IDLE) {
2595 status_t err = mOMX->sendCommand(
2596 mNode, OMX_CommandStateSet, OMX_StateExecuting);
2597
2598 CHECK_EQ(err, (status_t)OK);
2599
2600 setState(IDLE_TO_EXECUTING);
2601 } else {
2602 CHECK_EQ((int)mState, (int)EXECUTING_TO_IDLE);
2603
2604 if (countBuffersWeOwn(mPortBuffers[kPortIndexInput]) !=
2605 mPortBuffers[kPortIndexInput].size()) {
2606 ALOGE("Codec did not return all input buffers "
2607 "(received %d / %d)",
2608 countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
2609 mPortBuffers[kPortIndexInput].size());
2610 TRESPASS();
2611 }
2612
2613 if (countBuffersWeOwn(mPortBuffers[kPortIndexOutput]) !=
2614 mPortBuffers[kPortIndexOutput].size()) {
2615 ALOGE("Codec did not return all output buffers "
2616 "(received %d / %d)",
2617 countBuffersWeOwn(mPortBuffers[kPortIndexOutput]),
2618 mPortBuffers[kPortIndexOutput].size());
2619 TRESPASS();
2620 }
2621
2622 status_t err = mOMX->sendCommand(
2623 mNode, OMX_CommandStateSet, OMX_StateLoaded);
2624
2625 CHECK_EQ(err, (status_t)OK);
2626
2627 err = freeBuffersOnPort(kPortIndexInput);
2628 CHECK_EQ(err, (status_t)OK);
2629
2630 err = freeBuffersOnPort(kPortIndexOutput);
2631 CHECK_EQ(err, (status_t)OK);
2632
2633 mPortStatus[kPortIndexInput] = ENABLED;
2634 mPortStatus[kPortIndexOutput] = ENABLED;
2635
2636 if ((mFlags & kEnableGrallocUsageProtected) &&
2637 mNativeWindow != NULL) {
2638 // We push enough 1x1 blank buffers to ensure that one of
2639 // them has made it to the display. This allows the OMX
2640 // component teardown to zero out any protected buffers
2641 // without the risk of scanning out one of those buffers.
2642 pushBlankBuffersToNativeWindow();
2643 }
2644
2645 setState(IDLE_TO_LOADED);
2646 }
2647 break;
2648 }
2649
2650 case OMX_StateExecuting:
2651 {
2652 CHECK_EQ((int)mState, (int)IDLE_TO_EXECUTING);
2653
2654 CODEC_LOGV("Now Executing.");
2655
2656 mOutputPortSettingsChangedPending = false;
2657
2658 setState(EXECUTING);
2659
2660 // Buffers will be submitted to the component in the first
2661 // call to OMXCodec::read as mInitialBufferSubmit is true at
2662 // this point. This ensures that this on_message call returns,
2663 // releases the lock and ::init can notice the state change and
2664 // itself return.
2665 break;
2666 }
2667
2668 case OMX_StateLoaded:
2669 {
2670 CHECK_EQ((int)mState, (int)IDLE_TO_LOADED);
2671
2672 CODEC_LOGV("Now Loaded.");
2673
2674 setState(LOADED);
2675 break;
2676 }
2677
2678 case OMX_StateInvalid:
2679 {
2680 setState(ERROR);
2681 break;
2682 }
2683
2684 default:
2685 {
2686 CHECK(!"should not be here.");
2687 break;
2688 }
2689 }
2690 }
2691
2692 // static
countBuffersWeOwn(const Vector<BufferInfo> & buffers)2693 size_t OMXCodec::countBuffersWeOwn(const Vector<BufferInfo> &buffers) {
2694 size_t n = 0;
2695 for (size_t i = 0; i < buffers.size(); ++i) {
2696 if (buffers[i].mStatus != OWNED_BY_COMPONENT) {
2697 ++n;
2698 }
2699 }
2700
2701 return n;
2702 }
2703
freeBuffersOnPort(OMX_U32 portIndex,bool onlyThoseWeOwn)2704 status_t OMXCodec::freeBuffersOnPort(
2705 OMX_U32 portIndex, bool onlyThoseWeOwn) {
2706 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
2707
2708 status_t stickyErr = OK;
2709
2710 for (size_t i = buffers->size(); i-- > 0;) {
2711 BufferInfo *info = &buffers->editItemAt(i);
2712
2713 if (onlyThoseWeOwn && info->mStatus == OWNED_BY_COMPONENT) {
2714 continue;
2715 }
2716
2717 CHECK(info->mStatus == OWNED_BY_US
2718 || info->mStatus == OWNED_BY_NATIVE_WINDOW);
2719
2720 CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex);
2721
2722 status_t err = freeBuffer(portIndex, i);
2723
2724 if (err != OK) {
2725 stickyErr = err;
2726 }
2727
2728 }
2729
2730 CHECK(onlyThoseWeOwn || buffers->isEmpty());
2731
2732 return stickyErr;
2733 }
2734
freeBuffer(OMX_U32 portIndex,size_t bufIndex)2735 status_t OMXCodec::freeBuffer(OMX_U32 portIndex, size_t bufIndex) {
2736 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
2737
2738 BufferInfo *info = &buffers->editItemAt(bufIndex);
2739
2740 status_t err = mOMX->freeBuffer(mNode, portIndex, info->mBuffer);
2741
2742 if (err == OK && info->mMediaBuffer != NULL) {
2743 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
2744 info->mMediaBuffer->setObserver(NULL);
2745
2746 // Make sure nobody but us owns this buffer at this point.
2747 CHECK_EQ(info->mMediaBuffer->refcount(), 0);
2748
2749 // Cancel the buffer if it belongs to an ANativeWindow.
2750 sp<GraphicBuffer> graphicBuffer = info->mMediaBuffer->graphicBuffer();
2751 if (info->mStatus == OWNED_BY_US && graphicBuffer != 0) {
2752 err = cancelBufferToNativeWindow(info);
2753 }
2754
2755 info->mMediaBuffer->release();
2756 info->mMediaBuffer = NULL;
2757 }
2758
2759 if (err == OK) {
2760 buffers->removeAt(bufIndex);
2761 }
2762
2763 return err;
2764 }
2765
onPortSettingsChanged(OMX_U32 portIndex)2766 void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) {
2767 CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex);
2768
2769 CHECK_EQ((int)mState, (int)EXECUTING);
2770 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
2771 CHECK(!mOutputPortSettingsChangedPending);
2772
2773 if (mPortStatus[kPortIndexOutput] != ENABLED) {
2774 CODEC_LOGV("Deferring output port settings change.");
2775 mOutputPortSettingsChangedPending = true;
2776 return;
2777 }
2778
2779 setState(RECONFIGURING);
2780
2781 if (mQuirks & kNeedsFlushBeforeDisable) {
2782 if (!flushPortAsync(portIndex)) {
2783 onCmdComplete(OMX_CommandFlush, portIndex);
2784 }
2785 } else {
2786 disablePortAsync(portIndex);
2787 }
2788 }
2789
flushPortAsync(OMX_U32 portIndex)2790 bool OMXCodec::flushPortAsync(OMX_U32 portIndex) {
2791 CHECK(mState == EXECUTING || mState == RECONFIGURING
2792 || mState == EXECUTING_TO_IDLE);
2793
2794 CODEC_LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.",
2795 portIndex, countBuffersWeOwn(mPortBuffers[portIndex]),
2796 mPortBuffers[portIndex].size());
2797
2798 CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLED);
2799 mPortStatus[portIndex] = SHUTTING_DOWN;
2800
2801 if ((mQuirks & kRequiresFlushCompleteEmulation)
2802 && countBuffersWeOwn(mPortBuffers[portIndex])
2803 == mPortBuffers[portIndex].size()) {
2804 // No flush is necessary and this component fails to send a
2805 // flush-complete event in this case.
2806
2807 return false;
2808 }
2809
2810 status_t err =
2811 mOMX->sendCommand(mNode, OMX_CommandFlush, portIndex);
2812 CHECK_EQ(err, (status_t)OK);
2813
2814 return true;
2815 }
2816
disablePortAsync(OMX_U32 portIndex)2817 void OMXCodec::disablePortAsync(OMX_U32 portIndex) {
2818 CHECK(mState == EXECUTING || mState == RECONFIGURING);
2819
2820 CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLED);
2821 mPortStatus[portIndex] = DISABLING;
2822
2823 CODEC_LOGV("sending OMX_CommandPortDisable(%ld)", portIndex);
2824 status_t err =
2825 mOMX->sendCommand(mNode, OMX_CommandPortDisable, portIndex);
2826 CHECK_EQ(err, (status_t)OK);
2827
2828 freeBuffersOnPort(portIndex, true);
2829 }
2830
enablePortAsync(OMX_U32 portIndex)2831 status_t OMXCodec::enablePortAsync(OMX_U32 portIndex) {
2832 CHECK(mState == EXECUTING || mState == RECONFIGURING);
2833
2834 CHECK_EQ((int)mPortStatus[portIndex], (int)DISABLED);
2835 mPortStatus[portIndex] = ENABLING;
2836
2837 CODEC_LOGV("sending OMX_CommandPortEnable(%ld)", portIndex);
2838 return mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex);
2839 }
2840
fillOutputBuffers()2841 void OMXCodec::fillOutputBuffers() {
2842 CHECK_EQ((int)mState, (int)EXECUTING);
2843
2844 // This is a workaround for some decoders not properly reporting
2845 // end-of-output-stream. If we own all input buffers and also own
2846 // all output buffers and we already signalled end-of-input-stream,
2847 // the end-of-output-stream is implied.
2848 if (mSignalledEOS
2849 && countBuffersWeOwn(mPortBuffers[kPortIndexInput])
2850 == mPortBuffers[kPortIndexInput].size()
2851 && countBuffersWeOwn(mPortBuffers[kPortIndexOutput])
2852 == mPortBuffers[kPortIndexOutput].size()) {
2853 mNoMoreOutputData = true;
2854 mBufferFilled.signal();
2855
2856 return;
2857 }
2858
2859 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
2860 for (size_t i = 0; i < buffers->size(); ++i) {
2861 BufferInfo *info = &buffers->editItemAt(i);
2862 if (info->mStatus == OWNED_BY_US) {
2863 fillOutputBuffer(&buffers->editItemAt(i));
2864 }
2865 }
2866 }
2867
drainInputBuffers()2868 void OMXCodec::drainInputBuffers() {
2869 CHECK(mState == EXECUTING || mState == RECONFIGURING);
2870
2871 if (mFlags & kUseSecureInputBuffers) {
2872 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
2873 for (size_t i = 0; i < buffers->size(); ++i) {
2874 if (!drainAnyInputBuffer()
2875 || (mFlags & kOnlySubmitOneInputBufferAtOneTime)) {
2876 break;
2877 }
2878 }
2879 } else {
2880 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
2881 for (size_t i = 0; i < buffers->size(); ++i) {
2882 BufferInfo *info = &buffers->editItemAt(i);
2883
2884 if (info->mStatus != OWNED_BY_US) {
2885 continue;
2886 }
2887
2888 if (!drainInputBuffer(info)) {
2889 break;
2890 }
2891
2892 if (mFlags & kOnlySubmitOneInputBufferAtOneTime) {
2893 break;
2894 }
2895 }
2896 }
2897 }
2898
drainAnyInputBuffer()2899 bool OMXCodec::drainAnyInputBuffer() {
2900 return drainInputBuffer((BufferInfo *)NULL);
2901 }
2902
findInputBufferByDataPointer(void * ptr)2903 OMXCodec::BufferInfo *OMXCodec::findInputBufferByDataPointer(void *ptr) {
2904 Vector<BufferInfo> *infos = &mPortBuffers[kPortIndexInput];
2905 for (size_t i = 0; i < infos->size(); ++i) {
2906 BufferInfo *info = &infos->editItemAt(i);
2907
2908 if (info->mData == ptr) {
2909 CODEC_LOGV(
2910 "input buffer data ptr = %p, buffer_id = %p",
2911 ptr,
2912 info->mBuffer);
2913
2914 return info;
2915 }
2916 }
2917
2918 TRESPASS();
2919 }
2920
findEmptyInputBuffer()2921 OMXCodec::BufferInfo *OMXCodec::findEmptyInputBuffer() {
2922 Vector<BufferInfo> *infos = &mPortBuffers[kPortIndexInput];
2923 for (size_t i = 0; i < infos->size(); ++i) {
2924 BufferInfo *info = &infos->editItemAt(i);
2925
2926 if (info->mStatus == OWNED_BY_US) {
2927 return info;
2928 }
2929 }
2930
2931 TRESPASS();
2932 }
2933
drainInputBuffer(BufferInfo * info)2934 bool OMXCodec::drainInputBuffer(BufferInfo *info) {
2935 if (info != NULL) {
2936 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
2937 }
2938
2939 if (mSignalledEOS) {
2940 return false;
2941 }
2942
2943 if (mCodecSpecificDataIndex < mCodecSpecificData.size()) {
2944 CHECK(!(mFlags & kUseSecureInputBuffers));
2945
2946 const CodecSpecificData *specific =
2947 mCodecSpecificData[mCodecSpecificDataIndex];
2948
2949 size_t size = specific->mSize;
2950
2951 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME)
2952 && !(mQuirks & kWantsNALFragments)) {
2953 static const uint8_t kNALStartCode[4] =
2954 { 0x00, 0x00, 0x00, 0x01 };
2955
2956 CHECK(info->mSize >= specific->mSize + 4);
2957
2958 size += 4;
2959
2960 memcpy(info->mData, kNALStartCode, 4);
2961 memcpy((uint8_t *)info->mData + 4,
2962 specific->mData, specific->mSize);
2963 } else {
2964 CHECK(info->mSize >= specific->mSize);
2965 memcpy(info->mData, specific->mData, specific->mSize);
2966 }
2967
2968 mNoMoreOutputData = false;
2969
2970 CODEC_LOGV("calling emptyBuffer with codec specific data");
2971
2972 status_t err = mOMX->emptyBuffer(
2973 mNode, info->mBuffer, 0, size,
2974 OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG,
2975 0);
2976 CHECK_EQ(err, (status_t)OK);
2977
2978 info->mStatus = OWNED_BY_COMPONENT;
2979
2980 ++mCodecSpecificDataIndex;
2981 return true;
2982 }
2983
2984 if (mPaused) {
2985 return false;
2986 }
2987
2988 status_t err;
2989
2990 bool signalEOS = false;
2991 int64_t timestampUs = 0;
2992
2993 size_t offset = 0;
2994 int32_t n = 0;
2995
2996
2997 for (;;) {
2998 MediaBuffer *srcBuffer;
2999 if (mSeekTimeUs >= 0) {
3000 if (mLeftOverBuffer) {
3001 mLeftOverBuffer->release();
3002 mLeftOverBuffer = NULL;
3003 }
3004
3005 MediaSource::ReadOptions options;
3006 options.setSeekTo(mSeekTimeUs, mSeekMode);
3007
3008 mSeekTimeUs = -1;
3009 mSeekMode = ReadOptions::SEEK_CLOSEST_SYNC;
3010 mBufferFilled.signal();
3011
3012 err = mSource->read(&srcBuffer, &options);
3013
3014 if (err == OK) {
3015 int64_t targetTimeUs;
3016 if (srcBuffer->meta_data()->findInt64(
3017 kKeyTargetTime, &targetTimeUs)
3018 && targetTimeUs >= 0) {
3019 CODEC_LOGV("targetTimeUs = %lld us", targetTimeUs);
3020 mTargetTimeUs = targetTimeUs;
3021 } else {
3022 mTargetTimeUs = -1;
3023 }
3024 }
3025 } else if (mLeftOverBuffer) {
3026 srcBuffer = mLeftOverBuffer;
3027 mLeftOverBuffer = NULL;
3028
3029 err = OK;
3030 } else {
3031 err = mSource->read(&srcBuffer);
3032 }
3033
3034 if (err != OK) {
3035 signalEOS = true;
3036 mFinalStatus = err;
3037 mSignalledEOS = true;
3038 mBufferFilled.signal();
3039 break;
3040 }
3041
3042 if (mFlags & kUseSecureInputBuffers) {
3043 info = findInputBufferByDataPointer(srcBuffer->data());
3044 CHECK(info != NULL);
3045 }
3046
3047 size_t remainingBytes = info->mSize - offset;
3048
3049 if (srcBuffer->range_length() > remainingBytes) {
3050 if (offset == 0) {
3051 CODEC_LOGE(
3052 "Codec's input buffers are too small to accomodate "
3053 "buffer read from source (info->mSize = %d, srcLength = %d)",
3054 info->mSize, srcBuffer->range_length());
3055
3056 srcBuffer->release();
3057 srcBuffer = NULL;
3058
3059 setState(ERROR);
3060 return false;
3061 }
3062
3063 mLeftOverBuffer = srcBuffer;
3064 break;
3065 }
3066
3067 bool releaseBuffer = true;
3068 if (mIsEncoder && (mQuirks & kAvoidMemcopyInputRecordingFrames)) {
3069 CHECK(mOMXLivesLocally && offset == 0);
3070
3071 OMX_BUFFERHEADERTYPE *header =
3072 (OMX_BUFFERHEADERTYPE *)info->mBuffer;
3073
3074 CHECK(header->pBuffer == info->mData);
3075
3076 header->pBuffer =
3077 (OMX_U8 *)srcBuffer->data() + srcBuffer->range_offset();
3078
3079 releaseBuffer = false;
3080 info->mMediaBuffer = srcBuffer;
3081 } else {
3082 if (mFlags & kStoreMetaDataInVideoBuffers) {
3083 releaseBuffer = false;
3084 info->mMediaBuffer = srcBuffer;
3085 }
3086
3087 if (mFlags & kUseSecureInputBuffers) {
3088 // Data in "info" is already provided at this time.
3089
3090 releaseBuffer = false;
3091
3092 CHECK(info->mMediaBuffer == NULL);
3093 info->mMediaBuffer = srcBuffer;
3094 } else {
3095 CHECK(srcBuffer->data() != NULL) ;
3096 memcpy((uint8_t *)info->mData + offset,
3097 (const uint8_t *)srcBuffer->data()
3098 + srcBuffer->range_offset(),
3099 srcBuffer->range_length());
3100 }
3101 }
3102
3103 int64_t lastBufferTimeUs;
3104 CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &lastBufferTimeUs));
3105 CHECK(lastBufferTimeUs >= 0);
3106 if (mIsEncoder && mIsVideo) {
3107 mDecodingTimeList.push_back(lastBufferTimeUs);
3108 }
3109
3110 if (offset == 0) {
3111 timestampUs = lastBufferTimeUs;
3112 }
3113
3114 offset += srcBuffer->range_length();
3115
3116 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_VORBIS, mMIME)) {
3117 CHECK(!(mQuirks & kSupportsMultipleFramesPerInputBuffer));
3118 CHECK_GE(info->mSize, offset + sizeof(int32_t));
3119
3120 int32_t numPageSamples;
3121 if (!srcBuffer->meta_data()->findInt32(
3122 kKeyValidSamples, &numPageSamples)) {
3123 numPageSamples = -1;
3124 }
3125
3126 memcpy((uint8_t *)info->mData + offset,
3127 &numPageSamples,
3128 sizeof(numPageSamples));
3129
3130 offset += sizeof(numPageSamples);
3131 }
3132
3133 if (releaseBuffer) {
3134 srcBuffer->release();
3135 srcBuffer = NULL;
3136 }
3137
3138 ++n;
3139
3140 if (!(mQuirks & kSupportsMultipleFramesPerInputBuffer)) {
3141 break;
3142 }
3143
3144 int64_t coalescedDurationUs = lastBufferTimeUs - timestampUs;
3145
3146 if (coalescedDurationUs > 250000ll) {
3147 // Don't coalesce more than 250ms worth of encoded data at once.
3148 break;
3149 }
3150 }
3151
3152 if (n > 1) {
3153 ALOGV("coalesced %d frames into one input buffer", n);
3154 }
3155
3156 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3157
3158 if (signalEOS) {
3159 flags |= OMX_BUFFERFLAG_EOS;
3160 } else {
3161 mNoMoreOutputData = false;
3162 }
3163
3164 if (info == NULL) {
3165 CHECK(mFlags & kUseSecureInputBuffers);
3166 CHECK(signalEOS);
3167
3168 // This is fishy, there's still a MediaBuffer corresponding to this
3169 // info available to the source at this point even though we're going
3170 // to use it to signal EOS to the codec.
3171 info = findEmptyInputBuffer();
3172 }
3173
3174 CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d), "
3175 "timestamp %lld us (%.2f secs)",
3176 info->mBuffer, offset,
3177 timestampUs, timestampUs / 1E6);
3178
3179 err = mOMX->emptyBuffer(
3180 mNode, info->mBuffer, 0, offset,
3181 flags, timestampUs);
3182
3183 if (err != OK) {
3184 setState(ERROR);
3185 return false;
3186 }
3187
3188 info->mStatus = OWNED_BY_COMPONENT;
3189
3190 return true;
3191 }
3192
fillOutputBuffer(BufferInfo * info)3193 void OMXCodec::fillOutputBuffer(BufferInfo *info) {
3194 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
3195
3196 if (mNoMoreOutputData) {
3197 CODEC_LOGV("There is no more output data available, not "
3198 "calling fillOutputBuffer");
3199 return;
3200 }
3201
3202 if (info->mMediaBuffer != NULL) {
3203 sp<GraphicBuffer> graphicBuffer = info->mMediaBuffer->graphicBuffer();
3204 if (graphicBuffer != 0) {
3205 // When using a native buffer we need to lock the buffer before
3206 // giving it to OMX.
3207 CODEC_LOGV("Calling lockBuffer on %p", info->mBuffer);
3208 int err = mNativeWindow->lockBuffer(mNativeWindow.get(),
3209 graphicBuffer.get());
3210 if (err != 0) {
3211 CODEC_LOGE("lockBuffer failed w/ error 0x%08x", err);
3212
3213 setState(ERROR);
3214 return;
3215 }
3216 }
3217 }
3218
3219 CODEC_LOGV("Calling fillBuffer on buffer %p", info->mBuffer);
3220 status_t err = mOMX->fillBuffer(mNode, info->mBuffer);
3221
3222 if (err != OK) {
3223 CODEC_LOGE("fillBuffer failed w/ error 0x%08x", err);
3224
3225 setState(ERROR);
3226 return;
3227 }
3228
3229 info->mStatus = OWNED_BY_COMPONENT;
3230 }
3231
drainInputBuffer(IOMX::buffer_id buffer)3232 bool OMXCodec::drainInputBuffer(IOMX::buffer_id buffer) {
3233 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
3234 for (size_t i = 0; i < buffers->size(); ++i) {
3235 if ((*buffers)[i].mBuffer == buffer) {
3236 return drainInputBuffer(&buffers->editItemAt(i));
3237 }
3238 }
3239
3240 CHECK(!"should not be here.");
3241
3242 return false;
3243 }
3244
fillOutputBuffer(IOMX::buffer_id buffer)3245 void OMXCodec::fillOutputBuffer(IOMX::buffer_id buffer) {
3246 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
3247 for (size_t i = 0; i < buffers->size(); ++i) {
3248 if ((*buffers)[i].mBuffer == buffer) {
3249 fillOutputBuffer(&buffers->editItemAt(i));
3250 return;
3251 }
3252 }
3253
3254 CHECK(!"should not be here.");
3255 }
3256
setState(State newState)3257 void OMXCodec::setState(State newState) {
3258 mState = newState;
3259 mAsyncCompletion.signal();
3260
3261 // This may cause some spurious wakeups but is necessary to
3262 // unblock the reader if we enter ERROR state.
3263 mBufferFilled.signal();
3264 }
3265
waitForBufferFilled_l()3266 status_t OMXCodec::waitForBufferFilled_l() {
3267
3268 if (mIsEncoder) {
3269 // For timelapse video recording, the timelapse video recording may
3270 // not send an input frame for a _long_ time. Do not use timeout
3271 // for video encoding.
3272 return mBufferFilled.wait(mLock);
3273 }
3274 status_t err = mBufferFilled.waitRelative(mLock, kBufferFilledEventTimeOutNs);
3275 if (err != OK) {
3276 CODEC_LOGE("Timed out waiting for output buffers: %d/%d",
3277 countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
3278 countBuffersWeOwn(mPortBuffers[kPortIndexOutput]));
3279 }
3280 return err;
3281 }
3282
setRawAudioFormat(OMX_U32 portIndex,int32_t sampleRate,int32_t numChannels)3283 void OMXCodec::setRawAudioFormat(
3284 OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
3285
3286 // port definition
3287 OMX_PARAM_PORTDEFINITIONTYPE def;
3288 InitOMXParams(&def);
3289 def.nPortIndex = portIndex;
3290 status_t err = mOMX->getParameter(
3291 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3292 CHECK_EQ(err, (status_t)OK);
3293 def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
3294 CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition,
3295 &def, sizeof(def)), (status_t)OK);
3296
3297 // pcm param
3298 OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
3299 InitOMXParams(&pcmParams);
3300 pcmParams.nPortIndex = portIndex;
3301
3302 err = mOMX->getParameter(
3303 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
3304
3305 CHECK_EQ(err, (status_t)OK);
3306
3307 pcmParams.nChannels = numChannels;
3308 pcmParams.eNumData = OMX_NumericalDataSigned;
3309 pcmParams.bInterleaved = OMX_TRUE;
3310 pcmParams.nBitPerSample = 16;
3311 pcmParams.nSamplingRate = sampleRate;
3312 pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
3313
3314 CHECK_EQ(getOMXChannelMapping(
3315 numChannels, pcmParams.eChannelMapping), (status_t)OK);
3316
3317 err = mOMX->setParameter(
3318 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
3319
3320 CHECK_EQ(err, (status_t)OK);
3321 }
3322
pickModeFromBitRate(bool isAMRWB,int32_t bps)3323 static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(bool isAMRWB, int32_t bps) {
3324 if (isAMRWB) {
3325 if (bps <= 6600) {
3326 return OMX_AUDIO_AMRBandModeWB0;
3327 } else if (bps <= 8850) {
3328 return OMX_AUDIO_AMRBandModeWB1;
3329 } else if (bps <= 12650) {
3330 return OMX_AUDIO_AMRBandModeWB2;
3331 } else if (bps <= 14250) {
3332 return OMX_AUDIO_AMRBandModeWB3;
3333 } else if (bps <= 15850) {
3334 return OMX_AUDIO_AMRBandModeWB4;
3335 } else if (bps <= 18250) {
3336 return OMX_AUDIO_AMRBandModeWB5;
3337 } else if (bps <= 19850) {
3338 return OMX_AUDIO_AMRBandModeWB6;
3339 } else if (bps <= 23050) {
3340 return OMX_AUDIO_AMRBandModeWB7;
3341 }
3342
3343 // 23850 bps
3344 return OMX_AUDIO_AMRBandModeWB8;
3345 } else { // AMRNB
3346 if (bps <= 4750) {
3347 return OMX_AUDIO_AMRBandModeNB0;
3348 } else if (bps <= 5150) {
3349 return OMX_AUDIO_AMRBandModeNB1;
3350 } else if (bps <= 5900) {
3351 return OMX_AUDIO_AMRBandModeNB2;
3352 } else if (bps <= 6700) {
3353 return OMX_AUDIO_AMRBandModeNB3;
3354 } else if (bps <= 7400) {
3355 return OMX_AUDIO_AMRBandModeNB4;
3356 } else if (bps <= 7950) {
3357 return OMX_AUDIO_AMRBandModeNB5;
3358 } else if (bps <= 10200) {
3359 return OMX_AUDIO_AMRBandModeNB6;
3360 }
3361
3362 // 12200 bps
3363 return OMX_AUDIO_AMRBandModeNB7;
3364 }
3365 }
3366
setAMRFormat(bool isWAMR,int32_t bitRate)3367 void OMXCodec::setAMRFormat(bool isWAMR, int32_t bitRate) {
3368 OMX_U32 portIndex = mIsEncoder ? kPortIndexOutput : kPortIndexInput;
3369
3370 OMX_AUDIO_PARAM_AMRTYPE def;
3371 InitOMXParams(&def);
3372 def.nPortIndex = portIndex;
3373
3374 status_t err =
3375 mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
3376
3377 CHECK_EQ(err, (status_t)OK);
3378
3379 def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
3380
3381 def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitRate);
3382 err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
3383 CHECK_EQ(err, (status_t)OK);
3384
3385 ////////////////////////
3386
3387 if (mIsEncoder) {
3388 sp<MetaData> format = mSource->getFormat();
3389 int32_t sampleRate;
3390 int32_t numChannels;
3391 CHECK(format->findInt32(kKeySampleRate, &sampleRate));
3392 CHECK(format->findInt32(kKeyChannelCount, &numChannels));
3393
3394 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
3395 }
3396 }
3397
setAACFormat(int32_t numChannels,int32_t sampleRate,int32_t bitRate,int32_t aacProfile,bool isADTS)3398 status_t OMXCodec::setAACFormat(
3399 int32_t numChannels, int32_t sampleRate, int32_t bitRate, int32_t aacProfile, bool isADTS) {
3400 if (numChannels > 2) {
3401 ALOGW("Number of channels: (%d) \n", numChannels);
3402 }
3403
3404 if (mIsEncoder) {
3405 if (isADTS) {
3406 return -EINVAL;
3407 }
3408
3409 //////////////// input port ////////////////////
3410 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
3411
3412 //////////////// output port ////////////////////
3413 // format
3414 OMX_AUDIO_PARAM_PORTFORMATTYPE format;
3415 InitOMXParams(&format);
3416 format.nPortIndex = kPortIndexOutput;
3417 format.nIndex = 0;
3418 status_t err = OMX_ErrorNone;
3419 while (OMX_ErrorNone == err) {
3420 CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioPortFormat,
3421 &format, sizeof(format)), (status_t)OK);
3422 if (format.eEncoding == OMX_AUDIO_CodingAAC) {
3423 break;
3424 }
3425 format.nIndex++;
3426 }
3427 CHECK_EQ((status_t)OK, err);
3428 CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamAudioPortFormat,
3429 &format, sizeof(format)), (status_t)OK);
3430
3431 // port definition
3432 OMX_PARAM_PORTDEFINITIONTYPE def;
3433 InitOMXParams(&def);
3434 def.nPortIndex = kPortIndexOutput;
3435 CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamPortDefinition,
3436 &def, sizeof(def)), (status_t)OK);
3437 def.format.audio.bFlagErrorConcealment = OMX_TRUE;
3438 def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
3439 CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition,
3440 &def, sizeof(def)), (status_t)OK);
3441
3442 // profile
3443 OMX_AUDIO_PARAM_AACPROFILETYPE profile;
3444 InitOMXParams(&profile);
3445 profile.nPortIndex = kPortIndexOutput;
3446 CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioAac,
3447 &profile, sizeof(profile)), (status_t)OK);
3448 profile.nChannels = numChannels;
3449 profile.eChannelMode = (numChannels == 1?
3450 OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo);
3451 profile.nSampleRate = sampleRate;
3452 profile.nBitRate = bitRate;
3453 profile.nAudioBandWidth = 0;
3454 profile.nFrameLength = 0;
3455 profile.nAACtools = OMX_AUDIO_AACToolAll;
3456 profile.nAACERtools = OMX_AUDIO_AACERNone;
3457 profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
3458 profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
3459 err = mOMX->setParameter(mNode, OMX_IndexParamAudioAac,
3460 &profile, sizeof(profile));
3461
3462 if (err != OK) {
3463 CODEC_LOGE("setParameter('OMX_IndexParamAudioAac') failed "
3464 "(err = %d)",
3465 err);
3466 return err;
3467 }
3468 } else {
3469 OMX_AUDIO_PARAM_AACPROFILETYPE profile;
3470 InitOMXParams(&profile);
3471 profile.nPortIndex = kPortIndexInput;
3472
3473 status_t err = mOMX->getParameter(
3474 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
3475 CHECK_EQ(err, (status_t)OK);
3476
3477 profile.nChannels = numChannels;
3478 profile.nSampleRate = sampleRate;
3479
3480 profile.eAACStreamFormat =
3481 isADTS
3482 ? OMX_AUDIO_AACStreamFormatMP4ADTS
3483 : OMX_AUDIO_AACStreamFormatMP4FF;
3484
3485 err = mOMX->setParameter(
3486 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
3487
3488 if (err != OK) {
3489 CODEC_LOGE("setParameter('OMX_IndexParamAudioAac') failed "
3490 "(err = %d)",
3491 err);
3492 return err;
3493 }
3494 }
3495
3496 return OK;
3497 }
3498
setG711Format(int32_t numChannels)3499 void OMXCodec::setG711Format(int32_t numChannels) {
3500 CHECK(!mIsEncoder);
3501 setRawAudioFormat(kPortIndexInput, 8000, numChannels);
3502 }
3503
setImageOutputFormat(OMX_COLOR_FORMATTYPE format,OMX_U32 width,OMX_U32 height)3504 void OMXCodec::setImageOutputFormat(
3505 OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) {
3506 CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height);
3507
3508 #if 0
3509 OMX_INDEXTYPE index;
3510 status_t err = mOMX->get_extension_index(
3511 mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index);
3512 CHECK_EQ(err, (status_t)OK);
3513
3514 err = mOMX->set_config(mNode, index, &format, sizeof(format));
3515 CHECK_EQ(err, (status_t)OK);
3516 #endif
3517
3518 OMX_PARAM_PORTDEFINITIONTYPE def;
3519 InitOMXParams(&def);
3520 def.nPortIndex = kPortIndexOutput;
3521
3522 status_t err = mOMX->getParameter(
3523 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3524 CHECK_EQ(err, (status_t)OK);
3525
3526 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainImage);
3527
3528 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
3529
3530 CHECK_EQ((int)imageDef->eCompressionFormat, (int)OMX_IMAGE_CodingUnused);
3531 imageDef->eColorFormat = format;
3532 imageDef->nFrameWidth = width;
3533 imageDef->nFrameHeight = height;
3534
3535 switch (format) {
3536 case OMX_COLOR_FormatYUV420PackedPlanar:
3537 case OMX_COLOR_FormatYUV411Planar:
3538 {
3539 def.nBufferSize = (width * height * 3) / 2;
3540 break;
3541 }
3542
3543 case OMX_COLOR_FormatCbYCrY:
3544 {
3545 def.nBufferSize = width * height * 2;
3546 break;
3547 }
3548
3549 case OMX_COLOR_Format32bitARGB8888:
3550 {
3551 def.nBufferSize = width * height * 4;
3552 break;
3553 }
3554
3555 case OMX_COLOR_Format16bitARGB4444:
3556 case OMX_COLOR_Format16bitARGB1555:
3557 case OMX_COLOR_Format16bitRGB565:
3558 case OMX_COLOR_Format16bitBGR565:
3559 {
3560 def.nBufferSize = width * height * 2;
3561 break;
3562 }
3563
3564 default:
3565 CHECK(!"Should not be here. Unknown color format.");
3566 break;
3567 }
3568
3569 def.nBufferCountActual = def.nBufferCountMin;
3570
3571 err = mOMX->setParameter(
3572 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3573 CHECK_EQ(err, (status_t)OK);
3574 }
3575
setJPEGInputFormat(OMX_U32 width,OMX_U32 height,OMX_U32 compressedSize)3576 void OMXCodec::setJPEGInputFormat(
3577 OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) {
3578 OMX_PARAM_PORTDEFINITIONTYPE def;
3579 InitOMXParams(&def);
3580 def.nPortIndex = kPortIndexInput;
3581
3582 status_t err = mOMX->getParameter(
3583 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3584 CHECK_EQ(err, (status_t)OK);
3585
3586 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainImage);
3587 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
3588
3589 CHECK_EQ((int)imageDef->eCompressionFormat, (int)OMX_IMAGE_CodingJPEG);
3590 imageDef->nFrameWidth = width;
3591 imageDef->nFrameHeight = height;
3592
3593 def.nBufferSize = compressedSize;
3594 def.nBufferCountActual = def.nBufferCountMin;
3595
3596 err = mOMX->setParameter(
3597 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3598 CHECK_EQ(err, (status_t)OK);
3599 }
3600
addCodecSpecificData(const void * data,size_t size)3601 void OMXCodec::addCodecSpecificData(const void *data, size_t size) {
3602 CodecSpecificData *specific =
3603 (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1);
3604
3605 specific->mSize = size;
3606 memcpy(specific->mData, data, size);
3607
3608 mCodecSpecificData.push(specific);
3609 }
3610
clearCodecSpecificData()3611 void OMXCodec::clearCodecSpecificData() {
3612 for (size_t i = 0; i < mCodecSpecificData.size(); ++i) {
3613 free(mCodecSpecificData.editItemAt(i));
3614 }
3615 mCodecSpecificData.clear();
3616 mCodecSpecificDataIndex = 0;
3617 }
3618
start(MetaData * meta)3619 status_t OMXCodec::start(MetaData *meta) {
3620 Mutex::Autolock autoLock(mLock);
3621
3622 if (mState != LOADED) {
3623 return UNKNOWN_ERROR;
3624 }
3625
3626 sp<MetaData> params = new MetaData;
3627 if (mQuirks & kWantsNALFragments) {
3628 params->setInt32(kKeyWantsNALFragments, true);
3629 }
3630 if (meta) {
3631 int64_t startTimeUs = 0;
3632 int64_t timeUs;
3633 if (meta->findInt64(kKeyTime, &timeUs)) {
3634 startTimeUs = timeUs;
3635 }
3636 params->setInt64(kKeyTime, startTimeUs);
3637 }
3638 status_t err = mSource->start(params.get());
3639
3640 if (err != OK) {
3641 return err;
3642 }
3643
3644 mCodecSpecificDataIndex = 0;
3645 mInitialBufferSubmit = true;
3646 mSignalledEOS = false;
3647 mNoMoreOutputData = false;
3648 mOutputPortSettingsHaveChanged = false;
3649 mSeekTimeUs = -1;
3650 mSeekMode = ReadOptions::SEEK_CLOSEST_SYNC;
3651 mTargetTimeUs = -1;
3652 mFilledBuffers.clear();
3653 mPaused = false;
3654
3655 return init();
3656 }
3657
stop()3658 status_t OMXCodec::stop() {
3659 CODEC_LOGV("stop mState=%d", mState);
3660
3661 Mutex::Autolock autoLock(mLock);
3662
3663 while (isIntermediateState(mState)) {
3664 mAsyncCompletion.wait(mLock);
3665 }
3666
3667 bool isError = false;
3668 switch (mState) {
3669 case LOADED:
3670 break;
3671
3672 case ERROR:
3673 {
3674 if (mPortStatus[kPortIndexOutput] == ENABLING) {
3675 // Codec is in a wedged state (technical term)
3676 // We've seen an output port settings change from the codec,
3677 // We've disabled the output port, then freed the output
3678 // buffers, initiated re-enabling the output port but
3679 // failed to reallocate the output buffers.
3680 // There doesn't seem to be a way to orderly transition
3681 // from executing->idle and idle->loaded now that the
3682 // output port hasn't been reenabled yet...
3683 // Simply free as many resources as we can and pretend
3684 // that we're in LOADED state so that the destructor
3685 // will free the component instance without asserting.
3686 freeBuffersOnPort(kPortIndexInput, true /* onlyThoseWeOwn */);
3687 freeBuffersOnPort(kPortIndexOutput, true /* onlyThoseWeOwn */);
3688 setState(LOADED);
3689 break;
3690 } else {
3691 OMX_STATETYPE state = OMX_StateInvalid;
3692 status_t err = mOMX->getState(mNode, &state);
3693 CHECK_EQ(err, (status_t)OK);
3694
3695 if (state != OMX_StateExecuting) {
3696 break;
3697 }
3698 // else fall through to the idling code
3699 }
3700
3701 isError = true;
3702 }
3703
3704 case EXECUTING:
3705 {
3706 setState(EXECUTING_TO_IDLE);
3707
3708 if (mQuirks & kRequiresFlushBeforeShutdown) {
3709 CODEC_LOGV("This component requires a flush before transitioning "
3710 "from EXECUTING to IDLE...");
3711
3712 bool emulateInputFlushCompletion =
3713 !flushPortAsync(kPortIndexInput);
3714
3715 bool emulateOutputFlushCompletion =
3716 !flushPortAsync(kPortIndexOutput);
3717
3718 if (emulateInputFlushCompletion) {
3719 onCmdComplete(OMX_CommandFlush, kPortIndexInput);
3720 }
3721
3722 if (emulateOutputFlushCompletion) {
3723 onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
3724 }
3725 } else {
3726 mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
3727 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
3728
3729 status_t err =
3730 mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
3731 CHECK_EQ(err, (status_t)OK);
3732 }
3733
3734 while (mState != LOADED && mState != ERROR) {
3735 mAsyncCompletion.wait(mLock);
3736 }
3737
3738 if (isError) {
3739 // We were in the ERROR state coming in, so restore that now
3740 // that we've idled the OMX component.
3741 setState(ERROR);
3742 }
3743
3744 break;
3745 }
3746
3747 default:
3748 {
3749 CHECK(!"should not be here.");
3750 break;
3751 }
3752 }
3753
3754 if (mLeftOverBuffer) {
3755 mLeftOverBuffer->release();
3756 mLeftOverBuffer = NULL;
3757 }
3758
3759 mSource->stop();
3760
3761 CODEC_LOGV("stopped in state %d", mState);
3762
3763 return OK;
3764 }
3765
getFormat()3766 sp<MetaData> OMXCodec::getFormat() {
3767 Mutex::Autolock autoLock(mLock);
3768
3769 return mOutputFormat;
3770 }
3771
read(MediaBuffer ** buffer,const ReadOptions * options)3772 status_t OMXCodec::read(
3773 MediaBuffer **buffer, const ReadOptions *options) {
3774 status_t err = OK;
3775 *buffer = NULL;
3776
3777 Mutex::Autolock autoLock(mLock);
3778
3779 if (mState != EXECUTING && mState != RECONFIGURING) {
3780 return UNKNOWN_ERROR;
3781 }
3782
3783 bool seeking = false;
3784 int64_t seekTimeUs;
3785 ReadOptions::SeekMode seekMode;
3786 if (options && options->getSeekTo(&seekTimeUs, &seekMode)) {
3787 seeking = true;
3788 }
3789
3790 if (mInitialBufferSubmit) {
3791 mInitialBufferSubmit = false;
3792
3793 if (seeking) {
3794 CHECK(seekTimeUs >= 0);
3795 mSeekTimeUs = seekTimeUs;
3796 mSeekMode = seekMode;
3797
3798 // There's no reason to trigger the code below, there's
3799 // nothing to flush yet.
3800 seeking = false;
3801 mPaused = false;
3802 }
3803
3804 drainInputBuffers();
3805
3806 if (mState == EXECUTING) {
3807 // Otherwise mState == RECONFIGURING and this code will trigger
3808 // after the output port is reenabled.
3809 fillOutputBuffers();
3810 }
3811 }
3812
3813 if (seeking) {
3814 while (mState == RECONFIGURING) {
3815 if ((err = waitForBufferFilled_l()) != OK) {
3816 return err;
3817 }
3818 }
3819
3820 if (mState != EXECUTING) {
3821 return UNKNOWN_ERROR;
3822 }
3823
3824 CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6);
3825
3826 mSignalledEOS = false;
3827
3828 CHECK(seekTimeUs >= 0);
3829 mSeekTimeUs = seekTimeUs;
3830 mSeekMode = seekMode;
3831
3832 mFilledBuffers.clear();
3833
3834 CHECK_EQ((int)mState, (int)EXECUTING);
3835
3836 bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput);
3837 bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput);
3838
3839 if (emulateInputFlushCompletion) {
3840 onCmdComplete(OMX_CommandFlush, kPortIndexInput);
3841 }
3842
3843 if (emulateOutputFlushCompletion) {
3844 onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
3845 }
3846
3847 while (mSeekTimeUs >= 0) {
3848 if ((err = waitForBufferFilled_l()) != OK) {
3849 return err;
3850 }
3851 }
3852 }
3853
3854 while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) {
3855 if ((err = waitForBufferFilled_l()) != OK) {
3856 return err;
3857 }
3858 }
3859
3860 if (mState == ERROR) {
3861 return UNKNOWN_ERROR;
3862 }
3863
3864 if (mFilledBuffers.empty()) {
3865 return mSignalledEOS ? mFinalStatus : ERROR_END_OF_STREAM;
3866 }
3867
3868 if (mOutputPortSettingsHaveChanged) {
3869 mOutputPortSettingsHaveChanged = false;
3870
3871 return INFO_FORMAT_CHANGED;
3872 }
3873
3874 size_t index = *mFilledBuffers.begin();
3875 mFilledBuffers.erase(mFilledBuffers.begin());
3876
3877 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
3878 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
3879 info->mStatus = OWNED_BY_CLIENT;
3880
3881 info->mMediaBuffer->add_ref();
3882 if (mSkipCutBuffer != NULL) {
3883 mSkipCutBuffer->submit(info->mMediaBuffer);
3884 }
3885 *buffer = info->mMediaBuffer;
3886
3887 return OK;
3888 }
3889
signalBufferReturned(MediaBuffer * buffer)3890 void OMXCodec::signalBufferReturned(MediaBuffer *buffer) {
3891 Mutex::Autolock autoLock(mLock);
3892
3893 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
3894 for (size_t i = 0; i < buffers->size(); ++i) {
3895 BufferInfo *info = &buffers->editItemAt(i);
3896
3897 if (info->mMediaBuffer == buffer) {
3898 CHECK_EQ((int)mPortStatus[kPortIndexOutput], (int)ENABLED);
3899 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_CLIENT);
3900
3901 info->mStatus = OWNED_BY_US;
3902
3903 if (buffer->graphicBuffer() == 0) {
3904 fillOutputBuffer(info);
3905 } else {
3906 sp<MetaData> metaData = info->mMediaBuffer->meta_data();
3907 int32_t rendered = 0;
3908 if (!metaData->findInt32(kKeyRendered, &rendered)) {
3909 rendered = 0;
3910 }
3911 if (!rendered) {
3912 status_t err = cancelBufferToNativeWindow(info);
3913 if (err < 0) {
3914 return;
3915 }
3916 }
3917
3918 info->mStatus = OWNED_BY_NATIVE_WINDOW;
3919
3920 // Dequeue the next buffer from the native window.
3921 BufferInfo *nextBufInfo = dequeueBufferFromNativeWindow();
3922 if (nextBufInfo == 0) {
3923 return;
3924 }
3925
3926 // Give the buffer to the OMX node to fill.
3927 fillOutputBuffer(nextBufInfo);
3928 }
3929 return;
3930 }
3931 }
3932
3933 CHECK(!"should not be here.");
3934 }
3935
imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type)3936 static const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) {
3937 static const char *kNames[] = {
3938 "OMX_IMAGE_CodingUnused",
3939 "OMX_IMAGE_CodingAutoDetect",
3940 "OMX_IMAGE_CodingJPEG",
3941 "OMX_IMAGE_CodingJPEG2K",
3942 "OMX_IMAGE_CodingEXIF",
3943 "OMX_IMAGE_CodingTIFF",
3944 "OMX_IMAGE_CodingGIF",
3945 "OMX_IMAGE_CodingPNG",
3946 "OMX_IMAGE_CodingLZW",
3947 "OMX_IMAGE_CodingBMP",
3948 };
3949
3950 size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
3951
3952 if (type < 0 || (size_t)type >= numNames) {
3953 return "UNKNOWN";
3954 } else {
3955 return kNames[type];
3956 }
3957 }
3958
colorFormatString(OMX_COLOR_FORMATTYPE type)3959 static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) {
3960 static const char *kNames[] = {
3961 "OMX_COLOR_FormatUnused",
3962 "OMX_COLOR_FormatMonochrome",
3963 "OMX_COLOR_Format8bitRGB332",
3964 "OMX_COLOR_Format12bitRGB444",
3965 "OMX_COLOR_Format16bitARGB4444",
3966 "OMX_COLOR_Format16bitARGB1555",
3967 "OMX_COLOR_Format16bitRGB565",
3968 "OMX_COLOR_Format16bitBGR565",
3969 "OMX_COLOR_Format18bitRGB666",
3970 "OMX_COLOR_Format18bitARGB1665",
3971 "OMX_COLOR_Format19bitARGB1666",
3972 "OMX_COLOR_Format24bitRGB888",
3973 "OMX_COLOR_Format24bitBGR888",
3974 "OMX_COLOR_Format24bitARGB1887",
3975 "OMX_COLOR_Format25bitARGB1888",
3976 "OMX_COLOR_Format32bitBGRA8888",
3977 "OMX_COLOR_Format32bitARGB8888",
3978 "OMX_COLOR_FormatYUV411Planar",
3979 "OMX_COLOR_FormatYUV411PackedPlanar",
3980 "OMX_COLOR_FormatYUV420Planar",
3981 "OMX_COLOR_FormatYUV420PackedPlanar",
3982 "OMX_COLOR_FormatYUV420SemiPlanar",
3983 "OMX_COLOR_FormatYUV422Planar",
3984 "OMX_COLOR_FormatYUV422PackedPlanar",
3985 "OMX_COLOR_FormatYUV422SemiPlanar",
3986 "OMX_COLOR_FormatYCbYCr",
3987 "OMX_COLOR_FormatYCrYCb",
3988 "OMX_COLOR_FormatCbYCrY",
3989 "OMX_COLOR_FormatCrYCbY",
3990 "OMX_COLOR_FormatYUV444Interleaved",
3991 "OMX_COLOR_FormatRawBayer8bit",
3992 "OMX_COLOR_FormatRawBayer10bit",
3993 "OMX_COLOR_FormatRawBayer8bitcompressed",
3994 "OMX_COLOR_FormatL2",
3995 "OMX_COLOR_FormatL4",
3996 "OMX_COLOR_FormatL8",
3997 "OMX_COLOR_FormatL16",
3998 "OMX_COLOR_FormatL24",
3999 "OMX_COLOR_FormatL32",
4000 "OMX_COLOR_FormatYUV420PackedSemiPlanar",
4001 "OMX_COLOR_FormatYUV422PackedSemiPlanar",
4002 "OMX_COLOR_Format18BitBGR666",
4003 "OMX_COLOR_Format24BitARGB6666",
4004 "OMX_COLOR_Format24BitABGR6666",
4005 };
4006
4007 size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
4008
4009 if (type == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
4010 return "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar";
4011 } else if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) {
4012 return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar";
4013 } else if (type < 0 || (size_t)type >= numNames) {
4014 return "UNKNOWN";
4015 } else {
4016 return kNames[type];
4017 }
4018 }
4019
videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type)4020 static const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) {
4021 static const char *kNames[] = {
4022 "OMX_VIDEO_CodingUnused",
4023 "OMX_VIDEO_CodingAutoDetect",
4024 "OMX_VIDEO_CodingMPEG2",
4025 "OMX_VIDEO_CodingH263",
4026 "OMX_VIDEO_CodingMPEG4",
4027 "OMX_VIDEO_CodingWMV",
4028 "OMX_VIDEO_CodingRV",
4029 "OMX_VIDEO_CodingAVC",
4030 "OMX_VIDEO_CodingMJPEG",
4031 };
4032
4033 size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
4034
4035 if (type < 0 || (size_t)type >= numNames) {
4036 return "UNKNOWN";
4037 } else {
4038 return kNames[type];
4039 }
4040 }
4041
audioCodingTypeString(OMX_AUDIO_CODINGTYPE type)4042 static const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) {
4043 static const char *kNames[] = {
4044 "OMX_AUDIO_CodingUnused",
4045 "OMX_AUDIO_CodingAutoDetect",
4046 "OMX_AUDIO_CodingPCM",
4047 "OMX_AUDIO_CodingADPCM",
4048 "OMX_AUDIO_CodingAMR",
4049 "OMX_AUDIO_CodingGSMFR",
4050 "OMX_AUDIO_CodingGSMEFR",
4051 "OMX_AUDIO_CodingGSMHR",
4052 "OMX_AUDIO_CodingPDCFR",
4053 "OMX_AUDIO_CodingPDCEFR",
4054 "OMX_AUDIO_CodingPDCHR",
4055 "OMX_AUDIO_CodingTDMAFR",
4056 "OMX_AUDIO_CodingTDMAEFR",
4057 "OMX_AUDIO_CodingQCELP8",
4058 "OMX_AUDIO_CodingQCELP13",
4059 "OMX_AUDIO_CodingEVRC",
4060 "OMX_AUDIO_CodingSMV",
4061 "OMX_AUDIO_CodingG711",
4062 "OMX_AUDIO_CodingG723",
4063 "OMX_AUDIO_CodingG726",
4064 "OMX_AUDIO_CodingG729",
4065 "OMX_AUDIO_CodingAAC",
4066 "OMX_AUDIO_CodingMP3",
4067 "OMX_AUDIO_CodingSBC",
4068 "OMX_AUDIO_CodingVORBIS",
4069 "OMX_AUDIO_CodingWMA",
4070 "OMX_AUDIO_CodingRA",
4071 "OMX_AUDIO_CodingMIDI",
4072 };
4073
4074 size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
4075
4076 if (type < 0 || (size_t)type >= numNames) {
4077 return "UNKNOWN";
4078 } else {
4079 return kNames[type];
4080 }
4081 }
4082
audioPCMModeString(OMX_AUDIO_PCMMODETYPE type)4083 static const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) {
4084 static const char *kNames[] = {
4085 "OMX_AUDIO_PCMModeLinear",
4086 "OMX_AUDIO_PCMModeALaw",
4087 "OMX_AUDIO_PCMModeMULaw",
4088 };
4089
4090 size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
4091
4092 if (type < 0 || (size_t)type >= numNames) {
4093 return "UNKNOWN";
4094 } else {
4095 return kNames[type];
4096 }
4097 }
4098
amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type)4099 static const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) {
4100 static const char *kNames[] = {
4101 "OMX_AUDIO_AMRBandModeUnused",
4102 "OMX_AUDIO_AMRBandModeNB0",
4103 "OMX_AUDIO_AMRBandModeNB1",
4104 "OMX_AUDIO_AMRBandModeNB2",
4105 "OMX_AUDIO_AMRBandModeNB3",
4106 "OMX_AUDIO_AMRBandModeNB4",
4107 "OMX_AUDIO_AMRBandModeNB5",
4108 "OMX_AUDIO_AMRBandModeNB6",
4109 "OMX_AUDIO_AMRBandModeNB7",
4110 "OMX_AUDIO_AMRBandModeWB0",
4111 "OMX_AUDIO_AMRBandModeWB1",
4112 "OMX_AUDIO_AMRBandModeWB2",
4113 "OMX_AUDIO_AMRBandModeWB3",
4114 "OMX_AUDIO_AMRBandModeWB4",
4115 "OMX_AUDIO_AMRBandModeWB5",
4116 "OMX_AUDIO_AMRBandModeWB6",
4117 "OMX_AUDIO_AMRBandModeWB7",
4118 "OMX_AUDIO_AMRBandModeWB8",
4119 };
4120
4121 size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
4122
4123 if (type < 0 || (size_t)type >= numNames) {
4124 return "UNKNOWN";
4125 } else {
4126 return kNames[type];
4127 }
4128 }
4129
amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type)4130 static const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) {
4131 static const char *kNames[] = {
4132 "OMX_AUDIO_AMRFrameFormatConformance",
4133 "OMX_AUDIO_AMRFrameFormatIF1",
4134 "OMX_AUDIO_AMRFrameFormatIF2",
4135 "OMX_AUDIO_AMRFrameFormatFSF",
4136 "OMX_AUDIO_AMRFrameFormatRTPPayload",
4137 "OMX_AUDIO_AMRFrameFormatITU",
4138 };
4139
4140 size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
4141
4142 if (type < 0 || (size_t)type >= numNames) {
4143 return "UNKNOWN";
4144 } else {
4145 return kNames[type];
4146 }
4147 }
4148
dumpPortStatus(OMX_U32 portIndex)4149 void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
4150 OMX_PARAM_PORTDEFINITIONTYPE def;
4151 InitOMXParams(&def);
4152 def.nPortIndex = portIndex;
4153
4154 status_t err = mOMX->getParameter(
4155 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
4156 CHECK_EQ(err, (status_t)OK);
4157
4158 printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output");
4159
4160 CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput)
4161 || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput));
4162
4163 printf(" nBufferCountActual = %ld\n", def.nBufferCountActual);
4164 printf(" nBufferCountMin = %ld\n", def.nBufferCountMin);
4165 printf(" nBufferSize = %ld\n", def.nBufferSize);
4166
4167 switch (def.eDomain) {
4168 case OMX_PortDomainImage:
4169 {
4170 const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
4171
4172 printf("\n");
4173 printf(" // Image\n");
4174 printf(" nFrameWidth = %ld\n", imageDef->nFrameWidth);
4175 printf(" nFrameHeight = %ld\n", imageDef->nFrameHeight);
4176 printf(" nStride = %ld\n", imageDef->nStride);
4177
4178 printf(" eCompressionFormat = %s\n",
4179 imageCompressionFormatString(imageDef->eCompressionFormat));
4180
4181 printf(" eColorFormat = %s\n",
4182 colorFormatString(imageDef->eColorFormat));
4183
4184 break;
4185 }
4186
4187 case OMX_PortDomainVideo:
4188 {
4189 OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
4190
4191 printf("\n");
4192 printf(" // Video\n");
4193 printf(" nFrameWidth = %ld\n", videoDef->nFrameWidth);
4194 printf(" nFrameHeight = %ld\n", videoDef->nFrameHeight);
4195 printf(" nStride = %ld\n", videoDef->nStride);
4196
4197 printf(" eCompressionFormat = %s\n",
4198 videoCompressionFormatString(videoDef->eCompressionFormat));
4199
4200 printf(" eColorFormat = %s\n",
4201 colorFormatString(videoDef->eColorFormat));
4202
4203 break;
4204 }
4205
4206 case OMX_PortDomainAudio:
4207 {
4208 OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
4209
4210 printf("\n");
4211 printf(" // Audio\n");
4212 printf(" eEncoding = %s\n",
4213 audioCodingTypeString(audioDef->eEncoding));
4214
4215 if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) {
4216 OMX_AUDIO_PARAM_PCMMODETYPE params;
4217 InitOMXParams(¶ms);
4218 params.nPortIndex = portIndex;
4219
4220 err = mOMX->getParameter(
4221 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params));
4222 CHECK_EQ(err, (status_t)OK);
4223
4224 printf(" nSamplingRate = %ld\n", params.nSamplingRate);
4225 printf(" nChannels = %ld\n", params.nChannels);
4226 printf(" bInterleaved = %d\n", params.bInterleaved);
4227 printf(" nBitPerSample = %ld\n", params.nBitPerSample);
4228
4229 printf(" eNumData = %s\n",
4230 params.eNumData == OMX_NumericalDataSigned
4231 ? "signed" : "unsigned");
4232
4233 printf(" ePCMMode = %s\n", audioPCMModeString(params.ePCMMode));
4234 } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) {
4235 OMX_AUDIO_PARAM_AMRTYPE amr;
4236 InitOMXParams(&amr);
4237 amr.nPortIndex = portIndex;
4238
4239 err = mOMX->getParameter(
4240 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
4241 CHECK_EQ(err, (status_t)OK);
4242
4243 printf(" nChannels = %ld\n", amr.nChannels);
4244 printf(" eAMRBandMode = %s\n",
4245 amrBandModeString(amr.eAMRBandMode));
4246 printf(" eAMRFrameFormat = %s\n",
4247 amrFrameFormatString(amr.eAMRFrameFormat));
4248 }
4249
4250 break;
4251 }
4252
4253 default:
4254 {
4255 printf(" // Unknown\n");
4256 break;
4257 }
4258 }
4259
4260 printf("}\n");
4261 }
4262
initNativeWindow()4263 status_t OMXCodec::initNativeWindow() {
4264 // Enable use of a GraphicBuffer as the output for this node. This must
4265 // happen before getting the IndexParamPortDefinition parameter because it
4266 // will affect the pixel format that the node reports.
4267 status_t err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
4268 if (err != 0) {
4269 return err;
4270 }
4271
4272 return OK;
4273 }
4274
initNativeWindowCrop()4275 void OMXCodec::initNativeWindowCrop() {
4276 int32_t left, top, right, bottom;
4277
4278 CHECK(mOutputFormat->findRect(
4279 kKeyCropRect,
4280 &left, &top, &right, &bottom));
4281
4282 android_native_rect_t crop;
4283 crop.left = left;
4284 crop.top = top;
4285 crop.right = right + 1;
4286 crop.bottom = bottom + 1;
4287
4288 // We'll ignore any errors here, if the surface is
4289 // already invalid, we'll know soon enough.
4290 native_window_set_crop(mNativeWindow.get(), &crop);
4291 }
4292
initOutputFormat(const sp<MetaData> & inputFormat)4293 void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
4294 mOutputFormat = new MetaData;
4295 mOutputFormat->setCString(kKeyDecoderComponent, mComponentName);
4296 if (mIsEncoder) {
4297 int32_t timeScale;
4298 if (inputFormat->findInt32(kKeyTimeScale, &timeScale)) {
4299 mOutputFormat->setInt32(kKeyTimeScale, timeScale);
4300 }
4301 }
4302
4303 OMX_PARAM_PORTDEFINITIONTYPE def;
4304 InitOMXParams(&def);
4305 def.nPortIndex = kPortIndexOutput;
4306
4307 status_t err = mOMX->getParameter(
4308 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
4309 CHECK_EQ(err, (status_t)OK);
4310
4311 switch (def.eDomain) {
4312 case OMX_PortDomainImage:
4313 {
4314 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
4315 CHECK_EQ((int)imageDef->eCompressionFormat,
4316 (int)OMX_IMAGE_CodingUnused);
4317
4318 mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
4319 mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat);
4320 mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth);
4321 mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight);
4322 break;
4323 }
4324
4325 case OMX_PortDomainAudio:
4326 {
4327 OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio;
4328
4329 if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) {
4330 OMX_AUDIO_PARAM_PCMMODETYPE params;
4331 InitOMXParams(¶ms);
4332 params.nPortIndex = kPortIndexOutput;
4333
4334 err = mOMX->getParameter(
4335 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params));
4336 CHECK_EQ(err, (status_t)OK);
4337
4338 CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned);
4339 CHECK_EQ(params.nBitPerSample, 16u);
4340 CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear);
4341
4342 int32_t numChannels, sampleRate;
4343 inputFormat->findInt32(kKeyChannelCount, &numChannels);
4344 inputFormat->findInt32(kKeySampleRate, &sampleRate);
4345
4346 if ((OMX_U32)numChannels != params.nChannels) {
4347 ALOGV("Codec outputs a different number of channels than "
4348 "the input stream contains (contains %d channels, "
4349 "codec outputs %ld channels).",
4350 numChannels, params.nChannels);
4351 }
4352
4353 if (sampleRate != (int32_t)params.nSamplingRate) {
4354 ALOGV("Codec outputs at different sampling rate than "
4355 "what the input stream contains (contains data at "
4356 "%d Hz, codec outputs %lu Hz)",
4357 sampleRate, params.nSamplingRate);
4358 }
4359
4360 mOutputFormat->setCString(
4361 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
4362
4363 // Use the codec-advertised number of channels, as some
4364 // codecs appear to output stereo even if the input data is
4365 // mono. If we know the codec lies about this information,
4366 // use the actual number of channels instead.
4367 mOutputFormat->setInt32(
4368 kKeyChannelCount,
4369 (mQuirks & kDecoderLiesAboutNumberOfChannels)
4370 ? numChannels : params.nChannels);
4371
4372 mOutputFormat->setInt32(kKeySampleRate, params.nSamplingRate);
4373 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) {
4374 OMX_AUDIO_PARAM_AMRTYPE amr;
4375 InitOMXParams(&amr);
4376 amr.nPortIndex = kPortIndexOutput;
4377
4378 err = mOMX->getParameter(
4379 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
4380 CHECK_EQ(err, (status_t)OK);
4381
4382 CHECK_EQ(amr.nChannels, 1u);
4383 mOutputFormat->setInt32(kKeyChannelCount, 1);
4384
4385 if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0
4386 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) {
4387 mOutputFormat->setCString(
4388 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB);
4389 mOutputFormat->setInt32(kKeySampleRate, 8000);
4390 } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0
4391 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) {
4392 mOutputFormat->setCString(
4393 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB);
4394 mOutputFormat->setInt32(kKeySampleRate, 16000);
4395 } else {
4396 CHECK(!"Unknown AMR band mode.");
4397 }
4398 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) {
4399 mOutputFormat->setCString(
4400 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
4401 int32_t numChannels, sampleRate, bitRate;
4402 inputFormat->findInt32(kKeyChannelCount, &numChannels);
4403 inputFormat->findInt32(kKeySampleRate, &sampleRate);
4404 inputFormat->findInt32(kKeyBitRate, &bitRate);
4405 mOutputFormat->setInt32(kKeyChannelCount, numChannels);
4406 mOutputFormat->setInt32(kKeySampleRate, sampleRate);
4407 mOutputFormat->setInt32(kKeyBitRate, bitRate);
4408 } else {
4409 CHECK(!"Should not be here. Unknown audio encoding.");
4410 }
4411 break;
4412 }
4413
4414 case OMX_PortDomainVideo:
4415 {
4416 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
4417
4418 if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) {
4419 mOutputFormat->setCString(
4420 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
4421 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) {
4422 mOutputFormat->setCString(
4423 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
4424 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) {
4425 mOutputFormat->setCString(
4426 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
4427 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) {
4428 mOutputFormat->setCString(
4429 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
4430 } else {
4431 CHECK(!"Unknown compression format.");
4432 }
4433
4434 mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth);
4435 mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight);
4436 mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat);
4437
4438 if (!mIsEncoder) {
4439 OMX_CONFIG_RECTTYPE rect;
4440 InitOMXParams(&rect);
4441 rect.nPortIndex = kPortIndexOutput;
4442 status_t err =
4443 mOMX->getConfig(
4444 mNode, OMX_IndexConfigCommonOutputCrop,
4445 &rect, sizeof(rect));
4446
4447 CODEC_LOGI(
4448 "video dimensions are %ld x %ld",
4449 video_def->nFrameWidth, video_def->nFrameHeight);
4450
4451 if (err == OK) {
4452 CHECK_GE(rect.nLeft, 0);
4453 CHECK_GE(rect.nTop, 0);
4454 CHECK_GE(rect.nWidth, 0u);
4455 CHECK_GE(rect.nHeight, 0u);
4456 CHECK_LE(rect.nLeft + rect.nWidth - 1, video_def->nFrameWidth);
4457 CHECK_LE(rect.nTop + rect.nHeight - 1, video_def->nFrameHeight);
4458
4459 mOutputFormat->setRect(
4460 kKeyCropRect,
4461 rect.nLeft,
4462 rect.nTop,
4463 rect.nLeft + rect.nWidth - 1,
4464 rect.nTop + rect.nHeight - 1);
4465
4466 CODEC_LOGI(
4467 "Crop rect is %ld x %ld @ (%ld, %ld)",
4468 rect.nWidth, rect.nHeight, rect.nLeft, rect.nTop);
4469 } else {
4470 mOutputFormat->setRect(
4471 kKeyCropRect,
4472 0, 0,
4473 video_def->nFrameWidth - 1,
4474 video_def->nFrameHeight - 1);
4475 }
4476
4477 if (mNativeWindow != NULL) {
4478 initNativeWindowCrop();
4479 }
4480 }
4481 break;
4482 }
4483
4484 default:
4485 {
4486 CHECK(!"should not be here, neither audio nor video.");
4487 break;
4488 }
4489 }
4490
4491 // If the input format contains rotation information, flag the output
4492 // format accordingly.
4493
4494 int32_t rotationDegrees;
4495 if (mSource->getFormat()->findInt32(kKeyRotation, &rotationDegrees)) {
4496 mOutputFormat->setInt32(kKeyRotation, rotationDegrees);
4497 }
4498 }
4499
pause()4500 status_t OMXCodec::pause() {
4501 Mutex::Autolock autoLock(mLock);
4502
4503 mPaused = true;
4504
4505 return OK;
4506 }
4507
4508 ////////////////////////////////////////////////////////////////////////////////
4509
QueryCodecs(const sp<IOMX> & omx,const char * mime,bool queryDecoders,bool hwCodecOnly,Vector<CodecCapabilities> * results)4510 status_t QueryCodecs(
4511 const sp<IOMX> &omx,
4512 const char *mime, bool queryDecoders, bool hwCodecOnly,
4513 Vector<CodecCapabilities> *results) {
4514 Vector<String8> matchingCodecs;
4515 results->clear();
4516
4517 OMXCodec::findMatchingCodecs(mime,
4518 !queryDecoders /*createEncoder*/,
4519 NULL /*matchComponentName*/,
4520 hwCodecOnly ? OMXCodec::kHardwareCodecsOnly : 0 /*flags*/,
4521 &matchingCodecs);
4522
4523 for (size_t c = 0; c < matchingCodecs.size(); c++) {
4524 const char *componentName = matchingCodecs.itemAt(c).string();
4525
4526 results->push();
4527 CodecCapabilities *caps = &results->editItemAt(results->size() - 1);
4528
4529 status_t err =
4530 QueryCodec(omx, componentName, mime, !queryDecoders, caps);
4531
4532 if (err != OK) {
4533 results->removeAt(results->size() - 1);
4534 }
4535 }
4536
4537 return OK;
4538 }
4539
QueryCodec(const sp<IOMX> & omx,const char * componentName,const char * mime,bool isEncoder,CodecCapabilities * caps)4540 status_t QueryCodec(
4541 const sp<IOMX> &omx,
4542 const char *componentName, const char *mime,
4543 bool isEncoder,
4544 CodecCapabilities *caps) {
4545 if (strncmp(componentName, "OMX.", 4)) {
4546 // Not an OpenMax component but a software codec.
4547
4548 caps->mComponentName = componentName;
4549 return OK;
4550 }
4551
4552 sp<OMXCodecObserver> observer = new OMXCodecObserver;
4553 IOMX::node_id node;
4554 status_t err = omx->allocateNode(componentName, observer, &node);
4555
4556 if (err != OK) {
4557 return err;
4558 }
4559
4560 OMXCodec::setComponentRole(omx, node, isEncoder, mime);
4561
4562 caps->mComponentName = componentName;
4563
4564 OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
4565 InitOMXParams(¶m);
4566
4567 param.nPortIndex = !isEncoder ? 0 : 1;
4568
4569 for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
4570 err = omx->getParameter(
4571 node, OMX_IndexParamVideoProfileLevelQuerySupported,
4572 ¶m, sizeof(param));
4573
4574 if (err != OK) {
4575 break;
4576 }
4577
4578 CodecProfileLevel profileLevel;
4579 profileLevel.mProfile = param.eProfile;
4580 profileLevel.mLevel = param.eLevel;
4581
4582 caps->mProfileLevels.push(profileLevel);
4583 }
4584
4585 // Color format query
4586 OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
4587 InitOMXParams(&portFormat);
4588 portFormat.nPortIndex = !isEncoder ? 1 : 0;
4589 for (portFormat.nIndex = 0;; ++portFormat.nIndex) {
4590 err = omx->getParameter(
4591 node, OMX_IndexParamVideoPortFormat,
4592 &portFormat, sizeof(portFormat));
4593 if (err != OK) {
4594 break;
4595 }
4596 caps->mColorFormats.push(portFormat.eColorFormat);
4597 }
4598
4599 CHECK_EQ(omx->freeNode(node), (status_t)OK);
4600
4601 return OK;
4602 }
4603
QueryCodecs(const sp<IOMX> & omx,const char * mimeType,bool queryDecoders,Vector<CodecCapabilities> * results)4604 status_t QueryCodecs(
4605 const sp<IOMX> &omx,
4606 const char *mimeType, bool queryDecoders,
4607 Vector<CodecCapabilities> *results) {
4608 return QueryCodecs(omx, mimeType, queryDecoders, false /*hwCodecOnly*/, results);
4609 }
4610
restorePatchedDataPointer(BufferInfo * info)4611 void OMXCodec::restorePatchedDataPointer(BufferInfo *info) {
4612 CHECK(mIsEncoder && (mQuirks & kAvoidMemcopyInputRecordingFrames));
4613 CHECK(mOMXLivesLocally);
4614
4615 OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)info->mBuffer;
4616 header->pBuffer = (OMX_U8 *)info->mData;
4617 }
4618
4619 // These are supposed be equivalent to the logic in
4620 // "audio_channel_out_mask_from_count".
getOMXChannelMapping(size_t numChannels,OMX_AUDIO_CHANNELTYPE map[])4621 status_t getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) {
4622 switch (numChannels) {
4623 case 1:
4624 map[0] = OMX_AUDIO_ChannelCF;
4625 break;
4626 case 2:
4627 map[0] = OMX_AUDIO_ChannelLF;
4628 map[1] = OMX_AUDIO_ChannelRF;
4629 break;
4630 case 3:
4631 map[0] = OMX_AUDIO_ChannelLF;
4632 map[1] = OMX_AUDIO_ChannelRF;
4633 map[2] = OMX_AUDIO_ChannelCF;
4634 break;
4635 case 4:
4636 map[0] = OMX_AUDIO_ChannelLF;
4637 map[1] = OMX_AUDIO_ChannelRF;
4638 map[2] = OMX_AUDIO_ChannelLR;
4639 map[3] = OMX_AUDIO_ChannelRR;
4640 break;
4641 case 5:
4642 map[0] = OMX_AUDIO_ChannelLF;
4643 map[1] = OMX_AUDIO_ChannelRF;
4644 map[2] = OMX_AUDIO_ChannelCF;
4645 map[3] = OMX_AUDIO_ChannelLR;
4646 map[4] = OMX_AUDIO_ChannelRR;
4647 break;
4648 case 6:
4649 map[0] = OMX_AUDIO_ChannelLF;
4650 map[1] = OMX_AUDIO_ChannelRF;
4651 map[2] = OMX_AUDIO_ChannelCF;
4652 map[3] = OMX_AUDIO_ChannelLFE;
4653 map[4] = OMX_AUDIO_ChannelLR;
4654 map[5] = OMX_AUDIO_ChannelRR;
4655 break;
4656 case 7:
4657 map[0] = OMX_AUDIO_ChannelLF;
4658 map[1] = OMX_AUDIO_ChannelRF;
4659 map[2] = OMX_AUDIO_ChannelCF;
4660 map[3] = OMX_AUDIO_ChannelLFE;
4661 map[4] = OMX_AUDIO_ChannelLR;
4662 map[5] = OMX_AUDIO_ChannelRR;
4663 map[6] = OMX_AUDIO_ChannelCS;
4664 break;
4665 case 8:
4666 map[0] = OMX_AUDIO_ChannelLF;
4667 map[1] = OMX_AUDIO_ChannelRF;
4668 map[2] = OMX_AUDIO_ChannelCF;
4669 map[3] = OMX_AUDIO_ChannelLFE;
4670 map[4] = OMX_AUDIO_ChannelLR;
4671 map[5] = OMX_AUDIO_ChannelRR;
4672 map[6] = OMX_AUDIO_ChannelLS;
4673 map[7] = OMX_AUDIO_ChannelRS;
4674 break;
4675 default:
4676 return -EINVAL;
4677 }
4678
4679 return OK;
4680 }
4681
4682 } // namespace android
4683