OMXCodec.cpp revision a3f4d7f096e5c91dc6af085761b1459866c043d9
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/* 227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2009 The Android Open Source Project 327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * 427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License"); 527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License. 627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at 727c174483a8ae9688d5d4897c19074f62c7f1701James Dong * 827c174483a8ae9688d5d4897c19074f62c7f1701James Dong * http://www.apache.org/licenses/LICENSE-2.0 927c174483a8ae9688d5d4897c19074f62c7f1701James Dong * 1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software 1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS, 1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and 1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License. 1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */ 1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong 17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0 18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "OMXCodec" 19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <utils/Log.h> 20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "include/AACDecoder.h" 22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "include/AACEncoder.h" 23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "include/AMRNBDecoder.h" 24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "include/AMRNBEncoder.h" 25f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "include/AMRWBDecoder.h" 26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "include/AMRWBEncoder.h" 27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "include/AVCDecoder.h" 28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "include/AVCEncoder.h" 29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "include/G711Decoder.h" 301173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include "include/M4vH263Decoder.h" 31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "include/M4vH263Encoder.h" 321065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include "include/MP3Decoder.h" 33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "include/VorbisDecoder.h" 34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "include/VPXDecoder.h" 351173118eace0e9e347cb007f0da817cee87579edGlenn Kasten 36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "include/ESDS.h" 37f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/IServiceManager.h> 39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h> 40f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/ProcessState.h> 41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h> 42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/IMediaPlayerService.h> 43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/HardwareAPI.h> 44f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaBuffer.h> 45f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 46f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h> 47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaExtractor.h> 48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MetaData.h> 49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXCodec.h> 50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/Utils.h> 51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <utils/Vector.h> 52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Audio.h> 54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h> 55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if HAVE_SOFTWARE_DECODERS 57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "include/ThreadedSource.h" 58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif 59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "include/avc_utils.h" 61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 62f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android { 63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 64f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecInfo { 65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *mime; 66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *codec; 67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}; 68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define FACTORY_CREATE_ENCODER(name) \ 70f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic sp<MediaSource> Make##name(const sp<MediaSource> &source, const sp<MetaData> &meta) { \ 71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return new name(source, meta); \ 72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define FACTORY_REF(name) { #name, Make##name }, 75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 76f933441648ef6a71dee783d733aac17b9508b452Andreas HuberFACTORY_CREATE_ENCODER(AMRNBEncoder) 77f933441648ef6a71dee783d733aac17b9508b452Andreas HuberFACTORY_CREATE_ENCODER(AMRWBEncoder) 78f933441648ef6a71dee783d733aac17b9508b452Andreas HuberFACTORY_CREATE_ENCODER(AACEncoder) 79f933441648ef6a71dee783d733aac17b9508b452Andreas HuberFACTORY_CREATE_ENCODER(AVCEncoder) 80f933441648ef6a71dee783d733aac17b9508b452Andreas HuberFACTORY_CREATE_ENCODER(M4vH263Encoder) 81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if HAVE_SOFTWARE_DECODERS 83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define FACTORY_CREATE(name) \ 85f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic sp<MediaSource> Make##name(const sp<MediaSource> &source) { \ 86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return new name(source); \ 87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 89f933441648ef6a71dee783d733aac17b9508b452Andreas HuberFACTORY_CREATE(AMRNBDecoder) 90f933441648ef6a71dee783d733aac17b9508b452Andreas HuberFACTORY_CREATE(AMRWBDecoder) 91f933441648ef6a71dee783d733aac17b9508b452Andreas HuberFACTORY_CREATE(AACDecoder) 92f933441648ef6a71dee783d733aac17b9508b452Andreas HuberFACTORY_CREATE(AVCDecoder) 93f933441648ef6a71dee783d733aac17b9508b452Andreas HuberFACTORY_CREATE(G711Decoder) 94f933441648ef6a71dee783d733aac17b9508b452Andreas HuberFACTORY_CREATE(MP3Decoder) 95f933441648ef6a71dee783d733aac17b9508b452Andreas HuberFACTORY_CREATE(M4vH263Decoder) 96f933441648ef6a71dee783d733aac17b9508b452Andreas HuberFACTORY_CREATE(VorbisDecoder) 97f933441648ef6a71dee783d733aac17b9508b452Andreas HuberFACTORY_CREATE(VPXDecoder) 98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif 99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 100f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic sp<MediaSource> InstantiateSoftwareEncoder( 101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *name, const sp<MediaSource> &source, 102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const sp<MetaData> &meta) { 103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber struct FactoryInfo { 104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *name; 105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<MediaSource> (*CreateFunc)(const sp<MediaSource> &, const sp<MetaData> &); 106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber }; 107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber static const FactoryInfo kFactoryInfo[] = { 109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber FACTORY_REF(AMRNBEncoder) 110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber FACTORY_REF(AMRWBEncoder) 111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber FACTORY_REF(AACEncoder) 112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber FACTORY_REF(AVCEncoder) 113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber FACTORY_REF(M4vH263Encoder) 114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber }; 115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (size_t i = 0; 116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) { 117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strcmp(name, kFactoryInfo[i].name)) { 118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return (*kFactoryInfo[i].CreateFunc)(source, meta); 119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return NULL; 123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 125f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic sp<MediaSource> InstantiateSoftwareCodec( 126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *name, const sp<MediaSource> &source) { 127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if HAVE_SOFTWARE_DECODERS 128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber struct FactoryInfo { 129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *name; 130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<MediaSource> (*CreateFunc)(const sp<MediaSource> &); 131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber }; 132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber static const FactoryInfo kFactoryInfo[] = { 134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber FACTORY_REF(AMRNBDecoder) 135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber FACTORY_REF(AMRWBDecoder) 136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber FACTORY_REF(AACDecoder) 137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber FACTORY_REF(AVCDecoder) 138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber FACTORY_REF(G711Decoder) 139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber FACTORY_REF(MP3Decoder) 140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber FACTORY_REF(M4vH263Decoder) 141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber FACTORY_REF(VorbisDecoder) 142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber FACTORY_REF(VPXDecoder) 143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber }; 144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (size_t i = 0; 145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) { 146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strcmp(name, kFactoryInfo[i].name)) { 147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strcmp(name, "VPXDecoder")) { 148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return new ThreadedSource( 149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber (*kFactoryInfo[i].CreateFunc)(source)); 150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return (*kFactoryInfo[i].CreateFunc)(source); 152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif 155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return NULL; 157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#undef FACTORY_REF 160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#undef FACTORY_CREATE 161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 162f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic const CodecInfo kDecoderInfo[] = { 163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_IMAGE_JPEG, "OMX.TI.JPEG.decode" }, 164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" }, 165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.google.mp3.decoder" }, 166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_AUDIO_MPEG, "MP3Decoder" }, 167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.decode" }, 168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.Nvidia.amr.decoder" }, 169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.google.amrnb.decoder" }, 170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBDecoder" }, 171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.Nvidia.amrwb.decoder" }, 172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.decode" }, 173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.google.amrwb.decoder" }, 174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_AUDIO_AMR_WB, "AMRWBDecoder" }, 175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.Nvidia.aac.decoder" }, 176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.decode" }, 177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.google.aac.decoder" }, 178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_AUDIO_AAC, "AACDecoder" }, 179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_AUDIO_G711_ALAW, "OMX.google.g711.alaw.decoder" }, 180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_AUDIO_G711_ALAW, "G711Decoder" }, 181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_AUDIO_G711_MLAW, "OMX.google.g711.mlaw.decoder" }, 182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_AUDIO_G711_MLAW, "G711Decoder" }, 183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.DUCATI1.VIDEO.DECODER" }, 184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.Nvidia.mp4.decode" }, 185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.7x30.video.decoder.mpeg4" }, 186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.decoder.mpeg4" }, 187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.Decoder" }, 188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.SEC.MPEG4.Decoder" }, 189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.google.mpeg4.decoder" }, 190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_MPEG4, "M4vH263Decoder" }, 191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.DUCATI1.VIDEO.DECODER" }, 192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_H263, "OMX.Nvidia.h263.decode" }, 193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.7x30.video.decoder.h263" }, 194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.decoder.h263" }, 195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_H263, "OMX.SEC.H263.Decoder" }, 196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_H263, "OMX.google.h263.decoder" }, 197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_H263, "M4vH263Decoder" }, 198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.DUCATI1.VIDEO.DECODER" }, 199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.Nvidia.h264.decode" }, 200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.7x30.video.decoder.avc" }, 201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" }, 202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.Decoder" }, 203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.SEC.AVC.Decoder" }, 204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.google.h264.decoder" }, 205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.google.avc.decoder" }, 206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_AVC, "AVCDecoder" }, 207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_AUDIO_VORBIS, "OMX.google.vorbis.decoder" }, 208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_AUDIO_VORBIS, "VorbisDecoder" }, 209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_VPX, "OMX.google.vpx.decoder" }, 210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_VPX, "VPXDecoder" }, 211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_MPEG2, "OMX.Nvidia.mpeg2v.decode" }, 212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}; 213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 214f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic const CodecInfo kEncoderInfo[] = { 215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.encode" }, 216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBEncoder" }, 217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.encode" }, 218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_AUDIO_AMR_WB, "AMRWBEncoder" }, 219349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.encode" }, 220349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber { MEDIA_MIMETYPE_AUDIO_AAC, "AACEncoder" }, 221349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.DUCATI1.VIDEO.MPEG4E" }, 222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.7x30.video.encoder.mpeg4" }, 223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.encoder.mpeg4" }, 224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.encoder" }, 225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.Nvidia.mp4.encoder" }, 226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.SEC.MPEG4.Encoder" }, 227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_MPEG4, "M4vH263Encoder" }, 228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.DUCATI1.VIDEO.MPEG4E" }, 229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.7x30.video.encoder.h263" }, 230349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.encoder.h263" }, 231349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.encoder" }, 232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_H263, "OMX.Nvidia.h263.encoder" }, 233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_H263, "OMX.SEC.H263.Encoder" }, 234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_H263, "M4vH263Encoder" }, 235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.DUCATI1.VIDEO.H264E" }, 236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.7x30.video.encoder.avc" }, 237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.encoder.avc" }, 238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.encoder" }, 239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.Nvidia.h264.encoder" }, 240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.SEC.AVC.Encoder" }, 241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_AVC, "AVCEncoder" }, 242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}; 243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#undef OPTIONAL 245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define CODEC_LOGI(x, ...) LOGI("[%s] "x, mComponentName, ##__VA_ARGS__) 247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define CODEC_LOGV(x, ...) LOGV("[%s] "x, mComponentName, ##__VA_ARGS__) 248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define CODEC_LOGE(x, ...) LOGE("[%s] "x, mComponentName, ##__VA_ARGS__) 249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 250f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct OMXCodecObserver : public BnOMXObserver { 251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMXCodecObserver() { 252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber void setCodec(const sp<OMXCodec> &target) { 255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mTarget = target; 256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // from IOMXObserver 259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber virtual void onMessage(const omx_message &msg) { 260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<OMXCodec> codec = mTarget.promote(); 261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (codec.get() != NULL) { 263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Mutex::Autolock autoLock(codec->mLock); 264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber codec->on_message(msg); 265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber codec.clear(); 266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 269f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected: 270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber virtual ~OMXCodecObserver() {} 271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 272f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate: 273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber wp<OMXCodec> mTarget; 274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMXCodecObserver(const OMXCodecObserver &); 276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMXCodecObserver &operator=(const OMXCodecObserver &); 277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}; 278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 279f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic const char *GetCodec(const CodecInfo *info, size_t numInfos, 280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *mime, int index) { 281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(index >= 0); 282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for(size_t i = 0; i < numInfos; ++i) { 283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strcasecmp(mime, info[i].mime)) { 284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (index == 0) { 285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return info[i].codec; 286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber --index; 289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return NULL; 293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 295f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T> 296f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) { 297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber params->nSize = sizeof(T); 298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber params->nVersion.s.nVersionMajor = 1; 299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber params->nVersion.s.nVersionMinor = 0; 300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber params->nVersion.s.nRevision = 0; 301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber params->nVersion.s.nStep = 0; 302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 304f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic bool IsSoftwareCodec(const char *componentName) { 305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strncmp("OMX.google.", componentName, 11)) { 306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strncmp("OMX.", componentName, 4)) { 310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return false; 31131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber } 31231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// A sort order in which OMX software codecs are first, followed 317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// by other (non-OMX) software codecs, followed by everything else. 318f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic int CompareSoftwareCodecsFirst( 319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const String8 *elem1, const String8 *elem2) { 320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool isOMX1 = !strncmp(elem1->string(), "OMX.", 4); 321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool isOMX2 = !strncmp(elem2->string(), "OMX.", 4); 322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool isSoftwareCodec1 = IsSoftwareCodec(elem1->string()); 324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool isSoftwareCodec2 = IsSoftwareCodec(elem2->string()); 325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 326dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber if (isSoftwareCodec1) { 327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!isSoftwareCodec2) { return -1; } 328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (isOMX1) { 330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (isOMX2) { return 0; } 331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return -1; 333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (isOMX2) { return 0; } 335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return 1; 337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return -1; 340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (isSoftwareCodec2) { 343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return 1; 344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 3457a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong 346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return 0; 347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// static 350f933441648ef6a71dee783d733aac17b9508b452Andreas Huberuint32_t OMXCodec::getComponentQuirks( 351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *componentName, bool isEncoder) { 352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber uint32_t quirks = 0; 353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strcmp(componentName, "OMX.Nvidia.amr.decoder") || 355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber !strcmp(componentName, "OMX.Nvidia.amrwb.decoder") || 356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber !strcmp(componentName, "OMX.Nvidia.aac.decoder") || 357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber !strcmp(componentName, "OMX.Nvidia.mp3.decoder")) { 358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber quirks |= kDecoderLiesAboutNumberOfChannels; 359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strcmp(componentName, "OMX.TI.MP3.decode")) { 362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber quirks |= kNeedsFlushBeforeDisable; 363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber quirks |= kDecoderLiesAboutNumberOfChannels; 364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strcmp(componentName, "OMX.TI.AAC.decode")) { 366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber quirks |= kNeedsFlushBeforeDisable; 367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber quirks |= kRequiresFlushCompleteEmulation; 368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber quirks |= kSupportsMultipleFramesPerInputBuffer; 369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strncmp(componentName, "OMX.qcom.video.encoder.", 23)) { 371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber quirks |= kRequiresLoadedToIdleAfterAllocation; 372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber quirks |= kRequiresAllocateBufferOnInputPorts; 373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber quirks |= kRequiresAllocateBufferOnOutputPorts; 374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strncmp(componentName, "OMX.qcom.video.encoder.avc", 26)) { 375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // The AVC encoder advertises the size of output buffers 377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // based on the input video resolution and assumes 3783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block // the worst/least compression ratio is 0.5. It is found that 379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // sometimes, the output buffer size is larger than 380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // size advertised by the encoder. 381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber quirks |= kRequiresLargerEncoderOutputBuffer; 382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strncmp(componentName, "OMX.qcom.7x30.video.encoder.", 28)) { 385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strncmp(componentName, "OMX.qcom.video.decoder.", 23)) { 387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber quirks |= kRequiresAllocateBufferOnOutputPorts; 388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber quirks |= kDefersOutputBufferAllocation; 389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strncmp(componentName, "OMX.qcom.7x30.video.decoder.", 28)) { 3911065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber quirks |= kRequiresAllocateBufferOnInputPorts; 3921065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber quirks |= kRequiresAllocateBufferOnOutputPorts; 3931065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber quirks |= kDefersOutputBufferAllocation; 3941065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber } 3951065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber 3961065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber if (!strcmp(componentName, "OMX.TI.DUCATI1.VIDEO.DECODER")) { 3971065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber quirks |= kRequiresAllocateBufferOnInputPorts; 3981065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber quirks |= kRequiresAllocateBufferOnOutputPorts; 3991065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber } 4001065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber 4011065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber // FIXME: 4021065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber // Remove the quirks after the work is done. 4031065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber else if (!strcmp(componentName, "OMX.TI.DUCATI1.VIDEO.MPEG4E") || 4041065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber !strcmp(componentName, "OMX.TI.DUCATI1.VIDEO.H264E")) { 4051065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber 4061065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber quirks |= kRequiresAllocateBufferOnInputPorts; 407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber quirks |= kRequiresAllocateBufferOnOutputPorts; 408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber else if (!strncmp(componentName, "OMX.TI.", 7)) { 410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Apparently I must not use OMX_UseBuffer on either input or 411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // output ports on any of the TI components or quote: 412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // "(I) may have unexpected problem (sic) which can be timing related 413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // and hard to reproduce." 414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber quirks |= kRequiresAllocateBufferOnInputPorts; 416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber quirks |= kRequiresAllocateBufferOnOutputPorts; 417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strncmp(componentName, "OMX.TI.Video.encoder", 20)) { 418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber quirks |= kAvoidMemcopyInputRecordingFrames; 419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strcmp(componentName, "OMX.TI.Video.Decoder")) { 423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber quirks |= kInputBufferSizesAreBogus; 424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strncmp(componentName, "OMX.SEC.", 8) && !isEncoder) { 427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // These output buffers contain no video data, just some 428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // opaque information that allows the overlay to display their 429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // contents. 430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber quirks |= kOutputBuffersAreUnreadable; 431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return quirks; 4349bc7af17974f448291a44912566ec7472a0d798bMathias Agopian} 4359bc7af17974f448291a44912566ec7472a0d798bMathias Agopian 4369bc7af17974f448291a44912566ec7472a0d798bMathias Agopian// static 4379bc7af17974f448291a44912566ec7472a0d798bMathias Agopianvoid OMXCodec::findMatchingCodecs( 4389bc7af17974f448291a44912566ec7472a0d798bMathias Agopian const char *mime, 4399bc7af17974f448291a44912566ec7472a0d798bMathias Agopian bool createEncoder, const char *matchComponentName, 4409bc7af17974f448291a44912566ec7472a0d798bMathias Agopian uint32_t flags, 441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Vector<String8> *matchingCodecs) { 442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber matchingCodecs->clear(); 443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (int index = 0;; ++index) { 445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *componentName; 446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (createEncoder) { 448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber componentName = GetCodec( 449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber kEncoderInfo, 450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]), 451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mime, index); 452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber componentName = GetCodec( 4543c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis kDecoderInfo, 4553c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]), 4563c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis mime, index); 4573c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis } 4583c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis 4593c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis if (!componentName) { 4603c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis break; 4613c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis } 462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // If a specific codec is requested, skip the non-matching ones. 4643c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis if (matchComponentName && strcmp(componentName, matchComponentName)) { 465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber continue; 466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // When requesting software-only codecs, only push software codecs 469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // When requesting hardware-only codecs, only push hardware codecs 470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // When there is request neither for software-only nor for 471258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis // hardware-only codecs, push all codecs 472258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis if (((flags & kSoftwareCodecsOnly) && IsSoftwareCodec(componentName)) || 473258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis ((flags & kHardwareCodecsOnly) && !IsSoftwareCodec(componentName)) || 474258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis (!(flags & (kSoftwareCodecsOnly | kHardwareCodecsOnly)))) { 475258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis 476258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis matchingCodecs->push(String8(componentName)); 477258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis } 478258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis } 479258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis 480258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis if (flags & kPreferSoftwareCodecs) { 481258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis matchingCodecs->sort(CompareSoftwareCodecsFirst); 482258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis } 483258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis} 484258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis 485258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis// static 486258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennissp<MediaSource> OMXCodec::Create( 487258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis const sp<IOMX> &omx, 488258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis const sp<MetaData> &meta, bool createEncoder, 489258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis const sp<MediaSource> &source, 490258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis const char *matchComponentName, 491258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis uint32_t flags, 492258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis const sp<ANativeWindow> &nativeWindow) { 493258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis int32_t requiresSecureBuffers; 494258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis if (source->getFormat()->findInt32( 495258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis kKeyRequiresSecureBuffers, 496258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis &requiresSecureBuffers) 497258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis && requiresSecureBuffers) { 498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber flags |= kIgnoreCodecSpecificData; 499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber flags |= kUseSecureInputBuffers; 500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *mime; 503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool success = meta->findCString(kKeyMIMEType, &mime); 504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(success); 505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Vector<String8> matchingCodecs; 5073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block findMatchingCodecs( 508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mime, createEncoder, matchComponentName, flags, &matchingCodecs); 509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (matchingCodecs.isEmpty()) { 511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return NULL; 51274006804065941841883c4b46ee785070164023fJamie Gennis } 5138ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev 514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<OMXCodecObserver> observer = new OMXCodecObserver; 515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber IOMX::node_id node = 0; 516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *componentName; 518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (size_t i = 0; i < matchingCodecs.size(); ++i) { 519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber componentName = matchingCodecs[i].string(); 520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 52174006804065941841883c4b46ee785070164023fJamie Gennis sp<MediaSource> softwareCodec = createEncoder? 52274006804065941841883c4b46ee785070164023fJamie Gennis InstantiateSoftwareEncoder(componentName, source, meta): 52374006804065941841883c4b46ee785070164023fJamie Gennis InstantiateSoftwareCodec(componentName, source); 52474006804065941841883c4b46ee785070164023fJamie Gennis 52574006804065941841883c4b46ee785070164023fJamie Gennis if (softwareCodec != NULL) { 52674006804065941841883c4b46ee785070164023fJamie Gennis LOGV("Successfully allocated software codec '%s'", componentName); 527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return softwareCodec; 529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 53174006804065941841883c4b46ee785070164023fJamie Gennis LOGV("Attempting to allocate OMX node '%s'", componentName); 53274006804065941841883c4b46ee785070164023fJamie Gennis 533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber uint32_t quirks = getComponentQuirks(componentName, createEncoder); 534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!createEncoder 53674006804065941841883c4b46ee785070164023fJamie Gennis && (quirks & kOutputBuffersAreUnreadable) 53774006804065941841883c4b46ee785070164023fJamie Gennis && (flags & kClientNeedsFramebuffer)) { 5383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block if (strncmp(componentName, "OMX.SEC.", 8)) { 539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // For OMX.SEC.* decoders we can enable a special mode that 540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // gives the client access to the framebuffer contents. 541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGW("Component '%s' does not give the client access to " 543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber "the framebuffer contents. Skipping.", 544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber componentName); 545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber continue; 547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 55074006804065941841883c4b46ee785070164023fJamie Gennis status_t err = omx->allocateNode(componentName, observer, &node); 551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err == OK) { 552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGV("Successfully allocated OMX node '%s'", componentName); 553258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis 554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<OMXCodec> codec = new OMXCodec( 555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber omx, node, quirks, flags, 556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber createEncoder, mime, componentName, 557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber source, nativeWindow); 558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber observer->setCodec(codec); 560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = codec->configureCodec(meta); 562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err == OK) { 564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strcmp("OMX.Nvidia.mpeg2v.decode", componentName)) { 565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber codec->mFlags |= kOnlySubmitOneInputBufferAtOneTime; 566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block return codec; 569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGV("Failed to configure codec '%s'", componentName); 572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return NULL; 576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 578f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t OMXCodec::configureCodec(const sp<MetaData> &meta) { 579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGV("configureCodec protected=%d", 580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber (mFlags & kEnableGrallocUsageProtected) ? 1 : 0); 581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5828ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev if (!(mFlags & kIgnoreCodecSpecificData)) { 583c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber uint32_t type; 584c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber const void *data; 585c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber size_t size; 586c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber if (meta->findData(kKeyESDS, &type, &data, &size)) { 587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ESDS esds((const char *)data, size); 588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(esds.InitCheck(), (status_t)OK); 589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const void *codec_specific_data; 591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t codec_specific_data_size; 592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber esds.getCodecSpecificInfo( 593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber &codec_specific_data, &codec_specific_data_size); 594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber addCodecSpecificData( 596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber codec_specific_data, codec_specific_data_size); 597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (meta->findData(kKeyAVCC, &type, &data, &size)) { 598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Parse the AVCDecoderConfigurationRecord 599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const uint8_t *ptr = (const uint8_t *)data; 601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(size >= 7); 603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber uint8_t profile = ptr[1]; 605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber uint8_t level = ptr[3]; 606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // There is decodable content out there that fails the following 608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // assertion, let's be lenient for now... 609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // CHECK((ptr[4] >> 2) == 0x3f); // reserved 610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t lengthSize = 1 + (ptr[4] & 3); 612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // commented out check below as H264_QVGA_500_NO_AUDIO.3gp 614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // violates it... 615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // CHECK((ptr[5] >> 5) == 7); // reserved 616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 617349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber size_t numSeqParameterSets = ptr[5] & 31; 618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ptr += 6; 620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size -= 6; 621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 622349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber for (size_t i = 0; i < numSeqParameterSets; ++i) { 623349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber CHECK(size >= 2); 624349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber size_t length = U16_AT(ptr); 625349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 626349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber ptr += 2; 627349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber size -= 2; 628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(size >= length); 630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber addCodecSpecificData(ptr, length); 632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ptr += length; 634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size -= length; 635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(size >= 1); 638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t numPictureParameterSets = *ptr; 639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ++ptr; 640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber --size; 641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (size_t i = 0; i < numPictureParameterSets; ++i) { 643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(size >= 2); 644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t length = U16_AT(ptr); 645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ptr += 2; 647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size -= 2; 648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(size >= length); 650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber addCodecSpecificData(ptr, length); 652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ptr += length; 654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size -= length; 655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CODEC_LOGI( 658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber "AVC profile = %d (%s), level = %d", 659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber (int)profile, AVCProfileToString(profile), level); 660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strcmp(mComponentName, "OMX.TI.Video.Decoder") 662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber && (profile != kAVCProfileBaseline || level > 30)) { 663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // This stream exceeds the decoder's capabilities. The decoder 664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // does not handle this gracefully and would clobber the heap 665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // and wreak havoc instead... 666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGE("Profile and/or level exceed the decoder's capabilities."); 668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return ERROR_UNSUPPORTED; 669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) { 671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber addCodecSpecificData(data, size); 672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(meta->findData(kKeyVorbisBooks, &type, &data, &size)); 674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber addCodecSpecificData(data, size); 675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t bitRate = 0; 679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mIsEncoder) { 680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(meta->findInt32(kKeyBitRate, &bitRate)); 681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mMIME)) { 683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber setAMRFormat(false /* isWAMR */, bitRate); 684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mMIME)) { 6852944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber setAMRFormat(true /* isWAMR */, bitRate); 6862944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mMIME)) { 6872944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber int32_t numChannels, sampleRate; 6882944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); 689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber setAACFormat(numChannels, sampleRate, bitRate); 692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_ALAW, mMIME) 693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber || !strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_MLAW, mMIME)) { 694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // These are PCM-like formats with a fixed sample rate but 695729de186450f78c099637e1fce743fe531862c52Andreas Huber // a variable number of channels. 696729de186450f78c099637e1fce743fe531862c52Andreas Huber 697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t numChannels; 698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); 699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber setG711Format(numChannels); 701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strncasecmp(mMIME, "video/", 6)) { 704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mIsEncoder) { 706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber setVideoInputFormat(mMIME, meta); 707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t width, height; 709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool success = meta->findInt32(kKeyWidth, &width); 710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber success = success && meta->findInt32(kKeyHeight, &height); 711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(success); 712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err = setVideoOutputFormat( 713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mMIME, width, height); 714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strcasecmp(mMIME, MEDIA_MIMETYPE_IMAGE_JPEG) 722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber && !strcmp(mComponentName, "OMX.TI.JPEG.decode")) { 723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_COLOR_FORMATTYPE format = 724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_COLOR_Format32bitARGB8888; 725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // OMX_COLOR_FormatYUV420PackedPlanar; 726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // OMX_COLOR_FormatCbYCrY; 727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // OMX_COLOR_FormatYUV411Planar; 728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t width, height; 730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool success = meta->findInt32(kKeyWidth, &width); 731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber success = success && meta->findInt32(kKeyHeight, &height); 732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t compressedSize; 734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber success = success && meta->findInt32( 735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber kKeyMaxInputSize, &compressedSize); 736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(success); 738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(compressedSize > 0); 739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber setImageOutputFormat(format, width, height); 741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber setJPEGInputFormat(width, height, (OMX_U32)compressedSize); 742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t maxInputSize; 745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) { 746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber setMinBufferSize(kPortIndexInput, (OMX_U32)maxInputSize); 747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strcmp(mComponentName, "OMX.TI.AMR.encode") 750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber || !strcmp(mComponentName, "OMX.TI.WBAMR.encode") 751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber || !strcmp(mComponentName, "OMX.TI.AAC.encode")) { 752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber setMinBufferSize(kPortIndexOutput, 8192); // XXX 753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber initOutputFormat(meta); 756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if ((mFlags & kClientNeedsFramebuffer) 758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber && !strncmp(mComponentName, "OMX.SEC.", 8)) { 759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_INDEXTYPE index; 760729de186450f78c099637e1fce743fe531862c52Andreas Huber 761729de186450f78c099637e1fce743fe531862c52Andreas Huber status_t err = 762729de186450f78c099637e1fce743fe531862c52Andreas Huber mOMX->getExtensionIndex( 763729de186450f78c099637e1fce743fe531862c52Andreas Huber mNode, 764729de186450f78c099637e1fce743fe531862c52Andreas Huber "OMX.SEC.index.ThumbnailMode", 765729de186450f78c099637e1fce743fe531862c52Andreas Huber &index); 766729de186450f78c099637e1fce743fe531862c52Andreas Huber 767729de186450f78c099637e1fce743fe531862c52Andreas Huber if (err != OK) { 768729de186450f78c099637e1fce743fe531862c52Andreas Huber return err; 769729de186450f78c099637e1fce743fe531862c52Andreas Huber } 770729de186450f78c099637e1fce743fe531862c52Andreas Huber 771729de186450f78c099637e1fce743fe531862c52Andreas Huber OMX_BOOL enable = OMX_TRUE; 772729de186450f78c099637e1fce743fe531862c52Andreas Huber err = mOMX->setConfig(mNode, index, &enable, sizeof(enable)); 773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CODEC_LOGE("setConfig('OMX.SEC.index.ThumbnailMode') " 776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber "returned error 0x%08x", err); 777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mQuirks &= ~kOutputBuffersAreUnreadable; 782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mNativeWindow != NULL 785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber && !mIsEncoder 786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber && !strncasecmp(mMIME, "video/", 6) 787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber && !strncmp(mComponentName, "OMX.", 4)) { 788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err = initNativeWindow(); 789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 797f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) { 798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_PARAM_PORTDEFINITIONTYPE def; 799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber InitOMXParams(&def); 800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber def.nPortIndex = portIndex; 801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err = mOMX->getParameter( 803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(err, (status_t)OK); 805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if ((portIndex == kPortIndexInput && (mQuirks & kInputBufferSizesAreBogus)) 807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber || (def.nBufferSize < size)) { 808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber def.nBufferSize = size; 809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = mOMX->setParameter( 812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(err, (status_t)OK); 814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = mOMX->getParameter( 816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(err, (status_t)OK); 818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Make sure the setting actually stuck. 820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (portIndex == kPortIndexInput 821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber && (mQuirks & kInputBufferSizesAreBogus)) { 822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(def.nBufferSize, size); 823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(def.nBufferSize >= size); 825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 828f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t OMXCodec::setVideoPortFormatType( 829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_U32 portIndex, 830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_VIDEO_CODINGTYPE compressionFormat, 831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_COLOR_FORMATTYPE colorFormat) { 832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_VIDEO_PARAM_PORTFORMATTYPE format; 833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber InitOMXParams(&format); 834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber format.nPortIndex = portIndex; 835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber format.nIndex = 0; 836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool found = false; 837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_U32 index = 0; 839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (;;) { 840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber format.nIndex = index; 841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err = mOMX->getParameter( 842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, OMX_IndexParamVideoPortFormat, 843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber &format, sizeof(format)); 844729de186450f78c099637e1fce743fe531862c52Andreas Huber 845729de186450f78c099637e1fce743fe531862c52Andreas Huber if (err != OK) { 846729de186450f78c099637e1fce743fe531862c52Andreas Huber return err; 847729de186450f78c099637e1fce743fe531862c52Andreas Huber } 848729de186450f78c099637e1fce743fe531862c52Andreas Huber 849729de186450f78c099637e1fce743fe531862c52Andreas Huber // The following assertion is violated by TI's video decoder. 850729de186450f78c099637e1fce743fe531862c52Andreas Huber // CHECK_EQ(format.nIndex, index); 851729de186450f78c099637e1fce743fe531862c52Andreas Huber 852729de186450f78c099637e1fce743fe531862c52Andreas Huber#if 1 853729de186450f78c099637e1fce743fe531862c52Andreas Huber CODEC_LOGV("portIndex: %ld, index: %ld, eCompressionFormat=%d eColorFormat=%d", 854729de186450f78c099637e1fce743fe531862c52Andreas Huber portIndex, 855729de186450f78c099637e1fce743fe531862c52Andreas Huber index, format.eCompressionFormat, format.eColorFormat); 856729de186450f78c099637e1fce743fe531862c52Andreas Huber#endif 857729de186450f78c099637e1fce743fe531862c52Andreas Huber 858729de186450f78c099637e1fce743fe531862c52Andreas Huber if (!strcmp("OMX.TI.Video.encoder", mComponentName)) { 859729de186450f78c099637e1fce743fe531862c52Andreas Huber if (portIndex == kPortIndexInput 860729de186450f78c099637e1fce743fe531862c52Andreas Huber && colorFormat == format.eColorFormat) { 861729de186450f78c099637e1fce743fe531862c52Andreas Huber // eCompressionFormat does not seem right. 862729de186450f78c099637e1fce743fe531862c52Andreas Huber found = true; 863729de186450f78c099637e1fce743fe531862c52Andreas Huber break; 864729de186450f78c099637e1fce743fe531862c52Andreas Huber } 865729de186450f78c099637e1fce743fe531862c52Andreas Huber if (portIndex == kPortIndexOutput 866729de186450f78c099637e1fce743fe531862c52Andreas Huber && compressionFormat == format.eCompressionFormat) { 867729de186450f78c099637e1fce743fe531862c52Andreas Huber // eColorFormat does not seem right. 868729de186450f78c099637e1fce743fe531862c52Andreas Huber found = true; 869729de186450f78c099637e1fce743fe531862c52Andreas Huber break; 870729de186450f78c099637e1fce743fe531862c52Andreas Huber } 871729de186450f78c099637e1fce743fe531862c52Andreas Huber } 872729de186450f78c099637e1fce743fe531862c52Andreas Huber 873729de186450f78c099637e1fce743fe531862c52Andreas Huber if (format.eCompressionFormat == compressionFormat 874729de186450f78c099637e1fce743fe531862c52Andreas Huber && format.eColorFormat == colorFormat) { 875729de186450f78c099637e1fce743fe531862c52Andreas Huber found = true; 876729de186450f78c099637e1fce743fe531862c52Andreas Huber break; 877729de186450f78c099637e1fce743fe531862c52Andreas Huber } 878729de186450f78c099637e1fce743fe531862c52Andreas Huber 879729de186450f78c099637e1fce743fe531862c52Andreas Huber ++index; 880729de186450f78c099637e1fce743fe531862c52Andreas Huber } 881729de186450f78c099637e1fce743fe531862c52Andreas Huber 882729de186450f78c099637e1fce743fe531862c52Andreas Huber if (!found) { 883729de186450f78c099637e1fce743fe531862c52Andreas Huber return UNKNOWN_ERROR; 884729de186450f78c099637e1fce743fe531862c52Andreas Huber } 885729de186450f78c099637e1fce743fe531862c52Andreas Huber 886729de186450f78c099637e1fce743fe531862c52Andreas Huber CODEC_LOGV("found a match."); 887729de186450f78c099637e1fce743fe531862c52Andreas Huber status_t err = mOMX->setParameter( 888729de186450f78c099637e1fce743fe531862c52Andreas Huber mNode, OMX_IndexParamVideoPortFormat, 889729de186450f78c099637e1fce743fe531862c52Andreas Huber &format, sizeof(format)); 890729de186450f78c099637e1fce743fe531862c52Andreas Huber 891729de186450f78c099637e1fce743fe531862c52Andreas Huber return err; 892729de186450f78c099637e1fce743fe531862c52Andreas Huber} 893729de186450f78c099637e1fce743fe531862c52Andreas Huber 894729de186450f78c099637e1fce743fe531862c52Andreas Huberstatic size_t getFrameSize( 895729de186450f78c099637e1fce743fe531862c52Andreas Huber OMX_COLOR_FORMATTYPE colorFormat, int32_t width, int32_t height) { 896729de186450f78c099637e1fce743fe531862c52Andreas Huber switch (colorFormat) { 897729de186450f78c099637e1fce743fe531862c52Andreas Huber case OMX_COLOR_FormatYCbYCr: 898729de186450f78c099637e1fce743fe531862c52Andreas Huber case OMX_COLOR_FormatCbYCrY: 899729de186450f78c099637e1fce743fe531862c52Andreas Huber return width * height * 2; 900729de186450f78c099637e1fce743fe531862c52Andreas Huber 901729de186450f78c099637e1fce743fe531862c52Andreas Huber case OMX_COLOR_FormatYUV420Planar: 902729de186450f78c099637e1fce743fe531862c52Andreas Huber case OMX_COLOR_FormatYUV420SemiPlanar: 903729de186450f78c099637e1fce743fe531862c52Andreas Huber case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar: 904729de186450f78c099637e1fce743fe531862c52Andreas Huber return (width * height * 3) / 2; 905729de186450f78c099637e1fce743fe531862c52Andreas Huber 906729de186450f78c099637e1fce743fe531862c52Andreas Huber default: 907729de186450f78c099637e1fce743fe531862c52Andreas Huber CHECK(!"Should not be here. Unsupported color format."); 908729de186450f78c099637e1fce743fe531862c52Andreas Huber break; 909729de186450f78c099637e1fce743fe531862c52Andreas Huber } 910729de186450f78c099637e1fce743fe531862c52Andreas Huber} 911729de186450f78c099637e1fce743fe531862c52Andreas Huber 912729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t OMXCodec::findTargetColorFormat( 913729de186450f78c099637e1fce743fe531862c52Andreas Huber const sp<MetaData>& meta, OMX_COLOR_FORMATTYPE *colorFormat) { 914729de186450f78c099637e1fce743fe531862c52Andreas Huber LOGV("findTargetColorFormat"); 915729de186450f78c099637e1fce743fe531862c52Andreas Huber CHECK(mIsEncoder); 916729de186450f78c099637e1fce743fe531862c52Andreas Huber 917729de186450f78c099637e1fce743fe531862c52Andreas Huber *colorFormat = OMX_COLOR_FormatYUV420SemiPlanar; 918729de186450f78c099637e1fce743fe531862c52Andreas Huber int32_t targetColorFormat; 919729de186450f78c099637e1fce743fe531862c52Andreas Huber if (meta->findInt32(kKeyColorFormat, &targetColorFormat)) { 920729de186450f78c099637e1fce743fe531862c52Andreas Huber *colorFormat = (OMX_COLOR_FORMATTYPE) targetColorFormat; 921729de186450f78c099637e1fce743fe531862c52Andreas Huber } else { 922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strcasecmp("OMX.TI.Video.encoder", mComponentName)) { 923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber *colorFormat = OMX_COLOR_FormatYCbYCr; 924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Check whether the target color format is supported. 929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return isColorFormatSupported(*colorFormat, kPortIndexInput); 930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 932f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t OMXCodec::isColorFormatSupported( 933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_COLOR_FORMATTYPE colorFormat, int portIndex) { 934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGV("isColorFormatSupported: %d", static_cast<int>(colorFormat)); 935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Enumerate all the color formats supported by 937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // the omx component to see whether the given 938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // color format is supported. 939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat; 940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber InitOMXParams(&portFormat); 941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber portFormat.nPortIndex = portIndex; 942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_U32 index = 0; 943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber portFormat.nIndex = index; 944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber while (true) { 945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (OMX_ErrorNone != mOMX->getParameter( 946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, OMX_IndexParamVideoPortFormat, 947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber &portFormat, sizeof(portFormat))) { 948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Make sure that omx component does not overwrite 951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // the incremented index (bug 2897413). 952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(index, portFormat.nIndex); 953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if ((portFormat.eColorFormat == colorFormat)) { 954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGV("Found supported color format: %d", portFormat.eColorFormat); 955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; // colorFormat is supported! 956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ++index; 958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber portFormat.nIndex = index; 959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // OMX Spec defines less than 50 color formats 961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // 1000 is more than enough for us to tell whether the omx 962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // component in question is buggy or not. 963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (index >= 1000) { 964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGE("More than %ld color formats are supported???", index); 965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGE("color format %d is not supported", colorFormat); 970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return UNKNOWN_ERROR; 971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 973f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid OMXCodec::setVideoInputFormat( 974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *mime, const sp<MetaData>& meta) { 975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t width, height, frameRate, bitRate, stride, sliceHeight; 977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool success = meta->findInt32(kKeyWidth, &width); 978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber success = success && meta->findInt32(kKeyHeight, &height); 979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber success = success && meta->findInt32(kKeyFrameRate, &frameRate); 980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber success = success && meta->findInt32(kKeyBitRate, &bitRate); 981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber success = success && meta->findInt32(kKeyStride, &stride); 982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber success = success && meta->findInt32(kKeySliceHeight, &sliceHeight); 983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(success); 984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(stride != 0); 985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused; 987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber compressionFormat = OMX_VIDEO_CodingAVC; 989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { 990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber compressionFormat = OMX_VIDEO_CodingMPEG4; 991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { 992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber compressionFormat = OMX_VIDEO_CodingH263; 993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGE("Not a supported video mime type: %s", mime); 995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(!"Should not be here. Not a supported video mime type."); 9961065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber } 997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_COLOR_FORMATTYPE colorFormat; 999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ((status_t)OK, findTargetColorFormat(meta, &colorFormat)); 1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err; 1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_PARAM_PORTDEFINITIONTYPE def; 1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber //////////////////////// Input port ///////////////////////// 1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(setVideoPortFormatType( 1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber kPortIndexInput, OMX_VIDEO_CodingUnused, 1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber colorFormat), (status_t)OK); 1009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber InitOMXParams(&def); 1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber def.nPortIndex = kPortIndexInput; 1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1013386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber err = mOMX->getParameter( 1014386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(err, (status_t)OK); 1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber def.nBufferSize = getFrameSize(colorFormat, 1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber stride > 0? stride: -stride, sliceHeight); 1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); 1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber video_def->nFrameWidth = width; 1023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber video_def->nFrameHeight = height; 1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber video_def->nStride = stride; 1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber video_def->nSliceHeight = sliceHeight; 1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber video_def->xFramerate = (frameRate << 16); // Q16 format 1027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber video_def->eCompressionFormat = OMX_VIDEO_CodingUnused; 1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber video_def->eColorFormat = colorFormat; 1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = mOMX->setParameter( 1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(err, (status_t)OK); 1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber //////////////////////// Output port ///////////////////////// 1035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(setVideoPortFormatType( 1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused), 1037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber (status_t)OK); 1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber InitOMXParams(&def); 1039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber def.nPortIndex = kPortIndexOutput; 1040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = mOMX->getParameter( 1042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(err, (status_t)OK); 1045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); 1046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber video_def->nFrameWidth = width; 1048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber video_def->nFrameHeight = height; 1049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber video_def->xFramerate = 0; // No need for output port 1050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // FIXME: 1051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Revmoe this workaround after work is done. 1052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strncmp(mComponentName, "OMX.TI.DUCATI1", 14)) { 1053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber video_def->xFramerate = (frameRate << 16); 1054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber video_def->nBitrate = bitRate; // Q16 format 1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber video_def->eCompressionFormat = compressionFormat; 1057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber video_def->eColorFormat = OMX_COLOR_FormatUnused; 1058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mQuirks & kRequiresLargerEncoderOutputBuffer) { 1059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Increases the output buffer size 1060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber def.nBufferSize = ((def.nBufferSize * 3) >> 1); 1061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = mOMX->setParameter( 1064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(err, (status_t)OK); 1066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber /////////////////// Codec-specific //////////////////////// 1068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (compressionFormat) { 1069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case OMX_VIDEO_CodingMPEG4: 1070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 1071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(setupMPEG4EncoderParameters(meta), (status_t)OK); 1072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 1073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case OMX_VIDEO_CodingH263: 1076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(setupH263EncoderParameters(meta), (status_t)OK); 1077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 1078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case OMX_VIDEO_CodingAVC: 1080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 1081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(setupAVCEncoderParameters(meta), (status_t)OK); 1082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 1083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 1086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(!"Support for this compressionFormat to be implemented."); 1087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 1088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1091f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) { 1092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (iFramesInterval < 0) { 1093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return 0xFFFFFFFF; 1094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (iFramesInterval == 0) { 1095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return 0; 1096d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber } 1097d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber OMX_U32 ret = frameRate * iFramesInterval; 1098d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber CHECK(ret > 1); 1099d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber return ret; 1100d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber} 1101d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber 1102d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huberstatus_t OMXCodec::setupErrorCorrectionParameters() { 1103d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType; 1104d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber InitOMXParams(&errorCorrectionType); 1105d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber errorCorrectionType.nPortIndex = kPortIndexOutput; 1106d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber 1107d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber status_t err = mOMX->getParameter( 1108d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber mNode, OMX_IndexParamVideoErrorCorrection, 1109d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber &errorCorrectionType, sizeof(errorCorrectionType)); 1110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 1111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGW("Error correction param query is not supported"); 1112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; // Optional feature. Ignore this failure 1113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber errorCorrectionType.bEnableHEC = OMX_FALSE; 1116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber errorCorrectionType.bEnableResync = OMX_TRUE; 11173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block errorCorrectionType.nResynchMarkerSpacing = 256; 1118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber errorCorrectionType.bEnableDataPartitioning = OMX_FALSE; 1119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber errorCorrectionType.bEnableRVLC = OMX_FALSE; 1120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = mOMX->setParameter( 1122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, OMX_IndexParamVideoErrorCorrection, 1123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber &errorCorrectionType, sizeof(errorCorrectionType)); 1124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 1125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGW("Error correction param configuration is not supported"); 1126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Optional feature. Ignore the failure. 1129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 1130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1132f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t OMXCodec::setupBitRate(int32_t bitRate) { 1133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_VIDEO_PARAM_BITRATETYPE bitrateType; 1134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber InitOMXParams(&bitrateType); 1135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bitrateType.nPortIndex = kPortIndexOutput; 1136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err = mOMX->getParameter( 1138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, OMX_IndexParamVideoBitrate, 1139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber &bitrateType, sizeof(bitrateType)); 1140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(err, (status_t)OK); 1141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bitrateType.eControlRate = OMX_Video_ControlRateVariable; 1143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bitrateType.nTargetBitrate = bitRate; 1144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = mOMX->setParameter( 1146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, OMX_IndexParamVideoBitrate, 114731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber &bitrateType, sizeof(bitrateType)); 114831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber CHECK_EQ(err, (status_t)OK); 114931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber return OK; 115031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber} 115131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 115231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huberstatus_t OMXCodec::getVideoProfileLevel( 115331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber const sp<MetaData>& meta, 115431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber const CodecProfileLevel& defaultProfileLevel, 115531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber CodecProfileLevel &profileLevel) { 115631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber CODEC_LOGV("Default profile: %ld, level %ld", 115731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber defaultProfileLevel.mProfile, defaultProfileLevel.mLevel); 115831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 115931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber // Are the default profile and level overwriten? 116031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber int32_t profile, level; 116131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber if (!meta->findInt32(kKeyVideoProfile, &profile)) { 116231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber profile = defaultProfileLevel.mProfile; 116331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber } 116431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber if (!meta->findInt32(kKeyVideoLevel, &level)) { 116531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber level = defaultProfileLevel.mLevel; 116631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber } 116731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber CODEC_LOGV("Target profile: %d, level: %d", profile, level); 116831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 116931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber // Are the target profile and level supported by the encoder? 117031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber OMX_VIDEO_PARAM_PROFILELEVELTYPE param; 117131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber InitOMXParams(¶m); 117231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber param.nPortIndex = kPortIndexOutput; 117331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber for (param.nProfileIndex = 0;; ++param.nProfileIndex) { 117431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber status_t err = mOMX->getParameter( 117531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber mNode, OMX_IndexParamVideoProfileLevelQuerySupported, 117631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber ¶m, sizeof(param)); 117731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 117831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber if (err != OK) break; 117931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 118031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber int32_t supportedProfile = static_cast<int32_t>(param.eProfile); 118131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber int32_t supportedLevel = static_cast<int32_t>(param.eLevel); 118231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber CODEC_LOGV("Supported profile: %d, level %d", 118331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber supportedProfile, supportedLevel); 118431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 118531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber if (profile == supportedProfile && 118631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber level <= supportedLevel) { 118731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber // We can further check whether the level is a valid 118831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber // value; but we will leave that to the omx encoder component 118931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber // via OMX_SetParameter call. 119031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber profileLevel.mProfile = profile; 119131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber profileLevel.mLevel = level; 119231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber return OK; 119331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber } 119431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber } 119531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 119631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber CODEC_LOGE("Target profile (%d) and level (%d) is not supported", 119731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber profile, level); 119831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber return BAD_VALUE; 119931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber} 120031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 120189c120e7adbe09c6283591789594c5e591aa5032Andreas Huberstatus_t OMXCodec::setupH263EncoderParameters(const sp<MetaData>& meta) { 120289c120e7adbe09c6283591789594c5e591aa5032Andreas Huber int32_t iFramesInterval, frameRate, bitRate; 120331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber bool success = meta->findInt32(kKeyBitRate, &bitRate); 120431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber success = success && meta->findInt32(kKeyFrameRate, &frameRate); 120531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval); 120631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber CHECK(success); 120731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber OMX_VIDEO_PARAM_H263TYPE h263type; 120831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber InitOMXParams(&h263type); 120931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber h263type.nPortIndex = kPortIndexOutput; 121031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 121131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber status_t err = mOMX->getParameter( 121231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); 121331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber CHECK_EQ(err, (status_t)OK); 121431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 121531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber h263type.nAllowedPictureTypes = 121631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 121731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 121831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber h263type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate); 121931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber if (h263type.nPFrames == 0) { 122031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 122131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber } 122231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber h263type.nBFrames = 0; 122331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 122431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber // Check profile and level parameters 122531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber CodecProfileLevel defaultProfileLevel, profileLevel; 122631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber defaultProfileLevel.mProfile = h263type.eProfile; 122731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber defaultProfileLevel.mLevel = h263type.eLevel; 122831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel); 122931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber if (err != OK) return err; 123031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profileLevel.mProfile); 123131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(profileLevel.mLevel); 123231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 123331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber h263type.bPLUSPTYPEAllowed = OMX_FALSE; 123431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber h263type.bForceRoundingTypeToZero = OMX_FALSE; 123531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber h263type.nPictureHeaderRepetition = 0; 123631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber h263type.nGOBHeaderInterval = 0; 123731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 123831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber err = mOMX->setParameter( 123931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); 124031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber CHECK_EQ(err, (status_t)OK); 124131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 124231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber CHECK_EQ(setupBitRate(bitRate), (status_t)OK); 124331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber CHECK_EQ(setupErrorCorrectionParameters(), (status_t)OK); 1244cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber 1245cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber return OK; 1246cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber} 1247cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber 1248cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huberstatus_t OMXCodec::setupMPEG4EncoderParameters(const sp<MetaData>& meta) { 1249cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber int32_t iFramesInterval, frameRate, bitRate; 1250cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber bool success = meta->findInt32(kKeyBitRate, &bitRate); 1251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber success = success && meta->findInt32(kKeyFrameRate, &frameRate); 1252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval); 1253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(success); 1254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type; 1255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber InitOMXParams(&mpeg4type); 1256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mpeg4type.nPortIndex = kPortIndexOutput; 1257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err = mOMX->getParameter( 1259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 1260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(err, (status_t)OK); 1261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mpeg4type.nSliceHeaderSpacing = 0; 1263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mpeg4type.bSVH = OMX_FALSE; 1264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mpeg4type.bGov = OMX_FALSE; 1265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mpeg4type.nAllowedPictureTypes = 1267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 1268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mpeg4type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate); 1270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mpeg4type.nPFrames == 0) { 1271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 1272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mpeg4type.nBFrames = 0; 1274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mpeg4type.nIDCVLCThreshold = 0; 1275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mpeg4type.bACPred = OMX_TRUE; 1276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mpeg4type.nMaxPacketSize = 256; 1277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mpeg4type.nTimeIncRes = 1000; 1278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mpeg4type.nHeaderExtension = 0; 1279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mpeg4type.bReversibleVLC = OMX_FALSE; 1280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Check profile and level parameters 1282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CodecProfileLevel defaultProfileLevel, profileLevel; 1283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber defaultProfileLevel.mProfile = mpeg4type.eProfile; 1284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber defaultProfileLevel.mLevel = mpeg4type.eLevel; 1285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel); 1286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) return err; 1287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profileLevel.mProfile); 1288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(profileLevel.mLevel); 1289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = mOMX->setParameter( 1291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 1292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(err, (status_t)OK); 1293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(setupBitRate(bitRate), (status_t)OK); 1295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(setupErrorCorrectionParameters(), (status_t)OK); 1296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 1298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1300f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t OMXCodec::setupAVCEncoderParameters(const sp<MetaData>& meta) { 1301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t iFramesInterval, frameRate, bitRate; 1302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool success = meta->findInt32(kKeyBitRate, &bitRate); 1303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber success = success && meta->findInt32(kKeyFrameRate, &frameRate); 13040af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval); 13050af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber CHECK(success); 13060af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber 13070af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber OMX_VIDEO_PARAM_AVCTYPE h264type; 13080af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber InitOMXParams(&h264type); 13090af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber h264type.nPortIndex = kPortIndexOutput; 13100af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber 13110af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber status_t err = mOMX->getParameter( 13120af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 13130af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber CHECK_EQ(err, (status_t)OK); 13140af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber 1315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.nAllowedPictureTypes = 1316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 1317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Check profile and level parameters 1319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CodecProfileLevel defaultProfileLevel, profileLevel; 1320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber defaultProfileLevel.mProfile = h264type.eProfile; 1321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber defaultProfileLevel.mLevel = h264type.eLevel; 1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel); 1323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) return err; 1324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profileLevel.mProfile); 1325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(profileLevel.mLevel); 1326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // FIXME: 1328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Remove the workaround after the work in done. 1329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strncmp(mComponentName, "OMX.TI.DUCATI1", 14)) { 1330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.eProfile = OMX_VIDEO_AVCProfileBaseline; 1331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) { 1334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.nSliceHeaderSpacing = 0; 1335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.bUseHadamard = OMX_TRUE; 1336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.nRefFrames = 1; 1337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.nBFrames = 0; 1338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate); 1339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (h264type.nPFrames == 0) { 1340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 1341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.nRefIdx10ActiveMinus1 = 0; 1343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.nRefIdx11ActiveMinus1 = 0; 1344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.bEntropyCodingCABAC = OMX_FALSE; 1345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.bWeightedPPrediction = OMX_FALSE; 1346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.bconstIpred = OMX_FALSE; 1347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.bDirect8x8Inference = OMX_FALSE; 1348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.bDirectSpatialTemporal = OMX_FALSE; 1349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.nCabacInitIdc = 0; 1350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (h264type.nBFrames != 0) { 1353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB; 1354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.bEnableUEP = OMX_FALSE; 1357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.bEnableFMO = OMX_FALSE; 1358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.bEnableASO = OMX_FALSE; 1359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.bEnableRS = OMX_FALSE; 1360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.bFrameMBsOnly = OMX_TRUE; 1361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.bMBAFF = OMX_FALSE; 1362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable; 1363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 13643856b090cd04ba5dd4a59a12430ed724d5995909Steve Block if (!strcasecmp("OMX.Nvidia.h264.encoder", mComponentName)) { 1365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber h264type.eLevel = OMX_VIDEO_AVCLevelMax; 1366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = mOMX->setParameter( 1369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 1370c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber CHECK_EQ(err, (status_t)OK); 1371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1372cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber CHECK_EQ(setupBitRate(bitRate), (status_t)OK); 1373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 1375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1377f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t OMXCodec::setVideoOutputFormat( 13783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block const char *mime, OMX_U32 width, OMX_U32 height) { 1379349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber CODEC_LOGV("setVideoOutputFormat width=%ld, height=%ld", width, height); 1380349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 1381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused; 1382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 1383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber compressionFormat = OMX_VIDEO_CodingAVC; 1384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { 1385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber compressionFormat = OMX_VIDEO_CodingMPEG4; 1386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { 1387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber compressionFormat = OMX_VIDEO_CodingH263; 1388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VPX, mime)) { 1389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber compressionFormat = OMX_VIDEO_CodingVPX; 1390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG2, mime)) { 1391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber compressionFormat = OMX_VIDEO_CodingMPEG2; 1392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 1393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGE("Not a supported video mime type: %s", mime); 1394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(!"Should not be here. Not a supported video mime type."); 1395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err = setVideoPortFormatType( 1398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused); 1399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 1401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 1402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 1 1405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 1406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_VIDEO_PARAM_PORTFORMATTYPE format; 1407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber InitOMXParams(&format); 1408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber format.nPortIndex = kPortIndexOutput; 1409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber format.nIndex = 0; 1410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err = mOMX->getParameter( 1412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, OMX_IndexParamVideoPortFormat, 1413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber &format, sizeof(format)); 1414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(err, (status_t)OK); 1415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused); 1416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar 1418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar 1419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber || format.eColorFormat == OMX_COLOR_FormatCbYCrY 1420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar 1421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar); 1422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = mOMX->setParameter( 1424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, OMX_IndexParamVideoPortFormat, 1425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber &format, sizeof(format)); 1426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 1428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 1429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif 1432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_PARAM_PORTDEFINITIONTYPE def; 1434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber InitOMXParams(&def); 1435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber def.nPortIndex = kPortIndexInput; 1436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 1438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = mOMX->getParameter( 1440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 14413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block 14423831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber CHECK_EQ(err, (status_t)OK); 14433831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 1444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 1 1445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // XXX Need a (much) better heuristic to compute input buffer sizes. 1446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const size_t X = 64 * 1024; 1447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (def.nBufferSize < X) { 1448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber def.nBufferSize = X; 1449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif 1451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); 1453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber video_def->nFrameWidth = width; 1455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber video_def->nFrameHeight = height; 1456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber video_def->eCompressionFormat = compressionFormat; 1458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber video_def->eColorFormat = OMX_COLOR_FormatUnused; 1459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1460dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber err = mOMX->setParameter( 1461dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1462dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber 1463dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber if (err != OK) { 1464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 1465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber //////////////////////////////////////////////////////////////////////////// 1468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber InitOMXParams(&def); 1470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber def.nPortIndex = kPortIndexOutput; 1471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = mOMX->getParameter( 1473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(err, (status_t)OK); 1475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); 1476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0 1478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber def.nBufferSize = 1479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2; // YUV420 1480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif 1481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber video_def->nFrameWidth = width; 1483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber video_def->nFrameHeight = height; 1484349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 14853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block err = mOMX->setParameter( 1486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 1489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1491f933441648ef6a71dee783d733aac17b9508b452Andreas HuberOMXCodec::OMXCodec( 1492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const sp<IOMX> &omx, IOMX::node_id node, 1493078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber uint32_t quirks, uint32_t flags, 14943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block bool isEncoder, 1495078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber const char *mime, 1496078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber const char *componentName, 14973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block const sp<MediaSource> &source, 1498078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber const sp<ANativeWindow> &nativeWindow) 1499078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber : mOMX(omx), 1500349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber mOMXLivesLocally(omx->livesLocally(getpid())), 1501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode(node), 1502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mQuirks(quirks), 1503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFlags(flags), 1504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mIsEncoder(isEncoder), 1505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mMIME(strdup(mime)), 1506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mComponentName(strdup(componentName)), 1507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSource(source), 1508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodecSpecificDataIndex(0), 1509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mState(LOADED), 1510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mInitialBufferSubmit(true), 1511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSignalledEOS(false), 1512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNoMoreOutputData(false), 1513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mOutputPortSettingsHaveChanged(false), 1514dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber mSeekTimeUs(-1), 15153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block mSeekMode(ReadOptions::SEEK_CLOSEST_SYNC), 1516dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber mTargetTimeUs(-1), 1517dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber mOutputPortSettingsChangedPending(false), 1518dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber mLeftOverBuffer(NULL), 15193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block mPaused(false), 1520dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber mNativeWindow(!strncmp(componentName, "OMX.google.", 11) 1521dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber ? NULL : nativeWindow) { 1522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mPortStatus[kPortIndexInput] = ENABLED; 15233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block mPortStatus[kPortIndexOutput] = ENABLED; 1524349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 1525349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber setComponentRole(); 1526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// static 1529f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid OMXCodec::setComponentRole( 1530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder, 1531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *mime) { 1532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber struct MimeToRole { 1533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *mime; 1534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *decoderRole; 1535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *encoderRole; 1536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber }; 1537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1538dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber static const MimeToRole kMimeToRole[] = { 1539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_AUDIO_MPEG, 1540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber "audio_decoder.mp3", "audio_encoder.mp3" }, 1541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_AUDIO_AMR_NB, 1542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber "audio_decoder.amrnb", "audio_encoder.amrnb" }, 1543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_AUDIO_AMR_WB, 1544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber "audio_decoder.amrwb", "audio_encoder.amrwb" }, 1545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_AUDIO_AAC, 1546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber "audio_decoder.aac", "audio_encoder.aac" }, 1547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_AVC, 1548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber "video_decoder.avc", "video_encoder.avc" }, 1549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_MPEG4, 1550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber "video_decoder.mpeg4", "video_encoder.mpeg4" }, 1551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { MEDIA_MIMETYPE_VIDEO_H263, 1552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber "video_decoder.h263", "video_encoder.h263" }, 1553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber }; 1554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber static const size_t kNumMimeToRole = 1556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sizeof(kMimeToRole) / sizeof(kMimeToRole[0]); 1557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t i; 1559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (i = 0; i < kNumMimeToRole; ++i) { 1560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strcasecmp(mime, kMimeToRole[i].mime)) { 1561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 1562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (i == kNumMimeToRole) { 1566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 1567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *role = 1570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber isEncoder ? kMimeToRole[i].encoderRole 1571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber : kMimeToRole[i].decoderRole; 1572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (role != NULL) { 1574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_PARAM_COMPONENTROLETYPE roleParams; 1575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber InitOMXParams(&roleParams); 1576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber strncpy((char *)roleParams.cRole, 1578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber role, OMX_MAX_STRINGNAME_SIZE - 1); 1579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0'; 1581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err = omx->setParameter( 1583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber node, OMX_IndexParamStandardComponentRole, 1584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber &roleParams, sizeof(roleParams)); 15853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block 1586078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber if (err != OK) { 1587349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber LOGW("Failed to set standard component role '%s'.", role); 1588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1592f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid OMXCodec::setComponentRole() { 1593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber setComponentRole(mOMX, mNode, mIsEncoder, mMIME); 1594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1596f933441648ef6a71dee783d733aac17b9508b452Andreas HuberOMXCodec::~OMXCodec() { 1597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSource.clear(); 1598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mState == LOADED || mState == ERROR || mState == LOADED_TO_IDLE); 1600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err = mOMX->freeNode(mNode); 1602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(err, (status_t)OK); 1603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode = NULL; 1605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber setState(DEAD); 16063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block 1607349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber clearCodecSpecificData(); 1608349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 1609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber free(mComponentName); 1610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mComponentName = NULL; 1611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber free(mMIME); 1613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mMIME = NULL; 1614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 161631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huberstatus_t OMXCodec::init() { 161731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber // mLock is held. 161831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 161931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber CHECK_EQ((int)mState, (int)LOADED); 1620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err; 1622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) { 1623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 1624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(err, (status_t)OK); 1625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber setState(LOADED_TO_IDLE); 1626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = allocateBuffers(); 1629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != (status_t)OK) { 1630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 1631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mQuirks & kRequiresLoadedToIdleAfterAllocation) { 1634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 1635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(err, (status_t)OK); 1636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber setState(LOADED_TO_IDLE); 1638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber while (mState != EXECUTING && mState != ERROR) { 1641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAsyncCompletion.wait(mLock); 1642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return mState == ERROR ? UNKNOWN_ERROR : OK; 1645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1646dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber 1647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// static 1648f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool OMXCodec::isIntermediateState(State state) { 1649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return state == LOADED_TO_IDLE 1650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber || state == IDLE_TO_EXECUTING 1651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber || state == EXECUTING_TO_IDLE 1652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber || state == IDLE_TO_LOADED 1653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber || state == RECONFIGURING; 1654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1656f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t OMXCodec::allocateBuffers() { 1657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err = allocateBuffersOnPort(kPortIndexInput); 1658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 1660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 1661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return allocateBuffersOnPort(kPortIndexOutput); 1664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1666f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) { 1667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mNativeWindow != NULL && portIndex == kPortIndexOutput) { 1668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return allocateOutputBuffersFromNativeWindow(); 1669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if ((mFlags & kEnableGrallocUsageProtected) && portIndex == kPortIndexOutput) { 1672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGE("protected output buffers must be stent to an ANativeWindow"); 1673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return PERMISSION_DENIED; 1674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err = OK; 1677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if ((mFlags & kStoreMetaDataInVideoBuffers) 1678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber && portIndex == kPortIndexInput) { 1679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE); 1680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 1681cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber LOGE("Storing meta data in video buffers is not supported"); 1682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 1683cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber } 1684cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber } 1685cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber 1686cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber OMX_PARAM_PORTDEFINITIONTYPE def; 1687cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber InitOMXParams(&def); 1688cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber def.nPortIndex = portIndex; 1689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = mOMX->getParameter( 1691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 1694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 1695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CODEC_LOGI("allocating %lu buffers of size %lu on %s port", 1698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber def.nBufferCountActual, def.nBufferSize, 1699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber portIndex == kPortIndexInput ? "input" : "output"); 1700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t totalSize = def.nBufferCountActual * def.nBufferSize; 1702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDealer[portIndex] = new MemoryDealer(totalSize, "OMXCodec"); 1703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) { 1705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize); 1706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mem.get() != NULL); 1707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber BufferInfo info; 1709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info.mData = NULL; 1710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info.mSize = def.nBufferSize; 1711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber IOMX::buffer_id buffer; 1713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (portIndex == kPortIndexInput 1714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber && ((mQuirks & kRequiresAllocateBufferOnInputPorts) 1715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber || (mFlags & kUseSecureInputBuffers))) { 1716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mOMXLivesLocally) { 1717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mem.clear(); 1718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1719c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber err = mOMX->allocateBuffer( 17203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block mNode, portIndex, def.nBufferSize, &buffer, 1721c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber &info.mData); 1722349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber } else { 1723c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber err = mOMX->allocateBufferWithBackup( 1724c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber mNode, portIndex, mem, &buffer); 1725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1726c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber } else if (portIndex == kPortIndexOutput 1727c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) { 1728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mOMXLivesLocally) { 1729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mem.clear(); 1730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = mOMX->allocateBuffer( 1732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, portIndex, def.nBufferSize, &buffer, 1733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber &info.mData); 1734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 1735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = mOMX->allocateBufferWithBackup( 1736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, portIndex, mem, &buffer); 1737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 1739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = mOMX->useBuffer(mNode, portIndex, mem, &buffer); 1740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 1743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGE("allocate_buffer_with_backup failed"); 1744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 1745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mem != NULL) { 1748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info.mData = mem->pointer(); 1749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info.mBuffer = buffer; 1752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info.mStatus = OWNED_BY_US; 1753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info.mMem = mem; 1754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info.mMediaBuffer = NULL; 1755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (portIndex == kPortIndexOutput) { 1757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!(mOMXLivesLocally 1758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber && (mQuirks & kRequiresAllocateBufferOnOutputPorts) 1759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber && (mQuirks & kDefersOutputBufferAllocation))) { 1760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // If the node does not fill in the buffer ptr at this time, 1761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // we will defer creating the MediaBuffer until receiving 1762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // the first FILL_BUFFER_DONE notification instead. 1763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info.mMediaBuffer = new MediaBuffer(info.mData, info.mSize); 1764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info.mMediaBuffer->setObserver(this); 1765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1768c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber mPortBuffers[portIndex].push(info); 1769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CODEC_LOGV("allocated buffer %p on %s port", buffer, 1771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber portIndex == kPortIndexInput ? "input" : "output"); 1772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // dumpPortStatus(portIndex); 1775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (portIndex == kPortIndexInput && (mFlags & kUseSecureInputBuffers)) { 1777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Vector<MediaBuffer *> buffers; 1778c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber for (size_t i = 0; i < def.nBufferCountActual; ++i) { 1779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const BufferInfo &info = mPortBuffers[kPortIndexInput].itemAt(i); 1780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber MediaBuffer *mbuf = new MediaBuffer(info.mData, info.mSize); 1782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffers.push(mbuf); 1783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err = mSource->setBuffers(buffers); 1786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 1788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (size_t i = 0; i < def.nBufferCountActual; ++i) { 1789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffers.editItemAt(i)->release(); 1790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffers.clear(); 1792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CODEC_LOGE( 1794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber "Codec requested to use secure input buffers but " 1795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber "upstream source didn't support that."); 1796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 17981065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber } 17991065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber } 18001065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber 18011065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber return OK; 18021065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber} 18031065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber 18041065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huberstatus_t OMXCodec::applyRotation() { 18051065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber sp<MetaData> meta = mSource->getFormat(); 18061065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber 18071065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber int32_t rotationDegrees; 18081065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber if (!meta->findInt32(kKeyRotation, &rotationDegrees)) { 1809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber rotationDegrees = 0; 1810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 18111065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber 18121065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber uint32_t transform; 18131065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber switch (rotationDegrees) { 1814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case 0: transform = 0; break; 1815078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber case 90: transform = HAL_TRANSFORM_ROT_90; break; 1816078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber case 180: transform = HAL_TRANSFORM_ROT_180; break; 1817078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber case 270: transform = HAL_TRANSFORM_ROT_270; break; 18181065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber default: transform = 0; break; 1819078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 1820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 18211065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber status_t err = OK; 18221065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber 18231065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber if (transform) { 18241065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber err = native_window_set_buffers_transform( 18251065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber mNativeWindow.get(), transform); 18261065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber } 18271065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber 1828c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber return err; 1829c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber} 1830c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber 1831cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huberstatus_t OMXCodec::allocateOutputBuffersFromNativeWindow() { 1832c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber // Get the number of buffers needed. 1833c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber OMX_PARAM_PORTDEFINITIONTYPE def; 1834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber InitOMXParams(&def); 1835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber def.nPortIndex = kPortIndexOutput; 1836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err = mOMX->getParameter( 1838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 1840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 1841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1842349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 1843349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber err = native_window_set_buffers_geometry( 1844349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber mNativeWindow.get(), 1845dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber def.format.video.nFrameWidth, 1846dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber def.format.video.nFrameHeight, 1847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber def.format.video.eColorFormat); 1848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != 0) { 1850386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber LOGE("native_window_set_buffers_geometry failed: %s (%d)", 1851386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber strerror(-err), -err); 18521173118eace0e9e347cb007f0da817cee87579edGlenn Kasten return err; 18531173118eace0e9e347cb007f0da817cee87579edGlenn Kasten } 18541173118eace0e9e347cb007f0da817cee87579edGlenn Kasten 18551173118eace0e9e347cb007f0da817cee87579edGlenn Kasten err = applyRotation(); 1856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 1857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 1858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Set up the native window. 1861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_U32 usage = 0; 1862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage); 1863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != 0) { 1864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGW("querying usage flags from OMX IL component failed: %d", err); 1865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // XXX: Currently this error is logged, but not fatal. 1866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber usage = 0; 1867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mFlags & kEnableGrallocUsageProtected) { 1869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber usage |= GRALLOC_USAGE_PROTECTED; 1870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Make sure to check whether either Stagefright or the video decoder 18733856b090cd04ba5dd4a59a12430ed724d5995909Steve Block // requested protected buffers. 1874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (usage & GRALLOC_USAGE_PROTECTED) { 1875cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber // Verify that the ANativeWindow sends images directly to 1876cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber // SurfaceFlinger. 1877cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber int queuesToNativeWindow = 0; 1878cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber err = mNativeWindow->query( 1879cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, 1880cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber &queuesToNativeWindow); 1881cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber if (err != 0) { 1882cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber LOGE("error authenticating native window: %d", err); 1883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 1884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (queuesToNativeWindow != 1) { 1886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGE("native window could not be authenticated"); 1887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return PERMISSION_DENIED; 1888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGV("native_window_set_usage usage=0x%lx", usage); 1892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = native_window_set_usage( 1893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNativeWindow.get(), usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP); 1894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != 0) { 1895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err); 1896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 1897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int minUndequeuedBufs = 0; 1900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = mNativeWindow->query(mNativeWindow.get(), 1901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs); 1902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != 0) { 1903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)", 1904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber strerror(-err), -err); 1905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 1906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // XXX: Is this the right logic to use? It's not clear to me what the OMX 1909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // buffer counts refer to - how do they account for the renderer holding on 1910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // to buffers? 1911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (def.nBufferCountActual < def.nBufferCountMin + minUndequeuedBufs) { 1912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_U32 newBufferCount = def.nBufferCountMin + minUndequeuedBufs; 1913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber def.nBufferCountActual = newBufferCount; 1914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = mOMX->setParameter( 1915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 1917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CODEC_LOGE("setting nBufferCountActual to %lu failed: %d", 1918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber newBufferCount, err); 1919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 1920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = native_window_set_buffer_count( 1924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNativeWindow.get(), def.nBufferCountActual); 1925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != 0) { 1926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), 1927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber -err); 1928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 1929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CODEC_LOGI("allocating %lu buffers from a native window of size %lu on " 1932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber "output port", def.nBufferCountActual, def.nBufferSize); 1933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Dequeue buffers and send them to OMX 1935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) { 1936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ANativeWindowBuffer* buf; 19373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf); 1938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != 0) { 1939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err); 1940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 1941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false)); 1944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber BufferInfo info; 1945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info.mData = NULL; 1946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info.mSize = def.nBufferSize; 1947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info.mStatus = OWNED_BY_US; 1948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info.mMem = NULL; 1949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info.mMediaBuffer = new MediaBuffer(graphicBuffer); 1950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info.mMediaBuffer->setObserver(this); 1951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mPortBuffers[kPortIndexOutput].push(info); 1952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber IOMX::buffer_id bufferId; 1954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer, 1955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber &bufferId); 1956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != 0) { 1957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CODEC_LOGE("registering GraphicBuffer with OMX IL component " 1958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber "failed: %d", err); 1959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 1960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mPortBuffers[kPortIndexOutput].editItemAt(i).mBuffer = bufferId; 1963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CODEC_LOGV("registered graphic buffer with ID %p (pointer = %p)", 1965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bufferId, graphicBuffer.get()); 1966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_U32 cancelStart; 1969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_U32 cancelEnd; 1970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != 0) { 1971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // If an error occurred while dequeuing we need to cancel any buffers 1972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // that were dequeued. 1973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber cancelStart = 0; 1974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber cancelEnd = mPortBuffers[kPortIndexOutput].size(); 1975349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber } else { 1976349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber // Return the last two buffers to the native window. 1977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber cancelStart = def.nBufferCountActual - minUndequeuedBufs; 1978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber cancelEnd = def.nBufferCountActual; 1979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (OMX_U32 i = cancelStart; i < cancelEnd; i++) { 1982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(i); 1983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber cancelBufferToNativeWindow(info); 1984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 1987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1989f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t OMXCodec::cancelBufferToNativeWindow(BufferInfo *info) { 1990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US); 1991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CODEC_LOGV("Calling cancelBuffer on buffer %p", info->mBuffer); 1992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int err = mNativeWindow->cancelBuffer( 1993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNativeWindow.get(), info->mMediaBuffer->graphicBuffer().get()); 1994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != 0) { 1995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CODEC_LOGE("cancelBuffer failed w/ error 0x%08x", err); 1996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber setState(ERROR); 1998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 1999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info->mStatus = OWNED_BY_NATIVE_WINDOW; 2001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 2002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 2003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 20043856b090cd04ba5dd4a59a12430ed724d5995909Steve BlockOMXCodec::BufferInfo* OMXCodec::dequeueBufferFromNativeWindow() { 2005349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber // Dequeue the next buffer from the native window. 2006349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber ANativeWindowBuffer* buf; 2007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf); 2008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != 0) { 2009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CODEC_LOGE("dequeueBuffer failed w/ error 0x%08x", err); 2010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber setState(ERROR); 2012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return 0; 2013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2015349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber // Determine which buffer we just dequeued. 20163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 2017349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber BufferInfo *bufInfo = 0; 2018349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber for (size_t i = 0; i < buffers->size(); i++) { 2019349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber sp<GraphicBuffer> graphicBuffer = buffers->itemAt(i). 2020349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber mMediaBuffer->graphicBuffer(); 2021349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber if (graphicBuffer->handle == buf->handle) { 2022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bufInfo = &buffers->editItemAt(i); 2023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 2024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (bufInfo == 0) { 2028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CODEC_LOGE("dequeued unrecognized buffer: %p", buf); 2029349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 2030349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber setState(ERROR); 2031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return 0; 2032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 20343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block // The native window no longer owns the buffer. 2035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ((int)bufInfo->mStatus, (int)OWNED_BY_NATIVE_WINDOW); 2036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bufInfo->mStatus = OWNED_BY_US; 2037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return bufInfo; 2039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 2040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2041f933441648ef6a71dee783d733aac17b9508b452Andreas Huberint64_t OMXCodec::retrieveDecodingTimeUs(bool isCodecSpecific) { 2042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mIsEncoder); 2043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mDecodingTimeList.empty()) { 2045349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber CHECK(mNoMoreOutputData); 2046349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber // No corresponding input frame available. 2047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // This could happen when EOS is reached. 2048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return 0; 2049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber List<int64_t>::iterator it = mDecodingTimeList.begin(); 2052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t timeUs = *it; 2053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // If the output buffer is codec specific configuration, 2055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // do not remove the decoding time from the list. 2056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!isCodecSpecific) { 2057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDecodingTimeList.erase(it); 2058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 20597a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong return timeUs; 2060d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber} 2061d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber 2062d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubervoid OMXCodec::on_message(const omx_message &msg) { 2063d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber if (mState == ERROR) { 2064d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber LOGW("Dropping OMX message - we're in ERROR state."); 2065d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber return; 2066d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber } 2067349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 2068349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber switch (msg.type) { 2069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case omx_message::EVENT: 2070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 2071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onEvent( 2072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg.u.event_data.event, msg.u.event_data.data1, 2073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg.u.event_data.data2); 2074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 2076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case omx_message::EMPTY_BUFFER_DONE: 2079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 2080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer; 2081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CODEC_LOGV("EMPTY_BUFFER_DONE(buffer: %p)", buffer); 2083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 2085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t i = 0; 2086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) { 2087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ++i; 2088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(i < buffers->size()); 2091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if ((*buffers)[i].mStatus != OWNED_BY_COMPONENT) { 2092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGW("We already own input buffer %p, yet received " 2093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber "an EMPTY_BUFFER_DONE.", buffer); 2094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber BufferInfo* info = &buffers->editItemAt(i); 2097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info->mStatus = OWNED_BY_US; 2098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Buffer could not be released until empty buffer done is called. 2100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (info->mMediaBuffer != NULL) { 2101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mIsEncoder && 210231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber (mQuirks & kAvoidMemcopyInputRecordingFrames)) { 2103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // If zero-copy mode is enabled this will send the 2104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // input buffer back to the upstream source. 2105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber restorePatchedDataPointer(info); 2106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2108349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber info->mMediaBuffer->release(); 2109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info->mMediaBuffer = NULL; 2110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 211131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 211231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber if (mPortStatus[kPortIndexInput] == DISABLING) { 2113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CODEC_LOGV("Port is disabled, freeing buffer %p", buffer); 21143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block 2115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err = freeBuffer(kPortIndexInput, i); 2116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(err, (status_t)OK); 2117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (mState != ERROR 2118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber && mPortStatus[kPortIndexInput] != SHUTTING_DOWN) { 2119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ((int)mPortStatus[kPortIndexInput], (int)ENABLED); 2120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mFlags & kUseSecureInputBuffers) { 2122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber drainAnyInputBuffer(); 2123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 2124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber drainInputBuffer(&buffers->editItemAt(i)); 2125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 2128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case omx_message::FILL_BUFFER_DONE: 2131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 2132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer; 2133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_U32 flags = msg.u.extended_buffer_data.flags; 2134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CODEC_LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx, timestamp: %lld us (%.2f secs))", 2136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer, 2137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg.u.extended_buffer_data.range_length, 2138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber flags, 2139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg.u.extended_buffer_data.timestamp, 2140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg.u.extended_buffer_data.timestamp / 1E6); 2141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 2143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t i = 0; 2144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) { 2145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ++i; 2146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(i < buffers->size()); 2149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber BufferInfo *info = &buffers->editItemAt(i); 2150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (info->mStatus != OWNED_BY_COMPONENT) { 2152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGW("We already own output buffer %p, yet received " 2153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber "a FILL_BUFFER_DONE.", buffer); 2154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2156349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber info->mStatus = OWNED_BY_US; 2157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2158349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber if (mPortStatus[kPortIndexOutput] == DISABLING) { 21593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block CODEC_LOGV("Port is disabled, freeing buffer %p", buffer); 2160349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 2161349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber status_t err = freeBuffer(kPortIndexOutput, i); 2162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(err, (status_t)OK); 2163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0 2165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (mPortStatus[kPortIndexOutput] == ENABLED 2166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber && (flags & OMX_BUFFERFLAG_EOS)) { 2167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CODEC_LOGV("No more output data."); 2168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNoMoreOutputData = true; 2169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mBufferFilled.signal(); 2170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif 2171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) { 2172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ((int)mPortStatus[kPortIndexOutput], (int)ENABLED); 2173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (info->mMediaBuffer == NULL) { 2175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mOMXLivesLocally); 21763856b090cd04ba5dd4a59a12430ed724d5995909Steve Block CHECK(mQuirks & kRequiresAllocateBufferOnOutputPorts); 2177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mQuirks & kDefersOutputBufferAllocation); 2178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // The qcom video decoders on Nexus don't actually allocate 2180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // output buffer memory on a call to OMX_AllocateBuffer 2181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // the "pBuffer" member of the OMX_BUFFERHEADERTYPE 2182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // structure is only filled in later. 2183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info->mMediaBuffer = new MediaBuffer( 2185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg.u.extended_buffer_data.data_ptr, 2186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info->mSize); 2187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber info->mMediaBuffer->setObserver(this); 21883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block } 2189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber MediaBuffer *buffer = info->mMediaBuffer; 2191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool isGraphicBuffer = buffer->graphicBuffer() != NULL; 2192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!isGraphicBuffer 2194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber && msg.u.extended_buffer_data.range_offset 2195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber + msg.u.extended_buffer_data.range_length 2196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber > buffer->size()) { 2197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CODEC_LOGE( 2198cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber "Codec lied about its buffer size requirements, " 2199cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber "sending a buffer larger than the originally " 2200cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber "advertised size in FILL_BUFFER_DONE!"); 2201cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber } 2202cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber buffer->set_range( 2203cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber msg.u.extended_buffer_data.range_offset, 2204cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber msg.u.extended_buffer_data.range_length); 2205cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber 2206d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber buffer->meta_data()->clear(); 2207d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber 2208d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber buffer->meta_data()->setInt64( 2209d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber kKeyTime, msg.u.extended_buffer_data.timestamp); 2210d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber 2211d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) { 2212cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber buffer->meta_data()->setInt32(kKeyIsSyncFrame, true); 2213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool isCodecSpecific = false; 2215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_CODECCONFIG) { 2216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->meta_data()->setInt32(kKeyIsCodecConfig, true); 2217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber isCodecSpecific = true; 221831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber } 221931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 22203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block if (isGraphicBuffer || mQuirks & kOutputBuffersAreUnreadable) { 2221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->meta_data()->setInt32(kKeyIsUnreadable, true); 2222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2223349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 2224349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber buffer->meta_data()->setPointer( 2225349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber kKeyPlatformPrivate, 2226349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber msg.u.extended_buffer_data.platform_private); 2227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->meta_data()->setPointer( 2229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber kKeyBufferID, 2230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg.u.extended_buffer_data.buffer); 2231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_EOS) { 2233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CODEC_LOGV("No more output data."); 2234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNoMoreOutputData = true; 2235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mIsEncoder) { 2238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t decodingTimeUs = retrieveDecodingTimeUs(isCodecSpecific); 2239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs); 2240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mTargetTimeUs >= 0) { 2243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg.u.extended_buffer_data.timestamp <= mTargetTimeUs); 2244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (msg.u.extended_buffer_data.timestamp < mTargetTimeUs) { 2246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CODEC_LOGV( 2247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber "skipping output buffer at timestamp %lld us", 2248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg.u.extended_buffer_data.timestamp); 2249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber fillOutputBuffer(info); 2251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 2252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CODEC_LOGV( 2255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber "returning output buffer at target timestamp " 2256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber "%lld us", 2257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg.u.extended_buffer_data.timestamp); 2258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mTargetTimeUs = -1; 2260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFilledBuffers.push_back(i); 2263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mBufferFilled.signal(); 2264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mIsEncoder) { 2265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sched_yield(); 2266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 2270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 2273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 2274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(!"should not be here."); 22753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block break; 227631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber } 227731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber } 2278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 2279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// Has the format changed in any way that the client would have to be aware of? 2281f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic bool formatHasNotablyChanged( 2282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const sp<MetaData> &from, const sp<MetaData> &to) { 2283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (from.get() == NULL && to.get() == NULL) { 2284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return false; 2285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if ((from.get() == NULL && to.get() != NULL) 2288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber || (from.get() != NULL && to.get() == NULL)) { 2289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 2290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *mime_from, *mime_to; 2293349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber CHECK(from->findCString(kKeyMIMEType, &mime_from)); 2294349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber CHECK(to->findCString(kKeyMIMEType, &mime_to)); 2295349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 2296349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber if (strcasecmp(mime_from, mime_to)) { 2297349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber return true; 2298349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber } 2299349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 2300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strcasecmp(mime_from, MEDIA_MIMETYPE_VIDEO_RAW)) { 2301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t colorFormat_from, colorFormat_to; 2302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(from->findInt32(kKeyColorFormat, &colorFormat_from)); 2303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(to->findInt32(kKeyColorFormat, &colorFormat_to)); 23040af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber 2305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (colorFormat_from != colorFormat_to) { 2306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 2307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t width_from, width_to; 2310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(from->findInt32(kKeyWidth, &width_from)); 2311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(to->findInt32(kKeyWidth, &width_to)); 2312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (width_from != width_to) { 2314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 2315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t height_from, height_to; 2318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(from->findInt32(kKeyHeight, &height_from)); 2319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(to->findInt32(kKeyHeight, &height_to)); 2320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (height_from != height_to) { 2322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 2323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t left_from, top_from, right_from, bottom_from; 2326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(from->findRect( 2327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber kKeyCropRect, 2328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber &left_from, &top_from, &right_from, &bottom_from)); 2329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t left_to, top_to, right_to, bottom_to; 2331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(to->findRect( 2332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber kKeyCropRect, 2333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber &left_to, &top_to, &right_to, &bottom_to)); 2334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (left_to != left_from || top_to != top_from 2336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber || right_to != right_from || bottom_to != bottom_from) { 2337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 2338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (!strcasecmp(mime_from, MEDIA_MIMETYPE_AUDIO_RAW)) { 2340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t numChannels_from, numChannels_to; 2341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(from->findInt32(kKeyChannelCount, &numChannels_from)); 2342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(to->findInt32(kKeyChannelCount, &numChannels_to)); 2343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (numChannels_from != numChannels_to) { 2345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 2346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t sampleRate_from, sampleRate_to; 2349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(from->findInt32(kKeySampleRate, &sampleRate_from)); 2350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(to->findInt32(kKeySampleRate, &sampleRate_to)); 2351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (sampleRate_from != sampleRate_to) { 2353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 2354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return false; 2358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 2359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2360f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 2361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (event) { 2362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case OMX_EventCmdComplete: 2363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 2364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onCmdComplete((OMX_COMMANDTYPE)data1, data2); 2365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 2366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 23673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block 2368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case OMX_EventError: 2369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 2370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CODEC_LOGE("ERROR(0x%08lx, %ld)", data1, data2); 2371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber setState(ERROR); 2373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 2374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case OMX_EventPortSettingsChanged: 2377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 23783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block CODEC_LOGV("OMX_EventPortSettingsChanged(port=%ld, data2=0x%08lx)", 2379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber data1, data2); 2380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) { 2382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onPortSettingsChanged(data1); 2383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (data1 == kPortIndexOutput && 2384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber (data2 == OMX_IndexConfigCommonOutputCrop || 2385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber data2 == OMX_IndexConfigCommonScale)) { 2386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<MetaData> oldOutputFormat = mOutputFormat; 2388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber initOutputFormat(mSource->getFormat()); 2389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (data2 == OMX_IndexConfigCommonOutputCrop && 2391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber formatHasNotablyChanged(oldOutputFormat, mOutputFormat)) { 2392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mOutputPortSettingsHaveChanged = true; 2393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mNativeWindow != NULL) { 2395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t left, top, right, bottom; 2396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mOutputFormat->findRect( 2397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber kKeyCropRect, 2398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber &left, &top, &right, &bottom)); 2399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber android_native_rect_t crop; 2401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber crop.left = left; 2402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber crop.top = top; 2403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber crop.right = right + 1; 2404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber crop.bottom = bottom + 1; 2405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // We'll ignore any errors here, if the surface is 2407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // already invalid, we'll know soon enough. 24083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block native_window_set_crop(mNativeWindow.get(), &crop); 2409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (data2 == OMX_IndexConfigCommonScale) { 2411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_CONFIG_SCALEFACTORTYPE scale; 2412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber InitOMXParams(&scale); 2413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber scale.nPortIndex = kPortIndexOutput; 2414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Change display dimension only when necessary. 2416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (OK == mOMX->getConfig( 2417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNode, 2418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_IndexConfigCommonScale, 2419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber &scale, sizeof(scale))) { 2420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t left, top, right, bottom; 2421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mOutputFormat->findRect(kKeyCropRect, 2422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber &left, &top, 2423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber &right, &bottom)); 2424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // The scale is in 16.16 format. 2426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // scale 1.0 = 0x010000. When there is no 2427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // need to change the display, skip it. 2428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber LOGV("Get OMX_IndexConfigScale: 0x%lx/0x%lx", 2429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber scale.xWidth, scale.xHeight); 2430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (scale.xWidth != 0x010000) { 2432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mOutputFormat->setInt32(kKeyDisplayWidth, 2433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ((right - left + 1) * scale.xWidth) >> 16); 2434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mOutputPortSettingsHaveChanged = true; 2435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (scale.xHeight != 0x010000) { 2438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mOutputFormat->setInt32(kKeyDisplayHeight, 2439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ((bottom - top + 1) * scale.xHeight) >> 16); 24407a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong mOutputPortSettingsHaveChanged = true; 2441d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber } 2442d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber } 2443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 2446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0 2449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case OMX_EventBufferFlag: 2450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 2451e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1); 2452e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber 2453e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber if (data1 == kPortIndexOutput) { 2454e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber mNoMoreOutputData = true; 2455e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber } 2456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 2457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif 2459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 2461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 2462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CODEC_LOGV("EVENT(%d, %ld, %ld)", event, data1, data2); 2463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 2464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 2467349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 2468349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Hubervoid OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) { 2469349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber switch (cmd) { 2470349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber case OMX_CommandStateSet: 2471349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber { 2472349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber onStateChange((OMX_STATETYPE)data); 2473349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber break; 2474349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber } 2475349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 24763856b090cd04ba5dd4a59a12430ed724d5995909Steve Block case OMX_CommandPortDisable: 2477349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber { 2478349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber OMX_U32 portIndex = data; 2479349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber CODEC_LOGV("PORT_DISABLED(%ld)", portIndex); 2480349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 2481349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber CHECK(mState == EXECUTING || mState == RECONFIGURING); 2482349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber CHECK_EQ((int)mPortStatus[portIndex], (int)DISABLING); 2483349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber CHECK_EQ(mPortBuffers[portIndex].size(), 0u); 2484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mPortStatus[portIndex] = DISABLED; 2486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mState == RECONFIGURING) { 2488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); 2489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<MetaData> oldOutputFormat = mOutputFormat; 2491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber initOutputFormat(mSource->getFormat()); 2492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Don't notify clients if the output port settings change 2494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // wasn't of importance to them, i.e. it may be that just the 2495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // number of buffers has changed and nothing else. 2496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mOutputPortSettingsHaveChanged = 2497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber formatHasNotablyChanged(oldOutputFormat, mOutputFormat); 2498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber enablePortAsync(portIndex); 2500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err = allocateBuffersOnPort(portIndex); 2502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 2504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CODEC_LOGE("allocateBuffersOnPort failed (err = %d)", err); 2505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber setState(ERROR); 2506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 2509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case OMX_CommandPortEnable: 2512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 2513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber OMX_U32 portIndex = data; 2514dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber CODEC_LOGV("PORT_ENABLED(%ld)", portIndex); 2515dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber 2516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mState == EXECUTING || mState == RECONFIGURING); 2517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLING); 2518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mPortStatus[portIndex] = ENABLED; 2520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2521 if (mState == RECONFIGURING) { 2522 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); 2523 2524 setState(EXECUTING); 2525 2526 fillOutputBuffers(); 2527 } 2528 break; 2529 } 2530 2531 case OMX_CommandFlush: 2532 { 2533 OMX_U32 portIndex = data; 2534 2535 CODEC_LOGV("FLUSH_DONE(%ld)", portIndex); 2536 2537 CHECK_EQ((int)mPortStatus[portIndex], (int)SHUTTING_DOWN); 2538 mPortStatus[portIndex] = ENABLED; 2539 2540 CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]), 2541 mPortBuffers[portIndex].size()); 2542 2543 if (mState == RECONFIGURING) { 2544 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); 2545 2546 disablePortAsync(portIndex); 2547 } else if (mState == EXECUTING_TO_IDLE) { 2548 if (mPortStatus[kPortIndexInput] == ENABLED 2549 && mPortStatus[kPortIndexOutput] == ENABLED) { 2550 CODEC_LOGV("Finished flushing both ports, now completing " 2551 "transition from EXECUTING to IDLE."); 2552 2553 mPortStatus[kPortIndexInput] = SHUTTING_DOWN; 2554 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN; 2555 2556 status_t err = 2557 mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 2558 CHECK_EQ(err, (status_t)OK); 2559 } 2560 } else { 2561 // We're flushing both ports in preparation for seeking. 2562 2563 if (mPortStatus[kPortIndexInput] == ENABLED 2564 && mPortStatus[kPortIndexOutput] == ENABLED) { 2565 CODEC_LOGV("Finished flushing both ports, now continuing from" 2566 " seek-time."); 2567 2568 // We implicitly resume pulling on our upstream source. 2569 mPaused = false; 2570 2571 drainInputBuffers(); 2572 fillOutputBuffers(); 2573 } 2574 2575 if (mOutputPortSettingsChangedPending) { 2576 CODEC_LOGV( 2577 "Honoring deferred output port settings change."); 2578 2579 mOutputPortSettingsChangedPending = false; 2580 onPortSettingsChanged(kPortIndexOutput); 2581 } 2582 } 2583 2584 break; 2585 } 2586 2587 default: 2588 { 2589 CODEC_LOGV("CMD_COMPLETE(%d, %ld)", cmd, data); 2590 break; 2591 } 2592 } 2593} 2594 2595void OMXCodec::onStateChange(OMX_STATETYPE newState) { 2596 CODEC_LOGV("onStateChange %d", newState); 2597 2598 switch (newState) { 2599 case OMX_StateIdle: 2600 { 2601 CODEC_LOGV("Now Idle."); 2602 if (mState == LOADED_TO_IDLE) { 2603 status_t err = mOMX->sendCommand( 2604 mNode, OMX_CommandStateSet, OMX_StateExecuting); 2605 2606 CHECK_EQ(err, (status_t)OK); 2607 2608 setState(IDLE_TO_EXECUTING); 2609 } else { 2610 CHECK_EQ((int)mState, (int)EXECUTING_TO_IDLE); 2611 2612 CHECK_EQ( 2613 countBuffersWeOwn(mPortBuffers[kPortIndexInput]), 2614 mPortBuffers[kPortIndexInput].size()); 2615 2616 CHECK_EQ( 2617 countBuffersWeOwn(mPortBuffers[kPortIndexOutput]), 2618 mPortBuffers[kPortIndexOutput].size()); 2619 2620 status_t err = mOMX->sendCommand( 2621 mNode, OMX_CommandStateSet, OMX_StateLoaded); 2622 2623 CHECK_EQ(err, (status_t)OK); 2624 2625 err = freeBuffersOnPort(kPortIndexInput); 2626 CHECK_EQ(err, (status_t)OK); 2627 2628 err = freeBuffersOnPort(kPortIndexOutput); 2629 CHECK_EQ(err, (status_t)OK); 2630 2631 mPortStatus[kPortIndexInput] = ENABLED; 2632 mPortStatus[kPortIndexOutput] = ENABLED; 2633 2634 setState(IDLE_TO_LOADED); 2635 } 2636 break; 2637 } 2638 2639 case OMX_StateExecuting: 2640 { 2641 CHECK_EQ((int)mState, (int)IDLE_TO_EXECUTING); 2642 2643 CODEC_LOGV("Now Executing."); 2644 2645 mOutputPortSettingsChangedPending = false; 2646 2647 setState(EXECUTING); 2648 2649 // Buffers will be submitted to the component in the first 2650 // call to OMXCodec::read as mInitialBufferSubmit is true at 2651 // this point. This ensures that this on_message call returns, 2652 // releases the lock and ::init can notice the state change and 2653 // itself return. 2654 break; 2655 } 2656 2657 case OMX_StateLoaded: 2658 { 2659 CHECK_EQ((int)mState, (int)IDLE_TO_LOADED); 2660 2661 CODEC_LOGV("Now Loaded."); 2662 2663 setState(LOADED); 2664 break; 2665 } 2666 2667 case OMX_StateInvalid: 2668 { 2669 setState(ERROR); 2670 break; 2671 } 2672 2673 default: 2674 { 2675 CHECK(!"should not be here."); 2676 break; 2677 } 2678 } 2679} 2680 2681// static 2682size_t OMXCodec::countBuffersWeOwn(const Vector<BufferInfo> &buffers) { 2683 size_t n = 0; 2684 for (size_t i = 0; i < buffers.size(); ++i) { 2685 if (buffers[i].mStatus != OWNED_BY_COMPONENT) { 2686 ++n; 2687 } 2688 } 2689 2690 return n; 2691} 2692 2693status_t OMXCodec::freeBuffersOnPort( 2694 OMX_U32 portIndex, bool onlyThoseWeOwn) { 2695 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 2696 2697 status_t stickyErr = OK; 2698 2699 for (size_t i = buffers->size(); i-- > 0;) { 2700 BufferInfo *info = &buffers->editItemAt(i); 2701 2702 if (onlyThoseWeOwn && info->mStatus == OWNED_BY_COMPONENT) { 2703 continue; 2704 } 2705 2706 CHECK(info->mStatus == OWNED_BY_US 2707 || info->mStatus == OWNED_BY_NATIVE_WINDOW); 2708 2709 CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex); 2710 2711 status_t err = freeBuffer(portIndex, i); 2712 2713 if (err != OK) { 2714 stickyErr = err; 2715 } 2716 2717 } 2718 2719 CHECK(onlyThoseWeOwn || buffers->isEmpty()); 2720 2721 return stickyErr; 2722} 2723 2724status_t OMXCodec::freeBuffer(OMX_U32 portIndex, size_t bufIndex) { 2725 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 2726 2727 BufferInfo *info = &buffers->editItemAt(bufIndex); 2728 2729 status_t err = mOMX->freeBuffer(mNode, portIndex, info->mBuffer); 2730 2731 if (err == OK && info->mMediaBuffer != NULL) { 2732 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); 2733 info->mMediaBuffer->setObserver(NULL); 2734 2735 // Make sure nobody but us owns this buffer at this point. 2736 CHECK_EQ(info->mMediaBuffer->refcount(), 0); 2737 2738 // Cancel the buffer if it belongs to an ANativeWindow. 2739 sp<GraphicBuffer> graphicBuffer = info->mMediaBuffer->graphicBuffer(); 2740 if (info->mStatus == OWNED_BY_US && graphicBuffer != 0) { 2741 err = cancelBufferToNativeWindow(info); 2742 } 2743 2744 info->mMediaBuffer->release(); 2745 info->mMediaBuffer = NULL; 2746 } 2747 2748 if (err == OK) { 2749 buffers->removeAt(bufIndex); 2750 } 2751 2752 return err; 2753} 2754 2755void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) { 2756 CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex); 2757 2758 CHECK_EQ((int)mState, (int)EXECUTING); 2759 CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); 2760 CHECK(!mOutputPortSettingsChangedPending); 2761 2762 if (mPortStatus[kPortIndexOutput] != ENABLED) { 2763 CODEC_LOGV("Deferring output port settings change."); 2764 mOutputPortSettingsChangedPending = true; 2765 return; 2766 } 2767 2768 setState(RECONFIGURING); 2769 2770 if (mQuirks & kNeedsFlushBeforeDisable) { 2771 if (!flushPortAsync(portIndex)) { 2772 onCmdComplete(OMX_CommandFlush, portIndex); 2773 } 2774 } else { 2775 disablePortAsync(portIndex); 2776 } 2777} 2778 2779bool OMXCodec::flushPortAsync(OMX_U32 portIndex) { 2780 CHECK(mState == EXECUTING || mState == RECONFIGURING 2781 || mState == EXECUTING_TO_IDLE); 2782 2783 CODEC_LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.", 2784 portIndex, countBuffersWeOwn(mPortBuffers[portIndex]), 2785 mPortBuffers[portIndex].size()); 2786 2787 CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLED); 2788 mPortStatus[portIndex] = SHUTTING_DOWN; 2789 2790 if ((mQuirks & kRequiresFlushCompleteEmulation) 2791 && countBuffersWeOwn(mPortBuffers[portIndex]) 2792 == mPortBuffers[portIndex].size()) { 2793 // No flush is necessary and this component fails to send a 2794 // flush-complete event in this case. 2795 2796 return false; 2797 } 2798 2799 status_t err = 2800 mOMX->sendCommand(mNode, OMX_CommandFlush, portIndex); 2801 CHECK_EQ(err, (status_t)OK); 2802 2803 return true; 2804} 2805 2806void OMXCodec::disablePortAsync(OMX_U32 portIndex) { 2807 CHECK(mState == EXECUTING || mState == RECONFIGURING); 2808 2809 CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLED); 2810 mPortStatus[portIndex] = DISABLING; 2811 2812 CODEC_LOGV("sending OMX_CommandPortDisable(%ld)", portIndex); 2813 status_t err = 2814 mOMX->sendCommand(mNode, OMX_CommandPortDisable, portIndex); 2815 CHECK_EQ(err, (status_t)OK); 2816 2817 freeBuffersOnPort(portIndex, true); 2818} 2819 2820void OMXCodec::enablePortAsync(OMX_U32 portIndex) { 2821 CHECK(mState == EXECUTING || mState == RECONFIGURING); 2822 2823 CHECK_EQ((int)mPortStatus[portIndex], (int)DISABLED); 2824 mPortStatus[portIndex] = ENABLING; 2825 2826 CODEC_LOGV("sending OMX_CommandPortEnable(%ld)", portIndex); 2827 status_t err = 2828 mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex); 2829 CHECK_EQ(err, (status_t)OK); 2830} 2831 2832void OMXCodec::fillOutputBuffers() { 2833 CHECK_EQ((int)mState, (int)EXECUTING); 2834 2835 // This is a workaround for some decoders not properly reporting 2836 // end-of-output-stream. If we own all input buffers and also own 2837 // all output buffers and we already signalled end-of-input-stream, 2838 // the end-of-output-stream is implied. 2839 if (mSignalledEOS 2840 && countBuffersWeOwn(mPortBuffers[kPortIndexInput]) 2841 == mPortBuffers[kPortIndexInput].size() 2842 && countBuffersWeOwn(mPortBuffers[kPortIndexOutput]) 2843 == mPortBuffers[kPortIndexOutput].size()) { 2844 mNoMoreOutputData = true; 2845 mBufferFilled.signal(); 2846 2847 return; 2848 } 2849 2850 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 2851 for (size_t i = 0; i < buffers->size(); ++i) { 2852 BufferInfo *info = &buffers->editItemAt(i); 2853 if (info->mStatus == OWNED_BY_US) { 2854 fillOutputBuffer(&buffers->editItemAt(i)); 2855 } 2856 } 2857} 2858 2859void OMXCodec::drainInputBuffers() { 2860 CHECK(mState == EXECUTING || mState == RECONFIGURING); 2861 2862 if (mFlags & kUseSecureInputBuffers) { 2863 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 2864 for (size_t i = 0; i < buffers->size(); ++i) { 2865 if (!drainAnyInputBuffer() 2866 || (mFlags & kOnlySubmitOneInputBufferAtOneTime)) { 2867 break; 2868 } 2869 } 2870 } else { 2871 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 2872 for (size_t i = 0; i < buffers->size(); ++i) { 2873 BufferInfo *info = &buffers->editItemAt(i); 2874 2875 if (info->mStatus != OWNED_BY_US) { 2876 continue; 2877 } 2878 2879 if (!drainInputBuffer(info)) { 2880 break; 2881 } 2882 2883 if (mFlags & kOnlySubmitOneInputBufferAtOneTime) { 2884 break; 2885 } 2886 } 2887 } 2888} 2889 2890bool OMXCodec::drainAnyInputBuffer() { 2891 return drainInputBuffer((BufferInfo *)NULL); 2892} 2893 2894OMXCodec::BufferInfo *OMXCodec::findInputBufferByDataPointer(void *ptr) { 2895 Vector<BufferInfo> *infos = &mPortBuffers[kPortIndexInput]; 2896 for (size_t i = 0; i < infos->size(); ++i) { 2897 BufferInfo *info = &infos->editItemAt(i); 2898 2899 if (info->mData == ptr) { 2900 CODEC_LOGV( 2901 "input buffer data ptr = %p, buffer_id = %p", 2902 ptr, 2903 info->mBuffer); 2904 2905 return info; 2906 } 2907 } 2908 2909 TRESPASS(); 2910} 2911 2912OMXCodec::BufferInfo *OMXCodec::findEmptyInputBuffer() { 2913 Vector<BufferInfo> *infos = &mPortBuffers[kPortIndexInput]; 2914 for (size_t i = 0; i < infos->size(); ++i) { 2915 BufferInfo *info = &infos->editItemAt(i); 2916 2917 if (info->mStatus == OWNED_BY_US) { 2918 return info; 2919 } 2920 } 2921 2922 TRESPASS(); 2923} 2924 2925bool OMXCodec::drainInputBuffer(BufferInfo *info) { 2926 if (info != NULL) { 2927 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US); 2928 } 2929 2930 if (mSignalledEOS) { 2931 return false; 2932 } 2933 2934 if (mCodecSpecificDataIndex < mCodecSpecificData.size()) { 2935 CHECK(!(mFlags & kUseSecureInputBuffers)); 2936 2937 const CodecSpecificData *specific = 2938 mCodecSpecificData[mCodecSpecificDataIndex]; 2939 2940 size_t size = specific->mSize; 2941 2942 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME) 2943 && !(mQuirks & kWantsNALFragments)) { 2944 static const uint8_t kNALStartCode[4] = 2945 { 0x00, 0x00, 0x00, 0x01 }; 2946 2947 CHECK(info->mSize >= specific->mSize + 4); 2948 2949 size += 4; 2950 2951 memcpy(info->mData, kNALStartCode, 4); 2952 memcpy((uint8_t *)info->mData + 4, 2953 specific->mData, specific->mSize); 2954 } else { 2955 CHECK(info->mSize >= specific->mSize); 2956 memcpy(info->mData, specific->mData, specific->mSize); 2957 } 2958 2959 mNoMoreOutputData = false; 2960 2961 CODEC_LOGV("calling emptyBuffer with codec specific data"); 2962 2963 status_t err = mOMX->emptyBuffer( 2964 mNode, info->mBuffer, 0, size, 2965 OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG, 2966 0); 2967 CHECK_EQ(err, (status_t)OK); 2968 2969 info->mStatus = OWNED_BY_COMPONENT; 2970 2971 ++mCodecSpecificDataIndex; 2972 return true; 2973 } 2974 2975 if (mPaused) { 2976 return false; 2977 } 2978 2979 status_t err; 2980 2981 bool signalEOS = false; 2982 int64_t timestampUs = 0; 2983 2984 size_t offset = 0; 2985 int32_t n = 0; 2986 2987 for (;;) { 2988 MediaBuffer *srcBuffer; 2989 if (mSeekTimeUs >= 0) { 2990 if (mLeftOverBuffer) { 2991 mLeftOverBuffer->release(); 2992 mLeftOverBuffer = NULL; 2993 } 2994 2995 MediaSource::ReadOptions options; 2996 options.setSeekTo(mSeekTimeUs, mSeekMode); 2997 2998 mSeekTimeUs = -1; 2999 mSeekMode = ReadOptions::SEEK_CLOSEST_SYNC; 3000 mBufferFilled.signal(); 3001 3002 err = mSource->read(&srcBuffer, &options); 3003 3004 if (err == OK) { 3005 int64_t targetTimeUs; 3006 if (srcBuffer->meta_data()->findInt64( 3007 kKeyTargetTime, &targetTimeUs) 3008 && targetTimeUs >= 0) { 3009 CODEC_LOGV("targetTimeUs = %lld us", targetTimeUs); 3010 mTargetTimeUs = targetTimeUs; 3011 } else { 3012 mTargetTimeUs = -1; 3013 } 3014 } 3015 } else if (mLeftOverBuffer) { 3016 srcBuffer = mLeftOverBuffer; 3017 mLeftOverBuffer = NULL; 3018 3019 err = OK; 3020 } else { 3021 err = mSource->read(&srcBuffer); 3022 } 3023 3024 if (err != OK) { 3025 signalEOS = true; 3026 mFinalStatus = err; 3027 mSignalledEOS = true; 3028 mBufferFilled.signal(); 3029 break; 3030 } 3031 3032 if (mFlags & kUseSecureInputBuffers) { 3033 info = findInputBufferByDataPointer(srcBuffer->data()); 3034 CHECK(info != NULL); 3035 } 3036 3037 size_t remainingBytes = info->mSize - offset; 3038 3039 if (srcBuffer->range_length() > remainingBytes) { 3040 if (offset == 0) { 3041 CODEC_LOGE( 3042 "Codec's input buffers are too small to accomodate " 3043 "buffer read from source (info->mSize = %d, srcLength = %d)", 3044 info->mSize, srcBuffer->range_length()); 3045 3046 srcBuffer->release(); 3047 srcBuffer = NULL; 3048 3049 setState(ERROR); 3050 return false; 3051 } 3052 3053 mLeftOverBuffer = srcBuffer; 3054 break; 3055 } 3056 3057 bool releaseBuffer = true; 3058 if (mIsEncoder && (mQuirks & kAvoidMemcopyInputRecordingFrames)) { 3059 CHECK(mOMXLivesLocally && offset == 0); 3060 3061 OMX_BUFFERHEADERTYPE *header = 3062 (OMX_BUFFERHEADERTYPE *)info->mBuffer; 3063 3064 CHECK(header->pBuffer == info->mData); 3065 3066 header->pBuffer = 3067 (OMX_U8 *)srcBuffer->data() + srcBuffer->range_offset(); 3068 3069 releaseBuffer = false; 3070 info->mMediaBuffer = srcBuffer; 3071 } else { 3072 if (mFlags & kStoreMetaDataInVideoBuffers) { 3073 releaseBuffer = false; 3074 info->mMediaBuffer = srcBuffer; 3075 } 3076 3077 if (mFlags & kUseSecureInputBuffers) { 3078 // Data in "info" is already provided at this time. 3079 3080 releaseBuffer = false; 3081 3082 CHECK(info->mMediaBuffer == NULL); 3083 info->mMediaBuffer = srcBuffer; 3084 } else { 3085 memcpy((uint8_t *)info->mData + offset, 3086 (const uint8_t *)srcBuffer->data() 3087 + srcBuffer->range_offset(), 3088 srcBuffer->range_length()); 3089 } 3090 } 3091 3092 int64_t lastBufferTimeUs; 3093 CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &lastBufferTimeUs)); 3094 CHECK(lastBufferTimeUs >= 0); 3095 if (mIsEncoder) { 3096 mDecodingTimeList.push_back(lastBufferTimeUs); 3097 } 3098 3099 if (offset == 0) { 3100 timestampUs = lastBufferTimeUs; 3101 } 3102 3103 offset += srcBuffer->range_length(); 3104 3105 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_VORBIS, mMIME)) { 3106 CHECK(!(mQuirks & kSupportsMultipleFramesPerInputBuffer)); 3107 CHECK_GE(info->mSize, offset + sizeof(int32_t)); 3108 3109 int32_t numPageSamples; 3110 if (!srcBuffer->meta_data()->findInt32( 3111 kKeyValidSamples, &numPageSamples)) { 3112 numPageSamples = -1; 3113 } 3114 3115 memcpy((uint8_t *)info->mData + offset, 3116 &numPageSamples, 3117 sizeof(numPageSamples)); 3118 3119 offset += sizeof(numPageSamples); 3120 } 3121 3122 if (releaseBuffer) { 3123 srcBuffer->release(); 3124 srcBuffer = NULL; 3125 } 3126 3127 ++n; 3128 3129 if (!(mQuirks & kSupportsMultipleFramesPerInputBuffer)) { 3130 break; 3131 } 3132 3133 int64_t coalescedDurationUs = lastBufferTimeUs - timestampUs; 3134 3135 if (coalescedDurationUs > 250000ll) { 3136 // Don't coalesce more than 250ms worth of encoded data at once. 3137 break; 3138 } 3139 } 3140 3141 if (n > 1) { 3142 LOGV("coalesced %d frames into one input buffer", n); 3143 } 3144 3145 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; 3146 3147 if (signalEOS) { 3148 flags |= OMX_BUFFERFLAG_EOS; 3149 } else { 3150 mNoMoreOutputData = false; 3151 } 3152 3153 CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d), " 3154 "timestamp %lld us (%.2f secs)", 3155 info->mBuffer, offset, 3156 timestampUs, timestampUs / 1E6); 3157 3158 if (info == NULL) { 3159 CHECK(mFlags & kUseSecureInputBuffers); 3160 CHECK(signalEOS); 3161 3162 // This is fishy, there's still a MediaBuffer corresponding to this 3163 // info available to the source at this point even though we're going 3164 // to use it to signal EOS to the codec. 3165 info = findEmptyInputBuffer(); 3166 } 3167 3168 err = mOMX->emptyBuffer( 3169 mNode, info->mBuffer, 0, offset, 3170 flags, timestampUs); 3171 3172 if (err != OK) { 3173 setState(ERROR); 3174 return false; 3175 } 3176 3177 info->mStatus = OWNED_BY_COMPONENT; 3178 3179 // This component does not ever signal the EOS flag on output buffers, 3180 // Thanks for nothing. 3181 if (mSignalledEOS && !strcmp(mComponentName, "OMX.TI.Video.encoder")) { 3182 mNoMoreOutputData = true; 3183 mBufferFilled.signal(); 3184 } 3185 3186 return true; 3187} 3188 3189void OMXCodec::fillOutputBuffer(BufferInfo *info) { 3190 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US); 3191 3192 if (mNoMoreOutputData) { 3193 CODEC_LOGV("There is no more output data available, not " 3194 "calling fillOutputBuffer"); 3195 return; 3196 } 3197 3198 if (info->mMediaBuffer != NULL) { 3199 sp<GraphicBuffer> graphicBuffer = info->mMediaBuffer->graphicBuffer(); 3200 if (graphicBuffer != 0) { 3201 // When using a native buffer we need to lock the buffer before 3202 // giving it to OMX. 3203 CODEC_LOGV("Calling lockBuffer on %p", info->mBuffer); 3204 int err = mNativeWindow->lockBuffer(mNativeWindow.get(), 3205 graphicBuffer.get()); 3206 if (err != 0) { 3207 CODEC_LOGE("lockBuffer failed w/ error 0x%08x", err); 3208 3209 setState(ERROR); 3210 return; 3211 } 3212 } 3213 } 3214 3215 CODEC_LOGV("Calling fillBuffer on buffer %p", info->mBuffer); 3216 status_t err = mOMX->fillBuffer(mNode, info->mBuffer); 3217 3218 if (err != OK) { 3219 CODEC_LOGE("fillBuffer failed w/ error 0x%08x", err); 3220 3221 setState(ERROR); 3222 return; 3223 } 3224 3225 info->mStatus = OWNED_BY_COMPONENT; 3226} 3227 3228bool OMXCodec::drainInputBuffer(IOMX::buffer_id buffer) { 3229 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; 3230 for (size_t i = 0; i < buffers->size(); ++i) { 3231 if ((*buffers)[i].mBuffer == buffer) { 3232 return drainInputBuffer(&buffers->editItemAt(i)); 3233 } 3234 } 3235 3236 CHECK(!"should not be here."); 3237 3238 return false; 3239} 3240 3241void OMXCodec::fillOutputBuffer(IOMX::buffer_id buffer) { 3242 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 3243 for (size_t i = 0; i < buffers->size(); ++i) { 3244 if ((*buffers)[i].mBuffer == buffer) { 3245 fillOutputBuffer(&buffers->editItemAt(i)); 3246 return; 3247 } 3248 } 3249 3250 CHECK(!"should not be here."); 3251} 3252 3253void OMXCodec::setState(State newState) { 3254 mState = newState; 3255 mAsyncCompletion.signal(); 3256 3257 // This may cause some spurious wakeups but is necessary to 3258 // unblock the reader if we enter ERROR state. 3259 mBufferFilled.signal(); 3260} 3261 3262void OMXCodec::setRawAudioFormat( 3263 OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) { 3264 3265 // port definition 3266 OMX_PARAM_PORTDEFINITIONTYPE def; 3267 InitOMXParams(&def); 3268 def.nPortIndex = portIndex; 3269 status_t err = mOMX->getParameter( 3270 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3271 CHECK_EQ(err, (status_t)OK); 3272 def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 3273 CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition, 3274 &def, sizeof(def)), (status_t)OK); 3275 3276 // pcm param 3277 OMX_AUDIO_PARAM_PCMMODETYPE pcmParams; 3278 InitOMXParams(&pcmParams); 3279 pcmParams.nPortIndex = portIndex; 3280 3281 err = mOMX->getParameter( 3282 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 3283 3284 CHECK_EQ(err, (status_t)OK); 3285 3286 pcmParams.nChannels = numChannels; 3287 pcmParams.eNumData = OMX_NumericalDataSigned; 3288 pcmParams.bInterleaved = OMX_TRUE; 3289 pcmParams.nBitPerSample = 16; 3290 pcmParams.nSamplingRate = sampleRate; 3291 pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear; 3292 3293 if (numChannels == 1) { 3294 pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelCF; 3295 } else { 3296 CHECK_EQ(numChannels, 2); 3297 3298 pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelLF; 3299 pcmParams.eChannelMapping[1] = OMX_AUDIO_ChannelRF; 3300 } 3301 3302 err = mOMX->setParameter( 3303 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 3304 3305 CHECK_EQ(err, (status_t)OK); 3306} 3307 3308static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(bool isAMRWB, int32_t bps) { 3309 if (isAMRWB) { 3310 if (bps <= 6600) { 3311 return OMX_AUDIO_AMRBandModeWB0; 3312 } else if (bps <= 8850) { 3313 return OMX_AUDIO_AMRBandModeWB1; 3314 } else if (bps <= 12650) { 3315 return OMX_AUDIO_AMRBandModeWB2; 3316 } else if (bps <= 14250) { 3317 return OMX_AUDIO_AMRBandModeWB3; 3318 } else if (bps <= 15850) { 3319 return OMX_AUDIO_AMRBandModeWB4; 3320 } else if (bps <= 18250) { 3321 return OMX_AUDIO_AMRBandModeWB5; 3322 } else if (bps <= 19850) { 3323 return OMX_AUDIO_AMRBandModeWB6; 3324 } else if (bps <= 23050) { 3325 return OMX_AUDIO_AMRBandModeWB7; 3326 } 3327 3328 // 23850 bps 3329 return OMX_AUDIO_AMRBandModeWB8; 3330 } else { // AMRNB 3331 if (bps <= 4750) { 3332 return OMX_AUDIO_AMRBandModeNB0; 3333 } else if (bps <= 5150) { 3334 return OMX_AUDIO_AMRBandModeNB1; 3335 } else if (bps <= 5900) { 3336 return OMX_AUDIO_AMRBandModeNB2; 3337 } else if (bps <= 6700) { 3338 return OMX_AUDIO_AMRBandModeNB3; 3339 } else if (bps <= 7400) { 3340 return OMX_AUDIO_AMRBandModeNB4; 3341 } else if (bps <= 7950) { 3342 return OMX_AUDIO_AMRBandModeNB5; 3343 } else if (bps <= 10200) { 3344 return OMX_AUDIO_AMRBandModeNB6; 3345 } 3346 3347 // 12200 bps 3348 return OMX_AUDIO_AMRBandModeNB7; 3349 } 3350} 3351 3352void OMXCodec::setAMRFormat(bool isWAMR, int32_t bitRate) { 3353 OMX_U32 portIndex = mIsEncoder ? kPortIndexOutput : kPortIndexInput; 3354 3355 OMX_AUDIO_PARAM_AMRTYPE def; 3356 InitOMXParams(&def); 3357 def.nPortIndex = portIndex; 3358 3359 status_t err = 3360 mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 3361 3362 CHECK_EQ(err, (status_t)OK); 3363 3364 def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; 3365 3366 def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitRate); 3367 err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 3368 CHECK_EQ(err, (status_t)OK); 3369 3370 //////////////////////// 3371 3372 if (mIsEncoder) { 3373 sp<MetaData> format = mSource->getFormat(); 3374 int32_t sampleRate; 3375 int32_t numChannels; 3376 CHECK(format->findInt32(kKeySampleRate, &sampleRate)); 3377 CHECK(format->findInt32(kKeyChannelCount, &numChannels)); 3378 3379 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 3380 } 3381} 3382 3383void OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate, int32_t bitRate) { 3384 CHECK(numChannels == 1 || numChannels == 2); 3385 if (mIsEncoder) { 3386 //////////////// input port //////////////////// 3387 setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 3388 3389 //////////////// output port //////////////////// 3390 // format 3391 OMX_AUDIO_PARAM_PORTFORMATTYPE format; 3392 format.nPortIndex = kPortIndexOutput; 3393 format.nIndex = 0; 3394 status_t err = OMX_ErrorNone; 3395 while (OMX_ErrorNone == err) { 3396 CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioPortFormat, 3397 &format, sizeof(format)), (status_t)OK); 3398 if (format.eEncoding == OMX_AUDIO_CodingAAC) { 3399 break; 3400 } 3401 format.nIndex++; 3402 } 3403 CHECK_EQ((status_t)OK, err); 3404 CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamAudioPortFormat, 3405 &format, sizeof(format)), (status_t)OK); 3406 3407 // port definition 3408 OMX_PARAM_PORTDEFINITIONTYPE def; 3409 InitOMXParams(&def); 3410 def.nPortIndex = kPortIndexOutput; 3411 CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, 3412 &def, sizeof(def)), (status_t)OK); 3413 def.format.audio.bFlagErrorConcealment = OMX_TRUE; 3414 def.format.audio.eEncoding = OMX_AUDIO_CodingAAC; 3415 CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition, 3416 &def, sizeof(def)), (status_t)OK); 3417 3418 // profile 3419 OMX_AUDIO_PARAM_AACPROFILETYPE profile; 3420 InitOMXParams(&profile); 3421 profile.nPortIndex = kPortIndexOutput; 3422 CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioAac, 3423 &profile, sizeof(profile)), (status_t)OK); 3424 profile.nChannels = numChannels; 3425 profile.eChannelMode = (numChannels == 1? 3426 OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo); 3427 profile.nSampleRate = sampleRate; 3428 profile.nBitRate = bitRate; 3429 profile.nAudioBandWidth = 0; 3430 profile.nFrameLength = 0; 3431 profile.nAACtools = OMX_AUDIO_AACToolAll; 3432 profile.nAACERtools = OMX_AUDIO_AACERNone; 3433 profile.eAACProfile = OMX_AUDIO_AACObjectLC; 3434 profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF; 3435 CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamAudioAac, 3436 &profile, sizeof(profile)), (status_t)OK); 3437 3438 } else { 3439 OMX_AUDIO_PARAM_AACPROFILETYPE profile; 3440 InitOMXParams(&profile); 3441 profile.nPortIndex = kPortIndexInput; 3442 3443 status_t err = mOMX->getParameter( 3444 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 3445 CHECK_EQ(err, (status_t)OK); 3446 3447 profile.nChannels = numChannels; 3448 profile.nSampleRate = sampleRate; 3449 profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS; 3450 3451 err = mOMX->setParameter( 3452 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 3453 CHECK_EQ(err, (status_t)OK); 3454 } 3455} 3456 3457void OMXCodec::setG711Format(int32_t numChannels) { 3458 CHECK(!mIsEncoder); 3459 setRawAudioFormat(kPortIndexInput, 8000, numChannels); 3460} 3461 3462void OMXCodec::setImageOutputFormat( 3463 OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) { 3464 CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height); 3465 3466#if 0 3467 OMX_INDEXTYPE index; 3468 status_t err = mOMX->get_extension_index( 3469 mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index); 3470 CHECK_EQ(err, (status_t)OK); 3471 3472 err = mOMX->set_config(mNode, index, &format, sizeof(format)); 3473 CHECK_EQ(err, (status_t)OK); 3474#endif 3475 3476 OMX_PARAM_PORTDEFINITIONTYPE def; 3477 InitOMXParams(&def); 3478 def.nPortIndex = kPortIndexOutput; 3479 3480 status_t err = mOMX->getParameter( 3481 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3482 CHECK_EQ(err, (status_t)OK); 3483 3484 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainImage); 3485 3486 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 3487 3488 CHECK_EQ((int)imageDef->eCompressionFormat, (int)OMX_IMAGE_CodingUnused); 3489 imageDef->eColorFormat = format; 3490 imageDef->nFrameWidth = width; 3491 imageDef->nFrameHeight = height; 3492 3493 switch (format) { 3494 case OMX_COLOR_FormatYUV420PackedPlanar: 3495 case OMX_COLOR_FormatYUV411Planar: 3496 { 3497 def.nBufferSize = (width * height * 3) / 2; 3498 break; 3499 } 3500 3501 case OMX_COLOR_FormatCbYCrY: 3502 { 3503 def.nBufferSize = width * height * 2; 3504 break; 3505 } 3506 3507 case OMX_COLOR_Format32bitARGB8888: 3508 { 3509 def.nBufferSize = width * height * 4; 3510 break; 3511 } 3512 3513 case OMX_COLOR_Format16bitARGB4444: 3514 case OMX_COLOR_Format16bitARGB1555: 3515 case OMX_COLOR_Format16bitRGB565: 3516 case OMX_COLOR_Format16bitBGR565: 3517 { 3518 def.nBufferSize = width * height * 2; 3519 break; 3520 } 3521 3522 default: 3523 CHECK(!"Should not be here. Unknown color format."); 3524 break; 3525 } 3526 3527 def.nBufferCountActual = def.nBufferCountMin; 3528 3529 err = mOMX->setParameter( 3530 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3531 CHECK_EQ(err, (status_t)OK); 3532} 3533 3534void OMXCodec::setJPEGInputFormat( 3535 OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) { 3536 OMX_PARAM_PORTDEFINITIONTYPE def; 3537 InitOMXParams(&def); 3538 def.nPortIndex = kPortIndexInput; 3539 3540 status_t err = mOMX->getParameter( 3541 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3542 CHECK_EQ(err, (status_t)OK); 3543 3544 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainImage); 3545 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 3546 3547 CHECK_EQ((int)imageDef->eCompressionFormat, (int)OMX_IMAGE_CodingJPEG); 3548 imageDef->nFrameWidth = width; 3549 imageDef->nFrameHeight = height; 3550 3551 def.nBufferSize = compressedSize; 3552 def.nBufferCountActual = def.nBufferCountMin; 3553 3554 err = mOMX->setParameter( 3555 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 3556 CHECK_EQ(err, (status_t)OK); 3557} 3558 3559void OMXCodec::addCodecSpecificData(const void *data, size_t size) { 3560 CodecSpecificData *specific = 3561 (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1); 3562 3563 specific->mSize = size; 3564 memcpy(specific->mData, data, size); 3565 3566 mCodecSpecificData.push(specific); 3567} 3568 3569void OMXCodec::clearCodecSpecificData() { 3570 for (size_t i = 0; i < mCodecSpecificData.size(); ++i) { 3571 free(mCodecSpecificData.editItemAt(i)); 3572 } 3573 mCodecSpecificData.clear(); 3574 mCodecSpecificDataIndex = 0; 3575} 3576 3577status_t OMXCodec::start(MetaData *meta) { 3578 Mutex::Autolock autoLock(mLock); 3579 3580 if (mState != LOADED) { 3581 return UNKNOWN_ERROR; 3582 } 3583 3584 sp<MetaData> params = new MetaData; 3585 if (mQuirks & kWantsNALFragments) { 3586 params->setInt32(kKeyWantsNALFragments, true); 3587 } 3588 if (meta) { 3589 int64_t startTimeUs = 0; 3590 int64_t timeUs; 3591 if (meta->findInt64(kKeyTime, &timeUs)) { 3592 startTimeUs = timeUs; 3593 } 3594 params->setInt64(kKeyTime, startTimeUs); 3595 } 3596 status_t err = mSource->start(params.get()); 3597 3598 if (err != OK) { 3599 return err; 3600 } 3601 3602 mCodecSpecificDataIndex = 0; 3603 mInitialBufferSubmit = true; 3604 mSignalledEOS = false; 3605 mNoMoreOutputData = false; 3606 mOutputPortSettingsHaveChanged = false; 3607 mSeekTimeUs = -1; 3608 mSeekMode = ReadOptions::SEEK_CLOSEST_SYNC; 3609 mTargetTimeUs = -1; 3610 mFilledBuffers.clear(); 3611 mPaused = false; 3612 3613 return init(); 3614} 3615 3616status_t OMXCodec::stop() { 3617 CODEC_LOGV("stop mState=%d", mState); 3618 3619 Mutex::Autolock autoLock(mLock); 3620 3621 while (isIntermediateState(mState)) { 3622 mAsyncCompletion.wait(mLock); 3623 } 3624 3625 switch (mState) { 3626 case LOADED: 3627 case ERROR: 3628 break; 3629 3630 case EXECUTING: 3631 { 3632 setState(EXECUTING_TO_IDLE); 3633 3634 if (mQuirks & kRequiresFlushBeforeShutdown) { 3635 CODEC_LOGV("This component requires a flush before transitioning " 3636 "from EXECUTING to IDLE..."); 3637 3638 bool emulateInputFlushCompletion = 3639 !flushPortAsync(kPortIndexInput); 3640 3641 bool emulateOutputFlushCompletion = 3642 !flushPortAsync(kPortIndexOutput); 3643 3644 if (emulateInputFlushCompletion) { 3645 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 3646 } 3647 3648 if (emulateOutputFlushCompletion) { 3649 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 3650 } 3651 } else { 3652 mPortStatus[kPortIndexInput] = SHUTTING_DOWN; 3653 mPortStatus[kPortIndexOutput] = SHUTTING_DOWN; 3654 3655 status_t err = 3656 mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); 3657 CHECK_EQ(err, (status_t)OK); 3658 } 3659 3660 while (mState != LOADED && mState != ERROR) { 3661 mAsyncCompletion.wait(mLock); 3662 } 3663 3664 break; 3665 } 3666 3667 default: 3668 { 3669 CHECK(!"should not be here."); 3670 break; 3671 } 3672 } 3673 3674 if (mLeftOverBuffer) { 3675 mLeftOverBuffer->release(); 3676 mLeftOverBuffer = NULL; 3677 } 3678 3679 mSource->stop(); 3680 3681 CODEC_LOGI("stopped in state %d", mState); 3682 3683 return OK; 3684} 3685 3686sp<MetaData> OMXCodec::getFormat() { 3687 Mutex::Autolock autoLock(mLock); 3688 3689 return mOutputFormat; 3690} 3691 3692status_t OMXCodec::read( 3693 MediaBuffer **buffer, const ReadOptions *options) { 3694 *buffer = NULL; 3695 3696 Mutex::Autolock autoLock(mLock); 3697 3698 if (mState != EXECUTING && mState != RECONFIGURING) { 3699 return UNKNOWN_ERROR; 3700 } 3701 3702 bool seeking = false; 3703 int64_t seekTimeUs; 3704 ReadOptions::SeekMode seekMode; 3705 if (options && options->getSeekTo(&seekTimeUs, &seekMode)) { 3706 seeking = true; 3707 } 3708 3709 if (mInitialBufferSubmit) { 3710 mInitialBufferSubmit = false; 3711 3712 if (seeking) { 3713 CHECK(seekTimeUs >= 0); 3714 mSeekTimeUs = seekTimeUs; 3715 mSeekMode = seekMode; 3716 3717 // There's no reason to trigger the code below, there's 3718 // nothing to flush yet. 3719 seeking = false; 3720 mPaused = false; 3721 } 3722 3723 drainInputBuffers(); 3724 3725 if (mState == EXECUTING) { 3726 // Otherwise mState == RECONFIGURING and this code will trigger 3727 // after the output port is reenabled. 3728 fillOutputBuffers(); 3729 } 3730 } 3731 3732 if (seeking) { 3733 while (mState == RECONFIGURING) { 3734 mBufferFilled.wait(mLock); 3735 } 3736 3737 if (mState != EXECUTING) { 3738 return UNKNOWN_ERROR; 3739 } 3740 3741 CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6); 3742 3743 mSignalledEOS = false; 3744 3745 CHECK(seekTimeUs >= 0); 3746 mSeekTimeUs = seekTimeUs; 3747 mSeekMode = seekMode; 3748 3749 mFilledBuffers.clear(); 3750 3751 CHECK_EQ((int)mState, (int)EXECUTING); 3752 3753 bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput); 3754 bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput); 3755 3756 if (emulateInputFlushCompletion) { 3757 onCmdComplete(OMX_CommandFlush, kPortIndexInput); 3758 } 3759 3760 if (emulateOutputFlushCompletion) { 3761 onCmdComplete(OMX_CommandFlush, kPortIndexOutput); 3762 } 3763 3764 while (mSeekTimeUs >= 0) { 3765 mBufferFilled.wait(mLock); 3766 } 3767 } 3768 3769 while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) { 3770 if (mIsEncoder) { 3771 if (NO_ERROR != mBufferFilled.waitRelative(mLock, 3000000000LL)) { 3772 LOGW("Timed out waiting for buffers from video encoder: %d/%d", 3773 countBuffersWeOwn(mPortBuffers[kPortIndexInput]), 3774 countBuffersWeOwn(mPortBuffers[kPortIndexOutput])); 3775 } 3776 } else { 3777 mBufferFilled.wait(mLock); 3778 } 3779 } 3780 3781 if (mState == ERROR) { 3782 return UNKNOWN_ERROR; 3783 } 3784 3785 if (mFilledBuffers.empty()) { 3786 return mSignalledEOS ? mFinalStatus : ERROR_END_OF_STREAM; 3787 } 3788 3789 if (mOutputPortSettingsHaveChanged) { 3790 mOutputPortSettingsHaveChanged = false; 3791 3792 return INFO_FORMAT_CHANGED; 3793 } 3794 3795 size_t index = *mFilledBuffers.begin(); 3796 mFilledBuffers.erase(mFilledBuffers.begin()); 3797 3798 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index); 3799 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US); 3800 info->mStatus = OWNED_BY_CLIENT; 3801 3802 info->mMediaBuffer->add_ref(); 3803 *buffer = info->mMediaBuffer; 3804 3805 return OK; 3806} 3807 3808void OMXCodec::signalBufferReturned(MediaBuffer *buffer) { 3809 Mutex::Autolock autoLock(mLock); 3810 3811 Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput]; 3812 for (size_t i = 0; i < buffers->size(); ++i) { 3813 BufferInfo *info = &buffers->editItemAt(i); 3814 3815 if (info->mMediaBuffer == buffer) { 3816 CHECK_EQ((int)mPortStatus[kPortIndexOutput], (int)ENABLED); 3817 CHECK_EQ((int)info->mStatus, (int)OWNED_BY_CLIENT); 3818 3819 info->mStatus = OWNED_BY_US; 3820 3821 if (buffer->graphicBuffer() == 0) { 3822 fillOutputBuffer(info); 3823 } else { 3824 sp<MetaData> metaData = info->mMediaBuffer->meta_data(); 3825 int32_t rendered = 0; 3826 if (!metaData->findInt32(kKeyRendered, &rendered)) { 3827 rendered = 0; 3828 } 3829 if (!rendered) { 3830 status_t err = cancelBufferToNativeWindow(info); 3831 if (err < 0) { 3832 return; 3833 } 3834 } 3835 3836 info->mStatus = OWNED_BY_NATIVE_WINDOW; 3837 3838 // Dequeue the next buffer from the native window. 3839 BufferInfo *nextBufInfo = dequeueBufferFromNativeWindow(); 3840 if (nextBufInfo == 0) { 3841 return; 3842 } 3843 3844 // Give the buffer to the OMX node to fill. 3845 fillOutputBuffer(nextBufInfo); 3846 } 3847 return; 3848 } 3849 } 3850 3851 CHECK(!"should not be here."); 3852} 3853 3854static const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) { 3855 static const char *kNames[] = { 3856 "OMX_IMAGE_CodingUnused", 3857 "OMX_IMAGE_CodingAutoDetect", 3858 "OMX_IMAGE_CodingJPEG", 3859 "OMX_IMAGE_CodingJPEG2K", 3860 "OMX_IMAGE_CodingEXIF", 3861 "OMX_IMAGE_CodingTIFF", 3862 "OMX_IMAGE_CodingGIF", 3863 "OMX_IMAGE_CodingPNG", 3864 "OMX_IMAGE_CodingLZW", 3865 "OMX_IMAGE_CodingBMP", 3866 }; 3867 3868 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 3869 3870 if (type < 0 || (size_t)type >= numNames) { 3871 return "UNKNOWN"; 3872 } else { 3873 return kNames[type]; 3874 } 3875} 3876 3877static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) { 3878 static const char *kNames[] = { 3879 "OMX_COLOR_FormatUnused", 3880 "OMX_COLOR_FormatMonochrome", 3881 "OMX_COLOR_Format8bitRGB332", 3882 "OMX_COLOR_Format12bitRGB444", 3883 "OMX_COLOR_Format16bitARGB4444", 3884 "OMX_COLOR_Format16bitARGB1555", 3885 "OMX_COLOR_Format16bitRGB565", 3886 "OMX_COLOR_Format16bitBGR565", 3887 "OMX_COLOR_Format18bitRGB666", 3888 "OMX_COLOR_Format18bitARGB1665", 3889 "OMX_COLOR_Format19bitARGB1666", 3890 "OMX_COLOR_Format24bitRGB888", 3891 "OMX_COLOR_Format24bitBGR888", 3892 "OMX_COLOR_Format24bitARGB1887", 3893 "OMX_COLOR_Format25bitARGB1888", 3894 "OMX_COLOR_Format32bitBGRA8888", 3895 "OMX_COLOR_Format32bitARGB8888", 3896 "OMX_COLOR_FormatYUV411Planar", 3897 "OMX_COLOR_FormatYUV411PackedPlanar", 3898 "OMX_COLOR_FormatYUV420Planar", 3899 "OMX_COLOR_FormatYUV420PackedPlanar", 3900 "OMX_COLOR_FormatYUV420SemiPlanar", 3901 "OMX_COLOR_FormatYUV422Planar", 3902 "OMX_COLOR_FormatYUV422PackedPlanar", 3903 "OMX_COLOR_FormatYUV422SemiPlanar", 3904 "OMX_COLOR_FormatYCbYCr", 3905 "OMX_COLOR_FormatYCrYCb", 3906 "OMX_COLOR_FormatCbYCrY", 3907 "OMX_COLOR_FormatCrYCbY", 3908 "OMX_COLOR_FormatYUV444Interleaved", 3909 "OMX_COLOR_FormatRawBayer8bit", 3910 "OMX_COLOR_FormatRawBayer10bit", 3911 "OMX_COLOR_FormatRawBayer8bitcompressed", 3912 "OMX_COLOR_FormatL2", 3913 "OMX_COLOR_FormatL4", 3914 "OMX_COLOR_FormatL8", 3915 "OMX_COLOR_FormatL16", 3916 "OMX_COLOR_FormatL24", 3917 "OMX_COLOR_FormatL32", 3918 "OMX_COLOR_FormatYUV420PackedSemiPlanar", 3919 "OMX_COLOR_FormatYUV422PackedSemiPlanar", 3920 "OMX_COLOR_Format18BitBGR666", 3921 "OMX_COLOR_Format24BitARGB6666", 3922 "OMX_COLOR_Format24BitABGR6666", 3923 }; 3924 3925 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 3926 3927 if (type == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) { 3928 return "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar"; 3929 } else if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) { 3930 return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar"; 3931 } else if (type < 0 || (size_t)type >= numNames) { 3932 return "UNKNOWN"; 3933 } else { 3934 return kNames[type]; 3935 } 3936} 3937 3938static const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) { 3939 static const char *kNames[] = { 3940 "OMX_VIDEO_CodingUnused", 3941 "OMX_VIDEO_CodingAutoDetect", 3942 "OMX_VIDEO_CodingMPEG2", 3943 "OMX_VIDEO_CodingH263", 3944 "OMX_VIDEO_CodingMPEG4", 3945 "OMX_VIDEO_CodingWMV", 3946 "OMX_VIDEO_CodingRV", 3947 "OMX_VIDEO_CodingAVC", 3948 "OMX_VIDEO_CodingMJPEG", 3949 }; 3950 3951 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 3952 3953 if (type < 0 || (size_t)type >= numNames) { 3954 return "UNKNOWN"; 3955 } else { 3956 return kNames[type]; 3957 } 3958} 3959 3960static const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) { 3961 static const char *kNames[] = { 3962 "OMX_AUDIO_CodingUnused", 3963 "OMX_AUDIO_CodingAutoDetect", 3964 "OMX_AUDIO_CodingPCM", 3965 "OMX_AUDIO_CodingADPCM", 3966 "OMX_AUDIO_CodingAMR", 3967 "OMX_AUDIO_CodingGSMFR", 3968 "OMX_AUDIO_CodingGSMEFR", 3969 "OMX_AUDIO_CodingGSMHR", 3970 "OMX_AUDIO_CodingPDCFR", 3971 "OMX_AUDIO_CodingPDCEFR", 3972 "OMX_AUDIO_CodingPDCHR", 3973 "OMX_AUDIO_CodingTDMAFR", 3974 "OMX_AUDIO_CodingTDMAEFR", 3975 "OMX_AUDIO_CodingQCELP8", 3976 "OMX_AUDIO_CodingQCELP13", 3977 "OMX_AUDIO_CodingEVRC", 3978 "OMX_AUDIO_CodingSMV", 3979 "OMX_AUDIO_CodingG711", 3980 "OMX_AUDIO_CodingG723", 3981 "OMX_AUDIO_CodingG726", 3982 "OMX_AUDIO_CodingG729", 3983 "OMX_AUDIO_CodingAAC", 3984 "OMX_AUDIO_CodingMP3", 3985 "OMX_AUDIO_CodingSBC", 3986 "OMX_AUDIO_CodingVORBIS", 3987 "OMX_AUDIO_CodingWMA", 3988 "OMX_AUDIO_CodingRA", 3989 "OMX_AUDIO_CodingMIDI", 3990 }; 3991 3992 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 3993 3994 if (type < 0 || (size_t)type >= numNames) { 3995 return "UNKNOWN"; 3996 } else { 3997 return kNames[type]; 3998 } 3999} 4000 4001static const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) { 4002 static const char *kNames[] = { 4003 "OMX_AUDIO_PCMModeLinear", 4004 "OMX_AUDIO_PCMModeALaw", 4005 "OMX_AUDIO_PCMModeMULaw", 4006 }; 4007 4008 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4009 4010 if (type < 0 || (size_t)type >= numNames) { 4011 return "UNKNOWN"; 4012 } else { 4013 return kNames[type]; 4014 } 4015} 4016 4017static const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) { 4018 static const char *kNames[] = { 4019 "OMX_AUDIO_AMRBandModeUnused", 4020 "OMX_AUDIO_AMRBandModeNB0", 4021 "OMX_AUDIO_AMRBandModeNB1", 4022 "OMX_AUDIO_AMRBandModeNB2", 4023 "OMX_AUDIO_AMRBandModeNB3", 4024 "OMX_AUDIO_AMRBandModeNB4", 4025 "OMX_AUDIO_AMRBandModeNB5", 4026 "OMX_AUDIO_AMRBandModeNB6", 4027 "OMX_AUDIO_AMRBandModeNB7", 4028 "OMX_AUDIO_AMRBandModeWB0", 4029 "OMX_AUDIO_AMRBandModeWB1", 4030 "OMX_AUDIO_AMRBandModeWB2", 4031 "OMX_AUDIO_AMRBandModeWB3", 4032 "OMX_AUDIO_AMRBandModeWB4", 4033 "OMX_AUDIO_AMRBandModeWB5", 4034 "OMX_AUDIO_AMRBandModeWB6", 4035 "OMX_AUDIO_AMRBandModeWB7", 4036 "OMX_AUDIO_AMRBandModeWB8", 4037 }; 4038 4039 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4040 4041 if (type < 0 || (size_t)type >= numNames) { 4042 return "UNKNOWN"; 4043 } else { 4044 return kNames[type]; 4045 } 4046} 4047 4048static const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) { 4049 static const char *kNames[] = { 4050 "OMX_AUDIO_AMRFrameFormatConformance", 4051 "OMX_AUDIO_AMRFrameFormatIF1", 4052 "OMX_AUDIO_AMRFrameFormatIF2", 4053 "OMX_AUDIO_AMRFrameFormatFSF", 4054 "OMX_AUDIO_AMRFrameFormatRTPPayload", 4055 "OMX_AUDIO_AMRFrameFormatITU", 4056 }; 4057 4058 size_t numNames = sizeof(kNames) / sizeof(kNames[0]); 4059 4060 if (type < 0 || (size_t)type >= numNames) { 4061 return "UNKNOWN"; 4062 } else { 4063 return kNames[type]; 4064 } 4065} 4066 4067void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { 4068 OMX_PARAM_PORTDEFINITIONTYPE def; 4069 InitOMXParams(&def); 4070 def.nPortIndex = portIndex; 4071 4072 status_t err = mOMX->getParameter( 4073 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 4074 CHECK_EQ(err, (status_t)OK); 4075 4076 printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output"); 4077 4078 CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput) 4079 || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput)); 4080 4081 printf(" nBufferCountActual = %ld\n", def.nBufferCountActual); 4082 printf(" nBufferCountMin = %ld\n", def.nBufferCountMin); 4083 printf(" nBufferSize = %ld\n", def.nBufferSize); 4084 4085 switch (def.eDomain) { 4086 case OMX_PortDomainImage: 4087 { 4088 const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 4089 4090 printf("\n"); 4091 printf(" // Image\n"); 4092 printf(" nFrameWidth = %ld\n", imageDef->nFrameWidth); 4093 printf(" nFrameHeight = %ld\n", imageDef->nFrameHeight); 4094 printf(" nStride = %ld\n", imageDef->nStride); 4095 4096 printf(" eCompressionFormat = %s\n", 4097 imageCompressionFormatString(imageDef->eCompressionFormat)); 4098 4099 printf(" eColorFormat = %s\n", 4100 colorFormatString(imageDef->eColorFormat)); 4101 4102 break; 4103 } 4104 4105 case OMX_PortDomainVideo: 4106 { 4107 OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; 4108 4109 printf("\n"); 4110 printf(" // Video\n"); 4111 printf(" nFrameWidth = %ld\n", videoDef->nFrameWidth); 4112 printf(" nFrameHeight = %ld\n", videoDef->nFrameHeight); 4113 printf(" nStride = %ld\n", videoDef->nStride); 4114 4115 printf(" eCompressionFormat = %s\n", 4116 videoCompressionFormatString(videoDef->eCompressionFormat)); 4117 4118 printf(" eColorFormat = %s\n", 4119 colorFormatString(videoDef->eColorFormat)); 4120 4121 break; 4122 } 4123 4124 case OMX_PortDomainAudio: 4125 { 4126 OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio; 4127 4128 printf("\n"); 4129 printf(" // Audio\n"); 4130 printf(" eEncoding = %s\n", 4131 audioCodingTypeString(audioDef->eEncoding)); 4132 4133 if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) { 4134 OMX_AUDIO_PARAM_PCMMODETYPE params; 4135 InitOMXParams(¶ms); 4136 params.nPortIndex = portIndex; 4137 4138 err = mOMX->getParameter( 4139 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 4140 CHECK_EQ(err, (status_t)OK); 4141 4142 printf(" nSamplingRate = %ld\n", params.nSamplingRate); 4143 printf(" nChannels = %ld\n", params.nChannels); 4144 printf(" bInterleaved = %d\n", params.bInterleaved); 4145 printf(" nBitPerSample = %ld\n", params.nBitPerSample); 4146 4147 printf(" eNumData = %s\n", 4148 params.eNumData == OMX_NumericalDataSigned 4149 ? "signed" : "unsigned"); 4150 4151 printf(" ePCMMode = %s\n", audioPCMModeString(params.ePCMMode)); 4152 } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) { 4153 OMX_AUDIO_PARAM_AMRTYPE amr; 4154 InitOMXParams(&amr); 4155 amr.nPortIndex = portIndex; 4156 4157 err = mOMX->getParameter( 4158 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); 4159 CHECK_EQ(err, (status_t)OK); 4160 4161 printf(" nChannels = %ld\n", amr.nChannels); 4162 printf(" eAMRBandMode = %s\n", 4163 amrBandModeString(amr.eAMRBandMode)); 4164 printf(" eAMRFrameFormat = %s\n", 4165 amrFrameFormatString(amr.eAMRFrameFormat)); 4166 } 4167 4168 break; 4169 } 4170 4171 default: 4172 { 4173 printf(" // Unknown\n"); 4174 break; 4175 } 4176 } 4177 4178 printf("}\n"); 4179} 4180 4181status_t OMXCodec::initNativeWindow() { 4182 // Enable use of a GraphicBuffer as the output for this node. This must 4183 // happen before getting the IndexParamPortDefinition parameter because it 4184 // will affect the pixel format that the node reports. 4185 status_t err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE); 4186 if (err != 0) { 4187 return err; 4188 } 4189 4190 return OK; 4191} 4192 4193void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) { 4194 mOutputFormat = new MetaData; 4195 mOutputFormat->setCString(kKeyDecoderComponent, mComponentName); 4196 if (mIsEncoder) { 4197 int32_t timeScale; 4198 if (inputFormat->findInt32(kKeyTimeScale, &timeScale)) { 4199 mOutputFormat->setInt32(kKeyTimeScale, timeScale); 4200 } 4201 } 4202 4203 OMX_PARAM_PORTDEFINITIONTYPE def; 4204 InitOMXParams(&def); 4205 def.nPortIndex = kPortIndexOutput; 4206 4207 status_t err = mOMX->getParameter( 4208 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 4209 CHECK_EQ(err, (status_t)OK); 4210 4211 switch (def.eDomain) { 4212 case OMX_PortDomainImage: 4213 { 4214 OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; 4215 CHECK_EQ((int)imageDef->eCompressionFormat, 4216 (int)OMX_IMAGE_CodingUnused); 4217 4218 mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 4219 mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat); 4220 mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth); 4221 mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight); 4222 break; 4223 } 4224 4225 case OMX_PortDomainAudio: 4226 { 4227 OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio; 4228 4229 if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) { 4230 OMX_AUDIO_PARAM_PCMMODETYPE params; 4231 InitOMXParams(¶ms); 4232 params.nPortIndex = kPortIndexOutput; 4233 4234 err = mOMX->getParameter( 4235 mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); 4236 CHECK_EQ(err, (status_t)OK); 4237 4238 CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned); 4239 CHECK_EQ(params.nBitPerSample, 16u); 4240 CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear); 4241 4242 int32_t numChannels, sampleRate; 4243 inputFormat->findInt32(kKeyChannelCount, &numChannels); 4244 inputFormat->findInt32(kKeySampleRate, &sampleRate); 4245 4246 if ((OMX_U32)numChannels != params.nChannels) { 4247 LOGW("Codec outputs a different number of channels than " 4248 "the input stream contains (contains %d channels, " 4249 "codec outputs %ld channels).", 4250 numChannels, params.nChannels); 4251 } 4252 4253 if (sampleRate != (int32_t)params.nSamplingRate) { 4254 LOGW("Codec outputs at different sampling rate than " 4255 "what the input stream contains (contains data at " 4256 "%d Hz, codec outputs %lu Hz)", 4257 sampleRate, params.nSamplingRate); 4258 } 4259 4260 mOutputFormat->setCString( 4261 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 4262 4263 // Use the codec-advertised number of channels, as some 4264 // codecs appear to output stereo even if the input data is 4265 // mono. If we know the codec lies about this information, 4266 // use the actual number of channels instead. 4267 mOutputFormat->setInt32( 4268 kKeyChannelCount, 4269 (mQuirks & kDecoderLiesAboutNumberOfChannels) 4270 ? numChannels : params.nChannels); 4271 4272 mOutputFormat->setInt32(kKeySampleRate, params.nSamplingRate); 4273 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) { 4274 OMX_AUDIO_PARAM_AMRTYPE amr; 4275 InitOMXParams(&amr); 4276 amr.nPortIndex = kPortIndexOutput; 4277 4278 err = mOMX->getParameter( 4279 mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); 4280 CHECK_EQ(err, (status_t)OK); 4281 4282 CHECK_EQ(amr.nChannels, 1u); 4283 mOutputFormat->setInt32(kKeyChannelCount, 1); 4284 4285 if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0 4286 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) { 4287 mOutputFormat->setCString( 4288 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB); 4289 mOutputFormat->setInt32(kKeySampleRate, 8000); 4290 } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0 4291 && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) { 4292 mOutputFormat->setCString( 4293 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB); 4294 mOutputFormat->setInt32(kKeySampleRate, 16000); 4295 } else { 4296 CHECK(!"Unknown AMR band mode."); 4297 } 4298 } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) { 4299 mOutputFormat->setCString( 4300 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 4301 int32_t numChannels, sampleRate, bitRate; 4302 inputFormat->findInt32(kKeyChannelCount, &numChannels); 4303 inputFormat->findInt32(kKeySampleRate, &sampleRate); 4304 inputFormat->findInt32(kKeyBitRate, &bitRate); 4305 mOutputFormat->setInt32(kKeyChannelCount, numChannels); 4306 mOutputFormat->setInt32(kKeySampleRate, sampleRate); 4307 mOutputFormat->setInt32(kKeyBitRate, bitRate); 4308 } else { 4309 CHECK(!"Should not be here. Unknown audio encoding."); 4310 } 4311 break; 4312 } 4313 4314 case OMX_PortDomainVideo: 4315 { 4316 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 4317 4318 if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) { 4319 mOutputFormat->setCString( 4320 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 4321 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) { 4322 mOutputFormat->setCString( 4323 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 4324 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) { 4325 mOutputFormat->setCString( 4326 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 4327 } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) { 4328 mOutputFormat->setCString( 4329 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 4330 } else { 4331 CHECK(!"Unknown compression format."); 4332 } 4333 4334 mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth); 4335 mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight); 4336 mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat); 4337 4338 if (!mIsEncoder) { 4339 OMX_CONFIG_RECTTYPE rect; 4340 InitOMXParams(&rect); 4341 rect.nPortIndex = kPortIndexOutput; 4342 status_t err = 4343 mOMX->getConfig( 4344 mNode, OMX_IndexConfigCommonOutputCrop, 4345 &rect, sizeof(rect)); 4346 4347 CODEC_LOGI( 4348 "video dimensions are %ld x %ld", 4349 video_def->nFrameWidth, video_def->nFrameHeight); 4350 4351 if (err == OK) { 4352 CHECK_GE(rect.nLeft, 0); 4353 CHECK_GE(rect.nTop, 0); 4354 CHECK_GE(rect.nWidth, 0u); 4355 CHECK_GE(rect.nHeight, 0u); 4356 CHECK_LE(rect.nLeft + rect.nWidth - 1, video_def->nFrameWidth); 4357 CHECK_LE(rect.nTop + rect.nHeight - 1, video_def->nFrameHeight); 4358 4359 mOutputFormat->setRect( 4360 kKeyCropRect, 4361 rect.nLeft, 4362 rect.nTop, 4363 rect.nLeft + rect.nWidth - 1, 4364 rect.nTop + rect.nHeight - 1); 4365 4366 CODEC_LOGI( 4367 "Crop rect is %ld x %ld @ (%ld, %ld)", 4368 rect.nWidth, rect.nHeight, rect.nLeft, rect.nTop); 4369 } else { 4370 mOutputFormat->setRect( 4371 kKeyCropRect, 4372 0, 0, 4373 video_def->nFrameWidth - 1, 4374 video_def->nFrameHeight - 1); 4375 } 4376 } 4377 break; 4378 } 4379 4380 default: 4381 { 4382 CHECK(!"should not be here, neither audio nor video."); 4383 break; 4384 } 4385 } 4386 4387 // If the input format contains rotation information, flag the output 4388 // format accordingly. 4389 4390 int32_t rotationDegrees; 4391 if (mSource->getFormat()->findInt32(kKeyRotation, &rotationDegrees)) { 4392 mOutputFormat->setInt32(kKeyRotation, rotationDegrees); 4393 } 4394} 4395 4396status_t OMXCodec::pause() { 4397 Mutex::Autolock autoLock(mLock); 4398 4399 mPaused = true; 4400 4401 return OK; 4402} 4403 4404//////////////////////////////////////////////////////////////////////////////// 4405 4406status_t QueryCodecs( 4407 const sp<IOMX> &omx, 4408 const char *mime, bool queryDecoders, 4409 Vector<CodecCapabilities> *results) { 4410 results->clear(); 4411 4412 for (int index = 0;; ++index) { 4413 const char *componentName; 4414 4415 if (!queryDecoders) { 4416 componentName = GetCodec( 4417 kEncoderInfo, sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]), 4418 mime, index); 4419 } else { 4420 componentName = GetCodec( 4421 kDecoderInfo, sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]), 4422 mime, index); 4423 } 4424 4425 if (!componentName) { 4426 return OK; 4427 } 4428 4429 if (strncmp(componentName, "OMX.", 4)) { 4430 // Not an OpenMax component but a software codec. 4431 4432#if HAVE_SOFTWARE_DECODERS 4433 results->push(); 4434 CodecCapabilities *caps = &results->editItemAt(results->size() - 1); 4435 caps->mComponentName = componentName; 4436#endif 4437 4438 continue; 4439 } 4440 4441 sp<OMXCodecObserver> observer = new OMXCodecObserver; 4442 IOMX::node_id node; 4443 status_t err = omx->allocateNode(componentName, observer, &node); 4444 4445 if (err != OK) { 4446 continue; 4447 } 4448 4449 OMXCodec::setComponentRole(omx, node, !queryDecoders, mime); 4450 4451 results->push(); 4452 CodecCapabilities *caps = &results->editItemAt(results->size() - 1); 4453 caps->mComponentName = componentName; 4454 4455 OMX_VIDEO_PARAM_PROFILELEVELTYPE param; 4456 InitOMXParams(¶m); 4457 4458 param.nPortIndex = queryDecoders ? 0 : 1; 4459 4460 for (param.nProfileIndex = 0;; ++param.nProfileIndex) { 4461 err = omx->getParameter( 4462 node, OMX_IndexParamVideoProfileLevelQuerySupported, 4463 ¶m, sizeof(param)); 4464 4465 if (err != OK) { 4466 break; 4467 } 4468 4469 CodecProfileLevel profileLevel; 4470 profileLevel.mProfile = param.eProfile; 4471 profileLevel.mLevel = param.eLevel; 4472 4473 caps->mProfileLevels.push(profileLevel); 4474 } 4475 4476 // Color format query 4477 OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat; 4478 InitOMXParams(&portFormat); 4479 portFormat.nPortIndex = queryDecoders ? 1 : 0; 4480 for (portFormat.nIndex = 0;; ++portFormat.nIndex) { 4481 err = omx->getParameter( 4482 node, OMX_IndexParamVideoPortFormat, 4483 &portFormat, sizeof(portFormat)); 4484 if (err != OK) { 4485 break; 4486 } 4487 caps->mColorFormats.push(portFormat.eColorFormat); 4488 } 4489 4490 CHECK_EQ(omx->freeNode(node), (status_t)OK); 4491 } 4492} 4493 4494void OMXCodec::restorePatchedDataPointer(BufferInfo *info) { 4495 CHECK(mIsEncoder && (mQuirks & kAvoidMemcopyInputRecordingFrames)); 4496 CHECK(mOMXLivesLocally); 4497 4498 OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)info->mBuffer; 4499 header->pBuffer = (OMX_U8 *)info->mData; 4500} 4501 4502} // namespace android 4503