OMXCodec.cpp revision 7eaa9c9385535b651064e02d05a8ffa4b2359281
1693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber/*
2693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * Copyright (C) 2009 The Android Open Source Project
3693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber *
4693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * you may not use this file except in compliance with the License.
6693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * You may obtain a copy of the License at
7693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber *
8693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber *
10693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * Unless required by applicable law or agreed to in writing, software
11693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * See the License for the specific language governing permissions and
14693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * limitations under the License.
15693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber */
16693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
17693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber//#define LOG_NDEBUG 0
18693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#define LOG_TAG "OMXCodec"
19693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <utils/Log.h>
20693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2192616b5655b7aef260480f60f2aabf98e821c8f3Andreas Huber#if BUILD_WITH_FULL_STAGEFRIGHT
22f44de515d3b6098a0b585865c1a0c7b20d3075a6Andreas Huber#include "include/AACDecoder.h"
234f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber#include "include/AMRNBDecoder.h"
24b841f14f8e51f2365945281fbfa54ef6a1b1b5a6Andreas Huber#include "include/AMRNBEncoder.h"
254f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber#include "include/AMRWBDecoder.h"
26609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#include "include/AVCDecoder.h"
273306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include "include/M4vH263Decoder.h"
28d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "include/MP3Decoder.h"
2992616b5655b7aef260480f60f2aabf98e821c8f3Andreas Huber#endif
3092616b5655b7aef260480f60f2aabf98e821c8f3Andreas Huber
3189e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "include/ESDS.h"
3289e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber
33693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <binder/IServiceManager.h>
34693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <binder/MemoryDealer.h>
35693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <binder/ProcessState.h>
36693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/IMediaPlayerService.h>
37693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MediaBuffer.h>
38693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MediaBufferGroup.h>
39693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MediaDebug.h>
4018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h>
41693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MediaExtractor.h>
42693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MetaData.h>
43693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/OMXCodec.h>
44bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber#include <media/stagefright/Utils.h>
45693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <utils/Vector.h>
46693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
47693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <OMX_Audio.h>
48693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <OMX_Component.h>
49693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
50693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubernamespace android {
51693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
52ec430b158df17b2c766f7750a96c35d3902f5f49Andreas Huberstatic const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
53ec430b158df17b2c766f7750a96c35d3902f5f49Andreas Huber
54693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstruct CodecInfo {
55693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    const char *mime;
56693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    const char *codec;
57693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber};
58693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
591af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber#if BUILD_WITH_FULL_STAGEFRIGHT
601af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber#define OPTIONAL(x,y) { x, y },
611af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
621af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber#define FACTORY_CREATE(name) \
631af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huberstatic sp<MediaSource> Make##name(const sp<MediaSource> &source) { \
641af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    return new name(source); \
651af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber}
661af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
671af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber#define FACTORY_REF(name) { #name, Make##name },
681af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
691af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas HuberFACTORY_CREATE(MP3Decoder)
701af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas HuberFACTORY_CREATE(AMRNBDecoder)
711af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas HuberFACTORY_CREATE(AMRWBDecoder)
721af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas HuberFACTORY_CREATE(AACDecoder)
731af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas HuberFACTORY_CREATE(AVCDecoder)
743306cfee3bf38ab207a0504e49c2d492bb73ffbfJames DongFACTORY_CREATE(M4vH263Decoder)
751af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas HuberFACTORY_CREATE(AMRNBEncoder)
761af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
771af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huberstatic sp<MediaSource> InstantiateSoftwareCodec(
781af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        const char *name, const sp<MediaSource> &source) {
791af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    struct FactoryInfo {
801af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        const char *name;
811af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        sp<MediaSource> (*CreateFunc)(const sp<MediaSource> &);
821af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    };
831af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
841af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    static const FactoryInfo kFactoryInfo[] = {
851af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        FACTORY_REF(MP3Decoder)
861af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        FACTORY_REF(AMRNBDecoder)
871af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        FACTORY_REF(AMRWBDecoder)
881af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        FACTORY_REF(AACDecoder)
891af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        FACTORY_REF(AVCDecoder)
903306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        FACTORY_REF(M4vH263Decoder)
911af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        FACTORY_REF(AMRNBEncoder)
921af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    };
931af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    for (size_t i = 0;
941af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber         i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) {
951af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        if (!strcmp(name, kFactoryInfo[i].name)) {
961af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber            return (*kFactoryInfo[i].CreateFunc)(source);
971af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        }
981af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    }
991af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
1001af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    return NULL;
1011af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber}
1021af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
1031af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber#undef FACTORY_REF
1041af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber#undef FACTORY_CREATE
1051af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
1061af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber#else
1071af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber#define OPTIONAL(x,y)
1081af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber#endif
1091af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
110693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const CodecInfo kDecoderInfo[] = {
11118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_IMAGE_JPEG, "OMX.TI.JPEG.decode" },
11218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" },
1131af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    OPTIONAL(MEDIA_MIMETYPE_AUDIO_MPEG, "MP3Decoder")
11418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.PV.mp3dec" },
11518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.decode" },
1161af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    OPTIONAL(MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBDecoder")
11718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.PV.amrdec" },
11818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.decode" },
1191af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    OPTIONAL(MEDIA_MIMETYPE_AUDIO_AMR_WB, "AMRWBDecoder")
12018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.PV.amrdec" },
12118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.decode" },
1221af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    OPTIONAL(MEDIA_MIMETYPE_AUDIO_AAC, "AACDecoder")
12318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacdec" },
12418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.decoder.mpeg4" },
12518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.Decoder" },
126fd1fe13b4584628d73df31717794e8e886d6bc39James Dong    OPTIONAL(MEDIA_MIMETYPE_VIDEO_MPEG4, "M4vH263Decoder")
12718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4dec" },
12818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.decoder.h263" },
12918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.Decoder" },
130fd1fe13b4584628d73df31717794e8e886d6bc39James Dong    OPTIONAL(MEDIA_MIMETYPE_VIDEO_H263, "M4vH263Decoder")
13118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263dec" },
13218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" },
13318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.Decoder" },
1341af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    OPTIONAL(MEDIA_MIMETYPE_VIDEO_AVC, "AVCDecoder")
13518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcdec" },
136693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber};
137693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
138693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const CodecInfo kEncoderInfo[] = {
13918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.encode" },
1401af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    OPTIONAL(MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBEncoder")
14118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.PV.amrencnb" },
14218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.encode" },
14318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.encode" },
14418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacenc" },
14518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.encoder.mpeg4" },
14618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.encoder" },
14718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4enc" },
14818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.encoder.h263" },
14918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.encoder" },
15018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263enc" },
15118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.encoder" },
15218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcenc" },
153693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber};
154693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1551af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber#undef OPTIONAL
1561af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
1578cd11d23197209e2c2bdb7980bc17e3f1257a118Andreas Huber#define CODEC_LOGI(x, ...) LOGI("[%s] "x, mComponentName, ##__VA_ARGS__)
1587a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber#define CODEC_LOGV(x, ...) LOGV("[%s] "x, mComponentName, ##__VA_ARGS__)
1597a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
160693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstruct OMXCodecObserver : public BnOMXObserver {
161318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMXCodecObserver() {
162318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
163318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
164318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    void setCodec(const sp<OMXCodec> &target) {
165318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        mTarget = target;
166693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
167693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
168693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    // from IOMXObserver
169318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    virtual void onMessage(const omx_message &msg) {
170693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        sp<OMXCodec> codec = mTarget.promote();
171693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
172693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (codec.get() != NULL) {
173693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            codec->on_message(msg);
174693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
175693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
176693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
177693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected:
178693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    virtual ~OMXCodecObserver() {}
179693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
180693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprivate:
181693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    wp<OMXCodec> mTarget;
182693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
183693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMXCodecObserver(const OMXCodecObserver &);
184693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMXCodecObserver &operator=(const OMXCodecObserver &);
185693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber};
186693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
187693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const char *GetCodec(const CodecInfo *info, size_t numInfos,
188693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                            const char *mime, int index) {
189693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(index >= 0);
190693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for(size_t i = 0; i < numInfos; ++i) {
191693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (!strcasecmp(mime, info[i].mime)) {
192693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (index == 0) {
193693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                return info[i].codec;
194693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
195693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
196693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            --index;
197693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
198693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
199693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
200693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return NULL;
201693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
202693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
203bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huberenum {
204bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileBaseline      = 0x42,
205bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileMain          = 0x4d,
206bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileExtended      = 0x58,
207bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileHigh          = 0x64,
208bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileHigh10        = 0x6e,
209bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileHigh422       = 0x7a,
210bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileHigh444       = 0xf4,
211bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    kAVCProfileCAVLC444Intra = 0x2c
212bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber};
213bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
214bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huberstatic const char *AVCProfileToString(uint8_t profile) {
215bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    switch (profile) {
216bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileBaseline:
217bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "Baseline";
218bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileMain:
219bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "Main";
220bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileExtended:
221bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "Extended";
222bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileHigh:
223bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "High";
224bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileHigh10:
225bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "High 10";
226bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileHigh422:
227bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "High 422";
228bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileHigh444:
229bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "High 444";
230bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        case kAVCProfileCAVLC444Intra:
231bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return "CAVLC 444 Intra";
232bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        default:   return "Unknown";
233bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber    }
234bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber}
235bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
2367a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Hubertemplate<class T>
2377a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huberstatic void InitOMXParams(T *params) {
2387a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nSize = sizeof(T);
2397a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nVersion.s.nVersionMajor = 1;
2407a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nVersion.s.nVersionMinor = 0;
2417a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nVersion.s.nRevision = 0;
2427a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nVersion.s.nStep = 0;
2437a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber}
2447a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
245ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huberstatic bool IsSoftwareCodec(const char *componentName) {
246ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (!strncmp("OMX.PV.", componentName, 7)) {
247ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        return true;
248ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
249693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
250ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    return false;
251ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber}
252693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2531af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber// A sort order in which non-OMX components are first,
2541af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber// followed by software codecs, i.e. OMX.PV.*, followed
2551af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber// by all the others.
256ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huberstatic int CompareSoftwareCodecsFirst(
257ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const String8 *elem1, const String8 *elem2) {
2581af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    bool isNotOMX1 = strncmp(elem1->string(), "OMX.", 4);
2591af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    bool isNotOMX2 = strncmp(elem2->string(), "OMX.", 4);
2601af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
2611af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    if (isNotOMX1) {
2621af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        if (isNotOMX2) { return 0; }
2631af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        return -1;
2641af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    }
2651af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    if (isNotOMX2) {
2661af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        return 1;
2671af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber    }
2681af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
269ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    bool isSoftwareCodec1 = IsSoftwareCodec(elem1->string());
270ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    bool isSoftwareCodec2 = IsSoftwareCodec(elem2->string());
271693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
272ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (isSoftwareCodec1) {
273ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        if (isSoftwareCodec2) { return 0; }
274ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        return -1;
275ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
276693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
277ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (isSoftwareCodec2) {
278ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        return 1;
279693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
280693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
281ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    return 0;
282ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber}
283ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
284ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber// static
285ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huberuint32_t OMXCodec::getComponentQuirks(const char *componentName) {
286693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    uint32_t quirks = 0;
287ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
288693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!strcmp(componentName, "OMX.PV.avcdec")) {
289dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        quirks |= kWantsNALFragments;
290693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
291693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!strcmp(componentName, "OMX.TI.MP3.decode")) {
292693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        quirks |= kNeedsFlushBeforeDisable;
293693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
294693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!strcmp(componentName, "OMX.TI.AAC.decode")) {
295693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        quirks |= kNeedsFlushBeforeDisable;
2961beb760d920561679862ded945a04e370368c7f7Andreas Huber        quirks |= kRequiresFlushCompleteEmulation;
297693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
298693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!strncmp(componentName, "OMX.qcom.video.encoder.", 23)) {
299693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        quirks |= kRequiresLoadedToIdleAfterAllocation;
300693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        quirks |= kRequiresAllocateBufferOnInputPorts;
301888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        quirks |= kRequiresAllocateBufferOnOutputPorts;
302693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
303b7802d9ee9c9dbb471ae4f010bd67ba1aaa9f264Andreas Huber    if (!strncmp(componentName, "OMX.qcom.video.decoder.", 23)) {
304b7802d9ee9c9dbb471ae4f010bd67ba1aaa9f264Andreas Huber        // XXX Required on P....on only.
305b7802d9ee9c9dbb471ae4f010bd67ba1aaa9f264Andreas Huber        quirks |= kRequiresAllocateBufferOnOutputPorts;
306b7802d9ee9c9dbb471ae4f010bd67ba1aaa9f264Andreas Huber    }
307693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
308df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber    if (!strncmp(componentName, "OMX.TI.", 7)) {
309df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber        // Apparently I must not use OMX_UseBuffer on either input or
310df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber        // output ports on any of the TI components or quote:
311df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber        // "(I) may have unexpected problem (sic) which can be timing related
312df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber        //  and hard to reproduce."
313df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber
314df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber        quirks |= kRequiresAllocateBufferOnInputPorts;
315df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber        quirks |= kRequiresAllocateBufferOnOutputPorts;
316df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas Huber    }
317df4de7d7bd0060a84b064ce074d3f86d3a7aa0aeAndreas 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    success = false;
383ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
384ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    const char *componentName;
385ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    for (size_t i = 0; i < matchingCodecs.size(); ++i) {
386ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        componentName = matchingCodecs[i].string();
387ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
3881af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber#if BUILD_WITH_FULL_STAGEFRIGHT
3891af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        sp<MediaSource> softwareCodec =
3901af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber            InstantiateSoftwareCodec(componentName, source);
3911af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
3921af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        if (softwareCodec != NULL) {
3931af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber            LOGV("Successfully allocated software codec '%s'", componentName);
3941af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
3951af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber            return softwareCodec;
3961af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber        }
3971af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber#endif
3981af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
399ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        LOGV("Attempting to allocate OMX node '%s'", componentName);
400ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
401ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        status_t err = omx->allocateNode(componentName, observer, &node);
402ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        if (err == OK) {
403ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            LOGV("Successfully allocated OMX node '%s'", componentName);
404ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
405ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            success = true;
406ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            break;
407ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        }
408ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
409ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
410ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (!success) {
411ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        return NULL;
412ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
413ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
414693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    sp<OMXCodec> codec = new OMXCodec(
415ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            omx, node, getComponentQuirks(componentName),
416ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            createEncoder, mime, componentName,
417693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            source);
418693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
419318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    observer->setCodec(codec);
420318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
421693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    uint32_t type;
422693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    const void *data;
423693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t size;
424693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (meta->findData(kKeyESDS, &type, &data, &size)) {
425693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        ESDS esds((const char *)data, size);
426693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(esds.InitCheck(), OK);
427693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
428693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const void *codec_specific_data;
429693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        size_t codec_specific_data_size;
430693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        esds.getCodecSpecificInfo(
431693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                &codec_specific_data, &codec_specific_data_size);
432693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
433693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        codec->addCodecSpecificData(
434693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                codec_specific_data, codec_specific_data_size);
435693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else if (meta->findData(kKeyAVCC, &type, &data, &size)) {
436bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        // Parse the AVCDecoderConfigurationRecord
437bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
438bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        const uint8_t *ptr = (const uint8_t *)data;
439bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
440bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        CHECK(size >= 7);
441bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        CHECK_EQ(ptr[0], 1);  // configurationVersion == 1
442bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        uint8_t profile = ptr[1];
443bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        uint8_t level = ptr[3];
444bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
445e5d6df402da9b6c5577470abb81a5e6801bd7752Andreas Huber        // There is decodable content out there that fails the following
446e5d6df402da9b6c5577470abb81a5e6801bd7752Andreas Huber        // assertion, let's be lenient for now...
447e5d6df402da9b6c5577470abb81a5e6801bd7752Andreas Huber        // CHECK((ptr[4] >> 2) == 0x3f);  // reserved
448bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
449bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        size_t lengthSize = 1 + (ptr[4] & 3);
450bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
451bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
452bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        // violates it...
453bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        // CHECK((ptr[5] >> 5) == 7);  // reserved
454bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
455bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        size_t numSeqParameterSets = ptr[5] & 31;
456bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
457bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        ptr += 6;
458693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        size -= 6;
459bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
460bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        for (size_t i = 0; i < numSeqParameterSets; ++i) {
461bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            CHECK(size >= 2);
462bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            size_t length = U16_AT(ptr);
463693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
464693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            ptr += 2;
465693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            size -= 2;
466693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
467bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            CHECK(size >= length);
468bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
469bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            codec->addCodecSpecificData(ptr, length);
470bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
471bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            ptr += length;
472bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            size -= length;
473bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        }
474bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
475bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        CHECK(size >= 1);
476bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        size_t numPictureParameterSets = *ptr;
477bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        ++ptr;
478bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        --size;
479bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
480bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        for (size_t i = 0; i < numPictureParameterSets; ++i) {
481bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            CHECK(size >= 2);
482bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            size_t length = U16_AT(ptr);
483bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
484bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            ptr += 2;
485bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            size -= 2;
486693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
487693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(size >= length);
488693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
489693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            codec->addCodecSpecificData(ptr, length);
490693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
491693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            ptr += length;
492693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            size -= length;
493bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        }
494693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
4952a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber        LOGV("AVC profile = %d (%s), level = %d",
496bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber             (int)profile, AVCProfileToString(profile), (int)level / 10);
497693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
498bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        if (!strcmp(componentName, "OMX.TI.Video.Decoder")
499bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            && (profile != kAVCProfileBaseline || level > 39)) {
500318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            // This stream exceeds the decoder's capabilities. The decoder
501318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            // does not handle this gracefully and would clobber the heap
502318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            // and wreak havoc instead...
503bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
504bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            LOGE("Profile and/or level exceed the decoder's capabilities.");
505bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber            return NULL;
506693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
507693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
508693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
50918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) {
510c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber        codec->setAMRFormat(false /* isWAMR */);
511693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
51218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
513c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber        codec->setAMRFormat(true /* isWAMR */);
514456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber    }
51518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
51637940eefcba982836b579fe1ffec6cada72b0974Andreas Huber        int32_t numChannels, sampleRate;
51737940eefcba982836b579fe1ffec6cada72b0974Andreas Huber        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
51837940eefcba982836b579fe1ffec6cada72b0974Andreas Huber        CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
51937940eefcba982836b579fe1ffec6cada72b0974Andreas Huber
52037940eefcba982836b579fe1ffec6cada72b0974Andreas Huber        codec->setAACFormat(numChannels, sampleRate);
521693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
522693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!strncasecmp(mime, "video/", 6)) {
523693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        int32_t width, height;
524693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        bool success = meta->findInt32(kKeyWidth, &width);
525693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        success = success && meta->findInt32(kKeyHeight, &height);
5267530e9c708275c273c134c36c68179f511c1940eAndreas Huber        CHECK(success);
527693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
528693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (createEncoder) {
529693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            codec->setVideoInputFormat(mime, width, height);
530693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        } else {
531693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            codec->setVideoOutputFormat(mime, width, height);
532693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
533693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
53418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    if (!strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_JPEG)
535693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        && !strcmp(componentName, "OMX.TI.JPEG.decode")) {
536693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_COLOR_FORMATTYPE format =
537693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_COLOR_Format32bitARGB8888;
538693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            // OMX_COLOR_FormatYUV420PackedPlanar;
539693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            // OMX_COLOR_FormatCbYCrY;
540693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            // OMX_COLOR_FormatYUV411Planar;
541693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
542693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        int32_t width, height;
543693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        bool success = meta->findInt32(kKeyWidth, &width);
544693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        success = success && meta->findInt32(kKeyHeight, &height);
5457530e9c708275c273c134c36c68179f511c1940eAndreas Huber
5467530e9c708275c273c134c36c68179f511c1940eAndreas Huber        int32_t compressedSize;
5477530e9c708275c273c134c36c68179f511c1940eAndreas Huber        success = success && meta->findInt32(
548e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                kKeyMaxInputSize, &compressedSize);
5497530e9c708275c273c134c36c68179f511c1940eAndreas Huber
5507530e9c708275c273c134c36c68179f511c1940eAndreas Huber        CHECK(success);
5517530e9c708275c273c134c36c68179f511c1940eAndreas Huber        CHECK(compressedSize > 0);
552693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
553693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        codec->setImageOutputFormat(format, width, height);
5547530e9c708275c273c134c36c68179f511c1940eAndreas Huber        codec->setJPEGInputFormat(width, height, (OMX_U32)compressedSize);
555693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
556693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
557e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    int32_t maxInputSize;
558738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber    if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
559e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        codec->setMinBufferSize(kPortIndexInput, (OMX_U32)maxInputSize);
560e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
561e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
562e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    if (!strcmp(componentName, "OMX.TI.AMR.encode")
563e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        || !strcmp(componentName, "OMX.TI.WBAMR.encode")) {
564e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        codec->setMinBufferSize(kPortIndexOutput, 8192);  // XXX
565e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
566e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
567693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    codec->initOutputFormat(meta);
568693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
569693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return codec;
570693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
571693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
572e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Hubervoid OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) {
573e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
5747a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
575e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    def.nPortIndex = portIndex;
576e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
577318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
578e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
579e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    CHECK_EQ(err, OK);
580e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
581e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    if (def.nBufferSize < size) {
582e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        def.nBufferSize = size;
583e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
584e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
585318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
586e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
587e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    CHECK_EQ(err, OK);
588738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber
589738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber    err = mOMX->getParameter(
590738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
591738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber    CHECK_EQ(err, OK);
592738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber
593738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber    // Make sure the setting actually stuck.
594738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber    CHECK(def.nBufferSize >= size);
595e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber}
596e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
597693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::setVideoPortFormatType(
598693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_U32 portIndex,
599693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
600693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
601693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
6027a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&format);
603693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    format.nPortIndex = portIndex;
604693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    format.nIndex = 0;
605693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    bool found = false;
606693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
607693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_U32 index = 0;
608693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (;;) {
609693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        format.nIndex = index;
610318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        status_t err = mOMX->getParameter(
611693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
612693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                &format, sizeof(format));
613693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
614693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (err != OK) {
615693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            return err;
616693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
617693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
618693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        // The following assertion is violated by TI's video decoder.
6197530e9c708275c273c134c36c68179f511c1940eAndreas Huber        // CHECK_EQ(format.nIndex, index);
620693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
621693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#if 1
6222a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber        CODEC_LOGV("portIndex: %ld, index: %ld, eCompressionFormat=%d eColorFormat=%d",
623693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber             portIndex,
624693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber             index, format.eCompressionFormat, format.eColorFormat);
625693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#endif
626693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
627693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName)) {
628693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (portIndex == kPortIndexInput
629693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    && colorFormat == format.eColorFormat) {
630693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                // eCompressionFormat does not seem right.
631693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                found = true;
632693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                break;
633693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
634693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (portIndex == kPortIndexOutput
635693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
636693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                // eColorFormat does not seem right.
637693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                found = true;
638693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                break;
639693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
640693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
641693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
642693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (format.eCompressionFormat == compressionFormat
643693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            && format.eColorFormat == colorFormat) {
644693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            found = true;
645693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
646693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
647693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
648693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        ++index;
649693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
650693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
651693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!found) {
652693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return UNKNOWN_ERROR;
653693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
654693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
6552a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    CODEC_LOGV("found a match.");
656318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->setParameter(
657693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
658693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            &format, sizeof(format));
659693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
660693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return err;
661693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
662693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
663888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huberstatic size_t getFrameSize(
664888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat, int32_t width, int32_t height) {
665888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    switch (colorFormat) {
666888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        case OMX_COLOR_FormatYCbYCr:
667888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        case OMX_COLOR_FormatCbYCrY:
668888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            return width * height * 2;
669888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
670888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        case OMX_COLOR_FormatYUV420SemiPlanar:
671888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            return (width * height * 3) / 2;
672888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
673888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        default:
674888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            CHECK(!"Should not be here. Unsupported color format.");
675888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            break;
676888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    }
677888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber}
678888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
679693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::setVideoInputFormat(
680693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const char *mime, OMX_U32 width, OMX_U32 height) {
6812a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    CODEC_LOGV("setVideoInputFormat width=%ld, height=%ld", width, height);
682693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
683693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
68418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
685693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        compressionFormat = OMX_VIDEO_CodingAVC;
68618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
687693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        compressionFormat = OMX_VIDEO_CodingMPEG4;
68818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
689693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        compressionFormat = OMX_VIDEO_CodingH263;
690693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
691693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        LOGE("Not a supported video mime type: %s", mime);
692693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(!"Should not be here. Not a supported video mime type.");
693693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
694693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
69530ab66297501757d745b9ae10da61adcd891f497Andreas Huber    OMX_COLOR_FORMATTYPE colorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
69630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    if (!strcasecmp("OMX.TI.Video.encoder", mComponentName)) {
69730ab66297501757d745b9ae10da61adcd891f497Andreas Huber        colorFormat = OMX_COLOR_FormatYCbYCr;
698693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
699693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
700888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(setVideoPortFormatType(
701693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused,
702888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            colorFormat), OK);
703693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
704888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(setVideoPortFormatType(
705888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused),
706888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            OK);
707693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
708693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
7097a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
710693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexOutput;
711693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
7127a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
7137a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
714318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
715693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
716693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
717693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
718693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
719693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
720693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameWidth = width;
721693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameHeight = height;
722693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
723693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->eCompressionFormat = compressionFormat;
724693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
725693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
726318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
727693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
728693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
729693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
730693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    ////////////////////////////////////////////////////////////////////////////
731693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
7327a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
733693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexInput;
734693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
735318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->getParameter(
736693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
737693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
738693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
739888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    def.nBufferSize = getFrameSize(colorFormat, width, height);
7402a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    CODEC_LOGV("Setting nBufferSize = %ld", def.nBufferSize);
741693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
742693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
743693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
744693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameWidth = width;
745693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameHeight = height;
746693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
747693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->eColorFormat = colorFormat;
748693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
749888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    video_def->xFramerate = 24 << 16;  // XXX crucial!
750888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
751318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
752693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
753693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
754888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
755888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    switch (compressionFormat) {
756888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        case OMX_VIDEO_CodingMPEG4:
757888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        {
758888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            CHECK_EQ(setupMPEG4EncoderParameters(), OK);
759888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            break;
760888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        }
761888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
762888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        case OMX_VIDEO_CodingH263:
763888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            break;
764888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
76530ab66297501757d745b9ae10da61adcd891f497Andreas Huber        case OMX_VIDEO_CodingAVC:
76630ab66297501757d745b9ae10da61adcd891f497Andreas Huber        {
76730ab66297501757d745b9ae10da61adcd891f497Andreas Huber            CHECK_EQ(setupAVCEncoderParameters(), OK);
76830ab66297501757d745b9ae10da61adcd891f497Andreas Huber            break;
76930ab66297501757d745b9ae10da61adcd891f497Andreas Huber        }
77030ab66297501757d745b9ae10da61adcd891f497Andreas Huber
771888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        default:
772888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            CHECK(!"Support for this compressionFormat to be implemented.");
773888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            break;
774888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    }
775888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber}
776888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
777888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huberstatus_t OMXCodec::setupMPEG4EncoderParameters() {
778888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
779888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    InitOMXParams(&mpeg4type);
780888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
781888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
782888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    status_t err = mOMX->getParameter(
783888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
784888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(err, OK);
785888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
786888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
787888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.bSVH = OMX_FALSE;
788888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.bGov = OMX_FALSE;
789888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
790888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nAllowedPictureTypes =
791888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
792888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
793888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nPFrames = 23;
794888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nBFrames = 0;
795888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
796888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nIDCVLCThreshold = 0;
797888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.bACPred = OMX_TRUE;
798888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nMaxPacketSize = 256;
799888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nTimeIncRes = 1000;
800888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.nHeaderExtension = 0;
801888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
802888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
803888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.eProfile = OMX_VIDEO_MPEG4ProfileCore;
804888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    mpeg4type.eLevel = OMX_VIDEO_MPEG4Level2;
805888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
806888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    err = mOMX->setParameter(
807888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
808888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(err, OK);
809888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
810888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    // ----------------
811888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
812888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
813888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    InitOMXParams(&bitrateType);
814888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
815888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
816888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    err = mOMX->getParameter(
817888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            mNode, OMX_IndexParamVideoBitrate,
818888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            &bitrateType, sizeof(bitrateType));
819888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(err, OK);
820888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
821888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    bitrateType.eControlRate = OMX_Video_ControlRateVariable;
822888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    bitrateType.nTargetBitrate = 1000000;
823888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
824888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    err = mOMX->setParameter(
825888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            mNode, OMX_IndexParamVideoBitrate,
826888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            &bitrateType, sizeof(bitrateType));
827888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(err, OK);
828888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
829888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    // ----------------
830888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
831888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
832888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    InitOMXParams(&errorCorrectionType);
833888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
834888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
835888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    err = mOMX->getParameter(
836888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
837888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
838888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(err, OK);
839888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
840888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
841888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
842888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
843888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
844888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
845888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
846888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    err = mOMX->setParameter(
847888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
848888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
849888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    CHECK_EQ(err, OK);
850888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
851888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    return OK;
852693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
853693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
85430ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t OMXCodec::setupAVCEncoderParameters() {
85530ab66297501757d745b9ae10da61adcd891f497Andreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
85630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    InitOMXParams(&h264type);
85730ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nPortIndex = kPortIndexOutput;
85830ab66297501757d745b9ae10da61adcd891f497Andreas Huber
85930ab66297501757d745b9ae10da61adcd891f497Andreas Huber    status_t err = mOMX->getParameter(
86030ab66297501757d745b9ae10da61adcd891f497Andreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
86130ab66297501757d745b9ae10da61adcd891f497Andreas Huber    CHECK_EQ(err, OK);
86230ab66297501757d745b9ae10da61adcd891f497Andreas Huber
86330ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nAllowedPictureTypes =
86430ab66297501757d745b9ae10da61adcd891f497Andreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
86530ab66297501757d745b9ae10da61adcd891f497Andreas Huber
86630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nSliceHeaderSpacing = 0;
86730ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nBFrames = 0;
86830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bUseHadamard = OMX_TRUE;
86930ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nRefFrames = 1;
87030ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nRefIdx10ActiveMinus1 = 0;
87130ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nRefIdx11ActiveMinus1 = 0;
87230ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bEnableUEP = OMX_FALSE;
87330ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bEnableFMO = OMX_FALSE;
87430ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bEnableASO = OMX_FALSE;
87530ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bEnableRS = OMX_FALSE;
87630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
87730ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.eLevel = OMX_VIDEO_AVCLevel1b;
87830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
87930ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bMBAFF = OMX_FALSE;
88030ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bEntropyCodingCABAC = OMX_FALSE;
88130ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bWeightedPPrediction = OMX_FALSE;
88230ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bconstIpred = OMX_FALSE;
88330ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bDirect8x8Inference = OMX_FALSE;
88430ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.bDirectSpatialTemporal = OMX_FALSE;
88530ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.nCabacInitIdc = 0;
88630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
88730ab66297501757d745b9ae10da61adcd891f497Andreas Huber
88830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    err = mOMX->setParameter(
88930ab66297501757d745b9ae10da61adcd891f497Andreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
89030ab66297501757d745b9ae10da61adcd891f497Andreas Huber    CHECK_EQ(err, OK);
89130ab66297501757d745b9ae10da61adcd891f497Andreas Huber
89230ab66297501757d745b9ae10da61adcd891f497Andreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
89330ab66297501757d745b9ae10da61adcd891f497Andreas Huber    InitOMXParams(&bitrateType);
89430ab66297501757d745b9ae10da61adcd891f497Andreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
89530ab66297501757d745b9ae10da61adcd891f497Andreas Huber
89630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    err = mOMX->getParameter(
89730ab66297501757d745b9ae10da61adcd891f497Andreas Huber            mNode, OMX_IndexParamVideoBitrate,
89830ab66297501757d745b9ae10da61adcd891f497Andreas Huber            &bitrateType, sizeof(bitrateType));
89930ab66297501757d745b9ae10da61adcd891f497Andreas Huber    CHECK_EQ(err, OK);
90030ab66297501757d745b9ae10da61adcd891f497Andreas Huber
90130ab66297501757d745b9ae10da61adcd891f497Andreas Huber    bitrateType.eControlRate = OMX_Video_ControlRateVariable;
90230ab66297501757d745b9ae10da61adcd891f497Andreas Huber    bitrateType.nTargetBitrate = 1000000;
90330ab66297501757d745b9ae10da61adcd891f497Andreas Huber
90430ab66297501757d745b9ae10da61adcd891f497Andreas Huber    err = mOMX->setParameter(
90530ab66297501757d745b9ae10da61adcd891f497Andreas Huber            mNode, OMX_IndexParamVideoBitrate,
90630ab66297501757d745b9ae10da61adcd891f497Andreas Huber            &bitrateType, sizeof(bitrateType));
90730ab66297501757d745b9ae10da61adcd891f497Andreas Huber    CHECK_EQ(err, OK);
90830ab66297501757d745b9ae10da61adcd891f497Andreas Huber
90930ab66297501757d745b9ae10da61adcd891f497Andreas Huber    return OK;
91030ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
91130ab66297501757d745b9ae10da61adcd891f497Andreas Huber
912693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::setVideoOutputFormat(
913693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const char *mime, OMX_U32 width, OMX_U32 height) {
9142a4a7d5af053a17586a262a1267ba993e31790f1Andreas Huber    CODEC_LOGV("setVideoOutputFormat width=%ld, height=%ld", width, height);
915693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
916693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
91718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
918693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        compressionFormat = OMX_VIDEO_CodingAVC;
91918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
920693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        compressionFormat = OMX_VIDEO_CodingMPEG4;
92118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
922693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        compressionFormat = OMX_VIDEO_CodingH263;
923693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
924693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        LOGE("Not a supported video mime type: %s", mime);
925693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(!"Should not be here. Not a supported video mime type.");
926693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
927693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
928693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    setVideoPortFormatType(
929693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
930693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
931693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#if 1
932693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    {
933693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_VIDEO_PARAM_PORTFORMATTYPE format;
9347a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        InitOMXParams(&format);
935693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        format.nPortIndex = kPortIndexOutput;
936693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        format.nIndex = 0;
937693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
938318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        status_t err = mOMX->getParameter(
939693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
940693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                &format, sizeof(format));
941693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(err, OK);
942693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(format.eCompressionFormat, OMX_VIDEO_CodingUnused);
943693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
944693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
945693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
946693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
947693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber               || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
948693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber               || format.eColorFormat == OMX_COLOR_FormatCbYCrY
949693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber               || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar);
950693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
951318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        err = mOMX->setParameter(
952693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
953693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                &format, sizeof(format));
954693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(err, OK);
955693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
956693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#endif
957693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
958693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
9597a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
960693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexInput;
961693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
9627a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
9637a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
964318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
965693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
966693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
967693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
968693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
969693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#if 1
970693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    // XXX Need a (much) better heuristic to compute input buffer sizes.
971693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    const size_t X = 64 * 1024;
972693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (def.nBufferSize < X) {
973693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        def.nBufferSize = X;
974693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
975693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#endif
976693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
977693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
978693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
979693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameWidth = width;
980693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameHeight = height;
981693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
982888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    video_def->eCompressionFormat = compressionFormat;
983693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
984693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
985318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
986693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
987693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
988693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
989693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    ////////////////////////////////////////////////////////////////////////////
990693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
9917a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
992693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexOutput;
993693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
994318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->getParameter(
995693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
996693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
997693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
998693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
999693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#if 0
1000693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nBufferSize =
1001693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2;  // YUV420
1002693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#endif
1003693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1004693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameWidth = width;
1005693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    video_def->nFrameHeight = height;
1006693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1007318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
1008693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1009693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
1010693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1011693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1012693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberOMXCodec::OMXCodec(
1013693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks,
1014bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        bool isEncoder,
1015693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const char *mime,
1016693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const char *componentName,
1017693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const sp<MediaSource> &source)
1018693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    : mOMX(omx),
10197eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber      mOMXLivesLocally(omx->livesLocally(getpid())),
1020693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mNode(node),
1021693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mQuirks(quirks),
1022693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mIsEncoder(isEncoder),
1023693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mMIME(strdup(mime)),
1024693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mComponentName(strdup(componentName)),
1025693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mSource(source),
1026693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mCodecSpecificDataIndex(0),
1027693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mState(LOADED),
1028284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber      mInitialBufferSubmit(true),
1029693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mSignalledEOS(false),
1030693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mNoMoreOutputData(false),
10317f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber      mOutputPortSettingsHaveChanged(false),
1032693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber      mSeekTimeUs(-1) {
1033693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mPortStatus[kPortIndexInput] = ENABLED;
1034693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mPortStatus[kPortIndexOutput] = ENABLED;
1035693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
10367a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    setComponentRole();
10377a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber}
10387a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
103918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber// static
104018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Hubervoid OMXCodec::setComponentRole(
104118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder,
104218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        const char *mime) {
10437a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    struct MimeToRole {
10447a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        const char *mime;
10457a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        const char *decoderRole;
10467a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        const char *encoderRole;
10477a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    };
10487a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
10497a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    static const MimeToRole kMimeToRole[] = {
105018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
105118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
105218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
105318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
105418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
105518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
105618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
105718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
105818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
105918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
106018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
106118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
106218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
106318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
10647a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    };
10657a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
10667a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    static const size_t kNumMimeToRole =
10677a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
10687a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
10697a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    size_t i;
10707a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
107118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
10727a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            break;
10737a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        }
10747a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    }
10757a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
10767a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    if (i == kNumMimeToRole) {
10777a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        return;
10787a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    }
10797a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
10807a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    const char *role =
108118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
108218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                  : kMimeToRole[i].decoderRole;
10837a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
10847a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    if (role != NULL) {
10857a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
10867a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        InitOMXParams(&roleParams);
10877a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
10887a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        strncpy((char *)roleParams.cRole,
10897a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
10907a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
10917a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
10927a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
1093318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        status_t err = omx->setParameter(
109418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                node, OMX_IndexParamStandardComponentRole,
10957a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                &roleParams, sizeof(roleParams));
10967a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
10977a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        if (err != OK) {
10987a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            LOGW("Failed to set standard component role '%s'.", role);
10997a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        }
11007a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    }
1101693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1102693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
110318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Hubervoid OMXCodec::setComponentRole() {
110418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    setComponentRole(mOMX, mNode, mIsEncoder, mMIME);
110518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber}
110618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
1107693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberOMXCodec::~OMXCodec() {
1108dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    CHECK(mState == LOADED || mState == ERROR);
1109693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1110318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->freeNode(mNode);
1111693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
1112693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1113693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mNode = NULL;
1114693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    setState(DEAD);
1115693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1116693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    clearCodecSpecificData();
1117693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1118693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    free(mComponentName);
1119693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mComponentName = NULL;
1120bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
1121693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    free(mMIME);
1122693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mMIME = NULL;
1123693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1124693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1125693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::init() {
1126284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber    // mLock is held.
1127693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1128693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(mState, LOADED);
1129693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1130693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err;
1131693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) {
1132318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
1133693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(err, OK);
1134693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        setState(LOADED_TO_IDLE);
1135693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1136693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1137693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    err = allocateBuffers();
1138693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
1139693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1140693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mQuirks & kRequiresLoadedToIdleAfterAllocation) {
1141318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
1142693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(err, OK);
1143693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1144693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        setState(LOADED_TO_IDLE);
1145693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1146693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1147693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    while (mState != EXECUTING && mState != ERROR) {
1148693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mAsyncCompletion.wait(mLock);
1149693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1150693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1151693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return mState == ERROR ? UNKNOWN_ERROR : OK;
1152693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1153693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1154693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber// static
1155693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberbool OMXCodec::isIntermediateState(State state) {
1156693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return state == LOADED_TO_IDLE
1157693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        || state == IDLE_TO_EXECUTING
1158693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        || state == EXECUTING_TO_IDLE
1159693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        || state == IDLE_TO_LOADED
1160693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        || state == RECONFIGURING;
1161693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1162693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1163693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::allocateBuffers() {
1164693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err = allocateBuffersOnPort(kPortIndexInput);
1165693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1166693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (err != OK) {
1167693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return err;
1168693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1169693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1170693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return allocateBuffersOnPort(kPortIndexOutput);
1171693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1172693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1173693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
1174693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
11757a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
1176693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = portIndex;
1177693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1178318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
1179693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1180693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1181693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (err != OK) {
1182693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return err;
1183693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1184693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
11857530e9c708275c273c134c36c68179f511c1940eAndreas Huber    size_t totalSize = def.nBufferCountActual * def.nBufferSize;
11867530e9c708275c273c134c36c68179f511c1940eAndreas Huber    mDealer[portIndex] = new MemoryDealer(totalSize);
11877530e9c708275c273c134c36c68179f511c1940eAndreas Huber
1188693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
11897530e9c708275c273c134c36c68179f511c1940eAndreas Huber        sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
1190693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(mem.get() != NULL);
1191693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1192693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        IOMX::buffer_id buffer;
1193693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (portIndex == kPortIndexInput
1194693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                && (mQuirks & kRequiresAllocateBufferOnInputPorts)) {
11957eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber            if (mOMXLivesLocally) {
11967eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber                err = mOMX->allocateBuffer(
11977eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber                        mNode, portIndex, def.nBufferSize, &buffer);
11987eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber            } else {
11997eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber                err = mOMX->allocateBufferWithBackup(
12007eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber                        mNode, portIndex, mem, &buffer);
12017eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber            }
1202ea7d15629752256f6ea1d5c6ea796e59aefd030fAndreas Huber        } else if (portIndex == kPortIndexOutput
1203ea7d15629752256f6ea1d5c6ea796e59aefd030fAndreas Huber                && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) {
12047eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber            if (mOMXLivesLocally) {
12057eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber                err = mOMX->allocateBuffer(
12067eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber                        mNode, portIndex, def.nBufferSize, &buffer);
12077eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber            } else {
12087eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber                err = mOMX->allocateBufferWithBackup(
12097eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber                        mNode, portIndex, mem, &buffer);
12107eaa9c9385535b651064e02d05a8ffa4b2359281Andreas Huber            }
1211693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        } else {
1212318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
1213693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1214693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1215693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (err != OK) {
1216693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            LOGE("allocate_buffer_with_backup failed");
1217693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            return err;
1218693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1219693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1220693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        BufferInfo info;
1221693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        info.mBuffer = buffer;
1222693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        info.mOwnedByComponent = false;
1223693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        info.mMem = mem;
1224693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        info.mMediaBuffer = NULL;
1225693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1226693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (portIndex == kPortIndexOutput) {
1227693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            info.mMediaBuffer = new MediaBuffer(mem->pointer(), mem->size());
1228693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            info.mMediaBuffer->setObserver(this);
1229693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1230693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1231693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mPortBuffers[portIndex].push(info);
1232693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
12337a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        CODEC_LOGV("allocated buffer %p on %s port", buffer,
1234693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber             portIndex == kPortIndexInput ? "input" : "output");
1235693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1236693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1237134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    // dumpPortStatus(portIndex);
1238693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1239693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return OK;
1240693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1241693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1242693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::on_message(const omx_message &msg) {
1243693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Mutex::Autolock autoLock(mLock);
1244693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1245693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (msg.type) {
1246693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case omx_message::EVENT:
1247693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1248693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            onEvent(
1249693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 msg.u.event_data.event, msg.u.event_data.data1,
1250693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 msg.u.event_data.data2);
1251693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1252693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1253693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1254693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1255693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
1256693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1257693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
1258693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
12597a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("EMPTY_BUFFER_DONE(buffer: %p)", buffer);
1260693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1261693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
1262693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            size_t i = 0;
1263693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
1264693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                ++i;
1265693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1266693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1267693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(i < buffers->size());
1268693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (!(*buffers)[i].mOwnedByComponent) {
1269693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                LOGW("We already own input buffer %p, yet received "
1270693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                     "an EMPTY_BUFFER_DONE.", buffer);
1271693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1272693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1273693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            buffers->editItemAt(i).mOwnedByComponent = false;
1274693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1275693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (mPortStatus[kPortIndexInput] == DISABLING) {
12767a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
1277693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1278693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                status_t err =
1279318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                    mOMX->freeBuffer(mNode, kPortIndexInput, buffer);
1280693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1281693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1282693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                buffers->removeAt(i);
1283693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else if (mPortStatus[kPortIndexInput] != SHUTTING_DOWN) {
1284693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(mPortStatus[kPortIndexInput], ENABLED);
1285693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                drainInputBuffer(&buffers->editItemAt(i));
1286693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1287693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1288693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1289693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1290693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case omx_message::FILL_BUFFER_DONE:
1291693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1292693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
1293693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_U32 flags = msg.u.extended_buffer_data.flags;
1294693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1295134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber            CODEC_LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx, timestamp: %lld us (%.2f secs))",
1296693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 buffer,
1297693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 msg.u.extended_buffer_data.range_length,
1298134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber                 flags,
1299693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 msg.u.extended_buffer_data.timestamp,
1300693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 msg.u.extended_buffer_data.timestamp / 1E6);
1301693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1302693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
1303693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            size_t i = 0;
1304693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
1305693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                ++i;
1306693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1307693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1308693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(i < buffers->size());
1309693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            BufferInfo *info = &buffers->editItemAt(i);
1310693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1311693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (!info->mOwnedByComponent) {
1312693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                LOGW("We already own output buffer %p, yet received "
1313693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                     "a FILL_BUFFER_DONE.", buffer);
1314693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1315693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1316693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            info->mOwnedByComponent = false;
1317693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1318693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (mPortStatus[kPortIndexOutput] == DISABLING) {
13197a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
1320693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1321693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                status_t err =
1322318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                    mOMX->freeBuffer(mNode, kPortIndexOutput, buffer);
1323693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1324693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1325693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                buffers->removeAt(i);
1326134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber#if 0
1327355edcea2f15c0f619c1e1d0f4fa433b0d38098fAndreas Huber            } else if (mPortStatus[kPortIndexOutput] == ENABLED
1328355edcea2f15c0f619c1e1d0f4fa433b0d38098fAndreas Huber                       && (flags & OMX_BUFFERFLAG_EOS)) {
13297a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                CODEC_LOGV("No more output data.");
1330693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mNoMoreOutputData = true;
1331693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mBufferFilled.signal();
1332134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber#endif
1333693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) {
1334693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED);
1335bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
1336693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                MediaBuffer *buffer = info->mMediaBuffer;
1337693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1338693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                buffer->set_range(
1339693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        msg.u.extended_buffer_data.range_offset,
1340693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        msg.u.extended_buffer_data.range_length);
1341693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1342693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                buffer->meta_data()->clear();
1343693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
134448c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber                buffer->meta_data()->setInt64(
134548c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber                        kKeyTime, msg.u.extended_buffer_data.timestamp);
1346693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1347693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) {
1348693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    buffer->meta_data()->setInt32(kKeyIsSyncFrame, true);
1349693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                }
135030ab66297501757d745b9ae10da61adcd891f497Andreas Huber                if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_CODECCONFIG) {
135130ab66297501757d745b9ae10da61adcd891f497Andreas Huber                    buffer->meta_data()->setInt32(kKeyIsCodecConfig, true);
135230ab66297501757d745b9ae10da61adcd891f497Andreas Huber                }
1353693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1354693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                buffer->meta_data()->setPointer(
1355693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        kKeyPlatformPrivate,
1356693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        msg.u.extended_buffer_data.platform_private);
1357693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1358693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                buffer->meta_data()->setPointer(
1359693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        kKeyBufferID,
1360693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        msg.u.extended_buffer_data.buffer);
1361693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1362693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mFilledBuffers.push_back(i);
1363693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mBufferFilled.signal();
1364134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber
1365134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber                if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_EOS) {
1366134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber                    CODEC_LOGV("No more output data.");
1367134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber                    mNoMoreOutputData = true;
1368134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber                }
1369693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1370693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1371693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1372693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1373693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1374693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
1375693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1376693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(!"should not be here.");
1377693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1378693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1379693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1380693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1381693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1382693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
1383693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (event) {
1384693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_EventCmdComplete:
1385693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1386693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            onCmdComplete((OMX_COMMANDTYPE)data1, data2);
1387693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1388693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1389693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1390693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_EventError:
1391693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1392134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber            LOGE("ERROR(0x%08lx, %ld)", data1, data2);
1393693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1394693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            setState(ERROR);
1395693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1396693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1397693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1398693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_EventPortSettingsChanged:
1399693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1400693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            onPortSettingsChanged(data1);
1401693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1402693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1403693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1404134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber#if 0
1405693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_EventBufferFlag:
1406693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
14077a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1);
1408693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1409693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (data1 == kPortIndexOutput) {
1410693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mNoMoreOutputData = true;
1411693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1412693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1413693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1414134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber#endif
1415693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1416693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
1417693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
14187a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("EVENT(%d, %ld, %ld)", event, data1, data2);
1419693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1420693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1421693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1422693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1423693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
142412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber// Has the format changed in any way that the client would have to be aware of?
142512658b720b176b7d934444256d07ba3c595d9b44Andreas Huberstatic bool formatHasNotablyChanged(
142612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        const sp<MetaData> &from, const sp<MetaData> &to) {
142712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    if (from.get() == NULL && to.get() == NULL) {
142812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        return false;
142912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    }
143012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
1431c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber    if ((from.get() == NULL && to.get() != NULL)
1432c6323f9d72e0f08dd1e813550a56c8d2f0fd76a2Andreas Huber        || (from.get() != NULL && to.get() == NULL)) {
143312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        return true;
143412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    }
143512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
143612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    const char *mime_from, *mime_to;
143712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    CHECK(from->findCString(kKeyMIMEType, &mime_from));
143812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    CHECK(to->findCString(kKeyMIMEType, &mime_to));
143912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
144012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    if (strcasecmp(mime_from, mime_to)) {
144112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        return true;
144212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    }
144312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
144412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    if (!strcasecmp(mime_from, MEDIA_MIMETYPE_VIDEO_RAW)) {
144512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        int32_t colorFormat_from, colorFormat_to;
144612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(from->findInt32(kKeyColorFormat, &colorFormat_from));
144712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(to->findInt32(kKeyColorFormat, &colorFormat_to));
144812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
144912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        if (colorFormat_from != colorFormat_to) {
145012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber            return true;
145112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        }
145212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
145312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        int32_t width_from, width_to;
145412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(from->findInt32(kKeyWidth, &width_from));
145512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(to->findInt32(kKeyWidth, &width_to));
145612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
145712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        if (width_from != width_to) {
145812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber            return true;
145912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        }
146012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
146112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        int32_t height_from, height_to;
146212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(from->findInt32(kKeyHeight, &height_from));
146312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(to->findInt32(kKeyHeight, &height_to));
146412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
146512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        if (height_from != height_to) {
146612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber            return true;
146712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        }
146812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    } else if (!strcasecmp(mime_from, MEDIA_MIMETYPE_AUDIO_RAW)) {
146912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        int32_t numChannels_from, numChannels_to;
147012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(from->findInt32(kKeyChannelCount, &numChannels_from));
147112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(to->findInt32(kKeyChannelCount, &numChannels_to));
147212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
147312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        if (numChannels_from != numChannels_to) {
147412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber            return true;
147512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        }
147612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
147712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        int32_t sampleRate_from, sampleRate_to;
147812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(from->findInt32(kKeySampleRate, &sampleRate_from));
147912658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        CHECK(to->findInt32(kKeySampleRate, &sampleRate_to));
148012658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
148112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        if (sampleRate_from != sampleRate_to) {
148212658b720b176b7d934444256d07ba3c595d9b44Andreas Huber            return true;
148312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber        }
148412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    }
148512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
148612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber    return false;
148712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber}
148812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
1489693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) {
1490693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (cmd) {
1491693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_CommandStateSet:
1492693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1493693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            onStateChange((OMX_STATETYPE)data);
1494693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1495693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1496693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1497693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_CommandPortDisable:
1498693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1499693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_U32 portIndex = data;
15007a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("PORT_DISABLED(%ld)", portIndex);
1501693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1502693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(mState == EXECUTING || mState == RECONFIGURING);
1503693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mPortStatus[portIndex], DISABLING);
1504693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mPortBuffers[portIndex].size(), 0);
1505693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1506693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mPortStatus[portIndex] = DISABLED;
1507693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1508693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (mState == RECONFIGURING) {
1509693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(portIndex, kPortIndexOutput);
1510693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
151112658b720b176b7d934444256d07ba3c595d9b44Andreas Huber                sp<MetaData> oldOutputFormat = mOutputFormat;
15127f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber                initOutputFormat(mSource->getFormat());
151312658b720b176b7d934444256d07ba3c595d9b44Andreas Huber
151412658b720b176b7d934444256d07ba3c595d9b44Andreas Huber                // Don't notify clients if the output port settings change
151512658b720b176b7d934444256d07ba3c595d9b44Andreas Huber                // wasn't of importance to them, i.e. it may be that just the
151612658b720b176b7d934444256d07ba3c595d9b44Andreas Huber                // number of buffers has changed and nothing else.
151712658b720b176b7d934444256d07ba3c595d9b44Andreas Huber                mOutputPortSettingsHaveChanged =
151812658b720b176b7d934444256d07ba3c595d9b44Andreas Huber                    formatHasNotablyChanged(oldOutputFormat, mOutputFormat);
15197f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber
1520693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                enablePortAsync(portIndex);
1521693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1522693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                status_t err = allocateBuffersOnPort(portIndex);
1523693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1524693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1525693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1526693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1527693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1528693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_CommandPortEnable:
1529693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1530693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_U32 portIndex = data;
15317a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("PORT_ENABLED(%ld)", portIndex);
1532693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1533693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(mState == EXECUTING || mState == RECONFIGURING);
1534693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mPortStatus[portIndex], ENABLING);
1535693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1536693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mPortStatus[portIndex] = ENABLED;
1537693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1538693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (mState == RECONFIGURING) {
1539693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(portIndex, kPortIndexOutput);
1540693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1541693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                setState(EXECUTING);
1542693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1543693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                fillOutputBuffers();
1544693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1545693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1546693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1547693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1548693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_CommandFlush:
1549693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1550693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_U32 portIndex = data;
1551693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
15527a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("FLUSH_DONE(%ld)", portIndex);
1553693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1554693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mPortStatus[portIndex], SHUTTING_DOWN);
1555693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mPortStatus[portIndex] = ENABLED;
1556693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1557693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]),
1558693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                     mPortBuffers[portIndex].size());
1559693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1560693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (mState == RECONFIGURING) {
1561693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(portIndex, kPortIndexOutput);
1562693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1563693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                disablePortAsync(portIndex);
15648297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber            } else if (mState == EXECUTING_TO_IDLE) {
15658297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                if (mPortStatus[kPortIndexInput] == ENABLED
15668297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    && mPortStatus[kPortIndexOutput] == ENABLED) {
15677a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                    CODEC_LOGV("Finished flushing both ports, now completing "
15688297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                         "transition from EXECUTING to IDLE.");
15698297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber
15708297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
15718297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
15728297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber
15738297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    status_t err =
1574318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                        mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
15758297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    CHECK_EQ(err, OK);
15768297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                }
1577693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else {
1578693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                // We're flushing both ports in preparation for seeking.
1579693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1580693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                if (mPortStatus[kPortIndexInput] == ENABLED
1581693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    && mPortStatus[kPortIndexOutput] == ENABLED) {
15827a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                    CODEC_LOGV("Finished flushing both ports, now continuing from"
1583693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                         " seek-time.");
1584693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1585693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    drainInputBuffers();
1586693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    fillOutputBuffers();
1587693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                }
1588693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1589693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1590693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1591693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1592693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1593693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
1594693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
15957a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("CMD_COMPLETE(%d, %ld)", cmd, data);
1596693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1597693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1598693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1599693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1600693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1601693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::onStateChange(OMX_STATETYPE newState) {
1602693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (newState) {
1603693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_StateIdle:
1604693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
16057a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("Now Idle.");
1606693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (mState == LOADED_TO_IDLE) {
1607318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                status_t err = mOMX->sendCommand(
1608693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        mNode, OMX_CommandStateSet, OMX_StateExecuting);
1609693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1610693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1611693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1612693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                setState(IDLE_TO_EXECUTING);
1613693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else {
1614693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(mState, EXECUTING_TO_IDLE);
1615693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1616693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(
1617693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
1618693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    mPortBuffers[kPortIndexInput].size());
1619693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1620693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(
1621693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    countBuffersWeOwn(mPortBuffers[kPortIndexOutput]),
1622693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    mPortBuffers[kPortIndexOutput].size());
1623693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1624318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                status_t err = mOMX->sendCommand(
1625693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        mNode, OMX_CommandStateSet, OMX_StateLoaded);
1626693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1627693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1628693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1629693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                err = freeBuffersOnPort(kPortIndexInput);
1630693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1631693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1632693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                err = freeBuffersOnPort(kPortIndexOutput);
1633693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
1634693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1635693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mPortStatus[kPortIndexInput] = ENABLED;
1636693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mPortStatus[kPortIndexOutput] = ENABLED;
1637693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1638693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                setState(IDLE_TO_LOADED);
1639693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
1640693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1641693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1642693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1643693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_StateExecuting:
1644693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1645693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mState, IDLE_TO_EXECUTING);
1646693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
16477a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("Now Executing.");
1648693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1649693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            setState(EXECUTING);
1650693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1651284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber            // Buffers will be submitted to the component in the first
1652284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber            // call to OMXCodec::read as mInitialBufferSubmit is true at
1653284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber            // this point. This ensures that this on_message call returns,
1654284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber            // releases the lock and ::init can notice the state change and
1655284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber            // itself return.
1656693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1657693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1658693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1659693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_StateLoaded:
1660693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1661693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mState, IDLE_TO_LOADED);
1662693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
16637a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber            CODEC_LOGV("Now Loaded.");
1664693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1665693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            setState(LOADED);
1666693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1667693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1668693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1669693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
1670693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
1671693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(!"should not be here.");
1672693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
1673693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1674693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1675693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1676693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1677693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber// static
1678693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t OMXCodec::countBuffersWeOwn(const Vector<BufferInfo> &buffers) {
1679693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t n = 0;
1680693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < buffers.size(); ++i) {
1681693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (!buffers[i].mOwnedByComponent) {
1682693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            ++n;
1683693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1684693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1685693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1686693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return n;
1687693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1688693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1689693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::freeBuffersOnPort(
1690693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_U32 portIndex, bool onlyThoseWeOwn) {
1691693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
1692693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1693693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t stickyErr = OK;
1694693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1695693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = buffers->size(); i-- > 0;) {
1696693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        BufferInfo *info = &buffers->editItemAt(i);
1697693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1698693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (onlyThoseWeOwn && info->mOwnedByComponent) {
1699693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            continue;
1700693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1701693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1702693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(info->mOwnedByComponent, false);
1703693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
170495301196d59fb88ef96342fd307a2be374b5079bAndreas Huber        CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex);
170595301196d59fb88ef96342fd307a2be374b5079bAndreas Huber
1706693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        status_t err =
1707318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mOMX->freeBuffer(mNode, portIndex, info->mBuffer);
1708693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1709693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (err != OK) {
1710693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            stickyErr = err;
1711693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1712693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1713693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (info->mMediaBuffer != NULL) {
1714693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            info->mMediaBuffer->setObserver(NULL);
1715693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1716693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            // Make sure nobody but us owns this buffer at this point.
1717693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(info->mMediaBuffer->refcount(), 0);
1718693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1719693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            info->mMediaBuffer->release();
1720693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1721693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1722693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        buffers->removeAt(i);
1723693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1724693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1725693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(onlyThoseWeOwn || buffers->isEmpty());
1726693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1727693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return stickyErr;
1728693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1729693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1730693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) {
17317a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex);
1732693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1733693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(mState, EXECUTING);
1734693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(portIndex, kPortIndexOutput);
1735693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    setState(RECONFIGURING);
1736693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1737693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mQuirks & kNeedsFlushBeforeDisable) {
17381beb760d920561679862ded945a04e370368c7f7Andreas Huber        if (!flushPortAsync(portIndex)) {
17391beb760d920561679862ded945a04e370368c7f7Andreas Huber            onCmdComplete(OMX_CommandFlush, portIndex);
17401beb760d920561679862ded945a04e370368c7f7Andreas Huber        }
1741693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
1742693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        disablePortAsync(portIndex);
1743693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1744693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1745693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
17461beb760d920561679862ded945a04e370368c7f7Andreas Huberbool OMXCodec::flushPortAsync(OMX_U32 portIndex) {
17478297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber    CHECK(mState == EXECUTING || mState == RECONFIGURING
17488297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber            || mState == EXECUTING_TO_IDLE);
1749693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
17507a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    CODEC_LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.",
17511beb760d920561679862ded945a04e370368c7f7Andreas Huber         portIndex, countBuffersWeOwn(mPortBuffers[portIndex]),
17521beb760d920561679862ded945a04e370368c7f7Andreas Huber         mPortBuffers[portIndex].size());
17531beb760d920561679862ded945a04e370368c7f7Andreas Huber
1754693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(mPortStatus[portIndex], ENABLED);
1755693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mPortStatus[portIndex] = SHUTTING_DOWN;
1756693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
17571beb760d920561679862ded945a04e370368c7f7Andreas Huber    if ((mQuirks & kRequiresFlushCompleteEmulation)
17581beb760d920561679862ded945a04e370368c7f7Andreas Huber        && countBuffersWeOwn(mPortBuffers[portIndex])
17591beb760d920561679862ded945a04e370368c7f7Andreas Huber                == mPortBuffers[portIndex].size()) {
17601beb760d920561679862ded945a04e370368c7f7Andreas Huber        // No flush is necessary and this component fails to send a
17611beb760d920561679862ded945a04e370368c7f7Andreas Huber        // flush-complete event in this case.
17621beb760d920561679862ded945a04e370368c7f7Andreas Huber
17631beb760d920561679862ded945a04e370368c7f7Andreas Huber        return false;
17641beb760d920561679862ded945a04e370368c7f7Andreas Huber    }
17651beb760d920561679862ded945a04e370368c7f7Andreas Huber
1766693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err =
1767318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        mOMX->sendCommand(mNode, OMX_CommandFlush, portIndex);
1768693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
17691beb760d920561679862ded945a04e370368c7f7Andreas Huber
17701beb760d920561679862ded945a04e370368c7f7Andreas Huber    return true;
1771693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1772693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1773693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::disablePortAsync(OMX_U32 portIndex) {
1774693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(mState == EXECUTING || mState == RECONFIGURING);
1775693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1776693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(mPortStatus[portIndex], ENABLED);
1777693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mPortStatus[portIndex] = DISABLING;
1778693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1779693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err =
1780318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        mOMX->sendCommand(mNode, OMX_CommandPortDisable, portIndex);
1781693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
1782693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1783693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    freeBuffersOnPort(portIndex, true);
1784693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1785693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1786693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::enablePortAsync(OMX_U32 portIndex) {
1787693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(mState == EXECUTING || mState == RECONFIGURING);
1788693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1789693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(mPortStatus[portIndex], DISABLED);
1790693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mPortStatus[portIndex] = ENABLING;
1791693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1792693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err =
1793318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex);
1794693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
1795693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1796693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1797693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::fillOutputBuffers() {
1798693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(mState, EXECUTING);
1799693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1800b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber    // This is a workaround for some decoders not properly reporting
1801b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber    // end-of-output-stream. If we own all input buffers and also own
1802b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber    // all output buffers and we already signalled end-of-input-stream,
1803b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber    // the end-of-output-stream is implied.
1804b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber    if (mSignalledEOS
1805b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber            && countBuffersWeOwn(mPortBuffers[kPortIndexInput])
1806b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber                == mPortBuffers[kPortIndexInput].size()
1807b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber            && countBuffersWeOwn(mPortBuffers[kPortIndexOutput])
1808b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber                == mPortBuffers[kPortIndexOutput].size()) {
1809b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber        mNoMoreOutputData = true;
1810b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber        mBufferFilled.signal();
1811b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber
1812b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber        return;
1813b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber    }
1814b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber
1815693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
1816693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
1817693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        fillOutputBuffer(&buffers->editItemAt(i));
1818693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1819693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1820693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1821693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::drainInputBuffers() {
1822450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber    CHECK(mState == EXECUTING || mState == RECONFIGURING);
1823693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1824693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
1825693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
1826693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        drainInputBuffer(&buffers->editItemAt(i));
1827693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1828693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1829693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1830693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::drainInputBuffer(BufferInfo *info) {
1831693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(info->mOwnedByComponent, false);
1832693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1833693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mSignalledEOS) {
1834693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return;
1835693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1836693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1837693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mCodecSpecificDataIndex < mCodecSpecificData.size()) {
1838693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const CodecSpecificData *specific =
1839693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mCodecSpecificData[mCodecSpecificDataIndex];
1840693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1841693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        size_t size = specific->mSize;
1842693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
184318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME)
1844dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber                && !(mQuirks & kWantsNALFragments)) {
1845693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            static const uint8_t kNALStartCode[4] =
1846693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                    { 0x00, 0x00, 0x00, 0x01 };
1847693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1848693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(info->mMem->size() >= specific->mSize + 4);
1849693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1850693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            size += 4;
1851693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1852693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            memcpy(info->mMem->pointer(), kNALStartCode, 4);
1853693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            memcpy((uint8_t *)info->mMem->pointer() + 4,
1854693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                   specific->mData, specific->mSize);
1855693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        } else {
1856693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(info->mMem->size() >= specific->mSize);
1857693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            memcpy(info->mMem->pointer(), specific->mData, specific->mSize);
1858693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1859693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1860134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber        mNoMoreOutputData = false;
1861134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber
1862b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber        CODEC_LOGV("calling emptyBuffer with codec specific data");
1863b03fd8c97695d381e202f6a64989b51c7024c04aAndreas Huber
1864318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        status_t err = mOMX->emptyBuffer(
1865693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mNode, info->mBuffer, 0, size,
1866693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG,
1867693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                0);
186836efa039efaae4526791336cb688032d22b34becAndreas Huber        CHECK_EQ(err, OK);
1869693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1870693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        info->mOwnedByComponent = true;
1871693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1872693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        ++mCodecSpecificDataIndex;
1873693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return;
1874693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1875693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1876693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    MediaBuffer *srcBuffer;
1877693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err;
1878693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mSeekTimeUs >= 0) {
1879693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        MediaSource::ReadOptions options;
1880693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        options.setSeekTo(mSeekTimeUs);
1881134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber
1882693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mSeekTimeUs = -1;
1883134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber        mBufferFilled.signal();
1884693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1885693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        err = mSource->read(&srcBuffer, &options);
1886693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
1887693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        err = mSource->read(&srcBuffer);
1888693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1889693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1890693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
189148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber    OMX_TICKS timestampUs = 0;
1892693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t srcLength = 0;
1893693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1894693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (err != OK) {
18957a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        CODEC_LOGV("signalling end of input stream.");
1896693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        flags |= OMX_BUFFERFLAG_EOS;
1897693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1898693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mSignalledEOS = true;
1899693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
1900134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber        mNoMoreOutputData = false;
1901134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber
1902693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        srcLength = srcBuffer->range_length();
1903693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1904693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (info->mMem->size() < srcLength) {
1905693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            LOGE("info->mMem->size() = %d, srcLength = %d",
1906693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                 info->mMem->size(), srcLength);
1907693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1908693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(info->mMem->size() >= srcLength);
1909693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        memcpy(info->mMem->pointer(),
1910693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber               (const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(),
1911693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber               srcLength);
1912693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
191348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber        if (srcBuffer->meta_data()->findInt64(kKeyTime, &timestampUs)) {
1914134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber            CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d), "
1915134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber                       "timestamp %lld us (%.2f secs)",
1916134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber                       info->mBuffer, srcLength,
1917134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber                       timestampUs, timestampUs / 1E6);
1918693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1919693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1920693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1921693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (srcBuffer != NULL) {
1922693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        srcBuffer->release();
1923693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        srcBuffer = NULL;
1924693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
192536efa039efaae4526791336cb688032d22b34becAndreas Huber
1926318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->emptyBuffer(
192736efa039efaae4526791336cb688032d22b34becAndreas Huber            mNode, info->mBuffer, 0, srcLength,
192848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber            flags, timestampUs);
192936efa039efaae4526791336cb688032d22b34becAndreas Huber
193036efa039efaae4526791336cb688032d22b34becAndreas Huber    if (err != OK) {
193136efa039efaae4526791336cb688032d22b34becAndreas Huber        setState(ERROR);
193236efa039efaae4526791336cb688032d22b34becAndreas Huber        return;
193336efa039efaae4526791336cb688032d22b34becAndreas Huber    }
193436efa039efaae4526791336cb688032d22b34becAndreas Huber
193536efa039efaae4526791336cb688032d22b34becAndreas Huber    info->mOwnedByComponent = true;
193630ab66297501757d745b9ae10da61adcd891f497Andreas Huber
193730ab66297501757d745b9ae10da61adcd891f497Andreas Huber    // This component does not ever signal the EOS flag on output buffers,
193830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    // Thanks for nothing.
193930ab66297501757d745b9ae10da61adcd891f497Andreas Huber    if (mSignalledEOS && !strcmp(mComponentName, "OMX.TI.Video.encoder")) {
194030ab66297501757d745b9ae10da61adcd891f497Andreas Huber        mNoMoreOutputData = true;
194130ab66297501757d745b9ae10da61adcd891f497Andreas Huber        mBufferFilled.signal();
194230ab66297501757d745b9ae10da61adcd891f497Andreas Huber    }
1943693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1944693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1945693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::fillOutputBuffer(BufferInfo *info) {
1946693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(info->mOwnedByComponent, false);
1947693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
19481beb760d920561679862ded945a04e370368c7f7Andreas Huber    if (mNoMoreOutputData) {
19497a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        CODEC_LOGV("There is no more output data available, not "
19501beb760d920561679862ded945a04e370368c7f7Andreas Huber             "calling fillOutputBuffer");
19511beb760d920561679862ded945a04e370368c7f7Andreas Huber        return;
19521beb760d920561679862ded945a04e370368c7f7Andreas Huber    }
19531beb760d920561679862ded945a04e370368c7f7Andreas Huber
19547a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    CODEC_LOGV("Calling fill_buffer on buffer %p", info->mBuffer);
1955318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->fillBuffer(mNode, info->mBuffer);
195636efa039efaae4526791336cb688032d22b34becAndreas Huber    CHECK_EQ(err, OK);
1957693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1958693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    info->mOwnedByComponent = true;
1959693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1960693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1961693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::drainInputBuffer(IOMX::buffer_id buffer) {
1962693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
1963693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
1964693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if ((*buffers)[i].mBuffer == buffer) {
1965693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            drainInputBuffer(&buffers->editItemAt(i));
1966693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            return;
1967693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1968693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1969693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1970693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(!"should not be here.");
1971693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1972693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1973693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::fillOutputBuffer(IOMX::buffer_id buffer) {
1974693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
1975693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
1976693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if ((*buffers)[i].mBuffer == buffer) {
1977693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            fillOutputBuffer(&buffers->editItemAt(i));
1978693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            return;
1979693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
1980693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
1981693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1982693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(!"should not be here.");
1983693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1984693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1985693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::setState(State newState) {
1986693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mState = newState;
1987693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mAsyncCompletion.signal();
1988693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1989693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    // This may cause some spurious wakeups but is necessary to
1990693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    // unblock the reader if we enter ERROR state.
1991693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mBufferFilled.signal();
1992693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
1993693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1994e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Hubervoid OMXCodec::setRawAudioFormat(
1995e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1996e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
19977a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&pcmParams);
1998e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.nPortIndex = portIndex;
1999e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
2000318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
2001e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2002e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
2003e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    CHECK_EQ(err, OK);
2004e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
2005e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.nChannels = numChannels;
2006e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
2007e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.bInterleaved = OMX_TRUE;
2008e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.nBitPerSample = 16;
2009e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.nSamplingRate = sampleRate;
2010e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2011e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
2012e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    if (numChannels == 1) {
2013e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelCF;
2014e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    } else {
2015e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        CHECK_EQ(numChannels, 2);
2016e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
2017e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
2018e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        pcmParams.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
2019e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
2020e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
2021318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
2022e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2023e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
2024e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    CHECK_EQ(err, OK);
2025e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber}
2026e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
2027c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Hubervoid OMXCodec::setAMRFormat(bool isWAMR) {
2028c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    OMX_U32 portIndex = mIsEncoder ? kPortIndexOutput : kPortIndexInput;
2029693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2030c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
2031c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    InitOMXParams(&def);
2032c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    def.nPortIndex = portIndex;
2033456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber
2034c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    status_t err =
2035c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2036456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber
2037c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    CHECK_EQ(err, OK);
2038456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber
2039c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
2040c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    def.eAMRBandMode =
2041c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber        isWAMR ? OMX_AUDIO_AMRBandModeWB0 : OMX_AUDIO_AMRBandModeNB0;
2042456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber
2043c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2044c297fccffc4ab1cb3b9f5c6a5b0802be057f3e0fAndreas Huber    CHECK_EQ(err, OK);
2045456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber
2046456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber    ////////////////////////
2047456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber
2048456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber    if (mIsEncoder) {
2049456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber        sp<MetaData> format = mSource->getFormat();
2050456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber        int32_t sampleRate;
2051456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber        int32_t numChannels;
2052456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber        CHECK(format->findInt32(kKeySampleRate, &sampleRate));
2053693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(format->findInt32(kKeyChannelCount, &numChannels));
2054693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2055e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
2056e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
2057e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber}
2058693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2059e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Hubervoid OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate) {
2060e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    if (mIsEncoder) {
2061e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
2062e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    } else {
2063e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
20647a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        InitOMXParams(&profile);
2065e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        profile.nPortIndex = kPortIndexInput;
2066693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2067318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        status_t err = mOMX->getParameter(
2068e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2069693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(err, OK);
2070693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2071e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        profile.nChannels = numChannels;
2072e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        profile.nSampleRate = sampleRate;
2073e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
2074693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2075318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        err = mOMX->setParameter(
2076e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2077693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(err, OK);
2078693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2079693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2080693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2081693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::setImageOutputFormat(
2082693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) {
20837a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height);
2084693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2085693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#if 0
2086693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_INDEXTYPE index;
2087693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err = mOMX->get_extension_index(
2088693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index);
2089693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
2090693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2091693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    err = mOMX->set_config(mNode, index, &format, sizeof(format));
2092693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
2093693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#endif
2094693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2095693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
20967a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
2097693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexOutput;
2098693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2099318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
2100693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2101693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
2102693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2103693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(def.eDomain, OMX_PortDomainImage);
2104693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2105693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
2106bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
2107693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused);
2108693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    imageDef->eColorFormat = format;
2109693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    imageDef->nFrameWidth = width;
2110693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    imageDef->nFrameHeight = height;
2111693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2112693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (format) {
2113693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_COLOR_FormatYUV420PackedPlanar:
2114693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_COLOR_FormatYUV411Planar:
2115693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2116693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            def.nBufferSize = (width * height * 3) / 2;
2117693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2118693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2119693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2120693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_COLOR_FormatCbYCrY:
2121693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2122693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            def.nBufferSize = width * height * 2;
2123693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2124693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2125693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2126693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_COLOR_Format32bitARGB8888:
2127693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2128693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            def.nBufferSize = width * height * 4;
2129693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2130693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2131693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2132195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber        case OMX_COLOR_Format16bitARGB4444:
2133195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber        case OMX_COLOR_Format16bitARGB1555:
2134195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber        case OMX_COLOR_Format16bitRGB565:
2135195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber        case OMX_COLOR_Format16bitBGR565:
2136195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber        {
2137195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber            def.nBufferSize = width * height * 2;
2138195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber            break;
2139195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber        }
2140195ea1e0d4484f1deb2309e239f6a5cc9a7e5ba7Andreas Huber
2141693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
2142693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(!"Should not be here. Unknown color format.");
2143693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2144693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2145693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
21467530e9c708275c273c134c36c68179f511c1940eAndreas Huber    def.nBufferCountActual = def.nBufferCountMin;
21477530e9c708275c273c134c36c68179f511c1940eAndreas Huber
2148318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
2149693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2150693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
21517530e9c708275c273c134c36c68179f511c1940eAndreas Huber}
2152693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
21537530e9c708275c273c134c36c68179f511c1940eAndreas Hubervoid OMXCodec::setJPEGInputFormat(
21547530e9c708275c273c134c36c68179f511c1940eAndreas Huber        OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) {
21557530e9c708275c273c134c36c68179f511c1940eAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
21567a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
2157693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexInput;
2158693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2159318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
2160693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2161693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
2162693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
21637530e9c708275c273c134c36c68179f511c1940eAndreas Huber    CHECK_EQ(def.eDomain, OMX_PortDomainImage);
21647530e9c708275c273c134c36c68179f511c1940eAndreas Huber    OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
21657530e9c708275c273c134c36c68179f511c1940eAndreas Huber
2166693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingJPEG);
2167693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    imageDef->nFrameWidth = width;
2168693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    imageDef->nFrameHeight = height;
2169693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
21707530e9c708275c273c134c36c68179f511c1940eAndreas Huber    def.nBufferSize = compressedSize;
2171693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nBufferCountActual = def.nBufferCountMin;
2172693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2173318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    err = mOMX->setParameter(
2174693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2175693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
2176693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2177693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2178693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::addCodecSpecificData(const void *data, size_t size) {
2179693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CodecSpecificData *specific =
2180693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1);
2181693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2182693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    specific->mSize = size;
2183693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    memcpy(specific->mData, data, size);
2184693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2185693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mCodecSpecificData.push(specific);
2186693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2187693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2188693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::clearCodecSpecificData() {
2189693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < mCodecSpecificData.size(); ++i) {
2190693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        free(mCodecSpecificData.editItemAt(i));
2191693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2192693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mCodecSpecificData.clear();
2193693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mCodecSpecificDataIndex = 0;
2194693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2195693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2196693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::start(MetaData *) {
2197284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber    Mutex::Autolock autoLock(mLock);
2198284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber
2199693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mState != LOADED) {
2200693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return UNKNOWN_ERROR;
2201693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2202bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber
2203693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    sp<MetaData> params = new MetaData;
2204dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    if (mQuirks & kWantsNALFragments) {
2205dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        params->setInt32(kKeyWantsNALFragments, true);
2206693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2207693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    status_t err = mSource->start(params.get());
2208693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2209693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (err != OK) {
2210693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return err;
2211693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2212693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2213693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mCodecSpecificDataIndex = 0;
2214284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber    mInitialBufferSubmit = true;
2215693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mSignalledEOS = false;
2216693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mNoMoreOutputData = false;
22177f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber    mOutputPortSettingsHaveChanged = false;
2218693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mSeekTimeUs = -1;
2219693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mFilledBuffers.clear();
2220693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2221693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return init();
2222693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2223693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2224693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::stop() {
22257a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    CODEC_LOGV("stop");
2226693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2227693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Mutex::Autolock autoLock(mLock);
2228693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2229693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    while (isIntermediateState(mState)) {
2230693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mAsyncCompletion.wait(mLock);
2231693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2232693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2233693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (mState) {
2234693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case LOADED:
2235693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case ERROR:
2236693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2237693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2238693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case EXECUTING:
2239693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2240693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            setState(EXECUTING_TO_IDLE);
2241693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
22428297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber            if (mQuirks & kRequiresFlushBeforeShutdown) {
22437a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                CODEC_LOGV("This component requires a flush before transitioning "
22448297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                     "from EXECUTING to IDLE...");
22458297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber
22468297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                bool emulateInputFlushCompletion =
22478297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    !flushPortAsync(kPortIndexInput);
22488297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber
22498297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                bool emulateOutputFlushCompletion =
22508297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    !flushPortAsync(kPortIndexOutput);
2251693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
22528297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                if (emulateInputFlushCompletion) {
22538297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    onCmdComplete(OMX_CommandFlush, kPortIndexInput);
22548297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                }
22558297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber
22568297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                if (emulateOutputFlushCompletion) {
22578297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                    onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
22588297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                }
22598297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber            } else {
22608297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
22618297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
22628297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber
22638297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                status_t err =
2264318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                    mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
22658297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber                CHECK_EQ(err, OK);
22668297cedd12f689167d74de5ddacb514e9f6896eaAndreas Huber            }
2267693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2268693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            while (mState != LOADED && mState != ERROR) {
2269693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mAsyncCompletion.wait(mLock);
2270693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
2271693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2272693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2273693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2274693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2275693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
2276693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2277693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(!"should not be here.");
2278693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2279693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2280693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2281693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2282693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mSource->stop();
2283693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2284693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return OK;
2285693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2286693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2287693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MetaData> OMXCodec::getFormat() {
22887f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber    Mutex::Autolock autoLock(mLock);
22897f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber
2290693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return mOutputFormat;
2291693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2292693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2293693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatus_t OMXCodec::read(
2294693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        MediaBuffer **buffer, const ReadOptions *options) {
2295693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    *buffer = NULL;
2296693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2297693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Mutex::Autolock autoLock(mLock);
2298693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2299450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber    if (mState != EXECUTING && mState != RECONFIGURING) {
2300450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber        return UNKNOWN_ERROR;
2301450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber    }
2302450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber
23037e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    bool seeking = false;
23047e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    int64_t seekTimeUs;
23057e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if (options && options->getSeekTo(&seekTimeUs)) {
23067e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        seeking = true;
23077e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
23087e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
2309284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber    if (mInitialBufferSubmit) {
2310284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber        mInitialBufferSubmit = false;
2311284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber
23127e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        if (seeking) {
23137e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            CHECK(seekTimeUs >= 0);
23147e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            mSeekTimeUs = seekTimeUs;
23157e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
23167e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            // There's no reason to trigger the code below, there's
23177e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            // nothing to flush yet.
23187e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            seeking = false;
23197e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        }
23207e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
2321284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber        drainInputBuffers();
2322284f513a4ce2c5aa0e250c07c873731aedb0be26Andreas Huber
2323450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber        if (mState == EXECUTING) {
2324450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber            // Otherwise mState == RECONFIGURING and this code will trigger
2325450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber            // after the output port is reenabled.
2326450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber            fillOutputBuffers();
2327450bf4b0d25c933431b790d911a5fcae750fe38dAndreas Huber        }
2328693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2329693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
23307e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if (seeking) {
23317a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber        CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6);
2332693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2333693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mSignalledEOS = false;
2334693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2335693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK(seekTimeUs >= 0);
2336693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mSeekTimeUs = seekTimeUs;
2337693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2338693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mFilledBuffers.clear();
2339693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2340693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        CHECK_EQ(mState, EXECUTING);
2341693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
23421beb760d920561679862ded945a04e370368c7f7Andreas Huber        bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput);
23431beb760d920561679862ded945a04e370368c7f7Andreas Huber        bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput);
23441beb760d920561679862ded945a04e370368c7f7Andreas Huber
23451beb760d920561679862ded945a04e370368c7f7Andreas Huber        if (emulateInputFlushCompletion) {
23461beb760d920561679862ded945a04e370368c7f7Andreas Huber            onCmdComplete(OMX_CommandFlush, kPortIndexInput);
23471beb760d920561679862ded945a04e370368c7f7Andreas Huber        }
23481beb760d920561679862ded945a04e370368c7f7Andreas Huber
23491beb760d920561679862ded945a04e370368c7f7Andreas Huber        if (emulateOutputFlushCompletion) {
23501beb760d920561679862ded945a04e370368c7f7Andreas Huber            onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
23511beb760d920561679862ded945a04e370368c7f7Andreas Huber        }
2352134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber
2353134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber        while (mSeekTimeUs >= 0) {
2354134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber            mBufferFilled.wait(mLock);
2355134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber        }
2356693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2357693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2358693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) {
2359693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        mBufferFilled.wait(mLock);
2360693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2361693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2362693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mState == ERROR) {
2363693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return UNKNOWN_ERROR;
2364693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2365693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2366693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (mFilledBuffers.empty()) {
2367693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return ERROR_END_OF_STREAM;
2368693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2369693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
23707f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber    if (mOutputPortSettingsHaveChanged) {
23717f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber        mOutputPortSettingsHaveChanged = false;
23727f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber
23737f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber        return INFO_FORMAT_CHANGED;
23747f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber    }
23757f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber
2376693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t index = *mFilledBuffers.begin();
2377693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mFilledBuffers.erase(mFilledBuffers.begin());
2378693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2379693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
2380693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    info->mMediaBuffer->add_ref();
2381693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    *buffer = info->mMediaBuffer;
2382693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2383693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return OK;
2384693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2385693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2386693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::signalBufferReturned(MediaBuffer *buffer) {
2387693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Mutex::Autolock autoLock(mLock);
2388693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2389693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
2390693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
2391693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        BufferInfo *info = &buffers->editItemAt(i);
2392693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2393693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (info->mMediaBuffer == buffer) {
2394693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED);
2395693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            fillOutputBuffer(info);
2396693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            return;
2397693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2398693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2399693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2400693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK(!"should not be here.");
2401693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2402693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2403693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) {
2404693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    static const char *kNames[] = {
2405693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingUnused",
2406693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingAutoDetect",
2407693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingJPEG",
2408693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingJPEG2K",
2409693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingEXIF",
2410693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingTIFF",
2411693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingGIF",
2412693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingPNG",
2413693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingLZW",
2414693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_IMAGE_CodingBMP",
2415693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    };
2416693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2417693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2418693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2419693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (type < 0 || (size_t)type >= numNames) {
2420693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return "UNKNOWN";
2421693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
2422693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return kNames[type];
2423693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2424693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2425693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2426693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const char *colorFormatString(OMX_COLOR_FORMATTYPE type) {
2427693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    static const char *kNames[] = {
2428693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatUnused",
2429693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatMonochrome",
2430693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format8bitRGB332",
2431693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format12bitRGB444",
2432693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format16bitARGB4444",
2433693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format16bitARGB1555",
2434693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format16bitRGB565",
2435693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format16bitBGR565",
2436693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format18bitRGB666",
2437693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format18bitARGB1665",
2438bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        "OMX_COLOR_Format19bitARGB1666",
2439693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format24bitRGB888",
2440693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format24bitBGR888",
2441693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format24bitARGB1887",
2442693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format25bitARGB1888",
2443693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format32bitBGRA8888",
2444693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format32bitARGB8888",
2445693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV411Planar",
2446693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV411PackedPlanar",
2447693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV420Planar",
2448693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV420PackedPlanar",
2449693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV420SemiPlanar",
2450693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV422Planar",
2451693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV422PackedPlanar",
2452693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV422SemiPlanar",
2453693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYCbYCr",
2454693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYCrYCb",
2455693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatCbYCrY",
2456693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatCrYCbY",
2457693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV444Interleaved",
2458693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatRawBayer8bit",
2459693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatRawBayer10bit",
2460693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatRawBayer8bitcompressed",
2461bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        "OMX_COLOR_FormatL2",
2462bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        "OMX_COLOR_FormatL4",
2463bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        "OMX_COLOR_FormatL8",
2464bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        "OMX_COLOR_FormatL16",
2465bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber        "OMX_COLOR_FormatL24",
2466693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatL32",
2467693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV420PackedSemiPlanar",
2468693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_FormatYUV422PackedSemiPlanar",
2469693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format18BitBGR666",
2470693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format24BitARGB6666",
2471693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_COLOR_Format24BitABGR6666",
2472693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    };
2473693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2474693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2475693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2476693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) {
2477693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar";
2478693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else if (type < 0 || (size_t)type >= numNames) {
2479693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return "UNKNOWN";
2480693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
2481693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return kNames[type];
2482693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2483693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2484693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2485693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) {
2486693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    static const char *kNames[] = {
2487693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingUnused",
2488693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingAutoDetect",
2489693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingMPEG2",
2490693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingH263",
2491693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingMPEG4",
2492693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingWMV",
2493693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingRV",
2494693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingAVC",
2495693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_VIDEO_CodingMJPEG",
2496693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    };
2497693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2498693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2499693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2500693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (type < 0 || (size_t)type >= numNames) {
2501693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return "UNKNOWN";
2502693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
2503693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return kNames[type];
2504693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2505693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2506693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2507693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) {
2508693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    static const char *kNames[] = {
2509693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingUnused",
2510693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingAutoDetect",
2511693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingPCM",
2512693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingADPCM",
2513693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingAMR",
2514693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingGSMFR",
2515693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingGSMEFR",
2516693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingGSMHR",
2517693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingPDCFR",
2518693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingPDCEFR",
2519693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingPDCHR",
2520693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingTDMAFR",
2521693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingTDMAEFR",
2522693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingQCELP8",
2523693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingQCELP13",
2524693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingEVRC",
2525693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingSMV",
2526693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingG711",
2527693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingG723",
2528693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingG726",
2529693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingG729",
2530693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingAAC",
2531693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingMP3",
2532693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingSBC",
2533693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingVORBIS",
2534693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingWMA",
2535693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingRA",
2536693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_CodingMIDI",
2537693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    };
2538693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2539693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2540693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2541693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (type < 0 || (size_t)type >= numNames) {
2542693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return "UNKNOWN";
2543693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
2544693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return kNames[type];
2545693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2546693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2547693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2548693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) {
2549693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    static const char *kNames[] = {
2550693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_PCMModeLinear",
2551693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_PCMModeALaw",
2552693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        "OMX_AUDIO_PCMModeMULaw",
2553693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    };
2554693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2555693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
2556693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2557693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (type < 0 || (size_t)type >= numNames) {
2558693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return "UNKNOWN";
2559693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    } else {
2560693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return kNames[type];
2561693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2562693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2563693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
25642f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huberstatic const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) {
25652f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    static const char *kNames[] = {
25662f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeUnused",
25672f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB0",
25682f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB1",
25692f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB2",
25702f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB3",
25712f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB4",
25722f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB5",
25732f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB6",
25742f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeNB7",
25752f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB0",
25762f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB1",
25772f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB2",
25782f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB3",
25792f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB4",
25802f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB5",
25812f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB6",
25822f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB7",
25832f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRBandModeWB8",
25842f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    };
25852f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
25862f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
25872f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
25882f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    if (type < 0 || (size_t)type >= numNames) {
25892f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        return "UNKNOWN";
25902f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    } else {
25912f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        return kNames[type];
25922f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    }
25932f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber}
25942f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
25952f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huberstatic const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) {
25962f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    static const char *kNames[] = {
25972f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRFrameFormatConformance",
25982f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRFrameFormatIF1",
25992f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRFrameFormatIF2",
26002f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRFrameFormatFSF",
26012f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRFrameFormatRTPPayload",
26022f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        "OMX_AUDIO_AMRFrameFormatITU",
26032f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    };
26042f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
26052f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
26062f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
26072f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    if (type < 0 || (size_t)type >= numNames) {
26082f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        return "UNKNOWN";
26092f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    } else {
26102f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber        return kNames[type];
26112f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber    }
26122f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber}
2613693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2614693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
2615693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
26167a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
2617693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = portIndex;
2618693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2619318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
2620693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2621693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
2622693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2623693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output");
2624693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2625693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput)
2626693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber          || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput));
2627693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2628693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    printf("  nBufferCountActual = %ld\n", def.nBufferCountActual);
2629693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    printf("  nBufferCountMin = %ld\n", def.nBufferCountMin);
2630693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    printf("  nBufferSize = %ld\n", def.nBufferSize);
2631693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2632693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (def.eDomain) {
2633693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_PortDomainImage:
2634693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2635693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
2636693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2637693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("\n");
2638693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  // Image\n");
2639693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  nFrameWidth = %ld\n", imageDef->nFrameWidth);
2640693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  nFrameHeight = %ld\n", imageDef->nFrameHeight);
2641693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  nStride = %ld\n", imageDef->nStride);
2642693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2643693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  eCompressionFormat = %s\n",
2644693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                   imageCompressionFormatString(imageDef->eCompressionFormat));
2645693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2646693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  eColorFormat = %s\n",
2647693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                   colorFormatString(imageDef->eColorFormat));
2648693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2649693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2650693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2651693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2652693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_PortDomainVideo:
2653693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2654693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
2655693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2656693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("\n");
2657693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  // Video\n");
2658693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  nFrameWidth = %ld\n", videoDef->nFrameWidth);
2659693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  nFrameHeight = %ld\n", videoDef->nFrameHeight);
2660693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  nStride = %ld\n", videoDef->nStride);
2661693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2662693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  eCompressionFormat = %s\n",
2663693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                   videoCompressionFormatString(videoDef->eCompressionFormat));
2664693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2665693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  eColorFormat = %s\n",
2666693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                   colorFormatString(videoDef->eColorFormat));
2667693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2668693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2669693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2670693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2671693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_PortDomainAudio:
2672693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2673693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
2674693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2675693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("\n");
2676693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  // Audio\n");
2677693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  eEncoding = %s\n",
2678693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                   audioCodingTypeString(audioDef->eEncoding));
2679693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2680693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) {
2681693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                OMX_AUDIO_PARAM_PCMMODETYPE params;
26827a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                InitOMXParams(&params);
2683693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                params.nPortIndex = portIndex;
2684693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2685318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                err = mOMX->getParameter(
2686693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
2687693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK_EQ(err, OK);
2688693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2689693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                printf("  nSamplingRate = %ld\n", params.nSamplingRate);
2690693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                printf("  nChannels = %ld\n", params.nChannels);
2691693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                printf("  bInterleaved = %d\n", params.bInterleaved);
2692693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                printf("  nBitPerSample = %ld\n", params.nBitPerSample);
2693693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2694693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                printf("  eNumData = %s\n",
2695693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                       params.eNumData == OMX_NumericalDataSigned
2696693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        ? "signed" : "unsigned");
2697693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2698693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                printf("  ePCMMode = %s\n", audioPCMModeString(params.ePCMMode));
26992f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber            } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) {
27002f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                OMX_AUDIO_PARAM_AMRTYPE amr;
27012f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                InitOMXParams(&amr);
27022f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                amr.nPortIndex = portIndex;
27032f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
2704318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                err = mOMX->getParameter(
27052f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                        mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
27062f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                CHECK_EQ(err, OK);
27072f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
27082f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                printf("  nChannels = %ld\n", amr.nChannels);
27092f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                printf("  eAMRBandMode = %s\n",
27102f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                        amrBandModeString(amr.eAMRBandMode));
27112f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                printf("  eAMRFrameFormat = %s\n",
27122f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                        amrFrameFormatString(amr.eAMRFrameFormat));
2713693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
2714693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2715693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2716693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2717693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2718693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
2719693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2720693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            printf("  // Unknown\n");
2721693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2722693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2723693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2724693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2725693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    printf("}\n");
2726693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2727693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2728693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
2729693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mOutputFormat = new MetaData;
2730693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    mOutputFormat->setCString(kKeyDecoderComponent, mComponentName);
2731693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2732693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
27337a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    InitOMXParams(&def);
2734693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    def.nPortIndex = kPortIndexOutput;
2735693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2736318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    status_t err = mOMX->getParameter(
2737693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2738693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    CHECK_EQ(err, OK);
2739693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2740693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    switch (def.eDomain) {
2741693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_PortDomainImage:
2742693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2743693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
2744693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused);
2745693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
274618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
2747693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat);
2748693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth);
2749693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight);
2750693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2751693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2752693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2753693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_PortDomainAudio:
2754693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2755693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio;
2756693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2757e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) {
2758e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                OMX_AUDIO_PARAM_PCMMODETYPE params;
27597a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber                InitOMXParams(&params);
2760e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                params.nPortIndex = kPortIndexOutput;
2761693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2762318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                err = mOMX->getParameter(
2763e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                        mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
2764e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                CHECK_EQ(err, OK);
2765693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2766e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                CHECK_EQ(params.eNumData, OMX_NumericalDataSigned);
2767e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                CHECK_EQ(params.nBitPerSample, 16);
2768e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                CHECK_EQ(params.ePCMMode, OMX_AUDIO_PCMModeLinear);
2769693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2770e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                int32_t numChannels, sampleRate;
2771e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                inputFormat->findInt32(kKeyChannelCount, &numChannels);
2772e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                inputFormat->findInt32(kKeySampleRate, &sampleRate);
2773693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2774e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                if ((OMX_U32)numChannels != params.nChannels) {
2775e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                    LOGW("Codec outputs a different number of channels than "
2776e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                         "the input stream contains.");
2777e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                }
277837940eefcba982836b579fe1ffec6cada72b0974Andreas Huber
277918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                mOutputFormat->setCString(
278018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
278137940eefcba982836b579fe1ffec6cada72b0974Andreas Huber
2782e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                // Use the codec-advertised number of channels, as some
2783e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                // codecs appear to output stereo even if the input data is
2784e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                // mono.
2785e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                mOutputFormat->setInt32(kKeyChannelCount, params.nChannels);
278637940eefcba982836b579fe1ffec6cada72b0974Andreas Huber
2787e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                // The codec-reported sampleRate is not reliable...
2788e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                mOutputFormat->setInt32(kKeySampleRate, sampleRate);
2789e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) {
27902f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                OMX_AUDIO_PARAM_AMRTYPE amr;
27912f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                InitOMXParams(&amr);
27922f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                amr.nPortIndex = kPortIndexOutput;
27932f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
2794318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                err = mOMX->getParameter(
27952f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                        mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
27962f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                CHECK_EQ(err, OK);
27972f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
27982f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                CHECK_EQ(amr.nChannels, 1);
27992f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                mOutputFormat->setInt32(kKeyChannelCount, 1);
28002f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber
28012f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0
28022f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                    && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) {
280318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    mOutputFormat->setCString(
280418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                            kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB);
28052f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                    mOutputFormat->setInt32(kKeySampleRate, 8000);
28062f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0
28072f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                            && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) {
280818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    mOutputFormat->setCString(
280918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                            kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB);
28102f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                    mOutputFormat->setInt32(kKeySampleRate, 16000);
28112f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                } else {
28122f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                    CHECK(!"Unknown AMR band mode.");
28132f7daa1d7e01bfc2cd7546edeeaea0c3c2ee728cAndreas Huber                }
2814e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) {
281518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                mOutputFormat->setCString(
281618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
2817e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            } else {
2818e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber                CHECK(!"Should not be here. Unknown audio encoding.");
2819e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            }
2820693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2821693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2822693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2823693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        case OMX_PortDomainVideo:
2824693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2825693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2826693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2827693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) {
282818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                mOutputFormat->setCString(
282918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
2830693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) {
283118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                mOutputFormat->setCString(
283218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
2833693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) {
283418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                mOutputFormat->setCString(
283518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
2836693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) {
283718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                mOutputFormat->setCString(
283818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
2839693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else {
2840693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                CHECK(!"Unknown compression format.");
2841693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
2842693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2843693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            if (!strcmp(mComponentName, "OMX.PV.avcdec")) {
2844693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                // This component appears to be lying to me.
2845693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mOutputFormat->setInt32(
2846693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        kKeyWidth, (video_def->nFrameWidth + 15) & -16);
2847693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mOutputFormat->setInt32(
2848693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                        kKeyHeight, (video_def->nFrameHeight + 15) & -16);
2849693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            } else {
2850693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth);
2851693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight);
2852693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            }
2853693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2854693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat);
2855693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2856693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2857693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
2858693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        default:
2859693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        {
2860693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            CHECK(!"should not be here, neither audio nor video.");
2861693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            break;
2862693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
2863693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
2864693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
2865693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
286618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber////////////////////////////////////////////////////////////////////////////////
286718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
286818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatus_t QueryCodecs(
286918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        const sp<IOMX> &omx,
287018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        const char *mime, bool queryDecoders,
287118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        Vector<CodecCapabilities> *results) {
287218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    results->clear();
287318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
287418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    for (int index = 0;; ++index) {
287518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        const char *componentName;
287618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
287718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        if (!queryDecoders) {
287818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            componentName = GetCodec(
287918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    kEncoderInfo, sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]),
288018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    mime, index);
288118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        } else {
288218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            componentName = GetCodec(
288318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    kDecoderInfo, sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]),
288418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    mime, index);
288518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        }
288618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
288718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        if (!componentName) {
288818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            return OK;
288918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        }
289018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
2891318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        sp<OMXCodecObserver> observer = new OMXCodecObserver;
289218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        IOMX::node_id node;
2893318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        status_t err = omx->allocateNode(componentName, observer, &node);
289418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
289518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        if (err != OK) {
289618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            continue;
289718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        }
289818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
289918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        OMXCodec::setComponentRole(omx, node, queryDecoders, mime);
290018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
290118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        results->push();
290218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        CodecCapabilities *caps = &results->editItemAt(results->size() - 1);
290318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        caps->mComponentName = componentName;
290418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
290518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
290618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        InitOMXParams(&param);
290718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
290818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        param.nPortIndex = queryDecoders ? 0 : 1;
290918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
291018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
2911318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            err = omx->getParameter(
291218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    node, OMX_IndexParamVideoProfileLevelQuerySupported,
291318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                    &param, sizeof(param));
291418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
291518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            if (err != OK) {
291618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                break;
291718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            }
291818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
291918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            CodecProfileLevel profileLevel;
292018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            profileLevel.mProfile = param.eProfile;
292118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            profileLevel.mLevel = param.eLevel;
292218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
292318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            caps->mProfileLevels.push(profileLevel);
292418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        }
292518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
2926318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        CHECK_EQ(omx->freeNode(node), OK);
292718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    }
292818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber}
292918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber
2930693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}  // namespace android
2931