SoftVideoEncoderOMXComponent.cpp revision a21bed3d626d148e584bdddeeecf287b782b3fcb
12edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar/*
22edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar * Copyright 2014 The Android Open Source Project
32edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar *
42edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar * Licensed under the Apache License, Version 2.0 (the "License");
52edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar * you may not use this file except in compliance with the License.
62edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar * You may obtain a copy of the License at
72edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar *
82edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar *      http://www.apache.org/licenses/LICENSE-2.0
92edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar *
102edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar * Unless required by applicable law or agreed to in writing, software
112edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar * distributed under the License is distributed on an "AS IS" BASIS,
122edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar * See the License for the specific language governing permissions and
142edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar * limitations under the License.
152edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar */
162edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
172edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar#include <inttypes.h>
182edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
192edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar//#define LOG_NDEBUG 0
202edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar#define LOG_TAG "SoftVideoEncoderOMXComponent"
212edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar#include <utils/Log.h>
22a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar#include <utils/misc.h>
232edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
242edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar#include "include/SoftVideoEncoderOMXComponent.h"
252edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
262edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar#include <hardware/gralloc.h>
272edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar#include <media/hardware/HardwareAPI.h>
282edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar#include <media/stagefright/foundation/ADebug.h>
292edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar#include <media/stagefright/foundation/ALooper.h>
302edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar#include <media/stagefright/foundation/AMessage.h>
31a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar#include <media/stagefright/foundation/AUtils.h>
322edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar#include <media/stagefright/MediaDefs.h>
332edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
342edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar#include <ui/GraphicBuffer.h>
352edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar#include <ui/GraphicBufferMapper.h>
362edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
37c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar#include <OMX_IndexExt.h>
38c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
392edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnarnamespace android {
402edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
41a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnarconst static OMX_COLOR_FORMATTYPE kSupportedColorFormats[] = {
42a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    OMX_COLOR_FormatYUV420Planar,
43a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    OMX_COLOR_FormatYUV420SemiPlanar,
44a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    OMX_COLOR_FormatAndroidOpaque
45a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar};
46a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
47a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnartemplate<class T>
48a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnarstatic void InitOMXParams(T *params) {
49a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    params->nSize = sizeof(T);
50a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    params->nVersion.s.nVersionMajor = 1;
51a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    params->nVersion.s.nVersionMinor = 0;
52a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    params->nVersion.s.nRevision = 0;
53a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    params->nVersion.s.nStep = 0;
54a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar}
55a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
562edda09a2ad1d112c52acd37d323f63f0a492d67Lajos MolnarSoftVideoEncoderOMXComponent::SoftVideoEncoderOMXComponent(
572edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        const char *name,
58a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        const char *componentRole,
59a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        OMX_VIDEO_CODINGTYPE codingType,
60a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        const CodecProfileLevel *profileLevels,
61a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        size_t numProfileLevels,
62a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        int32_t width,
63a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        int32_t height,
642edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        const OMX_CALLBACKTYPE *callbacks,
652edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        OMX_PTR appData,
662edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        OMX_COMPONENTTYPE **component)
672edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    : SimpleSoftOMXComponent(name, callbacks, appData, component),
68a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mInputDataIsMeta(false),
69a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mWidth(width),
70a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mHeight(height),
71a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mBitrate(192000),
72a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mFramerate(30 << 16), // Q16 format
73a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mColorFormat(OMX_COLOR_FormatYUV420Planar),
74a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mGrallocModule(NULL),
75a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mMinOutputBufferSize(384), // arbitrary, using one uncompressed macroblock
76a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mMinCompressionRatio(1),   // max output size is normally the input size
77a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mComponentRole(componentRole),
78a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mCodingType(codingType),
79a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mProfileLevels(profileLevels),
80a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mNumProfileLevels(numProfileLevels) {
81a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar}
82a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
83a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnarvoid SoftVideoEncoderOMXComponent::initPorts(
84a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        OMX_U32 numInputBuffers, OMX_U32 numOutputBuffers, OMX_U32 outputBufferSize,
85a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        const char *mime, OMX_U32 minCompressionRatio) {
86a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
87a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
88a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    mMinOutputBufferSize = outputBufferSize;
89a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    mMinCompressionRatio = minCompressionRatio;
90a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
91a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    InitOMXParams(&def);
92a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
93a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.nPortIndex = kInputPortIndex;
94a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.eDir = OMX_DirInput;
95a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.nBufferCountMin = numInputBuffers;
96a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.nBufferCountActual = def.nBufferCountMin;
97a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.bEnabled = OMX_TRUE;
98a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.bPopulated = OMX_FALSE;
99a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.eDomain = OMX_PortDomainVideo;
100a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.bBuffersContiguous = OMX_FALSE;
101a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.pNativeRender = NULL;
102a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.nFrameWidth = mWidth;
103a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.nFrameHeight = mHeight;
104a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.nStride = def.format.video.nFrameWidth;
105a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.nSliceHeight = def.format.video.nFrameHeight;
106a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.nBitrate = 0;
107a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    // frameRate is in Q16 format.
108a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.xFramerate = mFramerate;
109a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.bFlagErrorConcealment = OMX_FALSE;
110a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.nBufferAlignment = kInputBufferAlignment;
111a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.cMIMEType = const_cast<char *>("video/raw");
112a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
113a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.eColorFormat = mColorFormat;
114a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.pNativeWindow = NULL;
115a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    // buffersize set in updatePortParams
116a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
117a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    addPort(def);
118a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
119a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    InitOMXParams(&def);
120a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
121a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.nPortIndex = kOutputPortIndex;
122a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.eDir = OMX_DirOutput;
123a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.nBufferCountMin = numOutputBuffers;
124a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.nBufferCountActual = def.nBufferCountMin;
125a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.bEnabled = OMX_TRUE;
126a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.bPopulated = OMX_FALSE;
127a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.eDomain = OMX_PortDomainVideo;
128a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.bBuffersContiguous = OMX_FALSE;
129a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.pNativeRender = NULL;
130a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.nFrameWidth = mWidth;
131a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.nFrameHeight = mHeight;
132a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.nStride = 0;
133a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.nSliceHeight = 0;
134a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.nBitrate = mBitrate;
135a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.xFramerate = 0 << 16;
136a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.bFlagErrorConcealment = OMX_FALSE;
137a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.nBufferAlignment = kOutputBufferAlignment;
138a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.cMIMEType = const_cast<char *>(mime);
139a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.eCompressionFormat = mCodingType;
140a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.eColorFormat = OMX_COLOR_FormatUnused;
141a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.pNativeWindow = NULL;
142a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    // buffersize set in updatePortParams
143a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
144a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    addPort(def);
145a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
146a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    updatePortParams();
147a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar}
148a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
149a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnarvoid SoftVideoEncoderOMXComponent::updatePortParams() {
150a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE *inDef = &editPortInfo(kInputPortIndex)->mDef;
151a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    inDef->format.video.nFrameWidth = mWidth;
152a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    inDef->format.video.nFrameHeight = mHeight;
153a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    inDef->format.video.nStride = inDef->format.video.nFrameWidth;
154a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    inDef->format.video.nSliceHeight = inDef->format.video.nFrameHeight;
155a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    inDef->format.video.xFramerate = mFramerate;
156a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    inDef->format.video.eColorFormat = mColorFormat;
157a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    uint32_t rawBufferSize =
158a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        inDef->format.video.nStride * inDef->format.video.nSliceHeight * 3 / 2;
159a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    if (inDef->format.video.eColorFormat == OMX_COLOR_FormatAndroidOpaque) {
160054219874873b41f1c815552987c10465c34ba2bLajos Molnar        inDef->nBufferSize = max(sizeof(VideoNativeMetadata), sizeof(VideoGrallocMetadata));
161a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    } else {
162a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        inDef->nBufferSize = rawBufferSize;
163a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    }
164a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
165a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE *outDef = &editPortInfo(kOutputPortIndex)->mDef;
166a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    outDef->format.video.nFrameWidth = mWidth;
167a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    outDef->format.video.nFrameHeight = mHeight;
168a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    outDef->format.video.nBitrate = mBitrate;
169a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
170a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    outDef->nBufferSize = max(mMinOutputBufferSize, rawBufferSize / mMinCompressionRatio);
171a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar}
172a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
173a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos MolnarOMX_ERRORTYPE SoftVideoEncoderOMXComponent::internalSetPortParams(
174a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        const OMX_PARAM_PORTDEFINITIONTYPE *port) {
175a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen
176a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen    if (!isValidOMXParam(port)) {
177a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen        return OMX_ErrorBadParameter;
178a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen    }
179a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen
180a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    if (port->nPortIndex == kInputPortIndex) {
181a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        mWidth = port->format.video.nFrameWidth;
182a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        mHeight = port->format.video.nFrameHeight;
183a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
184a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        // xFramerate comes in Q16 format, in frames per second unit
185a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        mFramerate = port->format.video.xFramerate;
186a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
187a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        if (port->format.video.eCompressionFormat != OMX_VIDEO_CodingUnused
188a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                || (port->format.video.eColorFormat != OMX_COLOR_FormatYUV420Planar
189a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                        && port->format.video.eColorFormat != OMX_COLOR_FormatYUV420SemiPlanar
190a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                        && port->format.video.eColorFormat != OMX_COLOR_FormatAndroidOpaque)) {
191a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return OMX_ErrorUnsupportedSetting;
192a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
193a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
194a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        mColorFormat = port->format.video.eColorFormat;
195a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    } else if (port->nPortIndex == kOutputPortIndex) {
196a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        if (port->format.video.eCompressionFormat != mCodingType
197a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                || port->format.video.eColorFormat != OMX_COLOR_FormatUnused) {
198a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return OMX_ErrorUnsupportedSetting;
199a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
200a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
201a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        mBitrate = port->format.video.nBitrate;
202a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    } else {
203a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        return OMX_ErrorBadPortIndex;
204a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    }
205a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
206a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    updatePortParams();
207a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    return OMX_ErrorNone;
208a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar}
209a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
210a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos MolnarOMX_ERRORTYPE SoftVideoEncoderOMXComponent::internalSetParameter(
211a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        OMX_INDEXTYPE index, const OMX_PTR param) {
212a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    // can include extension index OMX_INDEXEXTTYPE
213a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    const int32_t indexFull = index;
214a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
215a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    switch (indexFull) {
216a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        case OMX_IndexParamVideoErrorCorrection:
217a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        {
218a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return OMX_ErrorNotImplemented;
219a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
220a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
221a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        case OMX_IndexParamStandardComponentRole:
222a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        {
223a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            const OMX_PARAM_COMPONENTROLETYPE *roleParams =
224a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                (const OMX_PARAM_COMPONENTROLETYPE *)param;
225a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
226a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen            if (!isValidOMXParam(roleParams)) {
227a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen                return OMX_ErrorBadParameter;
228a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen            }
229a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen
230a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (strncmp((const char *)roleParams->cRole,
231a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                        mComponentRole,
232a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                        OMX_MAX_STRINGNAME_SIZE - 1)) {
233a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return OMX_ErrorUnsupportedSetting;
234a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            }
235a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
236a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return OMX_ErrorNone;
237a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
238a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
239a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        case OMX_IndexParamPortDefinition:
240a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        {
241a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            OMX_ERRORTYPE err = internalSetPortParams((const OMX_PARAM_PORTDEFINITIONTYPE *)param);
242a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
243a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (err != OMX_ErrorNone) {
244a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return err;
245a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            }
246a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
247a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return SimpleSoftOMXComponent::internalSetParameter(index, param);
248a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
249a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
250a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        case OMX_IndexParamVideoPortFormat:
251a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        {
252a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            const OMX_VIDEO_PARAM_PORTFORMATTYPE* format =
253a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                (const OMX_VIDEO_PARAM_PORTFORMATTYPE *)param;
254a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
255a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen            if (!isValidOMXParam(format)) {
256a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen                return OMX_ErrorBadParameter;
257a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen            }
258a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen
259a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (format->nPortIndex == kInputPortIndex) {
260a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                if (format->eColorFormat == OMX_COLOR_FormatYUV420Planar ||
261a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    format->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar ||
262a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    format->eColorFormat == OMX_COLOR_FormatAndroidOpaque) {
263a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    mColorFormat = format->eColorFormat;
264a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
265a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    updatePortParams();
266a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    return OMX_ErrorNone;
267a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                } else {
268a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    ALOGE("Unsupported color format %i", format->eColorFormat);
269a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    return OMX_ErrorUnsupportedSetting;
270a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                }
271a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            } else if (format->nPortIndex == kOutputPortIndex) {
272a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                if (format->eCompressionFormat == mCodingType) {
273a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    return OMX_ErrorNone;
274a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                } else {
275a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    return OMX_ErrorUnsupportedSetting;
276a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                }
277a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            } else {
278a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return OMX_ErrorBadPortIndex;
279a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            }
280a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
281a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
282a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        case kStoreMetaDataExtensionIndex:
283a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        {
284a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            // storeMetaDataInBuffers
285a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            const StoreMetaDataInBuffersParams *storeParam =
286a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                (const StoreMetaDataInBuffersParams *)param;
287a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
288a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen            if (!isValidOMXParam(storeParam)) {
289a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen                return OMX_ErrorBadParameter;
290a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen            }
291a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen
292a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (storeParam->nPortIndex == kOutputPortIndex) {
293a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return storeParam->bStoreMetaData ? OMX_ErrorUnsupportedSetting : OMX_ErrorNone;
294a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            } else if (storeParam->nPortIndex != kInputPortIndex) {
295a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return OMX_ErrorBadPortIndex;
296a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            }
297a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
298a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            mInputDataIsMeta = (storeParam->bStoreMetaData == OMX_TRUE);
299a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (mInputDataIsMeta) {
300a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                mColorFormat = OMX_COLOR_FormatAndroidOpaque;
301a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            } else if (mColorFormat == OMX_COLOR_FormatAndroidOpaque) {
302a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                mColorFormat = OMX_COLOR_FormatYUV420Planar;
303a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            }
304a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            updatePortParams();
305a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return OMX_ErrorNone;
306a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
307a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
308a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        default:
309a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return SimpleSoftOMXComponent::internalSetParameter(index, param);
310a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    }
311a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar}
312a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
313a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos MolnarOMX_ERRORTYPE SoftVideoEncoderOMXComponent::internalGetParameter(
314a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        OMX_INDEXTYPE index, OMX_PTR param) {
315c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    switch ((int)index) {
316a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        case OMX_IndexParamVideoErrorCorrection:
317a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        {
318a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return OMX_ErrorNotImplemented;
319a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
320a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
321a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        case OMX_IndexParamVideoPortFormat:
322a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        {
323a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams =
324a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                (OMX_VIDEO_PARAM_PORTFORMATTYPE *)param;
325a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
326a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen            if (!isValidOMXParam(formatParams)) {
327a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen                return OMX_ErrorBadParameter;
328a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen            }
329a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen
330a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (formatParams->nPortIndex == kInputPortIndex) {
331a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                if (formatParams->nIndex >= NELEM(kSupportedColorFormats)) {
332a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    return OMX_ErrorNoMore;
333a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                }
334a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
335a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                // Color formats, in order of preference
336a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                formatParams->eColorFormat = kSupportedColorFormats[formatParams->nIndex];
337a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                formatParams->eCompressionFormat = OMX_VIDEO_CodingUnused;
338a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                formatParams->xFramerate = mFramerate;
339a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return OMX_ErrorNone;
340a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            } else if (formatParams->nPortIndex == kOutputPortIndex) {
341a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                formatParams->eCompressionFormat = mCodingType;
342a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                formatParams->eColorFormat = OMX_COLOR_FormatUnused;
343a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                formatParams->xFramerate = 0;
344a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return OMX_ErrorNone;
345a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            } else {
346a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return OMX_ErrorBadPortIndex;
347a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            }
348a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
349a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
350a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        case OMX_IndexParamVideoProfileLevelQuerySupported:
351a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        {
352a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevel =
353a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                  (OMX_VIDEO_PARAM_PROFILELEVELTYPE *) param;
354a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
355a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen            if (!isValidOMXParam(profileLevel)) {
356a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen                return OMX_ErrorBadParameter;
357a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen            }
358a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen
359a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (profileLevel->nPortIndex != kOutputPortIndex) {
360a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                ALOGE("Invalid port index: %u", profileLevel->nPortIndex);
361a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return OMX_ErrorUnsupportedIndex;
362a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            }
363a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
364a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (profileLevel->nProfileIndex >= mNumProfileLevels) {
365a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return OMX_ErrorNoMore;
366a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            }
367a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
368a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            profileLevel->eProfile = mProfileLevels[profileLevel->nProfileIndex].mProfile;
369a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            profileLevel->eLevel   = mProfileLevels[profileLevel->nProfileIndex].mLevel;
370a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return OMX_ErrorNone;
371a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
372a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
373c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        case OMX_IndexParamConsumerUsageBits:
374c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        {
375c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            OMX_U32 *usageBits = (OMX_U32 *)param;
376c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            *usageBits = GRALLOC_USAGE_SW_READ_OFTEN;
377c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            return OMX_ErrorNone;
378c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        }
379c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
380a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        default:
381a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return SimpleSoftOMXComponent::internalGetParameter(index, param);
382a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    }
3832edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar}
3842edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
3852edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar// static
3862edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnarvoid SoftVideoEncoderOMXComponent::ConvertFlexYUVToPlanar(
3872edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        uint8_t *dst, size_t dstStride, size_t dstVStride,
3882edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        struct android_ycbcr *ycbcr, int32_t width, int32_t height) {
3892edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    const uint8_t *src = (const uint8_t *)ycbcr->y;
3902edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    const uint8_t *srcU = (const uint8_t *)ycbcr->cb;
3912edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    const uint8_t *srcV = (const uint8_t *)ycbcr->cr;
3922edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    uint8_t *dstU = dst + dstVStride * dstStride;
3932edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    uint8_t *dstV = dstU + (dstVStride >> 1) * (dstStride >> 1);
3942edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
3952edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    for (size_t y = height; y > 0; --y) {
3962edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        memcpy(dst, src, width);
3972edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        dst += dstStride;
3982edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        src += ycbcr->ystride;
3992edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
4002edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    if (ycbcr->cstride == ycbcr->ystride >> 1 && ycbcr->chroma_step == 1) {
4012edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        // planar
4022edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        for (size_t y = height >> 1; y > 0; --y) {
4032edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            memcpy(dstU, srcU, width >> 1);
4042edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            dstU += dstStride >> 1;
4052edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            srcU += ycbcr->cstride;
4062edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            memcpy(dstV, srcV, width >> 1);
4072edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            dstV += dstStride >> 1;
4082edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            srcV += ycbcr->cstride;
4092edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        }
4102edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    } else {
4112edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        // arbitrary
4122edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        for (size_t y = height >> 1; y > 0; --y) {
4132edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            for (size_t x = width >> 1; x > 0; --x) {
4142edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                *dstU++ = *srcU;
4152edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                *dstV++ = *srcV;
4162edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                srcU += ycbcr->chroma_step;
4172edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                srcV += ycbcr->chroma_step;
4182edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            }
4192edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            dstU += (dstStride >> 1) - (width >> 1);
4202edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            dstV += (dstStride >> 1) - (width >> 1);
4212edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            srcU += ycbcr->cstride - (width >> 1) * ycbcr->chroma_step;
4222edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            srcV += ycbcr->cstride - (width >> 1) * ycbcr->chroma_step;
4232edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        }
4242edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
4252edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar}
4262edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4272edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar// static
4282edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnarvoid SoftVideoEncoderOMXComponent::ConvertYUV420SemiPlanarToYUV420Planar(
4292edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        const uint8_t *inYVU, uint8_t* outYUV, int32_t width, int32_t height) {
4302edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    // TODO: add support for stride
4312edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    int32_t outYsize = width * height;
4322edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    uint32_t *outY  = (uint32_t *) outYUV;
4332edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    uint16_t *outCb = (uint16_t *) (outYUV + outYsize);
4342edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    uint16_t *outCr = (uint16_t *) (outYUV + outYsize + (outYsize >> 2));
4352edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4362edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    /* Y copying */
4372edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    memcpy(outY, inYVU, outYsize);
4382edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4392edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    /* U & V copying */
4402edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    // FIXME this only works if width is multiple of 4
4412edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    uint32_t *inYVU_4 = (uint32_t *) (inYVU + outYsize);
4422edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    for (int32_t i = height >> 1; i > 0; --i) {
4432edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        for (int32_t j = width >> 2; j > 0; --j) {
4442edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            uint32_t temp = *inYVU_4++;
4452edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            uint32_t tempU = temp & 0xFF;
4462edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            tempU = tempU | ((temp >> 8) & 0xFF00);
4472edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4482edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            uint32_t tempV = (temp >> 8) & 0xFF;
4492edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            tempV = tempV | ((temp >> 16) & 0xFF00);
4502edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4512edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            *outCb++ = tempU;
4522edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            *outCr++ = tempV;
4532edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        }
4542edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
4552edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar}
4562edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4572edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar// static
4582edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnarvoid SoftVideoEncoderOMXComponent::ConvertRGB32ToPlanar(
4592edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        uint8_t *dstY, size_t dstStride, size_t dstVStride,
4602edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        const uint8_t *src, size_t width, size_t height, size_t srcStride,
4612edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        bool bgr) {
4622edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    CHECK((width & 1) == 0);
4632edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    CHECK((height & 1) == 0);
4642edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4652edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    uint8_t *dstU = dstY + dstStride * dstVStride;
4662edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    uint8_t *dstV = dstU + (dstStride >> 1) * (dstVStride >> 1);
4672edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4682edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar#ifdef SURFACE_IS_BGR32
4692edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    bgr = !bgr;
4702edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar#endif
4712edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4722edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    const size_t redOffset   = bgr ? 2 : 0;
4732edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    const size_t greenOffset = 1;
4742edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    const size_t blueOffset  = bgr ? 0 : 2;
4752edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4762edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    for (size_t y = 0; y < height; ++y) {
4772edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        for (size_t x = 0; x < width; ++x) {
4782edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            unsigned red   = src[redOffset];
4792edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            unsigned green = src[greenOffset];
4802edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            unsigned blue  = src[blueOffset];
4812edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4822edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            // using ITU-R BT.601 conversion matrix
4832edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            unsigned luma =
4842edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                ((red * 66 + green * 129 + blue * 25) >> 8) + 16;
4852edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4862edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            dstY[x] = luma;
4872edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4882edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            if ((x & 1) == 0 && (y & 1) == 0) {
4892edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                unsigned U =
4902edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                    ((-red * 38 - green * 74 + blue * 112) >> 8) + 128;
4912edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4922edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                unsigned V =
4932edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                    ((red * 112 - green * 94 - blue * 18) >> 8) + 128;
4942edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4952edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                dstU[x >> 1] = U;
4962edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                dstV[x >> 1] = V;
4972edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            }
4982edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            src += 4;
4992edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        }
5002edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
5012edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        if ((y & 1) == 0) {
5022edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            dstU += dstStride >> 1;
5032edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            dstV += dstStride >> 1;
5042edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        }
5052edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
5062edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        src += srcStride - 4 * width;
5072edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        dstY += dstStride;
5082edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
5092edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar}
5102edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
5112edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnarconst uint8_t *SoftVideoEncoderOMXComponent::extractGraphicBuffer(
5122edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        uint8_t *dst, size_t dstSize,
5132edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        const uint8_t *src, size_t srcSize,
5142edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        size_t width, size_t height) const {
5152edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    size_t dstStride = width;
5162edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    size_t dstVStride = height;
5172edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
5182edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    MetadataBufferType bufferType = *(MetadataBufferType *)src;
519054219874873b41f1c815552987c10465c34ba2bLajos Molnar    bool usingANWBuffer = bufferType == kMetadataBufferTypeANWBuffer;
520054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!usingANWBuffer && bufferType != kMetadataBufferTypeGrallocSource) {
5212edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        ALOGE("Unsupported metadata type (%d)", bufferType);
5222edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        return NULL;
5232edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
5242edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
5252edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    if (mGrallocModule == NULL) {
5262edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        CHECK_EQ(0, hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mGrallocModule));
5272edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
5282edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
5292edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    const gralloc_module_t *grmodule =
5302edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        (const gralloc_module_t *)mGrallocModule;
5312edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
5322edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    buffer_handle_t handle;
5332edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    int format;
5342edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    size_t srcStride;
5352edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    size_t srcVStride;
536054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (usingANWBuffer) {
537054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (srcSize < sizeof(VideoNativeMetadata)) {
538054219874873b41f1c815552987c10465c34ba2bLajos Molnar            ALOGE("Metadata is too small (%zu vs %zu)", srcSize, sizeof(VideoNativeMetadata));
5392edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            return NULL;
5402edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        }
5412edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
542054219874873b41f1c815552987c10465c34ba2bLajos Molnar        VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)src;
543054219874873b41f1c815552987c10465c34ba2bLajos Molnar        ANativeWindowBuffer *buffer = nativeMeta.pBuffer;
5442edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        handle = buffer->handle;
5452edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        format = buffer->format;
5462edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        srcStride = buffer->stride;
5472edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        srcVStride = buffer->height;
5482edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        // convert stride from pixels to bytes
5492edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        if (format != HAL_PIXEL_FORMAT_YV12 &&
5502edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            format != HAL_PIXEL_FORMAT_YCbCr_420_888) {
5512edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            // TODO do we need to support other formats?
5522edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            srcStride *= 4;
5532edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        }
55415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
55515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (nativeMeta.nFenceFd >= 0) {
55615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            sp<Fence> fence = new Fence(nativeMeta.nFenceFd);
55715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            nativeMeta.nFenceFd = -1;
55815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            status_t err = fence->wait(IOMX::kFenceTimeoutMs);
55915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            if (err != OK) {
56015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                ALOGE("Timed out waiting on input fence");
56115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                return NULL;
56215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            }
56315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
5642edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    } else {
5652edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        // TODO: remove this part.  Check if anyone uses this.
5662edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
567054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (srcSize < sizeof(VideoGrallocMetadata)) {
568054219874873b41f1c815552987c10465c34ba2bLajos Molnar            ALOGE("Metadata is too small (%zu vs %zu)", srcSize, sizeof(VideoGrallocMetadata));
5692edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            return NULL;
5702edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        }
5712edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
572054219874873b41f1c815552987c10465c34ba2bLajos Molnar        VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)(src);
5739847fcefb183e1cb09eb48e17a09577392b0e8f4Lajos Molnar        handle = grallocMeta.pHandle;
5742edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        // assume HAL_PIXEL_FORMAT_RGBA_8888
5752edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        // there is no way to get the src stride without the graphic buffer
5762edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        format = HAL_PIXEL_FORMAT_RGBA_8888;
5772edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        srcStride = width * 4;
5782edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        srcVStride = height;
5792edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
5802edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
5812edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    size_t neededSize =
5822edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        dstStride * dstVStride + (width >> 1)
5832edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                + (dstStride >> 1) * ((dstVStride >> 1) + (height >> 1) - 1);
5842edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    if (dstSize < neededSize) {
5852edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        ALOGE("destination buffer is too small (%zu vs %zu)", dstSize, neededSize);
5862edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        return NULL;
5872edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
5882edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
5892edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    void *bits = NULL;
5902edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    struct android_ycbcr ycbcr;
5912edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    status_t res;
5922edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
5932edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        res = grmodule->lock_ycbcr(
5942edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                 grmodule, handle,
5952edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_NEVER,
5962edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                 0, 0, width, height, &ycbcr);
5972edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    } else {
5982edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        res = grmodule->lock(
5992edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                 grmodule, handle,
6002edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_NEVER,
6012edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                 0, 0, width, height, &bits);
6022edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
6032edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    if (res != OK) {
6042edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        ALOGE("Unable to lock image buffer %p for access", handle);
6052edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        return NULL;
6062edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
6072edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
6082edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    switch (format) {
6092edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        case HAL_PIXEL_FORMAT_YV12:  // YCrCb / YVU planar
6102edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            // convert to flex YUV
6112edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.y = bits;
6122edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.cr = (uint8_t *)bits + srcStride * srcVStride;
6132edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.cb = (uint8_t *)ycbcr.cr + (srcStride >> 1) * (srcVStride >> 1);
6142edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.chroma_step = 1;
6152edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.cstride = srcVStride >> 1;
6162edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.ystride = srcVStride;
6172edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ConvertFlexYUVToPlanar(dst, dstStride, dstVStride, &ycbcr, width, height);
6182edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            break;
6192edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        case HAL_PIXEL_FORMAT_YCrCb_420_SP:  // YCrCb / YVU semiplanar, NV21
6202edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            // convert to flex YUV
6212edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.y = bits;
6222edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.cr = (uint8_t *)bits + srcStride * srcVStride;
6232edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.cb = (uint8_t *)ycbcr.cr + 1;
6242edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.chroma_step = 2;
6252edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.cstride = srcVStride;
6262edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.ystride = srcVStride;
6272edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ConvertFlexYUVToPlanar(dst, dstStride, dstVStride, &ycbcr, width, height);
6282edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            break;
6292edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        case HAL_PIXEL_FORMAT_YCbCr_420_888:
6302edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ConvertFlexYUVToPlanar(dst, dstStride, dstVStride, &ycbcr, width, height);
6312edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            break;
6322edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        case HAL_PIXEL_FORMAT_RGBA_8888:
6332edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        case HAL_PIXEL_FORMAT_BGRA_8888:
6342edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ConvertRGB32ToPlanar(
6352edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                    dst, dstStride, dstVStride,
6362edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                    (const uint8_t *)bits, width, height, srcStride,
6372edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                    format == HAL_PIXEL_FORMAT_BGRA_8888);
6382edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            break;
6392edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        default:
6402edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ALOGE("Unsupported pixel format %#x", format);
6412edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            dst = NULL;
6422edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            break;
6432edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
6442edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
6452edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    if (grmodule->unlock(grmodule, handle) != OK) {
6462edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        ALOGE("Unable to unlock image buffer %p for access", handle);
6472edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
6482edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
6492edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    return dst;
6502edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar}
6512edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
6522edda09a2ad1d112c52acd37d323f63f0a492d67Lajos MolnarOMX_ERRORTYPE SoftVideoEncoderOMXComponent::getExtensionIndex(
6532edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        const char *name, OMX_INDEXTYPE *index) {
6542edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    if (!strcmp(name, "OMX.google.android.index.storeMetaDataInBuffers") ||
655054219874873b41f1c815552987c10465c34ba2bLajos Molnar        !strcmp(name, "OMX.google.android.index.storeANWBufferInMetadata")) {
6562edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        *(int32_t*)index = kStoreMetaDataExtensionIndex;
6572edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        return OMX_ErrorNone;
6582edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
6592edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    return SimpleSoftOMXComponent::getExtensionIndex(name, index);
6602edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar}
6612edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
6622edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar}  // namespace android
663