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