[go: nahoru, domu]

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 <media/hardware/HardwareAPI.h>
272edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar#include <media/stagefright/foundation/ADebug.h>
282edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar#include <media/stagefright/foundation/ALooper.h>
292edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar#include <media/stagefright/foundation/AMessage.h>
30a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar#include <media/stagefright/foundation/AUtils.h>
312edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar#include <media/stagefright/MediaDefs.h>
322edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
332edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar#include <ui/GraphicBuffer.h>
342edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar#include <ui/GraphicBufferMapper.h>
352edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
36c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar#include <OMX_IndexExt.h>
37c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
382edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnarnamespace android {
392edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
40a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnarconst static OMX_COLOR_FORMATTYPE kSupportedColorFormats[] = {
41a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    OMX_COLOR_FormatYUV420Planar,
42a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    OMX_COLOR_FormatYUV420SemiPlanar,
43a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    OMX_COLOR_FormatAndroidOpaque
44a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar};
45a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
46a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnartemplate<class T>
47a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnarstatic void InitOMXParams(T *params) {
48a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    params->nSize = sizeof(T);
49a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    params->nVersion.s.nVersionMajor = 1;
50a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    params->nVersion.s.nVersionMinor = 0;
51a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    params->nVersion.s.nRevision = 0;
52a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    params->nVersion.s.nStep = 0;
53a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar}
54a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
552edda09a2ad1d112c52acd37d323f63f0a492d67Lajos MolnarSoftVideoEncoderOMXComponent::SoftVideoEncoderOMXComponent(
562edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        const char *name,
57a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        const char *componentRole,
58a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        OMX_VIDEO_CODINGTYPE codingType,
59a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        const CodecProfileLevel *profileLevels,
60a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        size_t numProfileLevels,
61a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        int32_t width,
62a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        int32_t height,
632edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        const OMX_CALLBACKTYPE *callbacks,
642edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        OMX_PTR appData,
652edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        OMX_COMPONENTTYPE **component)
662edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    : SimpleSoftOMXComponent(name, callbacks, appData, component),
67a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mInputDataIsMeta(false),
68a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mWidth(width),
69a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mHeight(height),
70a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mBitrate(192000),
71a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mFramerate(30 << 16), // Q16 format
72a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mColorFormat(OMX_COLOR_FormatYUV420Planar),
73a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mMinOutputBufferSize(384), // arbitrary, using one uncompressed macroblock
74a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mMinCompressionRatio(1),   // max output size is normally the input size
75a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mComponentRole(componentRole),
76a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mCodingType(codingType),
77a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mProfileLevels(profileLevels),
78a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mNumProfileLevels(numProfileLevels) {
79a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar}
80a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
81a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnarvoid SoftVideoEncoderOMXComponent::initPorts(
82a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        OMX_U32 numInputBuffers, OMX_U32 numOutputBuffers, OMX_U32 outputBufferSize,
83a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        const char *mime, OMX_U32 minCompressionRatio) {
84a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
85a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
86a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    mMinOutputBufferSize = outputBufferSize;
87a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    mMinCompressionRatio = minCompressionRatio;
88a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
89a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    InitOMXParams(&def);
90a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
91a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.nPortIndex = kInputPortIndex;
92a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.eDir = OMX_DirInput;
93a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.nBufferCountMin = numInputBuffers;
94a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.nBufferCountActual = def.nBufferCountMin;
95a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.bEnabled = OMX_TRUE;
96a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.bPopulated = OMX_FALSE;
97a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.eDomain = OMX_PortDomainVideo;
98a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.bBuffersContiguous = OMX_FALSE;
99a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.pNativeRender = NULL;
100a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.nFrameWidth = mWidth;
101a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.nFrameHeight = mHeight;
102a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.nStride = def.format.video.nFrameWidth;
103a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.nSliceHeight = def.format.video.nFrameHeight;
104a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.nBitrate = 0;
105a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    // frameRate is in Q16 format.
106a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.xFramerate = mFramerate;
107a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.bFlagErrorConcealment = OMX_FALSE;
108a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.nBufferAlignment = kInputBufferAlignment;
109a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.cMIMEType = const_cast<char *>("video/raw");
110a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
111a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.eColorFormat = mColorFormat;
112a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.pNativeWindow = NULL;
113a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    // buffersize set in updatePortParams
114a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
115a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    addPort(def);
116a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
117a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    InitOMXParams(&def);
118a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
119a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.nPortIndex = kOutputPortIndex;
120a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.eDir = OMX_DirOutput;
121a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.nBufferCountMin = numOutputBuffers;
122a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.nBufferCountActual = def.nBufferCountMin;
123a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.bEnabled = OMX_TRUE;
124a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.bPopulated = OMX_FALSE;
125a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.eDomain = OMX_PortDomainVideo;
126a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.bBuffersContiguous = OMX_FALSE;
127a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.pNativeRender = NULL;
128a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.nFrameWidth = mWidth;
129a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.nFrameHeight = mHeight;
130a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.nStride = 0;
131a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.nSliceHeight = 0;
132a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.nBitrate = mBitrate;
133a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.xFramerate = 0 << 16;
134a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.bFlagErrorConcealment = OMX_FALSE;
135a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.nBufferAlignment = kOutputBufferAlignment;
136a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.cMIMEType = const_cast<char *>(mime);
137a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.eCompressionFormat = mCodingType;
138a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.eColorFormat = OMX_COLOR_FormatUnused;
139a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    def.format.video.pNativeWindow = NULL;
140a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    // buffersize set in updatePortParams
141a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
142a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    addPort(def);
143a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
144a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    updatePortParams();
145a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar}
146a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
147a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnarvoid SoftVideoEncoderOMXComponent::updatePortParams() {
148a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE *inDef = &editPortInfo(kInputPortIndex)->mDef;
149a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    inDef->format.video.nFrameWidth = mWidth;
150a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    inDef->format.video.nFrameHeight = mHeight;
151a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    inDef->format.video.nStride = inDef->format.video.nFrameWidth;
152a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    inDef->format.video.nSliceHeight = inDef->format.video.nFrameHeight;
153a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    inDef->format.video.xFramerate = mFramerate;
154a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    inDef->format.video.eColorFormat = mColorFormat;
155a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    uint32_t rawBufferSize =
156a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        inDef->format.video.nStride * inDef->format.video.nSliceHeight * 3 / 2;
157a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    if (inDef->format.video.eColorFormat == OMX_COLOR_FormatAndroidOpaque) {
158054219874873b41f1c815552987c10465c34ba2bLajos Molnar        inDef->nBufferSize = max(sizeof(VideoNativeMetadata), sizeof(VideoGrallocMetadata));
159a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    } else {
160a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        inDef->nBufferSize = rawBufferSize;
161a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    }
162a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
163a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE *outDef = &editPortInfo(kOutputPortIndex)->mDef;
164a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    outDef->format.video.nFrameWidth = mWidth;
165a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    outDef->format.video.nFrameHeight = mHeight;
166a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    outDef->format.video.nBitrate = mBitrate;
167a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
168a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    outDef->nBufferSize = max(mMinOutputBufferSize, rawBufferSize / mMinCompressionRatio);
169a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar}
170a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
171a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos MolnarOMX_ERRORTYPE SoftVideoEncoderOMXComponent::internalSetPortParams(
172a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        const OMX_PARAM_PORTDEFINITIONTYPE *port) {
173a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen
174a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen    if (!isValidOMXParam(port)) {
175a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen        return OMX_ErrorBadParameter;
176a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen    }
177a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen
178a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    if (port->nPortIndex == kInputPortIndex) {
179a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        mWidth = port->format.video.nFrameWidth;
180a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        mHeight = port->format.video.nFrameHeight;
181a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
182a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        // xFramerate comes in Q16 format, in frames per second unit
183a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        mFramerate = port->format.video.xFramerate;
184a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
185a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        if (port->format.video.eCompressionFormat != OMX_VIDEO_CodingUnused
186a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                || (port->format.video.eColorFormat != OMX_COLOR_FormatYUV420Planar
187a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                        && port->format.video.eColorFormat != OMX_COLOR_FormatYUV420SemiPlanar
188a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                        && port->format.video.eColorFormat != OMX_COLOR_FormatAndroidOpaque)) {
189a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return OMX_ErrorUnsupportedSetting;
190a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
191a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
192a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        mColorFormat = port->format.video.eColorFormat;
193a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    } else if (port->nPortIndex == kOutputPortIndex) {
194a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        if (port->format.video.eCompressionFormat != mCodingType
195a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                || port->format.video.eColorFormat != OMX_COLOR_FormatUnused) {
196a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return OMX_ErrorUnsupportedSetting;
197a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
198a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
199a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        mBitrate = port->format.video.nBitrate;
200a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    } else {
201a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        return OMX_ErrorBadPortIndex;
202a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    }
203a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
204a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    updatePortParams();
205a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    return OMX_ErrorNone;
206a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar}
207a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
208a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos MolnarOMX_ERRORTYPE SoftVideoEncoderOMXComponent::internalSetParameter(
209a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        OMX_INDEXTYPE index, const OMX_PTR param) {
210a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    // can include extension index OMX_INDEXEXTTYPE
211a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    const int32_t indexFull = index;
212a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
213a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    switch (indexFull) {
214a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        case OMX_IndexParamVideoErrorCorrection:
215a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        {
216a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return OMX_ErrorNotImplemented;
217a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
218a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
219a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        case OMX_IndexParamStandardComponentRole:
220a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        {
221a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            const OMX_PARAM_COMPONENTROLETYPE *roleParams =
222a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                (const OMX_PARAM_COMPONENTROLETYPE *)param;
223a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
224a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen            if (!isValidOMXParam(roleParams)) {
225a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen                return OMX_ErrorBadParameter;
226a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen            }
227a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen
228a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (strncmp((const char *)roleParams->cRole,
229a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                        mComponentRole,
230a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                        OMX_MAX_STRINGNAME_SIZE - 1)) {
231a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return OMX_ErrorUnsupportedSetting;
232a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            }
233a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
234a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return OMX_ErrorNone;
235a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
236a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
237a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        case OMX_IndexParamPortDefinition:
238a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        {
239a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            OMX_ERRORTYPE err = internalSetPortParams((const OMX_PARAM_PORTDEFINITIONTYPE *)param);
240a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
241a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (err != OMX_ErrorNone) {
242a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return err;
243a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            }
244a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
245a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return SimpleSoftOMXComponent::internalSetParameter(index, param);
246a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
247a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
248a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        case OMX_IndexParamVideoPortFormat:
249a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        {
250a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            const OMX_VIDEO_PARAM_PORTFORMATTYPE* format =
251a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                (const OMX_VIDEO_PARAM_PORTFORMATTYPE *)param;
252a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
253a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen            if (!isValidOMXParam(format)) {
254a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen                return OMX_ErrorBadParameter;
255a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen            }
256a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen
257a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (format->nPortIndex == kInputPortIndex) {
258a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                if (format->eColorFormat == OMX_COLOR_FormatYUV420Planar ||
259a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    format->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar ||
260a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    format->eColorFormat == OMX_COLOR_FormatAndroidOpaque) {
261a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    mColorFormat = format->eColorFormat;
262a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
263a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    updatePortParams();
264a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    return OMX_ErrorNone;
265a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                } else {
266a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    ALOGE("Unsupported color format %i", format->eColorFormat);
267a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    return OMX_ErrorUnsupportedSetting;
268a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                }
269a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            } else if (format->nPortIndex == kOutputPortIndex) {
270a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                if (format->eCompressionFormat == mCodingType) {
271a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    return OMX_ErrorNone;
272a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                } else {
273a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    return OMX_ErrorUnsupportedSetting;
274a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                }
275a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            } else {
276a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return OMX_ErrorBadPortIndex;
277a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            }
278a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
279a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
280a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        case kStoreMetaDataExtensionIndex:
281a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        {
282a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            // storeMetaDataInBuffers
283a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            const StoreMetaDataInBuffersParams *storeParam =
284a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                (const StoreMetaDataInBuffersParams *)param;
285a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
286a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen            if (!isValidOMXParam(storeParam)) {
287a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen                return OMX_ErrorBadParameter;
288a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen            }
289a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen
290a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (storeParam->nPortIndex == kOutputPortIndex) {
291a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return storeParam->bStoreMetaData ? OMX_ErrorUnsupportedSetting : OMX_ErrorNone;
292a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            } else if (storeParam->nPortIndex != kInputPortIndex) {
293a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return OMX_ErrorBadPortIndex;
294a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            }
295a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
296a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            mInputDataIsMeta = (storeParam->bStoreMetaData == OMX_TRUE);
297a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (mInputDataIsMeta) {
298a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                mColorFormat = OMX_COLOR_FormatAndroidOpaque;
299a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            } else if (mColorFormat == OMX_COLOR_FormatAndroidOpaque) {
300a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                mColorFormat = OMX_COLOR_FormatYUV420Planar;
301a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            }
302a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            updatePortParams();
303a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return OMX_ErrorNone;
304a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
305a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
306a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        default:
307a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return SimpleSoftOMXComponent::internalSetParameter(index, param);
308a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    }
309a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar}
310a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
311a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos MolnarOMX_ERRORTYPE SoftVideoEncoderOMXComponent::internalGetParameter(
312a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        OMX_INDEXTYPE index, OMX_PTR param) {
313c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    switch ((int)index) {
314a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        case OMX_IndexParamVideoErrorCorrection:
315a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        {
316a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return OMX_ErrorNotImplemented;
317a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
318a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
319a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        case OMX_IndexParamVideoPortFormat:
320a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        {
321a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams =
322a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                (OMX_VIDEO_PARAM_PORTFORMATTYPE *)param;
323a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
324a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen            if (!isValidOMXParam(formatParams)) {
325a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen                return OMX_ErrorBadParameter;
326a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen            }
327a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen
328a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (formatParams->nPortIndex == kInputPortIndex) {
329a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                if (formatParams->nIndex >= NELEM(kSupportedColorFormats)) {
330a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    return OMX_ErrorNoMore;
331a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                }
332a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
333a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                // Color formats, in order of preference
334a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                formatParams->eColorFormat = kSupportedColorFormats[formatParams->nIndex];
335a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                formatParams->eCompressionFormat = OMX_VIDEO_CodingUnused;
336a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                formatParams->xFramerate = mFramerate;
337a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return OMX_ErrorNone;
338a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            } else if (formatParams->nPortIndex == kOutputPortIndex) {
339a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                formatParams->eCompressionFormat = mCodingType;
340a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                formatParams->eColorFormat = OMX_COLOR_FormatUnused;
341a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                formatParams->xFramerate = 0;
342a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return OMX_ErrorNone;
343a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            } else {
344a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return OMX_ErrorBadPortIndex;
345a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            }
346a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
347a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
348a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        case OMX_IndexParamVideoProfileLevelQuerySupported:
349a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        {
350a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevel =
351a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                  (OMX_VIDEO_PARAM_PROFILELEVELTYPE *) param;
352a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
353a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen            if (!isValidOMXParam(profileLevel)) {
354a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen                return OMX_ErrorBadParameter;
355a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen            }
356a21bed3d626d148e584bdddeeecf287b782b3fcbMarco Nelissen
357a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (profileLevel->nPortIndex != kOutputPortIndex) {
358a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                ALOGE("Invalid port index: %u", profileLevel->nPortIndex);
359a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return OMX_ErrorUnsupportedIndex;
360a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            }
361a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
362a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (profileLevel->nProfileIndex >= mNumProfileLevels) {
363a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return OMX_ErrorNoMore;
364a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            }
365a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
366a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            profileLevel->eProfile = mProfileLevels[profileLevel->nProfileIndex].mProfile;
367a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            profileLevel->eLevel   = mProfileLevels[profileLevel->nProfileIndex].mLevel;
368a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return OMX_ErrorNone;
369a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
370a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
371c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        case OMX_IndexParamConsumerUsageBits:
372c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        {
373c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            OMX_U32 *usageBits = (OMX_U32 *)param;
374c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            *usageBits = GRALLOC_USAGE_SW_READ_OFTEN;
375c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            return OMX_ErrorNone;
376c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        }
377c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
378a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        default:
379a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return SimpleSoftOMXComponent::internalGetParameter(index, param);
380a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    }
3812edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar}
3822edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
3832edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar// static
38492f9f71ee45a260aed552c18ac5112f7672859edChad Brubaker__attribute__((no_sanitize("integer")))
3852edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnarvoid SoftVideoEncoderOMXComponent::ConvertFlexYUVToPlanar(
3862edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        uint8_t *dst, size_t dstStride, size_t dstVStride,
3872edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        struct android_ycbcr *ycbcr, int32_t width, int32_t height) {
3882edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    const uint8_t *src = (const uint8_t *)ycbcr->y;
3892edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    const uint8_t *srcU = (const uint8_t *)ycbcr->cb;
3902edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    const uint8_t *srcV = (const uint8_t *)ycbcr->cr;
3912edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    uint8_t *dstU = dst + dstVStride * dstStride;
3922edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    uint8_t *dstV = dstU + (dstVStride >> 1) * (dstStride >> 1);
3932edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
3942edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    for (size_t y = height; y > 0; --y) {
3952edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        memcpy(dst, src, width);
3962edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        dst += dstStride;
3972edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        src += ycbcr->ystride;
3982edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
3992edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    if (ycbcr->cstride == ycbcr->ystride >> 1 && ycbcr->chroma_step == 1) {
4002edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        // planar
4012edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        for (size_t y = height >> 1; y > 0; --y) {
4022edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            memcpy(dstU, srcU, width >> 1);
4032edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            dstU += dstStride >> 1;
4042edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            srcU += ycbcr->cstride;
4052edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            memcpy(dstV, srcV, width >> 1);
4062edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            dstV += dstStride >> 1;
4072edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            srcV += ycbcr->cstride;
4082edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        }
4092edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    } else {
4102edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        // arbitrary
4112edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        for (size_t y = height >> 1; y > 0; --y) {
4122edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            for (size_t x = width >> 1; x > 0; --x) {
4132edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                *dstU++ = *srcU;
4142edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                *dstV++ = *srcV;
4152edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                srcU += ycbcr->chroma_step;
4162edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                srcV += ycbcr->chroma_step;
4172edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            }
4182edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            dstU += (dstStride >> 1) - (width >> 1);
4192edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            dstV += (dstStride >> 1) - (width >> 1);
4202edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            srcU += ycbcr->cstride - (width >> 1) * ycbcr->chroma_step;
4212edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            srcV += ycbcr->cstride - (width >> 1) * ycbcr->chroma_step;
4222edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        }
4232edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
4242edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar}
4252edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4262edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar// static
42792f9f71ee45a260aed552c18ac5112f7672859edChad Brubaker__attribute__((no_sanitize("integer")))
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
45892f9f71ee45a260aed552c18ac5112f7672859edChad Brubaker__attribute__((no_sanitize("integer")))
4592edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnarvoid SoftVideoEncoderOMXComponent::ConvertRGB32ToPlanar(
4602edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        uint8_t *dstY, size_t dstStride, size_t dstVStride,
4612edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        const uint8_t *src, size_t width, size_t height, size_t srcStride,
4622edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        bool bgr) {
4632edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    CHECK((width & 1) == 0);
4642edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    CHECK((height & 1) == 0);
4652edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4662edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    uint8_t *dstU = dstY + dstStride * dstVStride;
4672edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    uint8_t *dstV = dstU + (dstStride >> 1) * (dstVStride >> 1);
4682edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4692edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar#ifdef SURFACE_IS_BGR32
4702edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    bgr = !bgr;
4712edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar#endif
4722edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4732edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    const size_t redOffset   = bgr ? 2 : 0;
4742edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    const size_t greenOffset = 1;
4752edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    const size_t blueOffset  = bgr ? 0 : 2;
4762edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4772edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    for (size_t y = 0; y < height; ++y) {
4782edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        for (size_t x = 0; x < width; ++x) {
4792edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            unsigned red   = src[redOffset];
4802edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            unsigned green = src[greenOffset];
4812edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            unsigned blue  = src[blueOffset];
4822edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4832edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            // using ITU-R BT.601 conversion matrix
4842edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            unsigned luma =
4852edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                ((red * 66 + green * 129 + blue * 25) >> 8) + 16;
4862edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4872edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            dstY[x] = luma;
4882edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4892edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            if ((x & 1) == 0 && (y & 1) == 0) {
4902edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                unsigned U =
4912edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                    ((-red * 38 - green * 74 + blue * 112) >> 8) + 128;
4922edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4932edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                unsigned V =
4942edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                    ((red * 112 - green * 94 - blue * 18) >> 8) + 128;
4952edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4962edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                dstU[x >> 1] = U;
4972edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                dstV[x >> 1] = V;
4982edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            }
4992edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            src += 4;
5002edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        }
5012edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
5022edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        if ((y & 1) == 0) {
5032edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            dstU += dstStride >> 1;
5042edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            dstV += dstStride >> 1;
5052edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        }
5062edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
5072edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        src += srcStride - 4 * width;
5082edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        dstY += dstStride;
5092edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
5102edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar}
5112edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
5122edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnarconst uint8_t *SoftVideoEncoderOMXComponent::extractGraphicBuffer(
5132edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        uint8_t *dst, size_t dstSize,
5142edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        const uint8_t *src, size_t srcSize,
5152edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        size_t width, size_t height) const {
5162edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    size_t dstStride = width;
5172edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    size_t dstVStride = height;
5182edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
5192edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    MetadataBufferType bufferType = *(MetadataBufferType *)src;
520054219874873b41f1c815552987c10465c34ba2bLajos Molnar    bool usingANWBuffer = bufferType == kMetadataBufferTypeANWBuffer;
521054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!usingANWBuffer && bufferType != kMetadataBufferTypeGrallocSource) {
5222edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        ALOGE("Unsupported metadata type (%d)", bufferType);
5232edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        return NULL;
5242edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
5252edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
5262edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    buffer_handle_t handle;
5272edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    int format;
5282edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    size_t srcStride;
5292edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    size_t srcVStride;
530054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (usingANWBuffer) {
531054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (srcSize < sizeof(VideoNativeMetadata)) {
532054219874873b41f1c815552987c10465c34ba2bLajos Molnar            ALOGE("Metadata is too small (%zu vs %zu)", srcSize, sizeof(VideoNativeMetadata));
5332edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            return NULL;
5342edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        }
5352edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
536054219874873b41f1c815552987c10465c34ba2bLajos Molnar        VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)src;
537054219874873b41f1c815552987c10465c34ba2bLajos Molnar        ANativeWindowBuffer *buffer = nativeMeta.pBuffer;
5382edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        handle = buffer->handle;
5392edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        format = buffer->format;
5402edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        srcStride = buffer->stride;
5412edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        srcVStride = buffer->height;
5422edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        // convert stride from pixels to bytes
5432edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        if (format != HAL_PIXEL_FORMAT_YV12 &&
5442edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            format != HAL_PIXEL_FORMAT_YCbCr_420_888) {
5452edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            // TODO do we need to support other formats?
5462edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            srcStride *= 4;
5472edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        }
54815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
54915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (nativeMeta.nFenceFd >= 0) {
55015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            sp<Fence> fence = new Fence(nativeMeta.nFenceFd);
55115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            nativeMeta.nFenceFd = -1;
55215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            status_t err = fence->wait(IOMX::kFenceTimeoutMs);
55315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            if (err != OK) {
55415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                ALOGE("Timed out waiting on input fence");
55515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                return NULL;
55615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            }
55715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
5582edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    } else {
5592edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        // TODO: remove this part.  Check if anyone uses this.
5602edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
561054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (srcSize < sizeof(VideoGrallocMetadata)) {
562054219874873b41f1c815552987c10465c34ba2bLajos Molnar            ALOGE("Metadata is too small (%zu vs %zu)", srcSize, sizeof(VideoGrallocMetadata));
5632edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            return NULL;
5642edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        }
5652edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
566054219874873b41f1c815552987c10465c34ba2bLajos Molnar        VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)(src);
5679847fcefb183e1cb09eb48e17a09577392b0e8f4Lajos Molnar        handle = grallocMeta.pHandle;
5682edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        // assume HAL_PIXEL_FORMAT_RGBA_8888
5692edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        // there is no way to get the src stride without the graphic buffer
5702edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        format = HAL_PIXEL_FORMAT_RGBA_8888;
5712edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        srcStride = width * 4;
5722edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        srcVStride = height;
5732edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
5742edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
5752edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    size_t neededSize =
5762edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        dstStride * dstVStride + (width >> 1)
5772edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                + (dstStride >> 1) * ((dstVStride >> 1) + (height >> 1) - 1);
5782edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    if (dstSize < neededSize) {
5792edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        ALOGE("destination buffer is too small (%zu vs %zu)", dstSize, neededSize);
5802edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        return NULL;
5812edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
5822edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
583fe7df6220dbdd2ada97bf195c542c5e399695ed0Dan Stoza    auto& mapper = GraphicBufferMapper::get();
584fe7df6220dbdd2ada97bf195c542c5e399695ed0Dan Stoza
5852edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    void *bits = NULL;
5862edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    struct android_ycbcr ycbcr;
5872edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    status_t res;
5882edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
589fe7df6220dbdd2ada97bf195c542c5e399695ed0Dan Stoza        res = mapper.lockYCbCr(
590fe7df6220dbdd2ada97bf195c542c5e399695ed0Dan Stoza                 handle,
5912edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_NEVER,
592fe7df6220dbdd2ada97bf195c542c5e399695ed0Dan Stoza                 Rect(width, height), &ycbcr);
5932edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    } else {
594fe7df6220dbdd2ada97bf195c542c5e399695ed0Dan Stoza        res = mapper.lock(
595fe7df6220dbdd2ada97bf195c542c5e399695ed0Dan Stoza                 handle,
5962edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_NEVER,
597fe7df6220dbdd2ada97bf195c542c5e399695ed0Dan Stoza                 Rect(width, height), &bits);
5982edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
5992edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    if (res != OK) {
6002edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        ALOGE("Unable to lock image buffer %p for access", handle);
6012edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        return NULL;
6022edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
6032edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
6042edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    switch (format) {
6052edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        case HAL_PIXEL_FORMAT_YV12:  // YCrCb / YVU planar
6062edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            // convert to flex YUV
6072edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.y = bits;
6082edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.cr = (uint8_t *)bits + srcStride * srcVStride;
6092edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.cb = (uint8_t *)ycbcr.cr + (srcStride >> 1) * (srcVStride >> 1);
6102edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.chroma_step = 1;
6112edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.cstride = srcVStride >> 1;
6122edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.ystride = srcVStride;
6132edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ConvertFlexYUVToPlanar(dst, dstStride, dstVStride, &ycbcr, width, height);
6142edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            break;
6152edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        case HAL_PIXEL_FORMAT_YCrCb_420_SP:  // YCrCb / YVU semiplanar, NV21
6162edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            // convert to flex YUV
6172edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.y = bits;
6182edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.cr = (uint8_t *)bits + srcStride * srcVStride;
6192edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.cb = (uint8_t *)ycbcr.cr + 1;
6202edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.chroma_step = 2;
6212edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.cstride = srcVStride;
6222edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.ystride = srcVStride;
6232edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ConvertFlexYUVToPlanar(dst, dstStride, dstVStride, &ycbcr, width, height);
6242edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            break;
6252edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        case HAL_PIXEL_FORMAT_YCbCr_420_888:
6262edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ConvertFlexYUVToPlanar(dst, dstStride, dstVStride, &ycbcr, width, height);
6272edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            break;
628075999616e5764462316f31ce628146c1174b1d5Justin Chuang        case HAL_PIXEL_FORMAT_RGBX_8888:
6292edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        case HAL_PIXEL_FORMAT_RGBA_8888:
6302edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        case HAL_PIXEL_FORMAT_BGRA_8888:
6312edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ConvertRGB32ToPlanar(
6322edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                    dst, dstStride, dstVStride,
6332edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                    (const uint8_t *)bits, width, height, srcStride,
6342edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                    format == HAL_PIXEL_FORMAT_BGRA_8888);
6352edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            break;
6362edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        default:
6372edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ALOGE("Unsupported pixel format %#x", format);
6382edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            dst = NULL;
6392edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            break;
6402edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
6412edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
642fe7df6220dbdd2ada97bf195c542c5e399695ed0Dan Stoza    if (mapper.unlock(handle) != OK) {
6432edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        ALOGE("Unable to unlock image buffer %p for access", handle);
6442edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
6452edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
6462edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    return dst;
6472edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar}
6482edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
6492edda09a2ad1d112c52acd37d323f63f0a492d67Lajos MolnarOMX_ERRORTYPE SoftVideoEncoderOMXComponent::getExtensionIndex(
6502edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        const char *name, OMX_INDEXTYPE *index) {
6512edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    if (!strcmp(name, "OMX.google.android.index.storeMetaDataInBuffers") ||
652054219874873b41f1c815552987c10465c34ba2bLajos Molnar        !strcmp(name, "OMX.google.android.index.storeANWBufferInMetadata")) {
6532edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        *(int32_t*)index = kStoreMetaDataExtensionIndex;
6542edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        return OMX_ErrorNone;
6552edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
6562edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    return SimpleSoftOMXComponent::getExtensionIndex(name, index);
6572edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar}
6582edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
6592edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar}  // namespace android
660