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