OMXCodec.cpp revision bf697e37550d9e8376089b0b5e498613bede798c
1693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber/*
2693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * Copyright (C) 2009 The Android Open Source Project
3693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber *
4693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * you may not use this file except in compliance with the License.
6693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * You may obtain a copy of the License at
7693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber *
8693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber *
10693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * Unless required by applicable law or agreed to in writing, software
11693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * See the License for the specific language governing permissions and
14693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * limitations under the License.
15693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber */
16693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
17693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber//#define LOG_NDEBUG 0
18693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#define LOG_TAG "OMXCodec"
19693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <utils/Log.h>
20693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2189e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "include/ESDS.h"
2289e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber
23693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <binder/IServiceManager.h>
24693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <binder/MemoryDealer.h>
25693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <binder/ProcessState.h>
26693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/IMediaPlayerService.h>
27693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MediaBuffer.h>
28693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MediaBufferGroup.h>
29693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MediaDebug.h>
3018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h>
31693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MediaExtractor.h>
32693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MetaData.h>
33693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/OMXCodec.h>
34bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber#include <media/stagefright/Utils.h>
35693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <utils/Vector.h>
36693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
37693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <OMX_Audio.h>
38693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <OMX_Component.h>
39693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
40693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubernamespace android {
41693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
42ec430b158df17b2c766f7750a96c35d3902f5f49Andreas Huberstatic const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
43ec430b158df17b2c766f7750a96c35d3902f5f49Andreas Huber
44693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstruct CodecInfo {
45693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    const char *mime;
46693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    const char *codec;
47693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber};
48693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
49693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const CodecInfo kDecoderInfo[] = {
5018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_IMAGE_JPEG, "OMX.TI.JPEG.decode" },
5118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" },
5218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.PV.mp3dec" },
5318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.decode" },
5418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.PV.amrdec" },
5518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.decode" },
5618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.PV.amrdec" },
5718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.decode" },
5818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacdec" },
5918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.decoder.mpeg4" },
6018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.Decoder" },
6118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4dec" },
6218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.decoder.h263" },
6318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.Decoder" },
6418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263dec" },
6518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" },
6618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.Decoder" },
6718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcdec" },
68693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber};
69693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
70693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const CodecInfo kEncoderInfo[] = {
7118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.encode" },
7218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.PV.amrencnb" },
7318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.encode" },
7418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.encode" },
7518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacenc" },
7618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.encoder.mpeg4" },
7718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.encoder" },
7818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4enc" },
7918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.encoder.h263" },
8018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.encoder" },
8118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263enc" },
8218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.encoder" },
8318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcenc" },
84693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber};
85693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
868cd11d23197209e2c2bdb7980bc17e3f1257a118Andreas Huber#define CODEC_LOGI(x, ...) LOGI("[%s] "x, mComponentName, ##__VA_ARGS__)
877a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber#define CODEC_LOGV(x, ...) LOGV("[%s] "x, mComponentName, ##__VA_ARGS__)
887a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
89693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstruct OMXCodecObserver : public BnOMXObserver {
90318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMXCodecObserver() {
91318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
92318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
93318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    void setCodec(const sp<OMXCodec> &target) {
94318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        mTarget = target;
95693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
96693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
97693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    // from IOMXObserver
98318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    virtual void onMessage(const omx_message &msg) {
99693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        sp<OMXCodec> codec = mTarget.promote();
100693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
101693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (codec.get() != NULL) {
102693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            codec->on_message(msg);
103693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
104693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
105693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
106693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected:
107693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    virtual ~OMXCodecObserver() {}
108693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
109693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprivate:
110693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    wp<OMXCodec> mTarget;
111693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
112693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMXCodecObserver(const OMXCodecObserver &);
113693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMXCodecObserver &operator=(const OMXCodecObserver &);
114693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber};
115693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
116693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const char *GetCodec(const CodecInfo *info, size_t numInfos,
117693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                            const char *mime, int index) {
118693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(index >= 0);
119693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for(size_t i = 0; i < numInfos; ++i) {
120693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (!strcasecmp(mime, info[i].mime)) {
121693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (index == 0) {
122693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                return info[i].codec;
123693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
124693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
125693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            --index;
126693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
127693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
128693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
129693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return NULL;
130693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
131693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
132bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huberenum {
133bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileBaseline      = 0x42,
134bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileMain          = 0x4d,
135bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileExtended      = 0x58,
136bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileHigh          = 0x64,
137bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileHigh10        = 0x6e,
138bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileHigh422       = 0x7a,
139bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileHigh444       = 0xf4,
140bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileCAVLC444Intra = 0x2c
141bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber};
142bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
143bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huberstatic const char *AVCProfileToString(uint8_t profile) {
144bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    switch (profile) {
145bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileBaseline:
146bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "Baseline";
147bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileMain:
148bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "Main";
149bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileExtended:
150bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "Extended";
151bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileHigh:
152bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "High";
153bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileHigh10:
154bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "High 10";
155bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileHigh422:
156bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "High 422";
157bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileHigh444:
158bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "High 444";
159bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileCAVLC444Intra:
160bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "CAVLC 444 Intra";
161bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        default:   return "Unknown";
162bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    }
163bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber}
164bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
1657a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Hubertemplate<class T>
1667a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huberstatic void InitOMXParams(T *params) {
1677a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nSize = sizeof(T);
1687a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nVersion.s.nVersionMajor = 1;
1697a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nVersion.s.nVersionMinor = 0;
1707a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nVersion.s.nRevision = 0;
1717a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nVersion.s.nStep = 0;
1727a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber}
1737a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
174ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huberstatic bool IsSoftwareCodec(const char *componentName) {
175ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (!strncmp("OMX.PV.", componentName, 7)) {
176ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        return true;
177ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
178693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
179ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    return false;
180ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber}
181693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
182ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huberstatic int CompareSoftwareCodecsFirst(
183ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const String8 *elem1, const String8 *elem2) {
184ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    bool isSoftwareCodec1 = IsSoftwareCodec(elem1->string());
185ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    bool isSoftwareCodec2 = IsSoftwareCodec(elem2->string());
186693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
187ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (isSoftwareCodec1) {
188ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        if (isSoftwareCodec2) { return 0; }
189ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        return -1;
190ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
191693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
192ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (isSoftwareCodec2) {
193ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        return 1;
194693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
195693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
196ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    return 0;
197ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber}
198ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
199ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber// static
200ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huberuint32_t OMXCodec::getComponentQuirks(const char *componentName) {
201693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    uint32_t quirks = 0;
202ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
203693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!strcmp(componentName, "OMX.PV.avcdec")) {
204dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        quirks |= kWantsNALFragments;
205693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
206693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!strcmp(componentName, "OMX.TI.MP3.decode")) {
207693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        quirks |= kNeedsFlushBeforeDisable;
208693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
209693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!strcmp(componentName, "OMX.TI.AAC.decode")) {
210693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        quirks |= kNeedsFlushBeforeDisable;
2111beb760d920561679862ded945a04e370368c7f7Andreas Huber        quirks |= kRequiresFlushCompleteEmulation;
212693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
213693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!strncmp(componentName, "OMX.qcom.video.encoder.", 23)) {
214693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        quirks |= kRequiresLoadedToIdleAfterAllocation;
215693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        quirks |= kRequiresAllocateBufferOnInputPorts;
216888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        quirks |= kRequiresAllocateBufferOnOutputPorts;
217693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
218b7802d9ee9c9dbb471ae4f010bd67ba1aaa9f264Andreas Huber    if (!strncmp(componentName, "OMX.qcom.video.decoder.", 23)) {
219b7802d9ee9c9dbb471ae4f010bd67ba1aaa9f264Andreas Huber        // XXX Required on P....on only.
220b7802d9ee9c9dbb471ae4f010bd67ba1aaa9f264Andreas Huber        quirks |= kRequiresAllocateBufferOnOutputPorts;
221b7802d9ee9c9dbb471ae4f010bd67ba1aaa9f264Andreas Huber    }
222693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
223df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber    if (!strncmp(componentName, "OMX.TI.", 7)) {
224df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber        // Apparently I must not use OMX_UseBuffer on either input or
225df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber        // output ports on any of the TI components or quote:
226df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber        // "(I) may have unexpected problem (sic) which can be timing related
227df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber        //  and hard to reproduce."
228df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber
229df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber        quirks |= kRequiresAllocateBufferOnInputPorts;
230df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber        quirks |= kRequiresAllocateBufferOnOutputPorts;
231df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber    }
232df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber
233ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    return quirks;
234ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber}
235ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
236ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber// static
237ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Hubervoid OMXCodec::findMatchingCodecs(
238ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const char *mime,
239ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        bool createEncoder, const char *matchComponentName,
240ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        uint32_t flags,
241ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        Vector<String8> *matchingCodecs) {
242ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    matchingCodecs->clear();
243ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
244ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    for (int index = 0;; ++index) {
245ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const char *componentName;
246ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
247ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        if (createEncoder) {
248ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            componentName = GetCodec(
249ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber                    kEncoderInfo,
250ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber                    sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]),
251ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber                    mime, index);
252ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        } else {
253ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            componentName = GetCodec(
254ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber                    kDecoderInfo,
255ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber                    sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]),
256ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber                    mime, index);
257ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        }
258ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
259ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        if (!componentName) {
260ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            break;
261ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        }
262ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
263ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        // If a specific codec is requested, skip the non-matching ones.
264ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        if (matchComponentName && strcmp(componentName, matchComponentName)) {
265ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            continue;
266ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        }
267ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
268ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        matchingCodecs->push(String8(componentName));
269ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
270ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
271ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (flags & kPreferSoftwareCodecs) {
272ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        matchingCodecs->sort(CompareSoftwareCodecsFirst);
273ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
274ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber}
275ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
276ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber// static
277bf697e37550d9e8376089b0b5e498613bede798cAndreas Hubersp<MediaSource> OMXCodec::Create(
278ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const sp<IOMX> &omx,
279ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const sp<MetaData> &meta, bool createEncoder,
280ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const sp<MediaSource> &source,
281ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const char *matchComponentName,
282ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        uint32_t flags) {
283ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    const char *mime;
284ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    bool success = meta->findCString(kKeyMIMEType, &mime);
285ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    CHECK(success);
286ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
287ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    Vector<String8> matchingCodecs;
288ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    findMatchingCodecs(
289ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            mime, createEncoder, matchComponentName, flags, &matchingCodecs);
290ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
291ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (matchingCodecs.isEmpty()) {
292ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        return NULL;
293ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
294ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
295ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    sp<OMXCodecObserver> observer = new OMXCodecObserver;
296ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    IOMX::node_id node = 0;
297ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    success = false;
298ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
299ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    const char *componentName;
300ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    for (size_t i = 0; i < matchingCodecs.size(); ++i) {
301ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        componentName = matchingCodecs[i].string();
302ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
303ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        LOGV("Attempting to allocate OMX node '%s'", componentName);
304ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
305ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        status_t err = omx->allocateNode(componentName, observer, &node);
306ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        if (err == OK) {
307ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            LOGV("Successfully allocated OMX node '%s'", componentName);
308ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
309ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            success = true;
310ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            break;
311ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        }
312ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
313ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
314ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (!success) {
315ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        return NULL;
316ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
317ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
318693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    sp<OMXCodec> codec = new OMXCodec(
319ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            omx, node, getComponentQuirks(componentName),
320ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            createEncoder, mime, componentName,
321693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            source);
322693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
323318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    observer->setCodec(codec);
324318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
325693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    uint32_t type;
326693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    const void *data;
327693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t size;
328693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (meta->findData(kKeyESDS, &type, &data, &size)) {
329693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        ESDS esds((const char *)data, size);
330693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(esds.InitCheck(), OK);
331693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
332693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const void *codec_specific_data;
333693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        size_t codec_specific_data_size;
334693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        esds.getCodecSpecificInfo(
335693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                &codec_specific_data, &codec_specific_data_size);
336693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
337693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        printf("found codec-specific data of size %d\n",
338693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber               codec_specific_data_size);
339693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
340693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        codec->addCodecSpecificData(
341693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                codec_specific_data, codec_specific_data_size);
342693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else if (meta->findData(kKeyAVCC, &type, &data, &size)) {
343693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        printf("found avcc of size %d\n", size);
344693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
345bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        // Parse the AVCDecoderConfigurationRecord
346bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
347bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        const uint8_t *ptr = (const uint8_t *)data;
348bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
349bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        CHECK(size >= 7);
350bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        CHECK_EQ(ptr[0], 1);  // configurationVersion == 1
351bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        uint8_t profile = ptr[1];
352bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        uint8_t level = ptr[3];
353bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
354e5d6df402da9b6c5577470abb81a5e6801bd7752Andreas Huber        // There is decodable content out there that fails the following
355e5d6df402da9b6c5577470abb81a5e6801bd7752Andreas Huber        // assertion, let's be lenient for now...
356e5d6df402da9b6c5577470abb81a5e6801bd7752Andreas Huber        // CHECK((ptr[4] >> 2) == 0x3f);  // reserved
357bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
358bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        size_t lengthSize = 1 + (ptr[4] & 3);
359bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
360bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
361bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        // violates it...
362bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        // CHECK((ptr[5] >> 5) == 7);  // reserved
363bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
364bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        size_t numSeqParameterSets = ptr[5] & 31;
365bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
366bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        ptr += 6;
367693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        size -= 6;
368bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
369bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        for (size_t i = 0; i < numSeqParameterSets; ++i) {
370bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            CHECK(size >= 2);
371bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            size_t length = U16_AT(ptr);
372693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
373693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            ptr += 2;
374693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            size -= 2;
375693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
376bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            CHECK(size >= length);
377bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
378bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            codec->addCodecSpecificData(ptr, length);
379bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
380bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            ptr += length;
381bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            size -= length;
382bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        }
383bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
384bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        CHECK(size >= 1);
385bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        size_t numPictureParameterSets = *ptr;
386bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        ++ptr;
387bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        --size;
388bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
389bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        for (size_t i = 0; i < numPictureParameterSets; ++i) {
390bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            CHECK(size >= 2);
391bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            size_t length = U16_AT(ptr);
392bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
393bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            ptr += 2;
394bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            size -= 2;
395693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
396693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(size >= length);
397693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
398693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            codec->addCodecSpecificData(ptr, length);
399693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
400693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            ptr += length;
401693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            size -= length;
402bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        }
403693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
4042a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber        LOGV("AVC profile = %d (%s), level = %d",
405bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber             (int)profile, AVCProfileToString(profile), (int)level / 10);
406693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
407bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        if (!strcmp(componentName, "OMX.TI.Video.Decoder")
408bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            && (profile != kAVCProfileBaseline || level > 39)) {
409318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            // This stream exceeds the decoder's capabilities. The decoder
410318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            // does not handle this gracefully and would clobber the heap
411318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            // and wreak havoc instead...
412bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
413bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            LOGE("Profile and/or level exceed the decoder's capabilities.");
414bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return NULL;
415693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
416693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
417693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
41818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) {
419c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber        codec->setAMRFormat(false /* isWAMR */);
420693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
42118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
422c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber        codec->setAMRFormat(true /* isWAMR */);
423456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber    }
42418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
42537940eefcba982836b579fe1ffec6cada72b0974Andreas Huber        int32_t numChannels, sampleRate;
42637940eefcba982836b579fe1ffec6cada72b0974Andreas Huber        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
42737940eefcba982836b579fe1ffec6cada72b0974Andreas Huber        CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
42837940eefcba982836b579fe1ffec6cada72b0974Andreas Huber
42937940eefcba982836b579fe1ffec6cada72b0974Andreas Huber        codec->setAACFormat(numChannels, sampleRate);
430693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
431693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!strncasecmp(mime, "video/", 6)) {
432693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        int32_t width, height;
433693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        bool success = meta->findInt32(kKeyWidth, &width);
434693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        success = success && meta->findInt32(kKeyHeight, &height);
4357530e9c708275c273c134c36c68179f511c1940eAndreas Huber        CHECK(success);
436693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
437693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (createEncoder) {
438693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            codec->setVideoInputFormat(mime, width, height);
439693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        } else {
440693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            codec->setVideoOutputFormat(mime, width, height);
441693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
442693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
44318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    if (!strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_JPEG)
444693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        && !strcmp(componentName, "OMX.TI.JPEG.decode")) {
445693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_COLOR_FORMATTYPE format =
446693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_COLOR_Format32bitARGB8888;
447693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            // OMX_COLOR_FormatYUV420PackedPlanar;
448693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            // OMX_COLOR_FormatCbYCrY;
449693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            // OMX_COLOR_FormatYUV411Planar;
450693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
451693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        int32_t width, height;
452693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        bool success = meta->findInt32(kKeyWidth, &width);
453693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        success = success && meta->findInt32(kKeyHeight, &height);
4547530e9c708275c273c134c36c68179f511c1940eAndreas Huber
4557530e9c708275c273c134c36c68179f511c1940eAndreas Huber        int32_t compressedSize;
4567530e9c708275c273c134c36c68179f511c1940eAndreas Huber        success = success && meta->findInt32(
457e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                kKeyMaxInputSize, &compressedSize);
4587530e9c708275c273c134c36c68179f511c1940eAndreas Huber
4597530e9c708275c273c134c36c68179f511c1940eAndreas Huber        CHECK(success);
4607530e9c708275c273c134c36c68179f511c1940eAndreas Huber        CHECK(compressedSize > 0);
461693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
462693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        codec->setImageOutputFormat(format, width, height);
4637530e9c708275c273c134c36c68179f511c1940eAndreas Huber        codec->setJPEGInputFormat(width, height, (OMX_U32)compressedSize);
464693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
465693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
466e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    int32_t maxInputSize;
467738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber    if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
468e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        codec->setMinBufferSize(kPortIndexInput, (OMX_U32)maxInputSize);
469e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
470e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
471e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    if (!strcmp(componentName, "OMX.TI.AMR.encode")
472e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        || !strcmp(componentName, "OMX.TI.WBAMR.encode")) {
473e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        codec->setMinBufferSize(kPortIndexOutput, 8192);  // XXX
474e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
475e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
476693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    codec->initOutputFormat(meta);
477693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
478693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return codec;
479693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
480693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
481e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Hubervoid OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) {
482e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
4837a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
484e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    def.nPortIndex = portIndex;
485e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
486318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
487e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
488e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    CHECK_EQ(err, OK);
489e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
490e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    if (def.nBufferSize < size) {
491e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        def.nBufferSize = size;
492e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
493e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
494318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
495e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
496e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    CHECK_EQ(err, OK);
497738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber
498738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber    err = mOMX->getParameter(
499738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
500738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber    CHECK_EQ(err, OK);
501738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber
502738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber    // Make sure the setting actually stuck.
503738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber    CHECK(def.nBufferSize >= size);
504e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber}
505e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
506693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::setVideoPortFormatType(
507693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_U32 portIndex,
508693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
509693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
510693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
5117a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&format);
512693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    format.nPortIndex = portIndex;
513693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    format.nIndex = 0;
514693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    bool found = false;
515693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
516693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_U32 index = 0;
517693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (;;) {
518693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        format.nIndex = index;
519318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        status_t err = mOMX->getParameter(
520693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
521693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                &format, sizeof(format));
522693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
523693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (err != OK) {
524693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            return err;
525693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
526693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
527693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        // The following assertion is violated by TI's video decoder.
5287530e9c708275c273c134c36c68179f511c1940eAndreas Huber        // CHECK_EQ(format.nIndex, index);
529693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
530693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#if 1
5312a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber        CODEC_LOGV("portIndex: %ld, index: %ld, eCompressionFormat=%d eColorFormat=%d",
532693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber             portIndex,
533693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber             index, format.eCompressionFormat, format.eColorFormat);
534693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#endif
535693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
536693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName)) {
537693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (portIndex == kPortIndexInput
538693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    && colorFormat == format.eColorFormat) {
539693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                // eCompressionFormat does not seem right.
540693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                found = true;
541693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                break;
542693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
543693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (portIndex == kPortIndexOutput
544693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
545693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                // eColorFormat does not seem right.
546693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                found = true;
547693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                break;
548693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
549693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
550693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
551693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (format.eCompressionFormat == compressionFormat
552693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            && format.eColorFormat == colorFormat) {
553693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            found = true;
554693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
555693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
556693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
557693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        ++index;
558693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
559693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
560693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!found) {
561693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return UNKNOWN_ERROR;
562693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
563693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
5642a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    CODEC_LOGV("found a match.");
565318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->setParameter(
566693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
567693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            &format, sizeof(format));
568693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
569693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return err;
570693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
571693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
572888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huberstatic size_t getFrameSize(
573888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat, int32_t width, int32_t height) {
574888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    switch (colorFormat) {
575888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        case OMX_COLOR_FormatYCbYCr:
576888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        case OMX_COLOR_FormatCbYCrY:
577888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            return width * height * 2;
578888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
579888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        case OMX_COLOR_FormatYUV420SemiPlanar:
580888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            return (width * height * 3) / 2;
581888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
582888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        default:
583888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            CHECK(!"Should not be here. Unsupported color format.");
584888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            break;
585888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    }
586888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber}
587888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
588693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::setVideoInputFormat(
589693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const char *mime, OMX_U32 width, OMX_U32 height) {
5902a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    CODEC_LOGV("setVideoInputFormat width=%ld, height=%ld", width, height);
591693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
592693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
59318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
594693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        compressionFormat = OMX_VIDEO_CodingAVC;
59518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
596693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        compressionFormat = OMX_VIDEO_CodingMPEG4;
59718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
598693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        compressionFormat = OMX_VIDEO_CodingH263;
599693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
600693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        LOGE("Not a supported video mime type: %s", mime);
601693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(!"Should not be here. Not a supported video mime type.");
602693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
603693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
60430ab66297501757d745b9ae10da61adcd891f497Andreas Huber    OMX_COLOR_FORMATTYPE colorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
60530ab66297501757d745b9ae10da61adcd891f497Andreas Huber    if (!strcasecmp("OMX.TI.Video.encoder", mComponentName)) {
60630ab66297501757d745b9ae10da61adcd891f497Andreas Huber        colorFormat = OMX_COLOR_FormatYCbYCr;
607693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
608693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
609888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(setVideoPortFormatType(
610693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused,
611888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            colorFormat), OK);
612693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
613888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(setVideoPortFormatType(
614888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused),
615888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            OK);
616693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
617693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
6187a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
619693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexOutput;
620693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
6217a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
6227a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
623318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
624693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
625693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
626693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
627693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
628693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
629693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameWidth = width;
630693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameHeight = height;
631693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
632693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->eCompressionFormat = compressionFormat;
633693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
634693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
635318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
636693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
637693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
638693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
639693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    ////////////////////////////////////////////////////////////////////////////
640693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
6417a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
642693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexInput;
643693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
644318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->getParameter(
645693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
646693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
647693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
648888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    def.nBufferSize = getFrameSize(colorFormat, width, height);
6492a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    CODEC_LOGV("Setting nBufferSize = %ld", def.nBufferSize);
650693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
651693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
652693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
653693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameWidth = width;
654693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameHeight = height;
655693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
656693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->eColorFormat = colorFormat;
657693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
658888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    video_def->xFramerate = 24 << 16;  // XXX crucial!
659888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
660318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
661693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
662693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
663888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
664888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    switch (compressionFormat) {
665888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        case OMX_VIDEO_CodingMPEG4:
666888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        {
667888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            CHECK_EQ(setupMPEG4EncoderParameters(), OK);
668888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            break;
669888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        }
670888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
671888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        case OMX_VIDEO_CodingH263:
672888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            break;
673888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
67430ab66297501757d745b9ae10da61adcd891f497Andreas Huber        case OMX_VIDEO_CodingAVC:
67530ab66297501757d745b9ae10da61adcd891f497Andreas Huber        {
67630ab66297501757d745b9ae10da61adcd891f497Andreas Huber            CHECK_EQ(setupAVCEncoderParameters(), OK);
67730ab66297501757d745b9ae10da61adcd891f497Andreas Huber            break;
67830ab66297501757d745b9ae10da61adcd891f497Andreas Huber        }
67930ab66297501757d745b9ae10da61adcd891f497Andreas Huber
680888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        default:
681888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            CHECK(!"Support for this compressionFormat to be implemented.");
682888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            break;
683888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    }
684888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber}
685888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
686888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huberstatus_t OMXCodec::setupMPEG4EncoderParameters() {
687888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
688888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    InitOMXParams(&mpeg4type);
689888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
690888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
691888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    status_t err = mOMX->getParameter(
692888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
693888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(err, OK);
694888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
695888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
696888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.bSVH = OMX_FALSE;
697888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.bGov = OMX_FALSE;
698888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
699888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nAllowedPictureTypes =
700888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
701888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
702888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nPFrames = 23;
703888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nBFrames = 0;
704888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
705888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nIDCVLCThreshold = 0;
706888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.bACPred = OMX_TRUE;
707888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nMaxPacketSize = 256;
708888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nTimeIncRes = 1000;
709888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nHeaderExtension = 0;
710888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
711888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
712888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.eProfile = OMX_VIDEO_MPEG4ProfileCore;
713888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.eLevel = OMX_VIDEO_MPEG4Level2;
714888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
715888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    err = mOMX->setParameter(
716888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
717888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(err, OK);
718888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
719888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    // ----------------
720888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
721888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
722888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    InitOMXParams(&bitrateType);
723888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
724888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
725888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    err = mOMX->getParameter(
726888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            mNode, OMX_IndexParamVideoBitrate,
727888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            &bitrateType, sizeof(bitrateType));
728888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(err, OK);
729888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
730888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    bitrateType.eControlRate = OMX_Video_ControlRateVariable;
731888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    bitrateType.nTargetBitrate = 1000000;
732888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
733888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    err = mOMX->setParameter(
734888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            mNode, OMX_IndexParamVideoBitrate,
735888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            &bitrateType, sizeof(bitrateType));
736888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(err, OK);
737888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
738888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    // ----------------
739888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
740888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
741888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    InitOMXParams(&errorCorrectionType);
742888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
743888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
744888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    err = mOMX->getParameter(
745888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
746888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
747888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(err, OK);
748888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
749888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
750888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
751888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
752888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
753888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
754888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
755888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    err = mOMX->setParameter(
756888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
757888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
758888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(err, OK);
759888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
760888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    return OK;
761693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
762693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
76330ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t OMXCodec::setupAVCEncoderParameters() {
76430ab66297501757d745b9ae10da61adcd891f497Andreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
76530ab66297501757d745b9ae10da61adcd891f497Andreas Huber    InitOMXParams(&h264type);
76630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nPortIndex = kPortIndexOutput;
76730ab66297501757d745b9ae10da61adcd891f497Andreas Huber
76830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    status_t err = mOMX->getParameter(
76930ab66297501757d745b9ae10da61adcd891f497Andreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
77030ab66297501757d745b9ae10da61adcd891f497Andreas Huber    CHECK_EQ(err, OK);
77130ab66297501757d745b9ae10da61adcd891f497Andreas Huber
77230ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nAllowedPictureTypes =
77330ab66297501757d745b9ae10da61adcd891f497Andreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
77430ab66297501757d745b9ae10da61adcd891f497Andreas Huber
77530ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nSliceHeaderSpacing = 0;
77630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nBFrames = 0;
77730ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bUseHadamard = OMX_TRUE;
77830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nRefFrames = 1;
77930ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nRefIdx10ActiveMinus1 = 0;
78030ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nRefIdx11ActiveMinus1 = 0;
78130ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bEnableUEP = OMX_FALSE;
78230ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bEnableFMO = OMX_FALSE;
78330ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bEnableASO = OMX_FALSE;
78430ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bEnableRS = OMX_FALSE;
78530ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
78630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.eLevel = OMX_VIDEO_AVCLevel1b;
78730ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
78830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bMBAFF = OMX_FALSE;
78930ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bEntropyCodingCABAC = OMX_FALSE;
79030ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bWeightedPPrediction = OMX_FALSE;
79130ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bconstIpred = OMX_FALSE;
79230ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bDirect8x8Inference = OMX_FALSE;
79330ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bDirectSpatialTemporal = OMX_FALSE;
79430ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nCabacInitIdc = 0;
79530ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
79630ab66297501757d745b9ae10da61adcd891f497Andreas Huber
79730ab66297501757d745b9ae10da61adcd891f497Andreas Huber    err = mOMX->setParameter(
79830ab66297501757d745b9ae10da61adcd891f497Andreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
79930ab66297501757d745b9ae10da61adcd891f497Andreas Huber    CHECK_EQ(err, OK);
80030ab66297501757d745b9ae10da61adcd891f497Andreas Huber
80130ab66297501757d745b9ae10da61adcd891f497Andreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
80230ab66297501757d745b9ae10da61adcd891f497Andreas Huber    InitOMXParams(&bitrateType);
80330ab66297501757d745b9ae10da61adcd891f497Andreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
80430ab66297501757d745b9ae10da61adcd891f497Andreas Huber
80530ab66297501757d745b9ae10da61adcd891f497Andreas Huber    err = mOMX->getParameter(
80630ab66297501757d745b9ae10da61adcd891f497Andreas Huber            mNode, OMX_IndexParamVideoBitrate,
80730ab66297501757d745b9ae10da61adcd891f497Andreas Huber            &bitrateType, sizeof(bitrateType));
80830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    CHECK_EQ(err, OK);
80930ab66297501757d745b9ae10da61adcd891f497Andreas Huber
81030ab66297501757d745b9ae10da61adcd891f497Andreas Huber    bitrateType.eControlRate = OMX_Video_ControlRateVariable;
81130ab66297501757d745b9ae10da61adcd891f497Andreas Huber    bitrateType.nTargetBitrate = 1000000;
81230ab66297501757d745b9ae10da61adcd891f497Andreas Huber
81330ab66297501757d745b9ae10da61adcd891f497Andreas Huber    err = mOMX->setParameter(
81430ab66297501757d745b9ae10da61adcd891f497Andreas Huber            mNode, OMX_IndexParamVideoBitrate,
81530ab66297501757d745b9ae10da61adcd891f497Andreas Huber            &bitrateType, sizeof(bitrateType));
81630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    CHECK_EQ(err, OK);
81730ab66297501757d745b9ae10da61adcd891f497Andreas Huber
81830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    return OK;
81930ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
82030ab66297501757d745b9ae10da61adcd891f497Andreas Huber
821693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::setVideoOutputFormat(
822693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const char *mime, OMX_U32 width, OMX_U32 height) {
8232a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    CODEC_LOGV("setVideoOutputFormat width=%ld, height=%ld", width, height);
824693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
825693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
82618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
827693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        compressionFormat = OMX_VIDEO_CodingAVC;
82818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
829693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        compressionFormat = OMX_VIDEO_CodingMPEG4;
83018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
831693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        compressionFormat = OMX_VIDEO_CodingH263;
832693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
833693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        LOGE("Not a supported video mime type: %s", mime);
834693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(!"Should not be here. Not a supported video mime type.");
835693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
836693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
837693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    setVideoPortFormatType(
838693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
839693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
840693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#if 1
841693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    {
842693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_VIDEO_PARAM_PORTFORMATTYPE format;
8437a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        InitOMXParams(&format);
844693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        format.nPortIndex = kPortIndexOutput;
845693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        format.nIndex = 0;
846693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
847318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        status_t err = mOMX->getParameter(
848693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
849693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                &format, sizeof(format));
850693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(err, OK);
851693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(format.eCompressionFormat, OMX_VIDEO_CodingUnused);
852693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
853693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
854693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
855693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
856693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber               || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
857693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber               || format.eColorFormat == OMX_COLOR_FormatCbYCrY
858693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber               || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar);
859693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
860318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        err = mOMX->setParameter(
861693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
862693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                &format, sizeof(format));
863693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(err, OK);
864693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
865693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#endif
866693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
867693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
8687a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
869693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexInput;
870693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
8717a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
8727a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
873318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
874693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
875693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
876693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
877693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
878693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#if 1
879693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    // XXX Need a (much) better heuristic to compute input buffer sizes.
880693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    const size_t X = 64 * 1024;
881693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (def.nBufferSize < X) {
882693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        def.nBufferSize = X;
883693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
884693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#endif
885693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
886693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
887693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
888693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameWidth = width;
889693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameHeight = height;
890693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
891888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    video_def->eCompressionFormat = compressionFormat;
892693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
893693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
894318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
895693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
896693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
897693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
898693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    ////////////////////////////////////////////////////////////////////////////
899693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
9007a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
901693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexOutput;
902693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
903318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->getParameter(
904693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
905693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
906693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
907693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
908693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#if 0
909693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nBufferSize =
910693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2;  // YUV420
911693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#endif
912693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
913693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameWidth = width;
914693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameHeight = height;
915693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
916318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
917693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
918693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
919693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
920693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
921693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberOMXCodec::OMXCodec(
922693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks,
923bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        bool isEncoder,
924693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const char *mime,
925693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const char *componentName,
926693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const sp<MediaSource> &source)
927693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    : mOMX(omx),
928693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mNode(node),
929693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mQuirks(quirks),
930693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mIsEncoder(isEncoder),
931693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mMIME(strdup(mime)),
932693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mComponentName(strdup(componentName)),
933693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mSource(source),
934693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mCodecSpecificDataIndex(0),
935693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mState(LOADED),
936284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber      mInitialBufferSubmit(true),
937693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mSignalledEOS(false),
938693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mNoMoreOutputData(false),
9397f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber      mOutputPortSettingsHaveChanged(false),
940693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mSeekTimeUs(-1) {
941693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mPortStatus[kPortIndexInput] = ENABLED;
942693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mPortStatus[kPortIndexOutput] = ENABLED;
943693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
9447a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    setComponentRole();
9457a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber}
9467a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
94718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber// static
94818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Hubervoid OMXCodec::setComponentRole(
94918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder,
95018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        const char *mime) {
9517a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    struct MimeToRole {
9527a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        const char *mime;
9537a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        const char *decoderRole;
9547a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        const char *encoderRole;
9557a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    };
9567a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
9577a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    static const MimeToRole kMimeToRole[] = {
95818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
95918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
96018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
96118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
96218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
96318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
96418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
96518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
96618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
96718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
96818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
96918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
97018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
97118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
9727a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    };
9737a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
9747a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    static const size_t kNumMimeToRole =
9757a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
9767a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
9777a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    size_t i;
9787a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
97918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
9807a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            break;
9817a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        }
9827a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    }
9837a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
9847a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    if (i == kNumMimeToRole) {
9857a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        return;
9867a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    }
9877a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
9887a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    const char *role =
98918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
99018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                  : kMimeToRole[i].decoderRole;
9917a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
9927a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    if (role != NULL) {
9937a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
9947a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        InitOMXParams(&roleParams);
9957a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
9967a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        strncpy((char *)roleParams.cRole,
9977a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
9987a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
9997a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
10007a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
1001318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        status_t err = omx->setParameter(
100218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                node, OMX_IndexParamStandardComponentRole,
10037a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                &roleParams, sizeof(roleParams));
10047a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
10057a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        if (err != OK) {
10067a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            LOGW("Failed to set standard component role '%s'.", role);
10077a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        }
10087a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    }
1009693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1010693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
101118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Hubervoid OMXCodec::setComponentRole() {
101218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    setComponentRole(mOMX, mNode, mIsEncoder, mMIME);
101318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber}
101418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
1015693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberOMXCodec::~OMXCodec() {
1016dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    CHECK(mState == LOADED || mState == ERROR);
1017693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1018318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->freeNode(mNode);
1019693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
1020693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1021693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mNode = NULL;
1022693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    setState(DEAD);
1023693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1024693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    clearCodecSpecificData();
1025693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1026693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    free(mComponentName);
1027693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mComponentName = NULL;
1028bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
1029693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    free(mMIME);
1030693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mMIME = NULL;
1031693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1032693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1033693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::init() {
1034284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber    // mLock is held.
1035693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1036693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(mState, LOADED);
1037693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1038693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err;
1039693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) {
1040318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
1041693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(err, OK);
1042693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        setState(LOADED_TO_IDLE);
1043693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1044693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1045693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    err = allocateBuffers();
1046693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
1047693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1048693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mQuirks & kRequiresLoadedToIdleAfterAllocation) {
1049318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
1050693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(err, OK);
1051693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1052693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        setState(LOADED_TO_IDLE);
1053693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1054693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1055693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    while (mState != EXECUTING && mState != ERROR) {
1056693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mAsyncCompletion.wait(mLock);
1057693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1058693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1059693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return mState == ERROR ? UNKNOWN_ERROR : OK;
1060693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1061693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1062693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber// static
1063693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberbool OMXCodec::isIntermediateState(State state) {
1064693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return state == LOADED_TO_IDLE
1065693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        || state == IDLE_TO_EXECUTING
1066693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        || state == EXECUTING_TO_IDLE
1067693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        || state == IDLE_TO_LOADED
1068693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        || state == RECONFIGURING;
1069693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1070693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1071693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::allocateBuffers() {
1072693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err = allocateBuffersOnPort(kPortIndexInput);
1073693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1074693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (err != OK) {
1075693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return err;
1076693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1077693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1078693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return allocateBuffersOnPort(kPortIndexOutput);
1079693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1080693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1081693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
1082693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
10837a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
1084693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = portIndex;
1085693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1086318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
1087693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1088693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1089693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (err != OK) {
1090693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return err;
1091693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1092693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
10937530e9c708275c273c134c36c68179f511c1940eAndreas Huber    size_t totalSize = def.nBufferCountActual * def.nBufferSize;
10947530e9c708275c273c134c36c68179f511c1940eAndreas Huber    mDealer[portIndex] = new MemoryDealer(totalSize);
10957530e9c708275c273c134c36c68179f511c1940eAndreas Huber
1096693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
10977530e9c708275c273c134c36c68179f511c1940eAndreas Huber        sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
1098693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(mem.get() != NULL);
1099693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1100693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        IOMX::buffer_id buffer;
1101693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (portIndex == kPortIndexInput
1102693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                && (mQuirks & kRequiresAllocateBufferOnInputPorts)) {
1103318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            err = mOMX->allocateBufferWithBackup(
1104693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    mNode, portIndex, mem, &buffer);
1105ea7d15629752256f6ea1d5c6ea796e59aefd030fAndreas Huber        } else if (portIndex == kPortIndexOutput
1106ea7d15629752256f6ea1d5c6ea796e59aefd030fAndreas Huber                && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) {
1107318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            err = mOMX->allocateBufferWithBackup(
1108df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber                    mNode, portIndex, mem, &buffer);
1109693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        } else {
1110318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
1111693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1112693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1113693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (err != OK) {
1114693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            LOGE("allocate_buffer_with_backup failed");
1115693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            return err;
1116693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1117693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1118693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        BufferInfo info;
1119693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        info.mBuffer = buffer;
1120693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        info.mOwnedByComponent = false;
1121693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        info.mMem = mem;
1122693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        info.mMediaBuffer = NULL;
1123693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1124693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (portIndex == kPortIndexOutput) {
1125693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            info.mMediaBuffer = new MediaBuffer(mem->pointer(), mem->size());
1126693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            info.mMediaBuffer->setObserver(this);
1127693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1128693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1129693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mPortBuffers[portIndex].push(info);
1130693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
11317a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        CODEC_LOGV("allocated buffer %p on %s port", buffer,
1132693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber             portIndex == kPortIndexInput ? "input" : "output");
1133693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1134693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1135693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    dumpPortStatus(portIndex);
1136693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1137693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return OK;
1138693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1139693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1140693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::on_message(const omx_message &msg) {
1141693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Mutex::Autolock autoLock(mLock);
1142693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1143693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (msg.type) {
1144693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case omx_message::EVENT:
1145693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1146693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            onEvent(
1147693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 msg.u.event_data.event, msg.u.event_data.data1,
1148693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 msg.u.event_data.data2);
1149693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1150693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1151693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1152693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1153693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
1154693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1155693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
1156693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
11577a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("EMPTY_BUFFER_DONE(buffer: %p)", buffer);
1158693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1159693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
1160693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            size_t i = 0;
1161693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
1162693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                ++i;
1163693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1164693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1165693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(i < buffers->size());
1166693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (!(*buffers)[i].mOwnedByComponent) {
1167693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                LOGW("We already own input buffer %p, yet received "
1168693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                     "an EMPTY_BUFFER_DONE.", buffer);
1169693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1170693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1171693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            buffers->editItemAt(i).mOwnedByComponent = false;
1172693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1173693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (mPortStatus[kPortIndexInput] == DISABLING) {
11747a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
1175693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1176693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                status_t err =
1177318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                    mOMX->freeBuffer(mNode, kPortIndexInput, buffer);
1178693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1179693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1180693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                buffers->removeAt(i);
1181693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else if (mPortStatus[kPortIndexInput] != SHUTTING_DOWN) {
1182693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(mPortStatus[kPortIndexInput], ENABLED);
1183693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                drainInputBuffer(&buffers->editItemAt(i));
1184693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1185693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1186693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1187693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1188693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1189693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case omx_message::FILL_BUFFER_DONE:
1190693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1191693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
1192693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_U32 flags = msg.u.extended_buffer_data.flags;
1193693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
11947a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx)",
1195693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 buffer,
1196693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 msg.u.extended_buffer_data.range_length,
1197693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 flags);
1198693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
11997a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("FILL_BUFFER_DONE(timestamp: %lld us (%.2f secs))",
1200693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 msg.u.extended_buffer_data.timestamp,
1201693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 msg.u.extended_buffer_data.timestamp / 1E6);
1202693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1203693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
1204693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            size_t i = 0;
1205693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
1206693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                ++i;
1207693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1208693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1209693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(i < buffers->size());
1210693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            BufferInfo *info = &buffers->editItemAt(i);
1211693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1212693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (!info->mOwnedByComponent) {
1213693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                LOGW("We already own output buffer %p, yet received "
1214693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                     "a FILL_BUFFER_DONE.", buffer);
1215693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1216693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1217693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            info->mOwnedByComponent = false;
1218693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1219693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (mPortStatus[kPortIndexOutput] == DISABLING) {
12207a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
1221693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1222693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                status_t err =
1223318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                    mOMX->freeBuffer(mNode, kPortIndexOutput, buffer);
1224693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1225693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1226693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                buffers->removeAt(i);
1227355edcea2f15c0f619c1e1d0f4fa433b0d38098fAndreas Huber            } else if (mPortStatus[kPortIndexOutput] == ENABLED
1228355edcea2f15c0f619c1e1d0f4fa433b0d38098fAndreas Huber                       && (flags & OMX_BUFFERFLAG_EOS)) {
12297a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                CODEC_LOGV("No more output data.");
1230693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mNoMoreOutputData = true;
1231693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mBufferFilled.signal();
1232693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) {
1233693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED);
1234bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
1235693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                MediaBuffer *buffer = info->mMediaBuffer;
1236693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1237693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                buffer->set_range(
1238693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        msg.u.extended_buffer_data.range_offset,
1239693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        msg.u.extended_buffer_data.range_length);
1240693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1241693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                buffer->meta_data()->clear();
1242693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
124348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber                buffer->meta_data()->setInt64(
124448c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber                        kKeyTime, msg.u.extended_buffer_data.timestamp);
1245693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1246693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) {
1247693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    buffer->meta_data()->setInt32(kKeyIsSyncFrame, true);
1248693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                }
124930ab66297501757d745b9ae10da61adcd891f497Andreas Huber                if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_CODECCONFIG) {
125030ab66297501757d745b9ae10da61adcd891f497Andreas Huber                    buffer->meta_data()->setInt32(kKeyIsCodecConfig, true);
125130ab66297501757d745b9ae10da61adcd891f497Andreas Huber                }
1252693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1253693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                buffer->meta_data()->setPointer(
1254693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        kKeyPlatformPrivate,
1255693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        msg.u.extended_buffer_data.platform_private);
1256693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1257693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                buffer->meta_data()->setPointer(
1258693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        kKeyBufferID,
1259693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        msg.u.extended_buffer_data.buffer);
1260693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1261693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mFilledBuffers.push_back(i);
1262693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mBufferFilled.signal();
1263693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1264693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1265693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1266693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1267693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1268693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
1269693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1270693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(!"should not be here.");
1271693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1272693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1273693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1274693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1275693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1276693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
1277693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (event) {
1278693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_EventCmdComplete:
1279693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1280693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            onCmdComplete((OMX_COMMANDTYPE)data1, data2);
1281693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1282693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1283693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1284693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_EventError:
1285693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1286693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            LOGE("ERROR(%ld, %ld)", data1, data2);
1287693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1288693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            setState(ERROR);
1289693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1290693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1291693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1292693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_EventPortSettingsChanged:
1293693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1294693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            onPortSettingsChanged(data1);
1295693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1296693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1297693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1298693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_EventBufferFlag:
1299693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
13007a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1);
1301693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1302693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (data1 == kPortIndexOutput) {
1303693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mNoMoreOutputData = true;
1304693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1305693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1306693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1307693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1308693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
1309693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
13107a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("EVENT(%d, %ld, %ld)", event, data1, data2);
1311693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1312693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1313693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1314693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1315693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
131612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber// Has the format changed in any way that the client would have to be aware of?
131712658b720b176b7d934444256d07ba3c595d9b44Andreas Huberstatic bool formatHasNotablyChanged(
131812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        const sp<MetaData> &from, const sp<MetaData> &to) {
131912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    if (from.get() == NULL && to.get() == NULL) {
132012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        return false;
132112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    }
132212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
1323c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber    if ((from.get() == NULL && to.get() != NULL)
1324c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber        || (from.get() != NULL && to.get() == NULL)) {
132512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        return true;
132612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    }
132712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
132812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    const char *mime_from, *mime_to;
132912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    CHECK(from->findCString(kKeyMIMEType, &mime_from));
133012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    CHECK(to->findCString(kKeyMIMEType, &mime_to));
133112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
133212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    if (strcasecmp(mime_from, mime_to)) {
133312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        return true;
133412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    }
133512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
133612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    if (!strcasecmp(mime_from, MEDIA_MIMETYPE_VIDEO_RAW)) {
133712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        int32_t colorFormat_from, colorFormat_to;
133812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(from->findInt32(kKeyColorFormat, &colorFormat_from));
133912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(to->findInt32(kKeyColorFormat, &colorFormat_to));
134012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
134112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        if (colorFormat_from != colorFormat_to) {
134212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber            return true;
134312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        }
134412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
134512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        int32_t width_from, width_to;
134612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(from->findInt32(kKeyWidth, &width_from));
134712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(to->findInt32(kKeyWidth, &width_to));
134812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
134912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        if (width_from != width_to) {
135012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber            return true;
135112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        }
135212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
135312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        int32_t height_from, height_to;
135412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(from->findInt32(kKeyHeight, &height_from));
135512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(to->findInt32(kKeyHeight, &height_to));
135612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
135712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        if (height_from != height_to) {
135812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber            return true;
135912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        }
136012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    } else if (!strcasecmp(mime_from, MEDIA_MIMETYPE_AUDIO_RAW)) {
136112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        int32_t numChannels_from, numChannels_to;
136212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(from->findInt32(kKeyChannelCount, &numChannels_from));
136312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(to->findInt32(kKeyChannelCount, &numChannels_to));
136412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
136512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        if (numChannels_from != numChannels_to) {
136612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber            return true;
136712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        }
136812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
136912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        int32_t sampleRate_from, sampleRate_to;
137012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(from->findInt32(kKeySampleRate, &sampleRate_from));
137112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(to->findInt32(kKeySampleRate, &sampleRate_to));
137212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
137312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        if (sampleRate_from != sampleRate_to) {
137412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber            return true;
137512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        }
137612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    }
137712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
137812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    return false;
137912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber}
138012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
1381693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) {
1382693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (cmd) {
1383693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_CommandStateSet:
1384693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1385693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            onStateChange((OMX_STATETYPE)data);
1386693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1387693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1388693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1389693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_CommandPortDisable:
1390693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1391693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_U32 portIndex = data;
13927a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("PORT_DISABLED(%ld)", portIndex);
1393693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1394693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(mState == EXECUTING || mState == RECONFIGURING);
1395693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mPortStatus[portIndex], DISABLING);
1396693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mPortBuffers[portIndex].size(), 0);
1397693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1398693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mPortStatus[portIndex] = DISABLED;
1399693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1400693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (mState == RECONFIGURING) {
1401693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(portIndex, kPortIndexOutput);
1402693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
140312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber                sp<MetaData> oldOutputFormat = mOutputFormat;
14047f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber                initOutputFormat(mSource->getFormat());
140512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
140612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber                // Don't notify clients if the output port settings change
140712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber                // wasn't of importance to them, i.e. it may be that just the
140812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber                // number of buffers has changed and nothing else.
140912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber                mOutputPortSettingsHaveChanged =
141012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber                    formatHasNotablyChanged(oldOutputFormat, mOutputFormat);
14117f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber
1412693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                enablePortAsync(portIndex);
1413693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1414693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                status_t err = allocateBuffersOnPort(portIndex);
1415693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1416693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1417693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1418693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1419693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1420693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_CommandPortEnable:
1421693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1422693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_U32 portIndex = data;
14237a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("PORT_ENABLED(%ld)", portIndex);
1424693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1425693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(mState == EXECUTING || mState == RECONFIGURING);
1426693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mPortStatus[portIndex], ENABLING);
1427693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1428693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mPortStatus[portIndex] = ENABLED;
1429693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1430693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (mState == RECONFIGURING) {
1431693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(portIndex, kPortIndexOutput);
1432693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1433693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                setState(EXECUTING);
1434693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1435693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                fillOutputBuffers();
1436693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1437693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1438693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1439693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1440693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_CommandFlush:
1441693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1442693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_U32 portIndex = data;
1443693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
14447a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("FLUSH_DONE(%ld)", portIndex);
1445693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1446693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mPortStatus[portIndex], SHUTTING_DOWN);
1447693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mPortStatus[portIndex] = ENABLED;
1448693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1449693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]),
1450693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                     mPortBuffers[portIndex].size());
1451693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1452693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (mState == RECONFIGURING) {
1453693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(portIndex, kPortIndexOutput);
1454693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1455693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                disablePortAsync(portIndex);
14568297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber            } else if (mState == EXECUTING_TO_IDLE) {
14578297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                if (mPortStatus[kPortIndexInput] == ENABLED
14588297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    && mPortStatus[kPortIndexOutput] == ENABLED) {
14597a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                    CODEC_LOGV("Finished flushing both ports, now completing "
14608297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                         "transition from EXECUTING to IDLE.");
14618297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber
14628297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
14638297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
14648297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber
14658297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    status_t err =
1466318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                        mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
14678297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    CHECK_EQ(err, OK);
14688297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                }
1469693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else {
1470693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                // We're flushing both ports in preparation for seeking.
1471693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1472693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                if (mPortStatus[kPortIndexInput] == ENABLED
1473693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    && mPortStatus[kPortIndexOutput] == ENABLED) {
14747a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                    CODEC_LOGV("Finished flushing both ports, now continuing from"
1475693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                         " seek-time.");
1476693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
14775228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber                    // Clear this flag in case the decoder sent us either
14785228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber                    // the EVENT_BUFFER_FLAG(1) or an output buffer with
14795228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber                    // the EOS flag set _while_ flushing. Since we're going
14805228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber                    // to submit "fresh" input data now, this flag no longer
14815228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber                    // applies to our future.
14825228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber                    mNoMoreOutputData = false;
14835228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber
1484693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    drainInputBuffers();
1485693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    fillOutputBuffers();
1486693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                }
1487693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1488693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1489693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1490693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1491693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1492693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
1493693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
14947a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("CMD_COMPLETE(%d, %ld)", cmd, data);
1495693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1496693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1497693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1498693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1499693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1500693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::onStateChange(OMX_STATETYPE newState) {
1501693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (newState) {
1502693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_StateIdle:
1503693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
15047a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("Now Idle.");
1505693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (mState == LOADED_TO_IDLE) {
1506318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                status_t err = mOMX->sendCommand(
1507693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        mNode, OMX_CommandStateSet, OMX_StateExecuting);
1508693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1509693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1510693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1511693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                setState(IDLE_TO_EXECUTING);
1512693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else {
1513693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(mState, EXECUTING_TO_IDLE);
1514693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1515693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(
1516693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
1517693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    mPortBuffers[kPortIndexInput].size());
1518693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1519693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(
1520693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    countBuffersWeOwn(mPortBuffers[kPortIndexOutput]),
1521693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    mPortBuffers[kPortIndexOutput].size());
1522693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1523318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                status_t err = mOMX->sendCommand(
1524693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        mNode, OMX_CommandStateSet, OMX_StateLoaded);
1525693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1526693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1527693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1528693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                err = freeBuffersOnPort(kPortIndexInput);
1529693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1530693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1531693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                err = freeBuffersOnPort(kPortIndexOutput);
1532693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1533693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1534693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mPortStatus[kPortIndexInput] = ENABLED;
1535693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mPortStatus[kPortIndexOutput] = ENABLED;
1536693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1537693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                setState(IDLE_TO_LOADED);
1538693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1539693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1540693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1541693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1542693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_StateExecuting:
1543693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1544693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mState, IDLE_TO_EXECUTING);
1545693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
15467a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("Now Executing.");
1547693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1548693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            setState(EXECUTING);
1549693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1550284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber            // Buffers will be submitted to the component in the first
1551284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber            // call to OMXCodec::read as mInitialBufferSubmit is true at
1552284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber            // this point. This ensures that this on_message call returns,
1553284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber            // releases the lock and ::init can notice the state change and
1554284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber            // itself return.
1555693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1556693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1557693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1558693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_StateLoaded:
1559693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1560693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mState, IDLE_TO_LOADED);
1561693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
15627a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("Now Loaded.");
1563693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1564693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            setState(LOADED);
1565693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1566693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1567693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1568693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
1569693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1570693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(!"should not be here.");
1571693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1572693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1573693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1574693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1575693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1576693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber// static
1577693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t OMXCodec::countBuffersWeOwn(const Vector<BufferInfo> &buffers) {
1578693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t n = 0;
1579693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < buffers.size(); ++i) {
1580693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (!buffers[i].mOwnedByComponent) {
1581693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            ++n;
1582693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1583693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1584693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1585693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return n;
1586693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1587693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1588693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::freeBuffersOnPort(
1589693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_U32 portIndex, bool onlyThoseWeOwn) {
1590693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
1591693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1592693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t stickyErr = OK;
1593693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1594693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = buffers->size(); i-- > 0;) {
1595693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        BufferInfo *info = &buffers->editItemAt(i);
1596693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1597693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (onlyThoseWeOwn && info->mOwnedByComponent) {
1598693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            continue;
1599693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1600693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1601693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(info->mOwnedByComponent, false);
1602693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
160395301196d59fb88ef96342fd307a2be374b5079bAndreas Huber        CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex);
160495301196d59fb88ef96342fd307a2be374b5079bAndreas Huber
1605693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        status_t err =
1606318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mOMX->freeBuffer(mNode, portIndex, info->mBuffer);
1607693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1608693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (err != OK) {
1609693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            stickyErr = err;
1610693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1611693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1612693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (info->mMediaBuffer != NULL) {
1613693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            info->mMediaBuffer->setObserver(NULL);
1614693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1615693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            // Make sure nobody but us owns this buffer at this point.
1616693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(info->mMediaBuffer->refcount(), 0);
1617693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1618693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            info->mMediaBuffer->release();
1619693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1620693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1621693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        buffers->removeAt(i);
1622693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1623693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1624693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(onlyThoseWeOwn || buffers->isEmpty());
1625693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1626693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return stickyErr;
1627693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1628693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1629693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) {
16307a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex);
1631693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1632693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(mState, EXECUTING);
1633693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(portIndex, kPortIndexOutput);
1634693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    setState(RECONFIGURING);
1635693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1636693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mQuirks & kNeedsFlushBeforeDisable) {
16371beb760d920561679862ded945a04e370368c7f7Andreas Huber        if (!flushPortAsync(portIndex)) {
16381beb760d920561679862ded945a04e370368c7f7Andreas Huber            onCmdComplete(OMX_CommandFlush, portIndex);
16391beb760d920561679862ded945a04e370368c7f7Andreas Huber        }
1640693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
1641693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        disablePortAsync(portIndex);
1642693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1643693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1644693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
16451beb760d920561679862ded945a04e370368c7f7Andreas Huberbool OMXCodec::flushPortAsync(OMX_U32 portIndex) {
16468297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber    CHECK(mState == EXECUTING || mState == RECONFIGURING
16478297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber            || mState == EXECUTING_TO_IDLE);
1648693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
16497a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    CODEC_LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.",
16501beb760d920561679862ded945a04e370368c7f7Andreas Huber         portIndex, countBuffersWeOwn(mPortBuffers[portIndex]),
16511beb760d920561679862ded945a04e370368c7f7Andreas Huber         mPortBuffers[portIndex].size());
16521beb760d920561679862ded945a04e370368c7f7Andreas Huber
1653693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(mPortStatus[portIndex], ENABLED);
1654693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mPortStatus[portIndex] = SHUTTING_DOWN;
1655693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
16561beb760d920561679862ded945a04e370368c7f7Andreas Huber    if ((mQuirks & kRequiresFlushCompleteEmulation)
16571beb760d920561679862ded945a04e370368c7f7Andreas Huber        && countBuffersWeOwn(mPortBuffers[portIndex])
16581beb760d920561679862ded945a04e370368c7f7Andreas Huber                == mPortBuffers[portIndex].size()) {
16591beb760d920561679862ded945a04e370368c7f7Andreas Huber        // No flush is necessary and this component fails to send a
16601beb760d920561679862ded945a04e370368c7f7Andreas Huber        // flush-complete event in this case.
16611beb760d920561679862ded945a04e370368c7f7Andreas Huber
16621beb760d920561679862ded945a04e370368c7f7Andreas Huber        return false;
16631beb760d920561679862ded945a04e370368c7f7Andreas Huber    }
16641beb760d920561679862ded945a04e370368c7f7Andreas Huber
1665693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err =
1666318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        mOMX->sendCommand(mNode, OMX_CommandFlush, portIndex);
1667693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
16681beb760d920561679862ded945a04e370368c7f7Andreas Huber
16691beb760d920561679862ded945a04e370368c7f7Andreas Huber    return true;
1670693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1671693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1672693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::disablePortAsync(OMX_U32 portIndex) {
1673693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(mState == EXECUTING || mState == RECONFIGURING);
1674693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1675693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(mPortStatus[portIndex], ENABLED);
1676693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mPortStatus[portIndex] = DISABLING;
1677693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1678693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err =
1679318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        mOMX->sendCommand(mNode, OMX_CommandPortDisable, portIndex);
1680693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
1681693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1682693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    freeBuffersOnPort(portIndex, true);
1683693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1684693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1685693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::enablePortAsync(OMX_U32 portIndex) {
1686693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(mState == EXECUTING || mState == RECONFIGURING);
1687693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1688693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(mPortStatus[portIndex], DISABLED);
1689693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mPortStatus[portIndex] = ENABLING;
1690693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1691693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err =
1692318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex);
1693693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
1694693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1695693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1696693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::fillOutputBuffers() {
1697693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(mState, EXECUTING);
1698693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1699693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
1700693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
1701693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        fillOutputBuffer(&buffers->editItemAt(i));
1702693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1703693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1704693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1705693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::drainInputBuffers() {
1706450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber    CHECK(mState == EXECUTING || mState == RECONFIGURING);
1707693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1708693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
1709693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
1710693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        drainInputBuffer(&buffers->editItemAt(i));
1711693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1712693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1713693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1714693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::drainInputBuffer(BufferInfo *info) {
1715693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(info->mOwnedByComponent, false);
1716693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1717693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mSignalledEOS) {
1718693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return;
1719693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1720693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1721693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mCodecSpecificDataIndex < mCodecSpecificData.size()) {
1722693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const CodecSpecificData *specific =
1723693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mCodecSpecificData[mCodecSpecificDataIndex];
1724693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1725693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        size_t size = specific->mSize;
1726693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
172718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME)
1728dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber                && !(mQuirks & kWantsNALFragments)) {
1729693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            static const uint8_t kNALStartCode[4] =
1730693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    { 0x00, 0x00, 0x00, 0x01 };
1731693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1732693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(info->mMem->size() >= specific->mSize + 4);
1733693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1734693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            size += 4;
1735693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1736693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            memcpy(info->mMem->pointer(), kNALStartCode, 4);
1737693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            memcpy((uint8_t *)info->mMem->pointer() + 4,
1738693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                   specific->mData, specific->mSize);
1739693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        } else {
1740693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(info->mMem->size() >= specific->mSize);
1741693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            memcpy(info->mMem->pointer(), specific->mData, specific->mSize);
1742693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1743693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1744318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        status_t err = mOMX->emptyBuffer(
1745693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mNode, info->mBuffer, 0, size,
1746693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG,
1747693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                0);
174836efa039efaae4526791336cb688032d22b34becAndreas Huber        CHECK_EQ(err, OK);
1749693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1750693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        info->mOwnedByComponent = true;
1751693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1752693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        ++mCodecSpecificDataIndex;
1753693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return;
1754693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1755693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1756693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    MediaBuffer *srcBuffer;
1757693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err;
1758693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mSeekTimeUs >= 0) {
1759693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        MediaSource::ReadOptions options;
1760693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        options.setSeekTo(mSeekTimeUs);
1761693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mSeekTimeUs = -1;
1762693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1763693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        err = mSource->read(&srcBuffer, &options);
1764693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
1765693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        err = mSource->read(&srcBuffer);
1766693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1767693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1768693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
176948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber    OMX_TICKS timestampUs = 0;
1770693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t srcLength = 0;
1771693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1772693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (err != OK) {
17737a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        CODEC_LOGV("signalling end of input stream.");
1774693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        flags |= OMX_BUFFERFLAG_EOS;
1775693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1776693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mSignalledEOS = true;
1777693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
1778693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        srcLength = srcBuffer->range_length();
1779693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1780693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (info->mMem->size() < srcLength) {
1781693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            LOGE("info->mMem->size() = %d, srcLength = %d",
1782693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 info->mMem->size(), srcLength);
1783693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1784693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(info->mMem->size() >= srcLength);
1785693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        memcpy(info->mMem->pointer(),
1786693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber               (const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(),
1787693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber               srcLength);
1788693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
178948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber        if (srcBuffer->meta_data()->findInt64(kKeyTime, &timestampUs)) {
1790318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d)",
1791693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 info->mBuffer, srcLength);
1792318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            CODEC_LOGV("Calling emptyBuffer with timestamp %lld us (%.2f secs)",
179348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber                 timestampUs, timestampUs / 1E6);
1794693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1795693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1796693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1797693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (srcBuffer != NULL) {
1798693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        srcBuffer->release();
1799693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        srcBuffer = NULL;
1800693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
180136efa039efaae4526791336cb688032d22b34becAndreas Huber
1802318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->emptyBuffer(
180336efa039efaae4526791336cb688032d22b34becAndreas Huber            mNode, info->mBuffer, 0, srcLength,
180448c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber            flags, timestampUs);
180536efa039efaae4526791336cb688032d22b34becAndreas Huber
180636efa039efaae4526791336cb688032d22b34becAndreas Huber    if (err != OK) {
180736efa039efaae4526791336cb688032d22b34becAndreas Huber        setState(ERROR);
180836efa039efaae4526791336cb688032d22b34becAndreas Huber        return;
180936efa039efaae4526791336cb688032d22b34becAndreas Huber    }
181036efa039efaae4526791336cb688032d22b34becAndreas Huber
181136efa039efaae4526791336cb688032d22b34becAndreas Huber    info->mOwnedByComponent = true;
181230ab66297501757d745b9ae10da61adcd891f497Andreas Huber
181330ab66297501757d745b9ae10da61adcd891f497Andreas Huber    // This component does not ever signal the EOS flag on output buffers,
181430ab66297501757d745b9ae10da61adcd891f497Andreas Huber    // Thanks for nothing.
181530ab66297501757d745b9ae10da61adcd891f497Andreas Huber    if (mSignalledEOS && !strcmp(mComponentName, "OMX.TI.Video.encoder")) {
181630ab66297501757d745b9ae10da61adcd891f497Andreas Huber        mNoMoreOutputData = true;
181730ab66297501757d745b9ae10da61adcd891f497Andreas Huber        mBufferFilled.signal();
181830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    }
1819693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1820693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1821693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::fillOutputBuffer(BufferInfo *info) {
1822693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(info->mOwnedByComponent, false);
1823693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
18241beb760d920561679862ded945a04e370368c7f7Andreas Huber    if (mNoMoreOutputData) {
18257a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        CODEC_LOGV("There is no more output data available, not "
18261beb760d920561679862ded945a04e370368c7f7Andreas Huber             "calling fillOutputBuffer");
18271beb760d920561679862ded945a04e370368c7f7Andreas Huber        return;
18281beb760d920561679862ded945a04e370368c7f7Andreas Huber    }
18291beb760d920561679862ded945a04e370368c7f7Andreas Huber
18307a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    CODEC_LOGV("Calling fill_buffer on buffer %p", info->mBuffer);
1831318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->fillBuffer(mNode, info->mBuffer);
183236efa039efaae4526791336cb688032d22b34becAndreas Huber    CHECK_EQ(err, OK);
1833693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1834693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    info->mOwnedByComponent = true;
1835693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1836693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1837693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::drainInputBuffer(IOMX::buffer_id buffer) {
1838693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
1839693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
1840693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if ((*buffers)[i].mBuffer == buffer) {
1841693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            drainInputBuffer(&buffers->editItemAt(i));
1842693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            return;
1843693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1844693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1845693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1846693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(!"should not be here.");
1847693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1848693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1849693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::fillOutputBuffer(IOMX::buffer_id buffer) {
1850693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
1851693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
1852693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if ((*buffers)[i].mBuffer == buffer) {
1853693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            fillOutputBuffer(&buffers->editItemAt(i));
1854693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            return;
1855693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1856693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1857693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1858693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(!"should not be here.");
1859693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1860693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1861693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::setState(State newState) {
1862693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mState = newState;
1863693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mAsyncCompletion.signal();
1864693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1865693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    // This may cause some spurious wakeups but is necessary to
1866693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    // unblock the reader if we enter ERROR state.
1867693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mBufferFilled.signal();
1868693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1869693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1870e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Hubervoid OMXCodec::setRawAudioFormat(
1871e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1872e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
18737a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&pcmParams);
1874e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.nPortIndex = portIndex;
1875e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
1876318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
1877e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1878e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
1879e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    CHECK_EQ(err, OK);
1880e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
1881e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.nChannels = numChannels;
1882e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1883e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1884e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.nBitPerSample = 16;
1885e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.nSamplingRate = sampleRate;
1886e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1887e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
1888e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    if (numChannels == 1) {
1889e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelCF;
1890e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    } else {
1891e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        CHECK_EQ(numChannels, 2);
1892e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
1893e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
1894e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        pcmParams.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
1895e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
1896e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
1897318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
1898e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1899e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
1900e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    CHECK_EQ(err, OK);
1901e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber}
1902e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
1903c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Hubervoid OMXCodec::setAMRFormat(bool isWAMR) {
1904c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    OMX_U32 portIndex = mIsEncoder ? kPortIndexOutput : kPortIndexInput;
1905693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1906c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1907c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    InitOMXParams(&def);
1908c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    def.nPortIndex = portIndex;
1909456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber
1910c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    status_t err =
1911c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1912456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber
1913c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    CHECK_EQ(err, OK);
1914456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber
1915c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
1916c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    def.eAMRBandMode =
1917c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber        isWAMR ? OMX_AUDIO_AMRBandModeWB0 : OMX_AUDIO_AMRBandModeNB0;
1918456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber
1919c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1920c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    CHECK_EQ(err, OK);
1921456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber
1922456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber    ////////////////////////
1923456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber
1924456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber    if (mIsEncoder) {
1925456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber        sp<MetaData> format = mSource->getFormat();
1926456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber        int32_t sampleRate;
1927456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber        int32_t numChannels;
1928456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber        CHECK(format->findInt32(kKeySampleRate, &sampleRate));
1929693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(format->findInt32(kKeyChannelCount, &numChannels));
1930693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1931e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1932e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
1933e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber}
1934693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1935e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Hubervoid OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate) {
1936e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    if (mIsEncoder) {
1937e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1938e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    } else {
1939e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
19407a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        InitOMXParams(&profile);
1941e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        profile.nPortIndex = kPortIndexInput;
1942693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1943318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        status_t err = mOMX->getParameter(
1944e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1945693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(err, OK);
1946693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1947e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        profile.nChannels = numChannels;
1948e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        profile.nSampleRate = sampleRate;
1949e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
1950693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1951318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        err = mOMX->setParameter(
1952e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1953693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(err, OK);
1954693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1955693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1956693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1957693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::setImageOutputFormat(
1958693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) {
19597a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height);
1960693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1961693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#if 0
1962693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_INDEXTYPE index;
1963693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err = mOMX->get_extension_index(
1964693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index);
1965693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
1966693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1967693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    err = mOMX->set_config(mNode, index, &format, sizeof(format));
1968693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
1969693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#endif
1970693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1971693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
19727a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
1973693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexOutput;
1974693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1975318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
1976693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1977693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
1978693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1979693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(def.eDomain, OMX_PortDomainImage);
1980693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1981693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
1982bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
1983693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused);
1984693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    imageDef->eColorFormat = format;
1985693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    imageDef->nFrameWidth = width;
1986693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    imageDef->nFrameHeight = height;
1987693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1988693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (format) {
1989693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_COLOR_FormatYUV420PackedPlanar:
1990693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_COLOR_FormatYUV411Planar:
1991693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1992693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            def.nBufferSize = (width * height * 3) / 2;
1993693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1994693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1995693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1996693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_COLOR_FormatCbYCrY:
1997693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1998693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            def.nBufferSize = width * height * 2;
1999693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2000693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2001693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2002693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_COLOR_Format32bitARGB8888:
2003693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2004693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            def.nBufferSize = width * height * 4;
2005693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2006693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2007693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2008195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber        case OMX_COLOR_Format16bitARGB4444:
2009195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber        case OMX_COLOR_Format16bitARGB1555:
2010195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber        case OMX_COLOR_Format16bitRGB565:
2011195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber        case OMX_COLOR_Format16bitBGR565:
2012195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber        {
2013195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber            def.nBufferSize = width * height * 2;
2014195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber            break;
2015195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber        }
2016195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber
2017693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
2018693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(!"Should not be here. Unknown color format.");
2019693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2020693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2021693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
20227530e9c708275c273c134c36c68179f511c1940eAndreas Huber    def.nBufferCountActual = def.nBufferCountMin;
20237530e9c708275c273c134c36c68179f511c1940eAndreas Huber
2024318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
2025693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2026693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
20277530e9c708275c273c134c36c68179f511c1940eAndreas Huber}
2028693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
20297530e9c708275c273c134c36c68179f511c1940eAndreas Hubervoid OMXCodec::setJPEGInputFormat(
20307530e9c708275c273c134c36c68179f511c1940eAndreas Huber        OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) {
20317530e9c708275c273c134c36c68179f511c1940eAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
20327a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
2033693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexInput;
2034693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2035318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
2036693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2037693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
2038693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
20397530e9c708275c273c134c36c68179f511c1940eAndreas Huber    CHECK_EQ(def.eDomain, OMX_PortDomainImage);
20407530e9c708275c273c134c36c68179f511c1940eAndreas Huber    OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
20417530e9c708275c273c134c36c68179f511c1940eAndreas Huber
2042693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingJPEG);
2043693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    imageDef->nFrameWidth = width;
2044693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    imageDef->nFrameHeight = height;
2045693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
20467530e9c708275c273c134c36c68179f511c1940eAndreas Huber    def.nBufferSize = compressedSize;
2047693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nBufferCountActual = def.nBufferCountMin;
2048693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2049318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
2050693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2051693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
2052693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2053693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2054693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::addCodecSpecificData(const void *data, size_t size) {
2055693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CodecSpecificData *specific =
2056693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1);
2057693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2058693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    specific->mSize = size;
2059693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    memcpy(specific->mData, data, size);
2060693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2061693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mCodecSpecificData.push(specific);
2062693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2063693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2064693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::clearCodecSpecificData() {
2065693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < mCodecSpecificData.size(); ++i) {
2066693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        free(mCodecSpecificData.editItemAt(i));
2067693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2068693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mCodecSpecificData.clear();
2069693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mCodecSpecificDataIndex = 0;
2070693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2071693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2072693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::start(MetaData *) {
2073284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber    Mutex::Autolock autoLock(mLock);
2074284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber
2075693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mState != LOADED) {
2076693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return UNKNOWN_ERROR;
2077693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2078bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
2079693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    sp<MetaData> params = new MetaData;
2080dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    if (mQuirks & kWantsNALFragments) {
2081dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        params->setInt32(kKeyWantsNALFragments, true);
2082693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2083693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err = mSource->start(params.get());
2084693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2085693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (err != OK) {
2086693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return err;
2087693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2088693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2089693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mCodecSpecificDataIndex = 0;
2090284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber    mInitialBufferSubmit = true;
2091693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mSignalledEOS = false;
2092693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mNoMoreOutputData = false;
20937f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber    mOutputPortSettingsHaveChanged = false;
2094693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mSeekTimeUs = -1;
2095693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mFilledBuffers.clear();
2096693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2097693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return init();
2098693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2099693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2100693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::stop() {
21017a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    CODEC_LOGV("stop");
2102693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2103693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Mutex::Autolock autoLock(mLock);
2104693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2105693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    while (isIntermediateState(mState)) {
2106693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mAsyncCompletion.wait(mLock);
2107693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2108693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2109693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (mState) {
2110693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case LOADED:
2111693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case ERROR:
2112693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2113693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2114693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case EXECUTING:
2115693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2116693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            setState(EXECUTING_TO_IDLE);
2117693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
21188297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber            if (mQuirks & kRequiresFlushBeforeShutdown) {
21197a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                CODEC_LOGV("This component requires a flush before transitioning "
21208297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                     "from EXECUTING to IDLE...");
21218297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber
21228297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                bool emulateInputFlushCompletion =
21238297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    !flushPortAsync(kPortIndexInput);
21248297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber
21258297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                bool emulateOutputFlushCompletion =
21268297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    !flushPortAsync(kPortIndexOutput);
2127693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
21288297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                if (emulateInputFlushCompletion) {
21298297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    onCmdComplete(OMX_CommandFlush, kPortIndexInput);
21308297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                }
21318297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber
21328297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                if (emulateOutputFlushCompletion) {
21338297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
21348297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                }
21358297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber            } else {
21368297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
21378297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
21388297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber
21398297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                status_t err =
2140318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                    mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
21418297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                CHECK_EQ(err, OK);
21428297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber            }
2143693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2144693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            while (mState != LOADED && mState != ERROR) {
2145693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mAsyncCompletion.wait(mLock);
2146693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
2147693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2148693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2149693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2150693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2151693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
2152693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2153693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(!"should not be here.");
2154693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2155693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2156693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2157693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2158693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mSource->stop();
2159693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2160693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return OK;
2161693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2162693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2163693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MetaData> OMXCodec::getFormat() {
21647f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber    Mutex::Autolock autoLock(mLock);
21657f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber
2166693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return mOutputFormat;
2167693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2168693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2169693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::read(
2170693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        MediaBuffer **buffer, const ReadOptions *options) {
2171693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    *buffer = NULL;
2172693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2173693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Mutex::Autolock autoLock(mLock);
2174693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2175450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber    if (mState != EXECUTING && mState != RECONFIGURING) {
2176450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber        return UNKNOWN_ERROR;
2177450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber    }
2178450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber
21797e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    bool seeking = false;
21807e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    int64_t seekTimeUs;
21817e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if (options && options->getSeekTo(&seekTimeUs)) {
21827e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        seeking = true;
21837e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
21847e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
2185284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber    if (mInitialBufferSubmit) {
2186284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber        mInitialBufferSubmit = false;
2187284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber
21887e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        if (seeking) {
21897e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            CHECK(seekTimeUs >= 0);
21907e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            mSeekTimeUs = seekTimeUs;
21917e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
21927e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            // There's no reason to trigger the code below, there's
21937e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            // nothing to flush yet.
21947e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            seeking = false;
21957e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        }
21967e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
2197284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber        drainInputBuffers();
2198284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber
2199450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber        if (mState == EXECUTING) {
2200450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber            // Otherwise mState == RECONFIGURING and this code will trigger
2201450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber            // after the output port is reenabled.
2202450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber            fillOutputBuffers();
2203450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber        }
2204693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2205693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
22067e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if (seeking) {
22077a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6);
2208693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2209693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mSignalledEOS = false;
2210693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mNoMoreOutputData = false;
2211693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2212693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(seekTimeUs >= 0);
2213693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mSeekTimeUs = seekTimeUs;
2214693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2215693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mFilledBuffers.clear();
2216693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2217693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(mState, EXECUTING);
2218693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
22191beb760d920561679862ded945a04e370368c7f7Andreas Huber        bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput);
22201beb760d920561679862ded945a04e370368c7f7Andreas Huber        bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput);
22211beb760d920561679862ded945a04e370368c7f7Andreas Huber
22221beb760d920561679862ded945a04e370368c7f7Andreas Huber        if (emulateInputFlushCompletion) {
22231beb760d920561679862ded945a04e370368c7f7Andreas Huber            onCmdComplete(OMX_CommandFlush, kPortIndexInput);
22241beb760d920561679862ded945a04e370368c7f7Andreas Huber        }
22251beb760d920561679862ded945a04e370368c7f7Andreas Huber
22261beb760d920561679862ded945a04e370368c7f7Andreas Huber        if (emulateOutputFlushCompletion) {
22271beb760d920561679862ded945a04e370368c7f7Andreas Huber            onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
22281beb760d920561679862ded945a04e370368c7f7Andreas Huber        }
2229693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2230693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2231693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) {
2232693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mBufferFilled.wait(mLock);
2233693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2234693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2235693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mState == ERROR) {
2236693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return UNKNOWN_ERROR;
2237693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2238693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2239693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mFilledBuffers.empty()) {
2240693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return ERROR_END_OF_STREAM;
2241693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2242693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
22437f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber    if (mOutputPortSettingsHaveChanged) {
22447f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber        mOutputPortSettingsHaveChanged = false;
22457f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber
22467f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber        return INFO_FORMAT_CHANGED;
22477f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber    }
22487f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber
2249693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t index = *mFilledBuffers.begin();
2250693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mFilledBuffers.erase(mFilledBuffers.begin());
2251693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2252693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
2253693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    info->mMediaBuffer->add_ref();
2254693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    *buffer = info->mMediaBuffer;
2255693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2256693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return OK;
2257693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2258693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2259693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::signalBufferReturned(MediaBuffer *buffer) {
2260693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Mutex::Autolock autoLock(mLock);
2261693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2262693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
2263693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
2264693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        BufferInfo *info = &buffers->editItemAt(i);
2265693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2266693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (info->mMediaBuffer == buffer) {
2267693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED);
2268693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            fillOutputBuffer(info);
2269693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            return;
2270693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2271693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2272693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2273693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(!"should not be here.");
2274693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2275693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2276693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) {
2277693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    static const char *kNames[] = {
2278693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingUnused",
2279693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingAutoDetect",
2280693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingJPEG",
2281693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingJPEG2K",
2282693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingEXIF",
2283693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingTIFF",
2284693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingGIF",
2285693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingPNG",
2286693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingLZW",
2287693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingBMP",
2288693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    };
2289693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2290693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2291693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2292693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (type < 0 || (size_t)type >= numNames) {
2293693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return "UNKNOWN";
2294693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
2295693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return kNames[type];
2296693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2297693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2298693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2299693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const char *colorFormatString(OMX_COLOR_FORMATTYPE type) {
2300693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    static const char *kNames[] = {
2301693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatUnused",
2302693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatMonochrome",
2303693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format8bitRGB332",
2304693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format12bitRGB444",
2305693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format16bitARGB4444",
2306693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format16bitARGB1555",
2307693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format16bitRGB565",
2308693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format16bitBGR565",
2309693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format18bitRGB666",
2310693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format18bitARGB1665",
2311bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        "OMX_COLOR_Format19bitARGB1666",
2312693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format24bitRGB888",
2313693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format24bitBGR888",
2314693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format24bitARGB1887",
2315693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format25bitARGB1888",
2316693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format32bitBGRA8888",
2317693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format32bitARGB8888",
2318693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV411Planar",
2319693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV411PackedPlanar",
2320693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV420Planar",
2321693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV420PackedPlanar",
2322693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV420SemiPlanar",
2323693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV422Planar",
2324693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV422PackedPlanar",
2325693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV422SemiPlanar",
2326693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYCbYCr",
2327693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYCrYCb",
2328693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatCbYCrY",
2329693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatCrYCbY",
2330693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV444Interleaved",
2331693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatRawBayer8bit",
2332693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatRawBayer10bit",
2333693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatRawBayer8bitcompressed",
2334bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        "OMX_COLOR_FormatL2",
2335bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        "OMX_COLOR_FormatL4",
2336bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        "OMX_COLOR_FormatL8",
2337bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        "OMX_COLOR_FormatL16",
2338bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        "OMX_COLOR_FormatL24",
2339693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatL32",
2340693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV420PackedSemiPlanar",
2341693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV422PackedSemiPlanar",
2342693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format18BitBGR666",
2343693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format24BitARGB6666",
2344693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format24BitABGR6666",
2345693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    };
2346693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2347693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2348693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2349693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) {
2350693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar";
2351693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else if (type < 0 || (size_t)type >= numNames) {
2352693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return "UNKNOWN";
2353693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
2354693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return kNames[type];
2355693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2356693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2357693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2358693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) {
2359693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    static const char *kNames[] = {
2360693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingUnused",
2361693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingAutoDetect",
2362693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingMPEG2",
2363693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingH263",
2364693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingMPEG4",
2365693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingWMV",
2366693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingRV",
2367693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingAVC",
2368693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingMJPEG",
2369693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    };
2370693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2371693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2372693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2373693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (type < 0 || (size_t)type >= numNames) {
2374693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return "UNKNOWN";
2375693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
2376693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return kNames[type];
2377693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2378693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2379693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2380693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) {
2381693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    static const char *kNames[] = {
2382693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingUnused",
2383693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingAutoDetect",
2384693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingPCM",
2385693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingADPCM",
2386693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingAMR",
2387693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingGSMFR",
2388693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingGSMEFR",
2389693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingGSMHR",
2390693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingPDCFR",
2391693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingPDCEFR",
2392693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingPDCHR",
2393693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingTDMAFR",
2394693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingTDMAEFR",
2395693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingQCELP8",
2396693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingQCELP13",
2397693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingEVRC",
2398693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingSMV",
2399693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingG711",
2400693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingG723",
2401693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingG726",
2402693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingG729",
2403693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingAAC",
2404693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingMP3",
2405693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingSBC",
2406693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingVORBIS",
2407693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingWMA",
2408693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingRA",
2409693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingMIDI",
2410693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    };
2411693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2412693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2413693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2414693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (type < 0 || (size_t)type >= numNames) {
2415693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return "UNKNOWN";
2416693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
2417693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return kNames[type];
2418693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2419693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2420693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2421693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) {
2422693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    static const char *kNames[] = {
2423693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_PCMModeLinear",
2424693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_PCMModeALaw",
2425693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_PCMModeMULaw",
2426693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    };
2427693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2428693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2429693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2430693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (type < 0 || (size_t)type >= numNames) {
2431693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return "UNKNOWN";
2432693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
2433693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return kNames[type];
2434693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2435693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2436693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
24372f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huberstatic const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) {
24382f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    static const char *kNames[] = {
24392f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeUnused",
24402f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB0",
24412f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB1",
24422f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB2",
24432f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB3",
24442f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB4",
24452f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB5",
24462f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB6",
24472f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB7",
24482f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB0",
24492f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB1",
24502f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB2",
24512f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB3",
24522f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB4",
24532f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB5",
24542f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB6",
24552f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB7",
24562f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB8",
24572f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    };
24582f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
24592f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
24602f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
24612f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    if (type < 0 || (size_t)type >= numNames) {
24622f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        return "UNKNOWN";
24632f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    } else {
24642f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        return kNames[type];
24652f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    }
24662f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber}
24672f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
24682f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huberstatic const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) {
24692f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    static const char *kNames[] = {
24702f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRFrameFormatConformance",
24712f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRFrameFormatIF1",
24722f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRFrameFormatIF2",
24732f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRFrameFormatFSF",
24742f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRFrameFormatRTPPayload",
24752f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRFrameFormatITU",
24762f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    };
24772f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
24782f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
24792f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
24802f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    if (type < 0 || (size_t)type >= numNames) {
24812f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        return "UNKNOWN";
24822f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    } else {
24832f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        return kNames[type];
24842f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    }
24852f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber}
2486693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2487693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
2488693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
24897a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
2490693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = portIndex;
2491693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2492318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
2493693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2494693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
2495693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2496693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output");
2497693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2498693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput)
2499693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber          || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput));
2500693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2501693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    printf("  nBufferCountActual = %ld\n", def.nBufferCountActual);
2502693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    printf("  nBufferCountMin = %ld\n", def.nBufferCountMin);
2503693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    printf("  nBufferSize = %ld\n", def.nBufferSize);
2504693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2505693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (def.eDomain) {
2506693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_PortDomainImage:
2507693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2508693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
2509693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2510693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("\n");
2511693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  // Image\n");
2512693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  nFrameWidth = %ld\n", imageDef->nFrameWidth);
2513693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  nFrameHeight = %ld\n", imageDef->nFrameHeight);
2514693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  nStride = %ld\n", imageDef->nStride);
2515693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2516693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  eCompressionFormat = %s\n",
2517693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                   imageCompressionFormatString(imageDef->eCompressionFormat));
2518693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2519693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  eColorFormat = %s\n",
2520693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                   colorFormatString(imageDef->eColorFormat));
2521693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2522693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2523693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2524693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2525693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_PortDomainVideo:
2526693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2527693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
2528693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2529693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("\n");
2530693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  // Video\n");
2531693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  nFrameWidth = %ld\n", videoDef->nFrameWidth);
2532693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  nFrameHeight = %ld\n", videoDef->nFrameHeight);
2533693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  nStride = %ld\n", videoDef->nStride);
2534693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2535693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  eCompressionFormat = %s\n",
2536693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                   videoCompressionFormatString(videoDef->eCompressionFormat));
2537693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2538693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  eColorFormat = %s\n",
2539693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                   colorFormatString(videoDef->eColorFormat));
2540693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2541693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2542693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2543693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2544693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_PortDomainAudio:
2545693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2546693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
2547693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2548693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("\n");
2549693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  // Audio\n");
2550693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  eEncoding = %s\n",
2551693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                   audioCodingTypeString(audioDef->eEncoding));
2552693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2553693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) {
2554693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                OMX_AUDIO_PARAM_PCMMODETYPE params;
25557a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                InitOMXParams(&params);
2556693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                params.nPortIndex = portIndex;
2557693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2558318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                err = mOMX->getParameter(
2559693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
2560693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
2561693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2562693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                printf("  nSamplingRate = %ld\n", params.nSamplingRate);
2563693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                printf("  nChannels = %ld\n", params.nChannels);
2564693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                printf("  bInterleaved = %d\n", params.bInterleaved);
2565693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                printf("  nBitPerSample = %ld\n", params.nBitPerSample);
2566693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2567693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                printf("  eNumData = %s\n",
2568693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                       params.eNumData == OMX_NumericalDataSigned
2569693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        ? "signed" : "unsigned");
2570693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2571693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                printf("  ePCMMode = %s\n", audioPCMModeString(params.ePCMMode));
25722f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber            } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) {
25732f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                OMX_AUDIO_PARAM_AMRTYPE amr;
25742f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                InitOMXParams(&amr);
25752f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                amr.nPortIndex = portIndex;
25762f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
2577318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                err = mOMX->getParameter(
25782f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                        mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
25792f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                CHECK_EQ(err, OK);
25802f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
25812f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                printf("  nChannels = %ld\n", amr.nChannels);
25822f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                printf("  eAMRBandMode = %s\n",
25832f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                        amrBandModeString(amr.eAMRBandMode));
25842f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                printf("  eAMRFrameFormat = %s\n",
25852f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                        amrFrameFormatString(amr.eAMRFrameFormat));
2586693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
2587693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2588693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2589693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2590693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2591693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
2592693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2593693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  // Unknown\n");
2594693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2595693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2596693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2597693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2598693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    printf("}\n");
2599693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2600693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2601693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
2602693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mOutputFormat = new MetaData;
2603693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mOutputFormat->setCString(kKeyDecoderComponent, mComponentName);
2604693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2605693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
26067a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
2607693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexOutput;
2608693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2609318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
2610693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2611693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
2612693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2613693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (def.eDomain) {
2614693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_PortDomainImage:
2615693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2616693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
2617693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused);
2618693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
261918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
2620693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat);
2621693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth);
2622693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight);
2623693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2624693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2625693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2626693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_PortDomainAudio:
2627693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2628693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio;
2629693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2630e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) {
2631e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                OMX_AUDIO_PARAM_PCMMODETYPE params;
26327a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                InitOMXParams(&params);
2633e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                params.nPortIndex = kPortIndexOutput;
2634693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2635318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                err = mOMX->getParameter(
2636e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                        mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
2637e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                CHECK_EQ(err, OK);
2638693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2639e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                CHECK_EQ(params.eNumData, OMX_NumericalDataSigned);
2640e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                CHECK_EQ(params.nBitPerSample, 16);
2641e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                CHECK_EQ(params.ePCMMode, OMX_AUDIO_PCMModeLinear);
2642693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2643e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                int32_t numChannels, sampleRate;
2644e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                inputFormat->findInt32(kKeyChannelCount, &numChannels);
2645e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                inputFormat->findInt32(kKeySampleRate, &sampleRate);
2646693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2647e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                if ((OMX_U32)numChannels != params.nChannels) {
2648e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                    LOGW("Codec outputs a different number of channels than "
2649e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                         "the input stream contains.");
2650e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                }
265137940eefcba982836b579fe1ffec6cada72b0974Andreas Huber
265218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                mOutputFormat->setCString(
265318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
265437940eefcba982836b579fe1ffec6cada72b0974Andreas Huber
2655e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                // Use the codec-advertised number of channels, as some
2656e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                // codecs appear to output stereo even if the input data is
2657e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                // mono.
2658e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                mOutputFormat->setInt32(kKeyChannelCount, params.nChannels);
265937940eefcba982836b579fe1ffec6cada72b0974Andreas Huber
2660e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                // The codec-reported sampleRate is not reliable...
2661e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                mOutputFormat->setInt32(kKeySampleRate, sampleRate);
2662e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) {
26632f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                OMX_AUDIO_PARAM_AMRTYPE amr;
26642f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                InitOMXParams(&amr);
26652f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                amr.nPortIndex = kPortIndexOutput;
26662f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
2667318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                err = mOMX->getParameter(
26682f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                        mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
26692f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                CHECK_EQ(err, OK);
26702f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
26712f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                CHECK_EQ(amr.nChannels, 1);
26722f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                mOutputFormat->setInt32(kKeyChannelCount, 1);
26732f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
26742f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0
26752f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                    && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) {
267618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    mOutputFormat->setCString(
267718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                            kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB);
26782f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                    mOutputFormat->setInt32(kKeySampleRate, 8000);
26792f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0
26802f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                            && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) {
268118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    mOutputFormat->setCString(
268218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                            kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB);
26832f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                    mOutputFormat->setInt32(kKeySampleRate, 16000);
26842f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                } else {
26852f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                    CHECK(!"Unknown AMR band mode.");
26862f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                }
2687e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) {
268818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                mOutputFormat->setCString(
268918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
2690e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            } else {
2691e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                CHECK(!"Should not be here. Unknown audio encoding.");
2692e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            }
2693693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2694693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2695693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2696693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_PortDomainVideo:
2697693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2698693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2699693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2700693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) {
270118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                mOutputFormat->setCString(
270218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
2703693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) {
270418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                mOutputFormat->setCString(
270518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
2706693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) {
270718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                mOutputFormat->setCString(
270818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
2709693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) {
271018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                mOutputFormat->setCString(
271118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
2712693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else {
2713693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK(!"Unknown compression format.");
2714693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
2715693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2716693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (!strcmp(mComponentName, "OMX.PV.avcdec")) {
2717693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                // This component appears to be lying to me.
2718693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mOutputFormat->setInt32(
2719693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        kKeyWidth, (video_def->nFrameWidth + 15) & -16);
2720693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mOutputFormat->setInt32(
2721693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        kKeyHeight, (video_def->nFrameHeight + 15) & -16);
2722693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else {
2723693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth);
2724693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight);
2725693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
2726693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2727693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat);
2728693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2729693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2730693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2731693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
2732693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2733693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(!"should not be here, neither audio nor video.");
2734693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2735693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2736693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2737693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2738693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
273918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber////////////////////////////////////////////////////////////////////////////////
274018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
274118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatus_t QueryCodecs(
274218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        const sp<IOMX> &omx,
274318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        const char *mime, bool queryDecoders,
274418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        Vector<CodecCapabilities> *results) {
274518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    results->clear();
274618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
274718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    for (int index = 0;; ++index) {
274818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        const char *componentName;
274918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
275018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        if (!queryDecoders) {
275118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            componentName = GetCodec(
275218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    kEncoderInfo, sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]),
275318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    mime, index);
275418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        } else {
275518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            componentName = GetCodec(
275618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    kDecoderInfo, sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]),
275718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    mime, index);
275818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        }
275918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
276018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        if (!componentName) {
276118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            return OK;
276218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        }
276318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
2764318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        sp<OMXCodecObserver> observer = new OMXCodecObserver;
276518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        IOMX::node_id node;
2766318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        status_t err = omx->allocateNode(componentName, observer, &node);
276718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
276818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        if (err != OK) {
276918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            continue;
277018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        }
277118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
277218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        OMXCodec::setComponentRole(omx, node, queryDecoders, mime);
277318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
277418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        results->push();
277518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        CodecCapabilities *caps = &results->editItemAt(results->size() - 1);
277618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        caps->mComponentName = componentName;
277718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
277818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
277918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        InitOMXParams(&param);
278018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
278118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        param.nPortIndex = queryDecoders ? 0 : 1;
278218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
278318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
2784318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            err = omx->getParameter(
278518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    node, OMX_IndexParamVideoProfileLevelQuerySupported,
278618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    &param, sizeof(param));
278718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
278818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            if (err != OK) {
278918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                break;
279018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            }
279118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
279218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            CodecProfileLevel profileLevel;
279318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            profileLevel.mProfile = param.eProfile;
279418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            profileLevel.mLevel = param.eLevel;
279518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
279618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            caps->mProfileLevels.push(profileLevel);
279718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        }
279818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
2799318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        CHECK_EQ(omx->freeNode(node), OK);
280018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    }
280118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber}
280218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
2803693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}  // namespace android
2804