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
372edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnarnamespace android {
382edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
39a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnarconst static OMX_COLOR_FORMATTYPE kSupportedColorFormats[] = {
40a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    OMX_COLOR_FormatYUV420Planar,
41a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    OMX_COLOR_FormatYUV420SemiPlanar,
42a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    OMX_COLOR_FormatAndroidOpaque
43a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar};
44a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
45a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnartemplate<class T>
46a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnarstatic void InitOMXParams(T *params) {
47a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    params->nSize = sizeof(T);
48a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    params->nVersion.s.nVersionMajor = 1;
49a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    params->nVersion.s.nVersionMinor = 0;
50a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    params->nVersion.s.nRevision = 0;
51a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    params->nVersion.s.nStep = 0;
52a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar}
53a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
542edda09a2ad1d112c52acd37d323f63f0a492d67Lajos MolnarSoftVideoEncoderOMXComponent::SoftVideoEncoderOMXComponent(
552edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        const char *name,
56a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        const char *componentRole,
57a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        OMX_VIDEO_CODINGTYPE codingType,
58a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        const CodecProfileLevel *profileLevels,
59a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        size_t numProfileLevels,
60a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        int32_t width,
61a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        int32_t height,
622edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        const OMX_CALLBACKTYPE *callbacks,
632edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        OMX_PTR appData,
642edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        OMX_COMPONENTTYPE **component)
652edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    : SimpleSoftOMXComponent(name, callbacks, appData, component),
66a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mInputDataIsMeta(false),
67a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mWidth(width),
68a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mHeight(height),
69a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mBitrate(192000),
70a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mFramerate(30 << 16), // Q16 format
71a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mColorFormat(OMX_COLOR_FormatYUV420Planar),
72a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar      mGrallocModule(NULL),
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) {
158a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        inDef->nBufferSize = 4 + max(sizeof(buffer_handle_t), sizeof(GraphicBuffer *));
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) {
173a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    if (port->nPortIndex == kInputPortIndex) {
174a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        mWidth = port->format.video.nFrameWidth;
175a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        mHeight = port->format.video.nFrameHeight;
176a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
177a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        // xFramerate comes in Q16 format, in frames per second unit
178a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        mFramerate = port->format.video.xFramerate;
179a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
180a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        if (port->format.video.eCompressionFormat != OMX_VIDEO_CodingUnused
181a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                || (port->format.video.eColorFormat != OMX_COLOR_FormatYUV420Planar
182a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                        && port->format.video.eColorFormat != OMX_COLOR_FormatYUV420SemiPlanar
183a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                        && port->format.video.eColorFormat != OMX_COLOR_FormatAndroidOpaque)) {
184a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return OMX_ErrorUnsupportedSetting;
185a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
186a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
187a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        mColorFormat = port->format.video.eColorFormat;
188a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    } else if (port->nPortIndex == kOutputPortIndex) {
189a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        if (port->format.video.eCompressionFormat != mCodingType
190a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                || port->format.video.eColorFormat != OMX_COLOR_FormatUnused) {
191a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return OMX_ErrorUnsupportedSetting;
192a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
193a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
194a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        mBitrate = port->format.video.nBitrate;
195a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    } else {
196a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        return OMX_ErrorBadPortIndex;
197a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    }
198a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
199a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    updatePortParams();
200a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    return OMX_ErrorNone;
201a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar}
202a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
203a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos MolnarOMX_ERRORTYPE SoftVideoEncoderOMXComponent::internalSetParameter(
204a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        OMX_INDEXTYPE index, const OMX_PTR param) {
205a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    // can include extension index OMX_INDEXEXTTYPE
206a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    const int32_t indexFull = index;
207a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
208a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    switch (indexFull) {
209a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        case OMX_IndexParamVideoErrorCorrection:
210a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        {
211a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return OMX_ErrorNotImplemented;
212a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
213a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
214a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        case OMX_IndexParamStandardComponentRole:
215a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        {
216a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            const OMX_PARAM_COMPONENTROLETYPE *roleParams =
217a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                (const OMX_PARAM_COMPONENTROLETYPE *)param;
218a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
219a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (strncmp((const char *)roleParams->cRole,
220a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                        mComponentRole,
221a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                        OMX_MAX_STRINGNAME_SIZE - 1)) {
222a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return OMX_ErrorUnsupportedSetting;
223a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            }
224a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
225a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return OMX_ErrorNone;
226a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
227a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
228a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        case OMX_IndexParamPortDefinition:
229a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        {
230a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            OMX_ERRORTYPE err = internalSetPortParams((const OMX_PARAM_PORTDEFINITIONTYPE *)param);
231a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
232a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (err != OMX_ErrorNone) {
233a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return err;
234a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            }
235a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
236a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return SimpleSoftOMXComponent::internalSetParameter(index, param);
237a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
238a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
239a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        case OMX_IndexParamVideoPortFormat:
240a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        {
241a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            const OMX_VIDEO_PARAM_PORTFORMATTYPE* format =
242a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                (const OMX_VIDEO_PARAM_PORTFORMATTYPE *)param;
243a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
244a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (format->nPortIndex == kInputPortIndex) {
245a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                if (format->eColorFormat == OMX_COLOR_FormatYUV420Planar ||
246a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    format->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar ||
247a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    format->eColorFormat == OMX_COLOR_FormatAndroidOpaque) {
248a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    mColorFormat = format->eColorFormat;
249a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
250a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    updatePortParams();
251a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    return OMX_ErrorNone;
252a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                } else {
253a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    ALOGE("Unsupported color format %i", format->eColorFormat);
254a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    return OMX_ErrorUnsupportedSetting;
255a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                }
256a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            } else if (format->nPortIndex == kOutputPortIndex) {
257a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                if (format->eCompressionFormat == mCodingType) {
258a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    return OMX_ErrorNone;
259a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                } else {
260a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    return OMX_ErrorUnsupportedSetting;
261a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                }
262a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            } else {
263a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return OMX_ErrorBadPortIndex;
264a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            }
265a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
266a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
267a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        case kStoreMetaDataExtensionIndex:
268a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        {
269a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            // storeMetaDataInBuffers
270a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            const StoreMetaDataInBuffersParams *storeParam =
271a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                (const StoreMetaDataInBuffersParams *)param;
272a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
273a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (storeParam->nPortIndex == kOutputPortIndex) {
274a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return storeParam->bStoreMetaData ? OMX_ErrorUnsupportedSetting : OMX_ErrorNone;
275a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            } else if (storeParam->nPortIndex != kInputPortIndex) {
276a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return OMX_ErrorBadPortIndex;
277a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            }
278a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
279a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            mInputDataIsMeta = (storeParam->bStoreMetaData == OMX_TRUE);
280a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (mInputDataIsMeta) {
281a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                mColorFormat = OMX_COLOR_FormatAndroidOpaque;
282a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            } else if (mColorFormat == OMX_COLOR_FormatAndroidOpaque) {
283a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                mColorFormat = OMX_COLOR_FormatYUV420Planar;
284a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            }
285a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            updatePortParams();
286a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return OMX_ErrorNone;
287a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
288a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
289a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        default:
290a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return SimpleSoftOMXComponent::internalSetParameter(index, param);
291a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    }
292a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar}
293a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
294a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos MolnarOMX_ERRORTYPE SoftVideoEncoderOMXComponent::internalGetParameter(
295a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        OMX_INDEXTYPE index, OMX_PTR param) {
296a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    switch (index) {
297a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        case OMX_IndexParamVideoErrorCorrection:
298a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        {
299a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return OMX_ErrorNotImplemented;
300a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
301a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
302a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        case OMX_IndexParamVideoPortFormat:
303a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        {
304a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams =
305a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                (OMX_VIDEO_PARAM_PORTFORMATTYPE *)param;
306a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
307a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (formatParams->nPortIndex == kInputPortIndex) {
308a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                if (formatParams->nIndex >= NELEM(kSupportedColorFormats)) {
309a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    return OMX_ErrorNoMore;
310a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                }
311a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
312a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                // Color formats, in order of preference
313a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                formatParams->eColorFormat = kSupportedColorFormats[formatParams->nIndex];
314a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                formatParams->eCompressionFormat = OMX_VIDEO_CodingUnused;
315a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                formatParams->xFramerate = mFramerate;
316a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return OMX_ErrorNone;
317a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            } else if (formatParams->nPortIndex == kOutputPortIndex) {
318a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                formatParams->eCompressionFormat = mCodingType;
319a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                formatParams->eColorFormat = OMX_COLOR_FormatUnused;
320a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                formatParams->xFramerate = 0;
321a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return OMX_ErrorNone;
322a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            } else {
323a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return OMX_ErrorBadPortIndex;
324a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            }
325a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
326a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
327a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        case OMX_IndexParamVideoProfileLevelQuerySupported:
328a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        {
329a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevel =
330a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                  (OMX_VIDEO_PARAM_PROFILELEVELTYPE *) param;
331a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
332a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (profileLevel->nPortIndex != kOutputPortIndex) {
333a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                ALOGE("Invalid port index: %u", profileLevel->nPortIndex);
334a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return OMX_ErrorUnsupportedIndex;
335a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            }
336a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
337a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (profileLevel->nProfileIndex >= mNumProfileLevels) {
338a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                return OMX_ErrorNoMore;
339a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            }
340a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
341a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            profileLevel->eProfile = mProfileLevels[profileLevel->nProfileIndex].mProfile;
342a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            profileLevel->eLevel   = mProfileLevels[profileLevel->nProfileIndex].mLevel;
343a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return OMX_ErrorNone;
344a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        }
345a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
346a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        default:
347a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return SimpleSoftOMXComponent::internalGetParameter(index, param);
348a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    }
3492edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar}
3502edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
3512edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar// static
3522edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnarvoid SoftVideoEncoderOMXComponent::ConvertFlexYUVToPlanar(
3532edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        uint8_t *dst, size_t dstStride, size_t dstVStride,
3542edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        struct android_ycbcr *ycbcr, int32_t width, int32_t height) {
3552edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    const uint8_t *src = (const uint8_t *)ycbcr->y;
3562edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    const uint8_t *srcU = (const uint8_t *)ycbcr->cb;
3572edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    const uint8_t *srcV = (const uint8_t *)ycbcr->cr;
3582edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    uint8_t *dstU = dst + dstVStride * dstStride;
3592edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    uint8_t *dstV = dstU + (dstVStride >> 1) * (dstStride >> 1);
3602edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
3612edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    for (size_t y = height; y > 0; --y) {
3622edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        memcpy(dst, src, width);
3632edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        dst += dstStride;
3642edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        src += ycbcr->ystride;
3652edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
3662edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    if (ycbcr->cstride == ycbcr->ystride >> 1 && ycbcr->chroma_step == 1) {
3672edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        // planar
3682edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        for (size_t y = height >> 1; y > 0; --y) {
3692edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            memcpy(dstU, srcU, width >> 1);
3702edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            dstU += dstStride >> 1;
3712edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            srcU += ycbcr->cstride;
3722edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            memcpy(dstV, srcV, width >> 1);
3732edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            dstV += dstStride >> 1;
3742edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            srcV += ycbcr->cstride;
3752edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        }
3762edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    } else {
3772edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        // arbitrary
3782edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        for (size_t y = height >> 1; y > 0; --y) {
3792edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            for (size_t x = width >> 1; x > 0; --x) {
3802edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                *dstU++ = *srcU;
3812edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                *dstV++ = *srcV;
3822edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                srcU += ycbcr->chroma_step;
3832edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                srcV += ycbcr->chroma_step;
3842edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            }
3852edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            dstU += (dstStride >> 1) - (width >> 1);
3862edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            dstV += (dstStride >> 1) - (width >> 1);
3872edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            srcU += ycbcr->cstride - (width >> 1) * ycbcr->chroma_step;
3882edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            srcV += ycbcr->cstride - (width >> 1) * ycbcr->chroma_step;
3892edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        }
3902edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
3912edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar}
3922edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
3932edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar// static
3942edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnarvoid SoftVideoEncoderOMXComponent::ConvertYUV420SemiPlanarToYUV420Planar(
3952edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        const uint8_t *inYVU, uint8_t* outYUV, int32_t width, int32_t height) {
3962edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    // TODO: add support for stride
3972edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    int32_t outYsize = width * height;
3982edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    uint32_t *outY  = (uint32_t *) outYUV;
3992edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    uint16_t *outCb = (uint16_t *) (outYUV + outYsize);
4002edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    uint16_t *outCr = (uint16_t *) (outYUV + outYsize + (outYsize >> 2));
4012edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4022edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    /* Y copying */
4032edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    memcpy(outY, inYVU, outYsize);
4042edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4052edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    /* U & V copying */
4062edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    // FIXME this only works if width is multiple of 4
4072edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    uint32_t *inYVU_4 = (uint32_t *) (inYVU + outYsize);
4082edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    for (int32_t i = height >> 1; i > 0; --i) {
4092edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        for (int32_t j = width >> 2; j > 0; --j) {
4102edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            uint32_t temp = *inYVU_4++;
4112edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            uint32_t tempU = temp & 0xFF;
4122edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            tempU = tempU | ((temp >> 8) & 0xFF00);
4132edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4142edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            uint32_t tempV = (temp >> 8) & 0xFF;
4152edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            tempV = tempV | ((temp >> 16) & 0xFF00);
4162edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4172edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            *outCb++ = tempU;
4182edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            *outCr++ = tempV;
4192edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        }
4202edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
4212edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar}
4222edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4232edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar// static
4242edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnarvoid SoftVideoEncoderOMXComponent::ConvertRGB32ToPlanar(
4252edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        uint8_t *dstY, size_t dstStride, size_t dstVStride,
4262edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        const uint8_t *src, size_t width, size_t height, size_t srcStride,
4272edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        bool bgr) {
4282edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    CHECK((width & 1) == 0);
4292edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    CHECK((height & 1) == 0);
4302edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4312edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    uint8_t *dstU = dstY + dstStride * dstVStride;
4322edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    uint8_t *dstV = dstU + (dstStride >> 1) * (dstVStride >> 1);
4332edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4342edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar#ifdef SURFACE_IS_BGR32
4352edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    bgr = !bgr;
4362edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar#endif
4372edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4382edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    const size_t redOffset   = bgr ? 2 : 0;
4392edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    const size_t greenOffset = 1;
4402edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    const size_t blueOffset  = bgr ? 0 : 2;
4412edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4422edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    for (size_t y = 0; y < height; ++y) {
4432edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        for (size_t x = 0; x < width; ++x) {
4442edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            unsigned red   = src[redOffset];
4452edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            unsigned green = src[greenOffset];
4462edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            unsigned blue  = src[blueOffset];
4472edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4482edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            // using ITU-R BT.601 conversion matrix
4492edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            unsigned luma =
4502edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                ((red * 66 + green * 129 + blue * 25) >> 8) + 16;
4512edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4522edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            dstY[x] = luma;
4532edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4542edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            if ((x & 1) == 0 && (y & 1) == 0) {
4552edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                unsigned U =
4562edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                    ((-red * 38 - green * 74 + blue * 112) >> 8) + 128;
4572edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4582edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                unsigned V =
4592edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                    ((red * 112 - green * 94 - blue * 18) >> 8) + 128;
4602edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4612edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                dstU[x >> 1] = U;
4622edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                dstV[x >> 1] = V;
4632edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            }
4642edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            src += 4;
4652edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        }
4662edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4672edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        if ((y & 1) == 0) {
4682edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            dstU += dstStride >> 1;
4692edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            dstV += dstStride >> 1;
4702edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        }
4712edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4722edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        src += srcStride - 4 * width;
4732edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        dstY += dstStride;
4742edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
4752edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar}
4762edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4772edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnarconst uint8_t *SoftVideoEncoderOMXComponent::extractGraphicBuffer(
4782edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        uint8_t *dst, size_t dstSize,
4792edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        const uint8_t *src, size_t srcSize,
4802edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        size_t width, size_t height) const {
4812edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    size_t dstStride = width;
4822edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    size_t dstVStride = height;
4832edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4842edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    MetadataBufferType bufferType = *(MetadataBufferType *)src;
4852edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    bool usingGraphicBuffer = bufferType == kMetadataBufferTypeGraphicBuffer;
4862edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    if (!usingGraphicBuffer && bufferType != kMetadataBufferTypeGrallocSource) {
4872edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        ALOGE("Unsupported metadata type (%d)", bufferType);
4882edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        return NULL;
4892edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
4902edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4912edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    if (mGrallocModule == NULL) {
4922edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        CHECK_EQ(0, hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mGrallocModule));
4932edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
4942edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4952edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    const gralloc_module_t *grmodule =
4962edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        (const gralloc_module_t *)mGrallocModule;
4972edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
4982edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    buffer_handle_t handle;
4992edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    int format;
5002edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    size_t srcStride;
5012edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    size_t srcVStride;
5022edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    if (usingGraphicBuffer) {
5032edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        if (srcSize < 4 + sizeof(GraphicBuffer *)) {
5042edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ALOGE("Metadata is too small (%zu vs %zu)", srcSize, 4 + sizeof(GraphicBuffer *));
5052edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            return NULL;
5062edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        }
5072edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
5082edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        GraphicBuffer *buffer = *(GraphicBuffer **)(src + 4);
5092edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        handle = buffer->handle;
5102edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        format = buffer->format;
5112edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        srcStride = buffer->stride;
5122edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        srcVStride = buffer->height;
5132edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        // convert stride from pixels to bytes
5142edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        if (format != HAL_PIXEL_FORMAT_YV12 &&
5152edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            format != HAL_PIXEL_FORMAT_YCbCr_420_888) {
5162edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            // TODO do we need to support other formats?
5172edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            srcStride *= 4;
5182edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        }
5192edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    } else {
5202edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        // TODO: remove this part.  Check if anyone uses this.
5212edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
5222edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        if (srcSize < 4 + sizeof(buffer_handle_t)) {
5232edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ALOGE("Metadata is too small (%zu vs %zu)", srcSize, 4 + sizeof(buffer_handle_t));
5242edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            return NULL;
5252edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        }
5262edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
5272edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        handle = *(buffer_handle_t *)(src + 4);
5282edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        // assume HAL_PIXEL_FORMAT_RGBA_8888
5292edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        // there is no way to get the src stride without the graphic buffer
5302edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        format = HAL_PIXEL_FORMAT_RGBA_8888;
5312edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        srcStride = width * 4;
5322edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        srcVStride = height;
5332edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
5342edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
5352edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    size_t neededSize =
5362edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        dstStride * dstVStride + (width >> 1)
5372edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                + (dstStride >> 1) * ((dstVStride >> 1) + (height >> 1) - 1);
5382edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    if (dstSize < neededSize) {
5392edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        ALOGE("destination buffer is too small (%zu vs %zu)", dstSize, neededSize);
5402edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        return NULL;
5412edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
5422edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
5432edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    void *bits = NULL;
5442edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    struct android_ycbcr ycbcr;
5452edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    status_t res;
5462edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
5472edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        res = grmodule->lock_ycbcr(
5482edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                 grmodule, handle,
5492edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_NEVER,
5502edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                 0, 0, width, height, &ycbcr);
5512edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    } else {
5522edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        res = grmodule->lock(
5532edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                 grmodule, handle,
5542edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_NEVER,
5552edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                 0, 0, width, height, &bits);
5562edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
5572edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    if (res != OK) {
5582edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        ALOGE("Unable to lock image buffer %p for access", handle);
5592edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        return NULL;
5602edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
5612edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
5622edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    switch (format) {
5632edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        case HAL_PIXEL_FORMAT_YV12:  // YCrCb / YVU planar
5642edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            // convert to flex YUV
5652edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.y = bits;
5662edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.cr = (uint8_t *)bits + srcStride * srcVStride;
5672edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.cb = (uint8_t *)ycbcr.cr + (srcStride >> 1) * (srcVStride >> 1);
5682edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.chroma_step = 1;
5692edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.cstride = srcVStride >> 1;
5702edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.ystride = srcVStride;
5712edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ConvertFlexYUVToPlanar(dst, dstStride, dstVStride, &ycbcr, width, height);
5722edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            break;
5732edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        case HAL_PIXEL_FORMAT_YCrCb_420_SP:  // YCrCb / YVU semiplanar, NV21
5742edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            // convert to flex YUV
5752edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.y = bits;
5762edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.cr = (uint8_t *)bits + srcStride * srcVStride;
5772edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.cb = (uint8_t *)ycbcr.cr + 1;
5782edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.chroma_step = 2;
5792edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.cstride = srcVStride;
5802edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ycbcr.ystride = srcVStride;
5812edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ConvertFlexYUVToPlanar(dst, dstStride, dstVStride, &ycbcr, width, height);
5822edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            break;
5832edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        case HAL_PIXEL_FORMAT_YCbCr_420_888:
5842edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ConvertFlexYUVToPlanar(dst, dstStride, dstVStride, &ycbcr, width, height);
5852edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            break;
5862edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        case HAL_PIXEL_FORMAT_RGBA_8888:
5872edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        case HAL_PIXEL_FORMAT_BGRA_8888:
5882edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ConvertRGB32ToPlanar(
5892edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                    dst, dstStride, dstVStride,
5902edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                    (const uint8_t *)bits, width, height, srcStride,
5912edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                    format == HAL_PIXEL_FORMAT_BGRA_8888);
5922edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            break;
5932edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        default:
5942edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ALOGE("Unsupported pixel format %#x", format);
5952edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            dst = NULL;
5962edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            break;
5972edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
5982edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
5992edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    if (grmodule->unlock(grmodule, handle) != OK) {
6002edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        ALOGE("Unable to unlock image buffer %p for access", handle);
6012edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
6022edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
6032edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    return dst;
6042edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar}
6052edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
6062edda09a2ad1d112c52acd37d323f63f0a492d67Lajos MolnarOMX_ERRORTYPE SoftVideoEncoderOMXComponent::getExtensionIndex(
6072edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        const char *name, OMX_INDEXTYPE *index) {
6082edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    if (!strcmp(name, "OMX.google.android.index.storeMetaDataInBuffers") ||
6092edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        !strcmp(name, "OMX.google.android.index.storeGraphicBufferInMetaData")) {
6102edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        *(int32_t*)index = kStoreMetaDataExtensionIndex;
6112edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        return OMX_ErrorNone;
6122edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    }
6132edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    return SimpleSoftOMXComponent::getExtensionIndex(name, index);
6142edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar}
6152edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar
6162edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar}  // namespace android
617