OMXCodec.cpp revision ee7ff20e69498ebd53dd9717a0f984188341a75e
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
21f44de515d3b6098a0b585865c1a0c7b20d3075a6Andreas Huber#include "include/AACDecoder.h"
224f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber#include "include/AMRNBDecoder.h"
23b841f14f8e51f2365945281fbfa54ef6a1b1b5a6Andreas Huber#include "include/AMRNBEncoder.h"
244f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber#include "include/AMRWBDecoder.h"
25609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#include "include/AVCDecoder.h"
263306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include "include/M4vH263Decoder.h"
27d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "include/MP3Decoder.h"
28ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber#include "include/VorbisDecoder.h"
2992616b5655b7aef260480f60f2aabf98e821c8f3Andreas Huber
3089e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "include/ESDS.h"
3189e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber
32693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <binder/IServiceManager.h>
33693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <binder/MemoryDealer.h>
34693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <binder/ProcessState.h>
35693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/IMediaPlayerService.h>
36693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MediaBuffer.h>
37693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MediaBufferGroup.h>
38693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MediaDebug.h>
3918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h>
40693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MediaExtractor.h>
41693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MetaData.h>
42693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/OMXCodec.h>
43bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber#include <media/stagefright/Utils.h>
44693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <utils/Vector.h>
45693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
46693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <OMX_Audio.h>
47693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <OMX_Component.h>
48693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
49693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubernamespace android {
50693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
51ec430b158df17b2c766f7750a96c35d3902f5f49Andreas Huberstatic const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
52ec430b158df17b2c766f7750a96c35d3902f5f49Andreas Huber
53693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstruct CodecInfo {
54693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    const char *mime;
55693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    const char *codec;
56693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber};
57693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
581af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber#define FACTORY_CREATE(name) \
591af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huberstatic sp<MediaSource> Make##name(const sp<MediaSource> &source) { \
601af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    return new name(source); \
611af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber}
621af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
631af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber#define FACTORY_REF(name) { #name, Make##name },
641af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
651af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas HuberFACTORY_CREATE(MP3Decoder)
661af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas HuberFACTORY_CREATE(AMRNBDecoder)
671af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas HuberFACTORY_CREATE(AMRWBDecoder)
681af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas HuberFACTORY_CREATE(AACDecoder)
691af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas HuberFACTORY_CREATE(AVCDecoder)
703306cfee3bf38ab207a0504e49c2d492bb73ffbfJames DongFACTORY_CREATE(M4vH263Decoder)
71ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas HuberFACTORY_CREATE(VorbisDecoder)
721af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas HuberFACTORY_CREATE(AMRNBEncoder)
731af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
741af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huberstatic sp<MediaSource> InstantiateSoftwareCodec(
751af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        const char *name, const sp<MediaSource> &source) {
761af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    struct FactoryInfo {
771af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        const char *name;
781af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        sp<MediaSource> (*CreateFunc)(const sp<MediaSource> &);
791af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    };
801af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
811af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    static const FactoryInfo kFactoryInfo[] = {
821af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        FACTORY_REF(MP3Decoder)
831af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        FACTORY_REF(AMRNBDecoder)
841af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        FACTORY_REF(AMRWBDecoder)
851af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        FACTORY_REF(AACDecoder)
861af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        FACTORY_REF(AVCDecoder)
873306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        FACTORY_REF(M4vH263Decoder)
88ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber        FACTORY_REF(VorbisDecoder)
891af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        FACTORY_REF(AMRNBEncoder)
901af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    };
911af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    for (size_t i = 0;
921af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber         i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) {
931af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        if (!strcmp(name, kFactoryInfo[i].name)) {
941af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber            return (*kFactoryInfo[i].CreateFunc)(source);
951af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        }
961af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    }
971af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
981af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    return NULL;
991af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber}
1001af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
1011af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber#undef FACTORY_REF
1021af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber#undef FACTORY_CREATE
1031af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
104693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const CodecInfo kDecoderInfo[] = {
10518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_IMAGE_JPEG, "OMX.TI.JPEG.decode" },
1060b5ba9eeed56a80fed3735f5cd4951477fda79f0James Dong//    { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" },
107b25e2a948c8b5a96e284069a908c2fddb49efc48Andreas Huber    { MEDIA_MIMETYPE_AUDIO_MPEG, "MP3Decoder" },
10808a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber//    { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.PV.mp3dec" },
1097f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber//    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.decode" },
110b25e2a948c8b5a96e284069a908c2fddb49efc48Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBDecoder" },
11108a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber//    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.PV.amrdec" },
11218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.decode" },
113b25e2a948c8b5a96e284069a908c2fddb49efc48Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "AMRWBDecoder" },
11408a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber//    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.PV.amrdec" },
11518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.decode" },
116b25e2a948c8b5a96e284069a908c2fddb49efc48Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AAC, "AACDecoder" },
11708a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber//    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacdec" },
11818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.decoder.mpeg4" },
11918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.Decoder" },
120b25e2a948c8b5a96e284069a908c2fddb49efc48Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, "M4vH263Decoder" },
12108a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber//    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4dec" },
12218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.decoder.h263" },
123b25e2a948c8b5a96e284069a908c2fddb49efc48Andreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, "M4vH263Decoder" },
12408a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber//    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263dec" },
12518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" },
12618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.Decoder" },
127b25e2a948c8b5a96e284069a908c2fddb49efc48Andreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, "AVCDecoder" },
12808a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber//    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcdec" },
129ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber    { MEDIA_MIMETYPE_AUDIO_VORBIS, "VorbisDecoder" },
130693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber};
131693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
132693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const CodecInfo kEncoderInfo[] = {
13318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.encode" },
134b25e2a948c8b5a96e284069a908c2fddb49efc48Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBEncoder" },
13518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.encode" },
13618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.encode" },
13718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacenc" },
13818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.encoder.mpeg4" },
13918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.encoder" },
14018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4enc" },
14118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.encoder.h263" },
14218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.encoder" },
14318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263enc" },
14418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.encoder" },
14518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcenc" },
146693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber};
147693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1481af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber#undef OPTIONAL
1491af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
1508cd11d23197209e2c2bdb7980bc17e3f1257a118Andreas Huber#define CODEC_LOGI(x, ...) LOGI("[%s] "x, mComponentName, ##__VA_ARGS__)
1517a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber#define CODEC_LOGV(x, ...) LOGV("[%s] "x, mComponentName, ##__VA_ARGS__)
152c017cfcc24dd63c7efde5747a6ed2d4053788abcAndreas Huber#define CODEC_LOGE(x, ...) LOGE("[%s] "x, mComponentName, ##__VA_ARGS__)
1537a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
154693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstruct OMXCodecObserver : public BnOMXObserver {
155318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMXCodecObserver() {
156318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
157318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
158318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    void setCodec(const sp<OMXCodec> &target) {
159318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        mTarget = target;
160693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
161693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
162693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    // from IOMXObserver
163318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    virtual void onMessage(const omx_message &msg) {
164693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        sp<OMXCodec> codec = mTarget.promote();
165693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
166693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (codec.get() != NULL) {
167693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            codec->on_message(msg);
168693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
169693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
170693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
171693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected:
172693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    virtual ~OMXCodecObserver() {}
173693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
174693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprivate:
175693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    wp<OMXCodec> mTarget;
176693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
177693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMXCodecObserver(const OMXCodecObserver &);
178693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMXCodecObserver &operator=(const OMXCodecObserver &);
179693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber};
180693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
181693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const char *GetCodec(const CodecInfo *info, size_t numInfos,
182693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                            const char *mime, int index) {
183693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(index >= 0);
184693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for(size_t i = 0; i < numInfos; ++i) {
185693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (!strcasecmp(mime, info[i].mime)) {
186693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (index == 0) {
187693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                return info[i].codec;
188693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
189693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
190693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            --index;
191693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
192693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
193693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
194693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return NULL;
195693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
196693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
197bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huberenum {
198bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileBaseline      = 0x42,
199bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileMain          = 0x4d,
200bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileExtended      = 0x58,
201bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileHigh          = 0x64,
202bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileHigh10        = 0x6e,
203bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileHigh422       = 0x7a,
204bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileHigh444       = 0xf4,
205bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileCAVLC444Intra = 0x2c
206bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber};
207bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
208bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huberstatic const char *AVCProfileToString(uint8_t profile) {
209bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    switch (profile) {
210bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileBaseline:
211bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "Baseline";
212bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileMain:
213bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "Main";
214bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileExtended:
215bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "Extended";
216bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileHigh:
217bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "High";
218bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileHigh10:
219bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "High 10";
220bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileHigh422:
221bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "High 422";
222bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileHigh444:
223bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "High 444";
224bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileCAVLC444Intra:
225bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "CAVLC 444 Intra";
226bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        default:   return "Unknown";
227bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    }
228bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber}
229bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
2307a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Hubertemplate<class T>
2317a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huberstatic void InitOMXParams(T *params) {
2327a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nSize = sizeof(T);
2337a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nVersion.s.nVersionMajor = 1;
2347a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nVersion.s.nVersionMinor = 0;
2357a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nVersion.s.nRevision = 0;
2367a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nVersion.s.nStep = 0;
2377a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber}
2387a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
239ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huberstatic bool IsSoftwareCodec(const char *componentName) {
240ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (!strncmp("OMX.PV.", componentName, 7)) {
241ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        return true;
242ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
243693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
244ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    return false;
245ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber}
246693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2471af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber// A sort order in which non-OMX components are first,
2481af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber// followed by software codecs, i.e. OMX.PV.*, followed
2491af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber// by all the others.
250ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huberstatic int CompareSoftwareCodecsFirst(
251ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const String8 *elem1, const String8 *elem2) {
2521af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    bool isNotOMX1 = strncmp(elem1->string(), "OMX.", 4);
2531af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    bool isNotOMX2 = strncmp(elem2->string(), "OMX.", 4);
2541af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
2551af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    if (isNotOMX1) {
2561af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        if (isNotOMX2) { return 0; }
2571af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        return -1;
2581af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    }
2591af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    if (isNotOMX2) {
2601af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        return 1;
2611af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    }
2621af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
263ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    bool isSoftwareCodec1 = IsSoftwareCodec(elem1->string());
264ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    bool isSoftwareCodec2 = IsSoftwareCodec(elem2->string());
265693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
266ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (isSoftwareCodec1) {
267ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        if (isSoftwareCodec2) { return 0; }
268ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        return -1;
269ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
270693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
271ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (isSoftwareCodec2) {
272ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        return 1;
273693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
274693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
275ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    return 0;
276ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber}
277ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
278ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber// static
279ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huberuint32_t OMXCodec::getComponentQuirks(const char *componentName) {
280693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    uint32_t quirks = 0;
281ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
282693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!strcmp(componentName, "OMX.PV.avcdec")) {
283dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        quirks |= kWantsNALFragments;
284693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
285693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!strcmp(componentName, "OMX.TI.MP3.decode")) {
286693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        quirks |= kNeedsFlushBeforeDisable;
28778d529eb330ab6c04b5c694403f5a7e7de4b702fAndreas Huber        quirks |= kDecoderLiesAboutNumberOfChannels;
288693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
289693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!strcmp(componentName, "OMX.TI.AAC.decode")) {
290693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        quirks |= kNeedsFlushBeforeDisable;
2911beb760d920561679862ded945a04e370368c7f7Andreas Huber        quirks |= kRequiresFlushCompleteEmulation;
2927f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber        quirks |= kSupportsMultipleFramesPerInputBuffer;
293693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
294693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!strncmp(componentName, "OMX.qcom.video.encoder.", 23)) {
295693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        quirks |= kRequiresLoadedToIdleAfterAllocation;
296693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        quirks |= kRequiresAllocateBufferOnInputPorts;
297888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        quirks |= kRequiresAllocateBufferOnOutputPorts;
298693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
299b7802d9ee9c9dbb471ae4f010bd67ba1aaa9f264Andreas Huber    if (!strncmp(componentName, "OMX.qcom.video.decoder.", 23)) {
300b7802d9ee9c9dbb471ae4f010bd67ba1aaa9f264Andreas Huber        quirks |= kRequiresAllocateBufferOnOutputPorts;
301213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber        quirks |= kDefersOutputBufferAllocation;
302b7802d9ee9c9dbb471ae4f010bd67ba1aaa9f264Andreas Huber    }
303693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
304df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber    if (!strncmp(componentName, "OMX.TI.", 7)) {
305df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber        // Apparently I must not use OMX_UseBuffer on either input or
306df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber        // output ports on any of the TI components or quote:
307df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber        // "(I) may have unexpected problem (sic) which can be timing related
308df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber        //  and hard to reproduce."
309df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber
310df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber        quirks |= kRequiresAllocateBufferOnInputPorts;
311df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber        quirks |= kRequiresAllocateBufferOnOutputPorts;
312df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber    }
313df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber
31486559de0275b46a9bdba06b749fbd549ad2022d1Andreas Huber    if (!strcmp(componentName, "OMX.TI.Video.Decoder")) {
31586559de0275b46a9bdba06b749fbd549ad2022d1Andreas Huber        quirks |= kInputBufferSizesAreBogus;
31686559de0275b46a9bdba06b749fbd549ad2022d1Andreas Huber    }
31786559de0275b46a9bdba06b749fbd549ad2022d1Andreas Huber
318ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    return quirks;
319ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber}
320ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
321ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber// static
322ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Hubervoid OMXCodec::findMatchingCodecs(
323ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const char *mime,
324ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        bool createEncoder, const char *matchComponentName,
325ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        uint32_t flags,
326ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        Vector<String8> *matchingCodecs) {
327ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    matchingCodecs->clear();
328ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
329ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    for (int index = 0;; ++index) {
330ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const char *componentName;
331ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
332ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        if (createEncoder) {
333ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            componentName = GetCodec(
334ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber                    kEncoderInfo,
335ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber                    sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]),
336ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber                    mime, index);
337ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        } else {
338ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            componentName = GetCodec(
339ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber                    kDecoderInfo,
340ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber                    sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]),
341ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber                    mime, index);
342ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        }
343ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
344ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        if (!componentName) {
345ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            break;
346ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        }
347ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
348ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        // If a specific codec is requested, skip the non-matching ones.
349ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        if (matchComponentName && strcmp(componentName, matchComponentName)) {
350ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            continue;
351ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        }
352ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
353ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        matchingCodecs->push(String8(componentName));
354ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
355ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
356ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (flags & kPreferSoftwareCodecs) {
357ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        matchingCodecs->sort(CompareSoftwareCodecsFirst);
358ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
359ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber}
360ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
361ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber// static
362bf697e37550d9e8376089b0b5e498613bede798cAndreas Hubersp<MediaSource> OMXCodec::Create(
363ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const sp<IOMX> &omx,
364ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const sp<MetaData> &meta, bool createEncoder,
365ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const sp<MediaSource> &source,
366ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const char *matchComponentName,
367ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        uint32_t flags) {
368ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    const char *mime;
369ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    bool success = meta->findCString(kKeyMIMEType, &mime);
370ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    CHECK(success);
371ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
372ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    Vector<String8> matchingCodecs;
373ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    findMatchingCodecs(
374ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            mime, createEncoder, matchComponentName, flags, &matchingCodecs);
375ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
376ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (matchingCodecs.isEmpty()) {
377ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        return NULL;
378ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
379ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
380ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    sp<OMXCodecObserver> observer = new OMXCodecObserver;
381ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    IOMX::node_id node = 0;
382ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
383ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    const char *componentName;
384ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    for (size_t i = 0; i < matchingCodecs.size(); ++i) {
385ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        componentName = matchingCodecs[i].string();
386ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
3871af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber#if BUILD_WITH_FULL_STAGEFRIGHT
3881af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        sp<MediaSource> softwareCodec =
3891af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber            InstantiateSoftwareCodec(componentName, source);
3901af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
3911af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        if (softwareCodec != NULL) {
3921af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber            LOGV("Successfully allocated software codec '%s'", componentName);
3931af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
3941af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber            return softwareCodec;
3951af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        }
3961af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber#endif
3971af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
398ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        LOGV("Attempting to allocate OMX node '%s'", componentName);
399ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
400ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        status_t err = omx->allocateNode(componentName, observer, &node);
401ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        if (err == OK) {
402ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            LOGV("Successfully allocated OMX node '%s'", componentName);
403ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
4042a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber            sp<OMXCodec> codec = new OMXCodec(
4052a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber                    omx, node, getComponentQuirks(componentName),
4062a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber                    createEncoder, mime, componentName,
4072a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber                    source);
408ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
4092a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber            observer->setCodec(codec);
4102a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber
4112a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber            err = codec->configureCodec(meta);
4122a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber
4132a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber            if (err == OK) {
4142a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber                return codec;
4152a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber            }
416ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
4172a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber            LOGV("Failed to configure codec '%s'", componentName);
4182a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        }
4192a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber    }
420693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
4212a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber    return NULL;
4222a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber}
423318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
4242a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huberstatus_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
425693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    uint32_t type;
426693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    const void *data;
427693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t size;
428693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (meta->findData(kKeyESDS, &type, &data, &size)) {
429693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        ESDS esds((const char *)data, size);
430693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(esds.InitCheck(), OK);
431693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
432693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const void *codec_specific_data;
433693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        size_t codec_specific_data_size;
434693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        esds.getCodecSpecificInfo(
435693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                &codec_specific_data, &codec_specific_data_size);
436693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
4372a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        addCodecSpecificData(
438693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                codec_specific_data, codec_specific_data_size);
439693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else if (meta->findData(kKeyAVCC, &type, &data, &size)) {
440bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        // Parse the AVCDecoderConfigurationRecord
441bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
442bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        const uint8_t *ptr = (const uint8_t *)data;
443bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
444bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        CHECK(size >= 7);
445bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        CHECK_EQ(ptr[0], 1);  // configurationVersion == 1
446bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        uint8_t profile = ptr[1];
447bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        uint8_t level = ptr[3];
448bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
449e5d6df402da9b6c5577470abb81a5e6801bd7752Andreas Huber        // There is decodable content out there that fails the following
450e5d6df402da9b6c5577470abb81a5e6801bd7752Andreas Huber        // assertion, let's be lenient for now...
451e5d6df402da9b6c5577470abb81a5e6801bd7752Andreas Huber        // CHECK((ptr[4] >> 2) == 0x3f);  // reserved
452bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
453bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        size_t lengthSize = 1 + (ptr[4] & 3);
454bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
455bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
456bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        // violates it...
457bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        // CHECK((ptr[5] >> 5) == 7);  // reserved
458bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
459bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        size_t numSeqParameterSets = ptr[5] & 31;
460bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
461bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        ptr += 6;
462693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        size -= 6;
463bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
464bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        for (size_t i = 0; i < numSeqParameterSets; ++i) {
465bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            CHECK(size >= 2);
466bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            size_t length = U16_AT(ptr);
467693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
468693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            ptr += 2;
469693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            size -= 2;
470693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
471bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            CHECK(size >= length);
472bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
4732a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber            addCodecSpecificData(ptr, length);
474bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
475bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            ptr += length;
476bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            size -= length;
477bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        }
478bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
479bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        CHECK(size >= 1);
480bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        size_t numPictureParameterSets = *ptr;
481bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        ++ptr;
482bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        --size;
483bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
484bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        for (size_t i = 0; i < numPictureParameterSets; ++i) {
485bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            CHECK(size >= 2);
486bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            size_t length = U16_AT(ptr);
487bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
488bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            ptr += 2;
489bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            size -= 2;
490693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
491693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(size >= length);
492693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
4932a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber            addCodecSpecificData(ptr, length);
494693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
495693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            ptr += length;
496693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            size -= length;
497bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        }
498693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
4992a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber        LOGV("AVC profile = %d (%s), level = %d",
500bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber             (int)profile, AVCProfileToString(profile), (int)level / 10);
501693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
5022a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        if (!strcmp(mComponentName, "OMX.TI.Video.Decoder")
503bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            && (profile != kAVCProfileBaseline || level > 39)) {
504318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            // This stream exceeds the decoder's capabilities. The decoder
505318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            // does not handle this gracefully and would clobber the heap
506318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            // and wreak havoc instead...
507bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
508bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            LOGE("Profile and/or level exceed the decoder's capabilities.");
5092a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber            return ERROR_UNSUPPORTED;
510693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
511693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
512693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
5132a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mMIME)) {
5142a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        setAMRFormat(false /* isWAMR */);
515693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
5162a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mMIME)) {
5172a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        setAMRFormat(true /* isWAMR */);
518456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber    }
5192a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mMIME)) {
52037940eefcba982836b579fe1ffec6cada72b0974Andreas Huber        int32_t numChannels, sampleRate;
52137940eefcba982836b579fe1ffec6cada72b0974Andreas Huber        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
52237940eefcba982836b579fe1ffec6cada72b0974Andreas Huber        CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
52337940eefcba982836b579fe1ffec6cada72b0974Andreas Huber
5242a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        setAACFormat(numChannels, sampleRate);
525693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
5262a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber    if (!strncasecmp(mMIME, "video/", 6)) {
527693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        int32_t width, height;
528693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        bool success = meta->findInt32(kKeyWidth, &width);
529693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        success = success && meta->findInt32(kKeyHeight, &height);
5307530e9c708275c273c134c36c68179f511c1940eAndreas Huber        CHECK(success);
531693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
5322a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        if (mIsEncoder) {
5332a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber            setVideoInputFormat(mMIME, width, height);
534693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        } else {
5352a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber            status_t err = setVideoOutputFormat(
5362a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber                    mMIME, width, height);
5372a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber
5382a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber            if (err != OK) {
5392a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber                return err;
5402a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber            }
541693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
542693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
5437f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber
5442a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber    if (!strcasecmp(mMIME, MEDIA_MIMETYPE_IMAGE_JPEG)
5452a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        && !strcmp(mComponentName, "OMX.TI.JPEG.decode")) {
546693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_COLOR_FORMATTYPE format =
547693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_COLOR_Format32bitARGB8888;
548693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            // OMX_COLOR_FormatYUV420PackedPlanar;
549693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            // OMX_COLOR_FormatCbYCrY;
550693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            // OMX_COLOR_FormatYUV411Planar;
551693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
552693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        int32_t width, height;
553693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        bool success = meta->findInt32(kKeyWidth, &width);
554693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        success = success && meta->findInt32(kKeyHeight, &height);
5557530e9c708275c273c134c36c68179f511c1940eAndreas Huber
5567530e9c708275c273c134c36c68179f511c1940eAndreas Huber        int32_t compressedSize;
5577530e9c708275c273c134c36c68179f511c1940eAndreas Huber        success = success && meta->findInt32(
558e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                kKeyMaxInputSize, &compressedSize);
5597530e9c708275c273c134c36c68179f511c1940eAndreas Huber
5607530e9c708275c273c134c36c68179f511c1940eAndreas Huber        CHECK(success);
5617530e9c708275c273c134c36c68179f511c1940eAndreas Huber        CHECK(compressedSize > 0);
562693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
5632a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        setImageOutputFormat(format, width, height);
5642a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        setJPEGInputFormat(width, height, (OMX_U32)compressedSize);
565693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
566693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
567e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    int32_t maxInputSize;
568738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber    if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
5692a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        setMinBufferSize(kPortIndexInput, (OMX_U32)maxInputSize);
570e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
571e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
5722a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber    if (!strcmp(mComponentName, "OMX.TI.AMR.encode")
5732a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        || !strcmp(mComponentName, "OMX.TI.WBAMR.encode")) {
5742a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        setMinBufferSize(kPortIndexOutput, 8192);  // XXX
575e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
576e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
5772a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber    initOutputFormat(meta);
578693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
5792a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber    return OK;
580693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
581693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
582e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Hubervoid OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) {
583e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
5847a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
585e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    def.nPortIndex = portIndex;
586e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
587318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
588e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
589e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    CHECK_EQ(err, OK);
590e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
59186559de0275b46a9bdba06b749fbd549ad2022d1Andreas Huber    if ((portIndex == kPortIndexInput && (mQuirks & kInputBufferSizesAreBogus))
59286559de0275b46a9bdba06b749fbd549ad2022d1Andreas Huber        || (def.nBufferSize < size)) {
593e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        def.nBufferSize = size;
594e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
595e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
596318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
597e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
598e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    CHECK_EQ(err, OK);
599738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber
600738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber    err = mOMX->getParameter(
601738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
602738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber    CHECK_EQ(err, OK);
603738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber
604738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber    // Make sure the setting actually stuck.
60586559de0275b46a9bdba06b749fbd549ad2022d1Andreas Huber    if (portIndex == kPortIndexInput
60686559de0275b46a9bdba06b749fbd549ad2022d1Andreas Huber            && (mQuirks & kInputBufferSizesAreBogus)) {
60786559de0275b46a9bdba06b749fbd549ad2022d1Andreas Huber        CHECK_EQ(def.nBufferSize, size);
60886559de0275b46a9bdba06b749fbd549ad2022d1Andreas Huber    } else {
60986559de0275b46a9bdba06b749fbd549ad2022d1Andreas Huber        CHECK(def.nBufferSize >= size);
61086559de0275b46a9bdba06b749fbd549ad2022d1Andreas Huber    }
611e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber}
612e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
613693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::setVideoPortFormatType(
614693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_U32 portIndex,
615693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
616693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
617693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
6187a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&format);
619693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    format.nPortIndex = portIndex;
620693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    format.nIndex = 0;
621693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    bool found = false;
622693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
623693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_U32 index = 0;
624693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (;;) {
625693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        format.nIndex = index;
626318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        status_t err = mOMX->getParameter(
627693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
628693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                &format, sizeof(format));
629693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
630693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (err != OK) {
631693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            return err;
632693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
633693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
634693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        // The following assertion is violated by TI's video decoder.
6357530e9c708275c273c134c36c68179f511c1940eAndreas Huber        // CHECK_EQ(format.nIndex, index);
636693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
637693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#if 1
6382a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber        CODEC_LOGV("portIndex: %ld, index: %ld, eCompressionFormat=%d eColorFormat=%d",
639693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber             portIndex,
640693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber             index, format.eCompressionFormat, format.eColorFormat);
641693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#endif
642693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
643693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName)) {
644693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (portIndex == kPortIndexInput
645693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    && colorFormat == format.eColorFormat) {
646693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                // eCompressionFormat does not seem right.
647693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                found = true;
648693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                break;
649693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
650693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (portIndex == kPortIndexOutput
651693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
652693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                // eColorFormat does not seem right.
653693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                found = true;
654693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                break;
655693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
656693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
657693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
658693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (format.eCompressionFormat == compressionFormat
659693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            && format.eColorFormat == colorFormat) {
660693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            found = true;
661693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
662693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
663693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
664693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        ++index;
665693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
666693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
667693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!found) {
668693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return UNKNOWN_ERROR;
669693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
670693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
6712a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    CODEC_LOGV("found a match.");
672318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->setParameter(
673693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
674693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            &format, sizeof(format));
675693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
676693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return err;
677693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
678693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
679888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huberstatic size_t getFrameSize(
680888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat, int32_t width, int32_t height) {
681888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    switch (colorFormat) {
682888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        case OMX_COLOR_FormatYCbYCr:
683888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        case OMX_COLOR_FormatCbYCrY:
684888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            return width * height * 2;
685888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
686888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        case OMX_COLOR_FormatYUV420SemiPlanar:
687888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            return (width * height * 3) / 2;
688888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
689888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        default:
690888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            CHECK(!"Should not be here. Unsupported color format.");
691888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            break;
692888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    }
693888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber}
694888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
695693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::setVideoInputFormat(
696693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const char *mime, OMX_U32 width, OMX_U32 height) {
6972a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    CODEC_LOGV("setVideoInputFormat width=%ld, height=%ld", width, height);
698693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
699693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
70018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
701693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        compressionFormat = OMX_VIDEO_CodingAVC;
70218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
703693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        compressionFormat = OMX_VIDEO_CodingMPEG4;
70418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
705693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        compressionFormat = OMX_VIDEO_CodingH263;
706693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
707693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        LOGE("Not a supported video mime type: %s", mime);
708693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(!"Should not be here. Not a supported video mime type.");
709693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
710693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
71130ab66297501757d745b9ae10da61adcd891f497Andreas Huber    OMX_COLOR_FORMATTYPE colorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
71230ab66297501757d745b9ae10da61adcd891f497Andreas Huber    if (!strcasecmp("OMX.TI.Video.encoder", mComponentName)) {
71330ab66297501757d745b9ae10da61adcd891f497Andreas Huber        colorFormat = OMX_COLOR_FormatYCbYCr;
714693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
715693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
716888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(setVideoPortFormatType(
717693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused,
718888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            colorFormat), OK);
719693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
720888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(setVideoPortFormatType(
721888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused),
722888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            OK);
723693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
724693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
7257a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
726693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexOutput;
727693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
7287a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
7297a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
730318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
731693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
732693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
733693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
734693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
735693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
736693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameWidth = width;
737693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameHeight = height;
738693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
739693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->eCompressionFormat = compressionFormat;
740693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
741693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
742318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
743693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
744693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
745693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
746693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    ////////////////////////////////////////////////////////////////////////////
747693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
7487a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
749693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexInput;
750693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
751318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->getParameter(
752693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
753693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
754693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
755888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    def.nBufferSize = getFrameSize(colorFormat, width, height);
7562a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    CODEC_LOGV("Setting nBufferSize = %ld", def.nBufferSize);
757693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
758693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
759693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
760693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameWidth = width;
761693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameHeight = height;
762693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
763693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->eColorFormat = colorFormat;
764693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
765888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    video_def->xFramerate = 24 << 16;  // XXX crucial!
766888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
767318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
768693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
769693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
770888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
771888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    switch (compressionFormat) {
772888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        case OMX_VIDEO_CodingMPEG4:
773888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        {
774888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            CHECK_EQ(setupMPEG4EncoderParameters(), OK);
775888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            break;
776888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        }
777888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
778888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        case OMX_VIDEO_CodingH263:
779888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            break;
780888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
78130ab66297501757d745b9ae10da61adcd891f497Andreas Huber        case OMX_VIDEO_CodingAVC:
78230ab66297501757d745b9ae10da61adcd891f497Andreas Huber        {
78330ab66297501757d745b9ae10da61adcd891f497Andreas Huber            CHECK_EQ(setupAVCEncoderParameters(), OK);
78430ab66297501757d745b9ae10da61adcd891f497Andreas Huber            break;
78530ab66297501757d745b9ae10da61adcd891f497Andreas Huber        }
78630ab66297501757d745b9ae10da61adcd891f497Andreas Huber
787888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        default:
788888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            CHECK(!"Support for this compressionFormat to be implemented.");
789888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            break;
790888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    }
791888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber}
792888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
793888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huberstatus_t OMXCodec::setupMPEG4EncoderParameters() {
794888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
795888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    InitOMXParams(&mpeg4type);
796888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
797888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
798888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    status_t err = mOMX->getParameter(
799888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
800888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(err, OK);
801888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
802888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
803888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.bSVH = OMX_FALSE;
804888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.bGov = OMX_FALSE;
805888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
806888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nAllowedPictureTypes =
807888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
808888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
809888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nPFrames = 23;
810888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nBFrames = 0;
811888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
812888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nIDCVLCThreshold = 0;
813888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.bACPred = OMX_TRUE;
814888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nMaxPacketSize = 256;
815888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nTimeIncRes = 1000;
816888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nHeaderExtension = 0;
817888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
818888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
819888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.eProfile = OMX_VIDEO_MPEG4ProfileCore;
820888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.eLevel = OMX_VIDEO_MPEG4Level2;
821888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
822888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    err = mOMX->setParameter(
823888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
824888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(err, OK);
825888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
826888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    // ----------------
827888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
828888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
829888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    InitOMXParams(&bitrateType);
830888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
831888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
832888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    err = mOMX->getParameter(
833888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            mNode, OMX_IndexParamVideoBitrate,
834888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            &bitrateType, sizeof(bitrateType));
835888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(err, OK);
836888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
837888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    bitrateType.eControlRate = OMX_Video_ControlRateVariable;
838888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    bitrateType.nTargetBitrate = 1000000;
839888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
840888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    err = mOMX->setParameter(
841888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            mNode, OMX_IndexParamVideoBitrate,
842888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            &bitrateType, sizeof(bitrateType));
843888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(err, OK);
844888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
845888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    // ----------------
846888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
847888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
848888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    InitOMXParams(&errorCorrectionType);
849888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
850888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
851888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    err = mOMX->getParameter(
852888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
853888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
854888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(err, OK);
855888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
856888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
857888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
858888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
859888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
860888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
861888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
862888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    err = mOMX->setParameter(
863888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
864888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
865888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(err, OK);
866888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
867888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    return OK;
868693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
869693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
87030ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t OMXCodec::setupAVCEncoderParameters() {
87130ab66297501757d745b9ae10da61adcd891f497Andreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
87230ab66297501757d745b9ae10da61adcd891f497Andreas Huber    InitOMXParams(&h264type);
87330ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nPortIndex = kPortIndexOutput;
87430ab66297501757d745b9ae10da61adcd891f497Andreas Huber
87530ab66297501757d745b9ae10da61adcd891f497Andreas Huber    status_t err = mOMX->getParameter(
87630ab66297501757d745b9ae10da61adcd891f497Andreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
87730ab66297501757d745b9ae10da61adcd891f497Andreas Huber    CHECK_EQ(err, OK);
87830ab66297501757d745b9ae10da61adcd891f497Andreas Huber
87930ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nAllowedPictureTypes =
88030ab66297501757d745b9ae10da61adcd891f497Andreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
88130ab66297501757d745b9ae10da61adcd891f497Andreas Huber
88230ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nSliceHeaderSpacing = 0;
88330ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nBFrames = 0;
88430ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bUseHadamard = OMX_TRUE;
88530ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nRefFrames = 1;
88630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nRefIdx10ActiveMinus1 = 0;
88730ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nRefIdx11ActiveMinus1 = 0;
88830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bEnableUEP = OMX_FALSE;
88930ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bEnableFMO = OMX_FALSE;
89030ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bEnableASO = OMX_FALSE;
89130ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bEnableRS = OMX_FALSE;
89230ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
89330ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.eLevel = OMX_VIDEO_AVCLevel1b;
89430ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
89530ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bMBAFF = OMX_FALSE;
89630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bEntropyCodingCABAC = OMX_FALSE;
89730ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bWeightedPPrediction = OMX_FALSE;
89830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bconstIpred = OMX_FALSE;
89930ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bDirect8x8Inference = OMX_FALSE;
90030ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bDirectSpatialTemporal = OMX_FALSE;
90130ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nCabacInitIdc = 0;
90230ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
90330ab66297501757d745b9ae10da61adcd891f497Andreas Huber
90430ab66297501757d745b9ae10da61adcd891f497Andreas Huber    err = mOMX->setParameter(
90530ab66297501757d745b9ae10da61adcd891f497Andreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
90630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    CHECK_EQ(err, OK);
90730ab66297501757d745b9ae10da61adcd891f497Andreas Huber
90830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
90930ab66297501757d745b9ae10da61adcd891f497Andreas Huber    InitOMXParams(&bitrateType);
91030ab66297501757d745b9ae10da61adcd891f497Andreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
91130ab66297501757d745b9ae10da61adcd891f497Andreas Huber
91230ab66297501757d745b9ae10da61adcd891f497Andreas Huber    err = mOMX->getParameter(
91330ab66297501757d745b9ae10da61adcd891f497Andreas Huber            mNode, OMX_IndexParamVideoBitrate,
91430ab66297501757d745b9ae10da61adcd891f497Andreas Huber            &bitrateType, sizeof(bitrateType));
91530ab66297501757d745b9ae10da61adcd891f497Andreas Huber    CHECK_EQ(err, OK);
91630ab66297501757d745b9ae10da61adcd891f497Andreas Huber
91730ab66297501757d745b9ae10da61adcd891f497Andreas Huber    bitrateType.eControlRate = OMX_Video_ControlRateVariable;
91830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    bitrateType.nTargetBitrate = 1000000;
91930ab66297501757d745b9ae10da61adcd891f497Andreas Huber
92030ab66297501757d745b9ae10da61adcd891f497Andreas Huber    err = mOMX->setParameter(
92130ab66297501757d745b9ae10da61adcd891f497Andreas Huber            mNode, OMX_IndexParamVideoBitrate,
92230ab66297501757d745b9ae10da61adcd891f497Andreas Huber            &bitrateType, sizeof(bitrateType));
92330ab66297501757d745b9ae10da61adcd891f497Andreas Huber    CHECK_EQ(err, OK);
92430ab66297501757d745b9ae10da61adcd891f497Andreas Huber
92530ab66297501757d745b9ae10da61adcd891f497Andreas Huber    return OK;
92630ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
92730ab66297501757d745b9ae10da61adcd891f497Andreas Huber
9282a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huberstatus_t OMXCodec::setVideoOutputFormat(
929693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const char *mime, OMX_U32 width, OMX_U32 height) {
9302a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    CODEC_LOGV("setVideoOutputFormat width=%ld, height=%ld", width, height);
931693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
932693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
93318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
934693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        compressionFormat = OMX_VIDEO_CodingAVC;
93518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
936693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        compressionFormat = OMX_VIDEO_CodingMPEG4;
93718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
938693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        compressionFormat = OMX_VIDEO_CodingH263;
939693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
940693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        LOGE("Not a supported video mime type: %s", mime);
941693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(!"Should not be here. Not a supported video mime type.");
942693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
943693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
9442a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber    status_t err = setVideoPortFormatType(
945693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
946693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
9472a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber    if (err != OK) {
9482a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        return err;
9492a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber    }
9502a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber
951693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#if 1
952693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    {
953693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_VIDEO_PARAM_PORTFORMATTYPE format;
9547a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        InitOMXParams(&format);
955693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        format.nPortIndex = kPortIndexOutput;
956693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        format.nIndex = 0;
957693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
958318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        status_t err = mOMX->getParameter(
959693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
960693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                &format, sizeof(format));
961693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(err, OK);
962693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(format.eCompressionFormat, OMX_VIDEO_CodingUnused);
963693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
964693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
965693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
966693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
967693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber               || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
968693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber               || format.eColorFormat == OMX_COLOR_FormatCbYCrY
969693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber               || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar);
970693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
971318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        err = mOMX->setParameter(
972693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
973693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                &format, sizeof(format));
9742a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber
9752a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        if (err != OK) {
9762a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber            return err;
9772a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        }
978693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
979693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#endif
980693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
981693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
9827a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
983693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexInput;
984693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
9857a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
9867a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
9872a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber    err = mOMX->getParameter(
988693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
989693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
990693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
991693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
992693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#if 1
993693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    // XXX Need a (much) better heuristic to compute input buffer sizes.
994693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    const size_t X = 64 * 1024;
995693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (def.nBufferSize < X) {
996693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        def.nBufferSize = X;
997693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
998693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#endif
999693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1000693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
1001693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1002693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameWidth = width;
1003693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameHeight = height;
1004693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1005888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    video_def->eCompressionFormat = compressionFormat;
1006693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
1007693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1008318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
1009693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
10102a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber
10112a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber    if (err != OK) {
10122a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        return err;
10132a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber    }
1014693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1015693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    ////////////////////////////////////////////////////////////////////////////
1016693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
10177a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
1018693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexOutput;
1019693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1020318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->getParameter(
1021693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1022693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
1023693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
1024693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1025693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#if 0
1026693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nBufferSize =
1027693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2;  // YUV420
1028693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#endif
1029693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1030693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameWidth = width;
1031693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameHeight = height;
1032693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1033318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
1034693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
10352a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber
10362a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber    return err;
1037693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1038693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1039693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberOMXCodec::OMXCodec(
1040693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks,
1041bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        bool isEncoder,
1042693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const char *mime,
1043693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const char *componentName,
1044693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const sp<MediaSource> &source)
1045693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    : mOMX(omx),
10467eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber      mOMXLivesLocally(omx->livesLocally(getpid())),
1047693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mNode(node),
1048693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mQuirks(quirks),
1049693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mIsEncoder(isEncoder),
1050693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mMIME(strdup(mime)),
1051693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mComponentName(strdup(componentName)),
1052693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mSource(source),
1053693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mCodecSpecificDataIndex(0),
1054693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mState(LOADED),
1055284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber      mInitialBufferSubmit(true),
1056693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mSignalledEOS(false),
1057693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mNoMoreOutputData(false),
10587f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber      mOutputPortSettingsHaveChanged(false),
10597f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber      mSeekTimeUs(-1),
10607f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber      mLeftOverBuffer(NULL) {
1061693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mPortStatus[kPortIndexInput] = ENABLED;
1062693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mPortStatus[kPortIndexOutput] = ENABLED;
1063693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
10647a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    setComponentRole();
10657a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber}
10667a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
106718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber// static
106818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Hubervoid OMXCodec::setComponentRole(
106918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder,
107018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        const char *mime) {
10717a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    struct MimeToRole {
10727a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        const char *mime;
10737a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        const char *decoderRole;
10747a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        const char *encoderRole;
10757a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    };
10767a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
10777a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    static const MimeToRole kMimeToRole[] = {
107818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
107918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
108018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
108118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
108218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
108318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
108418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
108518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
108618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
108718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
108818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
108918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
109018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
109118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
10927a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    };
10937a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
10947a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    static const size_t kNumMimeToRole =
10957a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
10967a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
10977a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    size_t i;
10987a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
109918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
11007a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            break;
11017a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        }
11027a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    }
11037a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
11047a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    if (i == kNumMimeToRole) {
11057a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        return;
11067a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    }
11077a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
11087a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    const char *role =
110918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
111018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                  : kMimeToRole[i].decoderRole;
11117a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
11127a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    if (role != NULL) {
11137a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
11147a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        InitOMXParams(&roleParams);
11157a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
11167a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        strncpy((char *)roleParams.cRole,
11177a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
11187a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
11197a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
11207a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
1121318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        status_t err = omx->setParameter(
112218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                node, OMX_IndexParamStandardComponentRole,
11237a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                &roleParams, sizeof(roleParams));
11247a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
11257a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        if (err != OK) {
11267a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            LOGW("Failed to set standard component role '%s'.", role);
11277a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        }
11287a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    }
1129693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1130693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
113118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Hubervoid OMXCodec::setComponentRole() {
113218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    setComponentRole(mOMX, mNode, mIsEncoder, mMIME);
113318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber}
113418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
1135693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberOMXCodec::~OMXCodec() {
1136dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    CHECK(mState == LOADED || mState == ERROR);
1137693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1138318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->freeNode(mNode);
1139693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
1140693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1141693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mNode = NULL;
1142693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    setState(DEAD);
1143693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1144693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    clearCodecSpecificData();
1145693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1146693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    free(mComponentName);
1147693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mComponentName = NULL;
1148bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
1149693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    free(mMIME);
1150693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mMIME = NULL;
1151693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1152693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1153693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::init() {
1154284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber    // mLock is held.
1155693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1156693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(mState, LOADED);
1157693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1158693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err;
1159693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) {
1160318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
1161693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(err, OK);
1162693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        setState(LOADED_TO_IDLE);
1163693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1164693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1165693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    err = allocateBuffers();
1166693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
1167693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1168693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mQuirks & kRequiresLoadedToIdleAfterAllocation) {
1169318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
1170693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(err, OK);
1171693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1172693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        setState(LOADED_TO_IDLE);
1173693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1174693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1175693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    while (mState != EXECUTING && mState != ERROR) {
1176693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mAsyncCompletion.wait(mLock);
1177693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1178693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1179693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return mState == ERROR ? UNKNOWN_ERROR : OK;
1180693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1181693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1182693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber// static
1183693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberbool OMXCodec::isIntermediateState(State state) {
1184693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return state == LOADED_TO_IDLE
1185693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        || state == IDLE_TO_EXECUTING
1186693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        || state == EXECUTING_TO_IDLE
1187693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        || state == IDLE_TO_LOADED
1188693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        || state == RECONFIGURING;
1189693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1190693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1191693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::allocateBuffers() {
1192693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err = allocateBuffersOnPort(kPortIndexInput);
1193693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1194693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (err != OK) {
1195693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return err;
1196693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1197693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1198693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return allocateBuffersOnPort(kPortIndexOutput);
1199693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1200693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1201693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
1202693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
12037a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
1204693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = portIndex;
1205693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1206318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
1207693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1208693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1209693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (err != OK) {
1210693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return err;
1211693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1212693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
12137530e9c708275c273c134c36c68179f511c1940eAndreas Huber    size_t totalSize = def.nBufferCountActual * def.nBufferSize;
1214867d2f6ce668968e463eb86b856d21525f12fd67Mathias Agopian    mDealer[portIndex] = new MemoryDealer(totalSize, "OMXCodec");
12157530e9c708275c273c134c36c68179f511c1940eAndreas Huber
1216693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
12177530e9c708275c273c134c36c68179f511c1940eAndreas Huber        sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
1218693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(mem.get() != NULL);
1219693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1220570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber        BufferInfo info;
1221570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber        info.mData = NULL;
1222570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber        info.mSize = def.nBufferSize;
1223570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber
1224693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        IOMX::buffer_id buffer;
1225693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (portIndex == kPortIndexInput
1226693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                && (mQuirks & kRequiresAllocateBufferOnInputPorts)) {
12277eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber            if (mOMXLivesLocally) {
1228570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber                mem.clear();
1229570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber
12307eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber                err = mOMX->allocateBuffer(
1231570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber                        mNode, portIndex, def.nBufferSize, &buffer,
1232570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber                        &info.mData);
12337eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber            } else {
12347eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber                err = mOMX->allocateBufferWithBackup(
12357eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber                        mNode, portIndex, mem, &buffer);
12367eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber            }
1237ea7d15629752256f6ea1d5c6ea796e59aefd030fAndreas Huber        } else if (portIndex == kPortIndexOutput
1238ea7d15629752256f6ea1d5c6ea796e59aefd030fAndreas Huber                && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) {
12397eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber            if (mOMXLivesLocally) {
1240570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber                mem.clear();
1241570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber
12427eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber                err = mOMX->allocateBuffer(
1243570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber                        mNode, portIndex, def.nBufferSize, &buffer,
1244570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber                        &info.mData);
12457eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber            } else {
12467eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber                err = mOMX->allocateBufferWithBackup(
12477eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber                        mNode, portIndex, mem, &buffer);
12487eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber            }
1249693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        } else {
1250318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
1251693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1252693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1253693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (err != OK) {
1254693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            LOGE("allocate_buffer_with_backup failed");
1255693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            return err;
1256693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1257693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1258570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber        if (mem != NULL) {
1259570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber            info.mData = mem->pointer();
1260570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber        }
1261570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber
1262693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        info.mBuffer = buffer;
1263693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        info.mOwnedByComponent = false;
1264693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        info.mMem = mem;
1265693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        info.mMediaBuffer = NULL;
1266693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1267693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (portIndex == kPortIndexOutput) {
1268213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber            if (!(mOMXLivesLocally
1269213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber                        && (mQuirks & kRequiresAllocateBufferOnOutputPorts)
1270213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber                        && (mQuirks & kDefersOutputBufferAllocation))) {
1271213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber                // If the node does not fill in the buffer ptr at this time,
1272213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber                // we will defer creating the MediaBuffer until receiving
1273213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber                // the first FILL_BUFFER_DONE notification instead.
1274213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber                info.mMediaBuffer = new MediaBuffer(info.mData, info.mSize);
1275213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber                info.mMediaBuffer->setObserver(this);
1276213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber            }
1277693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1278693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1279693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mPortBuffers[portIndex].push(info);
1280693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
12817a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        CODEC_LOGV("allocated buffer %p on %s port", buffer,
1282693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber             portIndex == kPortIndexInput ? "input" : "output");
1283693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1284693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1285134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    // dumpPortStatus(portIndex);
1286693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1287693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return OK;
1288693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1289693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1290693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::on_message(const omx_message &msg) {
1291693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Mutex::Autolock autoLock(mLock);
1292693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1293693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (msg.type) {
1294693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case omx_message::EVENT:
1295693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1296693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            onEvent(
1297693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 msg.u.event_data.event, msg.u.event_data.data1,
1298693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 msg.u.event_data.data2);
1299693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1300693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1301693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1302693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1303693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
1304693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1305693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
1306693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
13077a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("EMPTY_BUFFER_DONE(buffer: %p)", buffer);
1308693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1309693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
1310693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            size_t i = 0;
1311693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
1312693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                ++i;
1313693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1314693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1315693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(i < buffers->size());
1316693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (!(*buffers)[i].mOwnedByComponent) {
1317693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                LOGW("We already own input buffer %p, yet received "
1318693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                     "an EMPTY_BUFFER_DONE.", buffer);
1319693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1320693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1321693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            buffers->editItemAt(i).mOwnedByComponent = false;
1322693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1323693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (mPortStatus[kPortIndexInput] == DISABLING) {
13247a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
1325693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1326693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                status_t err =
1327318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                    mOMX->freeBuffer(mNode, kPortIndexInput, buffer);
1328693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1329693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1330693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                buffers->removeAt(i);
1331ec9dd59902c8beea4ba6a842f3a843d46150d949Andreas Huber            } else if (mState != ERROR
1332ec9dd59902c8beea4ba6a842f3a843d46150d949Andreas Huber                    && mPortStatus[kPortIndexInput] != SHUTTING_DOWN) {
1333693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(mPortStatus[kPortIndexInput], ENABLED);
1334693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                drainInputBuffer(&buffers->editItemAt(i));
1335693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1336693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1337693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1338693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1339693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case omx_message::FILL_BUFFER_DONE:
1340693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1341693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
1342693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_U32 flags = msg.u.extended_buffer_data.flags;
1343693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1344134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber            CODEC_LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx, timestamp: %lld us (%.2f secs))",
1345693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 buffer,
1346693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 msg.u.extended_buffer_data.range_length,
1347134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber                 flags,
1348693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 msg.u.extended_buffer_data.timestamp,
1349693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 msg.u.extended_buffer_data.timestamp / 1E6);
1350693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1351693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
1352693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            size_t i = 0;
1353693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
1354693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                ++i;
1355693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1356693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1357693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(i < buffers->size());
1358693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            BufferInfo *info = &buffers->editItemAt(i);
1359693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1360693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (!info->mOwnedByComponent) {
1361693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                LOGW("We already own output buffer %p, yet received "
1362693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                     "a FILL_BUFFER_DONE.", buffer);
1363693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1364693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1365693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            info->mOwnedByComponent = false;
1366693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1367693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (mPortStatus[kPortIndexOutput] == DISABLING) {
13687a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
1369693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1370693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                status_t err =
1371318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                    mOMX->freeBuffer(mNode, kPortIndexOutput, buffer);
1372693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1373693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1374693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                buffers->removeAt(i);
1375134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber#if 0
1376355edcea2f15c0f619c1e1d0f4fa433b0d38098fAndreas Huber            } else if (mPortStatus[kPortIndexOutput] == ENABLED
1377355edcea2f15c0f619c1e1d0f4fa433b0d38098fAndreas Huber                       && (flags & OMX_BUFFERFLAG_EOS)) {
13787a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                CODEC_LOGV("No more output data.");
1379693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mNoMoreOutputData = true;
1380693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mBufferFilled.signal();
1381134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber#endif
1382693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) {
1383693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED);
1384bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
1385213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber                if (info->mMediaBuffer == NULL) {
1386213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber                    CHECK(mOMXLivesLocally);
1387213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber                    CHECK(mQuirks & kRequiresAllocateBufferOnOutputPorts);
1388213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber                    CHECK(mQuirks & kDefersOutputBufferAllocation);
1389213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber
1390213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber                    // The qcom video decoders on Nexus don't actually allocate
1391213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber                    // output buffer memory on a call to OMX_AllocateBuffer
1392213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber                    // the "pBuffer" member of the OMX_BUFFERHEADERTYPE
1393213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber                    // structure is only filled in later.
1394213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber
1395213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber                    info->mMediaBuffer = new MediaBuffer(
1396213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber                            msg.u.extended_buffer_data.data_ptr,
1397213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber                            info->mSize);
1398213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber                    info->mMediaBuffer->setObserver(this);
1399213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber                }
1400213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber
1401693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                MediaBuffer *buffer = info->mMediaBuffer;
1402693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1403693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                buffer->set_range(
1404693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        msg.u.extended_buffer_data.range_offset,
1405693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        msg.u.extended_buffer_data.range_length);
1406693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1407693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                buffer->meta_data()->clear();
1408693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
140948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber                buffer->meta_data()->setInt64(
141048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber                        kKeyTime, msg.u.extended_buffer_data.timestamp);
1411693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1412693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) {
1413693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    buffer->meta_data()->setInt32(kKeyIsSyncFrame, true);
1414693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                }
141530ab66297501757d745b9ae10da61adcd891f497Andreas Huber                if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_CODECCONFIG) {
141630ab66297501757d745b9ae10da61adcd891f497Andreas Huber                    buffer->meta_data()->setInt32(kKeyIsCodecConfig, true);
141730ab66297501757d745b9ae10da61adcd891f497Andreas Huber                }
1418693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1419693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                buffer->meta_data()->setPointer(
1420693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        kKeyPlatformPrivate,
1421693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        msg.u.extended_buffer_data.platform_private);
1422693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1423693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                buffer->meta_data()->setPointer(
1424693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        kKeyBufferID,
1425693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        msg.u.extended_buffer_data.buffer);
1426693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1427693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mFilledBuffers.push_back(i);
1428693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mBufferFilled.signal();
1429134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber
1430134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber                if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_EOS) {
1431134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber                    CODEC_LOGV("No more output data.");
1432134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber                    mNoMoreOutputData = true;
1433134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber                }
1434693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1435693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1436693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1437693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1438693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1439693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
1440693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1441693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(!"should not be here.");
1442693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1443693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1444693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1445693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1446693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1447693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
1448693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (event) {
1449693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_EventCmdComplete:
1450693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1451693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            onCmdComplete((OMX_COMMANDTYPE)data1, data2);
1452693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1453693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1454693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1455693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_EventError:
1456693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1457134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber            LOGE("ERROR(0x%08lx, %ld)", data1, data2);
1458693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1459693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            setState(ERROR);
1460693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1461693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1462693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1463693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_EventPortSettingsChanged:
1464693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1465693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            onPortSettingsChanged(data1);
1466693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1467693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1468693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1469134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber#if 0
1470693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_EventBufferFlag:
1471693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
14727a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1);
1473693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1474693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (data1 == kPortIndexOutput) {
1475693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mNoMoreOutputData = true;
1476693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1477693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1478693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1479134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber#endif
1480693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1481693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
1482693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
14837a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("EVENT(%d, %ld, %ld)", event, data1, data2);
1484693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1485693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1486693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1487693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1488693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
148912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber// Has the format changed in any way that the client would have to be aware of?
149012658b720b176b7d934444256d07ba3c595d9b44Andreas Huberstatic bool formatHasNotablyChanged(
149112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        const sp<MetaData> &from, const sp<MetaData> &to) {
149212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    if (from.get() == NULL && to.get() == NULL) {
149312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        return false;
149412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    }
149512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
1496c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber    if ((from.get() == NULL && to.get() != NULL)
1497c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber        || (from.get() != NULL && to.get() == NULL)) {
149812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        return true;
149912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    }
150012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
150112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    const char *mime_from, *mime_to;
150212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    CHECK(from->findCString(kKeyMIMEType, &mime_from));
150312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    CHECK(to->findCString(kKeyMIMEType, &mime_to));
150412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
150512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    if (strcasecmp(mime_from, mime_to)) {
150612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        return true;
150712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    }
150812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
150912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    if (!strcasecmp(mime_from, MEDIA_MIMETYPE_VIDEO_RAW)) {
151012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        int32_t colorFormat_from, colorFormat_to;
151112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(from->findInt32(kKeyColorFormat, &colorFormat_from));
151212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(to->findInt32(kKeyColorFormat, &colorFormat_to));
151312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
151412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        if (colorFormat_from != colorFormat_to) {
151512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber            return true;
151612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        }
151712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
151812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        int32_t width_from, width_to;
151912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(from->findInt32(kKeyWidth, &width_from));
152012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(to->findInt32(kKeyWidth, &width_to));
152112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
152212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        if (width_from != width_to) {
152312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber            return true;
152412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        }
152512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
152612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        int32_t height_from, height_to;
152712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(from->findInt32(kKeyHeight, &height_from));
152812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(to->findInt32(kKeyHeight, &height_to));
152912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
153012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        if (height_from != height_to) {
153112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber            return true;
153212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        }
153312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    } else if (!strcasecmp(mime_from, MEDIA_MIMETYPE_AUDIO_RAW)) {
153412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        int32_t numChannels_from, numChannels_to;
153512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(from->findInt32(kKeyChannelCount, &numChannels_from));
153612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(to->findInt32(kKeyChannelCount, &numChannels_to));
153712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
153812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        if (numChannels_from != numChannels_to) {
153912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber            return true;
154012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        }
154112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
154212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        int32_t sampleRate_from, sampleRate_to;
154312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(from->findInt32(kKeySampleRate, &sampleRate_from));
154412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(to->findInt32(kKeySampleRate, &sampleRate_to));
154512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
154612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        if (sampleRate_from != sampleRate_to) {
154712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber            return true;
154812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        }
154912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    }
155012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
155112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    return false;
155212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber}
155312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
1554693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) {
1555693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (cmd) {
1556693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_CommandStateSet:
1557693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1558693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            onStateChange((OMX_STATETYPE)data);
1559693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1560693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1561693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1562693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_CommandPortDisable:
1563693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1564693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_U32 portIndex = data;
15657a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("PORT_DISABLED(%ld)", portIndex);
1566693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1567693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(mState == EXECUTING || mState == RECONFIGURING);
1568693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mPortStatus[portIndex], DISABLING);
1569693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mPortBuffers[portIndex].size(), 0);
1570693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1571693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mPortStatus[portIndex] = DISABLED;
1572693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1573693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (mState == RECONFIGURING) {
1574693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(portIndex, kPortIndexOutput);
1575693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
157612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber                sp<MetaData> oldOutputFormat = mOutputFormat;
15777f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber                initOutputFormat(mSource->getFormat());
157812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
157912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber                // Don't notify clients if the output port settings change
158012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber                // wasn't of importance to them, i.e. it may be that just the
158112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber                // number of buffers has changed and nothing else.
158212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber                mOutputPortSettingsHaveChanged =
158312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber                    formatHasNotablyChanged(oldOutputFormat, mOutputFormat);
15847f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber
1585693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                enablePortAsync(portIndex);
1586693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1587693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                status_t err = allocateBuffersOnPort(portIndex);
1588693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1589693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1590693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1591693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1592693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1593693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_CommandPortEnable:
1594693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1595693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_U32 portIndex = data;
15967a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("PORT_ENABLED(%ld)", portIndex);
1597693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1598693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(mState == EXECUTING || mState == RECONFIGURING);
1599693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mPortStatus[portIndex], ENABLING);
1600693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1601693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mPortStatus[portIndex] = ENABLED;
1602693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1603693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (mState == RECONFIGURING) {
1604693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(portIndex, kPortIndexOutput);
1605693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1606693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                setState(EXECUTING);
1607693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1608693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                fillOutputBuffers();
1609693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1610693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1611693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1612693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1613693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_CommandFlush:
1614693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1615693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_U32 portIndex = data;
1616693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
16177a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("FLUSH_DONE(%ld)", portIndex);
1618693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1619693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mPortStatus[portIndex], SHUTTING_DOWN);
1620693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mPortStatus[portIndex] = ENABLED;
1621693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1622693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]),
1623693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                     mPortBuffers[portIndex].size());
1624693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1625693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (mState == RECONFIGURING) {
1626693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(portIndex, kPortIndexOutput);
1627693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1628693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                disablePortAsync(portIndex);
16298297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber            } else if (mState == EXECUTING_TO_IDLE) {
16308297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                if (mPortStatus[kPortIndexInput] == ENABLED
16318297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    && mPortStatus[kPortIndexOutput] == ENABLED) {
16327a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                    CODEC_LOGV("Finished flushing both ports, now completing "
16338297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                         "transition from EXECUTING to IDLE.");
16348297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber
16358297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
16368297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
16378297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber
16388297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    status_t err =
1639318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                        mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
16408297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    CHECK_EQ(err, OK);
16418297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                }
1642693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else {
1643693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                // We're flushing both ports in preparation for seeking.
1644693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1645693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                if (mPortStatus[kPortIndexInput] == ENABLED
1646693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    && mPortStatus[kPortIndexOutput] == ENABLED) {
16477a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                    CODEC_LOGV("Finished flushing both ports, now continuing from"
1648693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                         " seek-time.");
1649693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1650693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    drainInputBuffers();
1651693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    fillOutputBuffers();
1652693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                }
1653693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1654693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1655693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1656693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1657693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1658693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
1659693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
16607a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("CMD_COMPLETE(%d, %ld)", cmd, data);
1661693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1662693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1663693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1664693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1665693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1666693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::onStateChange(OMX_STATETYPE newState) {
1667570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber    CODEC_LOGV("onStateChange %d", newState);
1668570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber
1669693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (newState) {
1670693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_StateIdle:
1671693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
16727a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("Now Idle.");
1673693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (mState == LOADED_TO_IDLE) {
1674318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                status_t err = mOMX->sendCommand(
1675693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        mNode, OMX_CommandStateSet, OMX_StateExecuting);
1676693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1677693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1678693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1679693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                setState(IDLE_TO_EXECUTING);
1680693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else {
1681693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(mState, EXECUTING_TO_IDLE);
1682693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1683693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(
1684693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
1685693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    mPortBuffers[kPortIndexInput].size());
1686693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1687693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(
1688693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    countBuffersWeOwn(mPortBuffers[kPortIndexOutput]),
1689693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    mPortBuffers[kPortIndexOutput].size());
1690693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1691318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                status_t err = mOMX->sendCommand(
1692693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        mNode, OMX_CommandStateSet, OMX_StateLoaded);
1693693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1694693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1695693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1696693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                err = freeBuffersOnPort(kPortIndexInput);
1697693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1698693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1699693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                err = freeBuffersOnPort(kPortIndexOutput);
1700693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1701693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1702693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mPortStatus[kPortIndexInput] = ENABLED;
1703693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mPortStatus[kPortIndexOutput] = ENABLED;
1704693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1705693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                setState(IDLE_TO_LOADED);
1706693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1707693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1708693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1709693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1710693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_StateExecuting:
1711693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1712693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mState, IDLE_TO_EXECUTING);
1713693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
17147a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("Now Executing.");
1715693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1716693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            setState(EXECUTING);
1717693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1718284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber            // Buffers will be submitted to the component in the first
1719284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber            // call to OMXCodec::read as mInitialBufferSubmit is true at
1720284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber            // this point. This ensures that this on_message call returns,
1721284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber            // releases the lock and ::init can notice the state change and
1722284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber            // itself return.
1723693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1724693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1725693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1726693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_StateLoaded:
1727693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1728693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mState, IDLE_TO_LOADED);
1729693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
17307a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("Now Loaded.");
1731693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1732693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            setState(LOADED);
1733693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1734693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1735693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1736570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber        case OMX_StateInvalid:
1737570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber        {
1738570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber            setState(ERROR);
1739570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber            break;
1740570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber        }
1741570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber
1742693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
1743693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1744693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(!"should not be here.");
1745693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1746693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1747693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1748693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1749693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1750693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber// static
1751693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t OMXCodec::countBuffersWeOwn(const Vector<BufferInfo> &buffers) {
1752693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t n = 0;
1753693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < buffers.size(); ++i) {
1754693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (!buffers[i].mOwnedByComponent) {
1755693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            ++n;
1756693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1757693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1758693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1759693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return n;
1760693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1761693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1762693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::freeBuffersOnPort(
1763693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_U32 portIndex, bool onlyThoseWeOwn) {
1764693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
1765693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1766693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t stickyErr = OK;
1767693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1768693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = buffers->size(); i-- > 0;) {
1769693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        BufferInfo *info = &buffers->editItemAt(i);
1770693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1771693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (onlyThoseWeOwn && info->mOwnedByComponent) {
1772693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            continue;
1773693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1774693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1775693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(info->mOwnedByComponent, false);
1776693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
177795301196d59fb88ef96342fd307a2be374b5079bAndreas Huber        CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex);
177895301196d59fb88ef96342fd307a2be374b5079bAndreas Huber
1779693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        status_t err =
1780318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mOMX->freeBuffer(mNode, portIndex, info->mBuffer);
1781693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1782693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (err != OK) {
1783693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            stickyErr = err;
1784693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1785693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1786693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (info->mMediaBuffer != NULL) {
1787693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            info->mMediaBuffer->setObserver(NULL);
1788693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1789693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            // Make sure nobody but us owns this buffer at this point.
1790693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(info->mMediaBuffer->refcount(), 0);
1791693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1792693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            info->mMediaBuffer->release();
1793693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1794693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1795693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        buffers->removeAt(i);
1796693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1797693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1798693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(onlyThoseWeOwn || buffers->isEmpty());
1799693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1800693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return stickyErr;
1801693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1802693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1803693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) {
18047a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex);
1805693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1806693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(mState, EXECUTING);
1807693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(portIndex, kPortIndexOutput);
1808693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    setState(RECONFIGURING);
1809693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1810693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mQuirks & kNeedsFlushBeforeDisable) {
18111beb760d920561679862ded945a04e370368c7f7Andreas Huber        if (!flushPortAsync(portIndex)) {
18121beb760d920561679862ded945a04e370368c7f7Andreas Huber            onCmdComplete(OMX_CommandFlush, portIndex);
18131beb760d920561679862ded945a04e370368c7f7Andreas Huber        }
1814693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
1815693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        disablePortAsync(portIndex);
1816693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1817693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1818693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
18191beb760d920561679862ded945a04e370368c7f7Andreas Huberbool OMXCodec::flushPortAsync(OMX_U32 portIndex) {
18208297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber    CHECK(mState == EXECUTING || mState == RECONFIGURING
18218297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber            || mState == EXECUTING_TO_IDLE);
1822693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
18237a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    CODEC_LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.",
18241beb760d920561679862ded945a04e370368c7f7Andreas Huber         portIndex, countBuffersWeOwn(mPortBuffers[portIndex]),
18251beb760d920561679862ded945a04e370368c7f7Andreas Huber         mPortBuffers[portIndex].size());
18261beb760d920561679862ded945a04e370368c7f7Andreas Huber
1827693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(mPortStatus[portIndex], ENABLED);
1828693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mPortStatus[portIndex] = SHUTTING_DOWN;
1829693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
18301beb760d920561679862ded945a04e370368c7f7Andreas Huber    if ((mQuirks & kRequiresFlushCompleteEmulation)
18311beb760d920561679862ded945a04e370368c7f7Andreas Huber        && countBuffersWeOwn(mPortBuffers[portIndex])
18321beb760d920561679862ded945a04e370368c7f7Andreas Huber                == mPortBuffers[portIndex].size()) {
18331beb760d920561679862ded945a04e370368c7f7Andreas Huber        // No flush is necessary and this component fails to send a
18341beb760d920561679862ded945a04e370368c7f7Andreas Huber        // flush-complete event in this case.
18351beb760d920561679862ded945a04e370368c7f7Andreas Huber
18361beb760d920561679862ded945a04e370368c7f7Andreas Huber        return false;
18371beb760d920561679862ded945a04e370368c7f7Andreas Huber    }
18381beb760d920561679862ded945a04e370368c7f7Andreas Huber
1839693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err =
1840318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        mOMX->sendCommand(mNode, OMX_CommandFlush, portIndex);
1841693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
18421beb760d920561679862ded945a04e370368c7f7Andreas Huber
18431beb760d920561679862ded945a04e370368c7f7Andreas Huber    return true;
1844693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1845693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1846693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::disablePortAsync(OMX_U32 portIndex) {
1847693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(mState == EXECUTING || mState == RECONFIGURING);
1848693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1849693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(mPortStatus[portIndex], ENABLED);
1850693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mPortStatus[portIndex] = DISABLING;
1851693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1852693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err =
1853318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        mOMX->sendCommand(mNode, OMX_CommandPortDisable, portIndex);
1854693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
1855693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1856693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    freeBuffersOnPort(portIndex, true);
1857693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1858693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1859693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::enablePortAsync(OMX_U32 portIndex) {
1860693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(mState == EXECUTING || mState == RECONFIGURING);
1861693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1862693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(mPortStatus[portIndex], DISABLED);
1863693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mPortStatus[portIndex] = ENABLING;
1864693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1865693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err =
1866318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex);
1867693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
1868693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1869693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1870693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::fillOutputBuffers() {
1871693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(mState, EXECUTING);
1872693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1873b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber    // This is a workaround for some decoders not properly reporting
1874b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber    // end-of-output-stream. If we own all input buffers and also own
1875b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber    // all output buffers and we already signalled end-of-input-stream,
1876b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber    // the end-of-output-stream is implied.
1877b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber    if (mSignalledEOS
1878b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber            && countBuffersWeOwn(mPortBuffers[kPortIndexInput])
1879b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber                == mPortBuffers[kPortIndexInput].size()
1880b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber            && countBuffersWeOwn(mPortBuffers[kPortIndexOutput])
1881b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber                == mPortBuffers[kPortIndexOutput].size()) {
1882b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber        mNoMoreOutputData = true;
1883b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber        mBufferFilled.signal();
1884b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber
1885b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber        return;
1886b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber    }
1887b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber
1888693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
1889693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
1890693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        fillOutputBuffer(&buffers->editItemAt(i));
1891693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1892693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1893693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1894693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::drainInputBuffers() {
1895450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber    CHECK(mState == EXECUTING || mState == RECONFIGURING);
1896693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1897693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
1898693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
1899693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        drainInputBuffer(&buffers->editItemAt(i));
1900693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1901693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1902693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1903693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::drainInputBuffer(BufferInfo *info) {
1904693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(info->mOwnedByComponent, false);
1905693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1906693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mSignalledEOS) {
1907693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return;
1908693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1909693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1910693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mCodecSpecificDataIndex < mCodecSpecificData.size()) {
1911693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const CodecSpecificData *specific =
1912693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mCodecSpecificData[mCodecSpecificDataIndex];
1913693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1914693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        size_t size = specific->mSize;
1915693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
191618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME)
1917dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber                && !(mQuirks & kWantsNALFragments)) {
1918693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            static const uint8_t kNALStartCode[4] =
1919693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    { 0x00, 0x00, 0x00, 0x01 };
1920693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1921570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber            CHECK(info->mSize >= specific->mSize + 4);
1922693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1923693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            size += 4;
1924693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1925570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber            memcpy(info->mData, kNALStartCode, 4);
1926570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber            memcpy((uint8_t *)info->mData + 4,
1927693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                   specific->mData, specific->mSize);
1928693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        } else {
1929570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber            CHECK(info->mSize >= specific->mSize);
1930570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber            memcpy(info->mData, specific->mData, specific->mSize);
1931693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1932693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1933134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber        mNoMoreOutputData = false;
1934134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber
1935b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber        CODEC_LOGV("calling emptyBuffer with codec specific data");
1936b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber
1937318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        status_t err = mOMX->emptyBuffer(
1938693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mNode, info->mBuffer, 0, size,
1939693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG,
1940693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                0);
194136efa039efaae4526791336cb688032d22b34becAndreas Huber        CHECK_EQ(err, OK);
1942693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1943693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        info->mOwnedByComponent = true;
1944693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1945693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        ++mCodecSpecificDataIndex;
1946693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return;
1947693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1948693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1949693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err;
1950134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber
19517f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber    bool signalEOS = false;
19527f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber    int64_t timestampUs = 0;
1953693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
19547f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber    size_t offset = 0;
19557f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber    int32_t n = 0;
19567f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber    for (;;) {
19577f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber        MediaBuffer *srcBuffer;
19587f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber        if (mSeekTimeUs >= 0) {
19597f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber            if (mLeftOverBuffer) {
19607f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber                mLeftOverBuffer->release();
19617f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber                mLeftOverBuffer = NULL;
19627f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber            }
1963693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
19647f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber            MediaSource::ReadOptions options;
19657f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber            options.setSeekTo(mSeekTimeUs);
1966693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
19677f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber            mSeekTimeUs = -1;
19687f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber            mBufferFilled.signal();
1969693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
19707f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber            err = mSource->read(&srcBuffer, &options);
19717f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber        } else if (mLeftOverBuffer) {
19727f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber            srcBuffer = mLeftOverBuffer;
19737f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber            mLeftOverBuffer = NULL;
19747f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber
19757f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber            err = OK;
19767f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber        } else {
19777f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber            err = mSource->read(&srcBuffer);
19787f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber        }
1979134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber
19807f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber        if (err != OK) {
19817f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber            signalEOS = true;
19827f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber            mFinalStatus = err;
19837f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber            mSignalledEOS = true;
19847f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber            break;
19857f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber        }
1986693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
19877f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber        size_t remainingBytes = info->mSize - offset;
1988c017cfcc24dd63c7efde5747a6ed2d4053788abcAndreas Huber
19897f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber        if (srcBuffer->range_length() > remainingBytes) {
19907f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber            if (offset == 0) {
19917f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber                CODEC_LOGE(
19927f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber                     "Codec's input buffers are too small to accomodate "
19937f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber                     "buffer read from source (info->mSize = %d, srcLength = %d)",
19947f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber                     info->mSize, srcBuffer->range_length());
1995c017cfcc24dd63c7efde5747a6ed2d4053788abcAndreas Huber
19967f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber                srcBuffer->release();
19977f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber                srcBuffer = NULL;
19987f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber
19997f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber                setState(ERROR);
20007f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber                return;
20017f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber            }
20027f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber
20037f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber            mLeftOverBuffer = srcBuffer;
20047f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber            break;
2005693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
20067f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber
20077f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber        memcpy((uint8_t *)info->mData + offset,
2008693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber               (const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(),
20097f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber               srcBuffer->range_length());
2010693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2011d2c6894b56a538aa807e20d3ef421807cd55c009Andreas Huber        int64_t lastBufferTimeUs;
2012d2c6894b56a538aa807e20d3ef421807cd55c009Andreas Huber        CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &lastBufferTimeUs));
2013d2c6894b56a538aa807e20d3ef421807cd55c009Andreas Huber        CHECK(timestampUs >= 0);
2014d2c6894b56a538aa807e20d3ef421807cd55c009Andreas Huber
20157f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber        if (offset == 0) {
2016d2c6894b56a538aa807e20d3ef421807cd55c009Andreas Huber            timestampUs = lastBufferTimeUs;
2017693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2018693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
20197f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber        offset += srcBuffer->range_length();
20207f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber
2021693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        srcBuffer->release();
2022693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        srcBuffer = NULL;
20237f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber
20247f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber        ++n;
20257f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber
20267f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber        if (!(mQuirks & kSupportsMultipleFramesPerInputBuffer)) {
20277f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber            break;
20287f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber        }
2029d2c6894b56a538aa807e20d3ef421807cd55c009Andreas Huber
2030d2c6894b56a538aa807e20d3ef421807cd55c009Andreas Huber        int64_t coalescedDurationUs = lastBufferTimeUs - timestampUs;
2031d2c6894b56a538aa807e20d3ef421807cd55c009Andreas Huber
2032d2c6894b56a538aa807e20d3ef421807cd55c009Andreas Huber        if (coalescedDurationUs > 250000ll) {
2033d2c6894b56a538aa807e20d3ef421807cd55c009Andreas Huber            // Don't coalesce more than 250ms worth of encoded data at once.
2034d2c6894b56a538aa807e20d3ef421807cd55c009Andreas Huber            break;
2035d2c6894b56a538aa807e20d3ef421807cd55c009Andreas Huber        }
2036693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
203736efa039efaae4526791336cb688032d22b34becAndreas Huber
20387f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber    if (n > 1) {
20397f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber        LOGV("coalesced %d frames into one input buffer", n);
20407f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber    }
20417f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber
20427f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber    OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
20437f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber
20447f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber    if (signalEOS) {
20457f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber        flags |= OMX_BUFFERFLAG_EOS;
20467f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber    } else {
20477f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber        mNoMoreOutputData = false;
20487f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber    }
20497f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber
20507f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber    CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d), "
20517f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber               "timestamp %lld us (%.2f secs)",
20527f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber               info->mBuffer, offset,
20537f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber               timestampUs, timestampUs / 1E6);
20547f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber
2055318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->emptyBuffer(
20567f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber            mNode, info->mBuffer, 0, offset,
205748c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber            flags, timestampUs);
205836efa039efaae4526791336cb688032d22b34becAndreas Huber
205936efa039efaae4526791336cb688032d22b34becAndreas Huber    if (err != OK) {
206036efa039efaae4526791336cb688032d22b34becAndreas Huber        setState(ERROR);
206136efa039efaae4526791336cb688032d22b34becAndreas Huber        return;
206236efa039efaae4526791336cb688032d22b34becAndreas Huber    }
206336efa039efaae4526791336cb688032d22b34becAndreas Huber
206436efa039efaae4526791336cb688032d22b34becAndreas Huber    info->mOwnedByComponent = true;
206530ab66297501757d745b9ae10da61adcd891f497Andreas Huber
206630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    // This component does not ever signal the EOS flag on output buffers,
206730ab66297501757d745b9ae10da61adcd891f497Andreas Huber    // Thanks for nothing.
206830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    if (mSignalledEOS && !strcmp(mComponentName, "OMX.TI.Video.encoder")) {
206930ab66297501757d745b9ae10da61adcd891f497Andreas Huber        mNoMoreOutputData = true;
207030ab66297501757d745b9ae10da61adcd891f497Andreas Huber        mBufferFilled.signal();
207130ab66297501757d745b9ae10da61adcd891f497Andreas Huber    }
2072693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2073693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2074693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::fillOutputBuffer(BufferInfo *info) {
2075693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(info->mOwnedByComponent, false);
2076693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
20771beb760d920561679862ded945a04e370368c7f7Andreas Huber    if (mNoMoreOutputData) {
20787a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        CODEC_LOGV("There is no more output data available, not "
20791beb760d920561679862ded945a04e370368c7f7Andreas Huber             "calling fillOutputBuffer");
20801beb760d920561679862ded945a04e370368c7f7Andreas Huber        return;
20811beb760d920561679862ded945a04e370368c7f7Andreas Huber    }
20821beb760d920561679862ded945a04e370368c7f7Andreas Huber
20837a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    CODEC_LOGV("Calling fill_buffer on buffer %p", info->mBuffer);
2084318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->fillBuffer(mNode, info->mBuffer);
20857110385b31c7bc65c8a923a09689ebb0c4a1e07aAndreas Huber
20867110385b31c7bc65c8a923a09689ebb0c4a1e07aAndreas Huber    if (err != OK) {
20877110385b31c7bc65c8a923a09689ebb0c4a1e07aAndreas Huber        CODEC_LOGE("fillBuffer failed w/ error 0x%08x", err);
20887110385b31c7bc65c8a923a09689ebb0c4a1e07aAndreas Huber
20897110385b31c7bc65c8a923a09689ebb0c4a1e07aAndreas Huber        setState(ERROR);
20907110385b31c7bc65c8a923a09689ebb0c4a1e07aAndreas Huber        return;
20917110385b31c7bc65c8a923a09689ebb0c4a1e07aAndreas Huber    }
2092693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2093693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    info->mOwnedByComponent = true;
2094693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2095693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2096693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::drainInputBuffer(IOMX::buffer_id buffer) {
2097693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
2098693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
2099693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if ((*buffers)[i].mBuffer == buffer) {
2100693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            drainInputBuffer(&buffers->editItemAt(i));
2101693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            return;
2102693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2103693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2104693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2105693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(!"should not be here.");
2106693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2107693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2108693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::fillOutputBuffer(IOMX::buffer_id buffer) {
2109693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
2110693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
2111693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if ((*buffers)[i].mBuffer == buffer) {
2112693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            fillOutputBuffer(&buffers->editItemAt(i));
2113693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            return;
2114693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2115693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2116693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2117693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(!"should not be here.");
2118693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2119693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2120693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::setState(State newState) {
2121693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mState = newState;
2122693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mAsyncCompletion.signal();
2123693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2124693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    // This may cause some spurious wakeups but is necessary to
2125693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    // unblock the reader if we enter ERROR state.
2126693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mBufferFilled.signal();
2127693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2128693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2129e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Hubervoid OMXCodec::setRawAudioFormat(
2130e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
2131e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
21327a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&pcmParams);
2133e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.nPortIndex = portIndex;
2134e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
2135318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
2136e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2137e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
2138e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    CHECK_EQ(err, OK);
2139e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
2140e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.nChannels = numChannels;
2141e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
2142e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.bInterleaved = OMX_TRUE;
2143e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.nBitPerSample = 16;
2144e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.nSamplingRate = sampleRate;
2145e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2146e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
2147e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    if (numChannels == 1) {
2148e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelCF;
2149e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    } else {
2150e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        CHECK_EQ(numChannels, 2);
2151e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
2152e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
2153e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        pcmParams.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
2154e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
2155e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
2156318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
2157e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2158e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
2159e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    CHECK_EQ(err, OK);
2160e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber}
2161e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
2162c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Hubervoid OMXCodec::setAMRFormat(bool isWAMR) {
2163c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    OMX_U32 portIndex = mIsEncoder ? kPortIndexOutput : kPortIndexInput;
2164693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2165c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
2166c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    InitOMXParams(&def);
2167c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    def.nPortIndex = portIndex;
2168456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber
2169c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    status_t err =
2170c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2171456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber
2172c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    CHECK_EQ(err, OK);
2173456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber
2174c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
2175c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    def.eAMRBandMode =
2176c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber        isWAMR ? OMX_AUDIO_AMRBandModeWB0 : OMX_AUDIO_AMRBandModeNB0;
2177456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber
2178c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2179c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    CHECK_EQ(err, OK);
2180456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber
2181456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber    ////////////////////////
2182456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber
2183456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber    if (mIsEncoder) {
2184456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber        sp<MetaData> format = mSource->getFormat();
2185456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber        int32_t sampleRate;
2186456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber        int32_t numChannels;
2187456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber        CHECK(format->findInt32(kKeySampleRate, &sampleRate));
2188693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(format->findInt32(kKeyChannelCount, &numChannels));
2189693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2190e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
2191e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
2192e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber}
2193693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2194e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Hubervoid OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate) {
2195e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    if (mIsEncoder) {
2196e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
2197e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    } else {
2198e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
21997a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        InitOMXParams(&profile);
2200e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        profile.nPortIndex = kPortIndexInput;
2201693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2202318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        status_t err = mOMX->getParameter(
2203e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2204693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(err, OK);
2205693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2206e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        profile.nChannels = numChannels;
2207e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        profile.nSampleRate = sampleRate;
2208e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
2209693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2210318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        err = mOMX->setParameter(
2211e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2212693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(err, OK);
2213693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2214693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2215693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2216693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::setImageOutputFormat(
2217693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) {
22187a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height);
2219693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2220693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#if 0
2221693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_INDEXTYPE index;
2222693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err = mOMX->get_extension_index(
2223693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index);
2224693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
2225693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2226693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    err = mOMX->set_config(mNode, index, &format, sizeof(format));
2227693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
2228693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#endif
2229693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2230693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
22317a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
2232693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexOutput;
2233693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2234318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
2235693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2236693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
2237693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2238693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(def.eDomain, OMX_PortDomainImage);
2239693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2240693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
2241bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
2242693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused);
2243693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    imageDef->eColorFormat = format;
2244693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    imageDef->nFrameWidth = width;
2245693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    imageDef->nFrameHeight = height;
2246693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2247693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (format) {
2248693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_COLOR_FormatYUV420PackedPlanar:
2249693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_COLOR_FormatYUV411Planar:
2250693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2251693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            def.nBufferSize = (width * height * 3) / 2;
2252693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2253693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2254693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2255693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_COLOR_FormatCbYCrY:
2256693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2257693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            def.nBufferSize = width * height * 2;
2258693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2259693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2260693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2261693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_COLOR_Format32bitARGB8888:
2262693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2263693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            def.nBufferSize = width * height * 4;
2264693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2265693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2266693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2267195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber        case OMX_COLOR_Format16bitARGB4444:
2268195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber        case OMX_COLOR_Format16bitARGB1555:
2269195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber        case OMX_COLOR_Format16bitRGB565:
2270195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber        case OMX_COLOR_Format16bitBGR565:
2271195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber        {
2272195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber            def.nBufferSize = width * height * 2;
2273195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber            break;
2274195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber        }
2275195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber
2276693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
2277693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(!"Should not be here. Unknown color format.");
2278693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2279693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2280693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
22817530e9c708275c273c134c36c68179f511c1940eAndreas Huber    def.nBufferCountActual = def.nBufferCountMin;
22827530e9c708275c273c134c36c68179f511c1940eAndreas Huber
2283318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
2284693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2285693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
22867530e9c708275c273c134c36c68179f511c1940eAndreas Huber}
2287693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
22887530e9c708275c273c134c36c68179f511c1940eAndreas Hubervoid OMXCodec::setJPEGInputFormat(
22897530e9c708275c273c134c36c68179f511c1940eAndreas Huber        OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) {
22907530e9c708275c273c134c36c68179f511c1940eAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
22917a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
2292693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexInput;
2293693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2294318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
2295693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2296693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
2297693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
22987530e9c708275c273c134c36c68179f511c1940eAndreas Huber    CHECK_EQ(def.eDomain, OMX_PortDomainImage);
22997530e9c708275c273c134c36c68179f511c1940eAndreas Huber    OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
23007530e9c708275c273c134c36c68179f511c1940eAndreas Huber
2301693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingJPEG);
2302693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    imageDef->nFrameWidth = width;
2303693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    imageDef->nFrameHeight = height;
2304693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
23057530e9c708275c273c134c36c68179f511c1940eAndreas Huber    def.nBufferSize = compressedSize;
2306693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nBufferCountActual = def.nBufferCountMin;
2307693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2308318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
2309693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2310693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
2311693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2312693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2313693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::addCodecSpecificData(const void *data, size_t size) {
2314693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CodecSpecificData *specific =
2315693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1);
2316693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2317693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    specific->mSize = size;
2318693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    memcpy(specific->mData, data, size);
2319693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2320693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mCodecSpecificData.push(specific);
2321693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2322693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2323693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::clearCodecSpecificData() {
2324693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < mCodecSpecificData.size(); ++i) {
2325693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        free(mCodecSpecificData.editItemAt(i));
2326693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2327693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mCodecSpecificData.clear();
2328693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mCodecSpecificDataIndex = 0;
2329693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2330693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2331693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::start(MetaData *) {
2332284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber    Mutex::Autolock autoLock(mLock);
2333284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber
2334693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mState != LOADED) {
2335693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return UNKNOWN_ERROR;
2336693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2337bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
2338693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    sp<MetaData> params = new MetaData;
2339dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    if (mQuirks & kWantsNALFragments) {
2340dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        params->setInt32(kKeyWantsNALFragments, true);
2341693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2342693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err = mSource->start(params.get());
2343693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2344693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (err != OK) {
2345693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return err;
2346693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2347693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2348693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mCodecSpecificDataIndex = 0;
2349284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber    mInitialBufferSubmit = true;
2350693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mSignalledEOS = false;
2351693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mNoMoreOutputData = false;
23527f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber    mOutputPortSettingsHaveChanged = false;
2353693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mSeekTimeUs = -1;
2354693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mFilledBuffers.clear();
2355693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2356693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return init();
2357693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2358693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2359693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::stop() {
2360ec9dd59902c8beea4ba6a842f3a843d46150d949Andreas Huber    CODEC_LOGV("stop mState=%d", mState);
2361693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2362693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Mutex::Autolock autoLock(mLock);
2363693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2364693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    while (isIntermediateState(mState)) {
2365693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mAsyncCompletion.wait(mLock);
2366693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2367693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2368693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (mState) {
2369693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case LOADED:
2370693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case ERROR:
2371693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2372693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2373693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case EXECUTING:
2374693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2375693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            setState(EXECUTING_TO_IDLE);
2376693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
23778297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber            if (mQuirks & kRequiresFlushBeforeShutdown) {
23787a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                CODEC_LOGV("This component requires a flush before transitioning "
23798297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                     "from EXECUTING to IDLE...");
23808297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber
23818297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                bool emulateInputFlushCompletion =
23828297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    !flushPortAsync(kPortIndexInput);
23838297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber
23848297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                bool emulateOutputFlushCompletion =
23858297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    !flushPortAsync(kPortIndexOutput);
2386693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
23878297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                if (emulateInputFlushCompletion) {
23888297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    onCmdComplete(OMX_CommandFlush, kPortIndexInput);
23898297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                }
23908297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber
23918297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                if (emulateOutputFlushCompletion) {
23928297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
23938297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                }
23948297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber            } else {
23958297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
23968297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
23978297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber
23988297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                status_t err =
2399318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                    mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
24008297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                CHECK_EQ(err, OK);
24018297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber            }
2402693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2403693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            while (mState != LOADED && mState != ERROR) {
2404693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mAsyncCompletion.wait(mLock);
2405693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
2406693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2407693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2408693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2409693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2410693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
2411693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2412693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(!"should not be here.");
2413693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2414693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2415693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2416693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
24177f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber    if (mLeftOverBuffer) {
24187f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber        mLeftOverBuffer->release();
24197f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber        mLeftOverBuffer = NULL;
24207f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber    }
24217f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber
2422693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mSource->stop();
2423693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2424ec9dd59902c8beea4ba6a842f3a843d46150d949Andreas Huber    CODEC_LOGV("stopped");
2425ec9dd59902c8beea4ba6a842f3a843d46150d949Andreas Huber
2426693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return OK;
2427693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2428693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2429693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MetaData> OMXCodec::getFormat() {
24307f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber    Mutex::Autolock autoLock(mLock);
24317f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber
2432693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return mOutputFormat;
2433693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2434693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2435693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::read(
2436693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        MediaBuffer **buffer, const ReadOptions *options) {
2437693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    *buffer = NULL;
2438693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2439693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Mutex::Autolock autoLock(mLock);
2440693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2441450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber    if (mState != EXECUTING && mState != RECONFIGURING) {
2442450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber        return UNKNOWN_ERROR;
2443450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber    }
2444450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber
24457e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    bool seeking = false;
24467e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    int64_t seekTimeUs;
24477e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if (options && options->getSeekTo(&seekTimeUs)) {
24487e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        seeking = true;
24497e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
24507e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
2451284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber    if (mInitialBufferSubmit) {
2452284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber        mInitialBufferSubmit = false;
2453284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber
24547e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        if (seeking) {
24557e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            CHECK(seekTimeUs >= 0);
24567e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            mSeekTimeUs = seekTimeUs;
24577e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
24587e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            // There's no reason to trigger the code below, there's
24597e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            // nothing to flush yet.
24607e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            seeking = false;
24617e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        }
24627e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
2463284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber        drainInputBuffers();
2464284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber
2465450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber        if (mState == EXECUTING) {
2466450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber            // Otherwise mState == RECONFIGURING and this code will trigger
2467450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber            // after the output port is reenabled.
2468450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber            fillOutputBuffers();
2469450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber        }
2470693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2471693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
24727e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if (seeking) {
24737a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6);
2474693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2475693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mSignalledEOS = false;
2476693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2477693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(seekTimeUs >= 0);
2478693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mSeekTimeUs = seekTimeUs;
2479693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2480693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mFilledBuffers.clear();
2481693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2482693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(mState, EXECUTING);
2483693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
24841beb760d920561679862ded945a04e370368c7f7Andreas Huber        bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput);
24851beb760d920561679862ded945a04e370368c7f7Andreas Huber        bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput);
24861beb760d920561679862ded945a04e370368c7f7Andreas Huber
24871beb760d920561679862ded945a04e370368c7f7Andreas Huber        if (emulateInputFlushCompletion) {
24881beb760d920561679862ded945a04e370368c7f7Andreas Huber            onCmdComplete(OMX_CommandFlush, kPortIndexInput);
24891beb760d920561679862ded945a04e370368c7f7Andreas Huber        }
24901beb760d920561679862ded945a04e370368c7f7Andreas Huber
24911beb760d920561679862ded945a04e370368c7f7Andreas Huber        if (emulateOutputFlushCompletion) {
24921beb760d920561679862ded945a04e370368c7f7Andreas Huber            onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
24931beb760d920561679862ded945a04e370368c7f7Andreas Huber        }
2494134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber
2495134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber        while (mSeekTimeUs >= 0) {
2496134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber            mBufferFilled.wait(mLock);
2497134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber        }
2498693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2499693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2500693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) {
2501693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mBufferFilled.wait(mLock);
2502693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2503693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2504693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mState == ERROR) {
2505693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return UNKNOWN_ERROR;
2506693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2507693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2508693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mFilledBuffers.empty()) {
25095295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber        return mSignalledEOS ? mFinalStatus : ERROR_END_OF_STREAM;
2510693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2511693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
25127f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber    if (mOutputPortSettingsHaveChanged) {
25137f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber        mOutputPortSettingsHaveChanged = false;
25147f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber
25157f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber        return INFO_FORMAT_CHANGED;
25167f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber    }
25177f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber
2518693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t index = *mFilledBuffers.begin();
2519693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mFilledBuffers.erase(mFilledBuffers.begin());
2520693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2521693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
2522693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    info->mMediaBuffer->add_ref();
2523693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    *buffer = info->mMediaBuffer;
2524693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2525693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return OK;
2526693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2527693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2528693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::signalBufferReturned(MediaBuffer *buffer) {
2529693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Mutex::Autolock autoLock(mLock);
2530693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2531693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
2532693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
2533693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        BufferInfo *info = &buffers->editItemAt(i);
2534693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2535693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (info->mMediaBuffer == buffer) {
2536693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED);
2537693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            fillOutputBuffer(info);
2538693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            return;
2539693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2540693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2541693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2542693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(!"should not be here.");
2543693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2544693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2545693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) {
2546693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    static const char *kNames[] = {
2547693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingUnused",
2548693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingAutoDetect",
2549693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingJPEG",
2550693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingJPEG2K",
2551693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingEXIF",
2552693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingTIFF",
2553693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingGIF",
2554693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingPNG",
2555693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingLZW",
2556693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingBMP",
2557693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    };
2558693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2559693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2560693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2561693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (type < 0 || (size_t)type >= numNames) {
2562693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return "UNKNOWN";
2563693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
2564693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return kNames[type];
2565693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2566693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2567693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2568693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const char *colorFormatString(OMX_COLOR_FORMATTYPE type) {
2569693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    static const char *kNames[] = {
2570693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatUnused",
2571693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatMonochrome",
2572693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format8bitRGB332",
2573693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format12bitRGB444",
2574693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format16bitARGB4444",
2575693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format16bitARGB1555",
2576693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format16bitRGB565",
2577693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format16bitBGR565",
2578693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format18bitRGB666",
2579693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format18bitARGB1665",
2580bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        "OMX_COLOR_Format19bitARGB1666",
2581693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format24bitRGB888",
2582693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format24bitBGR888",
2583693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format24bitARGB1887",
2584693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format25bitARGB1888",
2585693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format32bitBGRA8888",
2586693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format32bitARGB8888",
2587693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV411Planar",
2588693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV411PackedPlanar",
2589693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV420Planar",
2590693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV420PackedPlanar",
2591693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV420SemiPlanar",
2592693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV422Planar",
2593693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV422PackedPlanar",
2594693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV422SemiPlanar",
2595693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYCbYCr",
2596693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYCrYCb",
2597693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatCbYCrY",
2598693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatCrYCbY",
2599693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV444Interleaved",
2600693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatRawBayer8bit",
2601693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatRawBayer10bit",
2602693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatRawBayer8bitcompressed",
2603bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        "OMX_COLOR_FormatL2",
2604bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        "OMX_COLOR_FormatL4",
2605bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        "OMX_COLOR_FormatL8",
2606bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        "OMX_COLOR_FormatL16",
2607bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        "OMX_COLOR_FormatL24",
2608693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatL32",
2609693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV420PackedSemiPlanar",
2610693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV422PackedSemiPlanar",
2611693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format18BitBGR666",
2612693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format24BitARGB6666",
2613693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format24BitABGR6666",
2614693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    };
2615693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2616693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2617693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2618693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) {
2619693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar";
2620693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else if (type < 0 || (size_t)type >= numNames) {
2621693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return "UNKNOWN";
2622693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
2623693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return kNames[type];
2624693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2625693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2626693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2627693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) {
2628693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    static const char *kNames[] = {
2629693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingUnused",
2630693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingAutoDetect",
2631693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingMPEG2",
2632693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingH263",
2633693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingMPEG4",
2634693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingWMV",
2635693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingRV",
2636693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingAVC",
2637693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingMJPEG",
2638693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    };
2639693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2640693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2641693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2642693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (type < 0 || (size_t)type >= numNames) {
2643693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return "UNKNOWN";
2644693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
2645693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return kNames[type];
2646693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2647693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2648693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2649693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) {
2650693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    static const char *kNames[] = {
2651693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingUnused",
2652693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingAutoDetect",
2653693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingPCM",
2654693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingADPCM",
2655693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingAMR",
2656693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingGSMFR",
2657693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingGSMEFR",
2658693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingGSMHR",
2659693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingPDCFR",
2660693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingPDCEFR",
2661693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingPDCHR",
2662693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingTDMAFR",
2663693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingTDMAEFR",
2664693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingQCELP8",
2665693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingQCELP13",
2666693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingEVRC",
2667693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingSMV",
2668693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingG711",
2669693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingG723",
2670693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingG726",
2671693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingG729",
2672693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingAAC",
2673693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingMP3",
2674693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingSBC",
2675693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingVORBIS",
2676693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingWMA",
2677693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingRA",
2678693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingMIDI",
2679693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    };
2680693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2681693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2682693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2683693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (type < 0 || (size_t)type >= numNames) {
2684693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return "UNKNOWN";
2685693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
2686693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return kNames[type];
2687693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2688693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2689693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2690693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) {
2691693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    static const char *kNames[] = {
2692693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_PCMModeLinear",
2693693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_PCMModeALaw",
2694693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_PCMModeMULaw",
2695693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    };
2696693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2697693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2698693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2699693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (type < 0 || (size_t)type >= numNames) {
2700693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return "UNKNOWN";
2701693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
2702693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return kNames[type];
2703693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2704693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2705693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
27062f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huberstatic const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) {
27072f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    static const char *kNames[] = {
27082f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeUnused",
27092f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB0",
27102f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB1",
27112f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB2",
27122f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB3",
27132f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB4",
27142f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB5",
27152f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB6",
27162f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB7",
27172f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB0",
27182f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB1",
27192f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB2",
27202f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB3",
27212f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB4",
27222f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB5",
27232f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB6",
27242f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB7",
27252f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB8",
27262f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    };
27272f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
27282f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
27292f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
27302f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    if (type < 0 || (size_t)type >= numNames) {
27312f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        return "UNKNOWN";
27322f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    } else {
27332f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        return kNames[type];
27342f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    }
27352f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber}
27362f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
27372f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huberstatic const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) {
27382f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    static const char *kNames[] = {
27392f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRFrameFormatConformance",
27402f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRFrameFormatIF1",
27412f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRFrameFormatIF2",
27422f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRFrameFormatFSF",
27432f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRFrameFormatRTPPayload",
27442f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRFrameFormatITU",
27452f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    };
27462f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
27472f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
27482f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
27492f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    if (type < 0 || (size_t)type >= numNames) {
27502f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        return "UNKNOWN";
27512f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    } else {
27522f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        return kNames[type];
27532f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    }
27542f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber}
2755693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2756693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
2757693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
27587a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
2759693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = portIndex;
2760693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2761318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
2762693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2763693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
2764693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2765693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output");
2766693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2767693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput)
2768693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber          || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput));
2769693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2770693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    printf("  nBufferCountActual = %ld\n", def.nBufferCountActual);
2771693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    printf("  nBufferCountMin = %ld\n", def.nBufferCountMin);
2772693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    printf("  nBufferSize = %ld\n", def.nBufferSize);
2773693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2774693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (def.eDomain) {
2775693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_PortDomainImage:
2776693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2777693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
2778693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2779693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("\n");
2780693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  // Image\n");
2781693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  nFrameWidth = %ld\n", imageDef->nFrameWidth);
2782693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  nFrameHeight = %ld\n", imageDef->nFrameHeight);
2783693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  nStride = %ld\n", imageDef->nStride);
2784693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2785693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  eCompressionFormat = %s\n",
2786693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                   imageCompressionFormatString(imageDef->eCompressionFormat));
2787693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2788693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  eColorFormat = %s\n",
2789693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                   colorFormatString(imageDef->eColorFormat));
2790693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2791693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2792693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2793693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2794693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_PortDomainVideo:
2795693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2796693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
2797693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2798693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("\n");
2799693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  // Video\n");
2800693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  nFrameWidth = %ld\n", videoDef->nFrameWidth);
2801693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  nFrameHeight = %ld\n", videoDef->nFrameHeight);
2802693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  nStride = %ld\n", videoDef->nStride);
2803693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2804693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  eCompressionFormat = %s\n",
2805693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                   videoCompressionFormatString(videoDef->eCompressionFormat));
2806693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2807693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  eColorFormat = %s\n",
2808693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                   colorFormatString(videoDef->eColorFormat));
2809693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2810693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2811693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2812693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2813693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_PortDomainAudio:
2814693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2815693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
2816693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2817693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("\n");
2818693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  // Audio\n");
2819693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  eEncoding = %s\n",
2820693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                   audioCodingTypeString(audioDef->eEncoding));
2821693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2822693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) {
2823693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                OMX_AUDIO_PARAM_PCMMODETYPE params;
28247a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                InitOMXParams(&params);
2825693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                params.nPortIndex = portIndex;
2826693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2827318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                err = mOMX->getParameter(
2828693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
2829693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
2830693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2831693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                printf("  nSamplingRate = %ld\n", params.nSamplingRate);
2832693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                printf("  nChannels = %ld\n", params.nChannels);
2833693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                printf("  bInterleaved = %d\n", params.bInterleaved);
2834693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                printf("  nBitPerSample = %ld\n", params.nBitPerSample);
2835693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2836693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                printf("  eNumData = %s\n",
2837693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                       params.eNumData == OMX_NumericalDataSigned
2838693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        ? "signed" : "unsigned");
2839693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2840693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                printf("  ePCMMode = %s\n", audioPCMModeString(params.ePCMMode));
28412f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber            } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) {
28422f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                OMX_AUDIO_PARAM_AMRTYPE amr;
28432f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                InitOMXParams(&amr);
28442f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                amr.nPortIndex = portIndex;
28452f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
2846318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                err = mOMX->getParameter(
28472f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                        mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
28482f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                CHECK_EQ(err, OK);
28492f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
28502f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                printf("  nChannels = %ld\n", amr.nChannels);
28512f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                printf("  eAMRBandMode = %s\n",
28522f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                        amrBandModeString(amr.eAMRBandMode));
28532f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                printf("  eAMRFrameFormat = %s\n",
28542f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                        amrFrameFormatString(amr.eAMRFrameFormat));
2855693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
2856693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2857693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2858693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2859693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2860693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
2861693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2862693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  // Unknown\n");
2863693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2864693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2865693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2866693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2867693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    printf("}\n");
2868693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2869693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2870693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
2871693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mOutputFormat = new MetaData;
2872693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mOutputFormat->setCString(kKeyDecoderComponent, mComponentName);
2873693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2874693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
28757a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
2876693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexOutput;
2877693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2878318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
2879693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2880693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
2881693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2882693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (def.eDomain) {
2883693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_PortDomainImage:
2884693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2885693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
2886693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused);
2887693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
288818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
2889693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat);
2890693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth);
2891693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight);
2892693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2893693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2894693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2895693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_PortDomainAudio:
2896693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2897693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio;
2898693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2899e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) {
2900e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                OMX_AUDIO_PARAM_PCMMODETYPE params;
29017a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                InitOMXParams(&params);
2902e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                params.nPortIndex = kPortIndexOutput;
2903693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2904318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                err = mOMX->getParameter(
2905e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                        mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
2906e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                CHECK_EQ(err, OK);
2907693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2908e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                CHECK_EQ(params.eNumData, OMX_NumericalDataSigned);
2909e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                CHECK_EQ(params.nBitPerSample, 16);
2910e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                CHECK_EQ(params.ePCMMode, OMX_AUDIO_PCMModeLinear);
2911693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2912e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                int32_t numChannels, sampleRate;
2913e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                inputFormat->findInt32(kKeyChannelCount, &numChannels);
2914e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                inputFormat->findInt32(kKeySampleRate, &sampleRate);
2915693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2916e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                if ((OMX_U32)numChannels != params.nChannels) {
2917e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                    LOGW("Codec outputs a different number of channels than "
291878d529eb330ab6c04b5c694403f5a7e7de4b702fAndreas Huber                         "the input stream contains (contains %d channels, "
291978d529eb330ab6c04b5c694403f5a7e7de4b702fAndreas Huber                         "codec outputs %ld channels).",
292078d529eb330ab6c04b5c694403f5a7e7de4b702fAndreas Huber                         numChannels, params.nChannels);
2921e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                }
292237940eefcba982836b579fe1ffec6cada72b0974Andreas Huber
292318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                mOutputFormat->setCString(
292418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
292537940eefcba982836b579fe1ffec6cada72b0974Andreas Huber
2926e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                // Use the codec-advertised number of channels, as some
2927e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                // codecs appear to output stereo even if the input data is
292878d529eb330ab6c04b5c694403f5a7e7de4b702fAndreas Huber                // mono. If we know the codec lies about this information,
292978d529eb330ab6c04b5c694403f5a7e7de4b702fAndreas Huber                // use the actual number of channels instead.
293078d529eb330ab6c04b5c694403f5a7e7de4b702fAndreas Huber                mOutputFormat->setInt32(
293178d529eb330ab6c04b5c694403f5a7e7de4b702fAndreas Huber                        kKeyChannelCount,
293278d529eb330ab6c04b5c694403f5a7e7de4b702fAndreas Huber                        (mQuirks & kDecoderLiesAboutNumberOfChannels)
293378d529eb330ab6c04b5c694403f5a7e7de4b702fAndreas Huber                            ? numChannels : params.nChannels);
293437940eefcba982836b579fe1ffec6cada72b0974Andreas Huber
2935e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                // The codec-reported sampleRate is not reliable...
2936e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                mOutputFormat->setInt32(kKeySampleRate, sampleRate);
2937e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) {
29382f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                OMX_AUDIO_PARAM_AMRTYPE amr;
29392f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                InitOMXParams(&amr);
29402f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                amr.nPortIndex = kPortIndexOutput;
29412f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
2942318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                err = mOMX->getParameter(
29432f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                        mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
29442f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                CHECK_EQ(err, OK);
29452f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
29462f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                CHECK_EQ(amr.nChannels, 1);
29472f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                mOutputFormat->setInt32(kKeyChannelCount, 1);
29482f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
29492f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0
29502f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                    && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) {
295118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    mOutputFormat->setCString(
295218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                            kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB);
29532f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                    mOutputFormat->setInt32(kKeySampleRate, 8000);
29542f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0
29552f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                            && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) {
295618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    mOutputFormat->setCString(
295718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                            kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB);
29582f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                    mOutputFormat->setInt32(kKeySampleRate, 16000);
29592f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                } else {
29602f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                    CHECK(!"Unknown AMR band mode.");
29612f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                }
2962e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) {
296318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                mOutputFormat->setCString(
296418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
2965e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            } else {
2966e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                CHECK(!"Should not be here. Unknown audio encoding.");
2967e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            }
2968693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2969693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2970693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2971693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_PortDomainVideo:
2972693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2973693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2974693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2975693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) {
297618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                mOutputFormat->setCString(
297718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
2978693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) {
297918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                mOutputFormat->setCString(
298018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
2981693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) {
298218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                mOutputFormat->setCString(
298318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
2984693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) {
298518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                mOutputFormat->setCString(
298618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
2987693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else {
2988693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK(!"Unknown compression format.");
2989693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
2990693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2991693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (!strcmp(mComponentName, "OMX.PV.avcdec")) {
2992693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                // This component appears to be lying to me.
2993693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mOutputFormat->setInt32(
2994693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        kKeyWidth, (video_def->nFrameWidth + 15) & -16);
2995693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mOutputFormat->setInt32(
2996693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        kKeyHeight, (video_def->nFrameHeight + 15) & -16);
2997693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else {
2998693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth);
2999693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight);
3000693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
3001693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
3002693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat);
3003693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
3004693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
3005693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
3006693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
3007693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
3008693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(!"should not be here, neither audio nor video.");
3009693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
3010693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
3011693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
3012693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
3013693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
301418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber////////////////////////////////////////////////////////////////////////////////
301518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
301618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatus_t QueryCodecs(
301718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        const sp<IOMX> &omx,
301818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        const char *mime, bool queryDecoders,
301918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        Vector<CodecCapabilities> *results) {
302018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    results->clear();
302118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
302218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    for (int index = 0;; ++index) {
302318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        const char *componentName;
302418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
302518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        if (!queryDecoders) {
302618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            componentName = GetCodec(
302718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    kEncoderInfo, sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]),
302818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    mime, index);
302918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        } else {
303018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            componentName = GetCodec(
303118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    kDecoderInfo, sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]),
303218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    mime, index);
303318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        }
303418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
303518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        if (!componentName) {
303618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            return OK;
303718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        }
303818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
303908a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber        if (strncmp(componentName, "OMX.", 4)) {
304008a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber            // Not an OpenMax component but a software codec.
304108a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber
304208a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber            results->push();
304308a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber            CodecCapabilities *caps = &results->editItemAt(results->size() - 1);
304408a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber            caps->mComponentName = componentName;
304508a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber
304608a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber            continue;
304708a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber        }
304808a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber
3049318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        sp<OMXCodecObserver> observer = new OMXCodecObserver;
305018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        IOMX::node_id node;
3051318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        status_t err = omx->allocateNode(componentName, observer, &node);
305218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
305318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        if (err != OK) {
305418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            continue;
305518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        }
305618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
30575e3cf6cf36feb3b73b8f8c0a8134c46f5bc85094James Dong        OMXCodec::setComponentRole(omx, node, !queryDecoders, mime);
305818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
305918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        results->push();
306018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        CodecCapabilities *caps = &results->editItemAt(results->size() - 1);
306118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        caps->mComponentName = componentName;
306218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
306318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
306418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        InitOMXParams(&param);
306518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
306618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        param.nPortIndex = queryDecoders ? 0 : 1;
306718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
306818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
3069318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            err = omx->getParameter(
307018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    node, OMX_IndexParamVideoProfileLevelQuerySupported,
307118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    &param, sizeof(param));
307218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
307318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            if (err != OK) {
307418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                break;
307518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            }
307618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
307718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            CodecProfileLevel profileLevel;
307818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            profileLevel.mProfile = param.eProfile;
307918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            profileLevel.mLevel = param.eLevel;
308018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
308118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            caps->mProfileLevels.push(profileLevel);
308218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        }
308318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
3084318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        CHECK_EQ(omx->freeNode(node), OK);
308518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    }
308618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber}
308718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
3088693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}  // namespace android
3089