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