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 if (def.nBufferSize != 0 && def.nBufferCountActual > SIZE_MAX / def.nBufferSize) {
1654 return BAD_VALUE;
1655 }
1656 size_t totalSize = def.nBufferCountActual * def.nBufferSize;
1657 mDealer[portIndex] = new MemoryDealer(totalSize, "OMXCodec");
1658
1659 for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
1660 sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
1661 CHECK(mem.get() != NULL);
1662
1663 BufferInfo info;
1664 info.mData = NULL;
1665 info.mSize = def.nBufferSize;
1666
1667 IOMX::buffer_id buffer;
1668 if (portIndex == kPortIndexInput
1669 && ((mQuirks & kRequiresAllocateBufferOnInputPorts)
1670 || (mFlags & kUseSecureInputBuffers))) {
1671 if (mOMXLivesLocally) {
1672 mem.clear();
1673
1674 err = mOMX->allocateBuffer(
1675 mNode, portIndex, def.nBufferSize, &buffer,
1676 &info.mData);
1677 } else {
1678 err = mOMX->allocateBufferWithBackup(
1679 mNode, portIndex, mem, &buffer);
1680 }
1681 } else if (portIndex == kPortIndexOutput
1682 && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) {
1683 if (mOMXLivesLocally) {
1684 mem.clear();
1685
1686 err = mOMX->allocateBuffer(
1687 mNode, portIndex, def.nBufferSize, &buffer,
1688 &info.mData);
1689 } else {
1690 err = mOMX->allocateBufferWithBackup(
1691 mNode, portIndex, mem, &buffer);
1692 }
1693 } else {
1694 err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
1695 }
1696
1697 if (err != OK) {
1698 ALOGE("allocate_buffer_with_backup failed");
1699 return err;
1700 }
1701
1702 if (mem != NULL) {
1703 info.mData = mem->pointer();
1704 }
1705
1706 info.mBuffer = buffer;
1707 info.mStatus = OWNED_BY_US;
1708 info.mMem = mem;
1709 info.mMediaBuffer = NULL;
1710
1711 if (portIndex == kPortIndexOutput) {
1712 // Fail deferred MediaBuffer creation until FILL_BUFFER_DONE;
1713 // this legacy mode is no longer supported.
1714 LOG_ALWAYS_FATAL_IF((mOMXLivesLocally
1715 && (mQuirks & kRequiresAllocateBufferOnOutputPorts)
1716 && (mQuirks & kDefersOutputBufferAllocation)),
1717 "allocateBuffersOnPort cannot defer buffer allocation");
1718
1719 info.mMediaBuffer = new MediaBuffer(info.mData, info.mSize);
1720 info.mMediaBuffer->setObserver(this);
1721 }
1722
1723 mPortBuffers[portIndex].push(info);
1724
1725 CODEC_LOGV("allocated buffer %p on %s port", buffer,
1726 portIndex == kPortIndexInput ? "input" : "output");
1727 }
1728
1729 if (portIndex == kPortIndexOutput) {
1730
1731 sp<MetaData> meta = mSource->getFormat();
1732 int32_t delay = 0;
1733 if (!meta->findInt32(kKeyEncoderDelay, &delay)) {
1734 delay = 0;
1735 }
1736 int32_t padding = 0;
1737 if (!meta->findInt32(kKeyEncoderPadding, &padding)) {
1738 padding = 0;
1739 }
1740 int32_t numchannels = 0;
1741 if (delay + padding) {
1742 if (mOutputFormat->findInt32(kKeyChannelCount, &numchannels)) {
1743 size_t frameSize = numchannels * sizeof(int16_t);
1744 if (mSkipCutBuffer != NULL) {
1745 size_t prevbuffersize = mSkipCutBuffer->size();
1746 if (prevbuffersize != 0) {
1747 ALOGW("Replacing SkipCutBuffer holding %d bytes", prevbuffersize);
1748 }
1749 }
1750 mSkipCutBuffer = new SkipCutBuffer(delay * frameSize, padding * frameSize);
1751 }
1752 }
1753 }
1754
1755 // dumpPortStatus(portIndex);
1756
1757 if (portIndex == kPortIndexInput && (mFlags & kUseSecureInputBuffers)) {
1758 Vector<MediaBuffer *> buffers;
1759 for (size_t i = 0; i < def.nBufferCountActual; ++i) {
1760 const BufferInfo &info = mPortBuffers[kPortIndexInput].itemAt(i);
1761
1762 MediaBuffer *mbuf = new MediaBuffer(info.mData, info.mSize);
1763 buffers.push(mbuf);
1764 }
1765
1766 status_t err = mSource->setBuffers(buffers);
1767
1768 if (err != OK) {
1769 for (size_t i = 0; i < def.nBufferCountActual; ++i) {
1770 buffers.editItemAt(i)->release();
1771 }
1772 buffers.clear();
1773
1774 CODEC_LOGE(
1775 "Codec requested to use secure input buffers but "
1776 "upstream source didn't support that.");
1777
1778 return err;
1779 }
1780 }
1781
1782 return OK;
1783 }
1784
applyRotation()1785 status_t OMXCodec::applyRotation() {
1786 sp<MetaData> meta = mSource->getFormat();
1787
1788 int32_t rotationDegrees;
1789 if (!meta->findInt32(kKeyRotation, &rotationDegrees)) {
1790 rotationDegrees = 0;
1791 }
1792
1793 uint32_t transform;
1794 switch (rotationDegrees) {
1795 case 0: transform = 0; break;
1796 case 90: transform = HAL_TRANSFORM_ROT_90; break;
1797 case 180: transform = HAL_TRANSFORM_ROT_180; break;
1798 case 270: transform = HAL_TRANSFORM_ROT_270; break;
1799 default: transform = 0; break;
1800 }
1801
1802 status_t err = OK;
1803
1804 if (transform) {
1805 err = native_window_set_buffers_transform(
1806 mNativeWindow.get(), transform);
1807 ALOGE("native_window_set_buffers_transform failed: %s (%d)",
1808 strerror(-err), -err);
1809 }
1810
1811 return err;
1812 }
1813
allocateOutputBuffersFromNativeWindow()1814 status_t OMXCodec::allocateOutputBuffersFromNativeWindow() {
1815 // Get the number of buffers needed.
1816 OMX_PARAM_PORTDEFINITIONTYPE def;
1817 InitOMXParams(&def);
1818 def.nPortIndex = kPortIndexOutput;
1819
1820 status_t err = mOMX->getParameter(
1821 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1822 if (err != OK) {
1823 CODEC_LOGE("getParameter failed: %d", err);
1824 return err;
1825 }
1826
1827 err = native_window_set_buffers_geometry(
1828 mNativeWindow.get(),
1829 def.format.video.nFrameWidth,
1830 def.format.video.nFrameHeight,
1831 def.format.video.eColorFormat);
1832
1833 if (err != 0) {
1834 ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
1835 strerror(-err), -err);
1836 return err;
1837 }
1838
1839 err = applyRotation();
1840 if (err != OK) {
1841 return err;
1842 }
1843
1844 // Set up the native window.
1845 OMX_U32 usage = 0;
1846 err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
1847 if (err != 0) {
1848 ALOGW("querying usage flags from OMX IL component failed: %d", err);
1849 // XXX: Currently this error is logged, but not fatal.
1850 usage = 0;
1851 }
1852 if (mFlags & kEnableGrallocUsageProtected) {
1853 usage |= GRALLOC_USAGE_PROTECTED;
1854 }
1855
1856 // Make sure to check whether either Stagefright or the video decoder
1857 // requested protected buffers.
1858 if (usage & GRALLOC_USAGE_PROTECTED) {
1859 // Verify that the ANativeWindow sends images directly to
1860 // SurfaceFlinger.
1861 int queuesToNativeWindow = 0;
1862 err = mNativeWindow->query(
1863 mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
1864 &queuesToNativeWindow);
1865 if (err != 0) {
1866 ALOGE("error authenticating native window: %d", err);
1867 return err;
1868 }
1869 if (queuesToNativeWindow != 1) {
1870 ALOGE("native window could not be authenticated");
1871 return PERMISSION_DENIED;
1872 }
1873 }
1874
1875 ALOGV("native_window_set_usage usage=0x%lx", usage);
1876 err = native_window_set_usage(
1877 mNativeWindow.get(), usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
1878 if (err != 0) {
1879 ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
1880 return err;
1881 }
1882
1883 int minUndequeuedBufs = 0;
1884 err = mNativeWindow->query(mNativeWindow.get(),
1885 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
1886 if (err != 0) {
1887 ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
1888 strerror(-err), -err);
1889 return err;
1890 }
1891 // FIXME: assume that surface is controlled by app (native window
1892 // returns the number for the case when surface is not controlled by app)
1893 // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
1894 // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
1895
1896 // Use conservative allocation while also trying to reduce starvation
1897 //
1898 // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
1899 // minimum needed for the consumer to be able to work
1900 // 2. try to allocate two (2) additional buffers to reduce starvation from
1901 // the consumer
1902 // plus an extra buffer to account for incorrect minUndequeuedBufs
1903 CODEC_LOGI("OMX-buffers: min=%u actual=%u undeq=%d+1",
1904 def.nBufferCountMin, def.nBufferCountActual, minUndequeuedBufs);
1905
1906 for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
1907 OMX_U32 newBufferCount =
1908 def.nBufferCountMin + minUndequeuedBufs + extraBuffers;
1909 def.nBufferCountActual = newBufferCount;
1910 err = mOMX->setParameter(
1911 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1912
1913 if (err == OK) {
1914 minUndequeuedBufs += extraBuffers;
1915 break;
1916 }
1917
1918 CODEC_LOGW("setting nBufferCountActual to %u failed: %d",
1919 newBufferCount, err);
1920 /* exit condition */
1921 if (extraBuffers == 0) {
1922 return err;
1923 }
1924 }
1925 CODEC_LOGI("OMX-buffers: min=%u actual=%u undeq=%d+1",
1926 def.nBufferCountMin, def.nBufferCountActual, minUndequeuedBufs);
1927
1928 err = native_window_set_buffer_count(
1929 mNativeWindow.get(), def.nBufferCountActual);
1930 if (err != 0) {
1931 ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
1932 -err);
1933 return err;
1934 }
1935
1936 CODEC_LOGV("allocating %u buffers from a native window of size %u on "
1937 "output port", def.nBufferCountActual, def.nBufferSize);
1938
1939 // Dequeue buffers and send them to OMX
1940 for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
1941 ANativeWindowBuffer* buf;
1942 err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
1943 if (err != 0) {
1944 ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1945 break;
1946 }
1947
1948 sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
1949 BufferInfo info;
1950 info.mData = NULL;
1951 info.mSize = def.nBufferSize;
1952 info.mStatus = OWNED_BY_US;
1953 info.mMem = NULL;
1954 info.mMediaBuffer = new MediaBuffer(graphicBuffer);
1955 info.mMediaBuffer->setObserver(this);
1956 mPortBuffers[kPortIndexOutput].push(info);
1957
1958 IOMX::buffer_id bufferId;
1959 err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
1960 &bufferId);
1961 if (err != 0) {
1962 CODEC_LOGE("registering GraphicBuffer with OMX IL component "
1963 "failed: %d", err);
1964 break;
1965 }
1966
1967 mPortBuffers[kPortIndexOutput].editItemAt(i).mBuffer = bufferId;
1968
1969 CODEC_LOGV("registered graphic buffer with ID %u (pointer = %p)",
1970 bufferId, graphicBuffer.get());
1971 }
1972
1973 OMX_U32 cancelStart;
1974 OMX_U32 cancelEnd;
1975 if (err != 0) {
1976 // If an error occurred while dequeuing we need to cancel any buffers
1977 // that were dequeued.
1978 cancelStart = 0;
1979 cancelEnd = mPortBuffers[kPortIndexOutput].size();
1980 } else {
1981 // Return the last two buffers to the native window.
1982 cancelStart = def.nBufferCountActual - minUndequeuedBufs;
1983 cancelEnd = def.nBufferCountActual;
1984 }
1985
1986 for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
1987 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(i);
1988 cancelBufferToNativeWindow(info);
1989 }
1990
1991 return err;
1992 }
1993
cancelBufferToNativeWindow(BufferInfo * info)1994 status_t OMXCodec::cancelBufferToNativeWindow(BufferInfo *info) {
1995 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
1996 CODEC_LOGV("Calling cancelBuffer on buffer %u", info->mBuffer);
1997 int err = mNativeWindow->cancelBuffer(
1998 mNativeWindow.get(), info->mMediaBuffer->graphicBuffer().get(), -1);
1999 if (err != 0) {
2000 CODEC_LOGE("cancelBuffer failed w/ error 0x%08x", err);
2001
2002 setState(ERROR);
2003 return err;
2004 }
2005 info->mStatus = OWNED_BY_NATIVE_WINDOW;
2006 return OK;
2007 }
2008
dequeueBufferFromNativeWindow()2009 OMXCodec::BufferInfo* OMXCodec::dequeueBufferFromNativeWindow() {
2010 // Dequeue the next buffer from the native window.
2011 ANativeWindowBuffer* buf;
2012 int fenceFd = -1;
2013 int err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
2014 if (err != 0) {
2015 CODEC_LOGE("dequeueBuffer failed w/ error 0x%08x", err);
2016
2017 setState(ERROR);
2018 return 0;
2019 }
2020
2021 // Determine which buffer we just dequeued.
2022 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
2023 BufferInfo *bufInfo = 0;
2024 for (size_t i = 0; i < buffers->size(); i++) {
2025 sp<GraphicBuffer> graphicBuffer = buffers->itemAt(i).
2026 mMediaBuffer->graphicBuffer();
2027 if (graphicBuffer->handle == buf->handle) {
2028 bufInfo = &buffers->editItemAt(i);
2029 break;
2030 }
2031 }
2032
2033 if (bufInfo == 0) {
2034 CODEC_LOGE("dequeued unrecognized buffer: %p", buf);
2035
2036 setState(ERROR);
2037 return 0;
2038 }
2039
2040 // The native window no longer owns the buffer.
2041 CHECK_EQ((int)bufInfo->mStatus, (int)OWNED_BY_NATIVE_WINDOW);
2042 bufInfo->mStatus = OWNED_BY_US;
2043
2044 return bufInfo;
2045 }
2046
pushBlankBuffersToNativeWindow()2047 status_t OMXCodec::pushBlankBuffersToNativeWindow() {
2048 status_t err = NO_ERROR;
2049 ANativeWindowBuffer* anb = NULL;
2050 int numBufs = 0;
2051 int minUndequeuedBufs = 0;
2052
2053 // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2054 // no frames get dropped by SurfaceFlinger assuming that these are video
2055 // frames.
2056 err = native_window_api_disconnect(mNativeWindow.get(),
2057 NATIVE_WINDOW_API_MEDIA);
2058 if (err != NO_ERROR) {
2059 ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2060 strerror(-err), -err);
2061 return err;
2062 }
2063
2064 err = native_window_api_connect(mNativeWindow.get(),
2065 NATIVE_WINDOW_API_CPU);
2066 if (err != NO_ERROR) {
2067 ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2068 strerror(-err), -err);
2069 return err;
2070 }
2071
2072 err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2073 HAL_PIXEL_FORMAT_RGBX_8888);
2074 if (err != NO_ERROR) {
2075 ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2076 strerror(-err), -err);
2077 goto error;
2078 }
2079
2080 err = native_window_set_usage(mNativeWindow.get(),
2081 GRALLOC_USAGE_SW_WRITE_OFTEN);
2082 if (err != NO_ERROR) {
2083 ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2084 strerror(-err), -err);
2085 goto error;
2086 }
2087
2088 err = native_window_set_scaling_mode(mNativeWindow.get(),
2089 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
2090 if (err != OK) {
2091 ALOGE("error pushing blank frames: set_scaling_mode failed: %s (%d)",
2092 strerror(-err), -err);
2093 goto error;
2094 }
2095
2096 err = mNativeWindow->query(mNativeWindow.get(),
2097 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2098 if (err != NO_ERROR) {
2099 ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2100 "failed: %s (%d)", strerror(-err), -err);
2101 goto error;
2102 }
2103
2104 numBufs = minUndequeuedBufs + 1;
2105 err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2106 if (err != NO_ERROR) {
2107 ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2108 strerror(-err), -err);
2109 goto error;
2110 }
2111
2112 // We push numBufs + 1 buffers to ensure that we've drawn into the same
2113 // buffer twice. This should guarantee that the buffer has been displayed
2114 // on the screen and then been replaced, so an previous video frames are
2115 // guaranteed NOT to be currently displayed.
2116 for (int i = 0; i < numBufs + 1; i++) {
2117 int fenceFd = -1;
2118 err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2119 if (err != NO_ERROR) {
2120 ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2121 strerror(-err), -err);
2122 goto error;
2123 }
2124
2125 sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2126
2127 // Fill the buffer with the a 1x1 checkerboard pattern ;)
2128 uint32_t* img = NULL;
2129 err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2130 if (err != NO_ERROR) {
2131 ALOGE("error pushing blank frames: lock failed: %s (%d)",
2132 strerror(-err), -err);
2133 goto error;
2134 }
2135
2136 *img = 0;
2137
2138 err = buf->unlock();
2139 if (err != NO_ERROR) {
2140 ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2141 strerror(-err), -err);
2142 goto error;
2143 }
2144
2145 err = mNativeWindow->queueBuffer(mNativeWindow.get(),
2146 buf->getNativeBuffer(), -1);
2147 if (err != NO_ERROR) {
2148 ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2149 strerror(-err), -err);
2150 goto error;
2151 }
2152
2153 anb = NULL;
2154 }
2155
2156 error:
2157
2158 if (err != NO_ERROR) {
2159 // Clean up after an error.
2160 if (anb != NULL) {
2161 mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2162 }
2163
2164 native_window_api_disconnect(mNativeWindow.get(),
2165 NATIVE_WINDOW_API_CPU);
2166 native_window_api_connect(mNativeWindow.get(),
2167 NATIVE_WINDOW_API_MEDIA);
2168
2169 return err;
2170 } else {
2171 // Clean up after success.
2172 err = native_window_api_disconnect(mNativeWindow.get(),
2173 NATIVE_WINDOW_API_CPU);
2174 if (err != NO_ERROR) {
2175 ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2176 strerror(-err), -err);
2177 return err;
2178 }
2179
2180 err = native_window_api_connect(mNativeWindow.get(),
2181 NATIVE_WINDOW_API_MEDIA);
2182 if (err != NO_ERROR) {
2183 ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2184 strerror(-err), -err);
2185 return err;
2186 }
2187
2188 return NO_ERROR;
2189 }
2190 }
2191
getDecodingTimeUs()2192 int64_t OMXCodec::getDecodingTimeUs() {
2193 CHECK(mIsEncoder && mIsVideo);
2194
2195 if (mDecodingTimeList.empty()) {
2196 CHECK(mSignalledEOS || mNoMoreOutputData);
2197 // No corresponding input frame available.
2198 // This could happen when EOS is reached.
2199 return 0;
2200 }
2201
2202 List<int64_t>::iterator it = mDecodingTimeList.begin();
2203 int64_t timeUs = *it;
2204 mDecodingTimeList.erase(it);
2205 return timeUs;
2206 }
2207
on_message(const omx_message & msg)2208 void OMXCodec::on_message(const omx_message &msg) {
2209 if (mState == ERROR) {
2210 /*
2211 * only drop EVENT messages, EBD and FBD are still
2212 * processed for bookkeeping purposes
2213 */
2214 if (msg.type == omx_message::EVENT) {
2215 ALOGW("Dropping OMX EVENT message - we're in ERROR state.");
2216 return;
2217 }
2218 }
2219
2220 switch (msg.type) {
2221 case omx_message::EVENT:
2222 {
2223 onEvent(
2224 msg.u.event_data.event, msg.u.event_data.data1,
2225 msg.u.event_data.data2);
2226
2227 break;
2228 }
2229
2230 case omx_message::EMPTY_BUFFER_DONE:
2231 {
2232 IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
2233
2234 CODEC_LOGV("EMPTY_BUFFER_DONE(buffer: %u)", buffer);
2235
2236 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
2237 size_t i = 0;
2238 while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
2239 ++i;
2240 }
2241
2242 CHECK(i < buffers->size());
2243 if ((*buffers)[i].mStatus != OWNED_BY_COMPONENT) {
2244 ALOGW("We already own input buffer %u, yet received "
2245 "an EMPTY_BUFFER_DONE.", buffer);
2246 }
2247
2248 BufferInfo* info = &buffers->editItemAt(i);
2249 info->mStatus = OWNED_BY_US;
2250
2251 // Buffer could not be released until empty buffer done is called.
2252 if (info->mMediaBuffer != NULL) {
2253 info->mMediaBuffer->release();
2254 info->mMediaBuffer = NULL;
2255 }
2256
2257 if (mPortStatus[kPortIndexInput] == DISABLING) {
2258 CODEC_LOGV("Port is disabled, freeing buffer %u", buffer);
2259
2260 status_t err = freeBuffer(kPortIndexInput, i);
2261 CHECK_EQ(err, (status_t)OK);
2262 } else if (mState != ERROR
2263 && mPortStatus[kPortIndexInput] != SHUTTING_DOWN) {
2264 CHECK_EQ((int)mPortStatus[kPortIndexInput], (int)ENABLED);
2265
2266 if (mFlags & kUseSecureInputBuffers) {
2267 drainAnyInputBuffer();
2268 } else {
2269 drainInputBuffer(&buffers->editItemAt(i));
2270 }
2271 }
2272 break;
2273 }
2274
2275 case omx_message::FILL_BUFFER_DONE:
2276 {
2277 IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
2278 OMX_U32 flags = msg.u.extended_buffer_data.flags;
2279
2280 CODEC_LOGV("FILL_BUFFER_DONE(buffer: %u, size: %u, flags: 0x%08x, timestamp: %lld us (%.2f secs))",
2281 buffer,
2282 msg.u.extended_buffer_data.range_length,
2283 flags,
2284 msg.u.extended_buffer_data.timestamp,
2285 msg.u.extended_buffer_data.timestamp / 1E6);
2286
2287 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
2288 size_t i = 0;
2289 while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
2290 ++i;
2291 }
2292
2293 CHECK(i < buffers->size());
2294 BufferInfo *info = &buffers->editItemAt(i);
2295
2296 if (info->mStatus != OWNED_BY_COMPONENT) {
2297 ALOGW("We already own output buffer %u, yet received "
2298 "a FILL_BUFFER_DONE.", buffer);
2299 }
2300
2301 info->mStatus = OWNED_BY_US;
2302
2303 if (mPortStatus[kPortIndexOutput] == DISABLING) {
2304 CODEC_LOGV("Port is disabled, freeing buffer %u", buffer);
2305
2306 status_t err = freeBuffer(kPortIndexOutput, i);
2307 CHECK_EQ(err, (status_t)OK);
2308
2309 #if 0
2310 } else if (mPortStatus[kPortIndexOutput] == ENABLED
2311 && (flags & OMX_BUFFERFLAG_EOS)) {
2312 CODEC_LOGV("No more output data.");
2313 mNoMoreOutputData = true;
2314 mBufferFilled.signal();
2315 #endif
2316 } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) {
2317 CHECK_EQ((int)mPortStatus[kPortIndexOutput], (int)ENABLED);
2318
2319 MediaBuffer *buffer = info->mMediaBuffer;
2320 bool isGraphicBuffer = buffer->graphicBuffer() != NULL;
2321
2322 if (!isGraphicBuffer
2323 && msg.u.extended_buffer_data.range_offset
2324 + msg.u.extended_buffer_data.range_length
2325 > buffer->size()) {
2326 CODEC_LOGE(
2327 "Codec lied about its buffer size requirements, "
2328 "sending a buffer larger than the originally "
2329 "advertised size in FILL_BUFFER_DONE!");
2330 }
2331 buffer->set_range(
2332 msg.u.extended_buffer_data.range_offset,
2333 msg.u.extended_buffer_data.range_length);
2334
2335 buffer->meta_data()->clear();
2336
2337 buffer->meta_data()->setInt64(
2338 kKeyTime, msg.u.extended_buffer_data.timestamp);
2339
2340 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) {
2341 buffer->meta_data()->setInt32(kKeyIsSyncFrame, true);
2342 }
2343 bool isCodecSpecific = false;
2344 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_CODECCONFIG) {
2345 buffer->meta_data()->setInt32(kKeyIsCodecConfig, true);
2346 isCodecSpecific = true;
2347 }
2348
2349 if (isGraphicBuffer || mQuirks & kOutputBuffersAreUnreadable) {
2350 buffer->meta_data()->setInt32(kKeyIsUnreadable, true);
2351 }
2352
2353 buffer->meta_data()->setInt32(
2354 kKeyBufferID,
2355 msg.u.extended_buffer_data.buffer);
2356
2357 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_EOS) {
2358 CODEC_LOGV("No more output data.");
2359 mNoMoreOutputData = true;
2360 }
2361
2362 if (mIsEncoder && mIsVideo) {
2363 int64_t decodingTimeUs = isCodecSpecific? 0: getDecodingTimeUs();
2364 buffer->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs);
2365 }
2366
2367 if (mTargetTimeUs >= 0) {
2368 CHECK(msg.u.extended_buffer_data.timestamp <= mTargetTimeUs);
2369
2370 if (msg.u.extended_buffer_data.timestamp < mTargetTimeUs) {
2371 CODEC_LOGV(
2372 "skipping output buffer at timestamp %lld us",
2373 msg.u.extended_buffer_data.timestamp);
2374
2375 fillOutputBuffer(info);
2376 break;
2377 }
2378
2379 CODEC_LOGV(
2380 "returning output buffer at target timestamp "
2381 "%lld us",
2382 msg.u.extended_buffer_data.timestamp);
2383
2384 mTargetTimeUs = -1;
2385 }
2386
2387 mFilledBuffers.push_back(i);
2388 mBufferFilled.signal();
2389 if (mIsEncoder) {
2390 sched_yield();
2391 }
2392 }
2393
2394 break;
2395 }
2396
2397 default:
2398 {
2399 CHECK(!"should not be here.");
2400 break;
2401 }
2402 }
2403 }
2404
2405 // 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)2406 static bool formatHasNotablyChanged(
2407 const sp<MetaData> &from, const sp<MetaData> &to) {
2408 if (from.get() == NULL && to.get() == NULL) {
2409 return false;
2410 }
2411
2412 if ((from.get() == NULL && to.get() != NULL)
2413 || (from.get() != NULL && to.get() == NULL)) {
2414 return true;
2415 }
2416
2417 const char *mime_from, *mime_to;
2418 CHECK(from->findCString(kKeyMIMEType, &mime_from));
2419 CHECK(to->findCString(kKeyMIMEType, &mime_to));
2420
2421 if (strcasecmp(mime_from, mime_to)) {
2422 return true;
2423 }
2424
2425 if (!strcasecmp(mime_from, MEDIA_MIMETYPE_VIDEO_RAW)) {
2426 int32_t colorFormat_from, colorFormat_to;
2427 CHECK(from->findInt32(kKeyColorFormat, &colorFormat_from));
2428 CHECK(to->findInt32(kKeyColorFormat, &colorFormat_to));
2429
2430 if (colorFormat_from != colorFormat_to) {
2431 return true;
2432 }
2433
2434 int32_t width_from, width_to;
2435 CHECK(from->findInt32(kKeyWidth, &width_from));
2436 CHECK(to->findInt32(kKeyWidth, &width_to));
2437
2438 if (width_from != width_to) {
2439 return true;
2440 }
2441
2442 int32_t height_from, height_to;
2443 CHECK(from->findInt32(kKeyHeight, &height_from));
2444 CHECK(to->findInt32(kKeyHeight, &height_to));
2445
2446 if (height_from != height_to) {
2447 return true;
2448 }
2449
2450 int32_t left_from, top_from, right_from, bottom_from;
2451 CHECK(from->findRect(
2452 kKeyCropRect,
2453 &left_from, &top_from, &right_from, &bottom_from));
2454
2455 int32_t left_to, top_to, right_to, bottom_to;
2456 CHECK(to->findRect(
2457 kKeyCropRect,
2458 &left_to, &top_to, &right_to, &bottom_to));
2459
2460 if (left_to != left_from || top_to != top_from
2461 || right_to != right_from || bottom_to != bottom_from) {
2462 return true;
2463 }
2464 } else if (!strcasecmp(mime_from, MEDIA_MIMETYPE_AUDIO_RAW)) {
2465 int32_t numChannels_from, numChannels_to;
2466 CHECK(from->findInt32(kKeyChannelCount, &numChannels_from));
2467 CHECK(to->findInt32(kKeyChannelCount, &numChannels_to));
2468
2469 if (numChannels_from != numChannels_to) {
2470 return true;
2471 }
2472
2473 int32_t sampleRate_from, sampleRate_to;
2474 CHECK(from->findInt32(kKeySampleRate, &sampleRate_from));
2475 CHECK(to->findInt32(kKeySampleRate, &sampleRate_to));
2476
2477 if (sampleRate_from != sampleRate_to) {
2478 return true;
2479 }
2480 }
2481
2482 return false;
2483 }
2484
onEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)2485 void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2486 switch (event) {
2487 case OMX_EventCmdComplete:
2488 {
2489 onCmdComplete((OMX_COMMANDTYPE)data1, data2);
2490 break;
2491 }
2492
2493 case OMX_EventError:
2494 {
2495 CODEC_LOGE("OMX_EventError(0x%08x, %u)", data1, data2);
2496
2497 setState(ERROR);
2498 break;
2499 }
2500
2501 case OMX_EventPortSettingsChanged:
2502 {
2503 CODEC_LOGV("OMX_EventPortSettingsChanged(port=%u, data2=0x%08x)",
2504 data1, data2);
2505
2506 if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
2507 onPortSettingsChanged(data1);
2508 } else if (data1 == kPortIndexOutput &&
2509 (data2 == OMX_IndexConfigCommonOutputCrop ||
2510 data2 == OMX_IndexConfigCommonScale)) {
2511
2512 sp<MetaData> oldOutputFormat = mOutputFormat;
2513 initOutputFormat(mSource->getFormat());
2514
2515 if (data2 == OMX_IndexConfigCommonOutputCrop &&
2516 formatHasNotablyChanged(oldOutputFormat, mOutputFormat)) {
2517 mOutputPortSettingsHaveChanged = true;
2518
2519 } else if (data2 == OMX_IndexConfigCommonScale) {
2520 OMX_CONFIG_SCALEFACTORTYPE scale;
2521 InitOMXParams(&scale);
2522 scale.nPortIndex = kPortIndexOutput;
2523
2524 // Change display dimension only when necessary.
2525 if (OK == mOMX->getConfig(
2526 mNode,
2527 OMX_IndexConfigCommonScale,
2528 &scale, sizeof(scale))) {
2529 int32_t left, top, right, bottom;
2530 CHECK(mOutputFormat->findRect(kKeyCropRect,
2531 &left, &top,
2532 &right, &bottom));
2533
2534 // The scale is in 16.16 format.
2535 // scale 1.0 = 0x010000. When there is no
2536 // need to change the display, skip it.
2537 ALOGV("Get OMX_IndexConfigScale: 0x%x/0x%x",
2538 scale.xWidth, scale.xHeight);
2539
2540 if (scale.xWidth != 0x010000) {
2541 mOutputFormat->setInt32(kKeyDisplayWidth,
2542 ((right - left + 1) * scale.xWidth) >> 16);
2543 mOutputPortSettingsHaveChanged = true;
2544 }
2545
2546 if (scale.xHeight != 0x010000) {
2547 mOutputFormat->setInt32(kKeyDisplayHeight,
2548 ((bottom - top + 1) * scale.xHeight) >> 16);
2549 mOutputPortSettingsHaveChanged = true;
2550 }
2551 }
2552 }
2553 }
2554 break;
2555 }
2556
2557 #if 0
2558 case OMX_EventBufferFlag:
2559 {
2560 CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1);
2561
2562 if (data1 == kPortIndexOutput) {
2563 mNoMoreOutputData = true;
2564 }
2565 break;
2566 }
2567 #endif
2568
2569 default:
2570 {
2571 CODEC_LOGV("EVENT(%d, %u, %u)", event, data1, data2);
2572 break;
2573 }
2574 }
2575 }
2576
onCmdComplete(OMX_COMMANDTYPE cmd,OMX_U32 data)2577 void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) {
2578 switch (cmd) {
2579 case OMX_CommandStateSet:
2580 {
2581 onStateChange((OMX_STATETYPE)data);
2582 break;
2583 }
2584
2585 case OMX_CommandPortDisable:
2586 {
2587 OMX_U32 portIndex = data;
2588 CODEC_LOGV("PORT_DISABLED(%u)", portIndex);
2589
2590 CHECK(mState == EXECUTING || mState == RECONFIGURING);
2591 CHECK_EQ((int)mPortStatus[portIndex], (int)DISABLING);
2592 CHECK_EQ(mPortBuffers[portIndex].size(), 0u);
2593
2594 mPortStatus[portIndex] = DISABLED;
2595
2596 if (mState == RECONFIGURING) {
2597 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
2598
2599 sp<MetaData> oldOutputFormat = mOutputFormat;
2600 initOutputFormat(mSource->getFormat());
2601
2602 // Don't notify clients if the output port settings change
2603 // wasn't of importance to them, i.e. it may be that just the
2604 // number of buffers has changed and nothing else.
2605 bool formatChanged = formatHasNotablyChanged(oldOutputFormat, mOutputFormat);
2606 if (!mOutputPortSettingsHaveChanged) {
2607 mOutputPortSettingsHaveChanged = formatChanged;
2608 }
2609
2610 status_t err = enablePortAsync(portIndex);
2611 if (err != OK) {
2612 CODEC_LOGE("enablePortAsync(%u) failed (err = %d)", portIndex, err);
2613 setState(ERROR);
2614 } else {
2615 err = allocateBuffersOnPort(portIndex);
2616 if (err != OK) {
2617 CODEC_LOGE("allocateBuffersOnPort (%s) failed "
2618 "(err = %d)",
2619 portIndex == kPortIndexInput
2620 ? "input" : "output",
2621 err);
2622
2623 setState(ERROR);
2624 }
2625 }
2626 }
2627 break;
2628 }
2629
2630 case OMX_CommandPortEnable:
2631 {
2632 OMX_U32 portIndex = data;
2633 CODEC_LOGV("PORT_ENABLED(%u)", portIndex);
2634
2635 CHECK(mState == EXECUTING || mState == RECONFIGURING);
2636 CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLING);
2637
2638 mPortStatus[portIndex] = ENABLED;
2639
2640 if (mState == RECONFIGURING) {
2641 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
2642
2643 setState(EXECUTING);
2644
2645 fillOutputBuffers();
2646 }
2647 break;
2648 }
2649
2650 case OMX_CommandFlush:
2651 {
2652 OMX_U32 portIndex = data;
2653
2654 CODEC_LOGV("FLUSH_DONE(%u)", portIndex);
2655
2656 CHECK_EQ((int)mPortStatus[portIndex], (int)SHUTTING_DOWN);
2657 mPortStatus[portIndex] = ENABLED;
2658
2659 CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]),
2660 mPortBuffers[portIndex].size());
2661
2662 if (mSkipCutBuffer != NULL && mPortStatus[kPortIndexOutput] == ENABLED) {
2663 mSkipCutBuffer->clear();
2664 }
2665
2666 if (mState == RECONFIGURING) {
2667 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
2668
2669 disablePortAsync(portIndex);
2670 } else if (mState == EXECUTING_TO_IDLE) {
2671 if (mPortStatus[kPortIndexInput] == ENABLED
2672 && mPortStatus[kPortIndexOutput] == ENABLED) {
2673 CODEC_LOGV("Finished flushing both ports, now completing "
2674 "transition from EXECUTING to IDLE.");
2675
2676 mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
2677 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
2678
2679 status_t err =
2680 mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
2681 CHECK_EQ(err, (status_t)OK);
2682 }
2683 } else {
2684 // We're flushing both ports in preparation for seeking.
2685
2686 if (mPortStatus[kPortIndexInput] == ENABLED
2687 && mPortStatus[kPortIndexOutput] == ENABLED) {
2688 CODEC_LOGV("Finished flushing both ports, now continuing from"
2689 " seek-time.");
2690
2691 // We implicitly resume pulling on our upstream source.
2692 mPaused = false;
2693
2694 drainInputBuffers();
2695 fillOutputBuffers();
2696 }
2697
2698 if (mOutputPortSettingsChangedPending) {
2699 CODEC_LOGV(
2700 "Honoring deferred output port settings change.");
2701
2702 mOutputPortSettingsChangedPending = false;
2703 onPortSettingsChanged(kPortIndexOutput);
2704 }
2705 }
2706
2707 break;
2708 }
2709
2710 default:
2711 {
2712 CODEC_LOGV("CMD_COMPLETE(%d, %ld)", cmd, data);
2713 break;
2714 }
2715 }
2716 }
2717
onStateChange(OMX_STATETYPE newState)2718 void OMXCodec::onStateChange(OMX_STATETYPE newState) {
2719 CODEC_LOGV("onStateChange %d", newState);
2720
2721 switch (newState) {
2722 case OMX_StateIdle:
2723 {
2724 CODEC_LOGV("Now Idle.");
2725 if (mState == LOADED_TO_IDLE) {
2726 status_t err = mOMX->sendCommand(
2727 mNode, OMX_CommandStateSet, OMX_StateExecuting);
2728
2729 CHECK_EQ(err, (status_t)OK);
2730
2731 setState(IDLE_TO_EXECUTING);
2732 } else {
2733 CHECK_EQ((int)mState, (int)EXECUTING_TO_IDLE);
2734
2735 if (countBuffersWeOwn(mPortBuffers[kPortIndexInput]) !=
2736 mPortBuffers[kPortIndexInput].size()) {
2737 ALOGE("Codec did not return all input buffers "
2738 "(received %d / %d)",
2739 countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
2740 mPortBuffers[kPortIndexInput].size());
2741 TRESPASS();
2742 }
2743
2744 if (countBuffersWeOwn(mPortBuffers[kPortIndexOutput]) !=
2745 mPortBuffers[kPortIndexOutput].size()) {
2746 ALOGE("Codec did not return all output buffers "
2747 "(received %d / %d)",
2748 countBuffersWeOwn(mPortBuffers[kPortIndexOutput]),
2749 mPortBuffers[kPortIndexOutput].size());
2750 TRESPASS();
2751 }
2752
2753 status_t err = mOMX->sendCommand(
2754 mNode, OMX_CommandStateSet, OMX_StateLoaded);
2755
2756 CHECK_EQ(err, (status_t)OK);
2757
2758 err = freeBuffersOnPort(kPortIndexInput);
2759 CHECK_EQ(err, (status_t)OK);
2760
2761 err = freeBuffersOnPort(kPortIndexOutput);
2762 CHECK_EQ(err, (status_t)OK);
2763
2764 mPortStatus[kPortIndexInput] = ENABLED;
2765 mPortStatus[kPortIndexOutput] = ENABLED;
2766
2767 if ((mFlags & kEnableGrallocUsageProtected) &&
2768 mNativeWindow != NULL) {
2769 // We push enough 1x1 blank buffers to ensure that one of
2770 // them has made it to the display. This allows the OMX
2771 // component teardown to zero out any protected buffers
2772 // without the risk of scanning out one of those buffers.
2773 pushBlankBuffersToNativeWindow();
2774 }
2775
2776 setState(IDLE_TO_LOADED);
2777 }
2778 break;
2779 }
2780
2781 case OMX_StateExecuting:
2782 {
2783 CHECK_EQ((int)mState, (int)IDLE_TO_EXECUTING);
2784
2785 CODEC_LOGV("Now Executing.");
2786
2787 mOutputPortSettingsChangedPending = false;
2788
2789 setState(EXECUTING);
2790
2791 // Buffers will be submitted to the component in the first
2792 // call to OMXCodec::read as mInitialBufferSubmit is true at
2793 // this point. This ensures that this on_message call returns,
2794 // releases the lock and ::init can notice the state change and
2795 // itself return.
2796 break;
2797 }
2798
2799 case OMX_StateLoaded:
2800 {
2801 CHECK_EQ((int)mState, (int)IDLE_TO_LOADED);
2802
2803 CODEC_LOGV("Now Loaded.");
2804
2805 setState(LOADED);
2806 break;
2807 }
2808
2809 case OMX_StateInvalid:
2810 {
2811 setState(ERROR);
2812 break;
2813 }
2814
2815 default:
2816 {
2817 CHECK(!"should not be here.");
2818 break;
2819 }
2820 }
2821 }
2822
2823 // static
countBuffersWeOwn(const Vector<BufferInfo> & buffers)2824 size_t OMXCodec::countBuffersWeOwn(const Vector<BufferInfo> &buffers) {
2825 size_t n = 0;
2826 for (size_t i = 0; i < buffers.size(); ++i) {
2827 if (buffers[i].mStatus != OWNED_BY_COMPONENT) {
2828 ++n;
2829 }
2830 }
2831
2832 return n;
2833 }
2834
freeBuffersOnPort(OMX_U32 portIndex,bool onlyThoseWeOwn)2835 status_t OMXCodec::freeBuffersOnPort(
2836 OMX_U32 portIndex, bool onlyThoseWeOwn) {
2837 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
2838
2839 status_t stickyErr = OK;
2840
2841 for (size_t i = buffers->size(); i-- > 0;) {
2842 BufferInfo *info = &buffers->editItemAt(i);
2843
2844 if (onlyThoseWeOwn && info->mStatus == OWNED_BY_COMPONENT) {
2845 continue;
2846 }
2847
2848 CHECK(info->mStatus == OWNED_BY_US
2849 || info->mStatus == OWNED_BY_NATIVE_WINDOW);
2850
2851 CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex);
2852
2853 status_t err = freeBuffer(portIndex, i);
2854
2855 if (err != OK) {
2856 stickyErr = err;
2857 }
2858
2859 }
2860
2861 CHECK(onlyThoseWeOwn || buffers->isEmpty());
2862
2863 return stickyErr;
2864 }
2865
freeBuffer(OMX_U32 portIndex,size_t bufIndex)2866 status_t OMXCodec::freeBuffer(OMX_U32 portIndex, size_t bufIndex) {
2867 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
2868
2869 BufferInfo *info = &buffers->editItemAt(bufIndex);
2870
2871 status_t err = mOMX->freeBuffer(mNode, portIndex, info->mBuffer);
2872
2873 if (err == OK && info->mMediaBuffer != NULL) {
2874 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
2875 info->mMediaBuffer->setObserver(NULL);
2876
2877 // Make sure nobody but us owns this buffer at this point.
2878 CHECK_EQ(info->mMediaBuffer->refcount(), 0);
2879
2880 // Cancel the buffer if it belongs to an ANativeWindow.
2881 sp<GraphicBuffer> graphicBuffer = info->mMediaBuffer->graphicBuffer();
2882 if (info->mStatus == OWNED_BY_US && graphicBuffer != 0) {
2883 err = cancelBufferToNativeWindow(info);
2884 }
2885
2886 info->mMediaBuffer->release();
2887 info->mMediaBuffer = NULL;
2888 }
2889
2890 if (err == OK) {
2891 buffers->removeAt(bufIndex);
2892 }
2893
2894 return err;
2895 }
2896
onPortSettingsChanged(OMX_U32 portIndex)2897 void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) {
2898 CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex);
2899
2900 CHECK(mState == EXECUTING || mState == EXECUTING_TO_IDLE);
2901 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
2902 CHECK(!mOutputPortSettingsChangedPending);
2903
2904 if (mPortStatus[kPortIndexOutput] != ENABLED) {
2905 CODEC_LOGV("Deferring output port settings change.");
2906 mOutputPortSettingsChangedPending = true;
2907 return;
2908 }
2909
2910 setState(RECONFIGURING);
2911
2912 if (mQuirks & kNeedsFlushBeforeDisable) {
2913 if (!flushPortAsync(portIndex)) {
2914 onCmdComplete(OMX_CommandFlush, portIndex);
2915 }
2916 } else {
2917 disablePortAsync(portIndex);
2918 }
2919 }
2920
flushPortAsync(OMX_U32 portIndex)2921 bool OMXCodec::flushPortAsync(OMX_U32 portIndex) {
2922 CHECK(mState == EXECUTING || mState == RECONFIGURING
2923 || mState == EXECUTING_TO_IDLE);
2924
2925 CODEC_LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.",
2926 portIndex, countBuffersWeOwn(mPortBuffers[portIndex]),
2927 mPortBuffers[portIndex].size());
2928
2929 CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLED);
2930 mPortStatus[portIndex] = SHUTTING_DOWN;
2931
2932 if ((mQuirks & kRequiresFlushCompleteEmulation)
2933 && countBuffersWeOwn(mPortBuffers[portIndex])
2934 == mPortBuffers[portIndex].size()) {
2935 // No flush is necessary and this component fails to send a
2936 // flush-complete event in this case.
2937
2938 return false;
2939 }
2940
2941 status_t err =
2942 mOMX->sendCommand(mNode, OMX_CommandFlush, portIndex);
2943 CHECK_EQ(err, (status_t)OK);
2944
2945 return true;
2946 }
2947
disablePortAsync(OMX_U32 portIndex)2948 void OMXCodec::disablePortAsync(OMX_U32 portIndex) {
2949 CHECK(mState == EXECUTING || mState == RECONFIGURING);
2950
2951 CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLED);
2952 mPortStatus[portIndex] = DISABLING;
2953
2954 CODEC_LOGV("sending OMX_CommandPortDisable(%ld)", portIndex);
2955 status_t err =
2956 mOMX->sendCommand(mNode, OMX_CommandPortDisable, portIndex);
2957 CHECK_EQ(err, (status_t)OK);
2958
2959 freeBuffersOnPort(portIndex, true);
2960 }
2961
enablePortAsync(OMX_U32 portIndex)2962 status_t OMXCodec::enablePortAsync(OMX_U32 portIndex) {
2963 CHECK(mState == EXECUTING || mState == RECONFIGURING);
2964
2965 CHECK_EQ((int)mPortStatus[portIndex], (int)DISABLED);
2966 mPortStatus[portIndex] = ENABLING;
2967
2968 CODEC_LOGV("sending OMX_CommandPortEnable(%ld)", portIndex);
2969 return mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex);
2970 }
2971
fillOutputBuffers()2972 void OMXCodec::fillOutputBuffers() {
2973 CHECK_EQ((int)mState, (int)EXECUTING);
2974
2975 // This is a workaround for some decoders not properly reporting
2976 // end-of-output-stream. If we own all input buffers and also own
2977 // all output buffers and we already signalled end-of-input-stream,
2978 // the end-of-output-stream is implied.
2979 if (mSignalledEOS
2980 && countBuffersWeOwn(mPortBuffers[kPortIndexInput])
2981 == mPortBuffers[kPortIndexInput].size()
2982 && countBuffersWeOwn(mPortBuffers[kPortIndexOutput])
2983 == mPortBuffers[kPortIndexOutput].size()) {
2984 mNoMoreOutputData = true;
2985 mBufferFilled.signal();
2986
2987 return;
2988 }
2989
2990 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
2991 for (size_t i = 0; i < buffers->size(); ++i) {
2992 BufferInfo *info = &buffers->editItemAt(i);
2993 if (info->mStatus == OWNED_BY_US) {
2994 fillOutputBuffer(&buffers->editItemAt(i));
2995 }
2996 }
2997 }
2998
drainInputBuffers()2999 void OMXCodec::drainInputBuffers() {
3000 CHECK(mState == EXECUTING || mState == RECONFIGURING);
3001
3002 if (mFlags & kUseSecureInputBuffers) {
3003 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
3004 for (size_t i = 0; i < buffers->size(); ++i) {
3005 if (!drainAnyInputBuffer()
3006 || (mFlags & kOnlySubmitOneInputBufferAtOneTime)) {
3007 break;
3008 }
3009 }
3010 } else {
3011 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
3012 for (size_t i = 0; i < buffers->size(); ++i) {
3013 BufferInfo *info = &buffers->editItemAt(i);
3014
3015 if (info->mStatus != OWNED_BY_US) {
3016 continue;
3017 }
3018
3019 if (!drainInputBuffer(info)) {
3020 break;
3021 }
3022
3023 if (mFlags & kOnlySubmitOneInputBufferAtOneTime) {
3024 break;
3025 }
3026 }
3027 }
3028 }
3029
drainAnyInputBuffer()3030 bool OMXCodec::drainAnyInputBuffer() {
3031 return drainInputBuffer((BufferInfo *)NULL);
3032 }
3033
findInputBufferByDataPointer(void * ptr)3034 OMXCodec::BufferInfo *OMXCodec::findInputBufferByDataPointer(void *ptr) {
3035 Vector<BufferInfo> *infos = &mPortBuffers[kPortIndexInput];
3036 for (size_t i = 0; i < infos->size(); ++i) {
3037 BufferInfo *info = &infos->editItemAt(i);
3038
3039 if (info->mData == ptr) {
3040 CODEC_LOGV(
3041 "input buffer data ptr = %p, buffer_id = %p",
3042 ptr,
3043 info->mBuffer);
3044
3045 return info;
3046 }
3047 }
3048
3049 TRESPASS();
3050 }
3051
findEmptyInputBuffer()3052 OMXCodec::BufferInfo *OMXCodec::findEmptyInputBuffer() {
3053 Vector<BufferInfo> *infos = &mPortBuffers[kPortIndexInput];
3054 for (size_t i = 0; i < infos->size(); ++i) {
3055 BufferInfo *info = &infos->editItemAt(i);
3056
3057 if (info->mStatus == OWNED_BY_US) {
3058 return info;
3059 }
3060 }
3061
3062 TRESPASS();
3063 }
3064
drainInputBuffer(BufferInfo * info)3065 bool OMXCodec::drainInputBuffer(BufferInfo *info) {
3066 if (info != NULL) {
3067 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
3068 }
3069
3070 if (mSignalledEOS) {
3071 return false;
3072 }
3073
3074 if (mCodecSpecificDataIndex < mCodecSpecificData.size()) {
3075 CHECK(!(mFlags & kUseSecureInputBuffers));
3076
3077 const CodecSpecificData *specific =
3078 mCodecSpecificData[mCodecSpecificDataIndex];
3079
3080 size_t size = specific->mSize;
3081
3082 if ((!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME) ||
3083 !strcasecmp(MEDIA_MIMETYPE_VIDEO_HEVC, mMIME))
3084 && !(mQuirks & kWantsNALFragments)) {
3085 static const uint8_t kNALStartCode[4] =
3086 { 0x00, 0x00, 0x00, 0x01 };
3087
3088 CHECK(info->mSize >= specific->mSize + 4);
3089
3090 size += 4;
3091
3092 memcpy(info->mData, kNALStartCode, 4);
3093 memcpy((uint8_t *)info->mData + 4,
3094 specific->mData, specific->mSize);
3095 } else {
3096 CHECK(info->mSize >= specific->mSize);
3097 memcpy(info->mData, specific->mData, specific->mSize);
3098 }
3099
3100 mNoMoreOutputData = false;
3101
3102 CODEC_LOGV("calling emptyBuffer with codec specific data");
3103
3104 status_t err = mOMX->emptyBuffer(
3105 mNode, info->mBuffer, 0, size,
3106 OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG,
3107 0);
3108 CHECK_EQ(err, (status_t)OK);
3109
3110 info->mStatus = OWNED_BY_COMPONENT;
3111
3112 ++mCodecSpecificDataIndex;
3113 return true;
3114 }
3115
3116 if (mPaused) {
3117 return false;
3118 }
3119
3120 status_t err;
3121
3122 bool signalEOS = false;
3123 int64_t timestampUs = 0;
3124
3125 size_t offset = 0;
3126 int32_t n = 0;
3127
3128
3129 for (;;) {
3130 MediaBuffer *srcBuffer;
3131 if (mSeekTimeUs >= 0) {
3132 if (mLeftOverBuffer) {
3133 mLeftOverBuffer->release();
3134 mLeftOverBuffer = NULL;
3135 }
3136
3137 MediaSource::ReadOptions options;
3138 options.setSeekTo(mSeekTimeUs, mSeekMode);
3139
3140 mSeekTimeUs = -1;
3141 mSeekMode = ReadOptions::SEEK_CLOSEST_SYNC;
3142 mBufferFilled.signal();
3143
3144 err = mSource->read(&srcBuffer, &options);
3145
3146 if (err == OK) {
3147 int64_t targetTimeUs;
3148 if (srcBuffer->meta_data()->findInt64(
3149 kKeyTargetTime, &targetTimeUs)
3150 && targetTimeUs >= 0) {
3151 CODEC_LOGV("targetTimeUs = %lld us", targetTimeUs);
3152 mTargetTimeUs = targetTimeUs;
3153 } else {
3154 mTargetTimeUs = -1;
3155 }
3156 }
3157 } else if (mLeftOverBuffer) {
3158 srcBuffer = mLeftOverBuffer;
3159 mLeftOverBuffer = NULL;
3160
3161 err = OK;
3162 } else {
3163 err = mSource->read(&srcBuffer);
3164 }
3165
3166 if (err != OK) {
3167 signalEOS = true;
3168 mFinalStatus = err;
3169 mSignalledEOS = true;
3170 mBufferFilled.signal();
3171 break;
3172 }
3173
3174 if (mFlags & kUseSecureInputBuffers) {
3175 info = findInputBufferByDataPointer(srcBuffer->data());
3176 CHECK(info != NULL);
3177 }
3178
3179 size_t remainingBytes = info->mSize - offset;
3180
3181 if (srcBuffer->range_length() > remainingBytes) {
3182 if (offset == 0) {
3183 CODEC_LOGE(
3184 "Codec's input buffers are too small to accomodate "
3185 "buffer read from source (info->mSize = %d, srcLength = %d)",
3186 info->mSize, srcBuffer->range_length());
3187
3188 srcBuffer->release();
3189 srcBuffer = NULL;
3190
3191 setState(ERROR);
3192 return false;
3193 }
3194
3195 mLeftOverBuffer = srcBuffer;
3196 break;
3197 }
3198
3199 bool releaseBuffer = true;
3200 if (mFlags & kStoreMetaDataInVideoBuffers) {
3201 releaseBuffer = false;
3202 info->mMediaBuffer = srcBuffer;
3203 }
3204
3205 if (mFlags & kUseSecureInputBuffers) {
3206 // Data in "info" is already provided at this time.
3207
3208 releaseBuffer = false;
3209
3210 CHECK(info->mMediaBuffer == NULL);
3211 info->mMediaBuffer = srcBuffer;
3212 } else {
3213 CHECK(srcBuffer->data() != NULL) ;
3214 memcpy((uint8_t *)info->mData + offset,
3215 (const uint8_t *)srcBuffer->data()
3216 + srcBuffer->range_offset(),
3217 srcBuffer->range_length());
3218 }
3219
3220 int64_t lastBufferTimeUs;
3221 CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &lastBufferTimeUs));
3222 CHECK(lastBufferTimeUs >= 0);
3223 if (mIsEncoder && mIsVideo) {
3224 mDecodingTimeList.push_back(lastBufferTimeUs);
3225 }
3226
3227 if (offset == 0) {
3228 timestampUs = lastBufferTimeUs;
3229 }
3230
3231 offset += srcBuffer->range_length();
3232
3233 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_VORBIS, mMIME)) {
3234 CHECK(!(mQuirks & kSupportsMultipleFramesPerInputBuffer));
3235 CHECK_GE(info->mSize, offset + sizeof(int32_t));
3236
3237 int32_t numPageSamples;
3238 if (!srcBuffer->meta_data()->findInt32(
3239 kKeyValidSamples, &numPageSamples)) {
3240 numPageSamples = -1;
3241 }
3242
3243 memcpy((uint8_t *)info->mData + offset,
3244 &numPageSamples,
3245 sizeof(numPageSamples));
3246
3247 offset += sizeof(numPageSamples);
3248 }
3249
3250 if (releaseBuffer) {
3251 srcBuffer->release();
3252 srcBuffer = NULL;
3253 }
3254
3255 ++n;
3256
3257 if (!(mQuirks & kSupportsMultipleFramesPerInputBuffer)) {
3258 break;
3259 }
3260
3261 int64_t coalescedDurationUs = lastBufferTimeUs - timestampUs;
3262
3263 if (coalescedDurationUs > 250000ll) {
3264 // Don't coalesce more than 250ms worth of encoded data at once.
3265 break;
3266 }
3267 }
3268
3269 if (n > 1) {
3270 ALOGV("coalesced %d frames into one input buffer", n);
3271 }
3272
3273 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3274
3275 if (signalEOS) {
3276 flags |= OMX_BUFFERFLAG_EOS;
3277 } else {
3278 mNoMoreOutputData = false;
3279 }
3280
3281 if (info == NULL) {
3282 CHECK(mFlags & kUseSecureInputBuffers);
3283 CHECK(signalEOS);
3284
3285 // This is fishy, there's still a MediaBuffer corresponding to this
3286 // info available to the source at this point even though we're going
3287 // to use it to signal EOS to the codec.
3288 info = findEmptyInputBuffer();
3289 }
3290
3291 CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d), "
3292 "timestamp %lld us (%.2f secs)",
3293 info->mBuffer, offset,
3294 timestampUs, timestampUs / 1E6);
3295
3296 err = mOMX->emptyBuffer(
3297 mNode, info->mBuffer, 0, offset,
3298 flags, timestampUs);
3299
3300 if (err != OK) {
3301 setState(ERROR);
3302 return false;
3303 }
3304
3305 info->mStatus = OWNED_BY_COMPONENT;
3306
3307 return true;
3308 }
3309
fillOutputBuffer(BufferInfo * info)3310 void OMXCodec::fillOutputBuffer(BufferInfo *info) {
3311 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
3312
3313 if (mNoMoreOutputData) {
3314 CODEC_LOGV("There is no more output data available, not "
3315 "calling fillOutputBuffer");
3316 return;
3317 }
3318
3319 CODEC_LOGV("Calling fillBuffer on buffer %p", info->mBuffer);
3320 status_t err = mOMX->fillBuffer(mNode, info->mBuffer);
3321
3322 if (err != OK) {
3323 CODEC_LOGE("fillBuffer failed w/ error 0x%08x", err);
3324
3325 setState(ERROR);
3326 return;
3327 }
3328
3329 info->mStatus = OWNED_BY_COMPONENT;
3330 }
3331
drainInputBuffer(IOMX::buffer_id buffer)3332 bool OMXCodec::drainInputBuffer(IOMX::buffer_id buffer) {
3333 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
3334 for (size_t i = 0; i < buffers->size(); ++i) {
3335 if ((*buffers)[i].mBuffer == buffer) {
3336 return drainInputBuffer(&buffers->editItemAt(i));
3337 }
3338 }
3339
3340 CHECK(!"should not be here.");
3341
3342 return false;
3343 }
3344
fillOutputBuffer(IOMX::buffer_id buffer)3345 void OMXCodec::fillOutputBuffer(IOMX::buffer_id buffer) {
3346 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
3347 for (size_t i = 0; i < buffers->size(); ++i) {
3348 if ((*buffers)[i].mBuffer == buffer) {
3349 fillOutputBuffer(&buffers->editItemAt(i));
3350 return;
3351 }
3352 }
3353
3354 CHECK(!"should not be here.");
3355 }
3356
setState(State newState)3357 void OMXCodec::setState(State newState) {
3358 mState = newState;
3359 mAsyncCompletion.signal();
3360
3361 // This may cause some spurious wakeups but is necessary to
3362 // unblock the reader if we enter ERROR state.
3363 mBufferFilled.signal();
3364 }
3365
waitForBufferFilled_l()3366 status_t OMXCodec::waitForBufferFilled_l() {
3367
3368 if (mIsEncoder) {
3369 // For timelapse video recording, the timelapse video recording may
3370 // not send an input frame for a _long_ time. Do not use timeout
3371 // for video encoding.
3372 return mBufferFilled.wait(mLock);
3373 }
3374 status_t err = mBufferFilled.waitRelative(mLock, kBufferFilledEventTimeOutNs);
3375 if (err != OK) {
3376 CODEC_LOGE("Timed out waiting for output buffers: %d/%d",
3377 countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
3378 countBuffersWeOwn(mPortBuffers[kPortIndexOutput]));
3379 }
3380 return err;
3381 }
3382
setRawAudioFormat(OMX_U32 portIndex,int32_t sampleRate,int32_t numChannels)3383 void OMXCodec::setRawAudioFormat(
3384 OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
3385
3386 // port definition
3387 OMX_PARAM_PORTDEFINITIONTYPE def;
3388 InitOMXParams(&def);
3389 def.nPortIndex = portIndex;
3390 status_t err = mOMX->getParameter(
3391 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3392 CHECK_EQ(err, (status_t)OK);
3393 def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
3394 CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition,
3395 &def, sizeof(def)), (status_t)OK);
3396
3397 // pcm param
3398 OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
3399 InitOMXParams(&pcmParams);
3400 pcmParams.nPortIndex = portIndex;
3401
3402 err = mOMX->getParameter(
3403 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
3404
3405 CHECK_EQ(err, (status_t)OK);
3406
3407 pcmParams.nChannels = numChannels;
3408 pcmParams.eNumData = OMX_NumericalDataSigned;
3409 pcmParams.bInterleaved = OMX_TRUE;
3410 pcmParams.nBitPerSample = 16;
3411 pcmParams.nSamplingRate = sampleRate;
3412 pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
3413
3414 CHECK_EQ(getOMXChannelMapping(
3415 numChannels, pcmParams.eChannelMapping), (status_t)OK);
3416
3417 err = mOMX->setParameter(
3418 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
3419
3420 CHECK_EQ(err, (status_t)OK);
3421 }
3422
pickModeFromBitRate(bool isAMRWB,int32_t bps)3423 static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(bool isAMRWB, int32_t bps) {
3424 if (isAMRWB) {
3425 if (bps <= 6600) {
3426 return OMX_AUDIO_AMRBandModeWB0;
3427 } else if (bps <= 8850) {
3428 return OMX_AUDIO_AMRBandModeWB1;
3429 } else if (bps <= 12650) {
3430 return OMX_AUDIO_AMRBandModeWB2;
3431 } else if (bps <= 14250) {
3432 return OMX_AUDIO_AMRBandModeWB3;
3433 } else if (bps <= 15850) {
3434 return OMX_AUDIO_AMRBandModeWB4;
3435 } else if (bps <= 18250) {
3436 return OMX_AUDIO_AMRBandModeWB5;
3437 } else if (bps <= 19850) {
3438 return OMX_AUDIO_AMRBandModeWB6;
3439 } else if (bps <= 23050) {
3440 return OMX_AUDIO_AMRBandModeWB7;
3441 }
3442
3443 // 23850 bps
3444 return OMX_AUDIO_AMRBandModeWB8;
3445 } else { // AMRNB
3446 if (bps <= 4750) {
3447 return OMX_AUDIO_AMRBandModeNB0;
3448 } else if (bps <= 5150) {
3449 return OMX_AUDIO_AMRBandModeNB1;
3450 } else if (bps <= 5900) {
3451 return OMX_AUDIO_AMRBandModeNB2;
3452 } else if (bps <= 6700) {
3453 return OMX_AUDIO_AMRBandModeNB3;
3454 } else if (bps <= 7400) {
3455 return OMX_AUDIO_AMRBandModeNB4;
3456 } else if (bps <= 7950) {
3457 return OMX_AUDIO_AMRBandModeNB5;
3458 } else if (bps <= 10200) {
3459 return OMX_AUDIO_AMRBandModeNB6;
3460 }
3461
3462 // 12200 bps
3463 return OMX_AUDIO_AMRBandModeNB7;
3464 }
3465 }
3466
setAMRFormat(bool isWAMR,int32_t bitRate)3467 void OMXCodec::setAMRFormat(bool isWAMR, int32_t bitRate) {
3468 OMX_U32 portIndex = mIsEncoder ? kPortIndexOutput : kPortIndexInput;
3469
3470 OMX_AUDIO_PARAM_AMRTYPE def;
3471 InitOMXParams(&def);
3472 def.nPortIndex = portIndex;
3473
3474 status_t err =
3475 mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
3476
3477 CHECK_EQ(err, (status_t)OK);
3478
3479 def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
3480
3481 def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitRate);
3482 err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
3483 CHECK_EQ(err, (status_t)OK);
3484
3485 ////////////////////////
3486
3487 if (mIsEncoder) {
3488 sp<MetaData> format = mSource->getFormat();
3489 int32_t sampleRate;
3490 int32_t numChannels;
3491 CHECK(format->findInt32(kKeySampleRate, &sampleRate));
3492 CHECK(format->findInt32(kKeyChannelCount, &numChannels));
3493
3494 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
3495 }
3496 }
3497
setAACFormat(int32_t numChannels,int32_t sampleRate,int32_t bitRate,int32_t aacProfile,bool isADTS)3498 status_t OMXCodec::setAACFormat(
3499 int32_t numChannels, int32_t sampleRate, int32_t bitRate, int32_t aacProfile, bool isADTS) {
3500 if (numChannels > 2) {
3501 ALOGW("Number of channels: (%d) \n", numChannels);
3502 }
3503
3504 if (mIsEncoder) {
3505 if (isADTS) {
3506 return -EINVAL;
3507 }
3508
3509 //////////////// input port ////////////////////
3510 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
3511
3512 //////////////// output port ////////////////////
3513 // format
3514 OMX_AUDIO_PARAM_PORTFORMATTYPE format;
3515 InitOMXParams(&format);
3516 format.nPortIndex = kPortIndexOutput;
3517 format.nIndex = 0;
3518 status_t err = OMX_ErrorNone;
3519 while (OMX_ErrorNone == err) {
3520 CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioPortFormat,
3521 &format, sizeof(format)), (status_t)OK);
3522 if (format.eEncoding == OMX_AUDIO_CodingAAC) {
3523 break;
3524 }
3525 format.nIndex++;
3526 }
3527 CHECK_EQ((status_t)OK, err);
3528 CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamAudioPortFormat,
3529 &format, sizeof(format)), (status_t)OK);
3530
3531 // port definition
3532 OMX_PARAM_PORTDEFINITIONTYPE def;
3533 InitOMXParams(&def);
3534 def.nPortIndex = kPortIndexOutput;
3535 CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamPortDefinition,
3536 &def, sizeof(def)), (status_t)OK);
3537 def.format.audio.bFlagErrorConcealment = OMX_TRUE;
3538 def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
3539 CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition,
3540 &def, sizeof(def)), (status_t)OK);
3541
3542 // profile
3543 OMX_AUDIO_PARAM_AACPROFILETYPE profile;
3544 InitOMXParams(&profile);
3545 profile.nPortIndex = kPortIndexOutput;
3546 CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioAac,
3547 &profile, sizeof(profile)), (status_t)OK);
3548 profile.nChannels = numChannels;
3549 profile.eChannelMode = (numChannels == 1?
3550 OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo);
3551 profile.nSampleRate = sampleRate;
3552 profile.nBitRate = bitRate;
3553 profile.nAudioBandWidth = 0;
3554 profile.nFrameLength = 0;
3555 profile.nAACtools = OMX_AUDIO_AACToolAll;
3556 profile.nAACERtools = OMX_AUDIO_AACERNone;
3557 profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
3558 profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
3559 err = mOMX->setParameter(mNode, OMX_IndexParamAudioAac,
3560 &profile, sizeof(profile));
3561
3562 if (err != OK) {
3563 CODEC_LOGE("setParameter('OMX_IndexParamAudioAac') failed "
3564 "(err = %d)",
3565 err);
3566 return err;
3567 }
3568 } else {
3569 OMX_AUDIO_PARAM_AACPROFILETYPE profile;
3570 InitOMXParams(&profile);
3571 profile.nPortIndex = kPortIndexInput;
3572
3573 status_t err = mOMX->getParameter(
3574 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
3575 CHECK_EQ(err, (status_t)OK);
3576
3577 profile.nChannels = numChannels;
3578 profile.nSampleRate = sampleRate;
3579
3580 profile.eAACStreamFormat =
3581 isADTS
3582 ? OMX_AUDIO_AACStreamFormatMP4ADTS
3583 : OMX_AUDIO_AACStreamFormatMP4FF;
3584
3585 err = mOMX->setParameter(
3586 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
3587
3588 if (err != OK) {
3589 CODEC_LOGE("setParameter('OMX_IndexParamAudioAac') failed "
3590 "(err = %d)",
3591 err);
3592 return err;
3593 }
3594 }
3595
3596 return OK;
3597 }
3598
setAC3Format(int32_t numChannels,int32_t sampleRate)3599 status_t OMXCodec::setAC3Format(int32_t numChannels, int32_t sampleRate) {
3600 OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
3601 InitOMXParams(&def);
3602 def.nPortIndex = kPortIndexInput;
3603
3604 status_t err = mOMX->getParameter(
3605 mNode,
3606 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
3607 &def,
3608 sizeof(def));
3609
3610 if (err != OK) {
3611 return err;
3612 }
3613
3614 def.nChannels = numChannels;
3615 def.nSampleRate = sampleRate;
3616
3617 return mOMX->setParameter(
3618 mNode,
3619 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
3620 &def,
3621 sizeof(def));
3622 }
3623
setG711Format(int32_t numChannels)3624 void OMXCodec::setG711Format(int32_t numChannels) {
3625 CHECK(!mIsEncoder);
3626 setRawAudioFormat(kPortIndexInput, 8000, numChannels);
3627 }
3628
setImageOutputFormat(OMX_COLOR_FORMATTYPE format,OMX_U32 width,OMX_U32 height)3629 void OMXCodec::setImageOutputFormat(
3630 OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) {
3631 CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height);
3632
3633 #if 0
3634 OMX_INDEXTYPE index;
3635 status_t err = mOMX->get_extension_index(
3636 mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index);
3637 CHECK_EQ(err, (status_t)OK);
3638
3639 err = mOMX->set_config(mNode, index, &format, sizeof(format));
3640 CHECK_EQ(err, (status_t)OK);
3641 #endif
3642
3643 OMX_PARAM_PORTDEFINITIONTYPE def;
3644 InitOMXParams(&def);
3645 def.nPortIndex = kPortIndexOutput;
3646
3647 status_t err = mOMX->getParameter(
3648 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3649 CHECK_EQ(err, (status_t)OK);
3650
3651 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainImage);
3652
3653 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
3654
3655 CHECK_EQ((int)imageDef->eCompressionFormat, (int)OMX_IMAGE_CodingUnused);
3656 imageDef->eColorFormat = format;
3657 imageDef->nFrameWidth = width;
3658 imageDef->nFrameHeight = height;
3659
3660 switch (format) {
3661 case OMX_COLOR_FormatYUV420PackedPlanar:
3662 case OMX_COLOR_FormatYUV411Planar:
3663 {
3664 def.nBufferSize = (width * height * 3) / 2;
3665 break;
3666 }
3667
3668 case OMX_COLOR_FormatCbYCrY:
3669 {
3670 def.nBufferSize = width * height * 2;
3671 break;
3672 }
3673
3674 case OMX_COLOR_Format32bitARGB8888:
3675 {
3676 def.nBufferSize = width * height * 4;
3677 break;
3678 }
3679
3680 case OMX_COLOR_Format16bitARGB4444:
3681 case OMX_COLOR_Format16bitARGB1555:
3682 case OMX_COLOR_Format16bitRGB565:
3683 case OMX_COLOR_Format16bitBGR565:
3684 {
3685 def.nBufferSize = width * height * 2;
3686 break;
3687 }
3688
3689 default:
3690 CHECK(!"Should not be here. Unknown color format.");
3691 break;
3692 }
3693
3694 def.nBufferCountActual = def.nBufferCountMin;
3695
3696 err = mOMX->setParameter(
3697 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3698 CHECK_EQ(err, (status_t)OK);
3699 }
3700
setJPEGInputFormat(OMX_U32 width,OMX_U32 height,OMX_U32 compressedSize)3701 void OMXCodec::setJPEGInputFormat(
3702 OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) {
3703 OMX_PARAM_PORTDEFINITIONTYPE def;
3704 InitOMXParams(&def);
3705 def.nPortIndex = kPortIndexInput;
3706
3707 status_t err = mOMX->getParameter(
3708 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3709 CHECK_EQ(err, (status_t)OK);
3710
3711 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainImage);
3712 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
3713
3714 CHECK_EQ((int)imageDef->eCompressionFormat, (int)OMX_IMAGE_CodingJPEG);
3715 imageDef->nFrameWidth = width;
3716 imageDef->nFrameHeight = height;
3717
3718 def.nBufferSize = compressedSize;
3719 def.nBufferCountActual = def.nBufferCountMin;
3720
3721 err = mOMX->setParameter(
3722 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3723 CHECK_EQ(err, (status_t)OK);
3724 }
3725
addCodecSpecificData(const void * data,size_t size)3726 void OMXCodec::addCodecSpecificData(const void *data, size_t size) {
3727 CodecSpecificData *specific =
3728 (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1);
3729
3730 specific->mSize = size;
3731 memcpy(specific->mData, data, size);
3732
3733 mCodecSpecificData.push(specific);
3734 }
3735
clearCodecSpecificData()3736 void OMXCodec::clearCodecSpecificData() {
3737 for (size_t i = 0; i < mCodecSpecificData.size(); ++i) {
3738 free(mCodecSpecificData.editItemAt(i));
3739 }
3740 mCodecSpecificData.clear();
3741 mCodecSpecificDataIndex = 0;
3742 }
3743
start(MetaData * meta)3744 status_t OMXCodec::start(MetaData *meta) {
3745 Mutex::Autolock autoLock(mLock);
3746
3747 if (mState != LOADED) {
3748 CODEC_LOGE("called start in the unexpected state: %d", mState);
3749 return UNKNOWN_ERROR;
3750 }
3751
3752 sp<MetaData> params = new MetaData;
3753 if (mQuirks & kWantsNALFragments) {
3754 params->setInt32(kKeyWantsNALFragments, true);
3755 }
3756 if (meta) {
3757 int64_t startTimeUs = 0;
3758 int64_t timeUs;
3759 if (meta->findInt64(kKeyTime, &timeUs)) {
3760 startTimeUs = timeUs;
3761 }
3762 params->setInt64(kKeyTime, startTimeUs);
3763 }
3764
3765 mCodecSpecificDataIndex = 0;
3766 mInitialBufferSubmit = true;
3767 mSignalledEOS = false;
3768 mNoMoreOutputData = false;
3769 mOutputPortSettingsHaveChanged = false;
3770 mSeekTimeUs = -1;
3771 mSeekMode = ReadOptions::SEEK_CLOSEST_SYNC;
3772 mTargetTimeUs = -1;
3773 mFilledBuffers.clear();
3774 mPaused = false;
3775
3776 status_t err;
3777 if (mIsEncoder) {
3778 // Calling init() before starting its source so that we can configure,
3779 // if supported, the source to use exactly the same number of input
3780 // buffers as requested by the encoder.
3781 if ((err = init()) != OK) {
3782 CODEC_LOGE("init failed: %d", err);
3783 return err;
3784 }
3785
3786 params->setInt32(kKeyNumBuffers, mPortBuffers[kPortIndexInput].size());
3787 err = mSource->start(params.get());
3788 if (err != OK) {
3789 CODEC_LOGE("source failed to start: %d", err);
3790 stopOmxComponent_l();
3791 }
3792 return err;
3793 }
3794
3795 // Decoder case
3796 if ((err = mSource->start(params.get())) != OK) {
3797 CODEC_LOGE("source failed to start: %d", err);
3798 return err;
3799 }
3800 return init();
3801 }
3802
stop()3803 status_t OMXCodec::stop() {
3804 CODEC_LOGV("stop mState=%d", mState);
3805 Mutex::Autolock autoLock(mLock);
3806 status_t err = stopOmxComponent_l();
3807 mSource->stop();
3808
3809 CODEC_LOGV("stopped in state %d", mState);
3810 return err;
3811 }
3812
stopOmxComponent_l()3813 status_t OMXCodec::stopOmxComponent_l() {
3814 CODEC_LOGV("stopOmxComponent_l mState=%d", mState);
3815
3816 while (isIntermediateState(mState)) {
3817 mAsyncCompletion.wait(mLock);
3818 }
3819
3820 bool isError = false;
3821 switch (mState) {
3822 case LOADED:
3823 break;
3824
3825 case ERROR:
3826 {
3827 if (mPortStatus[kPortIndexOutput] == ENABLING) {
3828 // Codec is in a wedged state (technical term)
3829 // We've seen an output port settings change from the codec,
3830 // We've disabled the output port, then freed the output
3831 // buffers, initiated re-enabling the output port but
3832 // failed to reallocate the output buffers.
3833 // There doesn't seem to be a way to orderly transition
3834 // from executing->idle and idle->loaded now that the
3835 // output port hasn't been reenabled yet...
3836 // Simply free as many resources as we can and pretend
3837 // that we're in LOADED state so that the destructor
3838 // will free the component instance without asserting.
3839 freeBuffersOnPort(kPortIndexInput, true /* onlyThoseWeOwn */);
3840 freeBuffersOnPort(kPortIndexOutput, true /* onlyThoseWeOwn */);
3841 setState(LOADED);
3842 break;
3843 } else {
3844 OMX_STATETYPE state = OMX_StateInvalid;
3845 status_t err = mOMX->getState(mNode, &state);
3846 CHECK_EQ(err, (status_t)OK);
3847
3848 if (state != OMX_StateExecuting) {
3849 break;
3850 }
3851 // else fall through to the idling code
3852 }
3853
3854 isError = true;
3855 }
3856
3857 case EXECUTING:
3858 {
3859 setState(EXECUTING_TO_IDLE);
3860
3861 if (mQuirks & kRequiresFlushBeforeShutdown) {
3862 CODEC_LOGV("This component requires a flush before transitioning "
3863 "from EXECUTING to IDLE...");
3864
3865 bool emulateInputFlushCompletion =
3866 !flushPortAsync(kPortIndexInput);
3867
3868 bool emulateOutputFlushCompletion =
3869 !flushPortAsync(kPortIndexOutput);
3870
3871 if (emulateInputFlushCompletion) {
3872 onCmdComplete(OMX_CommandFlush, kPortIndexInput);
3873 }
3874
3875 if (emulateOutputFlushCompletion) {
3876 onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
3877 }
3878 } else {
3879 mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
3880 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
3881
3882 status_t err =
3883 mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
3884 CHECK_EQ(err, (status_t)OK);
3885 }
3886
3887 while (mState != LOADED && mState != ERROR) {
3888 mAsyncCompletion.wait(mLock);
3889 }
3890
3891 if (isError) {
3892 // We were in the ERROR state coming in, so restore that now
3893 // that we've idled the OMX component.
3894 setState(ERROR);
3895 }
3896
3897 break;
3898 }
3899
3900 default:
3901 {
3902 CHECK(!"should not be here.");
3903 break;
3904 }
3905 }
3906
3907 if (mLeftOverBuffer) {
3908 mLeftOverBuffer->release();
3909 mLeftOverBuffer = NULL;
3910 }
3911
3912 return OK;
3913 }
3914
getFormat()3915 sp<MetaData> OMXCodec::getFormat() {
3916 Mutex::Autolock autoLock(mLock);
3917
3918 return mOutputFormat;
3919 }
3920
read(MediaBuffer ** buffer,const ReadOptions * options)3921 status_t OMXCodec::read(
3922 MediaBuffer **buffer, const ReadOptions *options) {
3923 status_t err = OK;
3924 *buffer = NULL;
3925
3926 Mutex::Autolock autoLock(mLock);
3927
3928 if (mState != EXECUTING && mState != RECONFIGURING) {
3929 return UNKNOWN_ERROR;
3930 }
3931
3932 bool seeking = false;
3933 int64_t seekTimeUs;
3934 ReadOptions::SeekMode seekMode;
3935 if (options && options->getSeekTo(&seekTimeUs, &seekMode)) {
3936 seeking = true;
3937 }
3938
3939 if (mInitialBufferSubmit) {
3940 mInitialBufferSubmit = false;
3941
3942 if (seeking) {
3943 CHECK(seekTimeUs >= 0);
3944 mSeekTimeUs = seekTimeUs;
3945 mSeekMode = seekMode;
3946
3947 // There's no reason to trigger the code below, there's
3948 // nothing to flush yet.
3949 seeking = false;
3950 mPaused = false;
3951 }
3952
3953 drainInputBuffers();
3954
3955 if (mState == EXECUTING) {
3956 // Otherwise mState == RECONFIGURING and this code will trigger
3957 // after the output port is reenabled.
3958 fillOutputBuffers();
3959 }
3960 }
3961
3962 if (seeking) {
3963 while (mState == RECONFIGURING) {
3964 if ((err = waitForBufferFilled_l()) != OK) {
3965 return err;
3966 }
3967 }
3968
3969 if (mState != EXECUTING) {
3970 return UNKNOWN_ERROR;
3971 }
3972
3973 CODEC_LOGV("seeking to %" PRId64 " us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6);
3974
3975 mSignalledEOS = false;
3976
3977 CHECK(seekTimeUs >= 0);
3978 mSeekTimeUs = seekTimeUs;
3979 mSeekMode = seekMode;
3980
3981 mFilledBuffers.clear();
3982
3983 CHECK_EQ((int)mState, (int)EXECUTING);
3984
3985 bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput);
3986 bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput);
3987
3988 if (emulateInputFlushCompletion) {
3989 onCmdComplete(OMX_CommandFlush, kPortIndexInput);
3990 }
3991
3992 if (emulateOutputFlushCompletion) {
3993 onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
3994 }
3995
3996 while (mSeekTimeUs >= 0) {
3997 if ((err = waitForBufferFilled_l()) != OK) {
3998 return err;
3999 }
4000 }
4001 }
4002
4003 while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) {
4004 if ((err = waitForBufferFilled_l()) != OK) {
4005 return err;
4006 }
4007 }
4008
4009 if (mState == ERROR) {
4010 return UNKNOWN_ERROR;
4011 }
4012
4013 if (mFilledBuffers.empty()) {
4014 return mSignalledEOS ? mFinalStatus : ERROR_END_OF_STREAM;
4015 }
4016
4017 if (mOutputPortSettingsHaveChanged) {
4018 mOutputPortSettingsHaveChanged = false;
4019
4020 return INFO_FORMAT_CHANGED;
4021 }
4022
4023 size_t index = *mFilledBuffers.begin();
4024 mFilledBuffers.erase(mFilledBuffers.begin());
4025
4026 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
4027 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
4028 info->mStatus = OWNED_BY_CLIENT;
4029
4030 info->mMediaBuffer->add_ref();
4031 if (mSkipCutBuffer != NULL) {
4032 mSkipCutBuffer->submit(info->mMediaBuffer);
4033 }
4034 *buffer = info->mMediaBuffer;
4035
4036 return OK;
4037 }
4038
signalBufferReturned(MediaBuffer * buffer)4039 void OMXCodec::signalBufferReturned(MediaBuffer *buffer) {
4040 Mutex::Autolock autoLock(mLock);
4041
4042 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
4043 for (size_t i = 0; i < buffers->size(); ++i) {
4044 BufferInfo *info = &buffers->editItemAt(i);
4045
4046 if (info->mMediaBuffer == buffer) {
4047 CHECK_EQ((int)mPortStatus[kPortIndexOutput], (int)ENABLED);
4048 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_CLIENT);
4049
4050 info->mStatus = OWNED_BY_US;
4051
4052 if (buffer->graphicBuffer() == 0) {
4053 fillOutputBuffer(info);
4054 } else {
4055 sp<MetaData> metaData = info->mMediaBuffer->meta_data();
4056 int32_t rendered = 0;
4057 if (!metaData->findInt32(kKeyRendered, &rendered)) {
4058 rendered = 0;
4059 }
4060 if (!rendered) {
4061 status_t err = cancelBufferToNativeWindow(info);
4062 if (err < 0) {
4063 return;
4064 }
4065 }
4066
4067 info->mStatus = OWNED_BY_NATIVE_WINDOW;
4068
4069 // Dequeue the next buffer from the native window.
4070 BufferInfo *nextBufInfo = dequeueBufferFromNativeWindow();
4071 if (nextBufInfo == 0) {
4072 return;
4073 }
4074
4075 // Give the buffer to the OMX node to fill.
4076 fillOutputBuffer(nextBufInfo);
4077 }
4078 return;
4079 }
4080 }
4081
4082 CHECK(!"should not be here.");
4083 }
4084
dumpPortStatus(OMX_U32 portIndex)4085 void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
4086 OMX_PARAM_PORTDEFINITIONTYPE def;
4087 InitOMXParams(&def);
4088 def.nPortIndex = portIndex;
4089
4090 status_t err = mOMX->getParameter(
4091 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
4092 CHECK_EQ(err, (status_t)OK);
4093
4094 printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output");
4095
4096 CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput)
4097 || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput));
4098
4099 printf(" nBufferCountActual = %" PRIu32 "\n", def.nBufferCountActual);
4100 printf(" nBufferCountMin = %" PRIu32 "\n", def.nBufferCountMin);
4101 printf(" nBufferSize = %" PRIu32 "\n", def.nBufferSize);
4102
4103 switch (def.eDomain) {
4104 case OMX_PortDomainImage:
4105 {
4106 const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
4107
4108 printf("\n");
4109 printf(" // Image\n");
4110 printf(" nFrameWidth = %" PRIu32 "\n", imageDef->nFrameWidth);
4111 printf(" nFrameHeight = %" PRIu32 "\n", imageDef->nFrameHeight);
4112 printf(" nStride = %" PRIu32 "\n", imageDef->nStride);
4113
4114 printf(" eCompressionFormat = %s\n",
4115 asString(imageDef->eCompressionFormat));
4116
4117 printf(" eColorFormat = %s\n",
4118 asString(imageDef->eColorFormat));
4119
4120 break;
4121 }
4122
4123 case OMX_PortDomainVideo:
4124 {
4125 OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
4126
4127 printf("\n");
4128 printf(" // Video\n");
4129 printf(" nFrameWidth = %" PRIu32 "\n", videoDef->nFrameWidth);
4130 printf(" nFrameHeight = %" PRIu32 "\n", videoDef->nFrameHeight);
4131 printf(" nStride = %" PRIu32 "\n", videoDef->nStride);
4132
4133 printf(" eCompressionFormat = %s\n",
4134 asString(videoDef->eCompressionFormat));
4135
4136 printf(" eColorFormat = %s\n",
4137 asString(videoDef->eColorFormat));
4138
4139 break;
4140 }
4141
4142 case OMX_PortDomainAudio:
4143 {
4144 OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
4145
4146 printf("\n");
4147 printf(" // Audio\n");
4148 printf(" eEncoding = %s\n",
4149 asString(audioDef->eEncoding));
4150
4151 if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) {
4152 OMX_AUDIO_PARAM_PCMMODETYPE params;
4153 InitOMXParams(¶ms);
4154 params.nPortIndex = portIndex;
4155
4156 err = mOMX->getParameter(
4157 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params));
4158 CHECK_EQ(err, (status_t)OK);
4159
4160 printf(" nSamplingRate = %" PRIu32 "\n", params.nSamplingRate);
4161 printf(" nChannels = %" PRIu32 "\n", params.nChannels);
4162 printf(" bInterleaved = %d\n", params.bInterleaved);
4163 printf(" nBitPerSample = %" PRIu32 "\n", params.nBitPerSample);
4164
4165 printf(" eNumData = %s\n",
4166 params.eNumData == OMX_NumericalDataSigned
4167 ? "signed" : "unsigned");
4168
4169 printf(" ePCMMode = %s\n", asString(params.ePCMMode));
4170 } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) {
4171 OMX_AUDIO_PARAM_AMRTYPE amr;
4172 InitOMXParams(&amr);
4173 amr.nPortIndex = portIndex;
4174
4175 err = mOMX->getParameter(
4176 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
4177 CHECK_EQ(err, (status_t)OK);
4178
4179 printf(" nChannels = %" PRIu32 "\n", amr.nChannels);
4180 printf(" eAMRBandMode = %s\n",
4181 asString(amr.eAMRBandMode));
4182 printf(" eAMRFrameFormat = %s\n",
4183 asString(amr.eAMRFrameFormat));
4184 }
4185
4186 break;
4187 }
4188
4189 default:
4190 {
4191 printf(" // Unknown\n");
4192 break;
4193 }
4194 }
4195
4196 printf("}\n");
4197 }
4198
initNativeWindow()4199 status_t OMXCodec::initNativeWindow() {
4200 // Enable use of a GraphicBuffer as the output for this node. This must
4201 // happen before getting the IndexParamPortDefinition parameter because it
4202 // will affect the pixel format that the node reports.
4203 status_t err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
4204 if (err != 0) {
4205 return err;
4206 }
4207
4208 return OK;
4209 }
4210
initNativeWindowCrop()4211 void OMXCodec::initNativeWindowCrop() {
4212 int32_t left, top, right, bottom;
4213
4214 CHECK(mOutputFormat->findRect(
4215 kKeyCropRect,
4216 &left, &top, &right, &bottom));
4217
4218 android_native_rect_t crop;
4219 crop.left = left;
4220 crop.top = top;
4221 crop.right = right + 1;
4222 crop.bottom = bottom + 1;
4223
4224 // We'll ignore any errors here, if the surface is
4225 // already invalid, we'll know soon enough.
4226 native_window_set_crop(mNativeWindow.get(), &crop);
4227 }
4228
initOutputFormat(const sp<MetaData> & inputFormat)4229 void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
4230 mOutputFormat = new MetaData;
4231 mOutputFormat->setCString(kKeyDecoderComponent, mComponentName);
4232 if (mIsEncoder) {
4233 int32_t timeScale;
4234 if (inputFormat->findInt32(kKeyTimeScale, &timeScale)) {
4235 mOutputFormat->setInt32(kKeyTimeScale, timeScale);
4236 }
4237 }
4238
4239 OMX_PARAM_PORTDEFINITIONTYPE def;
4240 InitOMXParams(&def);
4241 def.nPortIndex = kPortIndexOutput;
4242
4243 status_t err = mOMX->getParameter(
4244 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
4245 CHECK_EQ(err, (status_t)OK);
4246
4247 switch (def.eDomain) {
4248 case OMX_PortDomainImage:
4249 {
4250 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
4251 CHECK_EQ((int)imageDef->eCompressionFormat,
4252 (int)OMX_IMAGE_CodingUnused);
4253
4254 mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
4255 mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat);
4256 mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth);
4257 mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight);
4258 break;
4259 }
4260
4261 case OMX_PortDomainAudio:
4262 {
4263 OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio;
4264
4265 if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) {
4266 OMX_AUDIO_PARAM_PCMMODETYPE params;
4267 InitOMXParams(¶ms);
4268 params.nPortIndex = kPortIndexOutput;
4269
4270 err = mOMX->getParameter(
4271 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params));
4272 CHECK_EQ(err, (status_t)OK);
4273
4274 CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned);
4275 CHECK_EQ(params.nBitPerSample, 16u);
4276 CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear);
4277
4278 int32_t numChannels, sampleRate;
4279 inputFormat->findInt32(kKeyChannelCount, &numChannels);
4280 inputFormat->findInt32(kKeySampleRate, &sampleRate);
4281
4282 if ((OMX_U32)numChannels != params.nChannels) {
4283 ALOGV("Codec outputs a different number of channels than "
4284 "the input stream contains (contains %d channels, "
4285 "codec outputs %ld channels).",
4286 numChannels, params.nChannels);
4287 }
4288
4289 if (sampleRate != (int32_t)params.nSamplingRate) {
4290 ALOGV("Codec outputs at different sampling rate than "
4291 "what the input stream contains (contains data at "
4292 "%d Hz, codec outputs %lu Hz)",
4293 sampleRate, params.nSamplingRate);
4294 }
4295
4296 mOutputFormat->setCString(
4297 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
4298
4299 // Use the codec-advertised number of channels, as some
4300 // codecs appear to output stereo even if the input data is
4301 // mono. If we know the codec lies about this information,
4302 // use the actual number of channels instead.
4303 mOutputFormat->setInt32(
4304 kKeyChannelCount,
4305 (mQuirks & kDecoderLiesAboutNumberOfChannels)
4306 ? numChannels : params.nChannels);
4307
4308 mOutputFormat->setInt32(kKeySampleRate, params.nSamplingRate);
4309 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) {
4310 OMX_AUDIO_PARAM_AMRTYPE amr;
4311 InitOMXParams(&amr);
4312 amr.nPortIndex = kPortIndexOutput;
4313
4314 err = mOMX->getParameter(
4315 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
4316 CHECK_EQ(err, (status_t)OK);
4317
4318 CHECK_EQ(amr.nChannels, 1u);
4319 mOutputFormat->setInt32(kKeyChannelCount, 1);
4320
4321 if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0
4322 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) {
4323 mOutputFormat->setCString(
4324 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB);
4325 mOutputFormat->setInt32(kKeySampleRate, 8000);
4326 } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0
4327 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) {
4328 mOutputFormat->setCString(
4329 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB);
4330 mOutputFormat->setInt32(kKeySampleRate, 16000);
4331 } else {
4332 CHECK(!"Unknown AMR band mode.");
4333 }
4334 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) {
4335 mOutputFormat->setCString(
4336 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
4337 int32_t numChannels, sampleRate, bitRate;
4338 inputFormat->findInt32(kKeyChannelCount, &numChannels);
4339 inputFormat->findInt32(kKeySampleRate, &sampleRate);
4340 inputFormat->findInt32(kKeyBitRate, &bitRate);
4341 mOutputFormat->setInt32(kKeyChannelCount, numChannels);
4342 mOutputFormat->setInt32(kKeySampleRate, sampleRate);
4343 mOutputFormat->setInt32(kKeyBitRate, bitRate);
4344 } else if (audio_def->eEncoding ==
4345 (OMX_AUDIO_CODINGTYPE)OMX_AUDIO_CodingAndroidAC3) {
4346 mOutputFormat->setCString(
4347 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC3);
4348 int32_t numChannels, sampleRate, bitRate;
4349 inputFormat->findInt32(kKeyChannelCount, &numChannels);
4350 inputFormat->findInt32(kKeySampleRate, &sampleRate);
4351 inputFormat->findInt32(kKeyBitRate, &bitRate);
4352 mOutputFormat->setInt32(kKeyChannelCount, numChannels);
4353 mOutputFormat->setInt32(kKeySampleRate, sampleRate);
4354 mOutputFormat->setInt32(kKeyBitRate, bitRate);
4355 } else {
4356 CHECK(!"Should not be here. Unknown audio encoding.");
4357 }
4358 break;
4359 }
4360
4361 case OMX_PortDomainVideo:
4362 {
4363 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
4364
4365 if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) {
4366 mOutputFormat->setCString(
4367 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
4368 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) {
4369 mOutputFormat->setCString(
4370 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
4371 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) {
4372 mOutputFormat->setCString(
4373 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
4374 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) {
4375 mOutputFormat->setCString(
4376 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
4377 } else {
4378 CHECK(!"Unknown compression format.");
4379 }
4380
4381 mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth);
4382 mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight);
4383 mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat);
4384
4385 if (!mIsEncoder) {
4386 OMX_CONFIG_RECTTYPE rect;
4387 InitOMXParams(&rect);
4388 rect.nPortIndex = kPortIndexOutput;
4389 status_t err =
4390 mOMX->getConfig(
4391 mNode, OMX_IndexConfigCommonOutputCrop,
4392 &rect, sizeof(rect));
4393
4394 CODEC_LOGI(
4395 "video dimensions are %ld x %ld",
4396 video_def->nFrameWidth, video_def->nFrameHeight);
4397
4398 if (err == OK) {
4399 CHECK_GE(rect.nLeft, 0);
4400 CHECK_GE(rect.nTop, 0);
4401 CHECK_GE(rect.nWidth, 0u);
4402 CHECK_GE(rect.nHeight, 0u);
4403 CHECK_LE(rect.nLeft + rect.nWidth - 1, video_def->nFrameWidth);
4404 CHECK_LE(rect.nTop + rect.nHeight - 1, video_def->nFrameHeight);
4405
4406 mOutputFormat->setRect(
4407 kKeyCropRect,
4408 rect.nLeft,
4409 rect.nTop,
4410 rect.nLeft + rect.nWidth - 1,
4411 rect.nTop + rect.nHeight - 1);
4412
4413 CODEC_LOGI(
4414 "Crop rect is %ld x %ld @ (%ld, %ld)",
4415 rect.nWidth, rect.nHeight, rect.nLeft, rect.nTop);
4416 } else {
4417 mOutputFormat->setRect(
4418 kKeyCropRect,
4419 0, 0,
4420 video_def->nFrameWidth - 1,
4421 video_def->nFrameHeight - 1);
4422 }
4423
4424 if (mNativeWindow != NULL) {
4425 initNativeWindowCrop();
4426 }
4427 }
4428 break;
4429 }
4430
4431 default:
4432 {
4433 CHECK(!"should not be here, neither audio nor video.");
4434 break;
4435 }
4436 }
4437
4438 // If the input format contains rotation information, flag the output
4439 // format accordingly.
4440
4441 int32_t rotationDegrees;
4442 if (mSource->getFormat()->findInt32(kKeyRotation, &rotationDegrees)) {
4443 mOutputFormat->setInt32(kKeyRotation, rotationDegrees);
4444 }
4445 }
4446
pause()4447 status_t OMXCodec::pause() {
4448 Mutex::Autolock autoLock(mLock);
4449
4450 mPaused = true;
4451
4452 return OK;
4453 }
4454
4455 ////////////////////////////////////////////////////////////////////////////////
4456
QueryCodecs(const sp<IOMX> & omx,const char * mime,bool queryDecoders,bool hwCodecOnly,Vector<CodecCapabilities> * results)4457 status_t QueryCodecs(
4458 const sp<IOMX> &omx,
4459 const char *mime, bool queryDecoders, bool hwCodecOnly,
4460 Vector<CodecCapabilities> *results) {
4461 Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
4462 results->clear();
4463
4464 OMXCodec::findMatchingCodecs(mime,
4465 !queryDecoders /*createEncoder*/,
4466 NULL /*matchComponentName*/,
4467 hwCodecOnly ? OMXCodec::kHardwareCodecsOnly : 0 /*flags*/,
4468 &matchingCodecs);
4469
4470 for (size_t c = 0; c < matchingCodecs.size(); c++) {
4471 const char *componentName = matchingCodecs.itemAt(c).mName.string();
4472
4473 results->push();
4474 CodecCapabilities *caps = &results->editItemAt(results->size() - 1);
4475
4476 status_t err =
4477 QueryCodec(omx, componentName, mime, !queryDecoders, caps);
4478
4479 if (err != OK) {
4480 results->removeAt(results->size() - 1);
4481 }
4482 }
4483
4484 return OK;
4485 }
4486
QueryCodec(const sp<IOMX> & omx,const char * componentName,const char * mime,bool isEncoder,CodecCapabilities * caps)4487 status_t QueryCodec(
4488 const sp<IOMX> &omx,
4489 const char *componentName, const char *mime,
4490 bool isEncoder,
4491 CodecCapabilities *caps) {
4492 bool isVideo = !strncasecmp(mime, "video/", 6);
4493
4494 sp<OMXCodecObserver> observer = new OMXCodecObserver;
4495 IOMX::node_id node;
4496 status_t err = omx->allocateNode(componentName, observer, &node);
4497
4498 if (err != OK) {
4499 return err;
4500 }
4501
4502 OMXCodec::setComponentRole(omx, node, isEncoder, mime);
4503
4504 caps->mFlags = 0;
4505 caps->mComponentName = componentName;
4506
4507 // NOTE: OMX does not provide a way to query AAC profile support
4508 if (isVideo) {
4509 OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
4510 InitOMXParams(¶m);
4511
4512 param.nPortIndex = !isEncoder ? 0 : 1;
4513
4514 for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
4515 err = omx->getParameter(
4516 node, OMX_IndexParamVideoProfileLevelQuerySupported,
4517 ¶m, sizeof(param));
4518
4519 if (err != OK) {
4520 break;
4521 }
4522
4523 CodecProfileLevel profileLevel;
4524 profileLevel.mProfile = param.eProfile;
4525 profileLevel.mLevel = param.eLevel;
4526
4527 caps->mProfileLevels.push(profileLevel);
4528 }
4529
4530 // Color format query
4531 // return colors in the order reported by the OMX component
4532 // prefix "flexible" standard ones with the flexible equivalent
4533 OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
4534 InitOMXParams(&portFormat);
4535 portFormat.nPortIndex = !isEncoder ? 1 : 0;
4536 for (portFormat.nIndex = 0;; ++portFormat.nIndex) {
4537 err = omx->getParameter(
4538 node, OMX_IndexParamVideoPortFormat,
4539 &portFormat, sizeof(portFormat));
4540 if (err != OK) {
4541 break;
4542 }
4543
4544 OMX_U32 flexibleEquivalent;
4545 if (ACodec::isFlexibleColorFormat(
4546 omx, node, portFormat.eColorFormat, false /* usingNativeWindow */,
4547 &flexibleEquivalent)) {
4548 bool marked = false;
4549 for (size_t i = 0; i < caps->mColorFormats.size(); i++) {
4550 if (caps->mColorFormats.itemAt(i) == flexibleEquivalent) {
4551 marked = true;
4552 break;
4553 }
4554 }
4555 if (!marked) {
4556 caps->mColorFormats.push(flexibleEquivalent);
4557 }
4558 }
4559 caps->mColorFormats.push(portFormat.eColorFormat);
4560 }
4561 }
4562
4563 if (isVideo && !isEncoder) {
4564 if (omx->storeMetaDataInBuffers(
4565 node, 1 /* port index */, OMX_TRUE) == OK ||
4566 omx->prepareForAdaptivePlayback(
4567 node, 1 /* port index */, OMX_TRUE,
4568 1280 /* width */, 720 /* height */) == OK) {
4569 caps->mFlags |= CodecCapabilities::kFlagSupportsAdaptivePlayback;
4570 }
4571 }
4572
4573 CHECK_EQ(omx->freeNode(node), (status_t)OK);
4574
4575 return OK;
4576 }
4577
QueryCodecs(const sp<IOMX> & omx,const char * mimeType,bool queryDecoders,Vector<CodecCapabilities> * results)4578 status_t QueryCodecs(
4579 const sp<IOMX> &omx,
4580 const char *mimeType, bool queryDecoders,
4581 Vector<CodecCapabilities> *results) {
4582 return QueryCodecs(omx, mimeType, queryDecoders, false /*hwCodecOnly*/, results);
4583 }
4584
4585 // These are supposed be equivalent to the logic in
4586 // "audio_channel_out_mask_from_count".
getOMXChannelMapping(size_t numChannels,OMX_AUDIO_CHANNELTYPE map[])4587 status_t getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) {
4588 switch (numChannels) {
4589 case 1:
4590 map[0] = OMX_AUDIO_ChannelCF;
4591 break;
4592 case 2:
4593 map[0] = OMX_AUDIO_ChannelLF;
4594 map[1] = OMX_AUDIO_ChannelRF;
4595 break;
4596 case 3:
4597 map[0] = OMX_AUDIO_ChannelLF;
4598 map[1] = OMX_AUDIO_ChannelRF;
4599 map[2] = OMX_AUDIO_ChannelCF;
4600 break;
4601 case 4:
4602 map[0] = OMX_AUDIO_ChannelLF;
4603 map[1] = OMX_AUDIO_ChannelRF;
4604 map[2] = OMX_AUDIO_ChannelLR;
4605 map[3] = OMX_AUDIO_ChannelRR;
4606 break;
4607 case 5:
4608 map[0] = OMX_AUDIO_ChannelLF;
4609 map[1] = OMX_AUDIO_ChannelRF;
4610 map[2] = OMX_AUDIO_ChannelCF;
4611 map[3] = OMX_AUDIO_ChannelLR;
4612 map[4] = OMX_AUDIO_ChannelRR;
4613 break;
4614 case 6:
4615 map[0] = OMX_AUDIO_ChannelLF;
4616 map[1] = OMX_AUDIO_ChannelRF;
4617 map[2] = OMX_AUDIO_ChannelCF;
4618 map[3] = OMX_AUDIO_ChannelLFE;
4619 map[4] = OMX_AUDIO_ChannelLR;
4620 map[5] = OMX_AUDIO_ChannelRR;
4621 break;
4622 case 7:
4623 map[0] = OMX_AUDIO_ChannelLF;
4624 map[1] = OMX_AUDIO_ChannelRF;
4625 map[2] = OMX_AUDIO_ChannelCF;
4626 map[3] = OMX_AUDIO_ChannelLFE;
4627 map[4] = OMX_AUDIO_ChannelLR;
4628 map[5] = OMX_AUDIO_ChannelRR;
4629 map[6] = OMX_AUDIO_ChannelCS;
4630 break;
4631 case 8:
4632 map[0] = OMX_AUDIO_ChannelLF;
4633 map[1] = OMX_AUDIO_ChannelRF;
4634 map[2] = OMX_AUDIO_ChannelCF;
4635 map[3] = OMX_AUDIO_ChannelLFE;
4636 map[4] = OMX_AUDIO_ChannelLR;
4637 map[5] = OMX_AUDIO_ChannelRR;
4638 map[6] = OMX_AUDIO_ChannelLS;
4639 map[7] = OMX_AUDIO_ChannelRS;
4640 break;
4641 default:
4642 return -EINVAL;
4643 }
4644
4645 return OK;
4646 }
4647
4648 } // namespace android
4649