OMXCodec.cpp revision 456db75516efc889e1ee4e5e16021e77c03b0941
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 <binder/IServiceManager.h>
22#include <binder/MemoryDealer.h>
23#include <binder/ProcessState.h>
24#include <media/IMediaPlayerService.h>
25#include <media/stagefright/ESDS.h>
26#include <media/stagefright/MediaBuffer.h>
27#include <media/stagefright/MediaBufferGroup.h>
28#include <media/stagefright/MediaDebug.h>
29#include <media/stagefright/MediaExtractor.h>
30#include <media/stagefright/MetaData.h>
31#include <media/stagefright/MmapSource.h>
32#include <media/stagefright/OMXCodec.h>
33#include <media/stagefright/Utils.h>
34#include <utils/Vector.h>
35
36#include <OMX_Audio.h>
37#include <OMX_Component.h>
38
39namespace android {
40
41struct CodecInfo {
42    const char *mime;
43    const char *codec;
44};
45
46static const CodecInfo kDecoderInfo[] = {
47    { "image/jpeg", "OMX.TI.JPEG.decode" },
48    { "audio/mpeg", "OMX.TI.MP3.decode" },
49    { "audio/mpeg", "OMX.PV.mp3dec" },
50    { "audio/3gpp", "OMX.TI.AMR.decode" },
51    { "audio/3gpp", "OMX.PV.amrdec" },
52    { "audio/amr-wb", "OMX.TI.WBAMR.decode" },
53    { "audio/mp4a-latm", "OMX.TI.AAC.decode" },
54    { "audio/mp4a-latm", "OMX.PV.aacdec" },
55    { "video/mp4v-es", "OMX.qcom.video.decoder.mpeg4" },
56    { "video/mp4v-es", "OMX.TI.Video.Decoder" },
57    { "video/mp4v-es", "OMX.PV.mpeg4dec" },
58    { "video/3gpp", "OMX.qcom.video.decoder.h263" },
59    { "video/3gpp", "OMX.TI.Video.Decoder" },
60    { "video/3gpp", "OMX.PV.h263dec" },
61    { "video/avc", "OMX.qcom.video.decoder.avc" },
62    { "video/avc", "OMX.TI.Video.Decoder" },
63    { "video/avc", "OMX.PV.avcdec" },
64};
65
66static const CodecInfo kEncoderInfo[] = {
67    { "audio/3gpp", "OMX.TI.AMR.encode" },
68    { "audio/3gpp", "OMX.PV.amrencnb" },
69    { "audio/amr-wb", "OMX.TI.WBAMR.encode" },
70    { "audio/mp4a-latm", "OMX.TI.AAC.encode" },
71    { "audio/mp4a-latm", "OMX.PV.aacenc" },
72    { "video/mp4v-es", "OMX.qcom.video.encoder.mpeg4" },
73    { "video/mp4v-es", "OMX.TI.Video.encoder" },
74    { "video/mp4v-es", "OMX.PV.mpeg4enc" },
75    { "video/3gpp", "OMX.qcom.video.encoder.h263" },
76    { "video/3gpp", "OMX.TI.Video.encoder" },
77    { "video/3gpp", "OMX.PV.h263enc" },
78    { "video/avc", "OMX.TI.Video.encoder" },
79    { "video/avc", "OMX.PV.avcenc" },
80};
81
82#define CODEC_LOGV(x, ...) LOGV("[%s] "x, mComponentName, ##__VA_ARGS__)
83
84struct OMXCodecObserver : public BnOMXObserver {
85    OMXCodecObserver(const wp<OMXCodec> &target)
86        : mTarget(target) {
87    }
88
89    // from IOMXObserver
90    virtual void on_message(const omx_message &msg) {
91        sp<OMXCodec> codec = mTarget.promote();
92
93        if (codec.get() != NULL) {
94            codec->on_message(msg);
95        }
96    }
97
98protected:
99    virtual ~OMXCodecObserver() {}
100
101private:
102    wp<OMXCodec> mTarget;
103
104    OMXCodecObserver(const OMXCodecObserver &);
105    OMXCodecObserver &operator=(const OMXCodecObserver &);
106};
107
108static const char *GetCodec(const CodecInfo *info, size_t numInfos,
109                            const char *mime, int index) {
110    CHECK(index >= 0);
111    for(size_t i = 0; i < numInfos; ++i) {
112        if (!strcasecmp(mime, info[i].mime)) {
113            if (index == 0) {
114                return info[i].codec;
115            }
116
117            --index;
118        }
119    }
120
121    return NULL;
122}
123
124enum {
125    kAVCProfileBaseline      = 0x42,
126    kAVCProfileMain          = 0x4d,
127    kAVCProfileExtended      = 0x58,
128    kAVCProfileHigh          = 0x64,
129    kAVCProfileHigh10        = 0x6e,
130    kAVCProfileHigh422       = 0x7a,
131    kAVCProfileHigh444       = 0xf4,
132    kAVCProfileCAVLC444Intra = 0x2c
133};
134
135static const char *AVCProfileToString(uint8_t profile) {
136    switch (profile) {
137        case kAVCProfileBaseline:
138            return "Baseline";
139        case kAVCProfileMain:
140            return "Main";
141        case kAVCProfileExtended:
142            return "Extended";
143        case kAVCProfileHigh:
144            return "High";
145        case kAVCProfileHigh10:
146            return "High 10";
147        case kAVCProfileHigh422:
148            return "High 422";
149        case kAVCProfileHigh444:
150            return "High 444";
151        case kAVCProfileCAVLC444Intra:
152            return "CAVLC 444 Intra";
153        default:   return "Unknown";
154    }
155}
156
157template<class T>
158static void InitOMXParams(T *params) {
159    params->nSize = sizeof(T);
160    params->nVersion.s.nVersionMajor = 1;
161    params->nVersion.s.nVersionMinor = 0;
162    params->nVersion.s.nRevision = 0;
163    params->nVersion.s.nStep = 0;
164}
165
166// static
167sp<OMXCodec> OMXCodec::Create(
168        const sp<IOMX> &omx,
169        const sp<MetaData> &meta, bool createEncoder,
170        const sp<MediaSource> &source) {
171    const char *mime;
172    bool success = meta->findCString(kKeyMIMEType, &mime);
173    CHECK(success);
174
175    const char *componentName = NULL;
176    IOMX::node_id node = 0;
177    for (int index = 0;; ++index) {
178        if (createEncoder) {
179            componentName = GetCodec(
180                    kEncoderInfo, sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]),
181                    mime, index);
182        } else {
183            componentName = GetCodec(
184                    kDecoderInfo, sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]),
185                    mime, index);
186        }
187
188        if (!componentName) {
189            return NULL;
190        }
191
192        LOGV("Attempting to allocate OMX node '%s'", componentName);
193
194        status_t err = omx->allocate_node(componentName, &node);
195        if (err == OK) {
196            LOGI("Successfully allocated OMX node '%s'", componentName);
197            break;
198        }
199    }
200
201    uint32_t quirks = 0;
202    if (!strcmp(componentName, "OMX.PV.avcdec")) {
203        quirks |= kWantsNALFragments;
204    }
205    if (!strcmp(componentName, "OMX.TI.MP3.decode")) {
206        quirks |= kNeedsFlushBeforeDisable;
207    }
208    if (!strcmp(componentName, "OMX.TI.AAC.decode")) {
209        quirks |= kNeedsFlushBeforeDisable;
210        quirks |= kRequiresFlushCompleteEmulation;
211
212        // The following is currently necessary for proper shutdown
213        // behaviour, but NOT enabled by default in order to make the
214        // bug reproducible...
215        // quirks |= kRequiresFlushBeforeShutdown;
216    }
217    if (!strncmp(componentName, "OMX.qcom.video.encoder.", 23)) {
218        quirks |= kRequiresLoadedToIdleAfterAllocation;
219        quirks |= kRequiresAllocateBufferOnInputPorts;
220    }
221    if (!strncmp(componentName, "OMX.qcom.video.decoder.", 23)) {
222        // XXX Required on P....on only.
223        quirks |= kRequiresAllocateBufferOnOutputPorts;
224    }
225
226    sp<OMXCodec> codec = new OMXCodec(
227            omx, node, quirks, createEncoder, mime, componentName,
228            source);
229
230    uint32_t type;
231    const void *data;
232    size_t size;
233    if (meta->findData(kKeyESDS, &type, &data, &size)) {
234        ESDS esds((const char *)data, size);
235        CHECK_EQ(esds.InitCheck(), OK);
236
237        const void *codec_specific_data;
238        size_t codec_specific_data_size;
239        esds.getCodecSpecificInfo(
240                &codec_specific_data, &codec_specific_data_size);
241
242        printf("found codec-specific data of size %d\n",
243               codec_specific_data_size);
244
245        codec->addCodecSpecificData(
246                codec_specific_data, codec_specific_data_size);
247    } else if (meta->findData(kKeyAVCC, &type, &data, &size)) {
248        printf("found avcc of size %d\n", size);
249
250        // Parse the AVCDecoderConfigurationRecord
251
252        const uint8_t *ptr = (const uint8_t *)data;
253
254        CHECK(size >= 7);
255        CHECK_EQ(ptr[0], 1);  // configurationVersion == 1
256        uint8_t profile = ptr[1];
257        uint8_t level = ptr[3];
258
259        CHECK((ptr[4] >> 2) == 0x3f);  // reserved
260
261        size_t lengthSize = 1 + (ptr[4] & 3);
262
263        // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
264        // violates it...
265        // CHECK((ptr[5] >> 5) == 7);  // reserved
266
267        size_t numSeqParameterSets = ptr[5] & 31;
268
269        ptr += 6;
270        size -= 6;
271
272        for (size_t i = 0; i < numSeqParameterSets; ++i) {
273            CHECK(size >= 2);
274            size_t length = U16_AT(ptr);
275
276            ptr += 2;
277            size -= 2;
278
279            CHECK(size >= length);
280
281            codec->addCodecSpecificData(ptr, length);
282
283            ptr += length;
284            size -= length;
285        }
286
287        CHECK(size >= 1);
288        size_t numPictureParameterSets = *ptr;
289        ++ptr;
290        --size;
291
292        for (size_t i = 0; i < numPictureParameterSets; ++i) {
293            CHECK(size >= 2);
294            size_t length = U16_AT(ptr);
295
296            ptr += 2;
297            size -= 2;
298
299            CHECK(size >= length);
300
301            codec->addCodecSpecificData(ptr, length);
302
303            ptr += length;
304            size -= length;
305        }
306
307        LOGI("AVC profile = %d (%s), level = %d",
308             (int)profile, AVCProfileToString(profile), (int)level / 10);
309
310        if (!strcmp(componentName, "OMX.TI.Video.Decoder")
311            && (profile != kAVCProfileBaseline || level > 39)) {
312            // This stream exceeds the decoder's capabilities.
313
314            LOGE("Profile and/or level exceed the decoder's capabilities.");
315            return NULL;
316        }
317    }
318
319    if (!strcasecmp("audio/3gpp", mime)) {
320        codec->setAMRFormat();
321    }
322    if (!strcasecmp("audio/amr-wb", mime)) {
323        codec->setAMRWBFormat();
324    }
325    if (!strcasecmp("audio/mp4a-latm", mime)) {
326        int32_t numChannels, sampleRate;
327        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
328        CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
329
330        codec->setAACFormat(numChannels, sampleRate);
331    }
332    if (!strncasecmp(mime, "video/", 6)) {
333        int32_t width, height;
334        bool success = meta->findInt32(kKeyWidth, &width);
335        success = success && meta->findInt32(kKeyHeight, &height);
336        CHECK(success);
337
338        if (createEncoder) {
339            codec->setVideoInputFormat(mime, width, height);
340        } else {
341            codec->setVideoOutputFormat(mime, width, height);
342        }
343    }
344    if (!strcasecmp(mime, "image/jpeg")
345        && !strcmp(componentName, "OMX.TI.JPEG.decode")) {
346        OMX_COLOR_FORMATTYPE format =
347            OMX_COLOR_Format32bitARGB8888;
348            // OMX_COLOR_FormatYUV420PackedPlanar;
349            // OMX_COLOR_FormatCbYCrY;
350            // OMX_COLOR_FormatYUV411Planar;
351
352        int32_t width, height;
353        bool success = meta->findInt32(kKeyWidth, &width);
354        success = success && meta->findInt32(kKeyHeight, &height);
355
356        int32_t compressedSize;
357        success = success && meta->findInt32(
358                kKeyMaxInputSize, &compressedSize);
359
360        CHECK(success);
361        CHECK(compressedSize > 0);
362
363        codec->setImageOutputFormat(format, width, height);
364        codec->setJPEGInputFormat(width, height, (OMX_U32)compressedSize);
365    }
366
367    int32_t maxInputSize;
368    if (createEncoder && meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
369        codec->setMinBufferSize(kPortIndexInput, (OMX_U32)maxInputSize);
370    }
371
372    if (!strcmp(componentName, "OMX.TI.AMR.encode")
373        || !strcmp(componentName, "OMX.TI.WBAMR.encode")) {
374        codec->setMinBufferSize(kPortIndexOutput, 8192);  // XXX
375    }
376
377    codec->initOutputFormat(meta);
378
379    return codec;
380}
381
382void OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) {
383    OMX_PARAM_PORTDEFINITIONTYPE def;
384    InitOMXParams(&def);
385    def.nPortIndex = portIndex;
386
387    status_t err = mOMX->get_parameter(
388            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
389    CHECK_EQ(err, OK);
390
391    if (def.nBufferSize < size) {
392        def.nBufferSize = size;
393
394    }
395
396    err = mOMX->set_parameter(
397            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
398    CHECK_EQ(err, OK);
399}
400
401status_t OMXCodec::setVideoPortFormatType(
402        OMX_U32 portIndex,
403        OMX_VIDEO_CODINGTYPE compressionFormat,
404        OMX_COLOR_FORMATTYPE colorFormat) {
405    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
406    InitOMXParams(&format);
407    format.nPortIndex = portIndex;
408    format.nIndex = 0;
409    bool found = false;
410
411    OMX_U32 index = 0;
412    for (;;) {
413        format.nIndex = index;
414        status_t err = mOMX->get_parameter(
415                mNode, OMX_IndexParamVideoPortFormat,
416                &format, sizeof(format));
417
418        if (err != OK) {
419            return err;
420        }
421
422        // The following assertion is violated by TI's video decoder.
423        // CHECK_EQ(format.nIndex, index);
424
425#if 1
426        LOGI("portIndex: %ld, index: %ld, eCompressionFormat=%d eColorFormat=%d",
427             portIndex,
428             index, format.eCompressionFormat, format.eColorFormat);
429#endif
430
431        if (!strcmp("OMX.TI.Video.encoder", mComponentName)) {
432            if (portIndex == kPortIndexInput
433                    && colorFormat == format.eColorFormat) {
434                // eCompressionFormat does not seem right.
435                found = true;
436                break;
437            }
438            if (portIndex == kPortIndexOutput
439                    && compressionFormat == format.eCompressionFormat) {
440                // eColorFormat does not seem right.
441                found = true;
442                break;
443            }
444        }
445
446        if (format.eCompressionFormat == compressionFormat
447            && format.eColorFormat == colorFormat) {
448            found = true;
449            break;
450        }
451
452        ++index;
453    }
454
455    if (!found) {
456        return UNKNOWN_ERROR;
457    }
458
459    LOGI("found a match.");
460    status_t err = mOMX->set_parameter(
461            mNode, OMX_IndexParamVideoPortFormat,
462            &format, sizeof(format));
463
464    return err;
465}
466
467void OMXCodec::setVideoInputFormat(
468        const char *mime, OMX_U32 width, OMX_U32 height) {
469    LOGI("setVideoInputFormat width=%ld, height=%ld", width, height);
470
471    OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
472    if (!strcasecmp("video/avc", mime)) {
473        compressionFormat = OMX_VIDEO_CodingAVC;
474    } else if (!strcasecmp("video/mp4v-es", mime)) {
475        compressionFormat = OMX_VIDEO_CodingMPEG4;
476    } else if (!strcasecmp("video/3gpp", mime)) {
477        compressionFormat = OMX_VIDEO_CodingH263;
478    } else {
479        LOGE("Not a supported video mime type: %s", mime);
480        CHECK(!"Should not be here. Not a supported video mime type.");
481    }
482
483    OMX_COLOR_FORMATTYPE colorFormat =
484        0 ? OMX_COLOR_FormatYCbYCr : OMX_COLOR_FormatCbYCrY;
485
486    if (!strncmp("OMX.qcom.video.encoder.", mComponentName, 23)) {
487        colorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
488    }
489
490    setVideoPortFormatType(
491            kPortIndexInput, OMX_VIDEO_CodingUnused,
492            colorFormat);
493
494    setVideoPortFormatType(
495            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
496
497    OMX_PARAM_PORTDEFINITIONTYPE def;
498    InitOMXParams(&def);
499    def.nPortIndex = kPortIndexOutput;
500
501    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
502
503    status_t err = mOMX->get_parameter(
504            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
505
506    CHECK_EQ(err, OK);
507    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
508
509    video_def->nFrameWidth = width;
510    video_def->nFrameHeight = height;
511
512    video_def->eCompressionFormat = compressionFormat;
513    video_def->eColorFormat = OMX_COLOR_FormatUnused;
514
515    err = mOMX->set_parameter(
516            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
517    CHECK_EQ(err, OK);
518
519    ////////////////////////////////////////////////////////////////////////////
520
521    InitOMXParams(&def);
522    def.nPortIndex = kPortIndexInput;
523
524    err = mOMX->get_parameter(
525            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
526    CHECK_EQ(err, OK);
527
528    def.nBufferSize = (width * height * 2); // (width * height * 3) / 2;
529    LOGI("Setting nBufferSize = %ld", def.nBufferSize);
530
531    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
532
533    video_def->nFrameWidth = width;
534    video_def->nFrameHeight = height;
535    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
536    video_def->eColorFormat = colorFormat;
537
538    err = mOMX->set_parameter(
539            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
540    CHECK_EQ(err, OK);
541}
542
543void OMXCodec::setVideoOutputFormat(
544        const char *mime, OMX_U32 width, OMX_U32 height) {
545    LOGI("setVideoOutputFormat width=%ld, height=%ld", width, height);
546
547    OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
548    if (!strcasecmp("video/avc", mime)) {
549        compressionFormat = OMX_VIDEO_CodingAVC;
550    } else if (!strcasecmp("video/mp4v-es", mime)) {
551        compressionFormat = OMX_VIDEO_CodingMPEG4;
552    } else if (!strcasecmp("video/3gpp", mime)) {
553        compressionFormat = OMX_VIDEO_CodingH263;
554    } else {
555        LOGE("Not a supported video mime type: %s", mime);
556        CHECK(!"Should not be here. Not a supported video mime type.");
557    }
558
559    setVideoPortFormatType(
560            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
561
562#if 1
563    {
564        OMX_VIDEO_PARAM_PORTFORMATTYPE format;
565        InitOMXParams(&format);
566        format.nPortIndex = kPortIndexOutput;
567        format.nIndex = 0;
568
569        status_t err = mOMX->get_parameter(
570                mNode, OMX_IndexParamVideoPortFormat,
571                &format, sizeof(format));
572        CHECK_EQ(err, OK);
573        CHECK_EQ(format.eCompressionFormat, OMX_VIDEO_CodingUnused);
574
575        static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
576
577        CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
578               || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
579               || format.eColorFormat == OMX_COLOR_FormatCbYCrY
580               || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar);
581
582        err = mOMX->set_parameter(
583                mNode, OMX_IndexParamVideoPortFormat,
584                &format, sizeof(format));
585        CHECK_EQ(err, OK);
586    }
587#endif
588
589    OMX_PARAM_PORTDEFINITIONTYPE def;
590    InitOMXParams(&def);
591    def.nPortIndex = kPortIndexInput;
592
593    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
594
595    status_t err = mOMX->get_parameter(
596            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
597
598    CHECK_EQ(err, OK);
599
600#if 1
601    // XXX Need a (much) better heuristic to compute input buffer sizes.
602    const size_t X = 64 * 1024;
603    if (def.nBufferSize < X) {
604        def.nBufferSize = X;
605    }
606#endif
607
608    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
609
610    video_def->nFrameWidth = width;
611    video_def->nFrameHeight = height;
612
613    video_def->eColorFormat = OMX_COLOR_FormatUnused;
614
615    err = mOMX->set_parameter(
616            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
617    CHECK_EQ(err, OK);
618
619    ////////////////////////////////////////////////////////////////////////////
620
621    InitOMXParams(&def);
622    def.nPortIndex = kPortIndexOutput;
623
624    err = mOMX->get_parameter(
625            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
626    CHECK_EQ(err, OK);
627    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
628
629#if 0
630    def.nBufferSize =
631        (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2;  // YUV420
632#endif
633
634    video_def->nFrameWidth = width;
635    video_def->nFrameHeight = height;
636
637    err = mOMX->set_parameter(
638            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
639    CHECK_EQ(err, OK);
640}
641
642
643OMXCodec::OMXCodec(
644        const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks,
645        bool isEncoder,
646        const char *mime,
647        const char *componentName,
648        const sp<MediaSource> &source)
649    : mOMX(omx),
650      mNode(node),
651      mQuirks(quirks),
652      mIsEncoder(isEncoder),
653      mMIME(strdup(mime)),
654      mComponentName(strdup(componentName)),
655      mSource(source),
656      mCodecSpecificDataIndex(0),
657      mState(LOADED),
658      mInitialBufferSubmit(true),
659      mSignalledEOS(false),
660      mNoMoreOutputData(false),
661      mSeekTimeUs(-1) {
662    mPortStatus[kPortIndexInput] = ENABLED;
663    mPortStatus[kPortIndexOutput] = ENABLED;
664
665    mObserver = new OMXCodecObserver(this);
666    mOMX->observe_node(mNode, mObserver);
667
668    setComponentRole();
669}
670
671void OMXCodec::setComponentRole() {
672    struct MimeToRole {
673        const char *mime;
674        const char *decoderRole;
675        const char *encoderRole;
676    };
677
678    static const MimeToRole kMimeToRole[] = {
679        { "audio/mpeg", "audio_decoder.mp3", "audio_encoder.mp3" },
680        { "audio/3gpp", "audio_decoder.amrnb", "audio_encoder.amrnb" },
681        { "audio/amr-wb", "audio_decoder.amrwb", "audio_encoder.amrwb" },
682        { "audio/mp4a-latm", "audio_decoder.aac", "audio_encoder.aac" },
683        { "video/avc",  "video_decoder.avc", "video_encoder.avc" },
684        { "video/mp4v-es", "video_decoder.mpeg4", "video_encoder.mpeg4" },
685        { "video/3gpp", "video_decoder.h263", "video_encoder.h263" },
686    };
687
688    static const size_t kNumMimeToRole =
689        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
690
691    size_t i;
692    for (i = 0; i < kNumMimeToRole; ++i) {
693        if (!strcasecmp(mMIME, kMimeToRole[i].mime)) {
694            break;
695        }
696    }
697
698    if (i == kNumMimeToRole) {
699        return;
700    }
701
702    const char *role =
703        mIsEncoder ? kMimeToRole[i].encoderRole
704                   : kMimeToRole[i].decoderRole;
705
706    if (role != NULL) {
707        CODEC_LOGV("Setting component role '%s'.", role);
708
709        OMX_PARAM_COMPONENTROLETYPE roleParams;
710        InitOMXParams(&roleParams);
711
712        strncpy((char *)roleParams.cRole,
713                role, OMX_MAX_STRINGNAME_SIZE - 1);
714
715        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
716
717        status_t err = mOMX->set_parameter(
718                mNode, OMX_IndexParamStandardComponentRole,
719                &roleParams, sizeof(roleParams));
720
721        if (err != OK) {
722            LOGW("Failed to set standard component role '%s'.", role);
723        }
724    }
725}
726
727OMXCodec::~OMXCodec() {
728    CHECK(mState == LOADED || mState == ERROR);
729
730    status_t err = mOMX->observe_node(mNode, NULL);
731    CHECK_EQ(err, OK);
732
733    err = mOMX->free_node(mNode);
734    CHECK_EQ(err, OK);
735
736    mNode = NULL;
737    setState(DEAD);
738
739    clearCodecSpecificData();
740
741    free(mComponentName);
742    mComponentName = NULL;
743
744    free(mMIME);
745    mMIME = NULL;
746}
747
748status_t OMXCodec::init() {
749    // mLock is held.
750
751    CHECK_EQ(mState, LOADED);
752
753    status_t err;
754    if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) {
755        err = mOMX->send_command(mNode, OMX_CommandStateSet, OMX_StateIdle);
756        CHECK_EQ(err, OK);
757        setState(LOADED_TO_IDLE);
758    }
759
760    err = allocateBuffers();
761    CHECK_EQ(err, OK);
762
763    if (mQuirks & kRequiresLoadedToIdleAfterAllocation) {
764        err = mOMX->send_command(mNode, OMX_CommandStateSet, OMX_StateIdle);
765        CHECK_EQ(err, OK);
766
767        setState(LOADED_TO_IDLE);
768    }
769
770    while (mState != EXECUTING && mState != ERROR) {
771        mAsyncCompletion.wait(mLock);
772    }
773
774    return mState == ERROR ? UNKNOWN_ERROR : OK;
775}
776
777// static
778bool OMXCodec::isIntermediateState(State state) {
779    return state == LOADED_TO_IDLE
780        || state == IDLE_TO_EXECUTING
781        || state == EXECUTING_TO_IDLE
782        || state == IDLE_TO_LOADED
783        || state == RECONFIGURING;
784}
785
786status_t OMXCodec::allocateBuffers() {
787    status_t err = allocateBuffersOnPort(kPortIndexInput);
788
789    if (err != OK) {
790        return err;
791    }
792
793    return allocateBuffersOnPort(kPortIndexOutput);
794}
795
796status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
797    OMX_PARAM_PORTDEFINITIONTYPE def;
798    InitOMXParams(&def);
799    def.nPortIndex = portIndex;
800
801    status_t err = mOMX->get_parameter(
802            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
803
804    if (err != OK) {
805        return err;
806    }
807
808    size_t totalSize = def.nBufferCountActual * def.nBufferSize;
809    mDealer[portIndex] = new MemoryDealer(totalSize);
810
811    for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
812        sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
813        CHECK(mem.get() != NULL);
814
815        IOMX::buffer_id buffer;
816        if (portIndex == kPortIndexInput
817                && (mQuirks & kRequiresAllocateBufferOnInputPorts)) {
818            err = mOMX->allocate_buffer_with_backup(
819                    mNode, portIndex, mem, &buffer);
820        } else if (portIndex == kPortIndexOutput
821                && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) {
822            err = mOMX->allocate_buffer(
823                    mNode, portIndex, def.nBufferSize, &buffer);
824        } else {
825            err = mOMX->use_buffer(mNode, portIndex, mem, &buffer);
826        }
827
828        if (err != OK) {
829            LOGE("allocate_buffer_with_backup failed");
830            return err;
831        }
832
833        BufferInfo info;
834        info.mBuffer = buffer;
835        info.mOwnedByComponent = false;
836        info.mMem = mem;
837        info.mMediaBuffer = NULL;
838
839        if (portIndex == kPortIndexOutput) {
840            info.mMediaBuffer = new MediaBuffer(mem->pointer(), mem->size());
841            info.mMediaBuffer->setObserver(this);
842        }
843
844        mPortBuffers[portIndex].push(info);
845
846        CODEC_LOGV("allocated buffer %p on %s port", buffer,
847             portIndex == kPortIndexInput ? "input" : "output");
848    }
849
850    dumpPortStatus(portIndex);
851
852    return OK;
853}
854
855void OMXCodec::on_message(const omx_message &msg) {
856    Mutex::Autolock autoLock(mLock);
857
858    switch (msg.type) {
859        case omx_message::EVENT:
860        {
861            onEvent(
862                 msg.u.event_data.event, msg.u.event_data.data1,
863                 msg.u.event_data.data2);
864
865            break;
866        }
867
868        case omx_message::EMPTY_BUFFER_DONE:
869        {
870            IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
871
872            CODEC_LOGV("EMPTY_BUFFER_DONE(buffer: %p)", buffer);
873
874            Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
875            size_t i = 0;
876            while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
877                ++i;
878            }
879
880            CHECK(i < buffers->size());
881            if (!(*buffers)[i].mOwnedByComponent) {
882                LOGW("We already own input buffer %p, yet received "
883                     "an EMPTY_BUFFER_DONE.", buffer);
884            }
885
886            buffers->editItemAt(i).mOwnedByComponent = false;
887
888            if (mPortStatus[kPortIndexInput] == DISABLING) {
889                CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
890
891                status_t err =
892                    mOMX->free_buffer(mNode, kPortIndexInput, buffer);
893                CHECK_EQ(err, OK);
894
895                buffers->removeAt(i);
896            } else if (mPortStatus[kPortIndexInput] != SHUTTING_DOWN) {
897                CHECK_EQ(mPortStatus[kPortIndexInput], ENABLED);
898                drainInputBuffer(&buffers->editItemAt(i));
899            }
900
901            break;
902        }
903
904        case omx_message::FILL_BUFFER_DONE:
905        {
906            IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
907            OMX_U32 flags = msg.u.extended_buffer_data.flags;
908
909            CODEC_LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx)",
910                 buffer,
911                 msg.u.extended_buffer_data.range_length,
912                 flags);
913
914            CODEC_LOGV("FILL_BUFFER_DONE(timestamp: %lld us (%.2f secs))",
915                 msg.u.extended_buffer_data.timestamp,
916                 msg.u.extended_buffer_data.timestamp / 1E6);
917
918            Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
919            size_t i = 0;
920            while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
921                ++i;
922            }
923
924            CHECK(i < buffers->size());
925            BufferInfo *info = &buffers->editItemAt(i);
926
927            if (!info->mOwnedByComponent) {
928                LOGW("We already own output buffer %p, yet received "
929                     "a FILL_BUFFER_DONE.", buffer);
930            }
931
932            info->mOwnedByComponent = false;
933
934            if (mPortStatus[kPortIndexOutput] == DISABLING) {
935                CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
936
937                status_t err =
938                    mOMX->free_buffer(mNode, kPortIndexOutput, buffer);
939                CHECK_EQ(err, OK);
940
941                buffers->removeAt(i);
942            } else if (mPortStatus[kPortIndexOutput] == ENABLED
943                       && (flags & OMX_BUFFERFLAG_EOS)) {
944                CODEC_LOGV("No more output data.");
945                mNoMoreOutputData = true;
946                mBufferFilled.signal();
947            } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) {
948                CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED);
949
950                MediaBuffer *buffer = info->mMediaBuffer;
951
952                buffer->set_range(
953                        msg.u.extended_buffer_data.range_offset,
954                        msg.u.extended_buffer_data.range_length);
955
956                buffer->meta_data()->clear();
957
958                buffer->meta_data()->setInt32(
959                        kKeyTimeUnits,
960                        (msg.u.extended_buffer_data.timestamp + 500) / 1000);
961
962                buffer->meta_data()->setInt32(
963                        kKeyTimeScale, 1000);
964
965                if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) {
966                    buffer->meta_data()->setInt32(kKeyIsSyncFrame, true);
967                }
968
969                buffer->meta_data()->setPointer(
970                        kKeyPlatformPrivate,
971                        msg.u.extended_buffer_data.platform_private);
972
973                buffer->meta_data()->setPointer(
974                        kKeyBufferID,
975                        msg.u.extended_buffer_data.buffer);
976
977                mFilledBuffers.push_back(i);
978                mBufferFilled.signal();
979            }
980
981            break;
982        }
983
984        default:
985        {
986            CHECK(!"should not be here.");
987            break;
988        }
989    }
990}
991
992void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
993    switch (event) {
994        case OMX_EventCmdComplete:
995        {
996            onCmdComplete((OMX_COMMANDTYPE)data1, data2);
997            break;
998        }
999
1000        case OMX_EventError:
1001        {
1002            LOGE("ERROR(%ld, %ld)", data1, data2);
1003
1004            setState(ERROR);
1005            break;
1006        }
1007
1008        case OMX_EventPortSettingsChanged:
1009        {
1010            onPortSettingsChanged(data1);
1011            break;
1012        }
1013
1014        case OMX_EventBufferFlag:
1015        {
1016            CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1);
1017
1018            if (data1 == kPortIndexOutput) {
1019                mNoMoreOutputData = true;
1020            }
1021            break;
1022        }
1023
1024        default:
1025        {
1026            CODEC_LOGV("EVENT(%d, %ld, %ld)", event, data1, data2);
1027            break;
1028        }
1029    }
1030}
1031
1032void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) {
1033    switch (cmd) {
1034        case OMX_CommandStateSet:
1035        {
1036            onStateChange((OMX_STATETYPE)data);
1037            break;
1038        }
1039
1040        case OMX_CommandPortDisable:
1041        {
1042            OMX_U32 portIndex = data;
1043            CODEC_LOGV("PORT_DISABLED(%ld)", portIndex);
1044
1045            CHECK(mState == EXECUTING || mState == RECONFIGURING);
1046            CHECK_EQ(mPortStatus[portIndex], DISABLING);
1047            CHECK_EQ(mPortBuffers[portIndex].size(), 0);
1048
1049            mPortStatus[portIndex] = DISABLED;
1050
1051            if (mState == RECONFIGURING) {
1052                CHECK_EQ(portIndex, kPortIndexOutput);
1053
1054                enablePortAsync(portIndex);
1055
1056                status_t err = allocateBuffersOnPort(portIndex);
1057                CHECK_EQ(err, OK);
1058            }
1059            break;
1060        }
1061
1062        case OMX_CommandPortEnable:
1063        {
1064            OMX_U32 portIndex = data;
1065            CODEC_LOGV("PORT_ENABLED(%ld)", portIndex);
1066
1067            CHECK(mState == EXECUTING || mState == RECONFIGURING);
1068            CHECK_EQ(mPortStatus[portIndex], ENABLING);
1069
1070            mPortStatus[portIndex] = ENABLED;
1071
1072            if (mState == RECONFIGURING) {
1073                CHECK_EQ(portIndex, kPortIndexOutput);
1074
1075                setState(EXECUTING);
1076
1077                fillOutputBuffers();
1078            }
1079            break;
1080        }
1081
1082        case OMX_CommandFlush:
1083        {
1084            OMX_U32 portIndex = data;
1085
1086            CODEC_LOGV("FLUSH_DONE(%ld)", portIndex);
1087
1088            CHECK_EQ(mPortStatus[portIndex], SHUTTING_DOWN);
1089            mPortStatus[portIndex] = ENABLED;
1090
1091            CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]),
1092                     mPortBuffers[portIndex].size());
1093
1094            if (mState == RECONFIGURING) {
1095                CHECK_EQ(portIndex, kPortIndexOutput);
1096
1097                disablePortAsync(portIndex);
1098            } else if (mState == EXECUTING_TO_IDLE) {
1099                if (mPortStatus[kPortIndexInput] == ENABLED
1100                    && mPortStatus[kPortIndexOutput] == ENABLED) {
1101                    CODEC_LOGV("Finished flushing both ports, now completing "
1102                         "transition from EXECUTING to IDLE.");
1103
1104                    mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
1105                    mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
1106
1107                    status_t err =
1108                        mOMX->send_command(mNode, OMX_CommandStateSet, OMX_StateIdle);
1109                    CHECK_EQ(err, OK);
1110                }
1111            } else {
1112                // We're flushing both ports in preparation for seeking.
1113
1114                if (mPortStatus[kPortIndexInput] == ENABLED
1115                    && mPortStatus[kPortIndexOutput] == ENABLED) {
1116                    CODEC_LOGV("Finished flushing both ports, now continuing from"
1117                         " seek-time.");
1118
1119                    drainInputBuffers();
1120                    fillOutputBuffers();
1121                }
1122            }
1123
1124            break;
1125        }
1126
1127        default:
1128        {
1129            CODEC_LOGV("CMD_COMPLETE(%d, %ld)", cmd, data);
1130            break;
1131        }
1132    }
1133}
1134
1135void OMXCodec::onStateChange(OMX_STATETYPE newState) {
1136    switch (newState) {
1137        case OMX_StateIdle:
1138        {
1139            CODEC_LOGV("Now Idle.");
1140            if (mState == LOADED_TO_IDLE) {
1141                status_t err = mOMX->send_command(
1142                        mNode, OMX_CommandStateSet, OMX_StateExecuting);
1143
1144                CHECK_EQ(err, OK);
1145
1146                setState(IDLE_TO_EXECUTING);
1147            } else {
1148                CHECK_EQ(mState, EXECUTING_TO_IDLE);
1149
1150                CHECK_EQ(
1151                    countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
1152                    mPortBuffers[kPortIndexInput].size());
1153
1154                CHECK_EQ(
1155                    countBuffersWeOwn(mPortBuffers[kPortIndexOutput]),
1156                    mPortBuffers[kPortIndexOutput].size());
1157
1158                status_t err = mOMX->send_command(
1159                        mNode, OMX_CommandStateSet, OMX_StateLoaded);
1160
1161                CHECK_EQ(err, OK);
1162
1163                err = freeBuffersOnPort(kPortIndexInput);
1164                CHECK_EQ(err, OK);
1165
1166                err = freeBuffersOnPort(kPortIndexOutput);
1167                CHECK_EQ(err, OK);
1168
1169                mPortStatus[kPortIndexInput] = ENABLED;
1170                mPortStatus[kPortIndexOutput] = ENABLED;
1171
1172                setState(IDLE_TO_LOADED);
1173            }
1174            break;
1175        }
1176
1177        case OMX_StateExecuting:
1178        {
1179            CHECK_EQ(mState, IDLE_TO_EXECUTING);
1180
1181            CODEC_LOGV("Now Executing.");
1182
1183            setState(EXECUTING);
1184
1185            // Buffers will be submitted to the component in the first
1186            // call to OMXCodec::read as mInitialBufferSubmit is true at
1187            // this point. This ensures that this on_message call returns,
1188            // releases the lock and ::init can notice the state change and
1189            // itself return.
1190            break;
1191        }
1192
1193        case OMX_StateLoaded:
1194        {
1195            CHECK_EQ(mState, IDLE_TO_LOADED);
1196
1197            CODEC_LOGV("Now Loaded.");
1198
1199            setState(LOADED);
1200            break;
1201        }
1202
1203        default:
1204        {
1205            CHECK(!"should not be here.");
1206            break;
1207        }
1208    }
1209}
1210
1211// static
1212size_t OMXCodec::countBuffersWeOwn(const Vector<BufferInfo> &buffers) {
1213    size_t n = 0;
1214    for (size_t i = 0; i < buffers.size(); ++i) {
1215        if (!buffers[i].mOwnedByComponent) {
1216            ++n;
1217        }
1218    }
1219
1220    return n;
1221}
1222
1223status_t OMXCodec::freeBuffersOnPort(
1224        OMX_U32 portIndex, bool onlyThoseWeOwn) {
1225    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
1226
1227    status_t stickyErr = OK;
1228
1229    for (size_t i = buffers->size(); i-- > 0;) {
1230        BufferInfo *info = &buffers->editItemAt(i);
1231
1232        if (onlyThoseWeOwn && info->mOwnedByComponent) {
1233            continue;
1234        }
1235
1236        CHECK_EQ(info->mOwnedByComponent, false);
1237
1238        status_t err =
1239            mOMX->free_buffer(mNode, portIndex, info->mBuffer);
1240
1241        if (err != OK) {
1242            stickyErr = err;
1243        }
1244
1245        if (info->mMediaBuffer != NULL) {
1246            info->mMediaBuffer->setObserver(NULL);
1247
1248            // Make sure nobody but us owns this buffer at this point.
1249            CHECK_EQ(info->mMediaBuffer->refcount(), 0);
1250
1251            info->mMediaBuffer->release();
1252        }
1253
1254        buffers->removeAt(i);
1255    }
1256
1257    CHECK(onlyThoseWeOwn || buffers->isEmpty());
1258
1259    return stickyErr;
1260}
1261
1262void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) {
1263    CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex);
1264
1265    CHECK_EQ(mState, EXECUTING);
1266    CHECK_EQ(portIndex, kPortIndexOutput);
1267    setState(RECONFIGURING);
1268
1269    if (mQuirks & kNeedsFlushBeforeDisable) {
1270        if (!flushPortAsync(portIndex)) {
1271            onCmdComplete(OMX_CommandFlush, portIndex);
1272        }
1273    } else {
1274        disablePortAsync(portIndex);
1275    }
1276}
1277
1278bool OMXCodec::flushPortAsync(OMX_U32 portIndex) {
1279    CHECK(mState == EXECUTING || mState == RECONFIGURING
1280            || mState == EXECUTING_TO_IDLE);
1281
1282    CODEC_LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.",
1283         portIndex, countBuffersWeOwn(mPortBuffers[portIndex]),
1284         mPortBuffers[portIndex].size());
1285
1286    CHECK_EQ(mPortStatus[portIndex], ENABLED);
1287    mPortStatus[portIndex] = SHUTTING_DOWN;
1288
1289    if ((mQuirks & kRequiresFlushCompleteEmulation)
1290        && countBuffersWeOwn(mPortBuffers[portIndex])
1291                == mPortBuffers[portIndex].size()) {
1292        // No flush is necessary and this component fails to send a
1293        // flush-complete event in this case.
1294
1295        return false;
1296    }
1297
1298    status_t err =
1299        mOMX->send_command(mNode, OMX_CommandFlush, portIndex);
1300    CHECK_EQ(err, OK);
1301
1302    return true;
1303}
1304
1305void OMXCodec::disablePortAsync(OMX_U32 portIndex) {
1306    CHECK(mState == EXECUTING || mState == RECONFIGURING);
1307
1308    CHECK_EQ(mPortStatus[portIndex], ENABLED);
1309    mPortStatus[portIndex] = DISABLING;
1310
1311    status_t err =
1312        mOMX->send_command(mNode, OMX_CommandPortDisable, portIndex);
1313    CHECK_EQ(err, OK);
1314
1315    freeBuffersOnPort(portIndex, true);
1316}
1317
1318void OMXCodec::enablePortAsync(OMX_U32 portIndex) {
1319    CHECK(mState == EXECUTING || mState == RECONFIGURING);
1320
1321    CHECK_EQ(mPortStatus[portIndex], DISABLED);
1322    mPortStatus[portIndex] = ENABLING;
1323
1324    status_t err =
1325        mOMX->send_command(mNode, OMX_CommandPortEnable, portIndex);
1326    CHECK_EQ(err, OK);
1327}
1328
1329void OMXCodec::fillOutputBuffers() {
1330    CHECK_EQ(mState, EXECUTING);
1331
1332    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
1333    for (size_t i = 0; i < buffers->size(); ++i) {
1334        fillOutputBuffer(&buffers->editItemAt(i));
1335    }
1336}
1337
1338void OMXCodec::drainInputBuffers() {
1339    CHECK(mState == EXECUTING || mState == RECONFIGURING);
1340
1341    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
1342    for (size_t i = 0; i < buffers->size(); ++i) {
1343        drainInputBuffer(&buffers->editItemAt(i));
1344    }
1345}
1346
1347void OMXCodec::drainInputBuffer(BufferInfo *info) {
1348    CHECK_EQ(info->mOwnedByComponent, false);
1349
1350    if (mSignalledEOS) {
1351        return;
1352    }
1353
1354    if (mCodecSpecificDataIndex < mCodecSpecificData.size()) {
1355        const CodecSpecificData *specific =
1356            mCodecSpecificData[mCodecSpecificDataIndex];
1357
1358        size_t size = specific->mSize;
1359
1360        if (!strcasecmp("video/avc", mMIME)
1361                && !(mQuirks & kWantsNALFragments)) {
1362            static const uint8_t kNALStartCode[4] =
1363                    { 0x00, 0x00, 0x00, 0x01 };
1364
1365            CHECK(info->mMem->size() >= specific->mSize + 4);
1366
1367            size += 4;
1368
1369            memcpy(info->mMem->pointer(), kNALStartCode, 4);
1370            memcpy((uint8_t *)info->mMem->pointer() + 4,
1371                   specific->mData, specific->mSize);
1372        } else {
1373            CHECK(info->mMem->size() >= specific->mSize);
1374            memcpy(info->mMem->pointer(), specific->mData, specific->mSize);
1375        }
1376
1377        mOMX->empty_buffer(
1378                mNode, info->mBuffer, 0, size,
1379                OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG,
1380                0);
1381
1382        info->mOwnedByComponent = true;
1383
1384        ++mCodecSpecificDataIndex;
1385        return;
1386    }
1387
1388    MediaBuffer *srcBuffer;
1389    status_t err;
1390    if (mSeekTimeUs >= 0) {
1391        MediaSource::ReadOptions options;
1392        options.setSeekTo(mSeekTimeUs);
1393        mSeekTimeUs = -1;
1394
1395        err = mSource->read(&srcBuffer, &options);
1396    } else {
1397        err = mSource->read(&srcBuffer);
1398    }
1399
1400    OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
1401    OMX_TICKS timestamp = 0;
1402    size_t srcLength = 0;
1403
1404    if (err != OK) {
1405        CODEC_LOGV("signalling end of input stream.");
1406        flags |= OMX_BUFFERFLAG_EOS;
1407
1408        mSignalledEOS = true;
1409    } else {
1410        srcLength = srcBuffer->range_length();
1411
1412        if (info->mMem->size() < srcLength) {
1413            LOGE("info->mMem->size() = %d, srcLength = %d",
1414                 info->mMem->size(), srcLength);
1415        }
1416        CHECK(info->mMem->size() >= srcLength);
1417        memcpy(info->mMem->pointer(),
1418               (const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(),
1419               srcLength);
1420
1421        int32_t units, scale;
1422        if (srcBuffer->meta_data()->findInt32(kKeyTimeUnits, &units)
1423            && srcBuffer->meta_data()->findInt32(kKeyTimeScale, &scale)) {
1424            timestamp = ((OMX_TICKS)units * 1000000) / scale;
1425
1426            CODEC_LOGV("Calling empty_buffer on buffer %p (length %d)",
1427                 info->mBuffer, srcLength);
1428            CODEC_LOGV("Calling empty_buffer with timestamp %lld us (%.2f secs)",
1429                 timestamp, timestamp / 1E6);
1430        }
1431    }
1432
1433    mOMX->empty_buffer(
1434            mNode, info->mBuffer, 0, srcLength,
1435            flags, timestamp);
1436
1437    info->mOwnedByComponent = true;
1438
1439    if (srcBuffer != NULL) {
1440        srcBuffer->release();
1441        srcBuffer = NULL;
1442    }
1443}
1444
1445void OMXCodec::fillOutputBuffer(BufferInfo *info) {
1446    CHECK_EQ(info->mOwnedByComponent, false);
1447
1448    if (mNoMoreOutputData) {
1449        CODEC_LOGV("There is no more output data available, not "
1450             "calling fillOutputBuffer");
1451        return;
1452    }
1453
1454    CODEC_LOGV("Calling fill_buffer on buffer %p", info->mBuffer);
1455    mOMX->fill_buffer(mNode, info->mBuffer);
1456
1457    info->mOwnedByComponent = true;
1458}
1459
1460void OMXCodec::drainInputBuffer(IOMX::buffer_id buffer) {
1461    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
1462    for (size_t i = 0; i < buffers->size(); ++i) {
1463        if ((*buffers)[i].mBuffer == buffer) {
1464            drainInputBuffer(&buffers->editItemAt(i));
1465            return;
1466        }
1467    }
1468
1469    CHECK(!"should not be here.");
1470}
1471
1472void OMXCodec::fillOutputBuffer(IOMX::buffer_id buffer) {
1473    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
1474    for (size_t i = 0; i < buffers->size(); ++i) {
1475        if ((*buffers)[i].mBuffer == buffer) {
1476            fillOutputBuffer(&buffers->editItemAt(i));
1477            return;
1478        }
1479    }
1480
1481    CHECK(!"should not be here.");
1482}
1483
1484void OMXCodec::setState(State newState) {
1485    mState = newState;
1486    mAsyncCompletion.signal();
1487
1488    // This may cause some spurious wakeups but is necessary to
1489    // unblock the reader if we enter ERROR state.
1490    mBufferFilled.signal();
1491}
1492
1493void OMXCodec::setRawAudioFormat(
1494        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1495    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1496    InitOMXParams(&pcmParams);
1497    pcmParams.nPortIndex = portIndex;
1498
1499    status_t err = mOMX->get_parameter(
1500            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1501
1502    CHECK_EQ(err, OK);
1503
1504    pcmParams.nChannels = numChannels;
1505    pcmParams.eNumData = OMX_NumericalDataSigned;
1506    pcmParams.bInterleaved = OMX_TRUE;
1507    pcmParams.nBitPerSample = 16;
1508    pcmParams.nSamplingRate = sampleRate;
1509    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1510
1511    if (numChannels == 1) {
1512        pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelCF;
1513    } else {
1514        CHECK_EQ(numChannels, 2);
1515
1516        pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
1517        pcmParams.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
1518    }
1519
1520    err = mOMX->set_parameter(
1521            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1522
1523    CHECK_EQ(err, OK);
1524}
1525
1526void OMXCodec::setAMRFormat() {
1527    if (!mIsEncoder) {
1528        OMX_AUDIO_PARAM_AMRTYPE def;
1529        InitOMXParams(&def);
1530        def.nPortIndex = kPortIndexInput;
1531
1532        status_t err =
1533            mOMX->get_parameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1534
1535        CHECK_EQ(err, OK);
1536
1537        def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
1538        def.eAMRBandMode = OMX_AUDIO_AMRBandModeNB0;
1539
1540        err = mOMX->set_parameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1541        CHECK_EQ(err, OK);
1542    }
1543
1544    ////////////////////////
1545
1546    if (mIsEncoder) {
1547        sp<MetaData> format = mSource->getFormat();
1548        int32_t sampleRate;
1549        int32_t numChannels;
1550        CHECK(format->findInt32(kKeySampleRate, &sampleRate));
1551        CHECK(format->findInt32(kKeyChannelCount, &numChannels));
1552
1553        setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1554    }
1555}
1556
1557void OMXCodec::setAMRWBFormat() {
1558    if (!mIsEncoder) {
1559        OMX_AUDIO_PARAM_AMRTYPE def;
1560        InitOMXParams(&def);
1561        def.nPortIndex = kPortIndexInput;
1562
1563        status_t err =
1564            mOMX->get_parameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1565
1566        CHECK_EQ(err, OK);
1567
1568        def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
1569        def.eAMRBandMode = OMX_AUDIO_AMRBandModeWB0;
1570
1571        err = mOMX->set_parameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1572        CHECK_EQ(err, OK);
1573    }
1574
1575    ////////////////////////
1576
1577    if (mIsEncoder) {
1578        sp<MetaData> format = mSource->getFormat();
1579        int32_t sampleRate;
1580        int32_t numChannels;
1581        CHECK(format->findInt32(kKeySampleRate, &sampleRate));
1582        CHECK(format->findInt32(kKeyChannelCount, &numChannels));
1583
1584        setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1585    }
1586}
1587
1588void OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate) {
1589    if (mIsEncoder) {
1590        setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1591    } else {
1592        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1593        InitOMXParams(&profile);
1594        profile.nPortIndex = kPortIndexInput;
1595
1596        status_t err = mOMX->get_parameter(
1597                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1598        CHECK_EQ(err, OK);
1599
1600        profile.nChannels = numChannels;
1601        profile.nSampleRate = sampleRate;
1602        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
1603
1604        err = mOMX->set_parameter(
1605                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1606        CHECK_EQ(err, OK);
1607    }
1608}
1609
1610void OMXCodec::setImageOutputFormat(
1611        OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) {
1612    CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height);
1613
1614#if 0
1615    OMX_INDEXTYPE index;
1616    status_t err = mOMX->get_extension_index(
1617            mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index);
1618    CHECK_EQ(err, OK);
1619
1620    err = mOMX->set_config(mNode, index, &format, sizeof(format));
1621    CHECK_EQ(err, OK);
1622#endif
1623
1624    OMX_PARAM_PORTDEFINITIONTYPE def;
1625    InitOMXParams(&def);
1626    def.nPortIndex = kPortIndexOutput;
1627
1628    status_t err = mOMX->get_parameter(
1629            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1630    CHECK_EQ(err, OK);
1631
1632    CHECK_EQ(def.eDomain, OMX_PortDomainImage);
1633
1634    OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
1635
1636    CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused);
1637    imageDef->eColorFormat = format;
1638    imageDef->nFrameWidth = width;
1639    imageDef->nFrameHeight = height;
1640
1641    switch (format) {
1642        case OMX_COLOR_FormatYUV420PackedPlanar:
1643        case OMX_COLOR_FormatYUV411Planar:
1644        {
1645            def.nBufferSize = (width * height * 3) / 2;
1646            break;
1647        }
1648
1649        case OMX_COLOR_FormatCbYCrY:
1650        {
1651            def.nBufferSize = width * height * 2;
1652            break;
1653        }
1654
1655        case OMX_COLOR_Format32bitARGB8888:
1656        {
1657            def.nBufferSize = width * height * 4;
1658            break;
1659        }
1660
1661        default:
1662            CHECK(!"Should not be here. Unknown color format.");
1663            break;
1664    }
1665
1666    def.nBufferCountActual = def.nBufferCountMin;
1667
1668    err = mOMX->set_parameter(
1669            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1670    CHECK_EQ(err, OK);
1671}
1672
1673void OMXCodec::setJPEGInputFormat(
1674        OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) {
1675    OMX_PARAM_PORTDEFINITIONTYPE def;
1676    InitOMXParams(&def);
1677    def.nPortIndex = kPortIndexInput;
1678
1679    status_t err = mOMX->get_parameter(
1680            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1681    CHECK_EQ(err, OK);
1682
1683    CHECK_EQ(def.eDomain, OMX_PortDomainImage);
1684    OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
1685
1686    CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingJPEG);
1687    imageDef->nFrameWidth = width;
1688    imageDef->nFrameHeight = height;
1689
1690    def.nBufferSize = compressedSize;
1691    def.nBufferCountActual = def.nBufferCountMin;
1692
1693    err = mOMX->set_parameter(
1694            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1695    CHECK_EQ(err, OK);
1696}
1697
1698void OMXCodec::addCodecSpecificData(const void *data, size_t size) {
1699    CodecSpecificData *specific =
1700        (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1);
1701
1702    specific->mSize = size;
1703    memcpy(specific->mData, data, size);
1704
1705    mCodecSpecificData.push(specific);
1706}
1707
1708void OMXCodec::clearCodecSpecificData() {
1709    for (size_t i = 0; i < mCodecSpecificData.size(); ++i) {
1710        free(mCodecSpecificData.editItemAt(i));
1711    }
1712    mCodecSpecificData.clear();
1713    mCodecSpecificDataIndex = 0;
1714}
1715
1716status_t OMXCodec::start(MetaData *) {
1717    Mutex::Autolock autoLock(mLock);
1718
1719    if (mState != LOADED) {
1720        return UNKNOWN_ERROR;
1721    }
1722
1723    sp<MetaData> params = new MetaData;
1724    if (mQuirks & kWantsNALFragments) {
1725        params->setInt32(kKeyWantsNALFragments, true);
1726    }
1727    status_t err = mSource->start(params.get());
1728
1729    if (err != OK) {
1730        return err;
1731    }
1732
1733    mCodecSpecificDataIndex = 0;
1734    mInitialBufferSubmit = true;
1735    mSignalledEOS = false;
1736    mNoMoreOutputData = false;
1737    mSeekTimeUs = -1;
1738    mFilledBuffers.clear();
1739
1740    return init();
1741}
1742
1743status_t OMXCodec::stop() {
1744    CODEC_LOGV("stop");
1745
1746    Mutex::Autolock autoLock(mLock);
1747
1748    while (isIntermediateState(mState)) {
1749        mAsyncCompletion.wait(mLock);
1750    }
1751
1752    switch (mState) {
1753        case LOADED:
1754        case ERROR:
1755            break;
1756
1757        case EXECUTING:
1758        {
1759            setState(EXECUTING_TO_IDLE);
1760
1761            if (mQuirks & kRequiresFlushBeforeShutdown) {
1762                CODEC_LOGV("This component requires a flush before transitioning "
1763                     "from EXECUTING to IDLE...");
1764
1765                bool emulateInputFlushCompletion =
1766                    !flushPortAsync(kPortIndexInput);
1767
1768                bool emulateOutputFlushCompletion =
1769                    !flushPortAsync(kPortIndexOutput);
1770
1771                if (emulateInputFlushCompletion) {
1772                    onCmdComplete(OMX_CommandFlush, kPortIndexInput);
1773                }
1774
1775                if (emulateOutputFlushCompletion) {
1776                    onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
1777                }
1778            } else {
1779                mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
1780                mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
1781
1782                status_t err =
1783                    mOMX->send_command(mNode, OMX_CommandStateSet, OMX_StateIdle);
1784                CHECK_EQ(err, OK);
1785            }
1786
1787            while (mState != LOADED && mState != ERROR) {
1788                mAsyncCompletion.wait(mLock);
1789            }
1790
1791            break;
1792        }
1793
1794        default:
1795        {
1796            CHECK(!"should not be here.");
1797            break;
1798        }
1799    }
1800
1801    mSource->stop();
1802
1803    return OK;
1804}
1805
1806sp<MetaData> OMXCodec::getFormat() {
1807    return mOutputFormat;
1808}
1809
1810status_t OMXCodec::read(
1811        MediaBuffer **buffer, const ReadOptions *options) {
1812    *buffer = NULL;
1813
1814    Mutex::Autolock autoLock(mLock);
1815
1816    if (mState != EXECUTING && mState != RECONFIGURING) {
1817        return UNKNOWN_ERROR;
1818    }
1819
1820    if (mInitialBufferSubmit) {
1821        mInitialBufferSubmit = false;
1822
1823        drainInputBuffers();
1824
1825        if (mState == EXECUTING) {
1826            // Otherwise mState == RECONFIGURING and this code will trigger
1827            // after the output port is reenabled.
1828            fillOutputBuffers();
1829        }
1830    }
1831
1832    int64_t seekTimeUs;
1833    if (options && options->getSeekTo(&seekTimeUs)) {
1834        CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6);
1835
1836        mSignalledEOS = false;
1837        mNoMoreOutputData = false;
1838
1839        CHECK(seekTimeUs >= 0);
1840        mSeekTimeUs = seekTimeUs;
1841
1842        mFilledBuffers.clear();
1843
1844        CHECK_EQ(mState, EXECUTING);
1845
1846        bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput);
1847        bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput);
1848
1849        if (emulateInputFlushCompletion) {
1850            onCmdComplete(OMX_CommandFlush, kPortIndexInput);
1851        }
1852
1853        if (emulateOutputFlushCompletion) {
1854            onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
1855        }
1856    }
1857
1858    while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) {
1859        mBufferFilled.wait(mLock);
1860    }
1861
1862    if (mState == ERROR) {
1863        return UNKNOWN_ERROR;
1864    }
1865
1866    if (mFilledBuffers.empty()) {
1867        return ERROR_END_OF_STREAM;
1868    }
1869
1870    size_t index = *mFilledBuffers.begin();
1871    mFilledBuffers.erase(mFilledBuffers.begin());
1872
1873    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
1874    info->mMediaBuffer->add_ref();
1875    *buffer = info->mMediaBuffer;
1876
1877    return OK;
1878}
1879
1880void OMXCodec::signalBufferReturned(MediaBuffer *buffer) {
1881    Mutex::Autolock autoLock(mLock);
1882
1883    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
1884    for (size_t i = 0; i < buffers->size(); ++i) {
1885        BufferInfo *info = &buffers->editItemAt(i);
1886
1887        if (info->mMediaBuffer == buffer) {
1888            CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED);
1889            fillOutputBuffer(info);
1890            return;
1891        }
1892    }
1893
1894    CHECK(!"should not be here.");
1895}
1896
1897static const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) {
1898    static const char *kNames[] = {
1899        "OMX_IMAGE_CodingUnused",
1900        "OMX_IMAGE_CodingAutoDetect",
1901        "OMX_IMAGE_CodingJPEG",
1902        "OMX_IMAGE_CodingJPEG2K",
1903        "OMX_IMAGE_CodingEXIF",
1904        "OMX_IMAGE_CodingTIFF",
1905        "OMX_IMAGE_CodingGIF",
1906        "OMX_IMAGE_CodingPNG",
1907        "OMX_IMAGE_CodingLZW",
1908        "OMX_IMAGE_CodingBMP",
1909    };
1910
1911    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
1912
1913    if (type < 0 || (size_t)type >= numNames) {
1914        return "UNKNOWN";
1915    } else {
1916        return kNames[type];
1917    }
1918}
1919
1920static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) {
1921    static const char *kNames[] = {
1922        "OMX_COLOR_FormatUnused",
1923        "OMX_COLOR_FormatMonochrome",
1924        "OMX_COLOR_Format8bitRGB332",
1925        "OMX_COLOR_Format12bitRGB444",
1926        "OMX_COLOR_Format16bitARGB4444",
1927        "OMX_COLOR_Format16bitARGB1555",
1928        "OMX_COLOR_Format16bitRGB565",
1929        "OMX_COLOR_Format16bitBGR565",
1930        "OMX_COLOR_Format18bitRGB666",
1931        "OMX_COLOR_Format18bitARGB1665",
1932        "OMX_COLOR_Format19bitARGB1666",
1933        "OMX_COLOR_Format24bitRGB888",
1934        "OMX_COLOR_Format24bitBGR888",
1935        "OMX_COLOR_Format24bitARGB1887",
1936        "OMX_COLOR_Format25bitARGB1888",
1937        "OMX_COLOR_Format32bitBGRA8888",
1938        "OMX_COLOR_Format32bitARGB8888",
1939        "OMX_COLOR_FormatYUV411Planar",
1940        "OMX_COLOR_FormatYUV411PackedPlanar",
1941        "OMX_COLOR_FormatYUV420Planar",
1942        "OMX_COLOR_FormatYUV420PackedPlanar",
1943        "OMX_COLOR_FormatYUV420SemiPlanar",
1944        "OMX_COLOR_FormatYUV422Planar",
1945        "OMX_COLOR_FormatYUV422PackedPlanar",
1946        "OMX_COLOR_FormatYUV422SemiPlanar",
1947        "OMX_COLOR_FormatYCbYCr",
1948        "OMX_COLOR_FormatYCrYCb",
1949        "OMX_COLOR_FormatCbYCrY",
1950        "OMX_COLOR_FormatCrYCbY",
1951        "OMX_COLOR_FormatYUV444Interleaved",
1952        "OMX_COLOR_FormatRawBayer8bit",
1953        "OMX_COLOR_FormatRawBayer10bit",
1954        "OMX_COLOR_FormatRawBayer8bitcompressed",
1955        "OMX_COLOR_FormatL2",
1956        "OMX_COLOR_FormatL4",
1957        "OMX_COLOR_FormatL8",
1958        "OMX_COLOR_FormatL16",
1959        "OMX_COLOR_FormatL24",
1960        "OMX_COLOR_FormatL32",
1961        "OMX_COLOR_FormatYUV420PackedSemiPlanar",
1962        "OMX_COLOR_FormatYUV422PackedSemiPlanar",
1963        "OMX_COLOR_Format18BitBGR666",
1964        "OMX_COLOR_Format24BitARGB6666",
1965        "OMX_COLOR_Format24BitABGR6666",
1966    };
1967
1968    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
1969
1970    static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
1971
1972    if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) {
1973        return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar";
1974    } else if (type < 0 || (size_t)type >= numNames) {
1975        return "UNKNOWN";
1976    } else {
1977        return kNames[type];
1978    }
1979}
1980
1981static const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) {
1982    static const char *kNames[] = {
1983        "OMX_VIDEO_CodingUnused",
1984        "OMX_VIDEO_CodingAutoDetect",
1985        "OMX_VIDEO_CodingMPEG2",
1986        "OMX_VIDEO_CodingH263",
1987        "OMX_VIDEO_CodingMPEG4",
1988        "OMX_VIDEO_CodingWMV",
1989        "OMX_VIDEO_CodingRV",
1990        "OMX_VIDEO_CodingAVC",
1991        "OMX_VIDEO_CodingMJPEG",
1992    };
1993
1994    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
1995
1996    if (type < 0 || (size_t)type >= numNames) {
1997        return "UNKNOWN";
1998    } else {
1999        return kNames[type];
2000    }
2001}
2002
2003static const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) {
2004    static const char *kNames[] = {
2005        "OMX_AUDIO_CodingUnused",
2006        "OMX_AUDIO_CodingAutoDetect",
2007        "OMX_AUDIO_CodingPCM",
2008        "OMX_AUDIO_CodingADPCM",
2009        "OMX_AUDIO_CodingAMR",
2010        "OMX_AUDIO_CodingGSMFR",
2011        "OMX_AUDIO_CodingGSMEFR",
2012        "OMX_AUDIO_CodingGSMHR",
2013        "OMX_AUDIO_CodingPDCFR",
2014        "OMX_AUDIO_CodingPDCEFR",
2015        "OMX_AUDIO_CodingPDCHR",
2016        "OMX_AUDIO_CodingTDMAFR",
2017        "OMX_AUDIO_CodingTDMAEFR",
2018        "OMX_AUDIO_CodingQCELP8",
2019        "OMX_AUDIO_CodingQCELP13",
2020        "OMX_AUDIO_CodingEVRC",
2021        "OMX_AUDIO_CodingSMV",
2022        "OMX_AUDIO_CodingG711",
2023        "OMX_AUDIO_CodingG723",
2024        "OMX_AUDIO_CodingG726",
2025        "OMX_AUDIO_CodingG729",
2026        "OMX_AUDIO_CodingAAC",
2027        "OMX_AUDIO_CodingMP3",
2028        "OMX_AUDIO_CodingSBC",
2029        "OMX_AUDIO_CodingVORBIS",
2030        "OMX_AUDIO_CodingWMA",
2031        "OMX_AUDIO_CodingRA",
2032        "OMX_AUDIO_CodingMIDI",
2033    };
2034
2035    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2036
2037    if (type < 0 || (size_t)type >= numNames) {
2038        return "UNKNOWN";
2039    } else {
2040        return kNames[type];
2041    }
2042}
2043
2044static const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) {
2045    static const char *kNames[] = {
2046        "OMX_AUDIO_PCMModeLinear",
2047        "OMX_AUDIO_PCMModeALaw",
2048        "OMX_AUDIO_PCMModeMULaw",
2049    };
2050
2051    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2052
2053    if (type < 0 || (size_t)type >= numNames) {
2054        return "UNKNOWN";
2055    } else {
2056        return kNames[type];
2057    }
2058}
2059
2060
2061void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
2062    OMX_PARAM_PORTDEFINITIONTYPE def;
2063    InitOMXParams(&def);
2064    def.nPortIndex = portIndex;
2065
2066    status_t err = mOMX->get_parameter(
2067            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2068    CHECK_EQ(err, OK);
2069
2070    printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output");
2071
2072    CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput)
2073          || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput));
2074
2075    printf("  nBufferCountActual = %ld\n", def.nBufferCountActual);
2076    printf("  nBufferCountMin = %ld\n", def.nBufferCountMin);
2077    printf("  nBufferSize = %ld\n", def.nBufferSize);
2078
2079    switch (def.eDomain) {
2080        case OMX_PortDomainImage:
2081        {
2082            const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
2083
2084            printf("\n");
2085            printf("  // Image\n");
2086            printf("  nFrameWidth = %ld\n", imageDef->nFrameWidth);
2087            printf("  nFrameHeight = %ld\n", imageDef->nFrameHeight);
2088            printf("  nStride = %ld\n", imageDef->nStride);
2089
2090            printf("  eCompressionFormat = %s\n",
2091                   imageCompressionFormatString(imageDef->eCompressionFormat));
2092
2093            printf("  eColorFormat = %s\n",
2094                   colorFormatString(imageDef->eColorFormat));
2095
2096            break;
2097        }
2098
2099        case OMX_PortDomainVideo:
2100        {
2101            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
2102
2103            printf("\n");
2104            printf("  // Video\n");
2105            printf("  nFrameWidth = %ld\n", videoDef->nFrameWidth);
2106            printf("  nFrameHeight = %ld\n", videoDef->nFrameHeight);
2107            printf("  nStride = %ld\n", videoDef->nStride);
2108
2109            printf("  eCompressionFormat = %s\n",
2110                   videoCompressionFormatString(videoDef->eCompressionFormat));
2111
2112            printf("  eColorFormat = %s\n",
2113                   colorFormatString(videoDef->eColorFormat));
2114
2115            break;
2116        }
2117
2118        case OMX_PortDomainAudio:
2119        {
2120            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
2121
2122            printf("\n");
2123            printf("  // Audio\n");
2124            printf("  eEncoding = %s\n",
2125                   audioCodingTypeString(audioDef->eEncoding));
2126
2127            if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) {
2128                OMX_AUDIO_PARAM_PCMMODETYPE params;
2129                InitOMXParams(&params);
2130                params.nPortIndex = portIndex;
2131
2132                err = mOMX->get_parameter(
2133                        mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
2134                CHECK_EQ(err, OK);
2135
2136                printf("  nSamplingRate = %ld\n", params.nSamplingRate);
2137                printf("  nChannels = %ld\n", params.nChannels);
2138                printf("  bInterleaved = %d\n", params.bInterleaved);
2139                printf("  nBitPerSample = %ld\n", params.nBitPerSample);
2140
2141                printf("  eNumData = %s\n",
2142                       params.eNumData == OMX_NumericalDataSigned
2143                        ? "signed" : "unsigned");
2144
2145                printf("  ePCMMode = %s\n", audioPCMModeString(params.ePCMMode));
2146            }
2147
2148            break;
2149        }
2150
2151        default:
2152        {
2153            printf("  // Unknown\n");
2154            break;
2155        }
2156    }
2157
2158    printf("}\n");
2159}
2160
2161void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
2162    mOutputFormat = new MetaData;
2163    mOutputFormat->setCString(kKeyDecoderComponent, mComponentName);
2164
2165    OMX_PARAM_PORTDEFINITIONTYPE def;
2166    InitOMXParams(&def);
2167    def.nPortIndex = kPortIndexOutput;
2168
2169    status_t err = mOMX->get_parameter(
2170            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2171    CHECK_EQ(err, OK);
2172
2173    switch (def.eDomain) {
2174        case OMX_PortDomainImage:
2175        {
2176            OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
2177            CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused);
2178
2179            mOutputFormat->setCString(kKeyMIMEType, "image/raw");
2180            mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat);
2181            mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth);
2182            mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight);
2183            break;
2184        }
2185
2186        case OMX_PortDomainAudio:
2187        {
2188            OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio;
2189
2190            if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) {
2191                OMX_AUDIO_PARAM_PCMMODETYPE params;
2192                InitOMXParams(&params);
2193                params.nPortIndex = kPortIndexOutput;
2194
2195                err = mOMX->get_parameter(
2196                        mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
2197                CHECK_EQ(err, OK);
2198
2199                CHECK_EQ(params.eNumData, OMX_NumericalDataSigned);
2200                CHECK_EQ(params.nBitPerSample, 16);
2201                CHECK_EQ(params.ePCMMode, OMX_AUDIO_PCMModeLinear);
2202
2203                int32_t numChannels, sampleRate;
2204                inputFormat->findInt32(kKeyChannelCount, &numChannels);
2205                inputFormat->findInt32(kKeySampleRate, &sampleRate);
2206
2207                if ((OMX_U32)numChannels != params.nChannels) {
2208                    LOGW("Codec outputs a different number of channels than "
2209                         "the input stream contains.");
2210                }
2211
2212                mOutputFormat->setCString(kKeyMIMEType, "audio/raw");
2213
2214                // Use the codec-advertised number of channels, as some
2215                // codecs appear to output stereo even if the input data is
2216                // mono.
2217                mOutputFormat->setInt32(kKeyChannelCount, params.nChannels);
2218
2219                // The codec-reported sampleRate is not reliable...
2220                mOutputFormat->setInt32(kKeySampleRate, sampleRate);
2221            } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) {
2222                mOutputFormat->setCString(kKeyMIMEType, "audio/3gpp");
2223            } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) {
2224                mOutputFormat->setCString(kKeyMIMEType, "audio/mp4a-latm");
2225            } else {
2226                CHECK(!"Should not be here. Unknown audio encoding.");
2227            }
2228            break;
2229        }
2230
2231        case OMX_PortDomainVideo:
2232        {
2233            OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2234
2235            if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) {
2236                mOutputFormat->setCString(kKeyMIMEType, "video/raw");
2237            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) {
2238                mOutputFormat->setCString(kKeyMIMEType, "video/mp4v-es");
2239            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) {
2240                mOutputFormat->setCString(kKeyMIMEType, "video/3gpp");
2241            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) {
2242                mOutputFormat->setCString(kKeyMIMEType, "video/avc");
2243            } else {
2244                CHECK(!"Unknown compression format.");
2245            }
2246
2247            if (!strcmp(mComponentName, "OMX.PV.avcdec")) {
2248                // This component appears to be lying to me.
2249                mOutputFormat->setInt32(
2250                        kKeyWidth, (video_def->nFrameWidth + 15) & -16);
2251                mOutputFormat->setInt32(
2252                        kKeyHeight, (video_def->nFrameHeight + 15) & -16);
2253            } else {
2254                mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth);
2255                mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight);
2256            }
2257
2258            mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat);
2259            break;
2260        }
2261
2262        default:
2263        {
2264            CHECK(!"should not be here, neither audio nor video.");
2265            break;
2266        }
2267    }
2268}
2269
2270}  // namespace android
2271