OMXCodec.cpp revision 7f498b90a4300ef9badf14d202b0a67c26e20931
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/AACDecoder.h"
22#include "include/AMRNBDecoder.h"
23#include "include/AMRNBEncoder.h"
24#include "include/AMRWBDecoder.h"
25#include "include/AVCDecoder.h"
26#include "include/M4vH263Decoder.h"
27#include "include/MP3Decoder.h"
28
29#include "include/ESDS.h"
30
31#include <binder/IServiceManager.h>
32#include <binder/MemoryDealer.h>
33#include <binder/ProcessState.h>
34#include <media/IMediaPlayerService.h>
35#include <media/stagefright/MediaBuffer.h>
36#include <media/stagefright/MediaBufferGroup.h>
37#include <media/stagefright/MediaDebug.h>
38#include <media/stagefright/MediaDefs.h>
39#include <media/stagefright/MediaExtractor.h>
40#include <media/stagefright/MetaData.h>
41#include <media/stagefright/OMXCodec.h>
42#include <media/stagefright/Utils.h>
43#include <utils/Vector.h>
44
45#include <OMX_Audio.h>
46#include <OMX_Component.h>
47
48namespace android {
49
50static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
51
52struct CodecInfo {
53    const char *mime;
54    const char *codec;
55};
56
57#define FACTORY_CREATE(name) \
58static sp<MediaSource> Make##name(const sp<MediaSource> &source) { \
59    return new name(source); \
60}
61
62#define FACTORY_REF(name) { #name, Make##name },
63
64FACTORY_CREATE(MP3Decoder)
65FACTORY_CREATE(AMRNBDecoder)
66FACTORY_CREATE(AMRWBDecoder)
67FACTORY_CREATE(AACDecoder)
68FACTORY_CREATE(AVCDecoder)
69FACTORY_CREATE(M4vH263Decoder)
70FACTORY_CREATE(AMRNBEncoder)
71
72static sp<MediaSource> InstantiateSoftwareCodec(
73        const char *name, const sp<MediaSource> &source) {
74    struct FactoryInfo {
75        const char *name;
76        sp<MediaSource> (*CreateFunc)(const sp<MediaSource> &);
77    };
78
79    static const FactoryInfo kFactoryInfo[] = {
80        FACTORY_REF(MP3Decoder)
81        FACTORY_REF(AMRNBDecoder)
82        FACTORY_REF(AMRWBDecoder)
83        FACTORY_REF(AACDecoder)
84        FACTORY_REF(AVCDecoder)
85        FACTORY_REF(M4vH263Decoder)
86        FACTORY_REF(AMRNBEncoder)
87    };
88    for (size_t i = 0;
89         i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) {
90        if (!strcmp(name, kFactoryInfo[i].name)) {
91            return (*kFactoryInfo[i].CreateFunc)(source);
92        }
93    }
94
95    return NULL;
96}
97
98#undef FACTORY_REF
99#undef FACTORY_CREATE
100
101static const CodecInfo kDecoderInfo[] = {
102    { MEDIA_MIMETYPE_IMAGE_JPEG, "OMX.TI.JPEG.decode" },
103    { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" },
104    { MEDIA_MIMETYPE_AUDIO_MPEG, "MP3Decoder" },
105//    { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.PV.mp3dec" },
106//    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.decode" },
107    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBDecoder" },
108//    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.PV.amrdec" },
109    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.decode" },
110    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "AMRWBDecoder" },
111//    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.PV.amrdec" },
112    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.decode" },
113    { MEDIA_MIMETYPE_AUDIO_AAC, "AACDecoder" },
114//    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacdec" },
115    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.decoder.mpeg4" },
116    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.Decoder" },
117    { MEDIA_MIMETYPE_VIDEO_MPEG4, "M4vH263Decoder" },
118//    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4dec" },
119    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.decoder.h263" },
120    { MEDIA_MIMETYPE_VIDEO_H263, "M4vH263Decoder" },
121//    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263dec" },
122    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" },
123    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.Decoder" },
124    { MEDIA_MIMETYPE_VIDEO_AVC, "AVCDecoder" },
125//    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcdec" },
126};
127
128static const CodecInfo kEncoderInfo[] = {
129    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.encode" },
130    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBEncoder" },
131    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.encode" },
132    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.encode" },
133    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacenc" },
134    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.encoder.mpeg4" },
135    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.encoder" },
136    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4enc" },
137    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.encoder.h263" },
138    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.encoder" },
139    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263enc" },
140    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.encoder" },
141    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcenc" },
142};
143
144#undef OPTIONAL
145
146#define CODEC_LOGI(x, ...) LOGI("[%s] "x, mComponentName, ##__VA_ARGS__)
147#define CODEC_LOGV(x, ...) LOGV("[%s] "x, mComponentName, ##__VA_ARGS__)
148#define CODEC_LOGE(x, ...) LOGE("[%s] "x, mComponentName, ##__VA_ARGS__)
149
150struct OMXCodecObserver : public BnOMXObserver {
151    OMXCodecObserver() {
152    }
153
154    void setCodec(const sp<OMXCodec> &target) {
155        mTarget = target;
156    }
157
158    // from IOMXObserver
159    virtual void onMessage(const omx_message &msg) {
160        sp<OMXCodec> codec = mTarget.promote();
161
162        if (codec.get() != NULL) {
163            codec->on_message(msg);
164        }
165    }
166
167protected:
168    virtual ~OMXCodecObserver() {}
169
170private:
171    wp<OMXCodec> mTarget;
172
173    OMXCodecObserver(const OMXCodecObserver &);
174    OMXCodecObserver &operator=(const OMXCodecObserver &);
175};
176
177static const char *GetCodec(const CodecInfo *info, size_t numInfos,
178                            const char *mime, int index) {
179    CHECK(index >= 0);
180    for(size_t i = 0; i < numInfos; ++i) {
181        if (!strcasecmp(mime, info[i].mime)) {
182            if (index == 0) {
183                return info[i].codec;
184            }
185
186            --index;
187        }
188    }
189
190    return NULL;
191}
192
193enum {
194    kAVCProfileBaseline      = 0x42,
195    kAVCProfileMain          = 0x4d,
196    kAVCProfileExtended      = 0x58,
197    kAVCProfileHigh          = 0x64,
198    kAVCProfileHigh10        = 0x6e,
199    kAVCProfileHigh422       = 0x7a,
200    kAVCProfileHigh444       = 0xf4,
201    kAVCProfileCAVLC444Intra = 0x2c
202};
203
204static const char *AVCProfileToString(uint8_t profile) {
205    switch (profile) {
206        case kAVCProfileBaseline:
207            return "Baseline";
208        case kAVCProfileMain:
209            return "Main";
210        case kAVCProfileExtended:
211            return "Extended";
212        case kAVCProfileHigh:
213            return "High";
214        case kAVCProfileHigh10:
215            return "High 10";
216        case kAVCProfileHigh422:
217            return "High 422";
218        case kAVCProfileHigh444:
219            return "High 444";
220        case kAVCProfileCAVLC444Intra:
221            return "CAVLC 444 Intra";
222        default:   return "Unknown";
223    }
224}
225
226template<class T>
227static void InitOMXParams(T *params) {
228    params->nSize = sizeof(T);
229    params->nVersion.s.nVersionMajor = 1;
230    params->nVersion.s.nVersionMinor = 0;
231    params->nVersion.s.nRevision = 0;
232    params->nVersion.s.nStep = 0;
233}
234
235static bool IsSoftwareCodec(const char *componentName) {
236    if (!strncmp("OMX.PV.", componentName, 7)) {
237        return true;
238    }
239
240    return false;
241}
242
243// A sort order in which non-OMX components are first,
244// followed by software codecs, i.e. OMX.PV.*, followed
245// by all the others.
246static int CompareSoftwareCodecsFirst(
247        const String8 *elem1, const String8 *elem2) {
248    bool isNotOMX1 = strncmp(elem1->string(), "OMX.", 4);
249    bool isNotOMX2 = strncmp(elem2->string(), "OMX.", 4);
250
251    if (isNotOMX1) {
252        if (isNotOMX2) { return 0; }
253        return -1;
254    }
255    if (isNotOMX2) {
256        return 1;
257    }
258
259    bool isSoftwareCodec1 = IsSoftwareCodec(elem1->string());
260    bool isSoftwareCodec2 = IsSoftwareCodec(elem2->string());
261
262    if (isSoftwareCodec1) {
263        if (isSoftwareCodec2) { return 0; }
264        return -1;
265    }
266
267    if (isSoftwareCodec2) {
268        return 1;
269    }
270
271    return 0;
272}
273
274// static
275uint32_t OMXCodec::getComponentQuirks(const char *componentName) {
276    uint32_t quirks = 0;
277
278    if (!strcmp(componentName, "OMX.PV.avcdec")) {
279        quirks |= kWantsNALFragments;
280    }
281    if (!strcmp(componentName, "OMX.TI.MP3.decode")) {
282        quirks |= kNeedsFlushBeforeDisable;
283        quirks |= kDecoderLiesAboutNumberOfChannels;
284    }
285    if (!strcmp(componentName, "OMX.TI.AAC.decode")) {
286        quirks |= kNeedsFlushBeforeDisable;
287        quirks |= kRequiresFlushCompleteEmulation;
288        quirks |= kSupportsMultipleFramesPerInputBuffer;
289    }
290    if (!strncmp(componentName, "OMX.qcom.video.encoder.", 23)) {
291        quirks |= kRequiresLoadedToIdleAfterAllocation;
292        quirks |= kRequiresAllocateBufferOnInputPorts;
293        quirks |= kRequiresAllocateBufferOnOutputPorts;
294    }
295    if (!strncmp(componentName, "OMX.qcom.video.decoder.", 23)) {
296        quirks |= kRequiresAllocateBufferOnOutputPorts;
297        quirks |= kDefersOutputBufferAllocation;
298    }
299
300    if (!strncmp(componentName, "OMX.TI.", 7)) {
301        // Apparently I must not use OMX_UseBuffer on either input or
302        // output ports on any of the TI components or quote:
303        // "(I) may have unexpected problem (sic) which can be timing related
304        //  and hard to reproduce."
305
306        quirks |= kRequiresAllocateBufferOnInputPorts;
307        quirks |= kRequiresAllocateBufferOnOutputPorts;
308    }
309
310    if (!strcmp(componentName, "OMX.TI.Video.Decoder")) {
311        quirks |= kInputBufferSizesAreBogus;
312    }
313
314    return quirks;
315}
316
317// static
318void OMXCodec::findMatchingCodecs(
319        const char *mime,
320        bool createEncoder, const char *matchComponentName,
321        uint32_t flags,
322        Vector<String8> *matchingCodecs) {
323    matchingCodecs->clear();
324
325    for (int index = 0;; ++index) {
326        const char *componentName;
327
328        if (createEncoder) {
329            componentName = GetCodec(
330                    kEncoderInfo,
331                    sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]),
332                    mime, index);
333        } else {
334            componentName = GetCodec(
335                    kDecoderInfo,
336                    sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]),
337                    mime, index);
338        }
339
340        if (!componentName) {
341            break;
342        }
343
344        // If a specific codec is requested, skip the non-matching ones.
345        if (matchComponentName && strcmp(componentName, matchComponentName)) {
346            continue;
347        }
348
349        matchingCodecs->push(String8(componentName));
350    }
351
352    if (flags & kPreferSoftwareCodecs) {
353        matchingCodecs->sort(CompareSoftwareCodecsFirst);
354    }
355}
356
357// static
358sp<MediaSource> OMXCodec::Create(
359        const sp<IOMX> &omx,
360        const sp<MetaData> &meta, bool createEncoder,
361        const sp<MediaSource> &source,
362        const char *matchComponentName,
363        uint32_t flags) {
364    const char *mime;
365    bool success = meta->findCString(kKeyMIMEType, &mime);
366    CHECK(success);
367
368    Vector<String8> matchingCodecs;
369    findMatchingCodecs(
370            mime, createEncoder, matchComponentName, flags, &matchingCodecs);
371
372    if (matchingCodecs.isEmpty()) {
373        return NULL;
374    }
375
376    sp<OMXCodecObserver> observer = new OMXCodecObserver;
377    IOMX::node_id node = 0;
378
379    const char *componentName;
380    for (size_t i = 0; i < matchingCodecs.size(); ++i) {
381        componentName = matchingCodecs[i].string();
382
383#if BUILD_WITH_FULL_STAGEFRIGHT
384        sp<MediaSource> softwareCodec =
385            InstantiateSoftwareCodec(componentName, source);
386
387        if (softwareCodec != NULL) {
388            LOGV("Successfully allocated software codec '%s'", componentName);
389
390            return softwareCodec;
391        }
392#endif
393
394        LOGV("Attempting to allocate OMX node '%s'", componentName);
395
396        status_t err = omx->allocateNode(componentName, observer, &node);
397        if (err == OK) {
398            LOGV("Successfully allocated OMX node '%s'", componentName);
399
400            sp<OMXCodec> codec = new OMXCodec(
401                    omx, node, getComponentQuirks(componentName),
402                    createEncoder, mime, componentName,
403                    source);
404
405            observer->setCodec(codec);
406
407            err = codec->configureCodec(meta);
408
409            if (err == OK) {
410                return codec;
411            }
412
413            LOGV("Failed to configure codec '%s'", componentName);
414        }
415    }
416
417    return NULL;
418}
419
420status_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
421    uint32_t type;
422    const void *data;
423    size_t size;
424    if (meta->findData(kKeyESDS, &type, &data, &size)) {
425        ESDS esds((const char *)data, size);
426        CHECK_EQ(esds.InitCheck(), OK);
427
428        const void *codec_specific_data;
429        size_t codec_specific_data_size;
430        esds.getCodecSpecificInfo(
431                &codec_specific_data, &codec_specific_data_size);
432
433        addCodecSpecificData(
434                codec_specific_data, codec_specific_data_size);
435    } else if (meta->findData(kKeyAVCC, &type, &data, &size)) {
436        // Parse the AVCDecoderConfigurationRecord
437
438        const uint8_t *ptr = (const uint8_t *)data;
439
440        CHECK(size >= 7);
441        CHECK_EQ(ptr[0], 1);  // configurationVersion == 1
442        uint8_t profile = ptr[1];
443        uint8_t level = ptr[3];
444
445        // There is decodable content out there that fails the following
446        // assertion, let's be lenient for now...
447        // CHECK((ptr[4] >> 2) == 0x3f);  // reserved
448
449        size_t lengthSize = 1 + (ptr[4] & 3);
450
451        // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
452        // violates it...
453        // CHECK((ptr[5] >> 5) == 7);  // reserved
454
455        size_t numSeqParameterSets = ptr[5] & 31;
456
457        ptr += 6;
458        size -= 6;
459
460        for (size_t i = 0; i < numSeqParameterSets; ++i) {
461            CHECK(size >= 2);
462            size_t length = U16_AT(ptr);
463
464            ptr += 2;
465            size -= 2;
466
467            CHECK(size >= length);
468
469            addCodecSpecificData(ptr, length);
470
471            ptr += length;
472            size -= length;
473        }
474
475        CHECK(size >= 1);
476        size_t numPictureParameterSets = *ptr;
477        ++ptr;
478        --size;
479
480        for (size_t i = 0; i < numPictureParameterSets; ++i) {
481            CHECK(size >= 2);
482            size_t length = U16_AT(ptr);
483
484            ptr += 2;
485            size -= 2;
486
487            CHECK(size >= length);
488
489            addCodecSpecificData(ptr, length);
490
491            ptr += length;
492            size -= length;
493        }
494
495        LOGV("AVC profile = %d (%s), level = %d",
496             (int)profile, AVCProfileToString(profile), (int)level / 10);
497
498        if (!strcmp(mComponentName, "OMX.TI.Video.Decoder")
499            && (profile != kAVCProfileBaseline || level > 39)) {
500            // This stream exceeds the decoder's capabilities. The decoder
501            // does not handle this gracefully and would clobber the heap
502            // and wreak havoc instead...
503
504            LOGE("Profile and/or level exceed the decoder's capabilities.");
505            return ERROR_UNSUPPORTED;
506        }
507    }
508
509    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mMIME)) {
510        setAMRFormat(false /* isWAMR */);
511    }
512    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mMIME)) {
513        setAMRFormat(true /* isWAMR */);
514    }
515    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mMIME)) {
516        int32_t numChannels, sampleRate;
517        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
518        CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
519
520        setAACFormat(numChannels, sampleRate);
521    }
522    if (!strncasecmp(mMIME, "video/", 6)) {
523        int32_t width, height;
524        bool success = meta->findInt32(kKeyWidth, &width);
525        success = success && meta->findInt32(kKeyHeight, &height);
526        CHECK(success);
527
528        if (mIsEncoder) {
529            setVideoInputFormat(mMIME, width, height);
530        } else {
531            status_t err = setVideoOutputFormat(
532                    mMIME, width, height);
533
534            if (err != OK) {
535                return err;
536            }
537        }
538    } else if (!strncasecmp(mMIME, "audio/", 6)) {
539        if ((mQuirks & kSupportsMultipleFramesPerInputBuffer)
540            && !strcmp(mComponentName, "OMX.TI.AAC.decode")) {
541            OMX_PARAM_PORTDEFINITIONTYPE def;
542            InitOMXParams(&def);
543            def.nPortIndex = kPortIndexInput;
544
545            status_t err = mOMX->getParameter(
546                    mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
547            CHECK_EQ(err, OK);
548
549            const size_t kMinBufferSize = 100 * 1024;
550            if (def.nBufferSize < kMinBufferSize) {
551                def.nBufferSize = kMinBufferSize;
552            }
553
554            err = mOMX->setParameter(
555                    mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
556            CHECK_EQ(err, OK);
557        }
558    }
559
560    if (!strcasecmp(mMIME, MEDIA_MIMETYPE_IMAGE_JPEG)
561        && !strcmp(mComponentName, "OMX.TI.JPEG.decode")) {
562        OMX_COLOR_FORMATTYPE format =
563            OMX_COLOR_Format32bitARGB8888;
564            // OMX_COLOR_FormatYUV420PackedPlanar;
565            // OMX_COLOR_FormatCbYCrY;
566            // OMX_COLOR_FormatYUV411Planar;
567
568        int32_t width, height;
569        bool success = meta->findInt32(kKeyWidth, &width);
570        success = success && meta->findInt32(kKeyHeight, &height);
571
572        int32_t compressedSize;
573        success = success && meta->findInt32(
574                kKeyMaxInputSize, &compressedSize);
575
576        CHECK(success);
577        CHECK(compressedSize > 0);
578
579        setImageOutputFormat(format, width, height);
580        setJPEGInputFormat(width, height, (OMX_U32)compressedSize);
581    }
582
583    int32_t maxInputSize;
584    if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
585        setMinBufferSize(kPortIndexInput, (OMX_U32)maxInputSize);
586    }
587
588    if (!strcmp(mComponentName, "OMX.TI.AMR.encode")
589        || !strcmp(mComponentName, "OMX.TI.WBAMR.encode")) {
590        setMinBufferSize(kPortIndexOutput, 8192);  // XXX
591    }
592
593    initOutputFormat(meta);
594
595    return OK;
596}
597
598void OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) {
599    OMX_PARAM_PORTDEFINITIONTYPE def;
600    InitOMXParams(&def);
601    def.nPortIndex = portIndex;
602
603    status_t err = mOMX->getParameter(
604            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
605    CHECK_EQ(err, OK);
606
607    if ((portIndex == kPortIndexInput && (mQuirks & kInputBufferSizesAreBogus))
608        || (def.nBufferSize < size)) {
609        def.nBufferSize = size;
610    }
611
612    err = mOMX->setParameter(
613            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
614    CHECK_EQ(err, OK);
615
616    err = mOMX->getParameter(
617            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
618    CHECK_EQ(err, OK);
619
620    // Make sure the setting actually stuck.
621    if (portIndex == kPortIndexInput
622            && (mQuirks & kInputBufferSizesAreBogus)) {
623        CHECK_EQ(def.nBufferSize, size);
624    } else {
625        CHECK(def.nBufferSize >= size);
626    }
627}
628
629status_t OMXCodec::setVideoPortFormatType(
630        OMX_U32 portIndex,
631        OMX_VIDEO_CODINGTYPE compressionFormat,
632        OMX_COLOR_FORMATTYPE colorFormat) {
633    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
634    InitOMXParams(&format);
635    format.nPortIndex = portIndex;
636    format.nIndex = 0;
637    bool found = false;
638
639    OMX_U32 index = 0;
640    for (;;) {
641        format.nIndex = index;
642        status_t err = mOMX->getParameter(
643                mNode, OMX_IndexParamVideoPortFormat,
644                &format, sizeof(format));
645
646        if (err != OK) {
647            return err;
648        }
649
650        // The following assertion is violated by TI's video decoder.
651        // CHECK_EQ(format.nIndex, index);
652
653#if 1
654        CODEC_LOGV("portIndex: %ld, index: %ld, eCompressionFormat=%d eColorFormat=%d",
655             portIndex,
656             index, format.eCompressionFormat, format.eColorFormat);
657#endif
658
659        if (!strcmp("OMX.TI.Video.encoder", mComponentName)) {
660            if (portIndex == kPortIndexInput
661                    && colorFormat == format.eColorFormat) {
662                // eCompressionFormat does not seem right.
663                found = true;
664                break;
665            }
666            if (portIndex == kPortIndexOutput
667                    && compressionFormat == format.eCompressionFormat) {
668                // eColorFormat does not seem right.
669                found = true;
670                break;
671            }
672        }
673
674        if (format.eCompressionFormat == compressionFormat
675            && format.eColorFormat == colorFormat) {
676            found = true;
677            break;
678        }
679
680        ++index;
681    }
682
683    if (!found) {
684        return UNKNOWN_ERROR;
685    }
686
687    CODEC_LOGV("found a match.");
688    status_t err = mOMX->setParameter(
689            mNode, OMX_IndexParamVideoPortFormat,
690            &format, sizeof(format));
691
692    return err;
693}
694
695static size_t getFrameSize(
696        OMX_COLOR_FORMATTYPE colorFormat, int32_t width, int32_t height) {
697    switch (colorFormat) {
698        case OMX_COLOR_FormatYCbYCr:
699        case OMX_COLOR_FormatCbYCrY:
700            return width * height * 2;
701
702        case OMX_COLOR_FormatYUV420SemiPlanar:
703            return (width * height * 3) / 2;
704
705        default:
706            CHECK(!"Should not be here. Unsupported color format.");
707            break;
708    }
709}
710
711void OMXCodec::setVideoInputFormat(
712        const char *mime, OMX_U32 width, OMX_U32 height) {
713    CODEC_LOGV("setVideoInputFormat width=%ld, height=%ld", width, height);
714
715    OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
716    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
717        compressionFormat = OMX_VIDEO_CodingAVC;
718    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
719        compressionFormat = OMX_VIDEO_CodingMPEG4;
720    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
721        compressionFormat = OMX_VIDEO_CodingH263;
722    } else {
723        LOGE("Not a supported video mime type: %s", mime);
724        CHECK(!"Should not be here. Not a supported video mime type.");
725    }
726
727    OMX_COLOR_FORMATTYPE colorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
728    if (!strcasecmp("OMX.TI.Video.encoder", mComponentName)) {
729        colorFormat = OMX_COLOR_FormatYCbYCr;
730    }
731
732    CHECK_EQ(setVideoPortFormatType(
733            kPortIndexInput, OMX_VIDEO_CodingUnused,
734            colorFormat), OK);
735
736    CHECK_EQ(setVideoPortFormatType(
737            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused),
738            OK);
739
740    OMX_PARAM_PORTDEFINITIONTYPE def;
741    InitOMXParams(&def);
742    def.nPortIndex = kPortIndexOutput;
743
744    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
745
746    status_t err = mOMX->getParameter(
747            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
748
749    CHECK_EQ(err, OK);
750    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
751
752    video_def->nFrameWidth = width;
753    video_def->nFrameHeight = height;
754
755    video_def->eCompressionFormat = compressionFormat;
756    video_def->eColorFormat = OMX_COLOR_FormatUnused;
757
758    err = mOMX->setParameter(
759            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
760    CHECK_EQ(err, OK);
761
762    ////////////////////////////////////////////////////////////////////////////
763
764    InitOMXParams(&def);
765    def.nPortIndex = kPortIndexInput;
766
767    err = mOMX->getParameter(
768            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
769    CHECK_EQ(err, OK);
770
771    def.nBufferSize = getFrameSize(colorFormat, width, height);
772    CODEC_LOGV("Setting nBufferSize = %ld", def.nBufferSize);
773
774    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
775
776    video_def->nFrameWidth = width;
777    video_def->nFrameHeight = height;
778    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
779    video_def->eColorFormat = colorFormat;
780
781    video_def->xFramerate = 24 << 16;  // XXX crucial!
782
783    err = mOMX->setParameter(
784            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
785    CHECK_EQ(err, OK);
786
787    switch (compressionFormat) {
788        case OMX_VIDEO_CodingMPEG4:
789        {
790            CHECK_EQ(setupMPEG4EncoderParameters(), OK);
791            break;
792        }
793
794        case OMX_VIDEO_CodingH263:
795            break;
796
797        case OMX_VIDEO_CodingAVC:
798        {
799            CHECK_EQ(setupAVCEncoderParameters(), OK);
800            break;
801        }
802
803        default:
804            CHECK(!"Support for this compressionFormat to be implemented.");
805            break;
806    }
807}
808
809status_t OMXCodec::setupMPEG4EncoderParameters() {
810    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
811    InitOMXParams(&mpeg4type);
812    mpeg4type.nPortIndex = kPortIndexOutput;
813
814    status_t err = mOMX->getParameter(
815            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
816    CHECK_EQ(err, OK);
817
818    mpeg4type.nSliceHeaderSpacing = 0;
819    mpeg4type.bSVH = OMX_FALSE;
820    mpeg4type.bGov = OMX_FALSE;
821
822    mpeg4type.nAllowedPictureTypes =
823        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
824
825    mpeg4type.nPFrames = 23;
826    mpeg4type.nBFrames = 0;
827
828    mpeg4type.nIDCVLCThreshold = 0;
829    mpeg4type.bACPred = OMX_TRUE;
830    mpeg4type.nMaxPacketSize = 256;
831    mpeg4type.nTimeIncRes = 1000;
832    mpeg4type.nHeaderExtension = 0;
833    mpeg4type.bReversibleVLC = OMX_FALSE;
834
835    mpeg4type.eProfile = OMX_VIDEO_MPEG4ProfileCore;
836    mpeg4type.eLevel = OMX_VIDEO_MPEG4Level2;
837
838    err = mOMX->setParameter(
839            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
840    CHECK_EQ(err, OK);
841
842    // ----------------
843
844    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
845    InitOMXParams(&bitrateType);
846    bitrateType.nPortIndex = kPortIndexOutput;
847
848    err = mOMX->getParameter(
849            mNode, OMX_IndexParamVideoBitrate,
850            &bitrateType, sizeof(bitrateType));
851    CHECK_EQ(err, OK);
852
853    bitrateType.eControlRate = OMX_Video_ControlRateVariable;
854    bitrateType.nTargetBitrate = 1000000;
855
856    err = mOMX->setParameter(
857            mNode, OMX_IndexParamVideoBitrate,
858            &bitrateType, sizeof(bitrateType));
859    CHECK_EQ(err, OK);
860
861    // ----------------
862
863    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
864    InitOMXParams(&errorCorrectionType);
865    errorCorrectionType.nPortIndex = kPortIndexOutput;
866
867    err = mOMX->getParameter(
868            mNode, OMX_IndexParamVideoErrorCorrection,
869            &errorCorrectionType, sizeof(errorCorrectionType));
870    CHECK_EQ(err, OK);
871
872    errorCorrectionType.bEnableHEC = OMX_FALSE;
873    errorCorrectionType.bEnableResync = OMX_TRUE;
874    errorCorrectionType.nResynchMarkerSpacing = 256;
875    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
876    errorCorrectionType.bEnableRVLC = OMX_FALSE;
877
878    err = mOMX->setParameter(
879            mNode, OMX_IndexParamVideoErrorCorrection,
880            &errorCorrectionType, sizeof(errorCorrectionType));
881    CHECK_EQ(err, OK);
882
883    return OK;
884}
885
886status_t OMXCodec::setupAVCEncoderParameters() {
887    OMX_VIDEO_PARAM_AVCTYPE h264type;
888    InitOMXParams(&h264type);
889    h264type.nPortIndex = kPortIndexOutput;
890
891    status_t err = mOMX->getParameter(
892            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
893    CHECK_EQ(err, OK);
894
895    h264type.nAllowedPictureTypes =
896        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
897
898    h264type.nSliceHeaderSpacing = 0;
899    h264type.nBFrames = 0;
900    h264type.bUseHadamard = OMX_TRUE;
901    h264type.nRefFrames = 1;
902    h264type.nRefIdx10ActiveMinus1 = 0;
903    h264type.nRefIdx11ActiveMinus1 = 0;
904    h264type.bEnableUEP = OMX_FALSE;
905    h264type.bEnableFMO = OMX_FALSE;
906    h264type.bEnableASO = OMX_FALSE;
907    h264type.bEnableRS = OMX_FALSE;
908    h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
909    h264type.eLevel = OMX_VIDEO_AVCLevel1b;
910    h264type.bFrameMBsOnly = OMX_TRUE;
911    h264type.bMBAFF = OMX_FALSE;
912    h264type.bEntropyCodingCABAC = OMX_FALSE;
913    h264type.bWeightedPPrediction = OMX_FALSE;
914    h264type.bconstIpred = OMX_FALSE;
915    h264type.bDirect8x8Inference = OMX_FALSE;
916    h264type.bDirectSpatialTemporal = OMX_FALSE;
917    h264type.nCabacInitIdc = 0;
918    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
919
920    err = mOMX->setParameter(
921            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
922    CHECK_EQ(err, OK);
923
924    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
925    InitOMXParams(&bitrateType);
926    bitrateType.nPortIndex = kPortIndexOutput;
927
928    err = mOMX->getParameter(
929            mNode, OMX_IndexParamVideoBitrate,
930            &bitrateType, sizeof(bitrateType));
931    CHECK_EQ(err, OK);
932
933    bitrateType.eControlRate = OMX_Video_ControlRateVariable;
934    bitrateType.nTargetBitrate = 1000000;
935
936    err = mOMX->setParameter(
937            mNode, OMX_IndexParamVideoBitrate,
938            &bitrateType, sizeof(bitrateType));
939    CHECK_EQ(err, OK);
940
941    return OK;
942}
943
944status_t OMXCodec::setVideoOutputFormat(
945        const char *mime, OMX_U32 width, OMX_U32 height) {
946    CODEC_LOGV("setVideoOutputFormat width=%ld, height=%ld", width, height);
947
948    OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
949    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
950        compressionFormat = OMX_VIDEO_CodingAVC;
951    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
952        compressionFormat = OMX_VIDEO_CodingMPEG4;
953    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
954        compressionFormat = OMX_VIDEO_CodingH263;
955    } else {
956        LOGE("Not a supported video mime type: %s", mime);
957        CHECK(!"Should not be here. Not a supported video mime type.");
958    }
959
960    status_t err = setVideoPortFormatType(
961            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
962
963    if (err != OK) {
964        return err;
965    }
966
967#if 1
968    {
969        OMX_VIDEO_PARAM_PORTFORMATTYPE format;
970        InitOMXParams(&format);
971        format.nPortIndex = kPortIndexOutput;
972        format.nIndex = 0;
973
974        status_t err = mOMX->getParameter(
975                mNode, OMX_IndexParamVideoPortFormat,
976                &format, sizeof(format));
977        CHECK_EQ(err, OK);
978        CHECK_EQ(format.eCompressionFormat, OMX_VIDEO_CodingUnused);
979
980        static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
981
982        CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
983               || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
984               || format.eColorFormat == OMX_COLOR_FormatCbYCrY
985               || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar);
986
987        err = mOMX->setParameter(
988                mNode, OMX_IndexParamVideoPortFormat,
989                &format, sizeof(format));
990
991        if (err != OK) {
992            return err;
993        }
994    }
995#endif
996
997    OMX_PARAM_PORTDEFINITIONTYPE def;
998    InitOMXParams(&def);
999    def.nPortIndex = kPortIndexInput;
1000
1001    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
1002
1003    err = mOMX->getParameter(
1004            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1005
1006    CHECK_EQ(err, OK);
1007
1008#if 1
1009    // XXX Need a (much) better heuristic to compute input buffer sizes.
1010    const size_t X = 64 * 1024;
1011    if (def.nBufferSize < X) {
1012        def.nBufferSize = X;
1013    }
1014#endif
1015
1016    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
1017
1018    video_def->nFrameWidth = width;
1019    video_def->nFrameHeight = height;
1020
1021    video_def->eCompressionFormat = compressionFormat;
1022    video_def->eColorFormat = OMX_COLOR_FormatUnused;
1023
1024    err = mOMX->setParameter(
1025            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1026
1027    if (err != OK) {
1028        return err;
1029    }
1030
1031    ////////////////////////////////////////////////////////////////////////////
1032
1033    InitOMXParams(&def);
1034    def.nPortIndex = kPortIndexOutput;
1035
1036    err = mOMX->getParameter(
1037            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1038    CHECK_EQ(err, OK);
1039    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
1040
1041#if 0
1042    def.nBufferSize =
1043        (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2;  // YUV420
1044#endif
1045
1046    video_def->nFrameWidth = width;
1047    video_def->nFrameHeight = height;
1048
1049    err = mOMX->setParameter(
1050            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1051
1052    return err;
1053}
1054
1055OMXCodec::OMXCodec(
1056        const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks,
1057        bool isEncoder,
1058        const char *mime,
1059        const char *componentName,
1060        const sp<MediaSource> &source)
1061    : mOMX(omx),
1062      mOMXLivesLocally(omx->livesLocally(getpid())),
1063      mNode(node),
1064      mQuirks(quirks),
1065      mIsEncoder(isEncoder),
1066      mMIME(strdup(mime)),
1067      mComponentName(strdup(componentName)),
1068      mSource(source),
1069      mCodecSpecificDataIndex(0),
1070      mState(LOADED),
1071      mInitialBufferSubmit(true),
1072      mSignalledEOS(false),
1073      mNoMoreOutputData(false),
1074      mOutputPortSettingsHaveChanged(false),
1075      mSeekTimeUs(-1),
1076      mLeftOverBuffer(NULL) {
1077    mPortStatus[kPortIndexInput] = ENABLED;
1078    mPortStatus[kPortIndexOutput] = ENABLED;
1079
1080    setComponentRole();
1081}
1082
1083// static
1084void OMXCodec::setComponentRole(
1085        const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder,
1086        const char *mime) {
1087    struct MimeToRole {
1088        const char *mime;
1089        const char *decoderRole;
1090        const char *encoderRole;
1091    };
1092
1093    static const MimeToRole kMimeToRole[] = {
1094        { MEDIA_MIMETYPE_AUDIO_MPEG,
1095            "audio_decoder.mp3", "audio_encoder.mp3" },
1096        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1097            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1098        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1099            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1100        { MEDIA_MIMETYPE_AUDIO_AAC,
1101            "audio_decoder.aac", "audio_encoder.aac" },
1102        { MEDIA_MIMETYPE_VIDEO_AVC,
1103            "video_decoder.avc", "video_encoder.avc" },
1104        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1105            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1106        { MEDIA_MIMETYPE_VIDEO_H263,
1107            "video_decoder.h263", "video_encoder.h263" },
1108    };
1109
1110    static const size_t kNumMimeToRole =
1111        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1112
1113    size_t i;
1114    for (i = 0; i < kNumMimeToRole; ++i) {
1115        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1116            break;
1117        }
1118    }
1119
1120    if (i == kNumMimeToRole) {
1121        return;
1122    }
1123
1124    const char *role =
1125        isEncoder ? kMimeToRole[i].encoderRole
1126                  : kMimeToRole[i].decoderRole;
1127
1128    if (role != NULL) {
1129        OMX_PARAM_COMPONENTROLETYPE roleParams;
1130        InitOMXParams(&roleParams);
1131
1132        strncpy((char *)roleParams.cRole,
1133                role, OMX_MAX_STRINGNAME_SIZE - 1);
1134
1135        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1136
1137        status_t err = omx->setParameter(
1138                node, OMX_IndexParamStandardComponentRole,
1139                &roleParams, sizeof(roleParams));
1140
1141        if (err != OK) {
1142            LOGW("Failed to set standard component role '%s'.", role);
1143        }
1144    }
1145}
1146
1147void OMXCodec::setComponentRole() {
1148    setComponentRole(mOMX, mNode, mIsEncoder, mMIME);
1149}
1150
1151OMXCodec::~OMXCodec() {
1152    CHECK(mState == LOADED || mState == ERROR);
1153
1154    status_t err = mOMX->freeNode(mNode);
1155    CHECK_EQ(err, OK);
1156
1157    mNode = NULL;
1158    setState(DEAD);
1159
1160    clearCodecSpecificData();
1161
1162    free(mComponentName);
1163    mComponentName = NULL;
1164
1165    free(mMIME);
1166    mMIME = NULL;
1167}
1168
1169status_t OMXCodec::init() {
1170    // mLock is held.
1171
1172    CHECK_EQ(mState, LOADED);
1173
1174    status_t err;
1175    if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) {
1176        err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
1177        CHECK_EQ(err, OK);
1178        setState(LOADED_TO_IDLE);
1179    }
1180
1181    err = allocateBuffers();
1182    CHECK_EQ(err, OK);
1183
1184    if (mQuirks & kRequiresLoadedToIdleAfterAllocation) {
1185        err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
1186        CHECK_EQ(err, OK);
1187
1188        setState(LOADED_TO_IDLE);
1189    }
1190
1191    while (mState != EXECUTING && mState != ERROR) {
1192        mAsyncCompletion.wait(mLock);
1193    }
1194
1195    return mState == ERROR ? UNKNOWN_ERROR : OK;
1196}
1197
1198// static
1199bool OMXCodec::isIntermediateState(State state) {
1200    return state == LOADED_TO_IDLE
1201        || state == IDLE_TO_EXECUTING
1202        || state == EXECUTING_TO_IDLE
1203        || state == IDLE_TO_LOADED
1204        || state == RECONFIGURING;
1205}
1206
1207status_t OMXCodec::allocateBuffers() {
1208    status_t err = allocateBuffersOnPort(kPortIndexInput);
1209
1210    if (err != OK) {
1211        return err;
1212    }
1213
1214    return allocateBuffersOnPort(kPortIndexOutput);
1215}
1216
1217status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
1218    OMX_PARAM_PORTDEFINITIONTYPE def;
1219    InitOMXParams(&def);
1220    def.nPortIndex = portIndex;
1221
1222    status_t err = mOMX->getParameter(
1223            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1224
1225    if (err != OK) {
1226        return err;
1227    }
1228
1229    size_t totalSize = def.nBufferCountActual * def.nBufferSize;
1230    mDealer[portIndex] = new MemoryDealer(totalSize, "OMXCodec");
1231
1232    for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
1233        sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
1234        CHECK(mem.get() != NULL);
1235
1236        BufferInfo info;
1237        info.mData = NULL;
1238        info.mSize = def.nBufferSize;
1239
1240        IOMX::buffer_id buffer;
1241        if (portIndex == kPortIndexInput
1242                && (mQuirks & kRequiresAllocateBufferOnInputPorts)) {
1243            if (mOMXLivesLocally) {
1244                mem.clear();
1245
1246                err = mOMX->allocateBuffer(
1247                        mNode, portIndex, def.nBufferSize, &buffer,
1248                        &info.mData);
1249            } else {
1250                err = mOMX->allocateBufferWithBackup(
1251                        mNode, portIndex, mem, &buffer);
1252            }
1253        } else if (portIndex == kPortIndexOutput
1254                && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) {
1255            if (mOMXLivesLocally) {
1256                mem.clear();
1257
1258                err = mOMX->allocateBuffer(
1259                        mNode, portIndex, def.nBufferSize, &buffer,
1260                        &info.mData);
1261            } else {
1262                err = mOMX->allocateBufferWithBackup(
1263                        mNode, portIndex, mem, &buffer);
1264            }
1265        } else {
1266            err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
1267        }
1268
1269        if (err != OK) {
1270            LOGE("allocate_buffer_with_backup failed");
1271            return err;
1272        }
1273
1274        if (mem != NULL) {
1275            info.mData = mem->pointer();
1276        }
1277
1278        info.mBuffer = buffer;
1279        info.mOwnedByComponent = false;
1280        info.mMem = mem;
1281        info.mMediaBuffer = NULL;
1282
1283        if (portIndex == kPortIndexOutput) {
1284            if (!(mOMXLivesLocally
1285                        && (mQuirks & kRequiresAllocateBufferOnOutputPorts)
1286                        && (mQuirks & kDefersOutputBufferAllocation))) {
1287                // If the node does not fill in the buffer ptr at this time,
1288                // we will defer creating the MediaBuffer until receiving
1289                // the first FILL_BUFFER_DONE notification instead.
1290                info.mMediaBuffer = new MediaBuffer(info.mData, info.mSize);
1291                info.mMediaBuffer->setObserver(this);
1292            }
1293        }
1294
1295        mPortBuffers[portIndex].push(info);
1296
1297        CODEC_LOGV("allocated buffer %p on %s port", buffer,
1298             portIndex == kPortIndexInput ? "input" : "output");
1299    }
1300
1301    // dumpPortStatus(portIndex);
1302
1303    return OK;
1304}
1305
1306void OMXCodec::on_message(const omx_message &msg) {
1307    Mutex::Autolock autoLock(mLock);
1308
1309    switch (msg.type) {
1310        case omx_message::EVENT:
1311        {
1312            onEvent(
1313                 msg.u.event_data.event, msg.u.event_data.data1,
1314                 msg.u.event_data.data2);
1315
1316            break;
1317        }
1318
1319        case omx_message::EMPTY_BUFFER_DONE:
1320        {
1321            IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
1322
1323            CODEC_LOGV("EMPTY_BUFFER_DONE(buffer: %p)", buffer);
1324
1325            Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
1326            size_t i = 0;
1327            while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
1328                ++i;
1329            }
1330
1331            CHECK(i < buffers->size());
1332            if (!(*buffers)[i].mOwnedByComponent) {
1333                LOGW("We already own input buffer %p, yet received "
1334                     "an EMPTY_BUFFER_DONE.", buffer);
1335            }
1336
1337            buffers->editItemAt(i).mOwnedByComponent = false;
1338
1339            if (mPortStatus[kPortIndexInput] == DISABLING) {
1340                CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
1341
1342                status_t err =
1343                    mOMX->freeBuffer(mNode, kPortIndexInput, buffer);
1344                CHECK_EQ(err, OK);
1345
1346                buffers->removeAt(i);
1347            } else if (mState != ERROR
1348                    && mPortStatus[kPortIndexInput] != SHUTTING_DOWN) {
1349                CHECK_EQ(mPortStatus[kPortIndexInput], ENABLED);
1350                drainInputBuffer(&buffers->editItemAt(i));
1351            }
1352            break;
1353        }
1354
1355        case omx_message::FILL_BUFFER_DONE:
1356        {
1357            IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
1358            OMX_U32 flags = msg.u.extended_buffer_data.flags;
1359
1360            CODEC_LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx, timestamp: %lld us (%.2f secs))",
1361                 buffer,
1362                 msg.u.extended_buffer_data.range_length,
1363                 flags,
1364                 msg.u.extended_buffer_data.timestamp,
1365                 msg.u.extended_buffer_data.timestamp / 1E6);
1366
1367            Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
1368            size_t i = 0;
1369            while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
1370                ++i;
1371            }
1372
1373            CHECK(i < buffers->size());
1374            BufferInfo *info = &buffers->editItemAt(i);
1375
1376            if (!info->mOwnedByComponent) {
1377                LOGW("We already own output buffer %p, yet received "
1378                     "a FILL_BUFFER_DONE.", buffer);
1379            }
1380
1381            info->mOwnedByComponent = false;
1382
1383            if (mPortStatus[kPortIndexOutput] == DISABLING) {
1384                CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
1385
1386                status_t err =
1387                    mOMX->freeBuffer(mNode, kPortIndexOutput, buffer);
1388                CHECK_EQ(err, OK);
1389
1390                buffers->removeAt(i);
1391#if 0
1392            } else if (mPortStatus[kPortIndexOutput] == ENABLED
1393                       && (flags & OMX_BUFFERFLAG_EOS)) {
1394                CODEC_LOGV("No more output data.");
1395                mNoMoreOutputData = true;
1396                mBufferFilled.signal();
1397#endif
1398            } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) {
1399                CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED);
1400
1401                if (info->mMediaBuffer == NULL) {
1402                    CHECK(mOMXLivesLocally);
1403                    CHECK(mQuirks & kRequiresAllocateBufferOnOutputPorts);
1404                    CHECK(mQuirks & kDefersOutputBufferAllocation);
1405
1406                    // The qcom video decoders on Nexus don't actually allocate
1407                    // output buffer memory on a call to OMX_AllocateBuffer
1408                    // the "pBuffer" member of the OMX_BUFFERHEADERTYPE
1409                    // structure is only filled in later.
1410
1411                    info->mMediaBuffer = new MediaBuffer(
1412                            msg.u.extended_buffer_data.data_ptr,
1413                            info->mSize);
1414                    info->mMediaBuffer->setObserver(this);
1415                }
1416
1417                MediaBuffer *buffer = info->mMediaBuffer;
1418
1419                buffer->set_range(
1420                        msg.u.extended_buffer_data.range_offset,
1421                        msg.u.extended_buffer_data.range_length);
1422
1423                buffer->meta_data()->clear();
1424
1425                buffer->meta_data()->setInt64(
1426                        kKeyTime, msg.u.extended_buffer_data.timestamp);
1427
1428                if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) {
1429                    buffer->meta_data()->setInt32(kKeyIsSyncFrame, true);
1430                }
1431                if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_CODECCONFIG) {
1432                    buffer->meta_data()->setInt32(kKeyIsCodecConfig, true);
1433                }
1434
1435                buffer->meta_data()->setPointer(
1436                        kKeyPlatformPrivate,
1437                        msg.u.extended_buffer_data.platform_private);
1438
1439                buffer->meta_data()->setPointer(
1440                        kKeyBufferID,
1441                        msg.u.extended_buffer_data.buffer);
1442
1443                mFilledBuffers.push_back(i);
1444                mBufferFilled.signal();
1445
1446                if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_EOS) {
1447                    CODEC_LOGV("No more output data.");
1448                    mNoMoreOutputData = true;
1449                }
1450            }
1451
1452            break;
1453        }
1454
1455        default:
1456        {
1457            CHECK(!"should not be here.");
1458            break;
1459        }
1460    }
1461}
1462
1463void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
1464    switch (event) {
1465        case OMX_EventCmdComplete:
1466        {
1467            onCmdComplete((OMX_COMMANDTYPE)data1, data2);
1468            break;
1469        }
1470
1471        case OMX_EventError:
1472        {
1473            LOGE("ERROR(0x%08lx, %ld)", data1, data2);
1474
1475            setState(ERROR);
1476            break;
1477        }
1478
1479        case OMX_EventPortSettingsChanged:
1480        {
1481            onPortSettingsChanged(data1);
1482            break;
1483        }
1484
1485#if 0
1486        case OMX_EventBufferFlag:
1487        {
1488            CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1);
1489
1490            if (data1 == kPortIndexOutput) {
1491                mNoMoreOutputData = true;
1492            }
1493            break;
1494        }
1495#endif
1496
1497        default:
1498        {
1499            CODEC_LOGV("EVENT(%d, %ld, %ld)", event, data1, data2);
1500            break;
1501        }
1502    }
1503}
1504
1505// Has the format changed in any way that the client would have to be aware of?
1506static bool formatHasNotablyChanged(
1507        const sp<MetaData> &from, const sp<MetaData> &to) {
1508    if (from.get() == NULL && to.get() == NULL) {
1509        return false;
1510    }
1511
1512    if ((from.get() == NULL && to.get() != NULL)
1513        || (from.get() != NULL && to.get() == NULL)) {
1514        return true;
1515    }
1516
1517    const char *mime_from, *mime_to;
1518    CHECK(from->findCString(kKeyMIMEType, &mime_from));
1519    CHECK(to->findCString(kKeyMIMEType, &mime_to));
1520
1521    if (strcasecmp(mime_from, mime_to)) {
1522        return true;
1523    }
1524
1525    if (!strcasecmp(mime_from, MEDIA_MIMETYPE_VIDEO_RAW)) {
1526        int32_t colorFormat_from, colorFormat_to;
1527        CHECK(from->findInt32(kKeyColorFormat, &colorFormat_from));
1528        CHECK(to->findInt32(kKeyColorFormat, &colorFormat_to));
1529
1530        if (colorFormat_from != colorFormat_to) {
1531            return true;
1532        }
1533
1534        int32_t width_from, width_to;
1535        CHECK(from->findInt32(kKeyWidth, &width_from));
1536        CHECK(to->findInt32(kKeyWidth, &width_to));
1537
1538        if (width_from != width_to) {
1539            return true;
1540        }
1541
1542        int32_t height_from, height_to;
1543        CHECK(from->findInt32(kKeyHeight, &height_from));
1544        CHECK(to->findInt32(kKeyHeight, &height_to));
1545
1546        if (height_from != height_to) {
1547            return true;
1548        }
1549    } else if (!strcasecmp(mime_from, MEDIA_MIMETYPE_AUDIO_RAW)) {
1550        int32_t numChannels_from, numChannels_to;
1551        CHECK(from->findInt32(kKeyChannelCount, &numChannels_from));
1552        CHECK(to->findInt32(kKeyChannelCount, &numChannels_to));
1553
1554        if (numChannels_from != numChannels_to) {
1555            return true;
1556        }
1557
1558        int32_t sampleRate_from, sampleRate_to;
1559        CHECK(from->findInt32(kKeySampleRate, &sampleRate_from));
1560        CHECK(to->findInt32(kKeySampleRate, &sampleRate_to));
1561
1562        if (sampleRate_from != sampleRate_to) {
1563            return true;
1564        }
1565    }
1566
1567    return false;
1568}
1569
1570void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) {
1571    switch (cmd) {
1572        case OMX_CommandStateSet:
1573        {
1574            onStateChange((OMX_STATETYPE)data);
1575            break;
1576        }
1577
1578        case OMX_CommandPortDisable:
1579        {
1580            OMX_U32 portIndex = data;
1581            CODEC_LOGV("PORT_DISABLED(%ld)", portIndex);
1582
1583            CHECK(mState == EXECUTING || mState == RECONFIGURING);
1584            CHECK_EQ(mPortStatus[portIndex], DISABLING);
1585            CHECK_EQ(mPortBuffers[portIndex].size(), 0);
1586
1587            mPortStatus[portIndex] = DISABLED;
1588
1589            if (mState == RECONFIGURING) {
1590                CHECK_EQ(portIndex, kPortIndexOutput);
1591
1592                sp<MetaData> oldOutputFormat = mOutputFormat;
1593                initOutputFormat(mSource->getFormat());
1594
1595                // Don't notify clients if the output port settings change
1596                // wasn't of importance to them, i.e. it may be that just the
1597                // number of buffers has changed and nothing else.
1598                mOutputPortSettingsHaveChanged =
1599                    formatHasNotablyChanged(oldOutputFormat, mOutputFormat);
1600
1601                enablePortAsync(portIndex);
1602
1603                status_t err = allocateBuffersOnPort(portIndex);
1604                CHECK_EQ(err, OK);
1605            }
1606            break;
1607        }
1608
1609        case OMX_CommandPortEnable:
1610        {
1611            OMX_U32 portIndex = data;
1612            CODEC_LOGV("PORT_ENABLED(%ld)", portIndex);
1613
1614            CHECK(mState == EXECUTING || mState == RECONFIGURING);
1615            CHECK_EQ(mPortStatus[portIndex], ENABLING);
1616
1617            mPortStatus[portIndex] = ENABLED;
1618
1619            if (mState == RECONFIGURING) {
1620                CHECK_EQ(portIndex, kPortIndexOutput);
1621
1622                setState(EXECUTING);
1623
1624                fillOutputBuffers();
1625            }
1626            break;
1627        }
1628
1629        case OMX_CommandFlush:
1630        {
1631            OMX_U32 portIndex = data;
1632
1633            CODEC_LOGV("FLUSH_DONE(%ld)", portIndex);
1634
1635            CHECK_EQ(mPortStatus[portIndex], SHUTTING_DOWN);
1636            mPortStatus[portIndex] = ENABLED;
1637
1638            CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]),
1639                     mPortBuffers[portIndex].size());
1640
1641            if (mState == RECONFIGURING) {
1642                CHECK_EQ(portIndex, kPortIndexOutput);
1643
1644                disablePortAsync(portIndex);
1645            } else if (mState == EXECUTING_TO_IDLE) {
1646                if (mPortStatus[kPortIndexInput] == ENABLED
1647                    && mPortStatus[kPortIndexOutput] == ENABLED) {
1648                    CODEC_LOGV("Finished flushing both ports, now completing "
1649                         "transition from EXECUTING to IDLE.");
1650
1651                    mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
1652                    mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
1653
1654                    status_t err =
1655                        mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
1656                    CHECK_EQ(err, OK);
1657                }
1658            } else {
1659                // We're flushing both ports in preparation for seeking.
1660
1661                if (mPortStatus[kPortIndexInput] == ENABLED
1662                    && mPortStatus[kPortIndexOutput] == ENABLED) {
1663                    CODEC_LOGV("Finished flushing both ports, now continuing from"
1664                         " seek-time.");
1665
1666                    drainInputBuffers();
1667                    fillOutputBuffers();
1668                }
1669            }
1670
1671            break;
1672        }
1673
1674        default:
1675        {
1676            CODEC_LOGV("CMD_COMPLETE(%d, %ld)", cmd, data);
1677            break;
1678        }
1679    }
1680}
1681
1682void OMXCodec::onStateChange(OMX_STATETYPE newState) {
1683    CODEC_LOGV("onStateChange %d", newState);
1684
1685    switch (newState) {
1686        case OMX_StateIdle:
1687        {
1688            CODEC_LOGV("Now Idle.");
1689            if (mState == LOADED_TO_IDLE) {
1690                status_t err = mOMX->sendCommand(
1691                        mNode, OMX_CommandStateSet, OMX_StateExecuting);
1692
1693                CHECK_EQ(err, OK);
1694
1695                setState(IDLE_TO_EXECUTING);
1696            } else {
1697                CHECK_EQ(mState, EXECUTING_TO_IDLE);
1698
1699                CHECK_EQ(
1700                    countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
1701                    mPortBuffers[kPortIndexInput].size());
1702
1703                CHECK_EQ(
1704                    countBuffersWeOwn(mPortBuffers[kPortIndexOutput]),
1705                    mPortBuffers[kPortIndexOutput].size());
1706
1707                status_t err = mOMX->sendCommand(
1708                        mNode, OMX_CommandStateSet, OMX_StateLoaded);
1709
1710                CHECK_EQ(err, OK);
1711
1712                err = freeBuffersOnPort(kPortIndexInput);
1713                CHECK_EQ(err, OK);
1714
1715                err = freeBuffersOnPort(kPortIndexOutput);
1716                CHECK_EQ(err, OK);
1717
1718                mPortStatus[kPortIndexInput] = ENABLED;
1719                mPortStatus[kPortIndexOutput] = ENABLED;
1720
1721                setState(IDLE_TO_LOADED);
1722            }
1723            break;
1724        }
1725
1726        case OMX_StateExecuting:
1727        {
1728            CHECK_EQ(mState, IDLE_TO_EXECUTING);
1729
1730            CODEC_LOGV("Now Executing.");
1731
1732            setState(EXECUTING);
1733
1734            // Buffers will be submitted to the component in the first
1735            // call to OMXCodec::read as mInitialBufferSubmit is true at
1736            // this point. This ensures that this on_message call returns,
1737            // releases the lock and ::init can notice the state change and
1738            // itself return.
1739            break;
1740        }
1741
1742        case OMX_StateLoaded:
1743        {
1744            CHECK_EQ(mState, IDLE_TO_LOADED);
1745
1746            CODEC_LOGV("Now Loaded.");
1747
1748            setState(LOADED);
1749            break;
1750        }
1751
1752        case OMX_StateInvalid:
1753        {
1754            setState(ERROR);
1755            break;
1756        }
1757
1758        default:
1759        {
1760            CHECK(!"should not be here.");
1761            break;
1762        }
1763    }
1764}
1765
1766// static
1767size_t OMXCodec::countBuffersWeOwn(const Vector<BufferInfo> &buffers) {
1768    size_t n = 0;
1769    for (size_t i = 0; i < buffers.size(); ++i) {
1770        if (!buffers[i].mOwnedByComponent) {
1771            ++n;
1772        }
1773    }
1774
1775    return n;
1776}
1777
1778status_t OMXCodec::freeBuffersOnPort(
1779        OMX_U32 portIndex, bool onlyThoseWeOwn) {
1780    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
1781
1782    status_t stickyErr = OK;
1783
1784    for (size_t i = buffers->size(); i-- > 0;) {
1785        BufferInfo *info = &buffers->editItemAt(i);
1786
1787        if (onlyThoseWeOwn && info->mOwnedByComponent) {
1788            continue;
1789        }
1790
1791        CHECK_EQ(info->mOwnedByComponent, false);
1792
1793        CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex);
1794
1795        status_t err =
1796            mOMX->freeBuffer(mNode, portIndex, info->mBuffer);
1797
1798        if (err != OK) {
1799            stickyErr = err;
1800        }
1801
1802        if (info->mMediaBuffer != NULL) {
1803            info->mMediaBuffer->setObserver(NULL);
1804
1805            // Make sure nobody but us owns this buffer at this point.
1806            CHECK_EQ(info->mMediaBuffer->refcount(), 0);
1807
1808            info->mMediaBuffer->release();
1809        }
1810
1811        buffers->removeAt(i);
1812    }
1813
1814    CHECK(onlyThoseWeOwn || buffers->isEmpty());
1815
1816    return stickyErr;
1817}
1818
1819void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) {
1820    CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex);
1821
1822    CHECK_EQ(mState, EXECUTING);
1823    CHECK_EQ(portIndex, kPortIndexOutput);
1824    setState(RECONFIGURING);
1825
1826    if (mQuirks & kNeedsFlushBeforeDisable) {
1827        if (!flushPortAsync(portIndex)) {
1828            onCmdComplete(OMX_CommandFlush, portIndex);
1829        }
1830    } else {
1831        disablePortAsync(portIndex);
1832    }
1833}
1834
1835bool OMXCodec::flushPortAsync(OMX_U32 portIndex) {
1836    CHECK(mState == EXECUTING || mState == RECONFIGURING
1837            || mState == EXECUTING_TO_IDLE);
1838
1839    CODEC_LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.",
1840         portIndex, countBuffersWeOwn(mPortBuffers[portIndex]),
1841         mPortBuffers[portIndex].size());
1842
1843    CHECK_EQ(mPortStatus[portIndex], ENABLED);
1844    mPortStatus[portIndex] = SHUTTING_DOWN;
1845
1846    if ((mQuirks & kRequiresFlushCompleteEmulation)
1847        && countBuffersWeOwn(mPortBuffers[portIndex])
1848                == mPortBuffers[portIndex].size()) {
1849        // No flush is necessary and this component fails to send a
1850        // flush-complete event in this case.
1851
1852        return false;
1853    }
1854
1855    status_t err =
1856        mOMX->sendCommand(mNode, OMX_CommandFlush, portIndex);
1857    CHECK_EQ(err, OK);
1858
1859    return true;
1860}
1861
1862void OMXCodec::disablePortAsync(OMX_U32 portIndex) {
1863    CHECK(mState == EXECUTING || mState == RECONFIGURING);
1864
1865    CHECK_EQ(mPortStatus[portIndex], ENABLED);
1866    mPortStatus[portIndex] = DISABLING;
1867
1868    status_t err =
1869        mOMX->sendCommand(mNode, OMX_CommandPortDisable, portIndex);
1870    CHECK_EQ(err, OK);
1871
1872    freeBuffersOnPort(portIndex, true);
1873}
1874
1875void OMXCodec::enablePortAsync(OMX_U32 portIndex) {
1876    CHECK(mState == EXECUTING || mState == RECONFIGURING);
1877
1878    CHECK_EQ(mPortStatus[portIndex], DISABLED);
1879    mPortStatus[portIndex] = ENABLING;
1880
1881    status_t err =
1882        mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex);
1883    CHECK_EQ(err, OK);
1884}
1885
1886void OMXCodec::fillOutputBuffers() {
1887    CHECK_EQ(mState, EXECUTING);
1888
1889    // This is a workaround for some decoders not properly reporting
1890    // end-of-output-stream. If we own all input buffers and also own
1891    // all output buffers and we already signalled end-of-input-stream,
1892    // the end-of-output-stream is implied.
1893    if (mSignalledEOS
1894            && countBuffersWeOwn(mPortBuffers[kPortIndexInput])
1895                == mPortBuffers[kPortIndexInput].size()
1896            && countBuffersWeOwn(mPortBuffers[kPortIndexOutput])
1897                == mPortBuffers[kPortIndexOutput].size()) {
1898        mNoMoreOutputData = true;
1899        mBufferFilled.signal();
1900
1901        return;
1902    }
1903
1904    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
1905    for (size_t i = 0; i < buffers->size(); ++i) {
1906        fillOutputBuffer(&buffers->editItemAt(i));
1907    }
1908}
1909
1910void OMXCodec::drainInputBuffers() {
1911    CHECK(mState == EXECUTING || mState == RECONFIGURING);
1912
1913    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
1914    for (size_t i = 0; i < buffers->size(); ++i) {
1915        drainInputBuffer(&buffers->editItemAt(i));
1916    }
1917}
1918
1919void OMXCodec::drainInputBuffer(BufferInfo *info) {
1920    CHECK_EQ(info->mOwnedByComponent, false);
1921
1922    if (mSignalledEOS) {
1923        return;
1924    }
1925
1926    if (mCodecSpecificDataIndex < mCodecSpecificData.size()) {
1927        const CodecSpecificData *specific =
1928            mCodecSpecificData[mCodecSpecificDataIndex];
1929
1930        size_t size = specific->mSize;
1931
1932        if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME)
1933                && !(mQuirks & kWantsNALFragments)) {
1934            static const uint8_t kNALStartCode[4] =
1935                    { 0x00, 0x00, 0x00, 0x01 };
1936
1937            CHECK(info->mSize >= specific->mSize + 4);
1938
1939            size += 4;
1940
1941            memcpy(info->mData, kNALStartCode, 4);
1942            memcpy((uint8_t *)info->mData + 4,
1943                   specific->mData, specific->mSize);
1944        } else {
1945            CHECK(info->mSize >= specific->mSize);
1946            memcpy(info->mData, specific->mData, specific->mSize);
1947        }
1948
1949        mNoMoreOutputData = false;
1950
1951        CODEC_LOGV("calling emptyBuffer with codec specific data");
1952
1953        status_t err = mOMX->emptyBuffer(
1954                mNode, info->mBuffer, 0, size,
1955                OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG,
1956                0);
1957        CHECK_EQ(err, OK);
1958
1959        info->mOwnedByComponent = true;
1960
1961        ++mCodecSpecificDataIndex;
1962        return;
1963    }
1964
1965    status_t err;
1966
1967    bool signalEOS = false;
1968    int64_t timestampUs = 0;
1969
1970    size_t offset = 0;
1971    int32_t n = 0;
1972    for (;;) {
1973        MediaBuffer *srcBuffer;
1974        if (mSeekTimeUs >= 0) {
1975            if (mLeftOverBuffer) {
1976                mLeftOverBuffer->release();
1977                mLeftOverBuffer = NULL;
1978            }
1979
1980            MediaSource::ReadOptions options;
1981            options.setSeekTo(mSeekTimeUs);
1982
1983            mSeekTimeUs = -1;
1984            mBufferFilled.signal();
1985
1986            err = mSource->read(&srcBuffer, &options);
1987        } else if (mLeftOverBuffer) {
1988            srcBuffer = mLeftOverBuffer;
1989            mLeftOverBuffer = NULL;
1990
1991            err = OK;
1992        } else {
1993            err = mSource->read(&srcBuffer);
1994        }
1995
1996        if (err != OK) {
1997            signalEOS = true;
1998            mFinalStatus = err;
1999            mSignalledEOS = true;
2000            break;
2001        }
2002
2003        size_t remainingBytes = info->mSize - offset;
2004
2005        if (srcBuffer->range_length() > remainingBytes) {
2006            if (offset == 0) {
2007                CODEC_LOGE(
2008                     "Codec's input buffers are too small to accomodate "
2009                     "buffer read from source (info->mSize = %d, srcLength = %d)",
2010                     info->mSize, srcBuffer->range_length());
2011
2012                srcBuffer->release();
2013                srcBuffer = NULL;
2014
2015                setState(ERROR);
2016                return;
2017            }
2018
2019            mLeftOverBuffer = srcBuffer;
2020            break;
2021        }
2022
2023        memcpy((uint8_t *)info->mData + offset,
2024               (const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(),
2025               srcBuffer->range_length());
2026
2027        if (offset == 0) {
2028            CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &timestampUs));
2029            CHECK(timestampUs >= 0);
2030        }
2031
2032        offset += srcBuffer->range_length();
2033
2034        srcBuffer->release();
2035        srcBuffer = NULL;
2036
2037        ++n;
2038
2039        if (!(mQuirks & kSupportsMultipleFramesPerInputBuffer)) {
2040            break;
2041        }
2042    }
2043
2044    if (n > 1) {
2045        LOGV("coalesced %d frames into one input buffer", n);
2046    }
2047
2048    OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
2049
2050    if (signalEOS) {
2051        flags |= OMX_BUFFERFLAG_EOS;
2052    } else {
2053        mNoMoreOutputData = false;
2054    }
2055
2056    CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d), "
2057               "timestamp %lld us (%.2f secs)",
2058               info->mBuffer, offset,
2059               timestampUs, timestampUs / 1E6);
2060
2061    err = mOMX->emptyBuffer(
2062            mNode, info->mBuffer, 0, offset,
2063            flags, timestampUs);
2064
2065    if (err != OK) {
2066        setState(ERROR);
2067        return;
2068    }
2069
2070    info->mOwnedByComponent = true;
2071
2072    // This component does not ever signal the EOS flag on output buffers,
2073    // Thanks for nothing.
2074    if (mSignalledEOS && !strcmp(mComponentName, "OMX.TI.Video.encoder")) {
2075        mNoMoreOutputData = true;
2076        mBufferFilled.signal();
2077    }
2078}
2079
2080void OMXCodec::fillOutputBuffer(BufferInfo *info) {
2081    CHECK_EQ(info->mOwnedByComponent, false);
2082
2083    if (mNoMoreOutputData) {
2084        CODEC_LOGV("There is no more output data available, not "
2085             "calling fillOutputBuffer");
2086        return;
2087    }
2088
2089    CODEC_LOGV("Calling fill_buffer on buffer %p", info->mBuffer);
2090    status_t err = mOMX->fillBuffer(mNode, info->mBuffer);
2091    CHECK_EQ(err, OK);
2092
2093    info->mOwnedByComponent = true;
2094}
2095
2096void OMXCodec::drainInputBuffer(IOMX::buffer_id buffer) {
2097    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
2098    for (size_t i = 0; i < buffers->size(); ++i) {
2099        if ((*buffers)[i].mBuffer == buffer) {
2100            drainInputBuffer(&buffers->editItemAt(i));
2101            return;
2102        }
2103    }
2104
2105    CHECK(!"should not be here.");
2106}
2107
2108void OMXCodec::fillOutputBuffer(IOMX::buffer_id buffer) {
2109    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
2110    for (size_t i = 0; i < buffers->size(); ++i) {
2111        if ((*buffers)[i].mBuffer == buffer) {
2112            fillOutputBuffer(&buffers->editItemAt(i));
2113            return;
2114        }
2115    }
2116
2117    CHECK(!"should not be here.");
2118}
2119
2120void OMXCodec::setState(State newState) {
2121    mState = newState;
2122    mAsyncCompletion.signal();
2123
2124    // This may cause some spurious wakeups but is necessary to
2125    // unblock the reader if we enter ERROR state.
2126    mBufferFilled.signal();
2127}
2128
2129void OMXCodec::setRawAudioFormat(
2130        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
2131    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2132    InitOMXParams(&pcmParams);
2133    pcmParams.nPortIndex = portIndex;
2134
2135    status_t err = mOMX->getParameter(
2136            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2137
2138    CHECK_EQ(err, OK);
2139
2140    pcmParams.nChannels = numChannels;
2141    pcmParams.eNumData = OMX_NumericalDataSigned;
2142    pcmParams.bInterleaved = OMX_TRUE;
2143    pcmParams.nBitPerSample = 16;
2144    pcmParams.nSamplingRate = sampleRate;
2145    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2146
2147    if (numChannels == 1) {
2148        pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelCF;
2149    } else {
2150        CHECK_EQ(numChannels, 2);
2151
2152        pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
2153        pcmParams.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
2154    }
2155
2156    err = mOMX->setParameter(
2157            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2158
2159    CHECK_EQ(err, OK);
2160}
2161
2162void OMXCodec::setAMRFormat(bool isWAMR) {
2163    OMX_U32 portIndex = mIsEncoder ? kPortIndexOutput : kPortIndexInput;
2164
2165    OMX_AUDIO_PARAM_AMRTYPE def;
2166    InitOMXParams(&def);
2167    def.nPortIndex = portIndex;
2168
2169    status_t err =
2170        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2171
2172    CHECK_EQ(err, OK);
2173
2174    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
2175    def.eAMRBandMode =
2176        isWAMR ? OMX_AUDIO_AMRBandModeWB0 : OMX_AUDIO_AMRBandModeNB0;
2177
2178    err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2179    CHECK_EQ(err, OK);
2180
2181    ////////////////////////
2182
2183    if (mIsEncoder) {
2184        sp<MetaData> format = mSource->getFormat();
2185        int32_t sampleRate;
2186        int32_t numChannels;
2187        CHECK(format->findInt32(kKeySampleRate, &sampleRate));
2188        CHECK(format->findInt32(kKeyChannelCount, &numChannels));
2189
2190        setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
2191    }
2192}
2193
2194void OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate) {
2195    if (mIsEncoder) {
2196        setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
2197    } else {
2198        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2199        InitOMXParams(&profile);
2200        profile.nPortIndex = kPortIndexInput;
2201
2202        status_t err = mOMX->getParameter(
2203                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2204        CHECK_EQ(err, OK);
2205
2206        profile.nChannels = numChannels;
2207        profile.nSampleRate = sampleRate;
2208        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
2209
2210        err = mOMX->setParameter(
2211                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2212        CHECK_EQ(err, OK);
2213    }
2214}
2215
2216void OMXCodec::setImageOutputFormat(
2217        OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) {
2218    CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height);
2219
2220#if 0
2221    OMX_INDEXTYPE index;
2222    status_t err = mOMX->get_extension_index(
2223            mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index);
2224    CHECK_EQ(err, OK);
2225
2226    err = mOMX->set_config(mNode, index, &format, sizeof(format));
2227    CHECK_EQ(err, OK);
2228#endif
2229
2230    OMX_PARAM_PORTDEFINITIONTYPE def;
2231    InitOMXParams(&def);
2232    def.nPortIndex = kPortIndexOutput;
2233
2234    status_t err = mOMX->getParameter(
2235            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2236    CHECK_EQ(err, OK);
2237
2238    CHECK_EQ(def.eDomain, OMX_PortDomainImage);
2239
2240    OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
2241
2242    CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused);
2243    imageDef->eColorFormat = format;
2244    imageDef->nFrameWidth = width;
2245    imageDef->nFrameHeight = height;
2246
2247    switch (format) {
2248        case OMX_COLOR_FormatYUV420PackedPlanar:
2249        case OMX_COLOR_FormatYUV411Planar:
2250        {
2251            def.nBufferSize = (width * height * 3) / 2;
2252            break;
2253        }
2254
2255        case OMX_COLOR_FormatCbYCrY:
2256        {
2257            def.nBufferSize = width * height * 2;
2258            break;
2259        }
2260
2261        case OMX_COLOR_Format32bitARGB8888:
2262        {
2263            def.nBufferSize = width * height * 4;
2264            break;
2265        }
2266
2267        case OMX_COLOR_Format16bitARGB4444:
2268        case OMX_COLOR_Format16bitARGB1555:
2269        case OMX_COLOR_Format16bitRGB565:
2270        case OMX_COLOR_Format16bitBGR565:
2271        {
2272            def.nBufferSize = width * height * 2;
2273            break;
2274        }
2275
2276        default:
2277            CHECK(!"Should not be here. Unknown color format.");
2278            break;
2279    }
2280
2281    def.nBufferCountActual = def.nBufferCountMin;
2282
2283    err = mOMX->setParameter(
2284            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2285    CHECK_EQ(err, OK);
2286}
2287
2288void OMXCodec::setJPEGInputFormat(
2289        OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) {
2290    OMX_PARAM_PORTDEFINITIONTYPE def;
2291    InitOMXParams(&def);
2292    def.nPortIndex = kPortIndexInput;
2293
2294    status_t err = mOMX->getParameter(
2295            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2296    CHECK_EQ(err, OK);
2297
2298    CHECK_EQ(def.eDomain, OMX_PortDomainImage);
2299    OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
2300
2301    CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingJPEG);
2302    imageDef->nFrameWidth = width;
2303    imageDef->nFrameHeight = height;
2304
2305    def.nBufferSize = compressedSize;
2306    def.nBufferCountActual = def.nBufferCountMin;
2307
2308    err = mOMX->setParameter(
2309            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2310    CHECK_EQ(err, OK);
2311}
2312
2313void OMXCodec::addCodecSpecificData(const void *data, size_t size) {
2314    CodecSpecificData *specific =
2315        (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1);
2316
2317    specific->mSize = size;
2318    memcpy(specific->mData, data, size);
2319
2320    mCodecSpecificData.push(specific);
2321}
2322
2323void OMXCodec::clearCodecSpecificData() {
2324    for (size_t i = 0; i < mCodecSpecificData.size(); ++i) {
2325        free(mCodecSpecificData.editItemAt(i));
2326    }
2327    mCodecSpecificData.clear();
2328    mCodecSpecificDataIndex = 0;
2329}
2330
2331status_t OMXCodec::start(MetaData *) {
2332    Mutex::Autolock autoLock(mLock);
2333
2334    if (mState != LOADED) {
2335        return UNKNOWN_ERROR;
2336    }
2337
2338    sp<MetaData> params = new MetaData;
2339    if (mQuirks & kWantsNALFragments) {
2340        params->setInt32(kKeyWantsNALFragments, true);
2341    }
2342    status_t err = mSource->start(params.get());
2343
2344    if (err != OK) {
2345        return err;
2346    }
2347
2348    mCodecSpecificDataIndex = 0;
2349    mInitialBufferSubmit = true;
2350    mSignalledEOS = false;
2351    mNoMoreOutputData = false;
2352    mOutputPortSettingsHaveChanged = false;
2353    mSeekTimeUs = -1;
2354    mFilledBuffers.clear();
2355
2356    return init();
2357}
2358
2359status_t OMXCodec::stop() {
2360    CODEC_LOGV("stop mState=%d", mState);
2361
2362    Mutex::Autolock autoLock(mLock);
2363
2364    while (isIntermediateState(mState)) {
2365        mAsyncCompletion.wait(mLock);
2366    }
2367
2368    switch (mState) {
2369        case LOADED:
2370        case ERROR:
2371            break;
2372
2373        case EXECUTING:
2374        {
2375            setState(EXECUTING_TO_IDLE);
2376
2377            if (mQuirks & kRequiresFlushBeforeShutdown) {
2378                CODEC_LOGV("This component requires a flush before transitioning "
2379                     "from EXECUTING to IDLE...");
2380
2381                bool emulateInputFlushCompletion =
2382                    !flushPortAsync(kPortIndexInput);
2383
2384                bool emulateOutputFlushCompletion =
2385                    !flushPortAsync(kPortIndexOutput);
2386
2387                if (emulateInputFlushCompletion) {
2388                    onCmdComplete(OMX_CommandFlush, kPortIndexInput);
2389                }
2390
2391                if (emulateOutputFlushCompletion) {
2392                    onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
2393                }
2394            } else {
2395                mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
2396                mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
2397
2398                status_t err =
2399                    mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
2400                CHECK_EQ(err, OK);
2401            }
2402
2403            while (mState != LOADED && mState != ERROR) {
2404                mAsyncCompletion.wait(mLock);
2405            }
2406
2407            break;
2408        }
2409
2410        default:
2411        {
2412            CHECK(!"should not be here.");
2413            break;
2414        }
2415    }
2416
2417    if (mLeftOverBuffer) {
2418        mLeftOverBuffer->release();
2419        mLeftOverBuffer = NULL;
2420    }
2421
2422    mSource->stop();
2423
2424    CODEC_LOGV("stopped");
2425
2426    return OK;
2427}
2428
2429sp<MetaData> OMXCodec::getFormat() {
2430    Mutex::Autolock autoLock(mLock);
2431
2432    return mOutputFormat;
2433}
2434
2435status_t OMXCodec::read(
2436        MediaBuffer **buffer, const ReadOptions *options) {
2437    *buffer = NULL;
2438
2439    Mutex::Autolock autoLock(mLock);
2440
2441    if (mState != EXECUTING && mState != RECONFIGURING) {
2442        return UNKNOWN_ERROR;
2443    }
2444
2445    bool seeking = false;
2446    int64_t seekTimeUs;
2447    if (options && options->getSeekTo(&seekTimeUs)) {
2448        seeking = true;
2449    }
2450
2451    if (mInitialBufferSubmit) {
2452        mInitialBufferSubmit = false;
2453
2454        if (seeking) {
2455            CHECK(seekTimeUs >= 0);
2456            mSeekTimeUs = seekTimeUs;
2457
2458            // There's no reason to trigger the code below, there's
2459            // nothing to flush yet.
2460            seeking = false;
2461        }
2462
2463        drainInputBuffers();
2464
2465        if (mState == EXECUTING) {
2466            // Otherwise mState == RECONFIGURING and this code will trigger
2467            // after the output port is reenabled.
2468            fillOutputBuffers();
2469        }
2470    }
2471
2472    if (seeking) {
2473        CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6);
2474
2475        mSignalledEOS = false;
2476
2477        CHECK(seekTimeUs >= 0);
2478        mSeekTimeUs = seekTimeUs;
2479
2480        mFilledBuffers.clear();
2481
2482        CHECK_EQ(mState, EXECUTING);
2483
2484        bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput);
2485        bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput);
2486
2487        if (emulateInputFlushCompletion) {
2488            onCmdComplete(OMX_CommandFlush, kPortIndexInput);
2489        }
2490
2491        if (emulateOutputFlushCompletion) {
2492            onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
2493        }
2494
2495        while (mSeekTimeUs >= 0) {
2496            mBufferFilled.wait(mLock);
2497        }
2498    }
2499
2500    while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) {
2501        mBufferFilled.wait(mLock);
2502    }
2503
2504    if (mState == ERROR) {
2505        return UNKNOWN_ERROR;
2506    }
2507
2508    if (mFilledBuffers.empty()) {
2509        return mSignalledEOS ? mFinalStatus : ERROR_END_OF_STREAM;
2510    }
2511
2512    if (mOutputPortSettingsHaveChanged) {
2513        mOutputPortSettingsHaveChanged = false;
2514
2515        return INFO_FORMAT_CHANGED;
2516    }
2517
2518    size_t index = *mFilledBuffers.begin();
2519    mFilledBuffers.erase(mFilledBuffers.begin());
2520
2521    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
2522    info->mMediaBuffer->add_ref();
2523    *buffer = info->mMediaBuffer;
2524
2525    return OK;
2526}
2527
2528void OMXCodec::signalBufferReturned(MediaBuffer *buffer) {
2529    Mutex::Autolock autoLock(mLock);
2530
2531    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
2532    for (size_t i = 0; i < buffers->size(); ++i) {
2533        BufferInfo *info = &buffers->editItemAt(i);
2534
2535        if (info->mMediaBuffer == buffer) {
2536            CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED);
2537            fillOutputBuffer(info);
2538            return;
2539        }
2540    }
2541
2542    CHECK(!"should not be here.");
2543}
2544
2545static const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) {
2546    static const char *kNames[] = {
2547        "OMX_IMAGE_CodingUnused",
2548        "OMX_IMAGE_CodingAutoDetect",
2549        "OMX_IMAGE_CodingJPEG",
2550        "OMX_IMAGE_CodingJPEG2K",
2551        "OMX_IMAGE_CodingEXIF",
2552        "OMX_IMAGE_CodingTIFF",
2553        "OMX_IMAGE_CodingGIF",
2554        "OMX_IMAGE_CodingPNG",
2555        "OMX_IMAGE_CodingLZW",
2556        "OMX_IMAGE_CodingBMP",
2557    };
2558
2559    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2560
2561    if (type < 0 || (size_t)type >= numNames) {
2562        return "UNKNOWN";
2563    } else {
2564        return kNames[type];
2565    }
2566}
2567
2568static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) {
2569    static const char *kNames[] = {
2570        "OMX_COLOR_FormatUnused",
2571        "OMX_COLOR_FormatMonochrome",
2572        "OMX_COLOR_Format8bitRGB332",
2573        "OMX_COLOR_Format12bitRGB444",
2574        "OMX_COLOR_Format16bitARGB4444",
2575        "OMX_COLOR_Format16bitARGB1555",
2576        "OMX_COLOR_Format16bitRGB565",
2577        "OMX_COLOR_Format16bitBGR565",
2578        "OMX_COLOR_Format18bitRGB666",
2579        "OMX_COLOR_Format18bitARGB1665",
2580        "OMX_COLOR_Format19bitARGB1666",
2581        "OMX_COLOR_Format24bitRGB888",
2582        "OMX_COLOR_Format24bitBGR888",
2583        "OMX_COLOR_Format24bitARGB1887",
2584        "OMX_COLOR_Format25bitARGB1888",
2585        "OMX_COLOR_Format32bitBGRA8888",
2586        "OMX_COLOR_Format32bitARGB8888",
2587        "OMX_COLOR_FormatYUV411Planar",
2588        "OMX_COLOR_FormatYUV411PackedPlanar",
2589        "OMX_COLOR_FormatYUV420Planar",
2590        "OMX_COLOR_FormatYUV420PackedPlanar",
2591        "OMX_COLOR_FormatYUV420SemiPlanar",
2592        "OMX_COLOR_FormatYUV422Planar",
2593        "OMX_COLOR_FormatYUV422PackedPlanar",
2594        "OMX_COLOR_FormatYUV422SemiPlanar",
2595        "OMX_COLOR_FormatYCbYCr",
2596        "OMX_COLOR_FormatYCrYCb",
2597        "OMX_COLOR_FormatCbYCrY",
2598        "OMX_COLOR_FormatCrYCbY",
2599        "OMX_COLOR_FormatYUV444Interleaved",
2600        "OMX_COLOR_FormatRawBayer8bit",
2601        "OMX_COLOR_FormatRawBayer10bit",
2602        "OMX_COLOR_FormatRawBayer8bitcompressed",
2603        "OMX_COLOR_FormatL2",
2604        "OMX_COLOR_FormatL4",
2605        "OMX_COLOR_FormatL8",
2606        "OMX_COLOR_FormatL16",
2607        "OMX_COLOR_FormatL24",
2608        "OMX_COLOR_FormatL32",
2609        "OMX_COLOR_FormatYUV420PackedSemiPlanar",
2610        "OMX_COLOR_FormatYUV422PackedSemiPlanar",
2611        "OMX_COLOR_Format18BitBGR666",
2612        "OMX_COLOR_Format24BitARGB6666",
2613        "OMX_COLOR_Format24BitABGR6666",
2614    };
2615
2616    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2617
2618    if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) {
2619        return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar";
2620    } else if (type < 0 || (size_t)type >= numNames) {
2621        return "UNKNOWN";
2622    } else {
2623        return kNames[type];
2624    }
2625}
2626
2627static const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) {
2628    static const char *kNames[] = {
2629        "OMX_VIDEO_CodingUnused",
2630        "OMX_VIDEO_CodingAutoDetect",
2631        "OMX_VIDEO_CodingMPEG2",
2632        "OMX_VIDEO_CodingH263",
2633        "OMX_VIDEO_CodingMPEG4",
2634        "OMX_VIDEO_CodingWMV",
2635        "OMX_VIDEO_CodingRV",
2636        "OMX_VIDEO_CodingAVC",
2637        "OMX_VIDEO_CodingMJPEG",
2638    };
2639
2640    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2641
2642    if (type < 0 || (size_t)type >= numNames) {
2643        return "UNKNOWN";
2644    } else {
2645        return kNames[type];
2646    }
2647}
2648
2649static const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) {
2650    static const char *kNames[] = {
2651        "OMX_AUDIO_CodingUnused",
2652        "OMX_AUDIO_CodingAutoDetect",
2653        "OMX_AUDIO_CodingPCM",
2654        "OMX_AUDIO_CodingADPCM",
2655        "OMX_AUDIO_CodingAMR",
2656        "OMX_AUDIO_CodingGSMFR",
2657        "OMX_AUDIO_CodingGSMEFR",
2658        "OMX_AUDIO_CodingGSMHR",
2659        "OMX_AUDIO_CodingPDCFR",
2660        "OMX_AUDIO_CodingPDCEFR",
2661        "OMX_AUDIO_CodingPDCHR",
2662        "OMX_AUDIO_CodingTDMAFR",
2663        "OMX_AUDIO_CodingTDMAEFR",
2664        "OMX_AUDIO_CodingQCELP8",
2665        "OMX_AUDIO_CodingQCELP13",
2666        "OMX_AUDIO_CodingEVRC",
2667        "OMX_AUDIO_CodingSMV",
2668        "OMX_AUDIO_CodingG711",
2669        "OMX_AUDIO_CodingG723",
2670        "OMX_AUDIO_CodingG726",
2671        "OMX_AUDIO_CodingG729",
2672        "OMX_AUDIO_CodingAAC",
2673        "OMX_AUDIO_CodingMP3",
2674        "OMX_AUDIO_CodingSBC",
2675        "OMX_AUDIO_CodingVORBIS",
2676        "OMX_AUDIO_CodingWMA",
2677        "OMX_AUDIO_CodingRA",
2678        "OMX_AUDIO_CodingMIDI",
2679    };
2680
2681    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2682
2683    if (type < 0 || (size_t)type >= numNames) {
2684        return "UNKNOWN";
2685    } else {
2686        return kNames[type];
2687    }
2688}
2689
2690static const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) {
2691    static const char *kNames[] = {
2692        "OMX_AUDIO_PCMModeLinear",
2693        "OMX_AUDIO_PCMModeALaw",
2694        "OMX_AUDIO_PCMModeMULaw",
2695    };
2696
2697    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2698
2699    if (type < 0 || (size_t)type >= numNames) {
2700        return "UNKNOWN";
2701    } else {
2702        return kNames[type];
2703    }
2704}
2705
2706static const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) {
2707    static const char *kNames[] = {
2708        "OMX_AUDIO_AMRBandModeUnused",
2709        "OMX_AUDIO_AMRBandModeNB0",
2710        "OMX_AUDIO_AMRBandModeNB1",
2711        "OMX_AUDIO_AMRBandModeNB2",
2712        "OMX_AUDIO_AMRBandModeNB3",
2713        "OMX_AUDIO_AMRBandModeNB4",
2714        "OMX_AUDIO_AMRBandModeNB5",
2715        "OMX_AUDIO_AMRBandModeNB6",
2716        "OMX_AUDIO_AMRBandModeNB7",
2717        "OMX_AUDIO_AMRBandModeWB0",
2718        "OMX_AUDIO_AMRBandModeWB1",
2719        "OMX_AUDIO_AMRBandModeWB2",
2720        "OMX_AUDIO_AMRBandModeWB3",
2721        "OMX_AUDIO_AMRBandModeWB4",
2722        "OMX_AUDIO_AMRBandModeWB5",
2723        "OMX_AUDIO_AMRBandModeWB6",
2724        "OMX_AUDIO_AMRBandModeWB7",
2725        "OMX_AUDIO_AMRBandModeWB8",
2726    };
2727
2728    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2729
2730    if (type < 0 || (size_t)type >= numNames) {
2731        return "UNKNOWN";
2732    } else {
2733        return kNames[type];
2734    }
2735}
2736
2737static const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) {
2738    static const char *kNames[] = {
2739        "OMX_AUDIO_AMRFrameFormatConformance",
2740        "OMX_AUDIO_AMRFrameFormatIF1",
2741        "OMX_AUDIO_AMRFrameFormatIF2",
2742        "OMX_AUDIO_AMRFrameFormatFSF",
2743        "OMX_AUDIO_AMRFrameFormatRTPPayload",
2744        "OMX_AUDIO_AMRFrameFormatITU",
2745    };
2746
2747    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2748
2749    if (type < 0 || (size_t)type >= numNames) {
2750        return "UNKNOWN";
2751    } else {
2752        return kNames[type];
2753    }
2754}
2755
2756void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
2757    OMX_PARAM_PORTDEFINITIONTYPE def;
2758    InitOMXParams(&def);
2759    def.nPortIndex = portIndex;
2760
2761    status_t err = mOMX->getParameter(
2762            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2763    CHECK_EQ(err, OK);
2764
2765    printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output");
2766
2767    CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput)
2768          || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput));
2769
2770    printf("  nBufferCountActual = %ld\n", def.nBufferCountActual);
2771    printf("  nBufferCountMin = %ld\n", def.nBufferCountMin);
2772    printf("  nBufferSize = %ld\n", def.nBufferSize);
2773
2774    switch (def.eDomain) {
2775        case OMX_PortDomainImage:
2776        {
2777            const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
2778
2779            printf("\n");
2780            printf("  // Image\n");
2781            printf("  nFrameWidth = %ld\n", imageDef->nFrameWidth);
2782            printf("  nFrameHeight = %ld\n", imageDef->nFrameHeight);
2783            printf("  nStride = %ld\n", imageDef->nStride);
2784
2785            printf("  eCompressionFormat = %s\n",
2786                   imageCompressionFormatString(imageDef->eCompressionFormat));
2787
2788            printf("  eColorFormat = %s\n",
2789                   colorFormatString(imageDef->eColorFormat));
2790
2791            break;
2792        }
2793
2794        case OMX_PortDomainVideo:
2795        {
2796            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
2797
2798            printf("\n");
2799            printf("  // Video\n");
2800            printf("  nFrameWidth = %ld\n", videoDef->nFrameWidth);
2801            printf("  nFrameHeight = %ld\n", videoDef->nFrameHeight);
2802            printf("  nStride = %ld\n", videoDef->nStride);
2803
2804            printf("  eCompressionFormat = %s\n",
2805                   videoCompressionFormatString(videoDef->eCompressionFormat));
2806
2807            printf("  eColorFormat = %s\n",
2808                   colorFormatString(videoDef->eColorFormat));
2809
2810            break;
2811        }
2812
2813        case OMX_PortDomainAudio:
2814        {
2815            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
2816
2817            printf("\n");
2818            printf("  // Audio\n");
2819            printf("  eEncoding = %s\n",
2820                   audioCodingTypeString(audioDef->eEncoding));
2821
2822            if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) {
2823                OMX_AUDIO_PARAM_PCMMODETYPE params;
2824                InitOMXParams(&params);
2825                params.nPortIndex = portIndex;
2826
2827                err = mOMX->getParameter(
2828                        mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
2829                CHECK_EQ(err, OK);
2830
2831                printf("  nSamplingRate = %ld\n", params.nSamplingRate);
2832                printf("  nChannels = %ld\n", params.nChannels);
2833                printf("  bInterleaved = %d\n", params.bInterleaved);
2834                printf("  nBitPerSample = %ld\n", params.nBitPerSample);
2835
2836                printf("  eNumData = %s\n",
2837                       params.eNumData == OMX_NumericalDataSigned
2838                        ? "signed" : "unsigned");
2839
2840                printf("  ePCMMode = %s\n", audioPCMModeString(params.ePCMMode));
2841            } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) {
2842                OMX_AUDIO_PARAM_AMRTYPE amr;
2843                InitOMXParams(&amr);
2844                amr.nPortIndex = portIndex;
2845
2846                err = mOMX->getParameter(
2847                        mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
2848                CHECK_EQ(err, OK);
2849
2850                printf("  nChannels = %ld\n", amr.nChannels);
2851                printf("  eAMRBandMode = %s\n",
2852                        amrBandModeString(amr.eAMRBandMode));
2853                printf("  eAMRFrameFormat = %s\n",
2854                        amrFrameFormatString(amr.eAMRFrameFormat));
2855            }
2856
2857            break;
2858        }
2859
2860        default:
2861        {
2862            printf("  // Unknown\n");
2863            break;
2864        }
2865    }
2866
2867    printf("}\n");
2868}
2869
2870void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
2871    mOutputFormat = new MetaData;
2872    mOutputFormat->setCString(kKeyDecoderComponent, mComponentName);
2873
2874    OMX_PARAM_PORTDEFINITIONTYPE def;
2875    InitOMXParams(&def);
2876    def.nPortIndex = kPortIndexOutput;
2877
2878    status_t err = mOMX->getParameter(
2879            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2880    CHECK_EQ(err, OK);
2881
2882    switch (def.eDomain) {
2883        case OMX_PortDomainImage:
2884        {
2885            OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
2886            CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused);
2887
2888            mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
2889            mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat);
2890            mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth);
2891            mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight);
2892            break;
2893        }
2894
2895        case OMX_PortDomainAudio:
2896        {
2897            OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio;
2898
2899            if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) {
2900                OMX_AUDIO_PARAM_PCMMODETYPE params;
2901                InitOMXParams(&params);
2902                params.nPortIndex = kPortIndexOutput;
2903
2904                err = mOMX->getParameter(
2905                        mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
2906                CHECK_EQ(err, OK);
2907
2908                CHECK_EQ(params.eNumData, OMX_NumericalDataSigned);
2909                CHECK_EQ(params.nBitPerSample, 16);
2910                CHECK_EQ(params.ePCMMode, OMX_AUDIO_PCMModeLinear);
2911
2912                int32_t numChannels, sampleRate;
2913                inputFormat->findInt32(kKeyChannelCount, &numChannels);
2914                inputFormat->findInt32(kKeySampleRate, &sampleRate);
2915
2916                if ((OMX_U32)numChannels != params.nChannels) {
2917                    LOGW("Codec outputs a different number of channels than "
2918                         "the input stream contains (contains %d channels, "
2919                         "codec outputs %ld channels).",
2920                         numChannels, params.nChannels);
2921                }
2922
2923                mOutputFormat->setCString(
2924                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
2925
2926                // Use the codec-advertised number of channels, as some
2927                // codecs appear to output stereo even if the input data is
2928                // mono. If we know the codec lies about this information,
2929                // use the actual number of channels instead.
2930                mOutputFormat->setInt32(
2931                        kKeyChannelCount,
2932                        (mQuirks & kDecoderLiesAboutNumberOfChannels)
2933                            ? numChannels : params.nChannels);
2934
2935                // The codec-reported sampleRate is not reliable...
2936                mOutputFormat->setInt32(kKeySampleRate, sampleRate);
2937            } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) {
2938                OMX_AUDIO_PARAM_AMRTYPE amr;
2939                InitOMXParams(&amr);
2940                amr.nPortIndex = kPortIndexOutput;
2941
2942                err = mOMX->getParameter(
2943                        mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
2944                CHECK_EQ(err, OK);
2945
2946                CHECK_EQ(amr.nChannels, 1);
2947                mOutputFormat->setInt32(kKeyChannelCount, 1);
2948
2949                if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0
2950                    && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) {
2951                    mOutputFormat->setCString(
2952                            kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB);
2953                    mOutputFormat->setInt32(kKeySampleRate, 8000);
2954                } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0
2955                            && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) {
2956                    mOutputFormat->setCString(
2957                            kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB);
2958                    mOutputFormat->setInt32(kKeySampleRate, 16000);
2959                } else {
2960                    CHECK(!"Unknown AMR band mode.");
2961                }
2962            } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) {
2963                mOutputFormat->setCString(
2964                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
2965            } else {
2966                CHECK(!"Should not be here. Unknown audio encoding.");
2967            }
2968            break;
2969        }
2970
2971        case OMX_PortDomainVideo:
2972        {
2973            OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2974
2975            if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) {
2976                mOutputFormat->setCString(
2977                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
2978            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) {
2979                mOutputFormat->setCString(
2980                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
2981            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) {
2982                mOutputFormat->setCString(
2983                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
2984            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) {
2985                mOutputFormat->setCString(
2986                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
2987            } else {
2988                CHECK(!"Unknown compression format.");
2989            }
2990
2991            if (!strcmp(mComponentName, "OMX.PV.avcdec")) {
2992                // This component appears to be lying to me.
2993                mOutputFormat->setInt32(
2994                        kKeyWidth, (video_def->nFrameWidth + 15) & -16);
2995                mOutputFormat->setInt32(
2996                        kKeyHeight, (video_def->nFrameHeight + 15) & -16);
2997            } else {
2998                mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth);
2999                mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight);
3000            }
3001
3002            mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat);
3003            break;
3004        }
3005
3006        default:
3007        {
3008            CHECK(!"should not be here, neither audio nor video.");
3009            break;
3010        }
3011    }
3012}
3013
3014////////////////////////////////////////////////////////////////////////////////
3015
3016status_t QueryCodecs(
3017        const sp<IOMX> &omx,
3018        const char *mime, bool queryDecoders,
3019        Vector<CodecCapabilities> *results) {
3020    results->clear();
3021
3022    for (int index = 0;; ++index) {
3023        const char *componentName;
3024
3025        if (!queryDecoders) {
3026            componentName = GetCodec(
3027                    kEncoderInfo, sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]),
3028                    mime, index);
3029        } else {
3030            componentName = GetCodec(
3031                    kDecoderInfo, sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]),
3032                    mime, index);
3033        }
3034
3035        if (!componentName) {
3036            return OK;
3037        }
3038
3039        if (strncmp(componentName, "OMX.", 4)) {
3040            // Not an OpenMax component but a software codec.
3041
3042            results->push();
3043            CodecCapabilities *caps = &results->editItemAt(results->size() - 1);
3044            caps->mComponentName = componentName;
3045
3046            continue;
3047        }
3048
3049        sp<OMXCodecObserver> observer = new OMXCodecObserver;
3050        IOMX::node_id node;
3051        status_t err = omx->allocateNode(componentName, observer, &node);
3052
3053        if (err != OK) {
3054            continue;
3055        }
3056
3057        OMXCodec::setComponentRole(omx, node, queryDecoders, mime);
3058
3059        results->push();
3060        CodecCapabilities *caps = &results->editItemAt(results->size() - 1);
3061        caps->mComponentName = componentName;
3062
3063        OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
3064        InitOMXParams(&param);
3065
3066        param.nPortIndex = queryDecoders ? 0 : 1;
3067
3068        for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
3069            err = omx->getParameter(
3070                    node, OMX_IndexParamVideoProfileLevelQuerySupported,
3071                    &param, sizeof(param));
3072
3073            if (err != OK) {
3074                break;
3075            }
3076
3077            CodecProfileLevel profileLevel;
3078            profileLevel.mProfile = param.eProfile;
3079            profileLevel.mLevel = param.eLevel;
3080
3081            caps->mProfileLevels.push(profileLevel);
3082        }
3083
3084        CHECK_EQ(omx->freeNode(node), OK);
3085    }
3086}
3087
3088}  // namespace android
3089