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