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