SoftVideoEncoderOMXComponent.cpp revision 8c953e45f3431f8e1c04f8973fe8bdebf7e61033
11ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni/* 21ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni * Copyright 2014 The Android Open Source Project 3da0f069871343119251d6b0586be356dc2146a62Yang Ni * 4433558f0f9abbf07770db288183a15fd261cace2Yabin Cui * Licensed under the Apache License, Version 2.0 (the "License"); 5433558f0f9abbf07770db288183a15fd261cace2Yabin Cui * you may not use this file except in compliance with the License. 6433558f0f9abbf07770db288183a15fd261cace2Yabin Cui * You may obtain a copy of the License at 7da0f069871343119251d6b0586be356dc2146a62Yang Ni * 8062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni * http://www.apache.org/licenses/LICENSE-2.0 9062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni * 10da0f069871343119251d6b0586be356dc2146a62Yang Ni * Unless required by applicable law or agreed to in writing, software 11da0f069871343119251d6b0586be356dc2146a62Yang Ni * distributed under the License is distributed on an "AS IS" BASIS, 12da0f069871343119251d6b0586be356dc2146a62Yang Ni * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13da0f069871343119251d6b0586be356dc2146a62Yang Ni * See the License for the specific language governing permissions and 14da0f069871343119251d6b0586be356dc2146a62Yang Ni * limitations under the License. 15da0f069871343119251d6b0586be356dc2146a62Yang Ni */ 16da0f069871343119251d6b0586be356dc2146a62Yang Ni 17da0f069871343119251d6b0586be356dc2146a62Yang Ni#include <inttypes.h> 181ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni 191ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni//#define LOG_NDEBUG 0 201ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni#define LOG_TAG "SoftVideoEncoderOMXComponent" 211ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni#include <utils/Log.h> 222abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#include <utils/misc.h> 231ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni 241ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni#include "include/SoftVideoEncoderOMXComponent.h" 251ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni 26da0f069871343119251d6b0586be356dc2146a62Yang Ni#include <media/hardware/HardwareAPI.h> 27da0f069871343119251d6b0586be356dc2146a62Yang Ni#include <media/stagefright/foundation/ADebug.h> 28da0f069871343119251d6b0586be356dc2146a62Yang Ni#include <media/stagefright/foundation/ALooper.h> 29da0f069871343119251d6b0586be356dc2146a62Yang Ni#include <media/stagefright/foundation/AMessage.h> 301ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni#include <media/stagefright/foundation/AUtils.h> 311ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni#include <media/stagefright/MediaDefs.h> 321ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni 331ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni#include <ui/GraphicBuffer.h> 341ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni#include <ui/GraphicBufferMapper.h> 351ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni 36da0f069871343119251d6b0586be356dc2146a62Yang Ni#include <OMX_IndexExt.h> 371ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni 381ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ninamespace android { 391ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni 40ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Niconst static OMX_COLOR_FORMATTYPE kSupportedColorFormats[] = { 41eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni OMX_COLOR_FormatYUV420Planar, 42eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni OMX_COLOR_FormatYUV420SemiPlanar, 43eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni OMX_COLOR_FormatAndroidOpaque 44eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni}; 45eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 46eb9aa675754c49f613c6ad71d41472b30f38b007Yang Nitemplate<class T> 47eb9aa675754c49f613c6ad71d41472b30f38b007Yang Nistatic void InitOMXParams(T *params) { 48eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni params->nSize = sizeof(T); 49eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni params->nVersion.s.nVersionMajor = 1; 50eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni params->nVersion.s.nVersionMinor = 0; 51eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni params->nVersion.s.nRevision = 0; 52eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni params->nVersion.s.nStep = 0; 53eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni} 54ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni 55ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang NiSoftVideoEncoderOMXComponent::SoftVideoEncoderOMXComponent( 56eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni const char *name, 57eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni const char *componentRole, 58eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni OMX_VIDEO_CODINGTYPE codingType, 59eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni const CodecProfileLevel *profileLevels, 60eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni size_t numProfileLevels, 61eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni int32_t width, 62eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni int32_t height, 63eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni const OMX_CALLBACKTYPE *callbacks, 64eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni OMX_PTR appData, 65eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni OMX_COMPONENTTYPE **component) 661ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni : SimpleSoftOMXComponent(name, callbacks, appData, component), 67eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni mInputDataIsMeta(false), 68eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni mWidth(width), 691ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni mHeight(height), 70eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni mBitrate(192000), 71eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni mFramerate(30 << 16), // Q16 format 72eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni mColorFormat(OMX_COLOR_FormatYUV420Planar), 73eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni mMinOutputBufferSize(384), // arbitrary, using one uncompressed macroblock 74eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni mMinCompressionRatio(1), // max output size is normally the input size 75eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni mComponentRole(componentRole), 76eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni mCodingType(codingType), 771ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni mProfileLevels(profileLevels), 78eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni mNumProfileLevels(numProfileLevels) { 791ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni} 80eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 811ffd86b448d78366190c540f98f8b6d641cdb6cfYang Nivoid SoftVideoEncoderOMXComponent::initPorts( 821ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni OMX_U32 numInputBuffers, OMX_U32 numOutputBuffers, OMX_U32 outputBufferSize, 83eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni const char *mime, OMX_U32 minCompressionRatio) { 84eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni OMX_PARAM_PORTDEFINITIONTYPE def; 851ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni 861ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni mMinOutputBufferSize = outputBufferSize; 87da0f069871343119251d6b0586be356dc2146a62Yang Ni mMinCompressionRatio = minCompressionRatio; 88da0f069871343119251d6b0586be356dc2146a62Yang Ni 89062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni InitOMXParams(&def); 90062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 91062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni def.nPortIndex = kInputPortIndex; 92062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni def.eDir = OMX_DirInput; 93062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni def.nBufferCountMin = numInputBuffers; 94da0f069871343119251d6b0586be356dc2146a62Yang Ni def.nBufferCountActual = def.nBufferCountMin; 95eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni def.bEnabled = OMX_TRUE; 96eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni def.bPopulated = OMX_FALSE; 97eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni def.eDomain = OMX_PortDomainVideo; 98062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni def.bBuffersContiguous = OMX_FALSE; 99da0f069871343119251d6b0586be356dc2146a62Yang Ni def.format.video.pNativeRender = NULL; 100da0f069871343119251d6b0586be356dc2146a62Yang Ni def.format.video.nFrameWidth = mWidth; 101ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni def.format.video.nFrameHeight = mHeight; 102eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni def.format.video.nStride = def.format.video.nFrameWidth; 103eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni def.format.video.nSliceHeight = def.format.video.nFrameHeight; 104eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni def.format.video.nBitrate = 0; 105da0f069871343119251d6b0586be356dc2146a62Yang Ni // frameRate is in Q16 format. 106ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni def.format.video.xFramerate = mFramerate; 107ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni def.format.video.bFlagErrorConcealment = OMX_FALSE; 108062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni def.nBufferAlignment = kInputBufferAlignment; 109eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni def.format.video.cMIMEType = const_cast<char *>("video/raw"); 110eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; 1111ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni def.format.video.eColorFormat = mColorFormat; 1121ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni def.format.video.pNativeWindow = NULL; 113eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni // buffersize set in updatePortParams 114ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni 115ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni addPort(def); 116ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni 117ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni InitOMXParams(&def); 118ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni 119ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni def.nPortIndex = kOutputPortIndex; 120ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni def.eDir = OMX_DirOutput; 121eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni def.nBufferCountMin = numOutputBuffers; 122ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni def.nBufferCountActual = def.nBufferCountMin; 123ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni def.bEnabled = OMX_TRUE; 124ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni def.bPopulated = OMX_FALSE; 125ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni def.eDomain = OMX_PortDomainVideo; 126ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni def.bBuffersContiguous = OMX_FALSE; 127ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni def.format.video.pNativeRender = NULL; 128eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni def.format.video.nFrameWidth = mWidth; 129eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni def.format.video.nFrameHeight = mHeight; 1301ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni def.format.video.nStride = 0; 1311ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni def.format.video.nSliceHeight = 0; 132ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni def.format.video.nBitrate = mBitrate; 133eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni def.format.video.xFramerate = 0 << 16; 1341ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni def.format.video.bFlagErrorConcealment = OMX_FALSE; 1351ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni def.nBufferAlignment = kOutputBufferAlignment; 1361ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni def.format.video.cMIMEType = const_cast<char *>(mime); 1371ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni def.format.video.eCompressionFormat = mCodingType; 138062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni def.format.video.eColorFormat = OMX_COLOR_FormatUnused; 139062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni def.format.video.pNativeWindow = NULL; 140eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni // buffersize set in updatePortParams 141eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 142062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni addPort(def); 143062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 144eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni updatePortParams(); 145eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni} 146062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 147062c287f573ecc06c38ee4295e5627e12c52ac3dYang Nivoid SoftVideoEncoderOMXComponent::updatePortParams() { 148062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni OMX_PARAM_PORTDEFINITIONTYPE *inDef = &editPortInfo(kInputPortIndex)->mDef; 149062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni inDef->format.video.nFrameWidth = mWidth; 150eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni inDef->format.video.nFrameHeight = mHeight; 151062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni inDef->format.video.nStride = inDef->format.video.nFrameWidth; 152062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni inDef->format.video.nSliceHeight = inDef->format.video.nFrameHeight; 153eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni inDef->format.video.xFramerate = mFramerate; 154eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni inDef->format.video.eColorFormat = mColorFormat; 155eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni uint32_t rawBufferSize = 1561ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni inDef->format.video.nStride * inDef->format.video.nSliceHeight * 3 / 2; 157eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni if (inDef->format.video.eColorFormat == OMX_COLOR_FormatAndroidOpaque) { 158eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni inDef->nBufferSize = max(sizeof(VideoNativeMetadata), sizeof(VideoGrallocMetadata)); 159062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } else { 160062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni inDef->nBufferSize = rawBufferSize; 161062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } 162eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 163da0f069871343119251d6b0586be356dc2146a62Yang Ni OMX_PARAM_PORTDEFINITIONTYPE *outDef = &editPortInfo(kOutputPortIndex)->mDef; 164eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni outDef->format.video.nFrameWidth = mWidth; 165eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni outDef->format.video.nFrameHeight = mHeight; 166da0f069871343119251d6b0586be356dc2146a62Yang Ni outDef->format.video.nBitrate = mBitrate; 167eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 168eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni outDef->nBufferSize = max(mMinOutputBufferSize, rawBufferSize / mMinCompressionRatio); 169da0f069871343119251d6b0586be356dc2146a62Yang Ni} 170da0f069871343119251d6b0586be356dc2146a62Yang Ni 171062c287f573ecc06c38ee4295e5627e12c52ac3dYang NiOMX_ERRORTYPE SoftVideoEncoderOMXComponent::internalSetPortParams( 172062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni const OMX_PARAM_PORTDEFINITIONTYPE *port) { 173062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni if (port->nPortIndex == kInputPortIndex) { 174062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni mWidth = port->format.video.nFrameWidth; 175062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni mHeight = port->format.video.nFrameHeight; 176eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 177062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni // xFramerate comes in Q16 format, in frames per second unit 178062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni mFramerate = port->format.video.xFramerate; 179062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 180062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni if (port->format.video.eCompressionFormat != OMX_VIDEO_CodingUnused 181062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni || (port->format.video.eColorFormat != OMX_COLOR_FormatYUV420Planar 182062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni && port->format.video.eColorFormat != OMX_COLOR_FormatYUV420SemiPlanar 183062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni && port->format.video.eColorFormat != OMX_COLOR_FormatAndroidOpaque)) { 184062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni return OMX_ErrorUnsupportedSetting; 185062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } 186062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 1871ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni mColorFormat = port->format.video.eColorFormat; 1881ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni } else if (port->nPortIndex == kOutputPortIndex) { 1891ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni if (port->format.video.eCompressionFormat != mCodingType 190eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni || port->format.video.eColorFormat != OMX_COLOR_FormatUnused) { 191eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni return OMX_ErrorUnsupportedSetting; 192eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni } 193062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 194062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni mBitrate = port->format.video.nBitrate; 195062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } else { 196062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni return OMX_ErrorBadPortIndex; 197062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } 198da0f069871343119251d6b0586be356dc2146a62Yang Ni 199da0f069871343119251d6b0586be356dc2146a62Yang Ni updatePortParams(); 200da0f069871343119251d6b0586be356dc2146a62Yang Ni return OMX_ErrorNone; 201da0f069871343119251d6b0586be356dc2146a62Yang Ni} 202da0f069871343119251d6b0586be356dc2146a62Yang Ni 203da0f069871343119251d6b0586be356dc2146a62Yang NiOMX_ERRORTYPE SoftVideoEncoderOMXComponent::internalSetParameter( 204edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni OMX_INDEXTYPE index, const OMX_PTR param) { 205edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni // can include extension index OMX_INDEXEXTTYPE 206edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni const int32_t indexFull = index; 207edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni 208edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni switch (indexFull) { 209edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni case OMX_IndexParamVideoErrorCorrection: 210edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni { 211edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni return OMX_ErrorNotImplemented; 212edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni } 213edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni 214edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni case OMX_IndexParamStandardComponentRole: 215edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni { 216edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni const OMX_PARAM_COMPONENTROLETYPE *roleParams = 217edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni (const OMX_PARAM_COMPONENTROLETYPE *)param; 218edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni 219edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni if (strncmp((const char *)roleParams->cRole, 220edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni mComponentRole, 221edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni OMX_MAX_STRINGNAME_SIZE - 1)) { 222edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni return OMX_ErrorUnsupportedSetting; 223edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni } 224edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni 225edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni return OMX_ErrorNone; 226edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni } 227edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni 228edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni case OMX_IndexParamPortDefinition: 229edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni { 230da0f069871343119251d6b0586be356dc2146a62Yang Ni OMX_ERRORTYPE err = internalSetPortParams((const OMX_PARAM_PORTDEFINITIONTYPE *)param); 231eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 232eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni if (err != OMX_ErrorNone) { 233da0f069871343119251d6b0586be356dc2146a62Yang Ni return err; 234da0f069871343119251d6b0586be356dc2146a62Yang Ni } 235da0f069871343119251d6b0586be356dc2146a62Yang Ni 236062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni return SimpleSoftOMXComponent::internalSetParameter(index, param); 237062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } 238eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 239edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni case OMX_IndexParamVideoPortFormat: 240edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni { 241eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni const OMX_VIDEO_PARAM_PORTFORMATTYPE* format = 242eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni (const OMX_VIDEO_PARAM_PORTFORMATTYPE *)param; 243eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 244eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni if (format->nPortIndex == kInputPortIndex) { 245eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni if (format->eColorFormat == OMX_COLOR_FormatYUV420Planar || 246eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni format->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar || 247edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni format->eColorFormat == OMX_COLOR_FormatAndroidOpaque) { 248edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni mColorFormat = format->eColorFormat; 249edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni 250eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni updatePortParams(); 251eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni return OMX_ErrorNone; 252eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni } else { 253062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni ALOGE("Unsupported color format %i", format->eColorFormat); 254062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni return OMX_ErrorUnsupportedSetting; 255062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } 256062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } else if (format->nPortIndex == kOutputPortIndex) { 257062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni if (format->eCompressionFormat == mCodingType) { 258062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni return OMX_ErrorNone; 259062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } else { 260eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni return OMX_ErrorUnsupportedSetting; 261eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni } 262eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni } else { 263eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni return OMX_ErrorBadPortIndex; 264eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni } 265eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni } 266da0f069871343119251d6b0586be356dc2146a62Yang Ni 267da0f069871343119251d6b0586be356dc2146a62Yang Ni case kStoreMetaDataExtensionIndex: 268da0f069871343119251d6b0586be356dc2146a62Yang Ni { 269da0f069871343119251d6b0586be356dc2146a62Yang Ni // storeMetaDataInBuffers 270eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni const StoreMetaDataInBuffersParams *storeParam = 271da0f069871343119251d6b0586be356dc2146a62Yang Ni (const StoreMetaDataInBuffersParams *)param; 272eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 273eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni if (storeParam->nPortIndex == kOutputPortIndex) { 274eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni return storeParam->bStoreMetaData ? OMX_ErrorUnsupportedSetting : OMX_ErrorNone; 275eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni } else if (storeParam->nPortIndex != kInputPortIndex) { 276da0f069871343119251d6b0586be356dc2146a62Yang Ni return OMX_ErrorBadPortIndex; 277eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni } 278eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 279eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni mInputDataIsMeta = (storeParam->bStoreMetaData == OMX_TRUE); 280eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni if (mInputDataIsMeta) { 281da0f069871343119251d6b0586be356dc2146a62Yang Ni mColorFormat = OMX_COLOR_FormatAndroidOpaque; 282eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni } else if (mColorFormat == OMX_COLOR_FormatAndroidOpaque) { 283eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni mColorFormat = OMX_COLOR_FormatYUV420Planar; 284eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni } 285eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni updatePortParams(); 286da0f069871343119251d6b0586be356dc2146a62Yang Ni return OMX_ErrorNone; 287eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni } 288eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 289eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni default: 290eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni return SimpleSoftOMXComponent::internalSetParameter(index, param); 291eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni } 292eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni} 293da0f069871343119251d6b0586be356dc2146a62Yang Ni 294eb9aa675754c49f613c6ad71d41472b30f38b007Yang NiOMX_ERRORTYPE SoftVideoEncoderOMXComponent::internalGetParameter( 295eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni OMX_INDEXTYPE index, OMX_PTR param) { 296eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni switch ((int)index) { 297eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni case OMX_IndexParamVideoErrorCorrection: 298da0f069871343119251d6b0586be356dc2146a62Yang Ni { 299eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni return OMX_ErrorNotImplemented; 300da0f069871343119251d6b0586be356dc2146a62Yang Ni } 301062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 302062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni case OMX_IndexParamVideoPortFormat: 303062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni { 304062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams = 305062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni (OMX_VIDEO_PARAM_PORTFORMATTYPE *)param; 306062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 307062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni if (formatParams->nPortIndex == kInputPortIndex) { 308062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni if (formatParams->nIndex >= NELEM(kSupportedColorFormats)) { 309062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni return OMX_ErrorNoMore; 310062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } 311062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 312062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni // Color formats, in order of preference 313062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni formatParams->eColorFormat = kSupportedColorFormats[formatParams->nIndex]; 314062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni formatParams->eCompressionFormat = OMX_VIDEO_CodingUnused; 315062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni formatParams->xFramerate = mFramerate; 316062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni return OMX_ErrorNone; 317062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } else if (formatParams->nPortIndex == kOutputPortIndex) { 318062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni formatParams->eCompressionFormat = mCodingType; 319062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni formatParams->eColorFormat = OMX_COLOR_FormatUnused; 320062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni formatParams->xFramerate = 0; 321da0f069871343119251d6b0586be356dc2146a62Yang Ni return OMX_ErrorNone; 322da0f069871343119251d6b0586be356dc2146a62Yang Ni } else { 323da0f069871343119251d6b0586be356dc2146a62Yang Ni return OMX_ErrorBadPortIndex; 324062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } 325da0f069871343119251d6b0586be356dc2146a62Yang Ni } 326062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 327eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni case OMX_IndexParamVideoProfileLevelQuerySupported: 328eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni { 329da0f069871343119251d6b0586be356dc2146a62Yang Ni OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevel = 330eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni (OMX_VIDEO_PARAM_PROFILELEVELTYPE *) param; 331eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 332eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni if (profileLevel->nPortIndex != kOutputPortIndex) { 333da0f069871343119251d6b0586be356dc2146a62Yang Ni ALOGE("Invalid port index: %u", profileLevel->nPortIndex); 334062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni return OMX_ErrorUnsupportedIndex; 335062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } 336062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 337da0f069871343119251d6b0586be356dc2146a62Yang Ni if (profileLevel->nProfileIndex >= mNumProfileLevels) { 338062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni return OMX_ErrorNoMore; 339eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni } 340eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 341eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni profileLevel->eProfile = mProfileLevels[profileLevel->nProfileIndex].mProfile; 342da0f069871343119251d6b0586be356dc2146a62Yang Ni profileLevel->eLevel = mProfileLevels[profileLevel->nProfileIndex].mLevel; 343eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni return OMX_ErrorNone; 344eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni } 345eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 346062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni case OMX_IndexParamConsumerUsageBits: 347062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni { 348062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni OMX_U32 *usageBits = (OMX_U32 *)param; 349062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni *usageBits = GRALLOC_USAGE_SW_READ_OFTEN; 350062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni return OMX_ErrorNone; 351062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } 352062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 353062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni default: 354062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni return SimpleSoftOMXComponent::internalGetParameter(index, param); 355062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } 356062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni} 357da0f069871343119251d6b0586be356dc2146a62Yang Ni 358062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni// static 359062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni__attribute__((no_sanitize("integer"))) 360062c287f573ecc06c38ee4295e5627e12c52ac3dYang Nivoid SoftVideoEncoderOMXComponent::ConvertFlexYUVToPlanar( 361062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni uint8_t *dst, size_t dstStride, size_t dstVStride, 362062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni struct android_ycbcr *ycbcr, int32_t width, int32_t height) { 363062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni const uint8_t *src = (const uint8_t *)ycbcr->y; 364062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni const uint8_t *srcU = (const uint8_t *)ycbcr->cb; 365062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni const uint8_t *srcV = (const uint8_t *)ycbcr->cr; 366062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni uint8_t *dstU = dst + dstVStride * dstStride; 367062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni uint8_t *dstV = dstU + (dstVStride >> 1) * (dstStride >> 1); 368062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 369062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni for (size_t y = height; y > 0; --y) { 370062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni memcpy(dst, src, width); 371eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni dst += dstStride; 372da0f069871343119251d6b0586be356dc2146a62Yang Ni src += ycbcr->ystride; 373433558f0f9abbf07770db288183a15fd261cace2Yabin Cui } 374433558f0f9abbf07770db288183a15fd261cace2Yabin Cui if (ycbcr->cstride == ycbcr->ystride >> 1 && ycbcr->chroma_step == 1) { 375433558f0f9abbf07770db288183a15fd261cace2Yabin Cui // planar 376433558f0f9abbf07770db288183a15fd261cace2Yabin Cui for (size_t y = height >> 1; y > 0; --y) { 377433558f0f9abbf07770db288183a15fd261cace2Yabin Cui memcpy(dstU, srcU, width >> 1); 378433558f0f9abbf07770db288183a15fd261cace2Yabin Cui dstU += dstStride >> 1; 379433558f0f9abbf07770db288183a15fd261cace2Yabin Cui srcU += ycbcr->cstride; 380433558f0f9abbf07770db288183a15fd261cace2Yabin Cui memcpy(dstV, srcV, width >> 1); 381433558f0f9abbf07770db288183a15fd261cace2Yabin Cui dstV += dstStride >> 1; 382433558f0f9abbf07770db288183a15fd261cace2Yabin Cui srcV += ycbcr->cstride; 383433558f0f9abbf07770db288183a15fd261cace2Yabin Cui } 384edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni } else { 385edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni // arbitrary 386edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni for (size_t y = height >> 1; y > 0; --y) { 387eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni for (size_t x = width >> 1; x > 0; --x) { 388062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni *dstU++ = *srcU; 389edf4ea312cc3f7dd4373f8db5aaf9325ff054c8eYang Ni *dstV++ = *srcV; 3902abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni srcU += ycbcr->chroma_step; 3912abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni srcV += ycbcr->chroma_step; 3922abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni } 393eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni dstU += (dstStride >> 1) - (width >> 1); 394eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni dstV += (dstStride >> 1) - (width >> 1); 395433558f0f9abbf07770db288183a15fd261cace2Yabin Cui srcU += ycbcr->cstride - (width >> 1) * ycbcr->chroma_step; 396eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni srcV += ycbcr->cstride - (width >> 1) * ycbcr->chroma_step; 397eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni } 398da0f069871343119251d6b0586be356dc2146a62Yang Ni } 399eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni} 400eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 401eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni// static 402da0f069871343119251d6b0586be356dc2146a62Yang Ni__attribute__((no_sanitize("integer"))) 403eb9aa675754c49f613c6ad71d41472b30f38b007Yang Nivoid SoftVideoEncoderOMXComponent::ConvertYUV420SemiPlanarToYUV420Planar( 404da0f069871343119251d6b0586be356dc2146a62Yang Ni const uint8_t *inYVU, uint8_t* outYUV, int32_t width, int32_t height) { 405eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni // TODO: add support for stride 406eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni int32_t outYsize = width * height; 407eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni uint32_t *outY = (uint32_t *) outYUV; 408eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni uint16_t *outCb = (uint16_t *) (outYUV + outYsize); 409da0f069871343119251d6b0586be356dc2146a62Yang Ni uint16_t *outCr = (uint16_t *) (outYUV + outYsize + (outYsize >> 2)); 410062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 411062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni /* Y copying */ 412eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni memcpy(outY, inYVU, outYsize); 413eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 414eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni /* U & V copying */ 415da0f069871343119251d6b0586be356dc2146a62Yang Ni // FIXME this only works if width is multiple of 4 416eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni uint32_t *inYVU_4 = (uint32_t *) (inYVU + outYsize); 417062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni for (int32_t i = height >> 1; i > 0; --i) { 418062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni for (int32_t j = width >> 2; j > 0; --j) { 419da0f069871343119251d6b0586be356dc2146a62Yang Ni uint32_t temp = *inYVU_4++; 420da0f069871343119251d6b0586be356dc2146a62Yang Ni uint32_t tempU = temp & 0xFF; 4211ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni tempU = tempU | ((temp >> 8) & 0xFF00); 4221ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni 4231ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni uint32_t tempV = (temp >> 8) & 0xFF; 424eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni tempV = tempV | ((temp >> 16) & 0xFF00); 425eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 426eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni *outCb++ = tempU; 427eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni *outCr++ = tempV; 4281ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni } 4291ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni } 430da0f069871343119251d6b0586be356dc2146a62Yang Ni} 431eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 432eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni// static 433062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni__attribute__((no_sanitize("integer"))) 434062c287f573ecc06c38ee4295e5627e12c52ac3dYang Nivoid SoftVideoEncoderOMXComponent::ConvertRGB32ToPlanar( 435eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni uint8_t *dstY, size_t dstStride, size_t dstVStride, 436eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni const uint8_t *src, size_t width, size_t height, size_t srcStride, 437eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni bool bgr) { 438eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni CHECK((width & 1) == 0); 439eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni CHECK((height & 1) == 0); 440eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 441eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni uint8_t *dstU = dstY + dstStride * dstVStride; 442eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni uint8_t *dstV = dstU + (dstStride >> 1) * (dstVStride >> 1); 443eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 444eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni#ifdef SURFACE_IS_BGR32 445ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni bgr = !bgr; 446ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni#endif 447ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni 448062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni const size_t redOffset = bgr ? 2 : 0; 449062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni const size_t greenOffset = 1; 450062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni const size_t blueOffset = bgr ? 0 : 2; 451062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 452062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni for (size_t y = 0; y < height; ++y) { 453062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni for (size_t x = 0; x < width; ++x) { 454062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni unsigned red = src[redOffset]; 455062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni unsigned green = src[greenOffset]; 456062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni unsigned blue = src[blueOffset]; 457062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 458062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni // using ITU-R BT.601 conversion matrix 459062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni unsigned luma = 460062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni ((red * 66 + green * 129 + blue * 25) >> 8) + 16; 461062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 462eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni dstY[x] = luma; 463062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 464062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni if ((x & 1) == 0 && (y & 1) == 0) { 465062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni unsigned U = 466062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni ((-red * 38 - green * 74 + blue * 112) >> 8) + 128; 467062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 468062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni unsigned V = 469eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni ((red * 112 - green * 94 - blue * 18) >> 8) + 128; 470eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 4711ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni dstU[x >> 1] = U; 4721ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni dstV[x >> 1] = V; 4731ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni } 474da0f069871343119251d6b0586be356dc2146a62Yang Ni src += 4; 475062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } 476062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 477062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni if ((y & 1) == 0) { 478062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni dstU += dstStride >> 1; 479062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni dstV += dstStride >> 1; 480062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } 481062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 482062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni src += srcStride - 4 * width; 483062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni dstY += dstStride; 484062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } 485062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni} 486062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 487062c287f573ecc06c38ee4295e5627e12c52ac3dYang Niconst uint8_t *SoftVideoEncoderOMXComponent::extractGraphicBuffer( 488062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni uint8_t *dst, size_t dstSize, 489062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni const uint8_t *src, size_t srcSize, 490062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni size_t width, size_t height) const { 491062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni size_t dstStride = width; 492062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni size_t dstVStride = height; 493062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni 494062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni MetadataBufferType bufferType = *(MetadataBufferType *)src; 495062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni bool usingANWBuffer = bufferType == kMetadataBufferTypeANWBuffer; 496eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni if (!usingANWBuffer && bufferType != kMetadataBufferTypeGrallocSource) { 497eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni ALOGE("Unsupported metadata type (%d)", bufferType); 498eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni return NULL; 499eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni } 500eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 501ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni buffer_handle_t handle; 502ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni int format; 503eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni size_t srcStride; 504eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni size_t srcVStride; 505eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni if (usingANWBuffer) { 506eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni if (srcSize < sizeof(VideoNativeMetadata)) { 507eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni ALOGE("Metadata is too small (%zu vs %zu)", srcSize, sizeof(VideoNativeMetadata)); 508062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni return NULL; 509eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni } 510eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 511ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)src; 512ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni ANativeWindowBuffer *buffer = nativeMeta.pBuffer; 513eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni handle = buffer->handle; 514eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni format = buffer->format; 515eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni srcStride = buffer->stride; 516eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni srcVStride = buffer->height; 517eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni // convert stride from pixels to bytes 518eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni if (format != HAL_PIXEL_FORMAT_YV12 && 519eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni format != HAL_PIXEL_FORMAT_YCbCr_420_888) { 520eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni // TODO do we need to support other formats? 521062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni srcStride *= 4; 522062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } 523eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 524ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni if (nativeMeta.nFenceFd >= 0) { 525ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni sp<Fence> fence = new Fence(nativeMeta.nFenceFd); 526062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni nativeMeta.nFenceFd = -1; 527eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni status_t err = fence->wait(IOMX::kFenceTimeoutMs); 528da0f069871343119251d6b0586be356dc2146a62Yang Ni if (err != OK) { 529eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni ALOGE("Timed out waiting on input fence"); 530eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni return NULL; 531eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni } 532da0f069871343119251d6b0586be356dc2146a62Yang Ni } 533ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni } else { 534ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni // TODO: remove this part. Check if anyone uses this. 535eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 536eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni if (srcSize < sizeof(VideoGrallocMetadata)) { 537da0f069871343119251d6b0586be356dc2146a62Yang Ni ALOGE("Metadata is too small (%zu vs %zu)", srcSize, sizeof(VideoGrallocMetadata)); 538eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni return NULL; 539eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni } 540eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 541da0f069871343119251d6b0586be356dc2146a62Yang Ni VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)(src); 542eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni handle = grallocMeta.pHandle; 543eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni // assume HAL_PIXEL_FORMAT_RGBA_8888 544eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni // there is no way to get the src stride without the graphic buffer 545eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni format = HAL_PIXEL_FORMAT_RGBA_8888; 546eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni srcStride = width * 4; 547062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni srcVStride = height; 548062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni } 549eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni 550ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni size_t neededSize = 551ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0dYang Ni dstStride * dstVStride + (width >> 1) 552eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni + (dstStride >> 1) * ((dstVStride >> 1) + (height >> 1) - 1); 553eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni if (dstSize < neededSize) { 5541ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni ALOGE("destination buffer is too small (%zu vs %zu)", dstSize, neededSize); 5551ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni return NULL; 5561ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni } 5571ffd86b448d78366190c540f98f8b6d641cdb6cfYang Ni 558 auto& mapper = GraphicBufferMapper::get(); 559 560 void *bits = NULL; 561 struct android_ycbcr ycbcr; 562 status_t res; 563 if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) { 564 res = mapper.lockYCbCr( 565 handle, 566 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_NEVER, 567 Rect(width, height), &ycbcr); 568 } else { 569 res = mapper.lock( 570 handle, 571 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_NEVER, 572 Rect(width, height), &bits); 573 } 574 if (res != OK) { 575 ALOGE("Unable to lock image buffer %p for access", handle); 576 return NULL; 577 } 578 579 switch (format) { 580 case HAL_PIXEL_FORMAT_YV12: // YCrCb / YVU planar 581 // convert to flex YUV 582 ycbcr.y = bits; 583 ycbcr.cr = (uint8_t *)bits + srcStride * srcVStride; 584 ycbcr.cb = (uint8_t *)ycbcr.cr + (srcStride >> 1) * (srcVStride >> 1); 585 ycbcr.chroma_step = 1; 586 ycbcr.cstride = srcVStride >> 1; 587 ycbcr.ystride = srcVStride; 588 ConvertFlexYUVToPlanar(dst, dstStride, dstVStride, &ycbcr, width, height); 589 break; 590 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // YCrCb / YVU semiplanar, NV21 591 // convert to flex YUV 592 ycbcr.y = bits; 593 ycbcr.cr = (uint8_t *)bits + srcStride * srcVStride; 594 ycbcr.cb = (uint8_t *)ycbcr.cr + 1; 595 ycbcr.chroma_step = 2; 596 ycbcr.cstride = srcVStride; 597 ycbcr.ystride = srcVStride; 598 ConvertFlexYUVToPlanar(dst, dstStride, dstVStride, &ycbcr, width, height); 599 break; 600 case HAL_PIXEL_FORMAT_YCbCr_420_888: 601 ConvertFlexYUVToPlanar(dst, dstStride, dstVStride, &ycbcr, width, height); 602 break; 603 case HAL_PIXEL_FORMAT_RGBA_8888: 604 case HAL_PIXEL_FORMAT_BGRA_8888: 605 ConvertRGB32ToPlanar( 606 dst, dstStride, dstVStride, 607 (const uint8_t *)bits, width, height, srcStride, 608 format == HAL_PIXEL_FORMAT_BGRA_8888); 609 break; 610 default: 611 ALOGE("Unsupported pixel format %#x", format); 612 dst = NULL; 613 break; 614 } 615 616 if (mapper.unlock(handle) != OK) { 617 ALOGE("Unable to unlock image buffer %p for access", handle); 618 } 619 620 return dst; 621} 622 623OMX_ERRORTYPE SoftVideoEncoderOMXComponent::getExtensionIndex( 624 const char *name, OMX_INDEXTYPE *index) { 625 if (!strcmp(name, "OMX.google.android.index.storeMetaDataInBuffers") || 626 !strcmp(name, "OMX.google.android.index.storeANWBufferInMetadata")) { 627 *(int32_t*)index = kStoreMetaDataExtensionIndex; 628 return OMX_ErrorNone; 629 } 630 return SimpleSoftOMXComponent::getExtensionIndex(name, index); 631} 632 633} // namespace android 634