OMXCodec.cpp revision f5ee327780ea2b538b8affafa8063f0ce0390fe0
1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "OMXCodec"
19#include <utils/Log.h>
20
21#include "include/AACEncoder.h"
22
23#include "include/ESDS.h"
24
25#include <binder/IServiceManager.h>
26#include <binder/MemoryDealer.h>
27#include <binder/ProcessState.h>
28#include <HardwareAPI.h>
29#include <media/stagefright/foundation/ADebug.h>
30#include <media/IMediaPlayerService.h>
31#include <media/stagefright/MediaBuffer.h>
32#include <media/stagefright/MediaBufferGroup.h>
33#include <media/stagefright/MediaDefs.h>
34#include <media/stagefright/MediaCodecList.h>
35#include <media/stagefright/MediaExtractor.h>
36#include <media/stagefright/MetaData.h>
37#include <media/stagefright/OMXCodec.h>
38#include <media/stagefright/Utils.h>
39#include <media/stagefright/SkipCutBuffer.h>
40#include <utils/Vector.h>
41
42#include <OMX_Audio.h>
43#include <OMX_Component.h>
44
45#include "include/avc_utils.h"
46
47namespace android {
48
49// Treat time out as an error if we have not received any output
50// buffers after 3 seconds.
51const static int64_t kBufferFilledEventTimeOutNs = 3000000000LL;
52
53// OMX Spec defines less than 50 color formats. If the query for
54// color format is executed for more than kMaxColorFormatSupported,
55// the query will fail to avoid looping forever.
56// 1000 is more than enough for us to tell whether the omx
57// component in question is buggy or not.
58const static uint32_t kMaxColorFormatSupported = 1000;
59
60#define FACTORY_CREATE_ENCODER(name) \
61static sp<MediaSource> Make##name(const sp<MediaSource> &source, const sp<MetaData> &meta) { \
62    return new name(source, meta); \
63}
64
65#define FACTORY_REF(name) { #name, Make##name },
66
67FACTORY_CREATE_ENCODER(AACEncoder)
68
69static sp<MediaSource> InstantiateSoftwareEncoder(
70        const char *name, const sp<MediaSource> &source,
71        const sp<MetaData> &meta) {
72    struct FactoryInfo {
73        const char *name;
74        sp<MediaSource> (*CreateFunc)(const sp<MediaSource> &, const sp<MetaData> &);
75    };
76
77    static const FactoryInfo kFactoryInfo[] = {
78        FACTORY_REF(AACEncoder)
79    };
80    for (size_t i = 0;
81         i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) {
82        if (!strcmp(name, kFactoryInfo[i].name)) {
83            return (*kFactoryInfo[i].CreateFunc)(source, meta);
84        }
85    }
86
87    return NULL;
88}
89
90#undef FACTORY_CREATE_ENCODER
91#undef FACTORY_REF
92
93#define CODEC_LOGI(x, ...) ALOGI("[%s] "x, mComponentName, ##__VA_ARGS__)
94#define CODEC_LOGV(x, ...) ALOGV("[%s] "x, mComponentName, ##__VA_ARGS__)
95#define CODEC_LOGW(x, ...) ALOGW("[%s] "x, mComponentName, ##__VA_ARGS__)
96#define CODEC_LOGE(x, ...) ALOGE("[%s] "x, mComponentName, ##__VA_ARGS__)
97
98struct OMXCodecObserver : public BnOMXObserver {
99    OMXCodecObserver() {
100    }
101
102    void setCodec(const sp<OMXCodec> &target) {
103        mTarget = target;
104    }
105
106    // from IOMXObserver
107    virtual void onMessage(const omx_message &msg) {
108        sp<OMXCodec> codec = mTarget.promote();
109
110        if (codec.get() != NULL) {
111            Mutex::Autolock autoLock(codec->mLock);
112            codec->on_message(msg);
113            codec.clear();
114        }
115    }
116
117protected:
118    virtual ~OMXCodecObserver() {}
119
120private:
121    wp<OMXCodec> mTarget;
122
123    OMXCodecObserver(const OMXCodecObserver &);
124    OMXCodecObserver &operator=(const OMXCodecObserver &);
125};
126
127template<class T>
128static void InitOMXParams(T *params) {
129    params->nSize = sizeof(T);
130    params->nVersion.s.nVersionMajor = 1;
131    params->nVersion.s.nVersionMinor = 0;
132    params->nVersion.s.nRevision = 0;
133    params->nVersion.s.nStep = 0;
134}
135
136static bool IsSoftwareCodec(const char *componentName) {
137    if (!strncmp("OMX.google.", componentName, 11)) {
138        return true;
139    }
140
141    if (!strncmp("OMX.", componentName, 4)) {
142        return false;
143    }
144
145    return true;
146}
147
148// A sort order in which OMX software codecs are first, followed
149// by other (non-OMX) software codecs, followed by everything else.
150static int CompareSoftwareCodecsFirst(
151        const OMXCodec::CodecNameAndQuirks *elem1,
152        const OMXCodec::CodecNameAndQuirks *elem2) {
153    bool isOMX1 = !strncmp(elem1->mName.string(), "OMX.", 4);
154    bool isOMX2 = !strncmp(elem2->mName.string(), "OMX.", 4);
155
156    bool isSoftwareCodec1 = IsSoftwareCodec(elem1->mName.string());
157    bool isSoftwareCodec2 = IsSoftwareCodec(elem2->mName.string());
158
159    if (isSoftwareCodec1) {
160        if (!isSoftwareCodec2) { return -1; }
161
162        if (isOMX1) {
163            if (isOMX2) { return 0; }
164
165            return -1;
166        } else {
167            if (isOMX2) { return 0; }
168
169            return 1;
170        }
171
172        return -1;
173    }
174
175    if (isSoftwareCodec2) {
176        return 1;
177    }
178
179    return 0;
180}
181
182// static
183void OMXCodec::findMatchingCodecs(
184        const char *mime,
185        bool createEncoder, const char *matchComponentName,
186        uint32_t flags,
187        Vector<CodecNameAndQuirks> *matchingCodecs) {
188    matchingCodecs->clear();
189
190    const MediaCodecList *list = MediaCodecList::getInstance();
191    if (list == NULL) {
192        return;
193    }
194
195    size_t index = 0;
196    for (;;) {
197        ssize_t matchIndex =
198            list->findCodecByType(mime, createEncoder, index);
199
200        if (matchIndex < 0) {
201            break;
202        }
203
204        index = matchIndex + 1;
205
206        const char *componentName = list->getCodecName(matchIndex);
207
208        // If a specific codec is requested, skip the non-matching ones.
209        if (matchComponentName && strcmp(componentName, matchComponentName)) {
210            continue;
211        }
212
213        // When requesting software-only codecs, only push software codecs
214        // When requesting hardware-only codecs, only push hardware codecs
215        // When there is request neither for software-only nor for
216        // hardware-only codecs, push all codecs
217        if (((flags & kSoftwareCodecsOnly) &&   IsSoftwareCodec(componentName)) ||
218            ((flags & kHardwareCodecsOnly) &&  !IsSoftwareCodec(componentName)) ||
219            (!(flags & (kSoftwareCodecsOnly | kHardwareCodecsOnly)))) {
220
221            ssize_t index = matchingCodecs->add();
222            CodecNameAndQuirks *entry = &matchingCodecs->editItemAt(index);
223            entry->mName = String8(componentName);
224            entry->mQuirks = getComponentQuirks(list, matchIndex);
225
226            ALOGV("matching '%s' quirks 0x%08x",
227                  entry->mName.string(), entry->mQuirks);
228        }
229    }
230
231    if (flags & kPreferSoftwareCodecs) {
232        matchingCodecs->sort(CompareSoftwareCodecsFirst);
233    }
234}
235
236// static
237uint32_t OMXCodec::getComponentQuirks(
238        const MediaCodecList *list, size_t index) {
239    uint32_t quirks = 0;
240    if (list->codecHasQuirk(
241                index, "requires-allocate-on-input-ports")) {
242        quirks |= kRequiresAllocateBufferOnInputPorts;
243    }
244    if (list->codecHasQuirk(
245                index, "requires-allocate-on-output-ports")) {
246        quirks |= kRequiresAllocateBufferOnOutputPorts;
247    }
248    if (list->codecHasQuirk(
249                index, "output-buffers-are-unreadable")) {
250        quirks |= kOutputBuffersAreUnreadable;
251    }
252
253    return quirks;
254}
255
256// static
257bool OMXCodec::findCodecQuirks(const char *componentName, uint32_t *quirks) {
258    const MediaCodecList *list = MediaCodecList::getInstance();
259
260    if (list == NULL) {
261        return false;
262    }
263
264    ssize_t index = list->findCodecByName(componentName);
265
266    if (index < 0) {
267        return false;
268    }
269
270    *quirks = getComponentQuirks(list, index);
271
272    return true;
273}
274
275// static
276sp<MediaSource> OMXCodec::Create(
277        const sp<IOMX> &omx,
278        const sp<MetaData> &meta, bool createEncoder,
279        const sp<MediaSource> &source,
280        const char *matchComponentName,
281        uint32_t flags,
282        const sp<ANativeWindow> &nativeWindow) {
283    int32_t requiresSecureBuffers;
284    if (source->getFormat()->findInt32(
285                kKeyRequiresSecureBuffers,
286                &requiresSecureBuffers)
287            && requiresSecureBuffers) {
288        flags |= kIgnoreCodecSpecificData;
289        flags |= kUseSecureInputBuffers;
290    }
291
292    const char *mime;
293    bool success = meta->findCString(kKeyMIMEType, &mime);
294    CHECK(success);
295
296    Vector<CodecNameAndQuirks> matchingCodecs;
297    findMatchingCodecs(
298            mime, createEncoder, matchComponentName, flags, &matchingCodecs);
299
300    if (matchingCodecs.isEmpty()) {
301        ALOGV("No matching codecs! (mime: %s, createEncoder: %s, "
302                "matchComponentName: %s, flags: 0x%x)",
303                mime, createEncoder ? "true" : "false", matchComponentName, flags);
304        return NULL;
305    }
306
307    sp<OMXCodecObserver> observer = new OMXCodecObserver;
308    IOMX::node_id node = 0;
309
310    for (size_t i = 0; i < matchingCodecs.size(); ++i) {
311        const char *componentNameBase = matchingCodecs[i].mName.string();
312        uint32_t quirks = matchingCodecs[i].mQuirks;
313        const char *componentName = componentNameBase;
314
315        AString tmp;
316        if (flags & kUseSecureInputBuffers) {
317            tmp = componentNameBase;
318            tmp.append(".secure");
319
320            componentName = tmp.c_str();
321        }
322
323        if (createEncoder) {
324            sp<MediaSource> softwareCodec =
325                InstantiateSoftwareEncoder(componentName, source, meta);
326
327            if (softwareCodec != NULL) {
328                ALOGV("Successfully allocated software codec '%s'", componentName);
329
330                return softwareCodec;
331            }
332        }
333
334        ALOGV("Attempting to allocate OMX node '%s'", componentName);
335
336        if (!createEncoder
337                && (quirks & kOutputBuffersAreUnreadable)
338                && (flags & kClientNeedsFramebuffer)) {
339            if (strncmp(componentName, "OMX.SEC.", 8)) {
340                // For OMX.SEC.* decoders we can enable a special mode that
341                // gives the client access to the framebuffer contents.
342
343                ALOGW("Component '%s' does not give the client access to "
344                     "the framebuffer contents. Skipping.",
345                     componentName);
346
347                continue;
348            }
349        }
350
351        status_t err = omx->allocateNode(componentName, observer, &node);
352        if (err == OK) {
353            ALOGV("Successfully allocated OMX node '%s'", componentName);
354
355            sp<OMXCodec> codec = new OMXCodec(
356                    omx, node, quirks, flags,
357                    createEncoder, mime, componentName,
358                    source, nativeWindow);
359
360            observer->setCodec(codec);
361
362            err = codec->configureCodec(meta);
363            if (err == OK) {
364                return codec;
365            }
366
367            ALOGV("Failed to configure codec '%s'", componentName);
368        }
369    }
370
371    return NULL;
372}
373
374status_t OMXCodec::parseAVCCodecSpecificData(
375        const void *data, size_t size,
376        unsigned *profile, unsigned *level) {
377    const uint8_t *ptr = (const uint8_t *)data;
378
379    // verify minimum size and configurationVersion == 1.
380    if (size < 7 || ptr[0] != 1) {
381        return ERROR_MALFORMED;
382    }
383
384    *profile = ptr[1];
385    *level = ptr[3];
386
387    // There is decodable content out there that fails the following
388    // assertion, let's be lenient for now...
389    // CHECK((ptr[4] >> 2) == 0x3f);  // reserved
390
391    size_t lengthSize = 1 + (ptr[4] & 3);
392
393    // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
394    // violates it...
395    // CHECK((ptr[5] >> 5) == 7);  // reserved
396
397    size_t numSeqParameterSets = ptr[5] & 31;
398
399    ptr += 6;
400    size -= 6;
401
402    for (size_t i = 0; i < numSeqParameterSets; ++i) {
403        if (size < 2) {
404            return ERROR_MALFORMED;
405        }
406
407        size_t length = U16_AT(ptr);
408
409        ptr += 2;
410        size -= 2;
411
412        if (size < length) {
413            return ERROR_MALFORMED;
414        }
415
416        addCodecSpecificData(ptr, length);
417
418        ptr += length;
419        size -= length;
420    }
421
422    if (size < 1) {
423        return ERROR_MALFORMED;
424    }
425
426    size_t numPictureParameterSets = *ptr;
427    ++ptr;
428    --size;
429
430    for (size_t i = 0; i < numPictureParameterSets; ++i) {
431        if (size < 2) {
432            return ERROR_MALFORMED;
433        }
434
435        size_t length = U16_AT(ptr);
436
437        ptr += 2;
438        size -= 2;
439
440        if (size < length) {
441            return ERROR_MALFORMED;
442        }
443
444        addCodecSpecificData(ptr, length);
445
446        ptr += length;
447        size -= length;
448    }
449
450    return OK;
451}
452
453status_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
454    ALOGV("configureCodec protected=%d",
455         (mFlags & kEnableGrallocUsageProtected) ? 1 : 0);
456
457    if (!(mFlags & kIgnoreCodecSpecificData)) {
458        uint32_t type;
459        const void *data;
460        size_t size;
461        if (meta->findData(kKeyESDS, &type, &data, &size)) {
462            ESDS esds((const char *)data, size);
463            CHECK_EQ(esds.InitCheck(), (status_t)OK);
464
465            const void *codec_specific_data;
466            size_t codec_specific_data_size;
467            esds.getCodecSpecificInfo(
468                    &codec_specific_data, &codec_specific_data_size);
469
470            addCodecSpecificData(
471                    codec_specific_data, codec_specific_data_size);
472        } else if (meta->findData(kKeyAVCC, &type, &data, &size)) {
473            // Parse the AVCDecoderConfigurationRecord
474
475            unsigned profile, level;
476            status_t err;
477            if ((err = parseAVCCodecSpecificData(
478                            data, size, &profile, &level)) != OK) {
479                ALOGE("Malformed AVC codec specific data.");
480                return err;
481            }
482
483            CODEC_LOGI(
484                    "AVC profile = %u (%s), level = %u",
485                    profile, AVCProfileToString(profile), level);
486        } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
487            addCodecSpecificData(data, size);
488
489            CHECK(meta->findData(kKeyVorbisBooks, &type, &data, &size));
490            addCodecSpecificData(data, size);
491        }
492    }
493
494    int32_t bitRate = 0;
495    if (mIsEncoder) {
496        CHECK(meta->findInt32(kKeyBitRate, &bitRate));
497    }
498    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mMIME)) {
499        setAMRFormat(false /* isWAMR */, bitRate);
500    } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mMIME)) {
501        setAMRFormat(true /* isWAMR */, bitRate);
502    } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mMIME)) {
503        int32_t numChannels, sampleRate, aacProfile;
504        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
505        CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
506
507        if (!meta->findInt32(kKeyAACProfile, &aacProfile)) {
508            aacProfile = OMX_AUDIO_AACObjectNull;
509        }
510
511        int32_t isADTS;
512        if (!meta->findInt32(kKeyIsADTS, &isADTS)) {
513            isADTS = false;
514        }
515
516        status_t err = setAACFormat(numChannels, sampleRate, bitRate, aacProfile, isADTS);
517        if (err != OK) {
518            CODEC_LOGE("setAACFormat() failed (err = %d)", err);
519            return err;
520        }
521    } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_MPEG, mMIME)) {
522        int32_t numChannels, sampleRate;
523        if (meta->findInt32(kKeyChannelCount, &numChannels)
524                && meta->findInt32(kKeySampleRate, &sampleRate)) {
525            // Since we did not always check for these, leave them optional
526            // and have the decoder figure it all out.
527            setRawAudioFormat(
528                    mIsEncoder ? kPortIndexInput : kPortIndexOutput,
529                    sampleRate,
530                    numChannels);
531        }
532    } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_ALAW, mMIME)
533            || !strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_MLAW, mMIME)) {
534        // These are PCM-like formats with a fixed sample rate but
535        // a variable number of channels.
536
537        int32_t numChannels;
538        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
539
540        setG711Format(numChannels);
541    } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, mMIME)) {
542        CHECK(!mIsEncoder);
543
544        int32_t numChannels, sampleRate;
545        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
546        CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
547
548        setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
549    }
550
551    if (!strncasecmp(mMIME, "video/", 6)) {
552
553        if (mIsEncoder) {
554            setVideoInputFormat(mMIME, meta);
555        } else {
556            status_t err = setVideoOutputFormat(
557                    mMIME, meta);
558
559            if (err != OK) {
560                return err;
561            }
562        }
563    }
564
565    int32_t maxInputSize;
566    if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
567        setMinBufferSize(kPortIndexInput, (OMX_U32)maxInputSize);
568    }
569
570    initOutputFormat(meta);
571
572    if ((mFlags & kClientNeedsFramebuffer)
573            && !strncmp(mComponentName, "OMX.SEC.", 8)) {
574        // This appears to no longer be needed???
575
576        OMX_INDEXTYPE index;
577
578        status_t err =
579            mOMX->getExtensionIndex(
580                    mNode,
581                    "OMX.SEC.index.ThumbnailMode",
582                    &index);
583
584        if (err != OK) {
585            return err;
586        }
587
588        OMX_BOOL enable = OMX_TRUE;
589        err = mOMX->setConfig(mNode, index, &enable, sizeof(enable));
590
591        if (err != OK) {
592            CODEC_LOGE("setConfig('OMX.SEC.index.ThumbnailMode') "
593                       "returned error 0x%08x", err);
594
595            return err;
596        }
597
598        mQuirks &= ~kOutputBuffersAreUnreadable;
599    }
600
601    if (mNativeWindow != NULL
602        && !mIsEncoder
603        && !strncasecmp(mMIME, "video/", 6)
604        && !strncmp(mComponentName, "OMX.", 4)) {
605        status_t err = initNativeWindow();
606        if (err != OK) {
607            return err;
608        }
609    }
610
611    return OK;
612}
613
614void OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) {
615    OMX_PARAM_PORTDEFINITIONTYPE def;
616    InitOMXParams(&def);
617    def.nPortIndex = portIndex;
618
619    status_t err = mOMX->getParameter(
620            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
621    CHECK_EQ(err, (status_t)OK);
622
623    if ((portIndex == kPortIndexInput && (mQuirks & kInputBufferSizesAreBogus))
624        || (def.nBufferSize < size)) {
625        def.nBufferSize = size;
626    }
627
628    err = mOMX->setParameter(
629            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
630    CHECK_EQ(err, (status_t)OK);
631
632    err = mOMX->getParameter(
633            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
634    CHECK_EQ(err, (status_t)OK);
635
636    // Make sure the setting actually stuck.
637    if (portIndex == kPortIndexInput
638            && (mQuirks & kInputBufferSizesAreBogus)) {
639        CHECK_EQ(def.nBufferSize, size);
640    } else {
641        CHECK(def.nBufferSize >= size);
642    }
643}
644
645status_t OMXCodec::setVideoPortFormatType(
646        OMX_U32 portIndex,
647        OMX_VIDEO_CODINGTYPE compressionFormat,
648        OMX_COLOR_FORMATTYPE colorFormat) {
649    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
650    InitOMXParams(&format);
651    format.nPortIndex = portIndex;
652    format.nIndex = 0;
653    bool found = false;
654
655    OMX_U32 index = 0;
656    for (;;) {
657        format.nIndex = index;
658        status_t err = mOMX->getParameter(
659                mNode, OMX_IndexParamVideoPortFormat,
660                &format, sizeof(format));
661
662        if (err != OK) {
663            return err;
664        }
665
666        // The following assertion is violated by TI's video decoder.
667        // CHECK_EQ(format.nIndex, index);
668
669#if 1
670        CODEC_LOGV("portIndex: %ld, index: %ld, eCompressionFormat=%d eColorFormat=%d",
671             portIndex,
672             index, format.eCompressionFormat, format.eColorFormat);
673#endif
674
675        if (format.eCompressionFormat == compressionFormat
676                && format.eColorFormat == colorFormat) {
677            found = true;
678            break;
679        }
680
681        ++index;
682        if (index >= kMaxColorFormatSupported) {
683            CODEC_LOGE("color format %d or compression format %d is not supported",
684                colorFormat, compressionFormat);
685            return UNKNOWN_ERROR;
686        }
687    }
688
689    if (!found) {
690        return UNKNOWN_ERROR;
691    }
692
693    CODEC_LOGV("found a match.");
694    status_t err = mOMX->setParameter(
695            mNode, OMX_IndexParamVideoPortFormat,
696            &format, sizeof(format));
697
698    return err;
699}
700
701static size_t getFrameSize(
702        OMX_COLOR_FORMATTYPE colorFormat, int32_t width, int32_t height) {
703    switch (colorFormat) {
704        case OMX_COLOR_FormatYCbYCr:
705        case OMX_COLOR_FormatCbYCrY:
706            return width * height * 2;
707
708        case OMX_COLOR_FormatYUV420Planar:
709        case OMX_COLOR_FormatYUV420SemiPlanar:
710        case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
711        /*
712        * FIXME: For the Opaque color format, the frame size does not
713        * need to be (w*h*3)/2. It just needs to
714        * be larger than certain minimum buffer size. However,
715        * currently, this opaque foramt has been tested only on
716        * YUV420 formats. If that is changed, then we need to revisit
717        * this part in the future
718        */
719        case OMX_COLOR_FormatAndroidOpaque:
720            return (width * height * 3) / 2;
721
722        default:
723            CHECK(!"Should not be here. Unsupported color format.");
724            break;
725    }
726}
727
728status_t OMXCodec::findTargetColorFormat(
729        const sp<MetaData>& meta, OMX_COLOR_FORMATTYPE *colorFormat) {
730    ALOGV("findTargetColorFormat");
731    CHECK(mIsEncoder);
732
733    *colorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
734    int32_t targetColorFormat;
735    if (meta->findInt32(kKeyColorFormat, &targetColorFormat)) {
736        *colorFormat = (OMX_COLOR_FORMATTYPE) targetColorFormat;
737    }
738
739    // Check whether the target color format is supported.
740    return isColorFormatSupported(*colorFormat, kPortIndexInput);
741}
742
743status_t OMXCodec::isColorFormatSupported(
744        OMX_COLOR_FORMATTYPE colorFormat, int portIndex) {
745    ALOGV("isColorFormatSupported: %d", static_cast<int>(colorFormat));
746
747    // Enumerate all the color formats supported by
748    // the omx component to see whether the given
749    // color format is supported.
750    OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
751    InitOMXParams(&portFormat);
752    portFormat.nPortIndex = portIndex;
753    OMX_U32 index = 0;
754    portFormat.nIndex = index;
755    while (true) {
756        if (OMX_ErrorNone != mOMX->getParameter(
757                mNode, OMX_IndexParamVideoPortFormat,
758                &portFormat, sizeof(portFormat))) {
759            break;
760        }
761        // Make sure that omx component does not overwrite
762        // the incremented index (bug 2897413).
763        CHECK_EQ(index, portFormat.nIndex);
764        if (portFormat.eColorFormat == colorFormat) {
765            CODEC_LOGV("Found supported color format: %d", portFormat.eColorFormat);
766            return OK;  // colorFormat is supported!
767        }
768        ++index;
769        portFormat.nIndex = index;
770
771        if (index >= kMaxColorFormatSupported) {
772            CODEC_LOGE("More than %ld color formats are supported???", index);
773            break;
774        }
775    }
776
777    CODEC_LOGE("color format %d is not supported", colorFormat);
778    return UNKNOWN_ERROR;
779}
780
781void OMXCodec::setVideoInputFormat(
782        const char *mime, const sp<MetaData>& meta) {
783
784    int32_t width, height, frameRate, bitRate, stride, sliceHeight;
785    bool success = meta->findInt32(kKeyWidth, &width);
786    success = success && meta->findInt32(kKeyHeight, &height);
787    success = success && meta->findInt32(kKeyFrameRate, &frameRate);
788    success = success && meta->findInt32(kKeyBitRate, &bitRate);
789    success = success && meta->findInt32(kKeyStride, &stride);
790    success = success && meta->findInt32(kKeySliceHeight, &sliceHeight);
791    CHECK(success);
792    CHECK(stride != 0);
793
794    OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
795    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
796        compressionFormat = OMX_VIDEO_CodingAVC;
797    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
798        compressionFormat = OMX_VIDEO_CodingMPEG4;
799    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
800        compressionFormat = OMX_VIDEO_CodingH263;
801    } else {
802        ALOGE("Not a supported video mime type: %s", mime);
803        CHECK(!"Should not be here. Not a supported video mime type.");
804    }
805
806    OMX_COLOR_FORMATTYPE colorFormat;
807    CHECK_EQ((status_t)OK, findTargetColorFormat(meta, &colorFormat));
808
809    status_t err;
810    OMX_PARAM_PORTDEFINITIONTYPE def;
811    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
812
813    //////////////////////// Input port /////////////////////////
814    CHECK_EQ(setVideoPortFormatType(
815            kPortIndexInput, OMX_VIDEO_CodingUnused,
816            colorFormat), (status_t)OK);
817
818    InitOMXParams(&def);
819    def.nPortIndex = kPortIndexInput;
820
821    err = mOMX->getParameter(
822            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
823    CHECK_EQ(err, (status_t)OK);
824
825    def.nBufferSize = getFrameSize(colorFormat,
826            stride > 0? stride: -stride, sliceHeight);
827
828    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
829
830    video_def->nFrameWidth = width;
831    video_def->nFrameHeight = height;
832    video_def->nStride = stride;
833    video_def->nSliceHeight = sliceHeight;
834    video_def->xFramerate = (frameRate << 16);  // Q16 format
835    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
836    video_def->eColorFormat = colorFormat;
837
838    err = mOMX->setParameter(
839            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
840    CHECK_EQ(err, (status_t)OK);
841
842    //////////////////////// Output port /////////////////////////
843    CHECK_EQ(setVideoPortFormatType(
844            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused),
845            (status_t)OK);
846    InitOMXParams(&def);
847    def.nPortIndex = kPortIndexOutput;
848
849    err = mOMX->getParameter(
850            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
851
852    CHECK_EQ(err, (status_t)OK);
853    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
854
855    video_def->nFrameWidth = width;
856    video_def->nFrameHeight = height;
857    video_def->xFramerate = 0;      // No need for output port
858    video_def->nBitrate = bitRate;  // Q16 format
859    video_def->eCompressionFormat = compressionFormat;
860    video_def->eColorFormat = OMX_COLOR_FormatUnused;
861    if (mQuirks & kRequiresLargerEncoderOutputBuffer) {
862        // Increases the output buffer size
863        def.nBufferSize = ((def.nBufferSize * 3) >> 1);
864    }
865
866    err = mOMX->setParameter(
867            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
868    CHECK_EQ(err, (status_t)OK);
869
870    /////////////////// Codec-specific ////////////////////////
871    switch (compressionFormat) {
872        case OMX_VIDEO_CodingMPEG4:
873        {
874            CHECK_EQ(setupMPEG4EncoderParameters(meta), (status_t)OK);
875            break;
876        }
877
878        case OMX_VIDEO_CodingH263:
879            CHECK_EQ(setupH263EncoderParameters(meta), (status_t)OK);
880            break;
881
882        case OMX_VIDEO_CodingAVC:
883        {
884            CHECK_EQ(setupAVCEncoderParameters(meta), (status_t)OK);
885            break;
886        }
887
888        default:
889            CHECK(!"Support for this compressionFormat to be implemented.");
890            break;
891    }
892}
893
894static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
895    if (iFramesInterval < 0) {
896        return 0xFFFFFFFF;
897    } else if (iFramesInterval == 0) {
898        return 0;
899    }
900    OMX_U32 ret = frameRate * iFramesInterval - 1;
901    CHECK(ret > 1);
902    return ret;
903}
904
905status_t OMXCodec::setupErrorCorrectionParameters() {
906    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
907    InitOMXParams(&errorCorrectionType);
908    errorCorrectionType.nPortIndex = kPortIndexOutput;
909
910    status_t err = mOMX->getParameter(
911            mNode, OMX_IndexParamVideoErrorCorrection,
912            &errorCorrectionType, sizeof(errorCorrectionType));
913    if (err != OK) {
914        ALOGW("Error correction param query is not supported");
915        return OK;  // Optional feature. Ignore this failure
916    }
917
918    errorCorrectionType.bEnableHEC = OMX_FALSE;
919    errorCorrectionType.bEnableResync = OMX_TRUE;
920    errorCorrectionType.nResynchMarkerSpacing = 256;
921    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
922    errorCorrectionType.bEnableRVLC = OMX_FALSE;
923
924    err = mOMX->setParameter(
925            mNode, OMX_IndexParamVideoErrorCorrection,
926            &errorCorrectionType, sizeof(errorCorrectionType));
927    if (err != OK) {
928        ALOGW("Error correction param configuration is not supported");
929    }
930
931    // Optional feature. Ignore the failure.
932    return OK;
933}
934
935status_t OMXCodec::setupBitRate(int32_t bitRate) {
936    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
937    InitOMXParams(&bitrateType);
938    bitrateType.nPortIndex = kPortIndexOutput;
939
940    status_t err = mOMX->getParameter(
941            mNode, OMX_IndexParamVideoBitrate,
942            &bitrateType, sizeof(bitrateType));
943    CHECK_EQ(err, (status_t)OK);
944
945    bitrateType.eControlRate = OMX_Video_ControlRateVariable;
946    bitrateType.nTargetBitrate = bitRate;
947
948    err = mOMX->setParameter(
949            mNode, OMX_IndexParamVideoBitrate,
950            &bitrateType, sizeof(bitrateType));
951    CHECK_EQ(err, (status_t)OK);
952    return OK;
953}
954
955status_t OMXCodec::getVideoProfileLevel(
956        const sp<MetaData>& meta,
957        const CodecProfileLevel& defaultProfileLevel,
958        CodecProfileLevel &profileLevel) {
959    CODEC_LOGV("Default profile: %ld, level %ld",
960            defaultProfileLevel.mProfile, defaultProfileLevel.mLevel);
961
962    // Are the default profile and level overwriten?
963    int32_t profile, level;
964    if (!meta->findInt32(kKeyVideoProfile, &profile)) {
965        profile = defaultProfileLevel.mProfile;
966    }
967    if (!meta->findInt32(kKeyVideoLevel, &level)) {
968        level = defaultProfileLevel.mLevel;
969    }
970    CODEC_LOGV("Target profile: %d, level: %d", profile, level);
971
972    // Are the target profile and level supported by the encoder?
973    OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
974    InitOMXParams(&param);
975    param.nPortIndex = kPortIndexOutput;
976    for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
977        status_t err = mOMX->getParameter(
978                mNode, OMX_IndexParamVideoProfileLevelQuerySupported,
979                &param, sizeof(param));
980
981        if (err != OK) break;
982
983        int32_t supportedProfile = static_cast<int32_t>(param.eProfile);
984        int32_t supportedLevel = static_cast<int32_t>(param.eLevel);
985        CODEC_LOGV("Supported profile: %d, level %d",
986            supportedProfile, supportedLevel);
987
988        if (profile == supportedProfile &&
989            level <= supportedLevel) {
990            // We can further check whether the level is a valid
991            // value; but we will leave that to the omx encoder component
992            // via OMX_SetParameter call.
993            profileLevel.mProfile = profile;
994            profileLevel.mLevel = level;
995            return OK;
996        }
997    }
998
999    CODEC_LOGE("Target profile (%d) and level (%d) is not supported",
1000            profile, level);
1001    return BAD_VALUE;
1002}
1003
1004status_t OMXCodec::setupH263EncoderParameters(const sp<MetaData>& meta) {
1005    int32_t iFramesInterval, frameRate, bitRate;
1006    bool success = meta->findInt32(kKeyBitRate, &bitRate);
1007    success = success && meta->findInt32(kKeyFrameRate, &frameRate);
1008    success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
1009    CHECK(success);
1010    OMX_VIDEO_PARAM_H263TYPE h263type;
1011    InitOMXParams(&h263type);
1012    h263type.nPortIndex = kPortIndexOutput;
1013
1014    status_t err = mOMX->getParameter(
1015            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
1016    CHECK_EQ(err, (status_t)OK);
1017
1018    h263type.nAllowedPictureTypes =
1019        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
1020
1021    h263type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate);
1022    if (h263type.nPFrames == 0) {
1023        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
1024    }
1025    h263type.nBFrames = 0;
1026
1027    // Check profile and level parameters
1028    CodecProfileLevel defaultProfileLevel, profileLevel;
1029    defaultProfileLevel.mProfile = h263type.eProfile;
1030    defaultProfileLevel.mLevel = h263type.eLevel;
1031    err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel);
1032    if (err != OK) return err;
1033    h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profileLevel.mProfile);
1034    h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(profileLevel.mLevel);
1035
1036    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
1037    h263type.bForceRoundingTypeToZero = OMX_FALSE;
1038    h263type.nPictureHeaderRepetition = 0;
1039    h263type.nGOBHeaderInterval = 0;
1040
1041    err = mOMX->setParameter(
1042            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
1043    CHECK_EQ(err, (status_t)OK);
1044
1045    CHECK_EQ(setupBitRate(bitRate), (status_t)OK);
1046    CHECK_EQ(setupErrorCorrectionParameters(), (status_t)OK);
1047
1048    return OK;
1049}
1050
1051status_t OMXCodec::setupMPEG4EncoderParameters(const sp<MetaData>& meta) {
1052    int32_t iFramesInterval, frameRate, bitRate;
1053    bool success = meta->findInt32(kKeyBitRate, &bitRate);
1054    success = success && meta->findInt32(kKeyFrameRate, &frameRate);
1055    success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
1056    CHECK(success);
1057    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
1058    InitOMXParams(&mpeg4type);
1059    mpeg4type.nPortIndex = kPortIndexOutput;
1060
1061    status_t err = mOMX->getParameter(
1062            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
1063    CHECK_EQ(err, (status_t)OK);
1064
1065    mpeg4type.nSliceHeaderSpacing = 0;
1066    mpeg4type.bSVH = OMX_FALSE;
1067    mpeg4type.bGov = OMX_FALSE;
1068
1069    mpeg4type.nAllowedPictureTypes =
1070        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
1071
1072    mpeg4type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate);
1073    if (mpeg4type.nPFrames == 0) {
1074        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
1075    }
1076    mpeg4type.nBFrames = 0;
1077    mpeg4type.nIDCVLCThreshold = 0;
1078    mpeg4type.bACPred = OMX_TRUE;
1079    mpeg4type.nMaxPacketSize = 256;
1080    mpeg4type.nTimeIncRes = 1000;
1081    mpeg4type.nHeaderExtension = 0;
1082    mpeg4type.bReversibleVLC = OMX_FALSE;
1083
1084    // Check profile and level parameters
1085    CodecProfileLevel defaultProfileLevel, profileLevel;
1086    defaultProfileLevel.mProfile = mpeg4type.eProfile;
1087    defaultProfileLevel.mLevel = mpeg4type.eLevel;
1088    err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel);
1089    if (err != OK) return err;
1090    mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profileLevel.mProfile);
1091    mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(profileLevel.mLevel);
1092
1093    err = mOMX->setParameter(
1094            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
1095    CHECK_EQ(err, (status_t)OK);
1096
1097    CHECK_EQ(setupBitRate(bitRate), (status_t)OK);
1098    CHECK_EQ(setupErrorCorrectionParameters(), (status_t)OK);
1099
1100    return OK;
1101}
1102
1103status_t OMXCodec::setupAVCEncoderParameters(const sp<MetaData>& meta) {
1104    int32_t iFramesInterval, frameRate, bitRate;
1105    bool success = meta->findInt32(kKeyBitRate, &bitRate);
1106    success = success && meta->findInt32(kKeyFrameRate, &frameRate);
1107    success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
1108    CHECK(success);
1109
1110    OMX_VIDEO_PARAM_AVCTYPE h264type;
1111    InitOMXParams(&h264type);
1112    h264type.nPortIndex = kPortIndexOutput;
1113
1114    status_t err = mOMX->getParameter(
1115            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
1116    CHECK_EQ(err, (status_t)OK);
1117
1118    h264type.nAllowedPictureTypes =
1119        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
1120
1121    // Check profile and level parameters
1122    CodecProfileLevel defaultProfileLevel, profileLevel;
1123    defaultProfileLevel.mProfile = h264type.eProfile;
1124    defaultProfileLevel.mLevel = h264type.eLevel;
1125    err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel);
1126    if (err != OK) return err;
1127    h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profileLevel.mProfile);
1128    h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(profileLevel.mLevel);
1129
1130    // XXX
1131    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
1132        ALOGW("Use baseline profile instead of %d for AVC recording",
1133            h264type.eProfile);
1134        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
1135    }
1136
1137    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
1138        h264type.nSliceHeaderSpacing = 0;
1139        h264type.bUseHadamard = OMX_TRUE;
1140        h264type.nRefFrames = 1;
1141        h264type.nBFrames = 0;
1142        h264type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate);
1143        if (h264type.nPFrames == 0) {
1144            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
1145        }
1146        h264type.nRefIdx10ActiveMinus1 = 0;
1147        h264type.nRefIdx11ActiveMinus1 = 0;
1148        h264type.bEntropyCodingCABAC = OMX_FALSE;
1149        h264type.bWeightedPPrediction = OMX_FALSE;
1150        h264type.bconstIpred = OMX_FALSE;
1151        h264type.bDirect8x8Inference = OMX_FALSE;
1152        h264type.bDirectSpatialTemporal = OMX_FALSE;
1153        h264type.nCabacInitIdc = 0;
1154    }
1155
1156    if (h264type.nBFrames != 0) {
1157        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
1158    }
1159
1160    h264type.bEnableUEP = OMX_FALSE;
1161    h264type.bEnableFMO = OMX_FALSE;
1162    h264type.bEnableASO = OMX_FALSE;
1163    h264type.bEnableRS = OMX_FALSE;
1164    h264type.bFrameMBsOnly = OMX_TRUE;
1165    h264type.bMBAFF = OMX_FALSE;
1166    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
1167
1168    err = mOMX->setParameter(
1169            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
1170    CHECK_EQ(err, (status_t)OK);
1171
1172    CHECK_EQ(setupBitRate(bitRate), (status_t)OK);
1173
1174    return OK;
1175}
1176
1177status_t OMXCodec::setVideoOutputFormat(
1178        const char *mime, const sp<MetaData>& meta) {
1179
1180    int32_t width, height;
1181    bool success = meta->findInt32(kKeyWidth, &width);
1182    success = success && meta->findInt32(kKeyHeight, &height);
1183    CHECK(success);
1184
1185    CODEC_LOGV("setVideoOutputFormat width=%ld, height=%ld", width, height);
1186
1187    OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
1188    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
1189        compressionFormat = OMX_VIDEO_CodingAVC;
1190    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
1191        compressionFormat = OMX_VIDEO_CodingMPEG4;
1192    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
1193        compressionFormat = OMX_VIDEO_CodingH263;
1194    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VP8, mime)) {
1195        compressionFormat = OMX_VIDEO_CodingVP8;
1196    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VP9, mime)) {
1197        compressionFormat = OMX_VIDEO_CodingVP9;
1198    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG2, mime)) {
1199        compressionFormat = OMX_VIDEO_CodingMPEG2;
1200    } else {
1201        ALOGE("Not a supported video mime type: %s", mime);
1202        CHECK(!"Should not be here. Not a supported video mime type.");
1203    }
1204
1205    status_t err = setVideoPortFormatType(
1206            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1207
1208    if (err != OK) {
1209        return err;
1210    }
1211
1212#if 1
1213    {
1214        OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1215        InitOMXParams(&format);
1216        format.nPortIndex = kPortIndexOutput;
1217        format.nIndex = 0;
1218
1219        status_t err = mOMX->getParameter(
1220                mNode, OMX_IndexParamVideoPortFormat,
1221                &format, sizeof(format));
1222        CHECK_EQ(err, (status_t)OK);
1223        CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1224
1225        int32_t colorFormat;
1226        if (meta->findInt32(kKeyColorFormat, &colorFormat)
1227                && colorFormat != OMX_COLOR_FormatUnused
1228                && colorFormat != format.eColorFormat) {
1229
1230            while (OMX_ErrorNoMore != err) {
1231                format.nIndex++;
1232                err = mOMX->getParameter(
1233                        mNode, OMX_IndexParamVideoPortFormat,
1234                            &format, sizeof(format));
1235                if (format.eColorFormat == colorFormat) {
1236                    break;
1237                }
1238            }
1239            if (format.eColorFormat != colorFormat) {
1240                CODEC_LOGE("Color format %d is not supported", colorFormat);
1241                return ERROR_UNSUPPORTED;
1242            }
1243        }
1244
1245        err = mOMX->setParameter(
1246                mNode, OMX_IndexParamVideoPortFormat,
1247                &format, sizeof(format));
1248
1249        if (err != OK) {
1250            return err;
1251        }
1252    }
1253#endif
1254
1255    OMX_PARAM_PORTDEFINITIONTYPE def;
1256    InitOMXParams(&def);
1257    def.nPortIndex = kPortIndexInput;
1258
1259    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
1260
1261    err = mOMX->getParameter(
1262            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1263
1264    CHECK_EQ(err, (status_t)OK);
1265
1266#if 1
1267    // XXX Need a (much) better heuristic to compute input buffer sizes.
1268    const size_t X = 64 * 1024;
1269    if (def.nBufferSize < X) {
1270        def.nBufferSize = X;
1271    }
1272#endif
1273
1274    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
1275
1276    video_def->nFrameWidth = width;
1277    video_def->nFrameHeight = height;
1278
1279    video_def->eCompressionFormat = compressionFormat;
1280    video_def->eColorFormat = OMX_COLOR_FormatUnused;
1281
1282    err = mOMX->setParameter(
1283            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1284
1285    if (err != OK) {
1286        return err;
1287    }
1288
1289    ////////////////////////////////////////////////////////////////////////////
1290
1291    InitOMXParams(&def);
1292    def.nPortIndex = kPortIndexOutput;
1293
1294    err = mOMX->getParameter(
1295            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1296    CHECK_EQ(err, (status_t)OK);
1297    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
1298
1299#if 0
1300    def.nBufferSize =
1301        (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2;  // YUV420
1302#endif
1303
1304    video_def->nFrameWidth = width;
1305    video_def->nFrameHeight = height;
1306
1307    err = mOMX->setParameter(
1308            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1309
1310    return err;
1311}
1312
1313OMXCodec::OMXCodec(
1314        const sp<IOMX> &omx, IOMX::node_id node,
1315        uint32_t quirks, uint32_t flags,
1316        bool isEncoder,
1317        const char *mime,
1318        const char *componentName,
1319        const sp<MediaSource> &source,
1320        const sp<ANativeWindow> &nativeWindow)
1321    : mOMX(omx),
1322      mOMXLivesLocally(omx->livesLocally(node, getpid())),
1323      mNode(node),
1324      mQuirks(quirks),
1325      mFlags(flags),
1326      mIsEncoder(isEncoder),
1327      mIsVideo(!strncasecmp("video/", mime, 6)),
1328      mMIME(strdup(mime)),
1329      mComponentName(strdup(componentName)),
1330      mSource(source),
1331      mCodecSpecificDataIndex(0),
1332      mState(LOADED),
1333      mInitialBufferSubmit(true),
1334      mSignalledEOS(false),
1335      mNoMoreOutputData(false),
1336      mOutputPortSettingsHaveChanged(false),
1337      mSeekTimeUs(-1),
1338      mSeekMode(ReadOptions::SEEK_CLOSEST_SYNC),
1339      mTargetTimeUs(-1),
1340      mOutputPortSettingsChangedPending(false),
1341      mSkipCutBuffer(NULL),
1342      mLeftOverBuffer(NULL),
1343      mPaused(false),
1344      mNativeWindow(
1345              (!strncmp(componentName, "OMX.google.", 11))
1346                        ? NULL : nativeWindow) {
1347    mPortStatus[kPortIndexInput] = ENABLED;
1348    mPortStatus[kPortIndexOutput] = ENABLED;
1349
1350    setComponentRole();
1351}
1352
1353// static
1354void OMXCodec::setComponentRole(
1355        const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder,
1356        const char *mime) {
1357    struct MimeToRole {
1358        const char *mime;
1359        const char *decoderRole;
1360        const char *encoderRole;
1361    };
1362
1363    static const MimeToRole kMimeToRole[] = {
1364        { MEDIA_MIMETYPE_AUDIO_MPEG,
1365            "audio_decoder.mp3", "audio_encoder.mp3" },
1366        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
1367            "audio_decoder.mp1", "audio_encoder.mp1" },
1368        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
1369            "audio_decoder.mp2", "audio_encoder.mp2" },
1370        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1371            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1372        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1373            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1374        { MEDIA_MIMETYPE_AUDIO_AAC,
1375            "audio_decoder.aac", "audio_encoder.aac" },
1376        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1377            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1378        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1379            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1380        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1381            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1382        { MEDIA_MIMETYPE_VIDEO_AVC,
1383            "video_decoder.avc", "video_encoder.avc" },
1384        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1385            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1386        { MEDIA_MIMETYPE_VIDEO_H263,
1387            "video_decoder.h263", "video_encoder.h263" },
1388        { MEDIA_MIMETYPE_VIDEO_VP8,
1389            "video_decoder.vp8", "video_encoder.vp8" },
1390        { MEDIA_MIMETYPE_VIDEO_VP9,
1391            "video_decoder.vp9", "video_encoder.vp9" },
1392        { MEDIA_MIMETYPE_AUDIO_RAW,
1393            "audio_decoder.raw", "audio_encoder.raw" },
1394        { MEDIA_MIMETYPE_AUDIO_FLAC,
1395            "audio_decoder.flac", "audio_encoder.flac" },
1396        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1397            "audio_decoder.gsm", "audio_encoder.gsm" },
1398    };
1399
1400    static const size_t kNumMimeToRole =
1401        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1402
1403    size_t i;
1404    for (i = 0; i < kNumMimeToRole; ++i) {
1405        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1406            break;
1407        }
1408    }
1409
1410    if (i == kNumMimeToRole) {
1411        return;
1412    }
1413
1414    const char *role =
1415        isEncoder ? kMimeToRole[i].encoderRole
1416                  : kMimeToRole[i].decoderRole;
1417
1418    if (role != NULL) {
1419        OMX_PARAM_COMPONENTROLETYPE roleParams;
1420        InitOMXParams(&roleParams);
1421
1422        strncpy((char *)roleParams.cRole,
1423                role, OMX_MAX_STRINGNAME_SIZE - 1);
1424
1425        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1426
1427        status_t err = omx->setParameter(
1428                node, OMX_IndexParamStandardComponentRole,
1429                &roleParams, sizeof(roleParams));
1430
1431        if (err != OK) {
1432            ALOGW("Failed to set standard component role '%s'.", role);
1433        }
1434    }
1435}
1436
1437void OMXCodec::setComponentRole() {
1438    setComponentRole(mOMX, mNode, mIsEncoder, mMIME);
1439}
1440
1441OMXCodec::~OMXCodec() {
1442    mSource.clear();
1443
1444    CHECK(mState == LOADED || mState == ERROR || mState == LOADED_TO_IDLE);
1445
1446    status_t err = mOMX->freeNode(mNode);
1447    CHECK_EQ(err, (status_t)OK);
1448
1449    mNode = NULL;
1450    setState(DEAD);
1451
1452    clearCodecSpecificData();
1453
1454    free(mComponentName);
1455    mComponentName = NULL;
1456
1457    free(mMIME);
1458    mMIME = NULL;
1459}
1460
1461status_t OMXCodec::init() {
1462    // mLock is held.
1463
1464    CHECK_EQ((int)mState, (int)LOADED);
1465
1466    status_t err;
1467    if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) {
1468        err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
1469        CHECK_EQ(err, (status_t)OK);
1470        setState(LOADED_TO_IDLE);
1471    }
1472
1473    err = allocateBuffers();
1474    if (err != (status_t)OK) {
1475        return err;
1476    }
1477
1478    if (mQuirks & kRequiresLoadedToIdleAfterAllocation) {
1479        err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
1480        CHECK_EQ(err, (status_t)OK);
1481
1482        setState(LOADED_TO_IDLE);
1483    }
1484
1485    while (mState != EXECUTING && mState != ERROR) {
1486        mAsyncCompletion.wait(mLock);
1487    }
1488
1489    return mState == ERROR ? UNKNOWN_ERROR : OK;
1490}
1491
1492// static
1493bool OMXCodec::isIntermediateState(State state) {
1494    return state == LOADED_TO_IDLE
1495        || state == IDLE_TO_EXECUTING
1496        || state == EXECUTING_TO_IDLE
1497        || state == IDLE_TO_LOADED
1498        || state == RECONFIGURING;
1499}
1500
1501status_t OMXCodec::allocateBuffers() {
1502    status_t err = allocateBuffersOnPort(kPortIndexInput);
1503
1504    if (err != OK) {
1505        return err;
1506    }
1507
1508    return allocateBuffersOnPort(kPortIndexOutput);
1509}
1510
1511status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
1512    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
1513        return allocateOutputBuffersFromNativeWindow();
1514    }
1515
1516    if ((mFlags & kEnableGrallocUsageProtected) && portIndex == kPortIndexOutput) {
1517        ALOGE("protected output buffers must be stent to an ANativeWindow");
1518        return PERMISSION_DENIED;
1519    }
1520
1521    status_t err = OK;
1522    if ((mFlags & kStoreMetaDataInVideoBuffers)
1523            && portIndex == kPortIndexInput) {
1524        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1525        if (err != OK) {
1526            ALOGE("Storing meta data in video buffers is not supported");
1527            return err;
1528        }
1529    }
1530
1531    OMX_PARAM_PORTDEFINITIONTYPE def;
1532    InitOMXParams(&def);
1533    def.nPortIndex = portIndex;
1534
1535    err = mOMX->getParameter(
1536            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1537
1538    if (err != OK) {
1539        return err;
1540    }
1541
1542    CODEC_LOGV("allocating %lu buffers of size %lu on %s port",
1543            def.nBufferCountActual, def.nBufferSize,
1544            portIndex == kPortIndexInput ? "input" : "output");
1545
1546    size_t totalSize = def.nBufferCountActual * def.nBufferSize;
1547    mDealer[portIndex] = new MemoryDealer(totalSize, "OMXCodec");
1548
1549    for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
1550        sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
1551        CHECK(mem.get() != NULL);
1552
1553        BufferInfo info;
1554        info.mData = NULL;
1555        info.mSize = def.nBufferSize;
1556
1557        IOMX::buffer_id buffer;
1558        if (portIndex == kPortIndexInput
1559                && ((mQuirks & kRequiresAllocateBufferOnInputPorts)
1560                    || (mFlags & kUseSecureInputBuffers))) {
1561            if (mOMXLivesLocally) {
1562                mem.clear();
1563
1564                err = mOMX->allocateBuffer(
1565                        mNode, portIndex, def.nBufferSize, &buffer,
1566                        &info.mData);
1567            } else {
1568                err = mOMX->allocateBufferWithBackup(
1569                        mNode, portIndex, mem, &buffer);
1570            }
1571        } else if (portIndex == kPortIndexOutput
1572                && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) {
1573            if (mOMXLivesLocally) {
1574                mem.clear();
1575
1576                err = mOMX->allocateBuffer(
1577                        mNode, portIndex, def.nBufferSize, &buffer,
1578                        &info.mData);
1579            } else {
1580                err = mOMX->allocateBufferWithBackup(
1581                        mNode, portIndex, mem, &buffer);
1582            }
1583        } else {
1584            err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
1585        }
1586
1587        if (err != OK) {
1588            ALOGE("allocate_buffer_with_backup failed");
1589            return err;
1590        }
1591
1592        if (mem != NULL) {
1593            info.mData = mem->pointer();
1594        }
1595
1596        info.mBuffer = buffer;
1597        info.mStatus = OWNED_BY_US;
1598        info.mMem = mem;
1599        info.mMediaBuffer = NULL;
1600
1601        if (portIndex == kPortIndexOutput) {
1602            if (!(mOMXLivesLocally
1603                        && (mQuirks & kRequiresAllocateBufferOnOutputPorts)
1604                        && (mQuirks & kDefersOutputBufferAllocation))) {
1605                // If the node does not fill in the buffer ptr at this time,
1606                // we will defer creating the MediaBuffer until receiving
1607                // the first FILL_BUFFER_DONE notification instead.
1608                info.mMediaBuffer = new MediaBuffer(info.mData, info.mSize);
1609                info.mMediaBuffer->setObserver(this);
1610            }
1611        }
1612
1613        mPortBuffers[portIndex].push(info);
1614
1615        CODEC_LOGV("allocated buffer %p on %s port", buffer,
1616             portIndex == kPortIndexInput ? "input" : "output");
1617    }
1618
1619    if (portIndex == kPortIndexOutput) {
1620
1621        sp<MetaData> meta = mSource->getFormat();
1622        int32_t delay = 0;
1623        if (!meta->findInt32(kKeyEncoderDelay, &delay)) {
1624            delay = 0;
1625        }
1626        int32_t padding = 0;
1627        if (!meta->findInt32(kKeyEncoderPadding, &padding)) {
1628            padding = 0;
1629        }
1630        int32_t numchannels = 0;
1631        if (delay + padding) {
1632            if (mOutputFormat->findInt32(kKeyChannelCount, &numchannels)) {
1633                size_t frameSize = numchannels * sizeof(int16_t);
1634                if (mSkipCutBuffer != NULL) {
1635                    size_t prevbuffersize = mSkipCutBuffer->size();
1636                    if (prevbuffersize != 0) {
1637                        ALOGW("Replacing SkipCutBuffer holding %d bytes", prevbuffersize);
1638                    }
1639                }
1640                mSkipCutBuffer = new SkipCutBuffer(delay * frameSize, padding * frameSize);
1641            }
1642        }
1643    }
1644
1645    // dumpPortStatus(portIndex);
1646
1647    if (portIndex == kPortIndexInput && (mFlags & kUseSecureInputBuffers)) {
1648        Vector<MediaBuffer *> buffers;
1649        for (size_t i = 0; i < def.nBufferCountActual; ++i) {
1650            const BufferInfo &info = mPortBuffers[kPortIndexInput].itemAt(i);
1651
1652            MediaBuffer *mbuf = new MediaBuffer(info.mData, info.mSize);
1653            buffers.push(mbuf);
1654        }
1655
1656        status_t err = mSource->setBuffers(buffers);
1657
1658        if (err != OK) {
1659            for (size_t i = 0; i < def.nBufferCountActual; ++i) {
1660                buffers.editItemAt(i)->release();
1661            }
1662            buffers.clear();
1663
1664            CODEC_LOGE(
1665                    "Codec requested to use secure input buffers but "
1666                    "upstream source didn't support that.");
1667
1668            return err;
1669        }
1670    }
1671
1672    return OK;
1673}
1674
1675status_t OMXCodec::applyRotation() {
1676    sp<MetaData> meta = mSource->getFormat();
1677
1678    int32_t rotationDegrees;
1679    if (!meta->findInt32(kKeyRotation, &rotationDegrees)) {
1680        rotationDegrees = 0;
1681    }
1682
1683    uint32_t transform;
1684    switch (rotationDegrees) {
1685        case 0: transform = 0; break;
1686        case 90: transform = HAL_TRANSFORM_ROT_90; break;
1687        case 180: transform = HAL_TRANSFORM_ROT_180; break;
1688        case 270: transform = HAL_TRANSFORM_ROT_270; break;
1689        default: transform = 0; break;
1690    }
1691
1692    status_t err = OK;
1693
1694    if (transform) {
1695        err = native_window_set_buffers_transform(
1696                mNativeWindow.get(), transform);
1697        ALOGE("native_window_set_buffers_transform failed: %s (%d)",
1698                strerror(-err), -err);
1699    }
1700
1701    return err;
1702}
1703
1704status_t OMXCodec::allocateOutputBuffersFromNativeWindow() {
1705    // Get the number of buffers needed.
1706    OMX_PARAM_PORTDEFINITIONTYPE def;
1707    InitOMXParams(&def);
1708    def.nPortIndex = kPortIndexOutput;
1709
1710    status_t err = mOMX->getParameter(
1711            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1712    if (err != OK) {
1713        CODEC_LOGE("getParameter failed: %d", err);
1714        return err;
1715    }
1716
1717    err = native_window_set_buffers_geometry(
1718            mNativeWindow.get(),
1719            def.format.video.nFrameWidth,
1720            def.format.video.nFrameHeight,
1721            def.format.video.eColorFormat);
1722
1723    if (err != 0) {
1724        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
1725                strerror(-err), -err);
1726        return err;
1727    }
1728
1729    err = applyRotation();
1730    if (err != OK) {
1731        return err;
1732    }
1733
1734    // Set up the native window.
1735    OMX_U32 usage = 0;
1736    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
1737    if (err != 0) {
1738        ALOGW("querying usage flags from OMX IL component failed: %d", err);
1739        // XXX: Currently this error is logged, but not fatal.
1740        usage = 0;
1741    }
1742    if (mFlags & kEnableGrallocUsageProtected) {
1743        usage |= GRALLOC_USAGE_PROTECTED;
1744    }
1745
1746    // Make sure to check whether either Stagefright or the video decoder
1747    // requested protected buffers.
1748    if (usage & GRALLOC_USAGE_PROTECTED) {
1749        // Verify that the ANativeWindow sends images directly to
1750        // SurfaceFlinger.
1751        int queuesToNativeWindow = 0;
1752        err = mNativeWindow->query(
1753                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
1754                &queuesToNativeWindow);
1755        if (err != 0) {
1756            ALOGE("error authenticating native window: %d", err);
1757            return err;
1758        }
1759        if (queuesToNativeWindow != 1) {
1760            ALOGE("native window could not be authenticated");
1761            return PERMISSION_DENIED;
1762        }
1763    }
1764
1765    ALOGV("native_window_set_usage usage=0x%lx", usage);
1766    err = native_window_set_usage(
1767            mNativeWindow.get(), usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
1768    if (err != 0) {
1769        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
1770        return err;
1771    }
1772
1773    int minUndequeuedBufs = 0;
1774    err = mNativeWindow->query(mNativeWindow.get(),
1775            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
1776    if (err != 0) {
1777        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
1778                strerror(-err), -err);
1779        return err;
1780    }
1781    // FIXME: assume that surface is controlled by app (native window
1782    // returns the number for the case when surface is not controlled by app)
1783    minUndequeuedBufs++;
1784
1785    // Use conservative allocation while also trying to reduce starvation
1786    //
1787    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
1788    //    minimum needed for the consumer to be able to work
1789    // 2. try to allocate two (2) additional buffers to reduce starvation from
1790    //    the consumer
1791    CODEC_LOGI("OMX-buffers: min=%u actual=%u undeq=%d",
1792            def.nBufferCountMin, def.nBufferCountActual, minUndequeuedBufs);
1793
1794    for (OMX_U32 extraBuffers = 2; /* condition inside loop */; extraBuffers--) {
1795        OMX_U32 newBufferCount =
1796            def.nBufferCountMin + minUndequeuedBufs + extraBuffers;
1797        def.nBufferCountActual = newBufferCount;
1798        err = mOMX->setParameter(
1799                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1800
1801        if (err == OK) {
1802            minUndequeuedBufs += extraBuffers;
1803            break;
1804        }
1805
1806        CODEC_LOGW("setting nBufferCountActual to %lu failed: %d",
1807                newBufferCount, err);
1808        /* exit condition */
1809        if (extraBuffers == 0) {
1810            return err;
1811        }
1812    }
1813    CODEC_LOGI("OMX-buffers: min=%u actual=%u undeq=%d",
1814            def.nBufferCountMin, def.nBufferCountActual, minUndequeuedBufs);
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 %lu buffers from a native window of size %lu 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 %p (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 %p", 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: %p)", 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 %p, 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 %p", 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: %p, size: %ld, flags: 0x%08lx, 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 %p, 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 %p", 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()->setPointer(
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("ERROR(0x%08lx, %ld)", data1, data2);
2404
2405            setState(ERROR);
2406            break;
2407        }
2408
2409        case OMX_EventPortSettingsChanged:
2410        {
2411            CODEC_LOGV("OMX_EventPortSettingsChanged(port=%ld, data2=0x%08lx)",
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%lx/0x%lx",
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, %ld, %ld)", 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(%ld)", 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(%ld) 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(%ld)", 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(%ld)", 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
3512void OMXCodec::setG711Format(int32_t numChannels) {
3513    CHECK(!mIsEncoder);
3514    setRawAudioFormat(kPortIndexInput, 8000, numChannels);
3515}
3516
3517void OMXCodec::setImageOutputFormat(
3518        OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) {
3519    CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height);
3520
3521#if 0
3522    OMX_INDEXTYPE index;
3523    status_t err = mOMX->get_extension_index(
3524            mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index);
3525    CHECK_EQ(err, (status_t)OK);
3526
3527    err = mOMX->set_config(mNode, index, &format, sizeof(format));
3528    CHECK_EQ(err, (status_t)OK);
3529#endif
3530
3531    OMX_PARAM_PORTDEFINITIONTYPE def;
3532    InitOMXParams(&def);
3533    def.nPortIndex = kPortIndexOutput;
3534
3535    status_t err = mOMX->getParameter(
3536            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3537    CHECK_EQ(err, (status_t)OK);
3538
3539    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainImage);
3540
3541    OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
3542
3543    CHECK_EQ((int)imageDef->eCompressionFormat, (int)OMX_IMAGE_CodingUnused);
3544    imageDef->eColorFormat = format;
3545    imageDef->nFrameWidth = width;
3546    imageDef->nFrameHeight = height;
3547
3548    switch (format) {
3549        case OMX_COLOR_FormatYUV420PackedPlanar:
3550        case OMX_COLOR_FormatYUV411Planar:
3551        {
3552            def.nBufferSize = (width * height * 3) / 2;
3553            break;
3554        }
3555
3556        case OMX_COLOR_FormatCbYCrY:
3557        {
3558            def.nBufferSize = width * height * 2;
3559            break;
3560        }
3561
3562        case OMX_COLOR_Format32bitARGB8888:
3563        {
3564            def.nBufferSize = width * height * 4;
3565            break;
3566        }
3567
3568        case OMX_COLOR_Format16bitARGB4444:
3569        case OMX_COLOR_Format16bitARGB1555:
3570        case OMX_COLOR_Format16bitRGB565:
3571        case OMX_COLOR_Format16bitBGR565:
3572        {
3573            def.nBufferSize = width * height * 2;
3574            break;
3575        }
3576
3577        default:
3578            CHECK(!"Should not be here. Unknown color format.");
3579            break;
3580    }
3581
3582    def.nBufferCountActual = def.nBufferCountMin;
3583
3584    err = mOMX->setParameter(
3585            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3586    CHECK_EQ(err, (status_t)OK);
3587}
3588
3589void OMXCodec::setJPEGInputFormat(
3590        OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) {
3591    OMX_PARAM_PORTDEFINITIONTYPE def;
3592    InitOMXParams(&def);
3593    def.nPortIndex = kPortIndexInput;
3594
3595    status_t err = mOMX->getParameter(
3596            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3597    CHECK_EQ(err, (status_t)OK);
3598
3599    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainImage);
3600    OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
3601
3602    CHECK_EQ((int)imageDef->eCompressionFormat, (int)OMX_IMAGE_CodingJPEG);
3603    imageDef->nFrameWidth = width;
3604    imageDef->nFrameHeight = height;
3605
3606    def.nBufferSize = compressedSize;
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::addCodecSpecificData(const void *data, size_t size) {
3615    CodecSpecificData *specific =
3616        (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1);
3617
3618    specific->mSize = size;
3619    memcpy(specific->mData, data, size);
3620
3621    mCodecSpecificData.push(specific);
3622}
3623
3624void OMXCodec::clearCodecSpecificData() {
3625    for (size_t i = 0; i < mCodecSpecificData.size(); ++i) {
3626        free(mCodecSpecificData.editItemAt(i));
3627    }
3628    mCodecSpecificData.clear();
3629    mCodecSpecificDataIndex = 0;
3630}
3631
3632status_t OMXCodec::start(MetaData *meta) {
3633    Mutex::Autolock autoLock(mLock);
3634
3635    if (mState != LOADED) {
3636        CODEC_LOGE("called start in the unexpected state: %d", mState);
3637        return UNKNOWN_ERROR;
3638    }
3639
3640    sp<MetaData> params = new MetaData;
3641    if (mQuirks & kWantsNALFragments) {
3642        params->setInt32(kKeyWantsNALFragments, true);
3643    }
3644    if (meta) {
3645        int64_t startTimeUs = 0;
3646        int64_t timeUs;
3647        if (meta->findInt64(kKeyTime, &timeUs)) {
3648            startTimeUs = timeUs;
3649        }
3650        params->setInt64(kKeyTime, startTimeUs);
3651    }
3652
3653    mCodecSpecificDataIndex = 0;
3654    mInitialBufferSubmit = true;
3655    mSignalledEOS = false;
3656    mNoMoreOutputData = false;
3657    mOutputPortSettingsHaveChanged = false;
3658    mSeekTimeUs = -1;
3659    mSeekMode = ReadOptions::SEEK_CLOSEST_SYNC;
3660    mTargetTimeUs = -1;
3661    mFilledBuffers.clear();
3662    mPaused = false;
3663
3664    status_t err;
3665    if (mIsEncoder) {
3666        // Calling init() before starting its source so that we can configure,
3667        // if supported, the source to use exactly the same number of input
3668        // buffers as requested by the encoder.
3669        if ((err = init()) != OK) {
3670            CODEC_LOGE("init failed: %d", err);
3671            return err;
3672        }
3673
3674        params->setInt32(kKeyNumBuffers, mPortBuffers[kPortIndexInput].size());
3675        err = mSource->start(params.get());
3676        if (err != OK) {
3677            CODEC_LOGE("source failed to start: %d", err);
3678            stopOmxComponent_l();
3679        }
3680        return err;
3681    }
3682
3683    // Decoder case
3684    if ((err = mSource->start(params.get())) != OK) {
3685        CODEC_LOGE("source failed to start: %d", err);
3686        return err;
3687    }
3688    return init();
3689}
3690
3691status_t OMXCodec::stop() {
3692    CODEC_LOGV("stop mState=%d", mState);
3693    Mutex::Autolock autoLock(mLock);
3694    status_t err = stopOmxComponent_l();
3695    mSource->stop();
3696
3697    CODEC_LOGV("stopped in state %d", mState);
3698    return err;
3699}
3700
3701status_t OMXCodec::stopOmxComponent_l() {
3702    CODEC_LOGV("stopOmxComponent_l mState=%d", mState);
3703
3704    while (isIntermediateState(mState)) {
3705        mAsyncCompletion.wait(mLock);
3706    }
3707
3708    bool isError = false;
3709    switch (mState) {
3710        case LOADED:
3711            break;
3712
3713        case ERROR:
3714        {
3715            if (mPortStatus[kPortIndexOutput] == ENABLING) {
3716                // Codec is in a wedged state (technical term)
3717                // We've seen an output port settings change from the codec,
3718                // We've disabled the output port, then freed the output
3719                // buffers, initiated re-enabling the output port but
3720                // failed to reallocate the output buffers.
3721                // There doesn't seem to be a way to orderly transition
3722                // from executing->idle and idle->loaded now that the
3723                // output port hasn't been reenabled yet...
3724                // Simply free as many resources as we can and pretend
3725                // that we're in LOADED state so that the destructor
3726                // will free the component instance without asserting.
3727                freeBuffersOnPort(kPortIndexInput, true /* onlyThoseWeOwn */);
3728                freeBuffersOnPort(kPortIndexOutput, true /* onlyThoseWeOwn */);
3729                setState(LOADED);
3730                break;
3731            } else {
3732                OMX_STATETYPE state = OMX_StateInvalid;
3733                status_t err = mOMX->getState(mNode, &state);
3734                CHECK_EQ(err, (status_t)OK);
3735
3736                if (state != OMX_StateExecuting) {
3737                    break;
3738                }
3739                // else fall through to the idling code
3740            }
3741
3742            isError = true;
3743        }
3744
3745        case EXECUTING:
3746        {
3747            setState(EXECUTING_TO_IDLE);
3748
3749            if (mQuirks & kRequiresFlushBeforeShutdown) {
3750                CODEC_LOGV("This component requires a flush before transitioning "
3751                     "from EXECUTING to IDLE...");
3752
3753                bool emulateInputFlushCompletion =
3754                    !flushPortAsync(kPortIndexInput);
3755
3756                bool emulateOutputFlushCompletion =
3757                    !flushPortAsync(kPortIndexOutput);
3758
3759                if (emulateInputFlushCompletion) {
3760                    onCmdComplete(OMX_CommandFlush, kPortIndexInput);
3761                }
3762
3763                if (emulateOutputFlushCompletion) {
3764                    onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
3765                }
3766            } else {
3767                mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
3768                mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
3769
3770                status_t err =
3771                    mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
3772                CHECK_EQ(err, (status_t)OK);
3773            }
3774
3775            while (mState != LOADED && mState != ERROR) {
3776                mAsyncCompletion.wait(mLock);
3777            }
3778
3779            if (isError) {
3780                // We were in the ERROR state coming in, so restore that now
3781                // that we've idled the OMX component.
3782                setState(ERROR);
3783            }
3784
3785            break;
3786        }
3787
3788        default:
3789        {
3790            CHECK(!"should not be here.");
3791            break;
3792        }
3793    }
3794
3795    if (mLeftOverBuffer) {
3796        mLeftOverBuffer->release();
3797        mLeftOverBuffer = NULL;
3798    }
3799
3800    return OK;
3801}
3802
3803sp<MetaData> OMXCodec::getFormat() {
3804    Mutex::Autolock autoLock(mLock);
3805
3806    return mOutputFormat;
3807}
3808
3809status_t OMXCodec::read(
3810        MediaBuffer **buffer, const ReadOptions *options) {
3811    status_t err = OK;
3812    *buffer = NULL;
3813
3814    Mutex::Autolock autoLock(mLock);
3815
3816    if (mState != EXECUTING && mState != RECONFIGURING) {
3817        return UNKNOWN_ERROR;
3818    }
3819
3820    bool seeking = false;
3821    int64_t seekTimeUs;
3822    ReadOptions::SeekMode seekMode;
3823    if (options && options->getSeekTo(&seekTimeUs, &seekMode)) {
3824        seeking = true;
3825    }
3826
3827    if (mInitialBufferSubmit) {
3828        mInitialBufferSubmit = false;
3829
3830        if (seeking) {
3831            CHECK(seekTimeUs >= 0);
3832            mSeekTimeUs = seekTimeUs;
3833            mSeekMode = seekMode;
3834
3835            // There's no reason to trigger the code below, there's
3836            // nothing to flush yet.
3837            seeking = false;
3838            mPaused = false;
3839        }
3840
3841        drainInputBuffers();
3842
3843        if (mState == EXECUTING) {
3844            // Otherwise mState == RECONFIGURING and this code will trigger
3845            // after the output port is reenabled.
3846            fillOutputBuffers();
3847        }
3848    }
3849
3850    if (seeking) {
3851        while (mState == RECONFIGURING) {
3852            if ((err = waitForBufferFilled_l()) != OK) {
3853                return err;
3854            }
3855        }
3856
3857        if (mState != EXECUTING) {
3858            return UNKNOWN_ERROR;
3859        }
3860
3861        CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6);
3862
3863        mSignalledEOS = false;
3864
3865        CHECK(seekTimeUs >= 0);
3866        mSeekTimeUs = seekTimeUs;
3867        mSeekMode = seekMode;
3868
3869        mFilledBuffers.clear();
3870
3871        CHECK_EQ((int)mState, (int)EXECUTING);
3872
3873        bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput);
3874        bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput);
3875
3876        if (emulateInputFlushCompletion) {
3877            onCmdComplete(OMX_CommandFlush, kPortIndexInput);
3878        }
3879
3880        if (emulateOutputFlushCompletion) {
3881            onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
3882        }
3883
3884        while (mSeekTimeUs >= 0) {
3885            if ((err = waitForBufferFilled_l()) != OK) {
3886                return err;
3887            }
3888        }
3889    }
3890
3891    while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) {
3892        if ((err = waitForBufferFilled_l()) != OK) {
3893            return err;
3894        }
3895    }
3896
3897    if (mState == ERROR) {
3898        return UNKNOWN_ERROR;
3899    }
3900
3901    if (mFilledBuffers.empty()) {
3902        return mSignalledEOS ? mFinalStatus : ERROR_END_OF_STREAM;
3903    }
3904
3905    if (mOutputPortSettingsHaveChanged) {
3906        mOutputPortSettingsHaveChanged = false;
3907
3908        return INFO_FORMAT_CHANGED;
3909    }
3910
3911    size_t index = *mFilledBuffers.begin();
3912    mFilledBuffers.erase(mFilledBuffers.begin());
3913
3914    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
3915    CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
3916    info->mStatus = OWNED_BY_CLIENT;
3917
3918    info->mMediaBuffer->add_ref();
3919    if (mSkipCutBuffer != NULL) {
3920        mSkipCutBuffer->submit(info->mMediaBuffer);
3921    }
3922    *buffer = info->mMediaBuffer;
3923
3924    return OK;
3925}
3926
3927void OMXCodec::signalBufferReturned(MediaBuffer *buffer) {
3928    Mutex::Autolock autoLock(mLock);
3929
3930    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
3931    for (size_t i = 0; i < buffers->size(); ++i) {
3932        BufferInfo *info = &buffers->editItemAt(i);
3933
3934        if (info->mMediaBuffer == buffer) {
3935            CHECK_EQ((int)mPortStatus[kPortIndexOutput], (int)ENABLED);
3936            CHECK_EQ((int)info->mStatus, (int)OWNED_BY_CLIENT);
3937
3938            info->mStatus = OWNED_BY_US;
3939
3940            if (buffer->graphicBuffer() == 0) {
3941                fillOutputBuffer(info);
3942            } else {
3943                sp<MetaData> metaData = info->mMediaBuffer->meta_data();
3944                int32_t rendered = 0;
3945                if (!metaData->findInt32(kKeyRendered, &rendered)) {
3946                    rendered = 0;
3947                }
3948                if (!rendered) {
3949                    status_t err = cancelBufferToNativeWindow(info);
3950                    if (err < 0) {
3951                        return;
3952                    }
3953                }
3954
3955                info->mStatus = OWNED_BY_NATIVE_WINDOW;
3956
3957                // Dequeue the next buffer from the native window.
3958                BufferInfo *nextBufInfo = dequeueBufferFromNativeWindow();
3959                if (nextBufInfo == 0) {
3960                    return;
3961                }
3962
3963                // Give the buffer to the OMX node to fill.
3964                fillOutputBuffer(nextBufInfo);
3965            }
3966            return;
3967        }
3968    }
3969
3970    CHECK(!"should not be here.");
3971}
3972
3973static const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) {
3974    static const char *kNames[] = {
3975        "OMX_IMAGE_CodingUnused",
3976        "OMX_IMAGE_CodingAutoDetect",
3977        "OMX_IMAGE_CodingJPEG",
3978        "OMX_IMAGE_CodingJPEG2K",
3979        "OMX_IMAGE_CodingEXIF",
3980        "OMX_IMAGE_CodingTIFF",
3981        "OMX_IMAGE_CodingGIF",
3982        "OMX_IMAGE_CodingPNG",
3983        "OMX_IMAGE_CodingLZW",
3984        "OMX_IMAGE_CodingBMP",
3985    };
3986
3987    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
3988
3989    if (type < 0 || (size_t)type >= numNames) {
3990        return "UNKNOWN";
3991    } else {
3992        return kNames[type];
3993    }
3994}
3995
3996static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) {
3997    static const char *kNames[] = {
3998        "OMX_COLOR_FormatUnused",
3999        "OMX_COLOR_FormatMonochrome",
4000        "OMX_COLOR_Format8bitRGB332",
4001        "OMX_COLOR_Format12bitRGB444",
4002        "OMX_COLOR_Format16bitARGB4444",
4003        "OMX_COLOR_Format16bitARGB1555",
4004        "OMX_COLOR_Format16bitRGB565",
4005        "OMX_COLOR_Format16bitBGR565",
4006        "OMX_COLOR_Format18bitRGB666",
4007        "OMX_COLOR_Format18bitARGB1665",
4008        "OMX_COLOR_Format19bitARGB1666",
4009        "OMX_COLOR_Format24bitRGB888",
4010        "OMX_COLOR_Format24bitBGR888",
4011        "OMX_COLOR_Format24bitARGB1887",
4012        "OMX_COLOR_Format25bitARGB1888",
4013        "OMX_COLOR_Format32bitBGRA8888",
4014        "OMX_COLOR_Format32bitARGB8888",
4015        "OMX_COLOR_FormatYUV411Planar",
4016        "OMX_COLOR_FormatYUV411PackedPlanar",
4017        "OMX_COLOR_FormatYUV420Planar",
4018        "OMX_COLOR_FormatYUV420PackedPlanar",
4019        "OMX_COLOR_FormatYUV420SemiPlanar",
4020        "OMX_COLOR_FormatYUV422Planar",
4021        "OMX_COLOR_FormatYUV422PackedPlanar",
4022        "OMX_COLOR_FormatYUV422SemiPlanar",
4023        "OMX_COLOR_FormatYCbYCr",
4024        "OMX_COLOR_FormatYCrYCb",
4025        "OMX_COLOR_FormatCbYCrY",
4026        "OMX_COLOR_FormatCrYCbY",
4027        "OMX_COLOR_FormatYUV444Interleaved",
4028        "OMX_COLOR_FormatRawBayer8bit",
4029        "OMX_COLOR_FormatRawBayer10bit",
4030        "OMX_COLOR_FormatRawBayer8bitcompressed",
4031        "OMX_COLOR_FormatL2",
4032        "OMX_COLOR_FormatL4",
4033        "OMX_COLOR_FormatL8",
4034        "OMX_COLOR_FormatL16",
4035        "OMX_COLOR_FormatL24",
4036        "OMX_COLOR_FormatL32",
4037        "OMX_COLOR_FormatYUV420PackedSemiPlanar",
4038        "OMX_COLOR_FormatYUV422PackedSemiPlanar",
4039        "OMX_COLOR_Format18BitBGR666",
4040        "OMX_COLOR_Format24BitARGB6666",
4041        "OMX_COLOR_Format24BitABGR6666",
4042    };
4043
4044    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
4045
4046    if (type == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
4047        return "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar";
4048    } else if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) {
4049        return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar";
4050    } else if (type < 0 || (size_t)type >= numNames) {
4051        return "UNKNOWN";
4052    } else {
4053        return kNames[type];
4054    }
4055}
4056
4057static const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) {
4058    static const char *kNames[] = {
4059        "OMX_VIDEO_CodingUnused",
4060        "OMX_VIDEO_CodingAutoDetect",
4061        "OMX_VIDEO_CodingMPEG2",
4062        "OMX_VIDEO_CodingH263",
4063        "OMX_VIDEO_CodingMPEG4",
4064        "OMX_VIDEO_CodingWMV",
4065        "OMX_VIDEO_CodingRV",
4066        "OMX_VIDEO_CodingAVC",
4067        "OMX_VIDEO_CodingMJPEG",
4068    };
4069
4070    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
4071
4072    if (type < 0 || (size_t)type >= numNames) {
4073        return "UNKNOWN";
4074    } else {
4075        return kNames[type];
4076    }
4077}
4078
4079static const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) {
4080    static const char *kNames[] = {
4081        "OMX_AUDIO_CodingUnused",
4082        "OMX_AUDIO_CodingAutoDetect",
4083        "OMX_AUDIO_CodingPCM",
4084        "OMX_AUDIO_CodingADPCM",
4085        "OMX_AUDIO_CodingAMR",
4086        "OMX_AUDIO_CodingGSMFR",
4087        "OMX_AUDIO_CodingGSMEFR",
4088        "OMX_AUDIO_CodingGSMHR",
4089        "OMX_AUDIO_CodingPDCFR",
4090        "OMX_AUDIO_CodingPDCEFR",
4091        "OMX_AUDIO_CodingPDCHR",
4092        "OMX_AUDIO_CodingTDMAFR",
4093        "OMX_AUDIO_CodingTDMAEFR",
4094        "OMX_AUDIO_CodingQCELP8",
4095        "OMX_AUDIO_CodingQCELP13",
4096        "OMX_AUDIO_CodingEVRC",
4097        "OMX_AUDIO_CodingSMV",
4098        "OMX_AUDIO_CodingG711",
4099        "OMX_AUDIO_CodingG723",
4100        "OMX_AUDIO_CodingG726",
4101        "OMX_AUDIO_CodingG729",
4102        "OMX_AUDIO_CodingAAC",
4103        "OMX_AUDIO_CodingMP3",
4104        "OMX_AUDIO_CodingSBC",
4105        "OMX_AUDIO_CodingVORBIS",
4106        "OMX_AUDIO_CodingWMA",
4107        "OMX_AUDIO_CodingRA",
4108        "OMX_AUDIO_CodingMIDI",
4109    };
4110
4111    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
4112
4113    if (type < 0 || (size_t)type >= numNames) {
4114        return "UNKNOWN";
4115    } else {
4116        return kNames[type];
4117    }
4118}
4119
4120static const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) {
4121    static const char *kNames[] = {
4122        "OMX_AUDIO_PCMModeLinear",
4123        "OMX_AUDIO_PCMModeALaw",
4124        "OMX_AUDIO_PCMModeMULaw",
4125    };
4126
4127    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
4128
4129    if (type < 0 || (size_t)type >= numNames) {
4130        return "UNKNOWN";
4131    } else {
4132        return kNames[type];
4133    }
4134}
4135
4136static const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) {
4137    static const char *kNames[] = {
4138        "OMX_AUDIO_AMRBandModeUnused",
4139        "OMX_AUDIO_AMRBandModeNB0",
4140        "OMX_AUDIO_AMRBandModeNB1",
4141        "OMX_AUDIO_AMRBandModeNB2",
4142        "OMX_AUDIO_AMRBandModeNB3",
4143        "OMX_AUDIO_AMRBandModeNB4",
4144        "OMX_AUDIO_AMRBandModeNB5",
4145        "OMX_AUDIO_AMRBandModeNB6",
4146        "OMX_AUDIO_AMRBandModeNB7",
4147        "OMX_AUDIO_AMRBandModeWB0",
4148        "OMX_AUDIO_AMRBandModeWB1",
4149        "OMX_AUDIO_AMRBandModeWB2",
4150        "OMX_AUDIO_AMRBandModeWB3",
4151        "OMX_AUDIO_AMRBandModeWB4",
4152        "OMX_AUDIO_AMRBandModeWB5",
4153        "OMX_AUDIO_AMRBandModeWB6",
4154        "OMX_AUDIO_AMRBandModeWB7",
4155        "OMX_AUDIO_AMRBandModeWB8",
4156    };
4157
4158    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
4159
4160    if (type < 0 || (size_t)type >= numNames) {
4161        return "UNKNOWN";
4162    } else {
4163        return kNames[type];
4164    }
4165}
4166
4167static const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) {
4168    static const char *kNames[] = {
4169        "OMX_AUDIO_AMRFrameFormatConformance",
4170        "OMX_AUDIO_AMRFrameFormatIF1",
4171        "OMX_AUDIO_AMRFrameFormatIF2",
4172        "OMX_AUDIO_AMRFrameFormatFSF",
4173        "OMX_AUDIO_AMRFrameFormatRTPPayload",
4174        "OMX_AUDIO_AMRFrameFormatITU",
4175    };
4176
4177    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
4178
4179    if (type < 0 || (size_t)type >= numNames) {
4180        return "UNKNOWN";
4181    } else {
4182        return kNames[type];
4183    }
4184}
4185
4186void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
4187    OMX_PARAM_PORTDEFINITIONTYPE def;
4188    InitOMXParams(&def);
4189    def.nPortIndex = portIndex;
4190
4191    status_t err = mOMX->getParameter(
4192            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
4193    CHECK_EQ(err, (status_t)OK);
4194
4195    printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output");
4196
4197    CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput)
4198          || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput));
4199
4200    printf("  nBufferCountActual = %ld\n", def.nBufferCountActual);
4201    printf("  nBufferCountMin = %ld\n", def.nBufferCountMin);
4202    printf("  nBufferSize = %ld\n", def.nBufferSize);
4203
4204    switch (def.eDomain) {
4205        case OMX_PortDomainImage:
4206        {
4207            const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
4208
4209            printf("\n");
4210            printf("  // Image\n");
4211            printf("  nFrameWidth = %ld\n", imageDef->nFrameWidth);
4212            printf("  nFrameHeight = %ld\n", imageDef->nFrameHeight);
4213            printf("  nStride = %ld\n", imageDef->nStride);
4214
4215            printf("  eCompressionFormat = %s\n",
4216                   imageCompressionFormatString(imageDef->eCompressionFormat));
4217
4218            printf("  eColorFormat = %s\n",
4219                   colorFormatString(imageDef->eColorFormat));
4220
4221            break;
4222        }
4223
4224        case OMX_PortDomainVideo:
4225        {
4226            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
4227
4228            printf("\n");
4229            printf("  // Video\n");
4230            printf("  nFrameWidth = %ld\n", videoDef->nFrameWidth);
4231            printf("  nFrameHeight = %ld\n", videoDef->nFrameHeight);
4232            printf("  nStride = %ld\n", videoDef->nStride);
4233
4234            printf("  eCompressionFormat = %s\n",
4235                   videoCompressionFormatString(videoDef->eCompressionFormat));
4236
4237            printf("  eColorFormat = %s\n",
4238                   colorFormatString(videoDef->eColorFormat));
4239
4240            break;
4241        }
4242
4243        case OMX_PortDomainAudio:
4244        {
4245            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
4246
4247            printf("\n");
4248            printf("  // Audio\n");
4249            printf("  eEncoding = %s\n",
4250                   audioCodingTypeString(audioDef->eEncoding));
4251
4252            if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) {
4253                OMX_AUDIO_PARAM_PCMMODETYPE params;
4254                InitOMXParams(&params);
4255                params.nPortIndex = portIndex;
4256
4257                err = mOMX->getParameter(
4258                        mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4259                CHECK_EQ(err, (status_t)OK);
4260
4261                printf("  nSamplingRate = %ld\n", params.nSamplingRate);
4262                printf("  nChannels = %ld\n", params.nChannels);
4263                printf("  bInterleaved = %d\n", params.bInterleaved);
4264                printf("  nBitPerSample = %ld\n", params.nBitPerSample);
4265
4266                printf("  eNumData = %s\n",
4267                       params.eNumData == OMX_NumericalDataSigned
4268                        ? "signed" : "unsigned");
4269
4270                printf("  ePCMMode = %s\n", audioPCMModeString(params.ePCMMode));
4271            } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) {
4272                OMX_AUDIO_PARAM_AMRTYPE amr;
4273                InitOMXParams(&amr);
4274                amr.nPortIndex = portIndex;
4275
4276                err = mOMX->getParameter(
4277                        mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
4278                CHECK_EQ(err, (status_t)OK);
4279
4280                printf("  nChannels = %ld\n", amr.nChannels);
4281                printf("  eAMRBandMode = %s\n",
4282                        amrBandModeString(amr.eAMRBandMode));
4283                printf("  eAMRFrameFormat = %s\n",
4284                        amrFrameFormatString(amr.eAMRFrameFormat));
4285            }
4286
4287            break;
4288        }
4289
4290        default:
4291        {
4292            printf("  // Unknown\n");
4293            break;
4294        }
4295    }
4296
4297    printf("}\n");
4298}
4299
4300status_t OMXCodec::initNativeWindow() {
4301    // Enable use of a GraphicBuffer as the output for this node.  This must
4302    // happen before getting the IndexParamPortDefinition parameter because it
4303    // will affect the pixel format that the node reports.
4304    status_t err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
4305    if (err != 0) {
4306        return err;
4307    }
4308
4309    return OK;
4310}
4311
4312void OMXCodec::initNativeWindowCrop() {
4313    int32_t left, top, right, bottom;
4314
4315    CHECK(mOutputFormat->findRect(
4316                        kKeyCropRect,
4317                        &left, &top, &right, &bottom));
4318
4319    android_native_rect_t crop;
4320    crop.left = left;
4321    crop.top = top;
4322    crop.right = right + 1;
4323    crop.bottom = bottom + 1;
4324
4325    // We'll ignore any errors here, if the surface is
4326    // already invalid, we'll know soon enough.
4327    native_window_set_crop(mNativeWindow.get(), &crop);
4328}
4329
4330void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
4331    mOutputFormat = new MetaData;
4332    mOutputFormat->setCString(kKeyDecoderComponent, mComponentName);
4333    if (mIsEncoder) {
4334        int32_t timeScale;
4335        if (inputFormat->findInt32(kKeyTimeScale, &timeScale)) {
4336            mOutputFormat->setInt32(kKeyTimeScale, timeScale);
4337        }
4338    }
4339
4340    OMX_PARAM_PORTDEFINITIONTYPE def;
4341    InitOMXParams(&def);
4342    def.nPortIndex = kPortIndexOutput;
4343
4344    status_t err = mOMX->getParameter(
4345            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
4346    CHECK_EQ(err, (status_t)OK);
4347
4348    switch (def.eDomain) {
4349        case OMX_PortDomainImage:
4350        {
4351            OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
4352            CHECK_EQ((int)imageDef->eCompressionFormat,
4353                     (int)OMX_IMAGE_CodingUnused);
4354
4355            mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
4356            mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat);
4357            mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth);
4358            mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight);
4359            break;
4360        }
4361
4362        case OMX_PortDomainAudio:
4363        {
4364            OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio;
4365
4366            if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) {
4367                OMX_AUDIO_PARAM_PCMMODETYPE params;
4368                InitOMXParams(&params);
4369                params.nPortIndex = kPortIndexOutput;
4370
4371                err = mOMX->getParameter(
4372                        mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4373                CHECK_EQ(err, (status_t)OK);
4374
4375                CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned);
4376                CHECK_EQ(params.nBitPerSample, 16u);
4377                CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear);
4378
4379                int32_t numChannels, sampleRate;
4380                inputFormat->findInt32(kKeyChannelCount, &numChannels);
4381                inputFormat->findInt32(kKeySampleRate, &sampleRate);
4382
4383                if ((OMX_U32)numChannels != params.nChannels) {
4384                    ALOGV("Codec outputs a different number of channels than "
4385                         "the input stream contains (contains %d channels, "
4386                         "codec outputs %ld channels).",
4387                         numChannels, params.nChannels);
4388                }
4389
4390                if (sampleRate != (int32_t)params.nSamplingRate) {
4391                    ALOGV("Codec outputs at different sampling rate than "
4392                         "what the input stream contains (contains data at "
4393                         "%d Hz, codec outputs %lu Hz)",
4394                         sampleRate, params.nSamplingRate);
4395                }
4396
4397                mOutputFormat->setCString(
4398                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
4399
4400                // Use the codec-advertised number of channels, as some
4401                // codecs appear to output stereo even if the input data is
4402                // mono. If we know the codec lies about this information,
4403                // use the actual number of channels instead.
4404                mOutputFormat->setInt32(
4405                        kKeyChannelCount,
4406                        (mQuirks & kDecoderLiesAboutNumberOfChannels)
4407                            ? numChannels : params.nChannels);
4408
4409                mOutputFormat->setInt32(kKeySampleRate, params.nSamplingRate);
4410            } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) {
4411                OMX_AUDIO_PARAM_AMRTYPE amr;
4412                InitOMXParams(&amr);
4413                amr.nPortIndex = kPortIndexOutput;
4414
4415                err = mOMX->getParameter(
4416                        mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
4417                CHECK_EQ(err, (status_t)OK);
4418
4419                CHECK_EQ(amr.nChannels, 1u);
4420                mOutputFormat->setInt32(kKeyChannelCount, 1);
4421
4422                if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0
4423                    && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) {
4424                    mOutputFormat->setCString(
4425                            kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB);
4426                    mOutputFormat->setInt32(kKeySampleRate, 8000);
4427                } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0
4428                            && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) {
4429                    mOutputFormat->setCString(
4430                            kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB);
4431                    mOutputFormat->setInt32(kKeySampleRate, 16000);
4432                } else {
4433                    CHECK(!"Unknown AMR band mode.");
4434                }
4435            } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) {
4436                mOutputFormat->setCString(
4437                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
4438                int32_t numChannels, sampleRate, bitRate;
4439                inputFormat->findInt32(kKeyChannelCount, &numChannels);
4440                inputFormat->findInt32(kKeySampleRate, &sampleRate);
4441                inputFormat->findInt32(kKeyBitRate, &bitRate);
4442                mOutputFormat->setInt32(kKeyChannelCount, numChannels);
4443                mOutputFormat->setInt32(kKeySampleRate, sampleRate);
4444                mOutputFormat->setInt32(kKeyBitRate, bitRate);
4445            } else {
4446                CHECK(!"Should not be here. Unknown audio encoding.");
4447            }
4448            break;
4449        }
4450
4451        case OMX_PortDomainVideo:
4452        {
4453            OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
4454
4455            if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) {
4456                mOutputFormat->setCString(
4457                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
4458            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) {
4459                mOutputFormat->setCString(
4460                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
4461            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) {
4462                mOutputFormat->setCString(
4463                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
4464            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) {
4465                mOutputFormat->setCString(
4466                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
4467            } else {
4468                CHECK(!"Unknown compression format.");
4469            }
4470
4471            mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth);
4472            mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight);
4473            mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat);
4474
4475            if (!mIsEncoder) {
4476                OMX_CONFIG_RECTTYPE rect;
4477                InitOMXParams(&rect);
4478                rect.nPortIndex = kPortIndexOutput;
4479                status_t err =
4480                        mOMX->getConfig(
4481                            mNode, OMX_IndexConfigCommonOutputCrop,
4482                            &rect, sizeof(rect));
4483
4484                CODEC_LOGI(
4485                        "video dimensions are %ld x %ld",
4486                        video_def->nFrameWidth, video_def->nFrameHeight);
4487
4488                if (err == OK) {
4489                    CHECK_GE(rect.nLeft, 0);
4490                    CHECK_GE(rect.nTop, 0);
4491                    CHECK_GE(rect.nWidth, 0u);
4492                    CHECK_GE(rect.nHeight, 0u);
4493                    CHECK_LE(rect.nLeft + rect.nWidth - 1, video_def->nFrameWidth);
4494                    CHECK_LE(rect.nTop + rect.nHeight - 1, video_def->nFrameHeight);
4495
4496                    mOutputFormat->setRect(
4497                            kKeyCropRect,
4498                            rect.nLeft,
4499                            rect.nTop,
4500                            rect.nLeft + rect.nWidth - 1,
4501                            rect.nTop + rect.nHeight - 1);
4502
4503                    CODEC_LOGI(
4504                            "Crop rect is %ld x %ld @ (%ld, %ld)",
4505                            rect.nWidth, rect.nHeight, rect.nLeft, rect.nTop);
4506                } else {
4507                    mOutputFormat->setRect(
4508                            kKeyCropRect,
4509                            0, 0,
4510                            video_def->nFrameWidth - 1,
4511                            video_def->nFrameHeight - 1);
4512                }
4513
4514                if (mNativeWindow != NULL) {
4515                     initNativeWindowCrop();
4516                }
4517            }
4518            break;
4519        }
4520
4521        default:
4522        {
4523            CHECK(!"should not be here, neither audio nor video.");
4524            break;
4525        }
4526    }
4527
4528    // If the input format contains rotation information, flag the output
4529    // format accordingly.
4530
4531    int32_t rotationDegrees;
4532    if (mSource->getFormat()->findInt32(kKeyRotation, &rotationDegrees)) {
4533        mOutputFormat->setInt32(kKeyRotation, rotationDegrees);
4534    }
4535}
4536
4537status_t OMXCodec::pause() {
4538    Mutex::Autolock autoLock(mLock);
4539
4540    mPaused = true;
4541
4542    return OK;
4543}
4544
4545////////////////////////////////////////////////////////////////////////////////
4546
4547status_t QueryCodecs(
4548        const sp<IOMX> &omx,
4549        const char *mime, bool queryDecoders, bool hwCodecOnly,
4550        Vector<CodecCapabilities> *results) {
4551    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
4552    results->clear();
4553
4554    OMXCodec::findMatchingCodecs(mime,
4555            !queryDecoders /*createEncoder*/,
4556            NULL /*matchComponentName*/,
4557            hwCodecOnly ? OMXCodec::kHardwareCodecsOnly : 0 /*flags*/,
4558            &matchingCodecs);
4559
4560    for (size_t c = 0; c < matchingCodecs.size(); c++) {
4561        const char *componentName = matchingCodecs.itemAt(c).mName.string();
4562
4563        results->push();
4564        CodecCapabilities *caps = &results->editItemAt(results->size() - 1);
4565
4566        status_t err =
4567            QueryCodec(omx, componentName, mime, !queryDecoders, caps);
4568
4569        if (err != OK) {
4570            results->removeAt(results->size() - 1);
4571        }
4572    }
4573
4574    return OK;
4575}
4576
4577status_t QueryCodec(
4578        const sp<IOMX> &omx,
4579        const char *componentName, const char *mime,
4580        bool isEncoder,
4581        CodecCapabilities *caps) {
4582    if (strncmp(componentName, "OMX.", 4)) {
4583        // Not an OpenMax component but a software codec.
4584        caps->mFlags = 0;
4585        caps->mComponentName = componentName;
4586        return OK;
4587    }
4588
4589    sp<OMXCodecObserver> observer = new OMXCodecObserver;
4590    IOMX::node_id node;
4591    status_t err = omx->allocateNode(componentName, observer, &node);
4592
4593    if (err != OK) {
4594        return err;
4595    }
4596
4597    OMXCodec::setComponentRole(omx, node, isEncoder, mime);
4598
4599    caps->mFlags = 0;
4600    caps->mComponentName = componentName;
4601
4602    OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
4603    InitOMXParams(&param);
4604
4605    param.nPortIndex = !isEncoder ? 0 : 1;
4606
4607    for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
4608        err = omx->getParameter(
4609                node, OMX_IndexParamVideoProfileLevelQuerySupported,
4610                &param, sizeof(param));
4611
4612        if (err != OK) {
4613            break;
4614        }
4615
4616        CodecProfileLevel profileLevel;
4617        profileLevel.mProfile = param.eProfile;
4618        profileLevel.mLevel = param.eLevel;
4619
4620        caps->mProfileLevels.push(profileLevel);
4621    }
4622
4623    // Color format query
4624    OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
4625    InitOMXParams(&portFormat);
4626    portFormat.nPortIndex = !isEncoder ? 1 : 0;
4627    for (portFormat.nIndex = 0;; ++portFormat.nIndex)  {
4628        err = omx->getParameter(
4629                node, OMX_IndexParamVideoPortFormat,
4630                &portFormat, sizeof(portFormat));
4631        if (err != OK) {
4632            break;
4633        }
4634        caps->mColorFormats.push(portFormat.eColorFormat);
4635    }
4636
4637    if (!isEncoder && !strncmp(mime, "video/", 6)) {
4638        if (omx->storeMetaDataInBuffers(
4639                    node, 1 /* port index */, OMX_TRUE) == OK ||
4640            omx->prepareForAdaptivePlayback(
4641                    node, 1 /* port index */, OMX_TRUE,
4642                    1280 /* width */, 720 /* height */) == OK) {
4643            caps->mFlags |= CodecCapabilities::kFlagSupportsAdaptivePlayback;
4644        }
4645    }
4646
4647    CHECK_EQ(omx->freeNode(node), (status_t)OK);
4648
4649    return OK;
4650}
4651
4652status_t QueryCodecs(
4653        const sp<IOMX> &omx,
4654        const char *mimeType, bool queryDecoders,
4655        Vector<CodecCapabilities> *results) {
4656    return QueryCodecs(omx, mimeType, queryDecoders, false /*hwCodecOnly*/, results);
4657}
4658
4659// These are supposed be equivalent to the logic in
4660// "audio_channel_out_mask_from_count".
4661status_t getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) {
4662    switch (numChannels) {
4663        case 1:
4664            map[0] = OMX_AUDIO_ChannelCF;
4665            break;
4666        case 2:
4667            map[0] = OMX_AUDIO_ChannelLF;
4668            map[1] = OMX_AUDIO_ChannelRF;
4669            break;
4670        case 3:
4671            map[0] = OMX_AUDIO_ChannelLF;
4672            map[1] = OMX_AUDIO_ChannelRF;
4673            map[2] = OMX_AUDIO_ChannelCF;
4674            break;
4675        case 4:
4676            map[0] = OMX_AUDIO_ChannelLF;
4677            map[1] = OMX_AUDIO_ChannelRF;
4678            map[2] = OMX_AUDIO_ChannelLR;
4679            map[3] = OMX_AUDIO_ChannelRR;
4680            break;
4681        case 5:
4682            map[0] = OMX_AUDIO_ChannelLF;
4683            map[1] = OMX_AUDIO_ChannelRF;
4684            map[2] = OMX_AUDIO_ChannelCF;
4685            map[3] = OMX_AUDIO_ChannelLR;
4686            map[4] = OMX_AUDIO_ChannelRR;
4687            break;
4688        case 6:
4689            map[0] = OMX_AUDIO_ChannelLF;
4690            map[1] = OMX_AUDIO_ChannelRF;
4691            map[2] = OMX_AUDIO_ChannelCF;
4692            map[3] = OMX_AUDIO_ChannelLFE;
4693            map[4] = OMX_AUDIO_ChannelLR;
4694            map[5] = OMX_AUDIO_ChannelRR;
4695            break;
4696        case 7:
4697            map[0] = OMX_AUDIO_ChannelLF;
4698            map[1] = OMX_AUDIO_ChannelRF;
4699            map[2] = OMX_AUDIO_ChannelCF;
4700            map[3] = OMX_AUDIO_ChannelLFE;
4701            map[4] = OMX_AUDIO_ChannelLR;
4702            map[5] = OMX_AUDIO_ChannelRR;
4703            map[6] = OMX_AUDIO_ChannelCS;
4704            break;
4705        case 8:
4706            map[0] = OMX_AUDIO_ChannelLF;
4707            map[1] = OMX_AUDIO_ChannelRF;
4708            map[2] = OMX_AUDIO_ChannelCF;
4709            map[3] = OMX_AUDIO_ChannelLFE;
4710            map[4] = OMX_AUDIO_ChannelLR;
4711            map[5] = OMX_AUDIO_ChannelRR;
4712            map[6] = OMX_AUDIO_ChannelLS;
4713            map[7] = OMX_AUDIO_ChannelRS;
4714            break;
4715        default:
4716            return -EINVAL;
4717    }
4718
4719    return OK;
4720}
4721
4722}  // namespace android
4723