OMXCodec.cpp revision ee7ff20e69498ebd53dd9717a0f984188341a75e
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#include "include/VorbisDecoder.h"
29
30#include "include/ESDS.h"
31
32#include <binder/IServiceManager.h>
33#include <binder/MemoryDealer.h>
34#include <binder/ProcessState.h>
35#include <media/IMediaPlayerService.h>
36#include <media/stagefright/MediaBuffer.h>
37#include <media/stagefright/MediaBufferGroup.h>
38#include <media/stagefright/MediaDebug.h>
39#include <media/stagefright/MediaDefs.h>
40#include <media/stagefright/MediaExtractor.h>
41#include <media/stagefright/MetaData.h>
42#include <media/stagefright/OMXCodec.h>
43#include <media/stagefright/Utils.h>
44#include <utils/Vector.h>
45
46#include <OMX_Audio.h>
47#include <OMX_Component.h>
48
49namespace android {
50
51static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
52
53struct CodecInfo {
54    const char *mime;
55    const char *codec;
56};
57
58#define FACTORY_CREATE(name) \
59static sp<MediaSource> Make##name(const sp<MediaSource> &source) { \
60    return new name(source); \
61}
62
63#define FACTORY_REF(name) { #name, Make##name },
64
65FACTORY_CREATE(MP3Decoder)
66FACTORY_CREATE(AMRNBDecoder)
67FACTORY_CREATE(AMRWBDecoder)
68FACTORY_CREATE(AACDecoder)
69FACTORY_CREATE(AVCDecoder)
70FACTORY_CREATE(M4vH263Decoder)
71FACTORY_CREATE(VorbisDecoder)
72FACTORY_CREATE(AMRNBEncoder)
73
74static sp<MediaSource> InstantiateSoftwareCodec(
75        const char *name, const sp<MediaSource> &source) {
76    struct FactoryInfo {
77        const char *name;
78        sp<MediaSource> (*CreateFunc)(const sp<MediaSource> &);
79    };
80
81    static const FactoryInfo kFactoryInfo[] = {
82        FACTORY_REF(MP3Decoder)
83        FACTORY_REF(AMRNBDecoder)
84        FACTORY_REF(AMRWBDecoder)
85        FACTORY_REF(AACDecoder)
86        FACTORY_REF(AVCDecoder)
87        FACTORY_REF(M4vH263Decoder)
88        FACTORY_REF(VorbisDecoder)
89        FACTORY_REF(AMRNBEncoder)
90    };
91    for (size_t i = 0;
92         i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) {
93        if (!strcmp(name, kFactoryInfo[i].name)) {
94            return (*kFactoryInfo[i].CreateFunc)(source);
95        }
96    }
97
98    return NULL;
99}
100
101#undef FACTORY_REF
102#undef FACTORY_CREATE
103
104static const CodecInfo kDecoderInfo[] = {
105    { MEDIA_MIMETYPE_IMAGE_JPEG, "OMX.TI.JPEG.decode" },
106//    { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" },
107    { MEDIA_MIMETYPE_AUDIO_MPEG, "MP3Decoder" },
108//    { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.PV.mp3dec" },
109//    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.decode" },
110    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBDecoder" },
111//    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.PV.amrdec" },
112    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.decode" },
113    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "AMRWBDecoder" },
114//    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.PV.amrdec" },
115    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.decode" },
116    { MEDIA_MIMETYPE_AUDIO_AAC, "AACDecoder" },
117//    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacdec" },
118    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.decoder.mpeg4" },
119    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.Decoder" },
120    { MEDIA_MIMETYPE_VIDEO_MPEG4, "M4vH263Decoder" },
121//    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4dec" },
122    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.decoder.h263" },
123    { MEDIA_MIMETYPE_VIDEO_H263, "M4vH263Decoder" },
124//    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263dec" },
125    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" },
126    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.Decoder" },
127    { MEDIA_MIMETYPE_VIDEO_AVC, "AVCDecoder" },
128//    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcdec" },
129    { MEDIA_MIMETYPE_AUDIO_VORBIS, "VorbisDecoder" },
130};
131
132static const CodecInfo kEncoderInfo[] = {
133    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.encode" },
134    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBEncoder" },
135    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.encode" },
136    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.encode" },
137    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacenc" },
138    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.encoder.mpeg4" },
139    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.encoder" },
140    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4enc" },
141    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.encoder.h263" },
142    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.encoder" },
143    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263enc" },
144    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.encoder" },
145    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcenc" },
146};
147
148#undef OPTIONAL
149
150#define CODEC_LOGI(x, ...) LOGI("[%s] "x, mComponentName, ##__VA_ARGS__)
151#define CODEC_LOGV(x, ...) LOGV("[%s] "x, mComponentName, ##__VA_ARGS__)
152#define CODEC_LOGE(x, ...) LOGE("[%s] "x, mComponentName, ##__VA_ARGS__)
153
154struct OMXCodecObserver : public BnOMXObserver {
155    OMXCodecObserver() {
156    }
157
158    void setCodec(const sp<OMXCodec> &target) {
159        mTarget = target;
160    }
161
162    // from IOMXObserver
163    virtual void onMessage(const omx_message &msg) {
164        sp<OMXCodec> codec = mTarget.promote();
165
166        if (codec.get() != NULL) {
167            codec->on_message(msg);
168        }
169    }
170
171protected:
172    virtual ~OMXCodecObserver() {}
173
174private:
175    wp<OMXCodec> mTarget;
176
177    OMXCodecObserver(const OMXCodecObserver &);
178    OMXCodecObserver &operator=(const OMXCodecObserver &);
179};
180
181static const char *GetCodec(const CodecInfo *info, size_t numInfos,
182                            const char *mime, int index) {
183    CHECK(index >= 0);
184    for(size_t i = 0; i < numInfos; ++i) {
185        if (!strcasecmp(mime, info[i].mime)) {
186            if (index == 0) {
187                return info[i].codec;
188            }
189
190            --index;
191        }
192    }
193
194    return NULL;
195}
196
197enum {
198    kAVCProfileBaseline      = 0x42,
199    kAVCProfileMain          = 0x4d,
200    kAVCProfileExtended      = 0x58,
201    kAVCProfileHigh          = 0x64,
202    kAVCProfileHigh10        = 0x6e,
203    kAVCProfileHigh422       = 0x7a,
204    kAVCProfileHigh444       = 0xf4,
205    kAVCProfileCAVLC444Intra = 0x2c
206};
207
208static const char *AVCProfileToString(uint8_t profile) {
209    switch (profile) {
210        case kAVCProfileBaseline:
211            return "Baseline";
212        case kAVCProfileMain:
213            return "Main";
214        case kAVCProfileExtended:
215            return "Extended";
216        case kAVCProfileHigh:
217            return "High";
218        case kAVCProfileHigh10:
219            return "High 10";
220        case kAVCProfileHigh422:
221            return "High 422";
222        case kAVCProfileHigh444:
223            return "High 444";
224        case kAVCProfileCAVLC444Intra:
225            return "CAVLC 444 Intra";
226        default:   return "Unknown";
227    }
228}
229
230template<class T>
231static void InitOMXParams(T *params) {
232    params->nSize = sizeof(T);
233    params->nVersion.s.nVersionMajor = 1;
234    params->nVersion.s.nVersionMinor = 0;
235    params->nVersion.s.nRevision = 0;
236    params->nVersion.s.nStep = 0;
237}
238
239static bool IsSoftwareCodec(const char *componentName) {
240    if (!strncmp("OMX.PV.", componentName, 7)) {
241        return true;
242    }
243
244    return false;
245}
246
247// A sort order in which non-OMX components are first,
248// followed by software codecs, i.e. OMX.PV.*, followed
249// by all the others.
250static int CompareSoftwareCodecsFirst(
251        const String8 *elem1, const String8 *elem2) {
252    bool isNotOMX1 = strncmp(elem1->string(), "OMX.", 4);
253    bool isNotOMX2 = strncmp(elem2->string(), "OMX.", 4);
254
255    if (isNotOMX1) {
256        if (isNotOMX2) { return 0; }
257        return -1;
258    }
259    if (isNotOMX2) {
260        return 1;
261    }
262
263    bool isSoftwareCodec1 = IsSoftwareCodec(elem1->string());
264    bool isSoftwareCodec2 = IsSoftwareCodec(elem2->string());
265
266    if (isSoftwareCodec1) {
267        if (isSoftwareCodec2) { return 0; }
268        return -1;
269    }
270
271    if (isSoftwareCodec2) {
272        return 1;
273    }
274
275    return 0;
276}
277
278// static
279uint32_t OMXCodec::getComponentQuirks(const char *componentName) {
280    uint32_t quirks = 0;
281
282    if (!strcmp(componentName, "OMX.PV.avcdec")) {
283        quirks |= kWantsNALFragments;
284    }
285    if (!strcmp(componentName, "OMX.TI.MP3.decode")) {
286        quirks |= kNeedsFlushBeforeDisable;
287        quirks |= kDecoderLiesAboutNumberOfChannels;
288    }
289    if (!strcmp(componentName, "OMX.TI.AAC.decode")) {
290        quirks |= kNeedsFlushBeforeDisable;
291        quirks |= kRequiresFlushCompleteEmulation;
292        quirks |= kSupportsMultipleFramesPerInputBuffer;
293    }
294    if (!strncmp(componentName, "OMX.qcom.video.encoder.", 23)) {
295        quirks |= kRequiresLoadedToIdleAfterAllocation;
296        quirks |= kRequiresAllocateBufferOnInputPorts;
297        quirks |= kRequiresAllocateBufferOnOutputPorts;
298    }
299    if (!strncmp(componentName, "OMX.qcom.video.decoder.", 23)) {
300        quirks |= kRequiresAllocateBufferOnOutputPorts;
301        quirks |= kDefersOutputBufferAllocation;
302    }
303
304    if (!strncmp(componentName, "OMX.TI.", 7)) {
305        // Apparently I must not use OMX_UseBuffer on either input or
306        // output ports on any of the TI components or quote:
307        // "(I) may have unexpected problem (sic) which can be timing related
308        //  and hard to reproduce."
309
310        quirks |= kRequiresAllocateBufferOnInputPorts;
311        quirks |= kRequiresAllocateBufferOnOutputPorts;
312    }
313
314    if (!strcmp(componentName, "OMX.TI.Video.Decoder")) {
315        quirks |= kInputBufferSizesAreBogus;
316    }
317
318    return quirks;
319}
320
321// static
322void OMXCodec::findMatchingCodecs(
323        const char *mime,
324        bool createEncoder, const char *matchComponentName,
325        uint32_t flags,
326        Vector<String8> *matchingCodecs) {
327    matchingCodecs->clear();
328
329    for (int index = 0;; ++index) {
330        const char *componentName;
331
332        if (createEncoder) {
333            componentName = GetCodec(
334                    kEncoderInfo,
335                    sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]),
336                    mime, index);
337        } else {
338            componentName = GetCodec(
339                    kDecoderInfo,
340                    sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]),
341                    mime, index);
342        }
343
344        if (!componentName) {
345            break;
346        }
347
348        // If a specific codec is requested, skip the non-matching ones.
349        if (matchComponentName && strcmp(componentName, matchComponentName)) {
350            continue;
351        }
352
353        matchingCodecs->push(String8(componentName));
354    }
355
356    if (flags & kPreferSoftwareCodecs) {
357        matchingCodecs->sort(CompareSoftwareCodecsFirst);
358    }
359}
360
361// static
362sp<MediaSource> OMXCodec::Create(
363        const sp<IOMX> &omx,
364        const sp<MetaData> &meta, bool createEncoder,
365        const sp<MediaSource> &source,
366        const char *matchComponentName,
367        uint32_t flags) {
368    const char *mime;
369    bool success = meta->findCString(kKeyMIMEType, &mime);
370    CHECK(success);
371
372    Vector<String8> matchingCodecs;
373    findMatchingCodecs(
374            mime, createEncoder, matchComponentName, flags, &matchingCodecs);
375
376    if (matchingCodecs.isEmpty()) {
377        return NULL;
378    }
379
380    sp<OMXCodecObserver> observer = new OMXCodecObserver;
381    IOMX::node_id node = 0;
382
383    const char *componentName;
384    for (size_t i = 0; i < matchingCodecs.size(); ++i) {
385        componentName = matchingCodecs[i].string();
386
387#if BUILD_WITH_FULL_STAGEFRIGHT
388        sp<MediaSource> softwareCodec =
389            InstantiateSoftwareCodec(componentName, source);
390
391        if (softwareCodec != NULL) {
392            LOGV("Successfully allocated software codec '%s'", componentName);
393
394            return softwareCodec;
395        }
396#endif
397
398        LOGV("Attempting to allocate OMX node '%s'", componentName);
399
400        status_t err = omx->allocateNode(componentName, observer, &node);
401        if (err == OK) {
402            LOGV("Successfully allocated OMX node '%s'", componentName);
403
404            sp<OMXCodec> codec = new OMXCodec(
405                    omx, node, getComponentQuirks(componentName),
406                    createEncoder, mime, componentName,
407                    source);
408
409            observer->setCodec(codec);
410
411            err = codec->configureCodec(meta);
412
413            if (err == OK) {
414                return codec;
415            }
416
417            LOGV("Failed to configure codec '%s'", componentName);
418        }
419    }
420
421    return NULL;
422}
423
424status_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
425    uint32_t type;
426    const void *data;
427    size_t size;
428    if (meta->findData(kKeyESDS, &type, &data, &size)) {
429        ESDS esds((const char *)data, size);
430        CHECK_EQ(esds.InitCheck(), OK);
431
432        const void *codec_specific_data;
433        size_t codec_specific_data_size;
434        esds.getCodecSpecificInfo(
435                &codec_specific_data, &codec_specific_data_size);
436
437        addCodecSpecificData(
438                codec_specific_data, codec_specific_data_size);
439    } else if (meta->findData(kKeyAVCC, &type, &data, &size)) {
440        // Parse the AVCDecoderConfigurationRecord
441
442        const uint8_t *ptr = (const uint8_t *)data;
443
444        CHECK(size >= 7);
445        CHECK_EQ(ptr[0], 1);  // configurationVersion == 1
446        uint8_t profile = ptr[1];
447        uint8_t level = ptr[3];
448
449        // There is decodable content out there that fails the following
450        // assertion, let's be lenient for now...
451        // CHECK((ptr[4] >> 2) == 0x3f);  // reserved
452
453        size_t lengthSize = 1 + (ptr[4] & 3);
454
455        // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
456        // violates it...
457        // CHECK((ptr[5] >> 5) == 7);  // reserved
458
459        size_t numSeqParameterSets = ptr[5] & 31;
460
461        ptr += 6;
462        size -= 6;
463
464        for (size_t i = 0; i < numSeqParameterSets; ++i) {
465            CHECK(size >= 2);
466            size_t length = U16_AT(ptr);
467
468            ptr += 2;
469            size -= 2;
470
471            CHECK(size >= length);
472
473            addCodecSpecificData(ptr, length);
474
475            ptr += length;
476            size -= length;
477        }
478
479        CHECK(size >= 1);
480        size_t numPictureParameterSets = *ptr;
481        ++ptr;
482        --size;
483
484        for (size_t i = 0; i < numPictureParameterSets; ++i) {
485            CHECK(size >= 2);
486            size_t length = U16_AT(ptr);
487
488            ptr += 2;
489            size -= 2;
490
491            CHECK(size >= length);
492
493            addCodecSpecificData(ptr, length);
494
495            ptr += length;
496            size -= length;
497        }
498
499        LOGV("AVC profile = %d (%s), level = %d",
500             (int)profile, AVCProfileToString(profile), (int)level / 10);
501
502        if (!strcmp(mComponentName, "OMX.TI.Video.Decoder")
503            && (profile != kAVCProfileBaseline || level > 39)) {
504            // This stream exceeds the decoder's capabilities. The decoder
505            // does not handle this gracefully and would clobber the heap
506            // and wreak havoc instead...
507
508            LOGE("Profile and/or level exceed the decoder's capabilities.");
509            return ERROR_UNSUPPORTED;
510        }
511    }
512
513    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mMIME)) {
514        setAMRFormat(false /* isWAMR */);
515    }
516    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mMIME)) {
517        setAMRFormat(true /* isWAMR */);
518    }
519    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mMIME)) {
520        int32_t numChannels, sampleRate;
521        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
522        CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
523
524        setAACFormat(numChannels, sampleRate);
525    }
526    if (!strncasecmp(mMIME, "video/", 6)) {
527        int32_t width, height;
528        bool success = meta->findInt32(kKeyWidth, &width);
529        success = success && meta->findInt32(kKeyHeight, &height);
530        CHECK(success);
531
532        if (mIsEncoder) {
533            setVideoInputFormat(mMIME, width, height);
534        } else {
535            status_t err = setVideoOutputFormat(
536                    mMIME, width, height);
537
538            if (err != OK) {
539                return err;
540            }
541        }
542    }
543
544    if (!strcasecmp(mMIME, MEDIA_MIMETYPE_IMAGE_JPEG)
545        && !strcmp(mComponentName, "OMX.TI.JPEG.decode")) {
546        OMX_COLOR_FORMATTYPE format =
547            OMX_COLOR_Format32bitARGB8888;
548            // OMX_COLOR_FormatYUV420PackedPlanar;
549            // OMX_COLOR_FormatCbYCrY;
550            // OMX_COLOR_FormatYUV411Planar;
551
552        int32_t width, height;
553        bool success = meta->findInt32(kKeyWidth, &width);
554        success = success && meta->findInt32(kKeyHeight, &height);
555
556        int32_t compressedSize;
557        success = success && meta->findInt32(
558                kKeyMaxInputSize, &compressedSize);
559
560        CHECK(success);
561        CHECK(compressedSize > 0);
562
563        setImageOutputFormat(format, width, height);
564        setJPEGInputFormat(width, height, (OMX_U32)compressedSize);
565    }
566
567    int32_t maxInputSize;
568    if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
569        setMinBufferSize(kPortIndexInput, (OMX_U32)maxInputSize);
570    }
571
572    if (!strcmp(mComponentName, "OMX.TI.AMR.encode")
573        || !strcmp(mComponentName, "OMX.TI.WBAMR.encode")) {
574        setMinBufferSize(kPortIndexOutput, 8192);  // XXX
575    }
576
577    initOutputFormat(meta);
578
579    return OK;
580}
581
582void OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) {
583    OMX_PARAM_PORTDEFINITIONTYPE def;
584    InitOMXParams(&def);
585    def.nPortIndex = portIndex;
586
587    status_t err = mOMX->getParameter(
588            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
589    CHECK_EQ(err, OK);
590
591    if ((portIndex == kPortIndexInput && (mQuirks & kInputBufferSizesAreBogus))
592        || (def.nBufferSize < size)) {
593        def.nBufferSize = size;
594    }
595
596    err = mOMX->setParameter(
597            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
598    CHECK_EQ(err, OK);
599
600    err = mOMX->getParameter(
601            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
602    CHECK_EQ(err, OK);
603
604    // Make sure the setting actually stuck.
605    if (portIndex == kPortIndexInput
606            && (mQuirks & kInputBufferSizesAreBogus)) {
607        CHECK_EQ(def.nBufferSize, size);
608    } else {
609        CHECK(def.nBufferSize >= size);
610    }
611}
612
613status_t OMXCodec::setVideoPortFormatType(
614        OMX_U32 portIndex,
615        OMX_VIDEO_CODINGTYPE compressionFormat,
616        OMX_COLOR_FORMATTYPE colorFormat) {
617    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
618    InitOMXParams(&format);
619    format.nPortIndex = portIndex;
620    format.nIndex = 0;
621    bool found = false;
622
623    OMX_U32 index = 0;
624    for (;;) {
625        format.nIndex = index;
626        status_t err = mOMX->getParameter(
627                mNode, OMX_IndexParamVideoPortFormat,
628                &format, sizeof(format));
629
630        if (err != OK) {
631            return err;
632        }
633
634        // The following assertion is violated by TI's video decoder.
635        // CHECK_EQ(format.nIndex, index);
636
637#if 1
638        CODEC_LOGV("portIndex: %ld, index: %ld, eCompressionFormat=%d eColorFormat=%d",
639             portIndex,
640             index, format.eCompressionFormat, format.eColorFormat);
641#endif
642
643        if (!strcmp("OMX.TI.Video.encoder", mComponentName)) {
644            if (portIndex == kPortIndexInput
645                    && colorFormat == format.eColorFormat) {
646                // eCompressionFormat does not seem right.
647                found = true;
648                break;
649            }
650            if (portIndex == kPortIndexOutput
651                    && compressionFormat == format.eCompressionFormat) {
652                // eColorFormat does not seem right.
653                found = true;
654                break;
655            }
656        }
657
658        if (format.eCompressionFormat == compressionFormat
659            && format.eColorFormat == colorFormat) {
660            found = true;
661            break;
662        }
663
664        ++index;
665    }
666
667    if (!found) {
668        return UNKNOWN_ERROR;
669    }
670
671    CODEC_LOGV("found a match.");
672    status_t err = mOMX->setParameter(
673            mNode, OMX_IndexParamVideoPortFormat,
674            &format, sizeof(format));
675
676    return err;
677}
678
679static size_t getFrameSize(
680        OMX_COLOR_FORMATTYPE colorFormat, int32_t width, int32_t height) {
681    switch (colorFormat) {
682        case OMX_COLOR_FormatYCbYCr:
683        case OMX_COLOR_FormatCbYCrY:
684            return width * height * 2;
685
686        case OMX_COLOR_FormatYUV420SemiPlanar:
687            return (width * height * 3) / 2;
688
689        default:
690            CHECK(!"Should not be here. Unsupported color format.");
691            break;
692    }
693}
694
695void OMXCodec::setVideoInputFormat(
696        const char *mime, OMX_U32 width, OMX_U32 height) {
697    CODEC_LOGV("setVideoInputFormat width=%ld, height=%ld", width, height);
698
699    OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
700    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
701        compressionFormat = OMX_VIDEO_CodingAVC;
702    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
703        compressionFormat = OMX_VIDEO_CodingMPEG4;
704    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
705        compressionFormat = OMX_VIDEO_CodingH263;
706    } else {
707        LOGE("Not a supported video mime type: %s", mime);
708        CHECK(!"Should not be here. Not a supported video mime type.");
709    }
710
711    OMX_COLOR_FORMATTYPE colorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
712    if (!strcasecmp("OMX.TI.Video.encoder", mComponentName)) {
713        colorFormat = OMX_COLOR_FormatYCbYCr;
714    }
715
716    CHECK_EQ(setVideoPortFormatType(
717            kPortIndexInput, OMX_VIDEO_CodingUnused,
718            colorFormat), OK);
719
720    CHECK_EQ(setVideoPortFormatType(
721            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused),
722            OK);
723
724    OMX_PARAM_PORTDEFINITIONTYPE def;
725    InitOMXParams(&def);
726    def.nPortIndex = kPortIndexOutput;
727
728    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
729
730    status_t err = mOMX->getParameter(
731            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
732
733    CHECK_EQ(err, OK);
734    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
735
736    video_def->nFrameWidth = width;
737    video_def->nFrameHeight = height;
738
739    video_def->eCompressionFormat = compressionFormat;
740    video_def->eColorFormat = OMX_COLOR_FormatUnused;
741
742    err = mOMX->setParameter(
743            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
744    CHECK_EQ(err, OK);
745
746    ////////////////////////////////////////////////////////////////////////////
747
748    InitOMXParams(&def);
749    def.nPortIndex = kPortIndexInput;
750
751    err = mOMX->getParameter(
752            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
753    CHECK_EQ(err, OK);
754
755    def.nBufferSize = getFrameSize(colorFormat, width, height);
756    CODEC_LOGV("Setting nBufferSize = %ld", def.nBufferSize);
757
758    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
759
760    video_def->nFrameWidth = width;
761    video_def->nFrameHeight = height;
762    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
763    video_def->eColorFormat = colorFormat;
764
765    video_def->xFramerate = 24 << 16;  // XXX crucial!
766
767    err = mOMX->setParameter(
768            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
769    CHECK_EQ(err, OK);
770
771    switch (compressionFormat) {
772        case OMX_VIDEO_CodingMPEG4:
773        {
774            CHECK_EQ(setupMPEG4EncoderParameters(), OK);
775            break;
776        }
777
778        case OMX_VIDEO_CodingH263:
779            break;
780
781        case OMX_VIDEO_CodingAVC:
782        {
783            CHECK_EQ(setupAVCEncoderParameters(), OK);
784            break;
785        }
786
787        default:
788            CHECK(!"Support for this compressionFormat to be implemented.");
789            break;
790    }
791}
792
793status_t OMXCodec::setupMPEG4EncoderParameters() {
794    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
795    InitOMXParams(&mpeg4type);
796    mpeg4type.nPortIndex = kPortIndexOutput;
797
798    status_t err = mOMX->getParameter(
799            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
800    CHECK_EQ(err, OK);
801
802    mpeg4type.nSliceHeaderSpacing = 0;
803    mpeg4type.bSVH = OMX_FALSE;
804    mpeg4type.bGov = OMX_FALSE;
805
806    mpeg4type.nAllowedPictureTypes =
807        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
808
809    mpeg4type.nPFrames = 23;
810    mpeg4type.nBFrames = 0;
811
812    mpeg4type.nIDCVLCThreshold = 0;
813    mpeg4type.bACPred = OMX_TRUE;
814    mpeg4type.nMaxPacketSize = 256;
815    mpeg4type.nTimeIncRes = 1000;
816    mpeg4type.nHeaderExtension = 0;
817    mpeg4type.bReversibleVLC = OMX_FALSE;
818
819    mpeg4type.eProfile = OMX_VIDEO_MPEG4ProfileCore;
820    mpeg4type.eLevel = OMX_VIDEO_MPEG4Level2;
821
822    err = mOMX->setParameter(
823            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
824    CHECK_EQ(err, OK);
825
826    // ----------------
827
828    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
829    InitOMXParams(&bitrateType);
830    bitrateType.nPortIndex = kPortIndexOutput;
831
832    err = mOMX->getParameter(
833            mNode, OMX_IndexParamVideoBitrate,
834            &bitrateType, sizeof(bitrateType));
835    CHECK_EQ(err, OK);
836
837    bitrateType.eControlRate = OMX_Video_ControlRateVariable;
838    bitrateType.nTargetBitrate = 1000000;
839
840    err = mOMX->setParameter(
841            mNode, OMX_IndexParamVideoBitrate,
842            &bitrateType, sizeof(bitrateType));
843    CHECK_EQ(err, OK);
844
845    // ----------------
846
847    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
848    InitOMXParams(&errorCorrectionType);
849    errorCorrectionType.nPortIndex = kPortIndexOutput;
850
851    err = mOMX->getParameter(
852            mNode, OMX_IndexParamVideoErrorCorrection,
853            &errorCorrectionType, sizeof(errorCorrectionType));
854    CHECK_EQ(err, OK);
855
856    errorCorrectionType.bEnableHEC = OMX_FALSE;
857    errorCorrectionType.bEnableResync = OMX_TRUE;
858    errorCorrectionType.nResynchMarkerSpacing = 256;
859    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
860    errorCorrectionType.bEnableRVLC = OMX_FALSE;
861
862    err = mOMX->setParameter(
863            mNode, OMX_IndexParamVideoErrorCorrection,
864            &errorCorrectionType, sizeof(errorCorrectionType));
865    CHECK_EQ(err, OK);
866
867    return OK;
868}
869
870status_t OMXCodec::setupAVCEncoderParameters() {
871    OMX_VIDEO_PARAM_AVCTYPE h264type;
872    InitOMXParams(&h264type);
873    h264type.nPortIndex = kPortIndexOutput;
874
875    status_t err = mOMX->getParameter(
876            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
877    CHECK_EQ(err, OK);
878
879    h264type.nAllowedPictureTypes =
880        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
881
882    h264type.nSliceHeaderSpacing = 0;
883    h264type.nBFrames = 0;
884    h264type.bUseHadamard = OMX_TRUE;
885    h264type.nRefFrames = 1;
886    h264type.nRefIdx10ActiveMinus1 = 0;
887    h264type.nRefIdx11ActiveMinus1 = 0;
888    h264type.bEnableUEP = OMX_FALSE;
889    h264type.bEnableFMO = OMX_FALSE;
890    h264type.bEnableASO = OMX_FALSE;
891    h264type.bEnableRS = OMX_FALSE;
892    h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
893    h264type.eLevel = OMX_VIDEO_AVCLevel1b;
894    h264type.bFrameMBsOnly = OMX_TRUE;
895    h264type.bMBAFF = OMX_FALSE;
896    h264type.bEntropyCodingCABAC = OMX_FALSE;
897    h264type.bWeightedPPrediction = OMX_FALSE;
898    h264type.bconstIpred = OMX_FALSE;
899    h264type.bDirect8x8Inference = OMX_FALSE;
900    h264type.bDirectSpatialTemporal = OMX_FALSE;
901    h264type.nCabacInitIdc = 0;
902    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
903
904    err = mOMX->setParameter(
905            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
906    CHECK_EQ(err, OK);
907
908    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
909    InitOMXParams(&bitrateType);
910    bitrateType.nPortIndex = kPortIndexOutput;
911
912    err = mOMX->getParameter(
913            mNode, OMX_IndexParamVideoBitrate,
914            &bitrateType, sizeof(bitrateType));
915    CHECK_EQ(err, OK);
916
917    bitrateType.eControlRate = OMX_Video_ControlRateVariable;
918    bitrateType.nTargetBitrate = 1000000;
919
920    err = mOMX->setParameter(
921            mNode, OMX_IndexParamVideoBitrate,
922            &bitrateType, sizeof(bitrateType));
923    CHECK_EQ(err, OK);
924
925    return OK;
926}
927
928status_t OMXCodec::setVideoOutputFormat(
929        const char *mime, OMX_U32 width, OMX_U32 height) {
930    CODEC_LOGV("setVideoOutputFormat width=%ld, height=%ld", width, height);
931
932    OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
933    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
934        compressionFormat = OMX_VIDEO_CodingAVC;
935    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
936        compressionFormat = OMX_VIDEO_CodingMPEG4;
937    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
938        compressionFormat = OMX_VIDEO_CodingH263;
939    } else {
940        LOGE("Not a supported video mime type: %s", mime);
941        CHECK(!"Should not be here. Not a supported video mime type.");
942    }
943
944    status_t err = setVideoPortFormatType(
945            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
946
947    if (err != OK) {
948        return err;
949    }
950
951#if 1
952    {
953        OMX_VIDEO_PARAM_PORTFORMATTYPE format;
954        InitOMXParams(&format);
955        format.nPortIndex = kPortIndexOutput;
956        format.nIndex = 0;
957
958        status_t err = mOMX->getParameter(
959                mNode, OMX_IndexParamVideoPortFormat,
960                &format, sizeof(format));
961        CHECK_EQ(err, OK);
962        CHECK_EQ(format.eCompressionFormat, OMX_VIDEO_CodingUnused);
963
964        static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
965
966        CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
967               || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
968               || format.eColorFormat == OMX_COLOR_FormatCbYCrY
969               || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar);
970
971        err = mOMX->setParameter(
972                mNode, OMX_IndexParamVideoPortFormat,
973                &format, sizeof(format));
974
975        if (err != OK) {
976            return err;
977        }
978    }
979#endif
980
981    OMX_PARAM_PORTDEFINITIONTYPE def;
982    InitOMXParams(&def);
983    def.nPortIndex = kPortIndexInput;
984
985    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
986
987    err = mOMX->getParameter(
988            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
989
990    CHECK_EQ(err, OK);
991
992#if 1
993    // XXX Need a (much) better heuristic to compute input buffer sizes.
994    const size_t X = 64 * 1024;
995    if (def.nBufferSize < X) {
996        def.nBufferSize = X;
997    }
998#endif
999
1000    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
1001
1002    video_def->nFrameWidth = width;
1003    video_def->nFrameHeight = height;
1004
1005    video_def->eCompressionFormat = compressionFormat;
1006    video_def->eColorFormat = OMX_COLOR_FormatUnused;
1007
1008    err = mOMX->setParameter(
1009            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1010
1011    if (err != OK) {
1012        return err;
1013    }
1014
1015    ////////////////////////////////////////////////////////////////////////////
1016
1017    InitOMXParams(&def);
1018    def.nPortIndex = kPortIndexOutput;
1019
1020    err = mOMX->getParameter(
1021            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1022    CHECK_EQ(err, OK);
1023    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
1024
1025#if 0
1026    def.nBufferSize =
1027        (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2;  // YUV420
1028#endif
1029
1030    video_def->nFrameWidth = width;
1031    video_def->nFrameHeight = height;
1032
1033    err = mOMX->setParameter(
1034            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1035
1036    return err;
1037}
1038
1039OMXCodec::OMXCodec(
1040        const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks,
1041        bool isEncoder,
1042        const char *mime,
1043        const char *componentName,
1044        const sp<MediaSource> &source)
1045    : mOMX(omx),
1046      mOMXLivesLocally(omx->livesLocally(getpid())),
1047      mNode(node),
1048      mQuirks(quirks),
1049      mIsEncoder(isEncoder),
1050      mMIME(strdup(mime)),
1051      mComponentName(strdup(componentName)),
1052      mSource(source),
1053      mCodecSpecificDataIndex(0),
1054      mState(LOADED),
1055      mInitialBufferSubmit(true),
1056      mSignalledEOS(false),
1057      mNoMoreOutputData(false),
1058      mOutputPortSettingsHaveChanged(false),
1059      mSeekTimeUs(-1),
1060      mLeftOverBuffer(NULL) {
1061    mPortStatus[kPortIndexInput] = ENABLED;
1062    mPortStatus[kPortIndexOutput] = ENABLED;
1063
1064    setComponentRole();
1065}
1066
1067// static
1068void OMXCodec::setComponentRole(
1069        const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder,
1070        const char *mime) {
1071    struct MimeToRole {
1072        const char *mime;
1073        const char *decoderRole;
1074        const char *encoderRole;
1075    };
1076
1077    static const MimeToRole kMimeToRole[] = {
1078        { MEDIA_MIMETYPE_AUDIO_MPEG,
1079            "audio_decoder.mp3", "audio_encoder.mp3" },
1080        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1081            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1082        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1083            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1084        { MEDIA_MIMETYPE_AUDIO_AAC,
1085            "audio_decoder.aac", "audio_encoder.aac" },
1086        { MEDIA_MIMETYPE_VIDEO_AVC,
1087            "video_decoder.avc", "video_encoder.avc" },
1088        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1089            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1090        { MEDIA_MIMETYPE_VIDEO_H263,
1091            "video_decoder.h263", "video_encoder.h263" },
1092    };
1093
1094    static const size_t kNumMimeToRole =
1095        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1096
1097    size_t i;
1098    for (i = 0; i < kNumMimeToRole; ++i) {
1099        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1100            break;
1101        }
1102    }
1103
1104    if (i == kNumMimeToRole) {
1105        return;
1106    }
1107
1108    const char *role =
1109        isEncoder ? kMimeToRole[i].encoderRole
1110                  : kMimeToRole[i].decoderRole;
1111
1112    if (role != NULL) {
1113        OMX_PARAM_COMPONENTROLETYPE roleParams;
1114        InitOMXParams(&roleParams);
1115
1116        strncpy((char *)roleParams.cRole,
1117                role, OMX_MAX_STRINGNAME_SIZE - 1);
1118
1119        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1120
1121        status_t err = omx->setParameter(
1122                node, OMX_IndexParamStandardComponentRole,
1123                &roleParams, sizeof(roleParams));
1124
1125        if (err != OK) {
1126            LOGW("Failed to set standard component role '%s'.", role);
1127        }
1128    }
1129}
1130
1131void OMXCodec::setComponentRole() {
1132    setComponentRole(mOMX, mNode, mIsEncoder, mMIME);
1133}
1134
1135OMXCodec::~OMXCodec() {
1136    CHECK(mState == LOADED || mState == ERROR);
1137
1138    status_t err = mOMX->freeNode(mNode);
1139    CHECK_EQ(err, OK);
1140
1141    mNode = NULL;
1142    setState(DEAD);
1143
1144    clearCodecSpecificData();
1145
1146    free(mComponentName);
1147    mComponentName = NULL;
1148
1149    free(mMIME);
1150    mMIME = NULL;
1151}
1152
1153status_t OMXCodec::init() {
1154    // mLock is held.
1155
1156    CHECK_EQ(mState, LOADED);
1157
1158    status_t err;
1159    if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) {
1160        err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
1161        CHECK_EQ(err, OK);
1162        setState(LOADED_TO_IDLE);
1163    }
1164
1165    err = allocateBuffers();
1166    CHECK_EQ(err, OK);
1167
1168    if (mQuirks & kRequiresLoadedToIdleAfterAllocation) {
1169        err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
1170        CHECK_EQ(err, OK);
1171
1172        setState(LOADED_TO_IDLE);
1173    }
1174
1175    while (mState != EXECUTING && mState != ERROR) {
1176        mAsyncCompletion.wait(mLock);
1177    }
1178
1179    return mState == ERROR ? UNKNOWN_ERROR : OK;
1180}
1181
1182// static
1183bool OMXCodec::isIntermediateState(State state) {
1184    return state == LOADED_TO_IDLE
1185        || state == IDLE_TO_EXECUTING
1186        || state == EXECUTING_TO_IDLE
1187        || state == IDLE_TO_LOADED
1188        || state == RECONFIGURING;
1189}
1190
1191status_t OMXCodec::allocateBuffers() {
1192    status_t err = allocateBuffersOnPort(kPortIndexInput);
1193
1194    if (err != OK) {
1195        return err;
1196    }
1197
1198    return allocateBuffersOnPort(kPortIndexOutput);
1199}
1200
1201status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
1202    OMX_PARAM_PORTDEFINITIONTYPE def;
1203    InitOMXParams(&def);
1204    def.nPortIndex = portIndex;
1205
1206    status_t err = mOMX->getParameter(
1207            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1208
1209    if (err != OK) {
1210        return err;
1211    }
1212
1213    size_t totalSize = def.nBufferCountActual * def.nBufferSize;
1214    mDealer[portIndex] = new MemoryDealer(totalSize, "OMXCodec");
1215
1216    for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
1217        sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
1218        CHECK(mem.get() != NULL);
1219
1220        BufferInfo info;
1221        info.mData = NULL;
1222        info.mSize = def.nBufferSize;
1223
1224        IOMX::buffer_id buffer;
1225        if (portIndex == kPortIndexInput
1226                && (mQuirks & kRequiresAllocateBufferOnInputPorts)) {
1227            if (mOMXLivesLocally) {
1228                mem.clear();
1229
1230                err = mOMX->allocateBuffer(
1231                        mNode, portIndex, def.nBufferSize, &buffer,
1232                        &info.mData);
1233            } else {
1234                err = mOMX->allocateBufferWithBackup(
1235                        mNode, portIndex, mem, &buffer);
1236            }
1237        } else if (portIndex == kPortIndexOutput
1238                && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) {
1239            if (mOMXLivesLocally) {
1240                mem.clear();
1241
1242                err = mOMX->allocateBuffer(
1243                        mNode, portIndex, def.nBufferSize, &buffer,
1244                        &info.mData);
1245            } else {
1246                err = mOMX->allocateBufferWithBackup(
1247                        mNode, portIndex, mem, &buffer);
1248            }
1249        } else {
1250            err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
1251        }
1252
1253        if (err != OK) {
1254            LOGE("allocate_buffer_with_backup failed");
1255            return err;
1256        }
1257
1258        if (mem != NULL) {
1259            info.mData = mem->pointer();
1260        }
1261
1262        info.mBuffer = buffer;
1263        info.mOwnedByComponent = false;
1264        info.mMem = mem;
1265        info.mMediaBuffer = NULL;
1266
1267        if (portIndex == kPortIndexOutput) {
1268            if (!(mOMXLivesLocally
1269                        && (mQuirks & kRequiresAllocateBufferOnOutputPorts)
1270                        && (mQuirks & kDefersOutputBufferAllocation))) {
1271                // If the node does not fill in the buffer ptr at this time,
1272                // we will defer creating the MediaBuffer until receiving
1273                // the first FILL_BUFFER_DONE notification instead.
1274                info.mMediaBuffer = new MediaBuffer(info.mData, info.mSize);
1275                info.mMediaBuffer->setObserver(this);
1276            }
1277        }
1278
1279        mPortBuffers[portIndex].push(info);
1280
1281        CODEC_LOGV("allocated buffer %p on %s port", buffer,
1282             portIndex == kPortIndexInput ? "input" : "output");
1283    }
1284
1285    // dumpPortStatus(portIndex);
1286
1287    return OK;
1288}
1289
1290void OMXCodec::on_message(const omx_message &msg) {
1291    Mutex::Autolock autoLock(mLock);
1292
1293    switch (msg.type) {
1294        case omx_message::EVENT:
1295        {
1296            onEvent(
1297                 msg.u.event_data.event, msg.u.event_data.data1,
1298                 msg.u.event_data.data2);
1299
1300            break;
1301        }
1302
1303        case omx_message::EMPTY_BUFFER_DONE:
1304        {
1305            IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
1306
1307            CODEC_LOGV("EMPTY_BUFFER_DONE(buffer: %p)", buffer);
1308
1309            Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
1310            size_t i = 0;
1311            while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
1312                ++i;
1313            }
1314
1315            CHECK(i < buffers->size());
1316            if (!(*buffers)[i].mOwnedByComponent) {
1317                LOGW("We already own input buffer %p, yet received "
1318                     "an EMPTY_BUFFER_DONE.", buffer);
1319            }
1320
1321            buffers->editItemAt(i).mOwnedByComponent = false;
1322
1323            if (mPortStatus[kPortIndexInput] == DISABLING) {
1324                CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
1325
1326                status_t err =
1327                    mOMX->freeBuffer(mNode, kPortIndexInput, buffer);
1328                CHECK_EQ(err, OK);
1329
1330                buffers->removeAt(i);
1331            } else if (mState != ERROR
1332                    && mPortStatus[kPortIndexInput] != SHUTTING_DOWN) {
1333                CHECK_EQ(mPortStatus[kPortIndexInput], ENABLED);
1334                drainInputBuffer(&buffers->editItemAt(i));
1335            }
1336            break;
1337        }
1338
1339        case omx_message::FILL_BUFFER_DONE:
1340        {
1341            IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
1342            OMX_U32 flags = msg.u.extended_buffer_data.flags;
1343
1344            CODEC_LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx, timestamp: %lld us (%.2f secs))",
1345                 buffer,
1346                 msg.u.extended_buffer_data.range_length,
1347                 flags,
1348                 msg.u.extended_buffer_data.timestamp,
1349                 msg.u.extended_buffer_data.timestamp / 1E6);
1350
1351            Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
1352            size_t i = 0;
1353            while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
1354                ++i;
1355            }
1356
1357            CHECK(i < buffers->size());
1358            BufferInfo *info = &buffers->editItemAt(i);
1359
1360            if (!info->mOwnedByComponent) {
1361                LOGW("We already own output buffer %p, yet received "
1362                     "a FILL_BUFFER_DONE.", buffer);
1363            }
1364
1365            info->mOwnedByComponent = false;
1366
1367            if (mPortStatus[kPortIndexOutput] == DISABLING) {
1368                CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
1369
1370                status_t err =
1371                    mOMX->freeBuffer(mNode, kPortIndexOutput, buffer);
1372                CHECK_EQ(err, OK);
1373
1374                buffers->removeAt(i);
1375#if 0
1376            } else if (mPortStatus[kPortIndexOutput] == ENABLED
1377                       && (flags & OMX_BUFFERFLAG_EOS)) {
1378                CODEC_LOGV("No more output data.");
1379                mNoMoreOutputData = true;
1380                mBufferFilled.signal();
1381#endif
1382            } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) {
1383                CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED);
1384
1385                if (info->mMediaBuffer == NULL) {
1386                    CHECK(mOMXLivesLocally);
1387                    CHECK(mQuirks & kRequiresAllocateBufferOnOutputPorts);
1388                    CHECK(mQuirks & kDefersOutputBufferAllocation);
1389
1390                    // The qcom video decoders on Nexus don't actually allocate
1391                    // output buffer memory on a call to OMX_AllocateBuffer
1392                    // the "pBuffer" member of the OMX_BUFFERHEADERTYPE
1393                    // structure is only filled in later.
1394
1395                    info->mMediaBuffer = new MediaBuffer(
1396                            msg.u.extended_buffer_data.data_ptr,
1397                            info->mSize);
1398                    info->mMediaBuffer->setObserver(this);
1399                }
1400
1401                MediaBuffer *buffer = info->mMediaBuffer;
1402
1403                buffer->set_range(
1404                        msg.u.extended_buffer_data.range_offset,
1405                        msg.u.extended_buffer_data.range_length);
1406
1407                buffer->meta_data()->clear();
1408
1409                buffer->meta_data()->setInt64(
1410                        kKeyTime, msg.u.extended_buffer_data.timestamp);
1411
1412                if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) {
1413                    buffer->meta_data()->setInt32(kKeyIsSyncFrame, true);
1414                }
1415                if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_CODECCONFIG) {
1416                    buffer->meta_data()->setInt32(kKeyIsCodecConfig, true);
1417                }
1418
1419                buffer->meta_data()->setPointer(
1420                        kKeyPlatformPrivate,
1421                        msg.u.extended_buffer_data.platform_private);
1422
1423                buffer->meta_data()->setPointer(
1424                        kKeyBufferID,
1425                        msg.u.extended_buffer_data.buffer);
1426
1427                mFilledBuffers.push_back(i);
1428                mBufferFilled.signal();
1429
1430                if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_EOS) {
1431                    CODEC_LOGV("No more output data.");
1432                    mNoMoreOutputData = true;
1433                }
1434            }
1435
1436            break;
1437        }
1438
1439        default:
1440        {
1441            CHECK(!"should not be here.");
1442            break;
1443        }
1444    }
1445}
1446
1447void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
1448    switch (event) {
1449        case OMX_EventCmdComplete:
1450        {
1451            onCmdComplete((OMX_COMMANDTYPE)data1, data2);
1452            break;
1453        }
1454
1455        case OMX_EventError:
1456        {
1457            LOGE("ERROR(0x%08lx, %ld)", data1, data2);
1458
1459            setState(ERROR);
1460            break;
1461        }
1462
1463        case OMX_EventPortSettingsChanged:
1464        {
1465            onPortSettingsChanged(data1);
1466            break;
1467        }
1468
1469#if 0
1470        case OMX_EventBufferFlag:
1471        {
1472            CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1);
1473
1474            if (data1 == kPortIndexOutput) {
1475                mNoMoreOutputData = true;
1476            }
1477            break;
1478        }
1479#endif
1480
1481        default:
1482        {
1483            CODEC_LOGV("EVENT(%d, %ld, %ld)", event, data1, data2);
1484            break;
1485        }
1486    }
1487}
1488
1489// Has the format changed in any way that the client would have to be aware of?
1490static bool formatHasNotablyChanged(
1491        const sp<MetaData> &from, const sp<MetaData> &to) {
1492    if (from.get() == NULL && to.get() == NULL) {
1493        return false;
1494    }
1495
1496    if ((from.get() == NULL && to.get() != NULL)
1497        || (from.get() != NULL && to.get() == NULL)) {
1498        return true;
1499    }
1500
1501    const char *mime_from, *mime_to;
1502    CHECK(from->findCString(kKeyMIMEType, &mime_from));
1503    CHECK(to->findCString(kKeyMIMEType, &mime_to));
1504
1505    if (strcasecmp(mime_from, mime_to)) {
1506        return true;
1507    }
1508
1509    if (!strcasecmp(mime_from, MEDIA_MIMETYPE_VIDEO_RAW)) {
1510        int32_t colorFormat_from, colorFormat_to;
1511        CHECK(from->findInt32(kKeyColorFormat, &colorFormat_from));
1512        CHECK(to->findInt32(kKeyColorFormat, &colorFormat_to));
1513
1514        if (colorFormat_from != colorFormat_to) {
1515            return true;
1516        }
1517
1518        int32_t width_from, width_to;
1519        CHECK(from->findInt32(kKeyWidth, &width_from));
1520        CHECK(to->findInt32(kKeyWidth, &width_to));
1521
1522        if (width_from != width_to) {
1523            return true;
1524        }
1525
1526        int32_t height_from, height_to;
1527        CHECK(from->findInt32(kKeyHeight, &height_from));
1528        CHECK(to->findInt32(kKeyHeight, &height_to));
1529
1530        if (height_from != height_to) {
1531            return true;
1532        }
1533    } else if (!strcasecmp(mime_from, MEDIA_MIMETYPE_AUDIO_RAW)) {
1534        int32_t numChannels_from, numChannels_to;
1535        CHECK(from->findInt32(kKeyChannelCount, &numChannels_from));
1536        CHECK(to->findInt32(kKeyChannelCount, &numChannels_to));
1537
1538        if (numChannels_from != numChannels_to) {
1539            return true;
1540        }
1541
1542        int32_t sampleRate_from, sampleRate_to;
1543        CHECK(from->findInt32(kKeySampleRate, &sampleRate_from));
1544        CHECK(to->findInt32(kKeySampleRate, &sampleRate_to));
1545
1546        if (sampleRate_from != sampleRate_to) {
1547            return true;
1548        }
1549    }
1550
1551    return false;
1552}
1553
1554void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) {
1555    switch (cmd) {
1556        case OMX_CommandStateSet:
1557        {
1558            onStateChange((OMX_STATETYPE)data);
1559            break;
1560        }
1561
1562        case OMX_CommandPortDisable:
1563        {
1564            OMX_U32 portIndex = data;
1565            CODEC_LOGV("PORT_DISABLED(%ld)", portIndex);
1566
1567            CHECK(mState == EXECUTING || mState == RECONFIGURING);
1568            CHECK_EQ(mPortStatus[portIndex], DISABLING);
1569            CHECK_EQ(mPortBuffers[portIndex].size(), 0);
1570
1571            mPortStatus[portIndex] = DISABLED;
1572
1573            if (mState == RECONFIGURING) {
1574                CHECK_EQ(portIndex, kPortIndexOutput);
1575
1576                sp<MetaData> oldOutputFormat = mOutputFormat;
1577                initOutputFormat(mSource->getFormat());
1578
1579                // Don't notify clients if the output port settings change
1580                // wasn't of importance to them, i.e. it may be that just the
1581                // number of buffers has changed and nothing else.
1582                mOutputPortSettingsHaveChanged =
1583                    formatHasNotablyChanged(oldOutputFormat, mOutputFormat);
1584
1585                enablePortAsync(portIndex);
1586
1587                status_t err = allocateBuffersOnPort(portIndex);
1588                CHECK_EQ(err, OK);
1589            }
1590            break;
1591        }
1592
1593        case OMX_CommandPortEnable:
1594        {
1595            OMX_U32 portIndex = data;
1596            CODEC_LOGV("PORT_ENABLED(%ld)", portIndex);
1597
1598            CHECK(mState == EXECUTING || mState == RECONFIGURING);
1599            CHECK_EQ(mPortStatus[portIndex], ENABLING);
1600
1601            mPortStatus[portIndex] = ENABLED;
1602
1603            if (mState == RECONFIGURING) {
1604                CHECK_EQ(portIndex, kPortIndexOutput);
1605
1606                setState(EXECUTING);
1607
1608                fillOutputBuffers();
1609            }
1610            break;
1611        }
1612
1613        case OMX_CommandFlush:
1614        {
1615            OMX_U32 portIndex = data;
1616
1617            CODEC_LOGV("FLUSH_DONE(%ld)", portIndex);
1618
1619            CHECK_EQ(mPortStatus[portIndex], SHUTTING_DOWN);
1620            mPortStatus[portIndex] = ENABLED;
1621
1622            CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]),
1623                     mPortBuffers[portIndex].size());
1624
1625            if (mState == RECONFIGURING) {
1626                CHECK_EQ(portIndex, kPortIndexOutput);
1627
1628                disablePortAsync(portIndex);
1629            } else if (mState == EXECUTING_TO_IDLE) {
1630                if (mPortStatus[kPortIndexInput] == ENABLED
1631                    && mPortStatus[kPortIndexOutput] == ENABLED) {
1632                    CODEC_LOGV("Finished flushing both ports, now completing "
1633                         "transition from EXECUTING to IDLE.");
1634
1635                    mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
1636                    mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
1637
1638                    status_t err =
1639                        mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
1640                    CHECK_EQ(err, OK);
1641                }
1642            } else {
1643                // We're flushing both ports in preparation for seeking.
1644
1645                if (mPortStatus[kPortIndexInput] == ENABLED
1646                    && mPortStatus[kPortIndexOutput] == ENABLED) {
1647                    CODEC_LOGV("Finished flushing both ports, now continuing from"
1648                         " seek-time.");
1649
1650                    drainInputBuffers();
1651                    fillOutputBuffers();
1652                }
1653            }
1654
1655            break;
1656        }
1657
1658        default:
1659        {
1660            CODEC_LOGV("CMD_COMPLETE(%d, %ld)", cmd, data);
1661            break;
1662        }
1663    }
1664}
1665
1666void OMXCodec::onStateChange(OMX_STATETYPE newState) {
1667    CODEC_LOGV("onStateChange %d", newState);
1668
1669    switch (newState) {
1670        case OMX_StateIdle:
1671        {
1672            CODEC_LOGV("Now Idle.");
1673            if (mState == LOADED_TO_IDLE) {
1674                status_t err = mOMX->sendCommand(
1675                        mNode, OMX_CommandStateSet, OMX_StateExecuting);
1676
1677                CHECK_EQ(err, OK);
1678
1679                setState(IDLE_TO_EXECUTING);
1680            } else {
1681                CHECK_EQ(mState, EXECUTING_TO_IDLE);
1682
1683                CHECK_EQ(
1684                    countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
1685                    mPortBuffers[kPortIndexInput].size());
1686
1687                CHECK_EQ(
1688                    countBuffersWeOwn(mPortBuffers[kPortIndexOutput]),
1689                    mPortBuffers[kPortIndexOutput].size());
1690
1691                status_t err = mOMX->sendCommand(
1692                        mNode, OMX_CommandStateSet, OMX_StateLoaded);
1693
1694                CHECK_EQ(err, OK);
1695
1696                err = freeBuffersOnPort(kPortIndexInput);
1697                CHECK_EQ(err, OK);
1698
1699                err = freeBuffersOnPort(kPortIndexOutput);
1700                CHECK_EQ(err, OK);
1701
1702                mPortStatus[kPortIndexInput] = ENABLED;
1703                mPortStatus[kPortIndexOutput] = ENABLED;
1704
1705                setState(IDLE_TO_LOADED);
1706            }
1707            break;
1708        }
1709
1710        case OMX_StateExecuting:
1711        {
1712            CHECK_EQ(mState, IDLE_TO_EXECUTING);
1713
1714            CODEC_LOGV("Now Executing.");
1715
1716            setState(EXECUTING);
1717
1718            // Buffers will be submitted to the component in the first
1719            // call to OMXCodec::read as mInitialBufferSubmit is true at
1720            // this point. This ensures that this on_message call returns,
1721            // releases the lock and ::init can notice the state change and
1722            // itself return.
1723            break;
1724        }
1725
1726        case OMX_StateLoaded:
1727        {
1728            CHECK_EQ(mState, IDLE_TO_LOADED);
1729
1730            CODEC_LOGV("Now Loaded.");
1731
1732            setState(LOADED);
1733            break;
1734        }
1735
1736        case OMX_StateInvalid:
1737        {
1738            setState(ERROR);
1739            break;
1740        }
1741
1742        default:
1743        {
1744            CHECK(!"should not be here.");
1745            break;
1746        }
1747    }
1748}
1749
1750// static
1751size_t OMXCodec::countBuffersWeOwn(const Vector<BufferInfo> &buffers) {
1752    size_t n = 0;
1753    for (size_t i = 0; i < buffers.size(); ++i) {
1754        if (!buffers[i].mOwnedByComponent) {
1755            ++n;
1756        }
1757    }
1758
1759    return n;
1760}
1761
1762status_t OMXCodec::freeBuffersOnPort(
1763        OMX_U32 portIndex, bool onlyThoseWeOwn) {
1764    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
1765
1766    status_t stickyErr = OK;
1767
1768    for (size_t i = buffers->size(); i-- > 0;) {
1769        BufferInfo *info = &buffers->editItemAt(i);
1770
1771        if (onlyThoseWeOwn && info->mOwnedByComponent) {
1772            continue;
1773        }
1774
1775        CHECK_EQ(info->mOwnedByComponent, false);
1776
1777        CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex);
1778
1779        status_t err =
1780            mOMX->freeBuffer(mNode, portIndex, info->mBuffer);
1781
1782        if (err != OK) {
1783            stickyErr = err;
1784        }
1785
1786        if (info->mMediaBuffer != NULL) {
1787            info->mMediaBuffer->setObserver(NULL);
1788
1789            // Make sure nobody but us owns this buffer at this point.
1790            CHECK_EQ(info->mMediaBuffer->refcount(), 0);
1791
1792            info->mMediaBuffer->release();
1793        }
1794
1795        buffers->removeAt(i);
1796    }
1797
1798    CHECK(onlyThoseWeOwn || buffers->isEmpty());
1799
1800    return stickyErr;
1801}
1802
1803void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) {
1804    CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex);
1805
1806    CHECK_EQ(mState, EXECUTING);
1807    CHECK_EQ(portIndex, kPortIndexOutput);
1808    setState(RECONFIGURING);
1809
1810    if (mQuirks & kNeedsFlushBeforeDisable) {
1811        if (!flushPortAsync(portIndex)) {
1812            onCmdComplete(OMX_CommandFlush, portIndex);
1813        }
1814    } else {
1815        disablePortAsync(portIndex);
1816    }
1817}
1818
1819bool OMXCodec::flushPortAsync(OMX_U32 portIndex) {
1820    CHECK(mState == EXECUTING || mState == RECONFIGURING
1821            || mState == EXECUTING_TO_IDLE);
1822
1823    CODEC_LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.",
1824         portIndex, countBuffersWeOwn(mPortBuffers[portIndex]),
1825         mPortBuffers[portIndex].size());
1826
1827    CHECK_EQ(mPortStatus[portIndex], ENABLED);
1828    mPortStatus[portIndex] = SHUTTING_DOWN;
1829
1830    if ((mQuirks & kRequiresFlushCompleteEmulation)
1831        && countBuffersWeOwn(mPortBuffers[portIndex])
1832                == mPortBuffers[portIndex].size()) {
1833        // No flush is necessary and this component fails to send a
1834        // flush-complete event in this case.
1835
1836        return false;
1837    }
1838
1839    status_t err =
1840        mOMX->sendCommand(mNode, OMX_CommandFlush, portIndex);
1841    CHECK_EQ(err, OK);
1842
1843    return true;
1844}
1845
1846void OMXCodec::disablePortAsync(OMX_U32 portIndex) {
1847    CHECK(mState == EXECUTING || mState == RECONFIGURING);
1848
1849    CHECK_EQ(mPortStatus[portIndex], ENABLED);
1850    mPortStatus[portIndex] = DISABLING;
1851
1852    status_t err =
1853        mOMX->sendCommand(mNode, OMX_CommandPortDisable, portIndex);
1854    CHECK_EQ(err, OK);
1855
1856    freeBuffersOnPort(portIndex, true);
1857}
1858
1859void OMXCodec::enablePortAsync(OMX_U32 portIndex) {
1860    CHECK(mState == EXECUTING || mState == RECONFIGURING);
1861
1862    CHECK_EQ(mPortStatus[portIndex], DISABLED);
1863    mPortStatus[portIndex] = ENABLING;
1864
1865    status_t err =
1866        mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex);
1867    CHECK_EQ(err, OK);
1868}
1869
1870void OMXCodec::fillOutputBuffers() {
1871    CHECK_EQ(mState, EXECUTING);
1872
1873    // This is a workaround for some decoders not properly reporting
1874    // end-of-output-stream. If we own all input buffers and also own
1875    // all output buffers and we already signalled end-of-input-stream,
1876    // the end-of-output-stream is implied.
1877    if (mSignalledEOS
1878            && countBuffersWeOwn(mPortBuffers[kPortIndexInput])
1879                == mPortBuffers[kPortIndexInput].size()
1880            && countBuffersWeOwn(mPortBuffers[kPortIndexOutput])
1881                == mPortBuffers[kPortIndexOutput].size()) {
1882        mNoMoreOutputData = true;
1883        mBufferFilled.signal();
1884
1885        return;
1886    }
1887
1888    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
1889    for (size_t i = 0; i < buffers->size(); ++i) {
1890        fillOutputBuffer(&buffers->editItemAt(i));
1891    }
1892}
1893
1894void OMXCodec::drainInputBuffers() {
1895    CHECK(mState == EXECUTING || mState == RECONFIGURING);
1896
1897    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
1898    for (size_t i = 0; i < buffers->size(); ++i) {
1899        drainInputBuffer(&buffers->editItemAt(i));
1900    }
1901}
1902
1903void OMXCodec::drainInputBuffer(BufferInfo *info) {
1904    CHECK_EQ(info->mOwnedByComponent, false);
1905
1906    if (mSignalledEOS) {
1907        return;
1908    }
1909
1910    if (mCodecSpecificDataIndex < mCodecSpecificData.size()) {
1911        const CodecSpecificData *specific =
1912            mCodecSpecificData[mCodecSpecificDataIndex];
1913
1914        size_t size = specific->mSize;
1915
1916        if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME)
1917                && !(mQuirks & kWantsNALFragments)) {
1918            static const uint8_t kNALStartCode[4] =
1919                    { 0x00, 0x00, 0x00, 0x01 };
1920
1921            CHECK(info->mSize >= specific->mSize + 4);
1922
1923            size += 4;
1924
1925            memcpy(info->mData, kNALStartCode, 4);
1926            memcpy((uint8_t *)info->mData + 4,
1927                   specific->mData, specific->mSize);
1928        } else {
1929            CHECK(info->mSize >= specific->mSize);
1930            memcpy(info->mData, specific->mData, specific->mSize);
1931        }
1932
1933        mNoMoreOutputData = false;
1934
1935        CODEC_LOGV("calling emptyBuffer with codec specific data");
1936
1937        status_t err = mOMX->emptyBuffer(
1938                mNode, info->mBuffer, 0, size,
1939                OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG,
1940                0);
1941        CHECK_EQ(err, OK);
1942
1943        info->mOwnedByComponent = true;
1944
1945        ++mCodecSpecificDataIndex;
1946        return;
1947    }
1948
1949    status_t err;
1950
1951    bool signalEOS = false;
1952    int64_t timestampUs = 0;
1953
1954    size_t offset = 0;
1955    int32_t n = 0;
1956    for (;;) {
1957        MediaBuffer *srcBuffer;
1958        if (mSeekTimeUs >= 0) {
1959            if (mLeftOverBuffer) {
1960                mLeftOverBuffer->release();
1961                mLeftOverBuffer = NULL;
1962            }
1963
1964            MediaSource::ReadOptions options;
1965            options.setSeekTo(mSeekTimeUs);
1966
1967            mSeekTimeUs = -1;
1968            mBufferFilled.signal();
1969
1970            err = mSource->read(&srcBuffer, &options);
1971        } else if (mLeftOverBuffer) {
1972            srcBuffer = mLeftOverBuffer;
1973            mLeftOverBuffer = NULL;
1974
1975            err = OK;
1976        } else {
1977            err = mSource->read(&srcBuffer);
1978        }
1979
1980        if (err != OK) {
1981            signalEOS = true;
1982            mFinalStatus = err;
1983            mSignalledEOS = true;
1984            break;
1985        }
1986
1987        size_t remainingBytes = info->mSize - offset;
1988
1989        if (srcBuffer->range_length() > remainingBytes) {
1990            if (offset == 0) {
1991                CODEC_LOGE(
1992                     "Codec's input buffers are too small to accomodate "
1993                     "buffer read from source (info->mSize = %d, srcLength = %d)",
1994                     info->mSize, srcBuffer->range_length());
1995
1996                srcBuffer->release();
1997                srcBuffer = NULL;
1998
1999                setState(ERROR);
2000                return;
2001            }
2002
2003            mLeftOverBuffer = srcBuffer;
2004            break;
2005        }
2006
2007        memcpy((uint8_t *)info->mData + offset,
2008               (const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(),
2009               srcBuffer->range_length());
2010
2011        int64_t lastBufferTimeUs;
2012        CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &lastBufferTimeUs));
2013        CHECK(timestampUs >= 0);
2014
2015        if (offset == 0) {
2016            timestampUs = lastBufferTimeUs;
2017        }
2018
2019        offset += srcBuffer->range_length();
2020
2021        srcBuffer->release();
2022        srcBuffer = NULL;
2023
2024        ++n;
2025
2026        if (!(mQuirks & kSupportsMultipleFramesPerInputBuffer)) {
2027            break;
2028        }
2029
2030        int64_t coalescedDurationUs = lastBufferTimeUs - timestampUs;
2031
2032        if (coalescedDurationUs > 250000ll) {
2033            // Don't coalesce more than 250ms worth of encoded data at once.
2034            break;
2035        }
2036    }
2037
2038    if (n > 1) {
2039        LOGV("coalesced %d frames into one input buffer", n);
2040    }
2041
2042    OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
2043
2044    if (signalEOS) {
2045        flags |= OMX_BUFFERFLAG_EOS;
2046    } else {
2047        mNoMoreOutputData = false;
2048    }
2049
2050    CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d), "
2051               "timestamp %lld us (%.2f secs)",
2052               info->mBuffer, offset,
2053               timestampUs, timestampUs / 1E6);
2054
2055    err = mOMX->emptyBuffer(
2056            mNode, info->mBuffer, 0, offset,
2057            flags, timestampUs);
2058
2059    if (err != OK) {
2060        setState(ERROR);
2061        return;
2062    }
2063
2064    info->mOwnedByComponent = true;
2065
2066    // This component does not ever signal the EOS flag on output buffers,
2067    // Thanks for nothing.
2068    if (mSignalledEOS && !strcmp(mComponentName, "OMX.TI.Video.encoder")) {
2069        mNoMoreOutputData = true;
2070        mBufferFilled.signal();
2071    }
2072}
2073
2074void OMXCodec::fillOutputBuffer(BufferInfo *info) {
2075    CHECK_EQ(info->mOwnedByComponent, false);
2076
2077    if (mNoMoreOutputData) {
2078        CODEC_LOGV("There is no more output data available, not "
2079             "calling fillOutputBuffer");
2080        return;
2081    }
2082
2083    CODEC_LOGV("Calling fill_buffer on buffer %p", info->mBuffer);
2084    status_t err = mOMX->fillBuffer(mNode, info->mBuffer);
2085
2086    if (err != OK) {
2087        CODEC_LOGE("fillBuffer failed w/ error 0x%08x", err);
2088
2089        setState(ERROR);
2090        return;
2091    }
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