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