OMXCodec.cpp revision 609f1a00c96cf5605f4614e7bb6d0487c98969c5
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
2192616b5655b7aef260480f60f2aabf98e821c8f3Andreas Huber#if BUILD_WITH_FULL_STAGEFRIGHT
22f44de515d3b6098a0b585865c1a0c7b20d3075a6Andreas Huber#include "include/AACDecoder.h"
234f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber#include "include/AMRNBDecoder.h"
244f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber#include "include/AMRWBDecoder.h"
25609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#include "include/AVCDecoder.h"
26d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "include/MP3Decoder.h"
2792616b5655b7aef260480f60f2aabf98e821c8f3Andreas Huber#endif
2892616b5655b7aef260480f60f2aabf98e821c8f3Andreas Huber
2989e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "include/ESDS.h"
3089e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber
31693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <binder/IServiceManager.h>
32693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <binder/MemoryDealer.h>
33693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <binder/ProcessState.h>
34693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/IMediaPlayerService.h>
35693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MediaBuffer.h>
36693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MediaBufferGroup.h>
37693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MediaDebug.h>
3818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h>
39693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MediaExtractor.h>
40693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MetaData.h>
41693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/OMXCodec.h>
42bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber#include <media/stagefright/Utils.h>
43693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <utils/Vector.h>
44693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
45693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <OMX_Audio.h>
46693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <OMX_Component.h>
47693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
48693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubernamespace android {
49693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
50ec430b158df17b2c766f7750a96c35d3902f5f49Andreas Huberstatic const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
51ec430b158df17b2c766f7750a96c35d3902f5f49Andreas Huber
52693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstruct CodecInfo {
53693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    const char *mime;
54693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    const char *codec;
55693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber};
56693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
57693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const CodecInfo kDecoderInfo[] = {
5818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_IMAGE_JPEG, "OMX.TI.JPEG.decode" },
5918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" },
6018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.PV.mp3dec" },
6118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.decode" },
6218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.PV.amrdec" },
6318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.decode" },
6418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.PV.amrdec" },
6518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.decode" },
6618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacdec" },
6718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.decoder.mpeg4" },
6818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.Decoder" },
6918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4dec" },
7018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.decoder.h263" },
7118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.Decoder" },
7218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263dec" },
7318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" },
7418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.Decoder" },
7518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcdec" },
76693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber};
77693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
78693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const CodecInfo kEncoderInfo[] = {
7918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.encode" },
8018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.PV.amrencnb" },
8118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.encode" },
8218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.encode" },
8318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacenc" },
8418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.encoder.mpeg4" },
8518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.encoder" },
8618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4enc" },
8718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.encoder.h263" },
8818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.encoder" },
8918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263enc" },
9018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.encoder" },
9118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcenc" },
92693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber};
93693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
948cd11d23197209e2c2bdb7980bc17e3f1257a118Andreas Huber#define CODEC_LOGI(x, ...) LOGI("[%s] "x, mComponentName, ##__VA_ARGS__)
957a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber#define CODEC_LOGV(x, ...) LOGV("[%s] "x, mComponentName, ##__VA_ARGS__)
967a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
97693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstruct OMXCodecObserver : public BnOMXObserver {
98318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMXCodecObserver() {
99318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
100318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
101318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    void setCodec(const sp<OMXCodec> &target) {
102318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        mTarget = target;
103693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
104693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
105693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    // from IOMXObserver
106318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    virtual void onMessage(const omx_message &msg) {
107693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        sp<OMXCodec> codec = mTarget.promote();
108693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
109693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (codec.get() != NULL) {
110693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            codec->on_message(msg);
111693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
112693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
113693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
114693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected:
115693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    virtual ~OMXCodecObserver() {}
116693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
117693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprivate:
118693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    wp<OMXCodec> mTarget;
119693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
120693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMXCodecObserver(const OMXCodecObserver &);
121693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMXCodecObserver &operator=(const OMXCodecObserver &);
122693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber};
123693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
124693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const char *GetCodec(const CodecInfo *info, size_t numInfos,
125693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                            const char *mime, int index) {
126693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(index >= 0);
127693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for(size_t i = 0; i < numInfos; ++i) {
128693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (!strcasecmp(mime, info[i].mime)) {
129693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (index == 0) {
130693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                return info[i].codec;
131693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
132693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
133693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            --index;
134693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
135693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
136693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
137693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return NULL;
138693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
139693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
140bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huberenum {
141bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileBaseline      = 0x42,
142bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileMain          = 0x4d,
143bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileExtended      = 0x58,
144bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileHigh          = 0x64,
145bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileHigh10        = 0x6e,
146bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileHigh422       = 0x7a,
147bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileHigh444       = 0xf4,
148bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileCAVLC444Intra = 0x2c
149bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber};
150bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
151bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huberstatic const char *AVCProfileToString(uint8_t profile) {
152bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    switch (profile) {
153bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileBaseline:
154bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "Baseline";
155bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileMain:
156bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "Main";
157bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileExtended:
158bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "Extended";
159bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileHigh:
160bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "High";
161bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileHigh10:
162bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "High 10";
163bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileHigh422:
164bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "High 422";
165bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileHigh444:
166bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "High 444";
167bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileCAVLC444Intra:
168bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "CAVLC 444 Intra";
169bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        default:   return "Unknown";
170bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    }
171bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber}
172bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
1737a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Hubertemplate<class T>
1747a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huberstatic void InitOMXParams(T *params) {
1757a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nSize = sizeof(T);
1767a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nVersion.s.nVersionMajor = 1;
1777a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nVersion.s.nVersionMinor = 0;
1787a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nVersion.s.nRevision = 0;
1797a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nVersion.s.nStep = 0;
1807a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber}
1817a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
182ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huberstatic bool IsSoftwareCodec(const char *componentName) {
183ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (!strncmp("OMX.PV.", componentName, 7)) {
184ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        return true;
185ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
186693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
187ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    return false;
188ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber}
189693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
190ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huberstatic int CompareSoftwareCodecsFirst(
191ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const String8 *elem1, const String8 *elem2) {
192ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    bool isSoftwareCodec1 = IsSoftwareCodec(elem1->string());
193ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    bool isSoftwareCodec2 = IsSoftwareCodec(elem2->string());
194693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
195ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (isSoftwareCodec1) {
196ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        if (isSoftwareCodec2) { return 0; }
197ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        return -1;
198ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
199693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
200ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (isSoftwareCodec2) {
201ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        return 1;
202693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
203693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
204ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    return 0;
205ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber}
206ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
207ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber// static
208ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huberuint32_t OMXCodec::getComponentQuirks(const char *componentName) {
209693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    uint32_t quirks = 0;
210ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
211693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!strcmp(componentName, "OMX.PV.avcdec")) {
212dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        quirks |= kWantsNALFragments;
213693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
214693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!strcmp(componentName, "OMX.TI.MP3.decode")) {
215693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        quirks |= kNeedsFlushBeforeDisable;
216693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
217693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!strcmp(componentName, "OMX.TI.AAC.decode")) {
218693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        quirks |= kNeedsFlushBeforeDisable;
2191beb760d920561679862ded945a04e370368c7f7Andreas Huber        quirks |= kRequiresFlushCompleteEmulation;
220693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
221693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!strncmp(componentName, "OMX.qcom.video.encoder.", 23)) {
222693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        quirks |= kRequiresLoadedToIdleAfterAllocation;
223693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        quirks |= kRequiresAllocateBufferOnInputPorts;
224888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        quirks |= kRequiresAllocateBufferOnOutputPorts;
225693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
226b7802d9ee9c9dbb471ae4f010bd67ba1aaa9f264Andreas Huber    if (!strncmp(componentName, "OMX.qcom.video.decoder.", 23)) {
227b7802d9ee9c9dbb471ae4f010bd67ba1aaa9f264Andreas Huber        // XXX Required on P....on only.
228b7802d9ee9c9dbb471ae4f010bd67ba1aaa9f264Andreas Huber        quirks |= kRequiresAllocateBufferOnOutputPorts;
229b7802d9ee9c9dbb471ae4f010bd67ba1aaa9f264Andreas Huber    }
230693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
231df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber    if (!strncmp(componentName, "OMX.TI.", 7)) {
232df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber        // Apparently I must not use OMX_UseBuffer on either input or
233df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber        // output ports on any of the TI components or quote:
234df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber        // "(I) may have unexpected problem (sic) which can be timing related
235df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber        //  and hard to reproduce."
236df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber
237df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber        quirks |= kRequiresAllocateBufferOnInputPorts;
238df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber        quirks |= kRequiresAllocateBufferOnOutputPorts;
239df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber    }
240df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber
241ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    return quirks;
242ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber}
243ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
244ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber// static
245ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Hubervoid OMXCodec::findMatchingCodecs(
246ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const char *mime,
247ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        bool createEncoder, const char *matchComponentName,
248ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        uint32_t flags,
249ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        Vector<String8> *matchingCodecs) {
250ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    matchingCodecs->clear();
251ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
252ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    for (int index = 0;; ++index) {
253ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const char *componentName;
254ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
255ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        if (createEncoder) {
256ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            componentName = GetCodec(
257ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber                    kEncoderInfo,
258ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber                    sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]),
259ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber                    mime, index);
260ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        } else {
261ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            componentName = GetCodec(
262ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber                    kDecoderInfo,
263ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber                    sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]),
264ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber                    mime, index);
265ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        }
266ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
267ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        if (!componentName) {
268ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            break;
269ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        }
270ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
271ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        // If a specific codec is requested, skip the non-matching ones.
272ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        if (matchComponentName && strcmp(componentName, matchComponentName)) {
273ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            continue;
274ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        }
275ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
276ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        matchingCodecs->push(String8(componentName));
277ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
278ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
279ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (flags & kPreferSoftwareCodecs) {
280ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        matchingCodecs->sort(CompareSoftwareCodecsFirst);
281ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
282ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber}
283ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
284ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber// static
285bf697e37550d9e8376089b0b5e498613bede798cAndreas Hubersp<MediaSource> OMXCodec::Create(
286ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const sp<IOMX> &omx,
287ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const sp<MetaData> &meta, bool createEncoder,
288ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const sp<MediaSource> &source,
289ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const char *matchComponentName,
290ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        uint32_t flags) {
291ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    const char *mime;
292ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    bool success = meta->findCString(kKeyMIMEType, &mime);
293ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    CHECK(success);
294ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
29592616b5655b7aef260480f60f2aabf98e821c8f3Andreas Huber#if BUILD_WITH_FULL_STAGEFRIGHT
296f44de515d3b6098a0b585865c1a0c7b20d3075a6Andreas Huber    if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
297f44de515d3b6098a0b585865c1a0c7b20d3075a6Andreas Huber        return new AACDecoder(source);
2984f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
2994f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        return new AMRNBDecoder(source);
3004f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
3014f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        return new AMRWBDecoder(source);
302d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
303d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber        return new MP3Decoder(source);
304609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)
305609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                && (flags & kPreferSoftwareCodecs)) {
306609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        return new AVCDecoder(source);
307f44de515d3b6098a0b585865c1a0c7b20d3075a6Andreas Huber    }
30892616b5655b7aef260480f60f2aabf98e821c8f3Andreas Huber#endif
309f44de515d3b6098a0b585865c1a0c7b20d3075a6Andreas Huber
310ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    Vector<String8> matchingCodecs;
311ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    findMatchingCodecs(
312ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            mime, createEncoder, matchComponentName, flags, &matchingCodecs);
313ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
314ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (matchingCodecs.isEmpty()) {
315ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        return NULL;
316ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
317ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
318ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    sp<OMXCodecObserver> observer = new OMXCodecObserver;
319ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    IOMX::node_id node = 0;
320ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    success = false;
321ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
322ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    const char *componentName;
323ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    for (size_t i = 0; i < matchingCodecs.size(); ++i) {
324ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        componentName = matchingCodecs[i].string();
325ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
326ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        LOGV("Attempting to allocate OMX node '%s'", componentName);
327ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
328ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        status_t err = omx->allocateNode(componentName, observer, &node);
329ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        if (err == OK) {
330ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            LOGV("Successfully allocated OMX node '%s'", componentName);
331ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
332ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            success = true;
333ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            break;
334ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        }
335ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
336ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
337ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (!success) {
338ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        return NULL;
339ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
340ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
341693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    sp<OMXCodec> codec = new OMXCodec(
342ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            omx, node, getComponentQuirks(componentName),
343ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            createEncoder, mime, componentName,
344693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            source);
345693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
346318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    observer->setCodec(codec);
347318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
348693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    uint32_t type;
349693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    const void *data;
350693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t size;
351693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (meta->findData(kKeyESDS, &type, &data, &size)) {
352693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        ESDS esds((const char *)data, size);
353693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(esds.InitCheck(), OK);
354693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
355693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const void *codec_specific_data;
356693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        size_t codec_specific_data_size;
357693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        esds.getCodecSpecificInfo(
358693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                &codec_specific_data, &codec_specific_data_size);
359693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
360693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        printf("found codec-specific data of size %d\n",
361693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber               codec_specific_data_size);
362693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
363693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        codec->addCodecSpecificData(
364693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                codec_specific_data, codec_specific_data_size);
365693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else if (meta->findData(kKeyAVCC, &type, &data, &size)) {
366693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        printf("found avcc of size %d\n", size);
367693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
368bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        // Parse the AVCDecoderConfigurationRecord
369bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
370bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        const uint8_t *ptr = (const uint8_t *)data;
371bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
372bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        CHECK(size >= 7);
373bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        CHECK_EQ(ptr[0], 1);  // configurationVersion == 1
374bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        uint8_t profile = ptr[1];
375bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        uint8_t level = ptr[3];
376bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
377e5d6df402da9b6c5577470abb81a5e6801bd7752Andreas Huber        // There is decodable content out there that fails the following
378e5d6df402da9b6c5577470abb81a5e6801bd7752Andreas Huber        // assertion, let's be lenient for now...
379e5d6df402da9b6c5577470abb81a5e6801bd7752Andreas Huber        // CHECK((ptr[4] >> 2) == 0x3f);  // reserved
380bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
381bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        size_t lengthSize = 1 + (ptr[4] & 3);
382bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
383bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
384bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        // violates it...
385bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        // CHECK((ptr[5] >> 5) == 7);  // reserved
386bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
387bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        size_t numSeqParameterSets = ptr[5] & 31;
388bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
389bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        ptr += 6;
390693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        size -= 6;
391bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
392bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        for (size_t i = 0; i < numSeqParameterSets; ++i) {
393bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            CHECK(size >= 2);
394bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            size_t length = U16_AT(ptr);
395693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
396693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            ptr += 2;
397693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            size -= 2;
398693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
399bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            CHECK(size >= length);
400bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
401bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            codec->addCodecSpecificData(ptr, length);
402bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
403bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            ptr += length;
404bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            size -= length;
405bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        }
406bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
407bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        CHECK(size >= 1);
408bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        size_t numPictureParameterSets = *ptr;
409bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        ++ptr;
410bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        --size;
411bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
412bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        for (size_t i = 0; i < numPictureParameterSets; ++i) {
413bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            CHECK(size >= 2);
414bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            size_t length = U16_AT(ptr);
415bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
416bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            ptr += 2;
417bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            size -= 2;
418693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
419693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(size >= length);
420693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
421693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            codec->addCodecSpecificData(ptr, length);
422693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
423693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            ptr += length;
424693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            size -= length;
425bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        }
426693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
4272a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber        LOGV("AVC profile = %d (%s), level = %d",
428bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber             (int)profile, AVCProfileToString(profile), (int)level / 10);
429693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
430bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        if (!strcmp(componentName, "OMX.TI.Video.Decoder")
431bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            && (profile != kAVCProfileBaseline || level > 39)) {
432318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            // This stream exceeds the decoder's capabilities. The decoder
433318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            // does not handle this gracefully and would clobber the heap
434318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            // and wreak havoc instead...
435bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
436bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            LOGE("Profile and/or level exceed the decoder's capabilities.");
437bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return NULL;
438693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
439693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
440693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
44118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) {
442c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber        codec->setAMRFormat(false /* isWAMR */);
443693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
44418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
445c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber        codec->setAMRFormat(true /* isWAMR */);
446456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber    }
44718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
44837940eefcba982836b579fe1ffec6cada72b0974Andreas Huber        int32_t numChannels, sampleRate;
44937940eefcba982836b579fe1ffec6cada72b0974Andreas Huber        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
45037940eefcba982836b579fe1ffec6cada72b0974Andreas Huber        CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
45137940eefcba982836b579fe1ffec6cada72b0974Andreas Huber
45237940eefcba982836b579fe1ffec6cada72b0974Andreas Huber        codec->setAACFormat(numChannels, sampleRate);
453693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
454693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!strncasecmp(mime, "video/", 6)) {
455693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        int32_t width, height;
456693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        bool success = meta->findInt32(kKeyWidth, &width);
457693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        success = success && meta->findInt32(kKeyHeight, &height);
4587530e9c708275c273c134c36c68179f511c1940eAndreas Huber        CHECK(success);
459693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
460693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (createEncoder) {
461693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            codec->setVideoInputFormat(mime, width, height);
462693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        } else {
463693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            codec->setVideoOutputFormat(mime, width, height);
464693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
465693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
46618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    if (!strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_JPEG)
467693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        && !strcmp(componentName, "OMX.TI.JPEG.decode")) {
468693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_COLOR_FORMATTYPE format =
469693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_COLOR_Format32bitARGB8888;
470693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            // OMX_COLOR_FormatYUV420PackedPlanar;
471693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            // OMX_COLOR_FormatCbYCrY;
472693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            // OMX_COLOR_FormatYUV411Planar;
473693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
474693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        int32_t width, height;
475693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        bool success = meta->findInt32(kKeyWidth, &width);
476693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        success = success && meta->findInt32(kKeyHeight, &height);
4777530e9c708275c273c134c36c68179f511c1940eAndreas Huber
4787530e9c708275c273c134c36c68179f511c1940eAndreas Huber        int32_t compressedSize;
4797530e9c708275c273c134c36c68179f511c1940eAndreas Huber        success = success && meta->findInt32(
480e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                kKeyMaxInputSize, &compressedSize);
4817530e9c708275c273c134c36c68179f511c1940eAndreas Huber
4827530e9c708275c273c134c36c68179f511c1940eAndreas Huber        CHECK(success);
4837530e9c708275c273c134c36c68179f511c1940eAndreas Huber        CHECK(compressedSize > 0);
484693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
485693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        codec->setImageOutputFormat(format, width, height);
4867530e9c708275c273c134c36c68179f511c1940eAndreas Huber        codec->setJPEGInputFormat(width, height, (OMX_U32)compressedSize);
487693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
488693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
489e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    int32_t maxInputSize;
490738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber    if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
491e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        codec->setMinBufferSize(kPortIndexInput, (OMX_U32)maxInputSize);
492e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
493e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
494e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    if (!strcmp(componentName, "OMX.TI.AMR.encode")
495e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        || !strcmp(componentName, "OMX.TI.WBAMR.encode")) {
496e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        codec->setMinBufferSize(kPortIndexOutput, 8192);  // XXX
497e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
498e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
499693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    codec->initOutputFormat(meta);
500693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
501693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return codec;
502693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
503693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
504e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Hubervoid OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) {
505e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
5067a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
507e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    def.nPortIndex = portIndex;
508e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
509318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
510e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
511e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    CHECK_EQ(err, OK);
512e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
513e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    if (def.nBufferSize < size) {
514e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        def.nBufferSize = size;
515e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
516e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
517318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
518e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
519e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    CHECK_EQ(err, OK);
520738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber
521738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber    err = mOMX->getParameter(
522738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
523738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber    CHECK_EQ(err, OK);
524738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber
525738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber    // Make sure the setting actually stuck.
526738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber    CHECK(def.nBufferSize >= size);
527e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber}
528e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
529693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::setVideoPortFormatType(
530693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_U32 portIndex,
531693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
532693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
533693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
5347a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&format);
535693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    format.nPortIndex = portIndex;
536693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    format.nIndex = 0;
537693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    bool found = false;
538693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
539693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_U32 index = 0;
540693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (;;) {
541693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        format.nIndex = index;
542318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        status_t err = mOMX->getParameter(
543693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
544693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                &format, sizeof(format));
545693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
546693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (err != OK) {
547693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            return err;
548693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
549693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
550693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        // The following assertion is violated by TI's video decoder.
5517530e9c708275c273c134c36c68179f511c1940eAndreas Huber        // CHECK_EQ(format.nIndex, index);
552693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
553693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#if 1
5542a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber        CODEC_LOGV("portIndex: %ld, index: %ld, eCompressionFormat=%d eColorFormat=%d",
555693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber             portIndex,
556693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber             index, format.eCompressionFormat, format.eColorFormat);
557693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#endif
558693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
559693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName)) {
560693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (portIndex == kPortIndexInput
561693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    && colorFormat == format.eColorFormat) {
562693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                // eCompressionFormat does not seem right.
563693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                found = true;
564693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                break;
565693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
566693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (portIndex == kPortIndexOutput
567693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
568693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                // eColorFormat does not seem right.
569693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                found = true;
570693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                break;
571693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
572693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
573693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
574693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (format.eCompressionFormat == compressionFormat
575693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            && format.eColorFormat == colorFormat) {
576693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            found = true;
577693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
578693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
579693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
580693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        ++index;
581693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
582693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
583693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!found) {
584693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return UNKNOWN_ERROR;
585693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
586693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
5872a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    CODEC_LOGV("found a match.");
588318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->setParameter(
589693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
590693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            &format, sizeof(format));
591693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
592693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return err;
593693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
594693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
595888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huberstatic size_t getFrameSize(
596888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat, int32_t width, int32_t height) {
597888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    switch (colorFormat) {
598888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        case OMX_COLOR_FormatYCbYCr:
599888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        case OMX_COLOR_FormatCbYCrY:
600888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            return width * height * 2;
601888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
602888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        case OMX_COLOR_FormatYUV420SemiPlanar:
603888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            return (width * height * 3) / 2;
604888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
605888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        default:
606888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            CHECK(!"Should not be here. Unsupported color format.");
607888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            break;
608888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    }
609888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber}
610888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
611693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::setVideoInputFormat(
612693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const char *mime, OMX_U32 width, OMX_U32 height) {
6132a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    CODEC_LOGV("setVideoInputFormat width=%ld, height=%ld", width, height);
614693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
615693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
61618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
617693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        compressionFormat = OMX_VIDEO_CodingAVC;
61818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
619693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        compressionFormat = OMX_VIDEO_CodingMPEG4;
62018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
621693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        compressionFormat = OMX_VIDEO_CodingH263;
622693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
623693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        LOGE("Not a supported video mime type: %s", mime);
624693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(!"Should not be here. Not a supported video mime type.");
625693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
626693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
62730ab66297501757d745b9ae10da61adcd891f497Andreas Huber    OMX_COLOR_FORMATTYPE colorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
62830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    if (!strcasecmp("OMX.TI.Video.encoder", mComponentName)) {
62930ab66297501757d745b9ae10da61adcd891f497Andreas Huber        colorFormat = OMX_COLOR_FormatYCbYCr;
630693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
631693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
632888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(setVideoPortFormatType(
633693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused,
634888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            colorFormat), OK);
635693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
636888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(setVideoPortFormatType(
637888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused),
638888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            OK);
639693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
640693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
6417a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
642693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexOutput;
643693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
6447a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
6457a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
646318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
647693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
648693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
649693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
650693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
651693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
652693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameWidth = width;
653693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameHeight = height;
654693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
655693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->eCompressionFormat = compressionFormat;
656693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
657693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
658318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
659693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
660693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
661693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
662693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    ////////////////////////////////////////////////////////////////////////////
663693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
6647a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
665693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexInput;
666693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
667318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->getParameter(
668693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
669693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
670693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
671888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    def.nBufferSize = getFrameSize(colorFormat, width, height);
6722a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    CODEC_LOGV("Setting nBufferSize = %ld", def.nBufferSize);
673693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
674693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
675693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
676693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameWidth = width;
677693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameHeight = height;
678693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
679693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->eColorFormat = colorFormat;
680693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
681888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    video_def->xFramerate = 24 << 16;  // XXX crucial!
682888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
683318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
684693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
685693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
686888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
687888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    switch (compressionFormat) {
688888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        case OMX_VIDEO_CodingMPEG4:
689888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        {
690888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            CHECK_EQ(setupMPEG4EncoderParameters(), OK);
691888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            break;
692888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        }
693888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
694888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        case OMX_VIDEO_CodingH263:
695888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            break;
696888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
69730ab66297501757d745b9ae10da61adcd891f497Andreas Huber        case OMX_VIDEO_CodingAVC:
69830ab66297501757d745b9ae10da61adcd891f497Andreas Huber        {
69930ab66297501757d745b9ae10da61adcd891f497Andreas Huber            CHECK_EQ(setupAVCEncoderParameters(), OK);
70030ab66297501757d745b9ae10da61adcd891f497Andreas Huber            break;
70130ab66297501757d745b9ae10da61adcd891f497Andreas Huber        }
70230ab66297501757d745b9ae10da61adcd891f497Andreas Huber
703888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        default:
704888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            CHECK(!"Support for this compressionFormat to be implemented.");
705888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            break;
706888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    }
707888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber}
708888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
709888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huberstatus_t OMXCodec::setupMPEG4EncoderParameters() {
710888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
711888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    InitOMXParams(&mpeg4type);
712888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
713888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
714888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    status_t err = mOMX->getParameter(
715888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
716888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(err, OK);
717888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
718888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
719888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.bSVH = OMX_FALSE;
720888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.bGov = OMX_FALSE;
721888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
722888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nAllowedPictureTypes =
723888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
724888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
725888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nPFrames = 23;
726888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nBFrames = 0;
727888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
728888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nIDCVLCThreshold = 0;
729888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.bACPred = OMX_TRUE;
730888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nMaxPacketSize = 256;
731888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nTimeIncRes = 1000;
732888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nHeaderExtension = 0;
733888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
734888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
735888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.eProfile = OMX_VIDEO_MPEG4ProfileCore;
736888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.eLevel = OMX_VIDEO_MPEG4Level2;
737888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
738888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    err = mOMX->setParameter(
739888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
740888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(err, OK);
741888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
742888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    // ----------------
743888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
744888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
745888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    InitOMXParams(&bitrateType);
746888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
747888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
748888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    err = mOMX->getParameter(
749888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            mNode, OMX_IndexParamVideoBitrate,
750888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            &bitrateType, sizeof(bitrateType));
751888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(err, OK);
752888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
753888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    bitrateType.eControlRate = OMX_Video_ControlRateVariable;
754888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    bitrateType.nTargetBitrate = 1000000;
755888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
756888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    err = mOMX->setParameter(
757888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            mNode, OMX_IndexParamVideoBitrate,
758888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            &bitrateType, sizeof(bitrateType));
759888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(err, OK);
760888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
761888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    // ----------------
762888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
763888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
764888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    InitOMXParams(&errorCorrectionType);
765888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
766888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
767888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    err = mOMX->getParameter(
768888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
769888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
770888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(err, OK);
771888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
772888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
773888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
774888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
775888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
776888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
777888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
778888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    err = mOMX->setParameter(
779888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
780888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
781888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(err, OK);
782888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
783888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    return OK;
784693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
785693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
78630ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t OMXCodec::setupAVCEncoderParameters() {
78730ab66297501757d745b9ae10da61adcd891f497Andreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
78830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    InitOMXParams(&h264type);
78930ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nPortIndex = kPortIndexOutput;
79030ab66297501757d745b9ae10da61adcd891f497Andreas Huber
79130ab66297501757d745b9ae10da61adcd891f497Andreas Huber    status_t err = mOMX->getParameter(
79230ab66297501757d745b9ae10da61adcd891f497Andreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
79330ab66297501757d745b9ae10da61adcd891f497Andreas Huber    CHECK_EQ(err, OK);
79430ab66297501757d745b9ae10da61adcd891f497Andreas Huber
79530ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nAllowedPictureTypes =
79630ab66297501757d745b9ae10da61adcd891f497Andreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
79730ab66297501757d745b9ae10da61adcd891f497Andreas Huber
79830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nSliceHeaderSpacing = 0;
79930ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nBFrames = 0;
80030ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bUseHadamard = OMX_TRUE;
80130ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nRefFrames = 1;
80230ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nRefIdx10ActiveMinus1 = 0;
80330ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nRefIdx11ActiveMinus1 = 0;
80430ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bEnableUEP = OMX_FALSE;
80530ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bEnableFMO = OMX_FALSE;
80630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bEnableASO = OMX_FALSE;
80730ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bEnableRS = OMX_FALSE;
80830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
80930ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.eLevel = OMX_VIDEO_AVCLevel1b;
81030ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
81130ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bMBAFF = OMX_FALSE;
81230ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bEntropyCodingCABAC = OMX_FALSE;
81330ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bWeightedPPrediction = OMX_FALSE;
81430ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bconstIpred = OMX_FALSE;
81530ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bDirect8x8Inference = OMX_FALSE;
81630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bDirectSpatialTemporal = OMX_FALSE;
81730ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nCabacInitIdc = 0;
81830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
81930ab66297501757d745b9ae10da61adcd891f497Andreas Huber
82030ab66297501757d745b9ae10da61adcd891f497Andreas Huber    err = mOMX->setParameter(
82130ab66297501757d745b9ae10da61adcd891f497Andreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
82230ab66297501757d745b9ae10da61adcd891f497Andreas Huber    CHECK_EQ(err, OK);
82330ab66297501757d745b9ae10da61adcd891f497Andreas Huber
82430ab66297501757d745b9ae10da61adcd891f497Andreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
82530ab66297501757d745b9ae10da61adcd891f497Andreas Huber    InitOMXParams(&bitrateType);
82630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
82730ab66297501757d745b9ae10da61adcd891f497Andreas Huber
82830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    err = mOMX->getParameter(
82930ab66297501757d745b9ae10da61adcd891f497Andreas Huber            mNode, OMX_IndexParamVideoBitrate,
83030ab66297501757d745b9ae10da61adcd891f497Andreas Huber            &bitrateType, sizeof(bitrateType));
83130ab66297501757d745b9ae10da61adcd891f497Andreas Huber    CHECK_EQ(err, OK);
83230ab66297501757d745b9ae10da61adcd891f497Andreas Huber
83330ab66297501757d745b9ae10da61adcd891f497Andreas Huber    bitrateType.eControlRate = OMX_Video_ControlRateVariable;
83430ab66297501757d745b9ae10da61adcd891f497Andreas Huber    bitrateType.nTargetBitrate = 1000000;
83530ab66297501757d745b9ae10da61adcd891f497Andreas Huber
83630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    err = mOMX->setParameter(
83730ab66297501757d745b9ae10da61adcd891f497Andreas Huber            mNode, OMX_IndexParamVideoBitrate,
83830ab66297501757d745b9ae10da61adcd891f497Andreas Huber            &bitrateType, sizeof(bitrateType));
83930ab66297501757d745b9ae10da61adcd891f497Andreas Huber    CHECK_EQ(err, OK);
84030ab66297501757d745b9ae10da61adcd891f497Andreas Huber
84130ab66297501757d745b9ae10da61adcd891f497Andreas Huber    return OK;
84230ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
84330ab66297501757d745b9ae10da61adcd891f497Andreas Huber
844693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::setVideoOutputFormat(
845693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const char *mime, OMX_U32 width, OMX_U32 height) {
8462a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    CODEC_LOGV("setVideoOutputFormat width=%ld, height=%ld", width, height);
847693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
848693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
84918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
850693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        compressionFormat = OMX_VIDEO_CodingAVC;
85118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
852693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        compressionFormat = OMX_VIDEO_CodingMPEG4;
85318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
854693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        compressionFormat = OMX_VIDEO_CodingH263;
855693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
856693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        LOGE("Not a supported video mime type: %s", mime);
857693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(!"Should not be here. Not a supported video mime type.");
858693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
859693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
860693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    setVideoPortFormatType(
861693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
862693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
863693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#if 1
864693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    {
865693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_VIDEO_PARAM_PORTFORMATTYPE format;
8667a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        InitOMXParams(&format);
867693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        format.nPortIndex = kPortIndexOutput;
868693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        format.nIndex = 0;
869693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
870318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        status_t err = mOMX->getParameter(
871693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
872693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                &format, sizeof(format));
873693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(err, OK);
874693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(format.eCompressionFormat, OMX_VIDEO_CodingUnused);
875693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
876693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
877693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
878693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
879693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber               || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
880693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber               || format.eColorFormat == OMX_COLOR_FormatCbYCrY
881693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber               || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar);
882693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
883318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        err = mOMX->setParameter(
884693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
885693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                &format, sizeof(format));
886693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(err, OK);
887693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
888693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#endif
889693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
890693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
8917a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
892693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexInput;
893693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
8947a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
8957a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
896318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
897693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
898693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
899693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
900693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
901693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#if 1
902693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    // XXX Need a (much) better heuristic to compute input buffer sizes.
903693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    const size_t X = 64 * 1024;
904693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (def.nBufferSize < X) {
905693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        def.nBufferSize = X;
906693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
907693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#endif
908693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
909693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
910693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
911693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameWidth = width;
912693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameHeight = height;
913693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
914888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    video_def->eCompressionFormat = compressionFormat;
915693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
916693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
917318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
918693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
919693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
920693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
921693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    ////////////////////////////////////////////////////////////////////////////
922693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
9237a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
924693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexOutput;
925693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
926318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->getParameter(
927693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
928693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
929693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
930693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
931693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#if 0
932693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nBufferSize =
933693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2;  // YUV420
934693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#endif
935693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
936693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameWidth = width;
937693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameHeight = height;
938693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
939318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
940693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
941693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
942693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
943693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
944693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberOMXCodec::OMXCodec(
945693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks,
946bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        bool isEncoder,
947693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const char *mime,
948693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const char *componentName,
949693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const sp<MediaSource> &source)
950693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    : mOMX(omx),
951693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mNode(node),
952693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mQuirks(quirks),
953693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mIsEncoder(isEncoder),
954693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mMIME(strdup(mime)),
955693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mComponentName(strdup(componentName)),
956693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mSource(source),
957693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mCodecSpecificDataIndex(0),
958693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mState(LOADED),
959284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber      mInitialBufferSubmit(true),
960693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mSignalledEOS(false),
961693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mNoMoreOutputData(false),
9627f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber      mOutputPortSettingsHaveChanged(false),
963693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mSeekTimeUs(-1) {
964693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mPortStatus[kPortIndexInput] = ENABLED;
965693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mPortStatus[kPortIndexOutput] = ENABLED;
966693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
9677a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    setComponentRole();
9687a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber}
9697a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
97018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber// static
97118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Hubervoid OMXCodec::setComponentRole(
97218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder,
97318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        const char *mime) {
9747a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    struct MimeToRole {
9757a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        const char *mime;
9767a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        const char *decoderRole;
9777a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        const char *encoderRole;
9787a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    };
9797a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
9807a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    static const MimeToRole kMimeToRole[] = {
98118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
98218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
98318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
98418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
98518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
98618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
98718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
98818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
98918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
99018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
99118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
99218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
99318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
99418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
9957a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    };
9967a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
9977a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    static const size_t kNumMimeToRole =
9987a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
9997a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
10007a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    size_t i;
10017a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
100218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
10037a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            break;
10047a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        }
10057a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    }
10067a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
10077a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    if (i == kNumMimeToRole) {
10087a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        return;
10097a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    }
10107a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
10117a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    const char *role =
101218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
101318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                  : kMimeToRole[i].decoderRole;
10147a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
10157a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    if (role != NULL) {
10167a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
10177a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        InitOMXParams(&roleParams);
10187a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
10197a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        strncpy((char *)roleParams.cRole,
10207a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
10217a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
10227a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
10237a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
1024318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        status_t err = omx->setParameter(
102518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                node, OMX_IndexParamStandardComponentRole,
10267a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                &roleParams, sizeof(roleParams));
10277a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
10287a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        if (err != OK) {
10297a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            LOGW("Failed to set standard component role '%s'.", role);
10307a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        }
10317a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    }
1032693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1033693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
103418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Hubervoid OMXCodec::setComponentRole() {
103518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    setComponentRole(mOMX, mNode, mIsEncoder, mMIME);
103618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber}
103718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
1038693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberOMXCodec::~OMXCodec() {
1039dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    CHECK(mState == LOADED || mState == ERROR);
1040693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1041318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->freeNode(mNode);
1042693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
1043693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1044693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mNode = NULL;
1045693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    setState(DEAD);
1046693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1047693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    clearCodecSpecificData();
1048693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1049693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    free(mComponentName);
1050693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mComponentName = NULL;
1051bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
1052693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    free(mMIME);
1053693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mMIME = NULL;
1054693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1055693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1056693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::init() {
1057284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber    // mLock is held.
1058693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1059693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(mState, LOADED);
1060693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1061693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err;
1062693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) {
1063318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
1064693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(err, OK);
1065693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        setState(LOADED_TO_IDLE);
1066693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1067693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1068693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    err = allocateBuffers();
1069693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
1070693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1071693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mQuirks & kRequiresLoadedToIdleAfterAllocation) {
1072318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
1073693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(err, OK);
1074693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1075693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        setState(LOADED_TO_IDLE);
1076693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1077693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1078693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    while (mState != EXECUTING && mState != ERROR) {
1079693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mAsyncCompletion.wait(mLock);
1080693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1081693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1082693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return mState == ERROR ? UNKNOWN_ERROR : OK;
1083693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1084693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1085693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber// static
1086693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberbool OMXCodec::isIntermediateState(State state) {
1087693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return state == LOADED_TO_IDLE
1088693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        || state == IDLE_TO_EXECUTING
1089693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        || state == EXECUTING_TO_IDLE
1090693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        || state == IDLE_TO_LOADED
1091693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        || state == RECONFIGURING;
1092693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1093693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1094693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::allocateBuffers() {
1095693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err = allocateBuffersOnPort(kPortIndexInput);
1096693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1097693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (err != OK) {
1098693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return err;
1099693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1100693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1101693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return allocateBuffersOnPort(kPortIndexOutput);
1102693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1103693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1104693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
1105693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
11067a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
1107693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = portIndex;
1108693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1109318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
1110693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1111693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1112693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (err != OK) {
1113693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return err;
1114693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1115693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
11167530e9c708275c273c134c36c68179f511c1940eAndreas Huber    size_t totalSize = def.nBufferCountActual * def.nBufferSize;
11177530e9c708275c273c134c36c68179f511c1940eAndreas Huber    mDealer[portIndex] = new MemoryDealer(totalSize);
11187530e9c708275c273c134c36c68179f511c1940eAndreas Huber
1119693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
11207530e9c708275c273c134c36c68179f511c1940eAndreas Huber        sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
1121693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(mem.get() != NULL);
1122693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1123693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        IOMX::buffer_id buffer;
1124693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (portIndex == kPortIndexInput
1125693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                && (mQuirks & kRequiresAllocateBufferOnInputPorts)) {
1126318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            err = mOMX->allocateBufferWithBackup(
1127693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    mNode, portIndex, mem, &buffer);
1128ea7d15629752256f6ea1d5c6ea796e59aefd030fAndreas Huber        } else if (portIndex == kPortIndexOutput
1129ea7d15629752256f6ea1d5c6ea796e59aefd030fAndreas Huber                && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) {
1130318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            err = mOMX->allocateBufferWithBackup(
1131df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber                    mNode, portIndex, mem, &buffer);
1132693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        } else {
1133318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
1134693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1135693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1136693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (err != OK) {
1137693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            LOGE("allocate_buffer_with_backup failed");
1138693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            return err;
1139693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1140693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1141693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        BufferInfo info;
1142693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        info.mBuffer = buffer;
1143693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        info.mOwnedByComponent = false;
1144693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        info.mMem = mem;
1145693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        info.mMediaBuffer = NULL;
1146693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1147693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (portIndex == kPortIndexOutput) {
1148693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            info.mMediaBuffer = new MediaBuffer(mem->pointer(), mem->size());
1149693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            info.mMediaBuffer->setObserver(this);
1150693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1151693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1152693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mPortBuffers[portIndex].push(info);
1153693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
11547a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        CODEC_LOGV("allocated buffer %p on %s port", buffer,
1155693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber             portIndex == kPortIndexInput ? "input" : "output");
1156693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1157693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1158693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    dumpPortStatus(portIndex);
1159693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1160693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return OK;
1161693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1162693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1163693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::on_message(const omx_message &msg) {
1164693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Mutex::Autolock autoLock(mLock);
1165693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1166693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (msg.type) {
1167693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case omx_message::EVENT:
1168693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1169693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            onEvent(
1170693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 msg.u.event_data.event, msg.u.event_data.data1,
1171693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 msg.u.event_data.data2);
1172693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1173693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1174693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1175693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1176693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
1177693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1178693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
1179693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
11807a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("EMPTY_BUFFER_DONE(buffer: %p)", buffer);
1181693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1182693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
1183693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            size_t i = 0;
1184693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
1185693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                ++i;
1186693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1187693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1188693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(i < buffers->size());
1189693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (!(*buffers)[i].mOwnedByComponent) {
1190693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                LOGW("We already own input buffer %p, yet received "
1191693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                     "an EMPTY_BUFFER_DONE.", buffer);
1192693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1193693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1194693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            buffers->editItemAt(i).mOwnedByComponent = false;
1195693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1196693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (mPortStatus[kPortIndexInput] == DISABLING) {
11977a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
1198693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1199693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                status_t err =
1200318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                    mOMX->freeBuffer(mNode, kPortIndexInput, buffer);
1201693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1202693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1203693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                buffers->removeAt(i);
1204693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else if (mPortStatus[kPortIndexInput] != SHUTTING_DOWN) {
1205693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(mPortStatus[kPortIndexInput], ENABLED);
1206693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                drainInputBuffer(&buffers->editItemAt(i));
1207693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1208693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1209693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1210693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1211693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1212693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case omx_message::FILL_BUFFER_DONE:
1213693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1214693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
1215693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_U32 flags = msg.u.extended_buffer_data.flags;
1216693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
12177a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx)",
1218693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 buffer,
1219693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 msg.u.extended_buffer_data.range_length,
1220693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 flags);
1221693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
12227a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("FILL_BUFFER_DONE(timestamp: %lld us (%.2f secs))",
1223693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 msg.u.extended_buffer_data.timestamp,
1224693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 msg.u.extended_buffer_data.timestamp / 1E6);
1225693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1226693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
1227693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            size_t i = 0;
1228693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
1229693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                ++i;
1230693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1231693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1232693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(i < buffers->size());
1233693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            BufferInfo *info = &buffers->editItemAt(i);
1234693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1235693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (!info->mOwnedByComponent) {
1236693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                LOGW("We already own output buffer %p, yet received "
1237693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                     "a FILL_BUFFER_DONE.", buffer);
1238693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1239693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1240693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            info->mOwnedByComponent = false;
1241693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1242693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (mPortStatus[kPortIndexOutput] == DISABLING) {
12437a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
1244693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1245693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                status_t err =
1246318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                    mOMX->freeBuffer(mNode, kPortIndexOutput, buffer);
1247693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1248693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1249693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                buffers->removeAt(i);
1250355edcea2f15c0f619c1e1d0f4fa433b0d38098fAndreas Huber            } else if (mPortStatus[kPortIndexOutput] == ENABLED
1251355edcea2f15c0f619c1e1d0f4fa433b0d38098fAndreas Huber                       && (flags & OMX_BUFFERFLAG_EOS)) {
12527a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                CODEC_LOGV("No more output data.");
1253693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mNoMoreOutputData = true;
1254693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mBufferFilled.signal();
1255693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) {
1256693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED);
1257bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
1258693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                MediaBuffer *buffer = info->mMediaBuffer;
1259693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1260693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                buffer->set_range(
1261693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        msg.u.extended_buffer_data.range_offset,
1262693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        msg.u.extended_buffer_data.range_length);
1263693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1264693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                buffer->meta_data()->clear();
1265693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
126648c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber                buffer->meta_data()->setInt64(
126748c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber                        kKeyTime, msg.u.extended_buffer_data.timestamp);
1268693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1269693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) {
1270693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    buffer->meta_data()->setInt32(kKeyIsSyncFrame, true);
1271693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                }
127230ab66297501757d745b9ae10da61adcd891f497Andreas Huber                if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_CODECCONFIG) {
127330ab66297501757d745b9ae10da61adcd891f497Andreas Huber                    buffer->meta_data()->setInt32(kKeyIsCodecConfig, true);
127430ab66297501757d745b9ae10da61adcd891f497Andreas Huber                }
1275693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1276693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                buffer->meta_data()->setPointer(
1277693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        kKeyPlatformPrivate,
1278693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        msg.u.extended_buffer_data.platform_private);
1279693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1280693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                buffer->meta_data()->setPointer(
1281693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        kKeyBufferID,
1282693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        msg.u.extended_buffer_data.buffer);
1283693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1284693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mFilledBuffers.push_back(i);
1285693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mBufferFilled.signal();
1286693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1287693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1288693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1289693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1290693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1291693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
1292693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1293693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(!"should not be here.");
1294693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1295693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1296693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1297693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1298693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1299693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
1300693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (event) {
1301693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_EventCmdComplete:
1302693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1303693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            onCmdComplete((OMX_COMMANDTYPE)data1, data2);
1304693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1305693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1306693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1307693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_EventError:
1308693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1309693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            LOGE("ERROR(%ld, %ld)", data1, data2);
1310693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1311693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            setState(ERROR);
1312693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1313693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1314693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1315693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_EventPortSettingsChanged:
1316693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1317693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            onPortSettingsChanged(data1);
1318693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1319693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1320693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1321693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_EventBufferFlag:
1322693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
13237a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1);
1324693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1325693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (data1 == kPortIndexOutput) {
1326693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mNoMoreOutputData = true;
1327693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1328693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1329693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1330693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1331693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
1332693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
13337a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("EVENT(%d, %ld, %ld)", event, data1, data2);
1334693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1335693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1336693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1337693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1338693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
133912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber// Has the format changed in any way that the client would have to be aware of?
134012658b720b176b7d934444256d07ba3c595d9b44Andreas Huberstatic bool formatHasNotablyChanged(
134112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        const sp<MetaData> &from, const sp<MetaData> &to) {
134212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    if (from.get() == NULL && to.get() == NULL) {
134312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        return false;
134412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    }
134512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
1346c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber    if ((from.get() == NULL && to.get() != NULL)
1347c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber        || (from.get() != NULL && to.get() == NULL)) {
134812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        return true;
134912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    }
135012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
135112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    const char *mime_from, *mime_to;
135212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    CHECK(from->findCString(kKeyMIMEType, &mime_from));
135312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    CHECK(to->findCString(kKeyMIMEType, &mime_to));
135412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
135512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    if (strcasecmp(mime_from, mime_to)) {
135612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        return true;
135712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    }
135812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
135912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    if (!strcasecmp(mime_from, MEDIA_MIMETYPE_VIDEO_RAW)) {
136012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        int32_t colorFormat_from, colorFormat_to;
136112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(from->findInt32(kKeyColorFormat, &colorFormat_from));
136212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(to->findInt32(kKeyColorFormat, &colorFormat_to));
136312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
136412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        if (colorFormat_from != colorFormat_to) {
136512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber            return true;
136612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        }
136712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
136812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        int32_t width_from, width_to;
136912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(from->findInt32(kKeyWidth, &width_from));
137012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(to->findInt32(kKeyWidth, &width_to));
137112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
137212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        if (width_from != width_to) {
137312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber            return true;
137412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        }
137512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
137612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        int32_t height_from, height_to;
137712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(from->findInt32(kKeyHeight, &height_from));
137812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(to->findInt32(kKeyHeight, &height_to));
137912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
138012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        if (height_from != height_to) {
138112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber            return true;
138212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        }
138312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    } else if (!strcasecmp(mime_from, MEDIA_MIMETYPE_AUDIO_RAW)) {
138412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        int32_t numChannels_from, numChannels_to;
138512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(from->findInt32(kKeyChannelCount, &numChannels_from));
138612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(to->findInt32(kKeyChannelCount, &numChannels_to));
138712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
138812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        if (numChannels_from != numChannels_to) {
138912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber            return true;
139012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        }
139112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
139212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        int32_t sampleRate_from, sampleRate_to;
139312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(from->findInt32(kKeySampleRate, &sampleRate_from));
139412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(to->findInt32(kKeySampleRate, &sampleRate_to));
139512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
139612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        if (sampleRate_from != sampleRate_to) {
139712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber            return true;
139812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        }
139912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    }
140012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
140112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    return false;
140212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber}
140312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
1404693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) {
1405693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (cmd) {
1406693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_CommandStateSet:
1407693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1408693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            onStateChange((OMX_STATETYPE)data);
1409693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1410693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1411693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1412693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_CommandPortDisable:
1413693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1414693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_U32 portIndex = data;
14157a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("PORT_DISABLED(%ld)", portIndex);
1416693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1417693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(mState == EXECUTING || mState == RECONFIGURING);
1418693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mPortStatus[portIndex], DISABLING);
1419693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mPortBuffers[portIndex].size(), 0);
1420693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1421693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mPortStatus[portIndex] = DISABLED;
1422693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1423693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (mState == RECONFIGURING) {
1424693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(portIndex, kPortIndexOutput);
1425693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
142612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber                sp<MetaData> oldOutputFormat = mOutputFormat;
14277f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber                initOutputFormat(mSource->getFormat());
142812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
142912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber                // Don't notify clients if the output port settings change
143012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber                // wasn't of importance to them, i.e. it may be that just the
143112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber                // number of buffers has changed and nothing else.
143212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber                mOutputPortSettingsHaveChanged =
143312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber                    formatHasNotablyChanged(oldOutputFormat, mOutputFormat);
14347f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber
1435693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                enablePortAsync(portIndex);
1436693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1437693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                status_t err = allocateBuffersOnPort(portIndex);
1438693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1439693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1440693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1441693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1442693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1443693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_CommandPortEnable:
1444693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1445693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_U32 portIndex = data;
14467a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("PORT_ENABLED(%ld)", portIndex);
1447693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1448693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(mState == EXECUTING || mState == RECONFIGURING);
1449693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mPortStatus[portIndex], ENABLING);
1450693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1451693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mPortStatus[portIndex] = ENABLED;
1452693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1453693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (mState == RECONFIGURING) {
1454693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(portIndex, kPortIndexOutput);
1455693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1456693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                setState(EXECUTING);
1457693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1458693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                fillOutputBuffers();
1459693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1460693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1461693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1462693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1463693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_CommandFlush:
1464693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1465693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_U32 portIndex = data;
1466693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
14677a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("FLUSH_DONE(%ld)", portIndex);
1468693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1469693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mPortStatus[portIndex], SHUTTING_DOWN);
1470693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mPortStatus[portIndex] = ENABLED;
1471693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1472693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]),
1473693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                     mPortBuffers[portIndex].size());
1474693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1475693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (mState == RECONFIGURING) {
1476693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(portIndex, kPortIndexOutput);
1477693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1478693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                disablePortAsync(portIndex);
14798297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber            } else if (mState == EXECUTING_TO_IDLE) {
14808297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                if (mPortStatus[kPortIndexInput] == ENABLED
14818297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    && mPortStatus[kPortIndexOutput] == ENABLED) {
14827a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                    CODEC_LOGV("Finished flushing both ports, now completing "
14838297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                         "transition from EXECUTING to IDLE.");
14848297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber
14858297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
14868297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
14878297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber
14888297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    status_t err =
1489318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                        mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
14908297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    CHECK_EQ(err, OK);
14918297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                }
1492693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else {
1493693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                // We're flushing both ports in preparation for seeking.
1494693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1495693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                if (mPortStatus[kPortIndexInput] == ENABLED
1496693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    && mPortStatus[kPortIndexOutput] == ENABLED) {
14977a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                    CODEC_LOGV("Finished flushing both ports, now continuing from"
1498693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                         " seek-time.");
1499693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
15005228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber                    // Clear this flag in case the decoder sent us either
15015228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber                    // the EVENT_BUFFER_FLAG(1) or an output buffer with
15025228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber                    // the EOS flag set _while_ flushing. Since we're going
15035228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber                    // to submit "fresh" input data now, this flag no longer
15045228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber                    // applies to our future.
15055228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber                    mNoMoreOutputData = false;
15065228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber
1507693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    drainInputBuffers();
1508693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    fillOutputBuffers();
1509693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                }
1510693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1511693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1512693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1513693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1514693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1515693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
1516693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
15177a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("CMD_COMPLETE(%d, %ld)", cmd, data);
1518693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1519693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1520693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1521693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1522693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1523693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::onStateChange(OMX_STATETYPE newState) {
1524693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (newState) {
1525693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_StateIdle:
1526693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
15277a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("Now Idle.");
1528693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (mState == LOADED_TO_IDLE) {
1529318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                status_t err = mOMX->sendCommand(
1530693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        mNode, OMX_CommandStateSet, OMX_StateExecuting);
1531693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1532693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1533693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1534693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                setState(IDLE_TO_EXECUTING);
1535693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else {
1536693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(mState, EXECUTING_TO_IDLE);
1537693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1538693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(
1539693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
1540693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    mPortBuffers[kPortIndexInput].size());
1541693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1542693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(
1543693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    countBuffersWeOwn(mPortBuffers[kPortIndexOutput]),
1544693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    mPortBuffers[kPortIndexOutput].size());
1545693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1546318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                status_t err = mOMX->sendCommand(
1547693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        mNode, OMX_CommandStateSet, OMX_StateLoaded);
1548693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1549693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1550693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1551693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                err = freeBuffersOnPort(kPortIndexInput);
1552693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1553693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1554693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                err = freeBuffersOnPort(kPortIndexOutput);
1555693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1556693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1557693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mPortStatus[kPortIndexInput] = ENABLED;
1558693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mPortStatus[kPortIndexOutput] = ENABLED;
1559693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1560693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                setState(IDLE_TO_LOADED);
1561693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1562693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1563693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1564693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1565693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_StateExecuting:
1566693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1567693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mState, IDLE_TO_EXECUTING);
1568693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
15697a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("Now Executing.");
1570693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1571693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            setState(EXECUTING);
1572693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1573284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber            // Buffers will be submitted to the component in the first
1574284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber            // call to OMXCodec::read as mInitialBufferSubmit is true at
1575284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber            // this point. This ensures that this on_message call returns,
1576284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber            // releases the lock and ::init can notice the state change and
1577284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber            // itself return.
1578693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1579693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1580693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1581693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_StateLoaded:
1582693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1583693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mState, IDLE_TO_LOADED);
1584693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
15857a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("Now Loaded.");
1586693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1587693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            setState(LOADED);
1588693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1589693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1590693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1591693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
1592693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1593693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(!"should not be here.");
1594693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1595693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1596693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1597693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1598693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1599693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber// static
1600693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t OMXCodec::countBuffersWeOwn(const Vector<BufferInfo> &buffers) {
1601693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t n = 0;
1602693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < buffers.size(); ++i) {
1603693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (!buffers[i].mOwnedByComponent) {
1604693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            ++n;
1605693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1606693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1607693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1608693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return n;
1609693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1610693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1611693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::freeBuffersOnPort(
1612693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_U32 portIndex, bool onlyThoseWeOwn) {
1613693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
1614693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1615693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t stickyErr = OK;
1616693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1617693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = buffers->size(); i-- > 0;) {
1618693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        BufferInfo *info = &buffers->editItemAt(i);
1619693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1620693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (onlyThoseWeOwn && info->mOwnedByComponent) {
1621693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            continue;
1622693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1623693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1624693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(info->mOwnedByComponent, false);
1625693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
162695301196d59fb88ef96342fd307a2be374b5079bAndreas Huber        CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex);
162795301196d59fb88ef96342fd307a2be374b5079bAndreas Huber
1628693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        status_t err =
1629318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mOMX->freeBuffer(mNode, portIndex, info->mBuffer);
1630693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1631693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (err != OK) {
1632693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            stickyErr = err;
1633693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1634693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1635693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (info->mMediaBuffer != NULL) {
1636693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            info->mMediaBuffer->setObserver(NULL);
1637693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1638693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            // Make sure nobody but us owns this buffer at this point.
1639693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(info->mMediaBuffer->refcount(), 0);
1640693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1641693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            info->mMediaBuffer->release();
1642693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1643693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1644693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        buffers->removeAt(i);
1645693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1646693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1647693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(onlyThoseWeOwn || buffers->isEmpty());
1648693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1649693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return stickyErr;
1650693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1651693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1652693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) {
16537a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex);
1654693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1655693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(mState, EXECUTING);
1656693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(portIndex, kPortIndexOutput);
1657693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    setState(RECONFIGURING);
1658693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1659693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mQuirks & kNeedsFlushBeforeDisable) {
16601beb760d920561679862ded945a04e370368c7f7Andreas Huber        if (!flushPortAsync(portIndex)) {
16611beb760d920561679862ded945a04e370368c7f7Andreas Huber            onCmdComplete(OMX_CommandFlush, portIndex);
16621beb760d920561679862ded945a04e370368c7f7Andreas Huber        }
1663693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
1664693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        disablePortAsync(portIndex);
1665693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1666693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1667693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
16681beb760d920561679862ded945a04e370368c7f7Andreas Huberbool OMXCodec::flushPortAsync(OMX_U32 portIndex) {
16698297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber    CHECK(mState == EXECUTING || mState == RECONFIGURING
16708297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber            || mState == EXECUTING_TO_IDLE);
1671693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
16727a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    CODEC_LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.",
16731beb760d920561679862ded945a04e370368c7f7Andreas Huber         portIndex, countBuffersWeOwn(mPortBuffers[portIndex]),
16741beb760d920561679862ded945a04e370368c7f7Andreas Huber         mPortBuffers[portIndex].size());
16751beb760d920561679862ded945a04e370368c7f7Andreas Huber
1676693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(mPortStatus[portIndex], ENABLED);
1677693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mPortStatus[portIndex] = SHUTTING_DOWN;
1678693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
16791beb760d920561679862ded945a04e370368c7f7Andreas Huber    if ((mQuirks & kRequiresFlushCompleteEmulation)
16801beb760d920561679862ded945a04e370368c7f7Andreas Huber        && countBuffersWeOwn(mPortBuffers[portIndex])
16811beb760d920561679862ded945a04e370368c7f7Andreas Huber                == mPortBuffers[portIndex].size()) {
16821beb760d920561679862ded945a04e370368c7f7Andreas Huber        // No flush is necessary and this component fails to send a
16831beb760d920561679862ded945a04e370368c7f7Andreas Huber        // flush-complete event in this case.
16841beb760d920561679862ded945a04e370368c7f7Andreas Huber
16851beb760d920561679862ded945a04e370368c7f7Andreas Huber        return false;
16861beb760d920561679862ded945a04e370368c7f7Andreas Huber    }
16871beb760d920561679862ded945a04e370368c7f7Andreas Huber
1688693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err =
1689318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        mOMX->sendCommand(mNode, OMX_CommandFlush, portIndex);
1690693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
16911beb760d920561679862ded945a04e370368c7f7Andreas Huber
16921beb760d920561679862ded945a04e370368c7f7Andreas Huber    return true;
1693693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1694693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1695693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::disablePortAsync(OMX_U32 portIndex) {
1696693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(mState == EXECUTING || mState == RECONFIGURING);
1697693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1698693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(mPortStatus[portIndex], ENABLED);
1699693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mPortStatus[portIndex] = DISABLING;
1700693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1701693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err =
1702318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        mOMX->sendCommand(mNode, OMX_CommandPortDisable, portIndex);
1703693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
1704693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1705693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    freeBuffersOnPort(portIndex, true);
1706693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1707693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1708693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::enablePortAsync(OMX_U32 portIndex) {
1709693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(mState == EXECUTING || mState == RECONFIGURING);
1710693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1711693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(mPortStatus[portIndex], DISABLED);
1712693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mPortStatus[portIndex] = ENABLING;
1713693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1714693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err =
1715318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex);
1716693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
1717693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1718693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1719693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::fillOutputBuffers() {
1720693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(mState, EXECUTING);
1721693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1722693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
1723693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
1724693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        fillOutputBuffer(&buffers->editItemAt(i));
1725693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1726693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1727693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1728693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::drainInputBuffers() {
1729450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber    CHECK(mState == EXECUTING || mState == RECONFIGURING);
1730693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1731693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
1732693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
1733693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        drainInputBuffer(&buffers->editItemAt(i));
1734693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1735693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1736693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1737693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::drainInputBuffer(BufferInfo *info) {
1738693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(info->mOwnedByComponent, false);
1739693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1740693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mSignalledEOS) {
1741693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return;
1742693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1743693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1744693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mCodecSpecificDataIndex < mCodecSpecificData.size()) {
1745693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const CodecSpecificData *specific =
1746693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mCodecSpecificData[mCodecSpecificDataIndex];
1747693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1748693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        size_t size = specific->mSize;
1749693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
175018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME)
1751dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber                && !(mQuirks & kWantsNALFragments)) {
1752693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            static const uint8_t kNALStartCode[4] =
1753693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    { 0x00, 0x00, 0x00, 0x01 };
1754693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1755693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(info->mMem->size() >= specific->mSize + 4);
1756693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1757693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            size += 4;
1758693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1759693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            memcpy(info->mMem->pointer(), kNALStartCode, 4);
1760693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            memcpy((uint8_t *)info->mMem->pointer() + 4,
1761693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                   specific->mData, specific->mSize);
1762693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        } else {
1763693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(info->mMem->size() >= specific->mSize);
1764693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            memcpy(info->mMem->pointer(), specific->mData, specific->mSize);
1765693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1766693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1767318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        status_t err = mOMX->emptyBuffer(
1768693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mNode, info->mBuffer, 0, size,
1769693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG,
1770693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                0);
177136efa039efaae4526791336cb688032d22b34becAndreas Huber        CHECK_EQ(err, OK);
1772693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1773693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        info->mOwnedByComponent = true;
1774693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1775693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        ++mCodecSpecificDataIndex;
1776693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return;
1777693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1778693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1779693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    MediaBuffer *srcBuffer;
1780693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err;
1781693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mSeekTimeUs >= 0) {
1782693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        MediaSource::ReadOptions options;
1783693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        options.setSeekTo(mSeekTimeUs);
1784693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mSeekTimeUs = -1;
1785693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1786693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        err = mSource->read(&srcBuffer, &options);
1787693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
1788693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        err = mSource->read(&srcBuffer);
1789693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1790693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1791693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
179248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber    OMX_TICKS timestampUs = 0;
1793693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t srcLength = 0;
1794693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1795693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (err != OK) {
17967a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        CODEC_LOGV("signalling end of input stream.");
1797693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        flags |= OMX_BUFFERFLAG_EOS;
1798693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1799693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mSignalledEOS = true;
1800693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
1801693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        srcLength = srcBuffer->range_length();
1802693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1803693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (info->mMem->size() < srcLength) {
1804693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            LOGE("info->mMem->size() = %d, srcLength = %d",
1805693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 info->mMem->size(), srcLength);
1806693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1807693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(info->mMem->size() >= srcLength);
1808693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        memcpy(info->mMem->pointer(),
1809693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber               (const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(),
1810693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber               srcLength);
1811693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
181248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber        if (srcBuffer->meta_data()->findInt64(kKeyTime, &timestampUs)) {
1813318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d)",
1814693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 info->mBuffer, srcLength);
1815318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            CODEC_LOGV("Calling emptyBuffer with timestamp %lld us (%.2f secs)",
181648c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber                 timestampUs, timestampUs / 1E6);
1817693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1818693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1819693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1820693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (srcBuffer != NULL) {
1821693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        srcBuffer->release();
1822693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        srcBuffer = NULL;
1823693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
182436efa039efaae4526791336cb688032d22b34becAndreas Huber
1825318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->emptyBuffer(
182636efa039efaae4526791336cb688032d22b34becAndreas Huber            mNode, info->mBuffer, 0, srcLength,
182748c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber            flags, timestampUs);
182836efa039efaae4526791336cb688032d22b34becAndreas Huber
182936efa039efaae4526791336cb688032d22b34becAndreas Huber    if (err != OK) {
183036efa039efaae4526791336cb688032d22b34becAndreas Huber        setState(ERROR);
183136efa039efaae4526791336cb688032d22b34becAndreas Huber        return;
183236efa039efaae4526791336cb688032d22b34becAndreas Huber    }
183336efa039efaae4526791336cb688032d22b34becAndreas Huber
183436efa039efaae4526791336cb688032d22b34becAndreas Huber    info->mOwnedByComponent = true;
183530ab66297501757d745b9ae10da61adcd891f497Andreas Huber
183630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    // This component does not ever signal the EOS flag on output buffers,
183730ab66297501757d745b9ae10da61adcd891f497Andreas Huber    // Thanks for nothing.
183830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    if (mSignalledEOS && !strcmp(mComponentName, "OMX.TI.Video.encoder")) {
183930ab66297501757d745b9ae10da61adcd891f497Andreas Huber        mNoMoreOutputData = true;
184030ab66297501757d745b9ae10da61adcd891f497Andreas Huber        mBufferFilled.signal();
184130ab66297501757d745b9ae10da61adcd891f497Andreas Huber    }
1842693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1843693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1844693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::fillOutputBuffer(BufferInfo *info) {
1845693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(info->mOwnedByComponent, false);
1846693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
18471beb760d920561679862ded945a04e370368c7f7Andreas Huber    if (mNoMoreOutputData) {
18487a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        CODEC_LOGV("There is no more output data available, not "
18491beb760d920561679862ded945a04e370368c7f7Andreas Huber             "calling fillOutputBuffer");
18501beb760d920561679862ded945a04e370368c7f7Andreas Huber        return;
18511beb760d920561679862ded945a04e370368c7f7Andreas Huber    }
18521beb760d920561679862ded945a04e370368c7f7Andreas Huber
18537a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    CODEC_LOGV("Calling fill_buffer on buffer %p", info->mBuffer);
1854318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->fillBuffer(mNode, info->mBuffer);
185536efa039efaae4526791336cb688032d22b34becAndreas Huber    CHECK_EQ(err, OK);
1856693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1857693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    info->mOwnedByComponent = true;
1858693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1859693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1860693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::drainInputBuffer(IOMX::buffer_id buffer) {
1861693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
1862693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
1863693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if ((*buffers)[i].mBuffer == buffer) {
1864693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            drainInputBuffer(&buffers->editItemAt(i));
1865693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            return;
1866693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1867693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1868693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1869693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(!"should not be here.");
1870693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1871693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1872693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::fillOutputBuffer(IOMX::buffer_id buffer) {
1873693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
1874693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
1875693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if ((*buffers)[i].mBuffer == buffer) {
1876693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            fillOutputBuffer(&buffers->editItemAt(i));
1877693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            return;
1878693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1879693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1880693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1881693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(!"should not be here.");
1882693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1883693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1884693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::setState(State newState) {
1885693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mState = newState;
1886693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mAsyncCompletion.signal();
1887693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1888693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    // This may cause some spurious wakeups but is necessary to
1889693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    // unblock the reader if we enter ERROR state.
1890693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mBufferFilled.signal();
1891693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1892693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1893e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Hubervoid OMXCodec::setRawAudioFormat(
1894e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1895e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
18967a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&pcmParams);
1897e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.nPortIndex = portIndex;
1898e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
1899318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
1900e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1901e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
1902e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    CHECK_EQ(err, OK);
1903e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
1904e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.nChannels = numChannels;
1905e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1906e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1907e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.nBitPerSample = 16;
1908e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.nSamplingRate = sampleRate;
1909e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1910e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
1911e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    if (numChannels == 1) {
1912e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelCF;
1913e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    } else {
1914e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        CHECK_EQ(numChannels, 2);
1915e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
1916e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
1917e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        pcmParams.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
1918e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
1919e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
1920318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
1921e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1922e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
1923e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    CHECK_EQ(err, OK);
1924e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber}
1925e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
1926c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Hubervoid OMXCodec::setAMRFormat(bool isWAMR) {
1927c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    OMX_U32 portIndex = mIsEncoder ? kPortIndexOutput : kPortIndexInput;
1928693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1929c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1930c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    InitOMXParams(&def);
1931c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    def.nPortIndex = portIndex;
1932456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber
1933c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    status_t err =
1934c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1935456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber
1936c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    CHECK_EQ(err, OK);
1937456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber
1938c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
1939c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    def.eAMRBandMode =
1940c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber        isWAMR ? OMX_AUDIO_AMRBandModeWB0 : OMX_AUDIO_AMRBandModeNB0;
1941456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber
1942c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1943c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    CHECK_EQ(err, OK);
1944456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber
1945456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber    ////////////////////////
1946456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber
1947456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber    if (mIsEncoder) {
1948456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber        sp<MetaData> format = mSource->getFormat();
1949456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber        int32_t sampleRate;
1950456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber        int32_t numChannels;
1951456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber        CHECK(format->findInt32(kKeySampleRate, &sampleRate));
1952693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(format->findInt32(kKeyChannelCount, &numChannels));
1953693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1954e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1955e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
1956e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber}
1957693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1958e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Hubervoid OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate) {
1959e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    if (mIsEncoder) {
1960e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1961e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    } else {
1962e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
19637a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        InitOMXParams(&profile);
1964e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        profile.nPortIndex = kPortIndexInput;
1965693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1966318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        status_t err = mOMX->getParameter(
1967e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1968693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(err, OK);
1969693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1970e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        profile.nChannels = numChannels;
1971e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        profile.nSampleRate = sampleRate;
1972e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
1973693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1974318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        err = mOMX->setParameter(
1975e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1976693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(err, OK);
1977693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1978693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1979693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1980693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::setImageOutputFormat(
1981693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) {
19827a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height);
1983693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1984693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#if 0
1985693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_INDEXTYPE index;
1986693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err = mOMX->get_extension_index(
1987693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index);
1988693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
1989693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1990693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    err = mOMX->set_config(mNode, index, &format, sizeof(format));
1991693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
1992693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#endif
1993693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1994693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
19957a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
1996693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexOutput;
1997693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1998318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
1999693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2000693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
2001693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2002693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(def.eDomain, OMX_PortDomainImage);
2003693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2004693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
2005bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
2006693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused);
2007693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    imageDef->eColorFormat = format;
2008693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    imageDef->nFrameWidth = width;
2009693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    imageDef->nFrameHeight = height;
2010693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2011693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (format) {
2012693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_COLOR_FormatYUV420PackedPlanar:
2013693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_COLOR_FormatYUV411Planar:
2014693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2015693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            def.nBufferSize = (width * height * 3) / 2;
2016693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2017693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2018693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2019693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_COLOR_FormatCbYCrY:
2020693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2021693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            def.nBufferSize = width * height * 2;
2022693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2023693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2024693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2025693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_COLOR_Format32bitARGB8888:
2026693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2027693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            def.nBufferSize = width * height * 4;
2028693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2029693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2030693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2031195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber        case OMX_COLOR_Format16bitARGB4444:
2032195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber        case OMX_COLOR_Format16bitARGB1555:
2033195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber        case OMX_COLOR_Format16bitRGB565:
2034195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber        case OMX_COLOR_Format16bitBGR565:
2035195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber        {
2036195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber            def.nBufferSize = width * height * 2;
2037195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber            break;
2038195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber        }
2039195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber
2040693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
2041693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(!"Should not be here. Unknown color format.");
2042693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2043693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2044693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
20457530e9c708275c273c134c36c68179f511c1940eAndreas Huber    def.nBufferCountActual = def.nBufferCountMin;
20467530e9c708275c273c134c36c68179f511c1940eAndreas Huber
2047318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
2048693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2049693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
20507530e9c708275c273c134c36c68179f511c1940eAndreas Huber}
2051693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
20527530e9c708275c273c134c36c68179f511c1940eAndreas Hubervoid OMXCodec::setJPEGInputFormat(
20537530e9c708275c273c134c36c68179f511c1940eAndreas Huber        OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) {
20547530e9c708275c273c134c36c68179f511c1940eAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
20557a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
2056693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexInput;
2057693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2058318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
2059693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2060693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
2061693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
20627530e9c708275c273c134c36c68179f511c1940eAndreas Huber    CHECK_EQ(def.eDomain, OMX_PortDomainImage);
20637530e9c708275c273c134c36c68179f511c1940eAndreas Huber    OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
20647530e9c708275c273c134c36c68179f511c1940eAndreas Huber
2065693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingJPEG);
2066693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    imageDef->nFrameWidth = width;
2067693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    imageDef->nFrameHeight = height;
2068693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
20697530e9c708275c273c134c36c68179f511c1940eAndreas Huber    def.nBufferSize = compressedSize;
2070693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nBufferCountActual = def.nBufferCountMin;
2071693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2072318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
2073693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2074693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
2075693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2076693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2077693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::addCodecSpecificData(const void *data, size_t size) {
2078693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CodecSpecificData *specific =
2079693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1);
2080693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2081693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    specific->mSize = size;
2082693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    memcpy(specific->mData, data, size);
2083693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2084693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mCodecSpecificData.push(specific);
2085693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2086693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2087693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::clearCodecSpecificData() {
2088693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < mCodecSpecificData.size(); ++i) {
2089693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        free(mCodecSpecificData.editItemAt(i));
2090693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2091693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mCodecSpecificData.clear();
2092693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mCodecSpecificDataIndex = 0;
2093693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2094693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2095693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::start(MetaData *) {
2096284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber    Mutex::Autolock autoLock(mLock);
2097284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber
2098693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mState != LOADED) {
2099693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return UNKNOWN_ERROR;
2100693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2101bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
2102693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    sp<MetaData> params = new MetaData;
2103dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    if (mQuirks & kWantsNALFragments) {
2104dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        params->setInt32(kKeyWantsNALFragments, true);
2105693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2106693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err = mSource->start(params.get());
2107693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2108693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (err != OK) {
2109693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return err;
2110693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2111693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2112693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mCodecSpecificDataIndex = 0;
2113284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber    mInitialBufferSubmit = true;
2114693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mSignalledEOS = false;
2115693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mNoMoreOutputData = false;
21167f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber    mOutputPortSettingsHaveChanged = false;
2117693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mSeekTimeUs = -1;
2118693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mFilledBuffers.clear();
2119693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2120693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return init();
2121693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2122693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2123693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::stop() {
21247a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    CODEC_LOGV("stop");
2125693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2126693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Mutex::Autolock autoLock(mLock);
2127693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2128693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    while (isIntermediateState(mState)) {
2129693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mAsyncCompletion.wait(mLock);
2130693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2131693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2132693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (mState) {
2133693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case LOADED:
2134693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case ERROR:
2135693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2136693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2137693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case EXECUTING:
2138693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2139693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            setState(EXECUTING_TO_IDLE);
2140693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
21418297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber            if (mQuirks & kRequiresFlushBeforeShutdown) {
21427a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                CODEC_LOGV("This component requires a flush before transitioning "
21438297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                     "from EXECUTING to IDLE...");
21448297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber
21458297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                bool emulateInputFlushCompletion =
21468297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    !flushPortAsync(kPortIndexInput);
21478297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber
21488297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                bool emulateOutputFlushCompletion =
21498297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    !flushPortAsync(kPortIndexOutput);
2150693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
21518297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                if (emulateInputFlushCompletion) {
21528297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    onCmdComplete(OMX_CommandFlush, kPortIndexInput);
21538297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                }
21548297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber
21558297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                if (emulateOutputFlushCompletion) {
21568297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
21578297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                }
21588297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber            } else {
21598297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
21608297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
21618297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber
21628297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                status_t err =
2163318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                    mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
21648297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                CHECK_EQ(err, OK);
21658297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber            }
2166693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2167693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            while (mState != LOADED && mState != ERROR) {
2168693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mAsyncCompletion.wait(mLock);
2169693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
2170693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2171693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2172693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2173693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2174693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
2175693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2176693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(!"should not be here.");
2177693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2178693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2179693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2180693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2181693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mSource->stop();
2182693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2183693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return OK;
2184693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2185693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2186693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MetaData> OMXCodec::getFormat() {
21877f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber    Mutex::Autolock autoLock(mLock);
21887f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber
2189693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return mOutputFormat;
2190693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2191693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2192693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::read(
2193693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        MediaBuffer **buffer, const ReadOptions *options) {
2194693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    *buffer = NULL;
2195693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2196693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Mutex::Autolock autoLock(mLock);
2197693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2198450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber    if (mState != EXECUTING && mState != RECONFIGURING) {
2199450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber        return UNKNOWN_ERROR;
2200450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber    }
2201450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber
22027e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    bool seeking = false;
22037e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    int64_t seekTimeUs;
22047e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if (options && options->getSeekTo(&seekTimeUs)) {
22057e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        seeking = true;
22067e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
22077e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
2208284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber    if (mInitialBufferSubmit) {
2209284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber        mInitialBufferSubmit = false;
2210284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber
22117e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        if (seeking) {
22127e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            CHECK(seekTimeUs >= 0);
22137e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            mSeekTimeUs = seekTimeUs;
22147e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
22157e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            // There's no reason to trigger the code below, there's
22167e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            // nothing to flush yet.
22177e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            seeking = false;
22187e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        }
22197e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
2220284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber        drainInputBuffers();
2221284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber
2222450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber        if (mState == EXECUTING) {
2223450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber            // Otherwise mState == RECONFIGURING and this code will trigger
2224450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber            // after the output port is reenabled.
2225450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber            fillOutputBuffers();
2226450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber        }
2227693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2228693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
22297e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if (seeking) {
22307a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6);
2231693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2232693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mSignalledEOS = false;
2233693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mNoMoreOutputData = false;
2234693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2235693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(seekTimeUs >= 0);
2236693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mSeekTimeUs = seekTimeUs;
2237693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2238693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mFilledBuffers.clear();
2239693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2240693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(mState, EXECUTING);
2241693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
22421beb760d920561679862ded945a04e370368c7f7Andreas Huber        bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput);
22431beb760d920561679862ded945a04e370368c7f7Andreas Huber        bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput);
22441beb760d920561679862ded945a04e370368c7f7Andreas Huber
22451beb760d920561679862ded945a04e370368c7f7Andreas Huber        if (emulateInputFlushCompletion) {
22461beb760d920561679862ded945a04e370368c7f7Andreas Huber            onCmdComplete(OMX_CommandFlush, kPortIndexInput);
22471beb760d920561679862ded945a04e370368c7f7Andreas Huber        }
22481beb760d920561679862ded945a04e370368c7f7Andreas Huber
22491beb760d920561679862ded945a04e370368c7f7Andreas Huber        if (emulateOutputFlushCompletion) {
22501beb760d920561679862ded945a04e370368c7f7Andreas Huber            onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
22511beb760d920561679862ded945a04e370368c7f7Andreas Huber        }
2252693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2253693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2254693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) {
2255693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mBufferFilled.wait(mLock);
2256693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2257693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2258693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mState == ERROR) {
2259693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return UNKNOWN_ERROR;
2260693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2261693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2262693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mFilledBuffers.empty()) {
2263693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return ERROR_END_OF_STREAM;
2264693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2265693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
22667f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber    if (mOutputPortSettingsHaveChanged) {
22677f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber        mOutputPortSettingsHaveChanged = false;
22687f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber
22697f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber        return INFO_FORMAT_CHANGED;
22707f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber    }
22717f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber
2272693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t index = *mFilledBuffers.begin();
2273693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mFilledBuffers.erase(mFilledBuffers.begin());
2274693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2275693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
2276693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    info->mMediaBuffer->add_ref();
2277693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    *buffer = info->mMediaBuffer;
2278693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2279693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return OK;
2280693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2281693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2282693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::signalBufferReturned(MediaBuffer *buffer) {
2283693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Mutex::Autolock autoLock(mLock);
2284693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2285693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
2286693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
2287693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        BufferInfo *info = &buffers->editItemAt(i);
2288693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2289693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (info->mMediaBuffer == buffer) {
2290693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED);
2291693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            fillOutputBuffer(info);
2292693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            return;
2293693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2294693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2295693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2296693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(!"should not be here.");
2297693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2298693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2299693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) {
2300693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    static const char *kNames[] = {
2301693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingUnused",
2302693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingAutoDetect",
2303693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingJPEG",
2304693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingJPEG2K",
2305693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingEXIF",
2306693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingTIFF",
2307693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingGIF",
2308693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingPNG",
2309693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingLZW",
2310693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingBMP",
2311693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    };
2312693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2313693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2314693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2315693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (type < 0 || (size_t)type >= numNames) {
2316693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return "UNKNOWN";
2317693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
2318693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return kNames[type];
2319693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2320693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2321693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2322693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const char *colorFormatString(OMX_COLOR_FORMATTYPE type) {
2323693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    static const char *kNames[] = {
2324693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatUnused",
2325693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatMonochrome",
2326693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format8bitRGB332",
2327693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format12bitRGB444",
2328693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format16bitARGB4444",
2329693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format16bitARGB1555",
2330693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format16bitRGB565",
2331693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format16bitBGR565",
2332693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format18bitRGB666",
2333693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format18bitARGB1665",
2334bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        "OMX_COLOR_Format19bitARGB1666",
2335693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format24bitRGB888",
2336693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format24bitBGR888",
2337693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format24bitARGB1887",
2338693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format25bitARGB1888",
2339693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format32bitBGRA8888",
2340693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format32bitARGB8888",
2341693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV411Planar",
2342693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV411PackedPlanar",
2343693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV420Planar",
2344693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV420PackedPlanar",
2345693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV420SemiPlanar",
2346693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV422Planar",
2347693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV422PackedPlanar",
2348693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV422SemiPlanar",
2349693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYCbYCr",
2350693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYCrYCb",
2351693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatCbYCrY",
2352693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatCrYCbY",
2353693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV444Interleaved",
2354693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatRawBayer8bit",
2355693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatRawBayer10bit",
2356693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatRawBayer8bitcompressed",
2357bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        "OMX_COLOR_FormatL2",
2358bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        "OMX_COLOR_FormatL4",
2359bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        "OMX_COLOR_FormatL8",
2360bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        "OMX_COLOR_FormatL16",
2361bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        "OMX_COLOR_FormatL24",
2362693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatL32",
2363693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV420PackedSemiPlanar",
2364693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV422PackedSemiPlanar",
2365693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format18BitBGR666",
2366693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format24BitARGB6666",
2367693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format24BitABGR6666",
2368693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    };
2369693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2370693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2371693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2372693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) {
2373693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar";
2374693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else if (type < 0 || (size_t)type >= numNames) {
2375693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return "UNKNOWN";
2376693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
2377693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return kNames[type];
2378693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2379693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2380693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2381693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) {
2382693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    static const char *kNames[] = {
2383693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingUnused",
2384693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingAutoDetect",
2385693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingMPEG2",
2386693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingH263",
2387693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingMPEG4",
2388693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingWMV",
2389693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingRV",
2390693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingAVC",
2391693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingMJPEG",
2392693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    };
2393693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2394693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2395693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2396693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (type < 0 || (size_t)type >= numNames) {
2397693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return "UNKNOWN";
2398693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
2399693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return kNames[type];
2400693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2401693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2402693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2403693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) {
2404693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    static const char *kNames[] = {
2405693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingUnused",
2406693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingAutoDetect",
2407693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingPCM",
2408693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingADPCM",
2409693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingAMR",
2410693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingGSMFR",
2411693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingGSMEFR",
2412693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingGSMHR",
2413693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingPDCFR",
2414693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingPDCEFR",
2415693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingPDCHR",
2416693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingTDMAFR",
2417693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingTDMAEFR",
2418693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingQCELP8",
2419693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingQCELP13",
2420693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingEVRC",
2421693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingSMV",
2422693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingG711",
2423693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingG723",
2424693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingG726",
2425693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingG729",
2426693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingAAC",
2427693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingMP3",
2428693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingSBC",
2429693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingVORBIS",
2430693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingWMA",
2431693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingRA",
2432693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingMIDI",
2433693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    };
2434693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2435693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2436693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2437693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (type < 0 || (size_t)type >= numNames) {
2438693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return "UNKNOWN";
2439693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
2440693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return kNames[type];
2441693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2442693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2443693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2444693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) {
2445693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    static const char *kNames[] = {
2446693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_PCMModeLinear",
2447693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_PCMModeALaw",
2448693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_PCMModeMULaw",
2449693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    };
2450693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2451693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2452693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2453693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (type < 0 || (size_t)type >= numNames) {
2454693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return "UNKNOWN";
2455693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
2456693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return kNames[type];
2457693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2458693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2459693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
24602f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huberstatic const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) {
24612f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    static const char *kNames[] = {
24622f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeUnused",
24632f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB0",
24642f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB1",
24652f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB2",
24662f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB3",
24672f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB4",
24682f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB5",
24692f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB6",
24702f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB7",
24712f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB0",
24722f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB1",
24732f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB2",
24742f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB3",
24752f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB4",
24762f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB5",
24772f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB6",
24782f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB7",
24792f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB8",
24802f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    };
24812f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
24822f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
24832f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
24842f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    if (type < 0 || (size_t)type >= numNames) {
24852f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        return "UNKNOWN";
24862f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    } else {
24872f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        return kNames[type];
24882f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    }
24892f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber}
24902f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
24912f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huberstatic const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) {
24922f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    static const char *kNames[] = {
24932f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRFrameFormatConformance",
24942f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRFrameFormatIF1",
24952f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRFrameFormatIF2",
24962f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRFrameFormatFSF",
24972f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRFrameFormatRTPPayload",
24982f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRFrameFormatITU",
24992f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    };
25002f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
25012f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
25022f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
25032f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    if (type < 0 || (size_t)type >= numNames) {
25042f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        return "UNKNOWN";
25052f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    } else {
25062f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        return kNames[type];
25072f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    }
25082f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber}
2509693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2510693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
2511693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
25127a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
2513693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = portIndex;
2514693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2515318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
2516693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2517693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
2518693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2519693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output");
2520693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2521693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput)
2522693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber          || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput));
2523693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2524693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    printf("  nBufferCountActual = %ld\n", def.nBufferCountActual);
2525693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    printf("  nBufferCountMin = %ld\n", def.nBufferCountMin);
2526693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    printf("  nBufferSize = %ld\n", def.nBufferSize);
2527693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2528693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (def.eDomain) {
2529693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_PortDomainImage:
2530693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2531693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
2532693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2533693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("\n");
2534693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  // Image\n");
2535693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  nFrameWidth = %ld\n", imageDef->nFrameWidth);
2536693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  nFrameHeight = %ld\n", imageDef->nFrameHeight);
2537693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  nStride = %ld\n", imageDef->nStride);
2538693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2539693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  eCompressionFormat = %s\n",
2540693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                   imageCompressionFormatString(imageDef->eCompressionFormat));
2541693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2542693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  eColorFormat = %s\n",
2543693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                   colorFormatString(imageDef->eColorFormat));
2544693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2545693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2546693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2547693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2548693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_PortDomainVideo:
2549693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2550693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
2551693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2552693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("\n");
2553693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  // Video\n");
2554693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  nFrameWidth = %ld\n", videoDef->nFrameWidth);
2555693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  nFrameHeight = %ld\n", videoDef->nFrameHeight);
2556693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  nStride = %ld\n", videoDef->nStride);
2557693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2558693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  eCompressionFormat = %s\n",
2559693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                   videoCompressionFormatString(videoDef->eCompressionFormat));
2560693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2561693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  eColorFormat = %s\n",
2562693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                   colorFormatString(videoDef->eColorFormat));
2563693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2564693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2565693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2566693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2567693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_PortDomainAudio:
2568693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2569693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
2570693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2571693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("\n");
2572693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  // Audio\n");
2573693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  eEncoding = %s\n",
2574693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                   audioCodingTypeString(audioDef->eEncoding));
2575693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2576693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) {
2577693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                OMX_AUDIO_PARAM_PCMMODETYPE params;
25787a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                InitOMXParams(&params);
2579693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                params.nPortIndex = portIndex;
2580693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2581318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                err = mOMX->getParameter(
2582693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
2583693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
2584693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2585693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                printf("  nSamplingRate = %ld\n", params.nSamplingRate);
2586693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                printf("  nChannels = %ld\n", params.nChannels);
2587693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                printf("  bInterleaved = %d\n", params.bInterleaved);
2588693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                printf("  nBitPerSample = %ld\n", params.nBitPerSample);
2589693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2590693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                printf("  eNumData = %s\n",
2591693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                       params.eNumData == OMX_NumericalDataSigned
2592693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        ? "signed" : "unsigned");
2593693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2594693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                printf("  ePCMMode = %s\n", audioPCMModeString(params.ePCMMode));
25952f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber            } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) {
25962f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                OMX_AUDIO_PARAM_AMRTYPE amr;
25972f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                InitOMXParams(&amr);
25982f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                amr.nPortIndex = portIndex;
25992f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
2600318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                err = mOMX->getParameter(
26012f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                        mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
26022f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                CHECK_EQ(err, OK);
26032f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
26042f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                printf("  nChannels = %ld\n", amr.nChannels);
26052f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                printf("  eAMRBandMode = %s\n",
26062f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                        amrBandModeString(amr.eAMRBandMode));
26072f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                printf("  eAMRFrameFormat = %s\n",
26082f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                        amrFrameFormatString(amr.eAMRFrameFormat));
2609693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
2610693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2611693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2612693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2613693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2614693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
2615693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2616693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  // Unknown\n");
2617693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2618693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2619693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2620693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2621693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    printf("}\n");
2622693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2623693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2624693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
2625693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mOutputFormat = new MetaData;
2626693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mOutputFormat->setCString(kKeyDecoderComponent, mComponentName);
2627693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2628693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
26297a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
2630693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexOutput;
2631693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2632318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
2633693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2634693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
2635693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2636693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (def.eDomain) {
2637693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_PortDomainImage:
2638693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2639693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
2640693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused);
2641693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
264218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
2643693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat);
2644693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth);
2645693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight);
2646693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2647693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2648693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2649693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_PortDomainAudio:
2650693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2651693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio;
2652693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2653e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) {
2654e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                OMX_AUDIO_PARAM_PCMMODETYPE params;
26557a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                InitOMXParams(&params);
2656e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                params.nPortIndex = kPortIndexOutput;
2657693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2658318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                err = mOMX->getParameter(
2659e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                        mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
2660e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                CHECK_EQ(err, OK);
2661693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2662e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                CHECK_EQ(params.eNumData, OMX_NumericalDataSigned);
2663e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                CHECK_EQ(params.nBitPerSample, 16);
2664e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                CHECK_EQ(params.ePCMMode, OMX_AUDIO_PCMModeLinear);
2665693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2666e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                int32_t numChannels, sampleRate;
2667e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                inputFormat->findInt32(kKeyChannelCount, &numChannels);
2668e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                inputFormat->findInt32(kKeySampleRate, &sampleRate);
2669693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2670e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                if ((OMX_U32)numChannels != params.nChannels) {
2671e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                    LOGW("Codec outputs a different number of channels than "
2672e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                         "the input stream contains.");
2673e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                }
267437940eefcba982836b579fe1ffec6cada72b0974Andreas Huber
267518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                mOutputFormat->setCString(
267618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
267737940eefcba982836b579fe1ffec6cada72b0974Andreas Huber
2678e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                // Use the codec-advertised number of channels, as some
2679e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                // codecs appear to output stereo even if the input data is
2680e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                // mono.
2681e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                mOutputFormat->setInt32(kKeyChannelCount, params.nChannels);
268237940eefcba982836b579fe1ffec6cada72b0974Andreas Huber
2683e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                // The codec-reported sampleRate is not reliable...
2684e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                mOutputFormat->setInt32(kKeySampleRate, sampleRate);
2685e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) {
26862f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                OMX_AUDIO_PARAM_AMRTYPE amr;
26872f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                InitOMXParams(&amr);
26882f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                amr.nPortIndex = kPortIndexOutput;
26892f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
2690318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                err = mOMX->getParameter(
26912f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                        mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
26922f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                CHECK_EQ(err, OK);
26932f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
26942f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                CHECK_EQ(amr.nChannels, 1);
26952f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                mOutputFormat->setInt32(kKeyChannelCount, 1);
26962f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
26972f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0
26982f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                    && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) {
269918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    mOutputFormat->setCString(
270018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                            kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB);
27012f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                    mOutputFormat->setInt32(kKeySampleRate, 8000);
27022f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0
27032f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                            && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) {
270418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    mOutputFormat->setCString(
270518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                            kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB);
27062f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                    mOutputFormat->setInt32(kKeySampleRate, 16000);
27072f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                } else {
27082f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                    CHECK(!"Unknown AMR band mode.");
27092f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                }
2710e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) {
271118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                mOutputFormat->setCString(
271218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
2713e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            } else {
2714e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                CHECK(!"Should not be here. Unknown audio encoding.");
2715e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            }
2716693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2717693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2718693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2719693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_PortDomainVideo:
2720693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2721693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2722693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2723693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) {
272418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                mOutputFormat->setCString(
272518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
2726693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) {
272718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                mOutputFormat->setCString(
272818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
2729693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) {
273018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                mOutputFormat->setCString(
273118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
2732693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) {
273318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                mOutputFormat->setCString(
273418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
2735693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else {
2736693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK(!"Unknown compression format.");
2737693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
2738693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2739693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (!strcmp(mComponentName, "OMX.PV.avcdec")) {
2740693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                // This component appears to be lying to me.
2741693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mOutputFormat->setInt32(
2742693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        kKeyWidth, (video_def->nFrameWidth + 15) & -16);
2743693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mOutputFormat->setInt32(
2744693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        kKeyHeight, (video_def->nFrameHeight + 15) & -16);
2745693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else {
2746693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth);
2747693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight);
2748693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
2749693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2750693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat);
2751693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2752693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2753693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2754693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
2755693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2756693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(!"should not be here, neither audio nor video.");
2757693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2758693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2759693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2760693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2761693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
276218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber////////////////////////////////////////////////////////////////////////////////
276318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
276418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatus_t QueryCodecs(
276518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        const sp<IOMX> &omx,
276618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        const char *mime, bool queryDecoders,
276718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        Vector<CodecCapabilities> *results) {
276818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    results->clear();
276918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
277018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    for (int index = 0;; ++index) {
277118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        const char *componentName;
277218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
277318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        if (!queryDecoders) {
277418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            componentName = GetCodec(
277518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    kEncoderInfo, sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]),
277618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    mime, index);
277718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        } else {
277818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            componentName = GetCodec(
277918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    kDecoderInfo, sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]),
278018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    mime, index);
278118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        }
278218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
278318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        if (!componentName) {
278418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            return OK;
278518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        }
278618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
2787318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        sp<OMXCodecObserver> observer = new OMXCodecObserver;
278818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        IOMX::node_id node;
2789318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        status_t err = omx->allocateNode(componentName, observer, &node);
279018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
279118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        if (err != OK) {
279218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            continue;
279318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        }
279418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
279518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        OMXCodec::setComponentRole(omx, node, queryDecoders, mime);
279618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
279718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        results->push();
279818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        CodecCapabilities *caps = &results->editItemAt(results->size() - 1);
279918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        caps->mComponentName = componentName;
280018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
280118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
280218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        InitOMXParams(&param);
280318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
280418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        param.nPortIndex = queryDecoders ? 0 : 1;
280518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
280618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
2807318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            err = omx->getParameter(
280818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    node, OMX_IndexParamVideoProfileLevelQuerySupported,
280918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    &param, sizeof(param));
281018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
281118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            if (err != OK) {
281218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                break;
281318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            }
281418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
281518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            CodecProfileLevel profileLevel;
281618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            profileLevel.mProfile = param.eProfile;
281718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            profileLevel.mLevel = param.eLevel;
281818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
281918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            caps->mProfileLevels.push(profileLevel);
282018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        }
282118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
2822318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        CHECK_EQ(omx->freeNode(node), OK);
282318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    }
282418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber}
282518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
2826693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}  // namespace android
2827