1 /*--------------------------------------------------------------------------
2 Copyright (c) 2014-2017, 2019, The Linux Foundation. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6 * Redistributions of source code must retain the above copyright
7 notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright
9 notice, this list of conditions and the following disclaimer in the
10 documentation and/or other materials provided with the distribution.
11 * Neither the name of The Linux Foundation nor
12 the names of its contributors may be used to endorse or promote
13 products derived from this software without specific prior written
14 permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 --------------------------------------------------------------------------*/
28 #include "omx_swvenc_mpeg4.h"
29
30 /* def: StoreMetaDataInBuffersParams */
31 #include <media/hardware/HardwareAPI.h>
32
33 /* def: VENUS_BUFFER_SIZE, VENUS_Y_STRIDE etc */
34 #include <media/msm_media_info.h>
35
36 /* def: private_handle_t*/
37 #include <gralloc_priv.h>
38
39 #include "PlatformConfig.h"
40
41 /* use GraphicBuffer for rotation */
42 #include <ui/GraphicBufferAllocator.h>
43 #include <gralloc.h>
44
45 /* def: GET_VT_TIMESTAMP */
46 #include <qdMetaData.h>
47
48 /*----------------------------------------------------------------------------
49 * Preprocessor Definitions and Constants
50 * -------------------------------------------------------------------------*/
51 #define OMX_SPEC_VERSION 0x00000101
52 #define OMX_INIT_STRUCT(_s_, _name_) \
53 memset((_s_), 0x0, sizeof(_name_)); \
54 (_s_)->nSize = sizeof(_name_); \
55 (_s_)->nVersion.nVersion = OMX_SPEC_VERSION
56
57 #define ENTER_FUNC() DEBUG_PRINT_HIGH("ENTERING: %s",__FUNCTION__)
58 #define EXIT_FUNC() DEBUG_PRINT_HIGH("EXITING: %s",__FUNCTION__)
59 #define RETURN(x) EXIT_FUNC(); return x;
60 #undef ALIGN
61 #define ALIGN(value,alignment) (((value) + (alignment-1)) & (~(alignment-1)))
62
63 #define BUFFER_LOG_LOC "/data/vendor/media"
64
65 /* factory function executed by the core to create instances */
get_omx_component_factory_fn(void)66 void *get_omx_component_factory_fn(void)
67 {
68 RETURN((new omx_venc));
69 }
70
omx_venc()71 omx_venc::omx_venc()
72 {
73 ENTER_FUNC();
74
75 char property_value[PROPERTY_VALUE_MAX] = {0};
76
77 memset(&m_debug,0,sizeof(m_debug));
78
79 property_value[0] = '\0';
80 property_get("vendor.vidc.debug.level", property_value, "1");
81 debug_level = atoi(property_value);
82
83 Platform::Config::getInt32(Platform::vidc_enc_log_in,
84 (int32_t *)&m_debug.in_buffer_log, 0);
85 Platform::Config::getInt32(Platform::vidc_enc_log_out,
86 (int32_t *)&m_debug.out_buffer_log, 0);
87
88 property_value[0] = '\0';
89 property_get("vendor.vidc.enc.log.in", property_value, "0");
90 m_debug.in_buffer_log = atoi(property_value);
91
92 property_value[0] = '\0';
93 property_get("vendor.vidc.enc.log.out", property_value, "0");
94 m_debug.out_buffer_log = atoi(property_value);
95
96 snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX, "%s", BUFFER_LOG_LOC);
97 property_value[0] = '\0';
98 property_get("vendor.vidc.log.loc", property_value, "");
99 if (*property_value)
100 {
101 strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
102 }
103
104 memset(meta_buffer_hdr,0,sizeof(meta_buffer_hdr));
105 meta_mode_enable = false;
106 memset(meta_buffer_hdr,0,sizeof(meta_buffer_hdr));
107 memset(meta_buffers,0,sizeof(meta_buffers));
108 memset(opaque_buffer_hdr,0,sizeof(opaque_buffer_hdr));
109 mUseProxyColorFormat = false;
110 get_syntaxhdr_enable = false;
111 m_bSeqHdrRequested = false;
112 m_bDimensionsNeedFlip = false;
113 m_bIsRotationSupported = false;
114 m_bIsInFrameSizeSet = false;
115 m_bIsOutFrameSizeSet = false;
116 m_bIsInFlipDone = false;
117 m_bIsOutFlipDone = false;
118 m_bUseAVTimerTimestamps = false;
119 m_pIpbuffers = nullptr;
120 set_format = false;
121
122 EXIT_FUNC();
123 }
124
~omx_venc()125 omx_venc::~omx_venc()
126 {
127 ENTER_FUNC();
128 get_syntaxhdr_enable = false;
129 EXIT_FUNC();
130 }
131
component_init(OMX_STRING role)132 OMX_ERRORTYPE omx_venc::component_init(OMX_STRING role)
133 {
134 ENTER_FUNC();
135
136 OMX_ERRORTYPE eRet = OMX_ErrorNone;
137 SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
138 SWVENC_CALLBACK callBackInfo;
139 OMX_VIDEO_CODINGTYPE codec_type;
140 SWVENC_PROPERTY Prop;
141 int fds[2];
142
143 strlcpy((char *)m_nkind,role,OMX_MAX_STRINGNAME_SIZE);
144 secure_session = false;
145
146 if (!strncmp( (char *)m_nkind,"OMX.qcom.video.encoder.mpeg4sw",
147 OMX_MAX_STRINGNAME_SIZE))
148 {
149 strlcpy((char *)m_cRole, "video_encoder.mpeg4",\
150 OMX_MAX_STRINGNAME_SIZE);
151 codec_type = OMX_VIDEO_CodingMPEG4;
152 m_codec = SWVENC_CODEC_MPEG4;
153 }
154 else if (!strncmp( (char *)m_nkind,"OMX.qcom.video.encoder.h263sw",
155 OMX_MAX_STRINGNAME_SIZE))
156 {
157 strlcpy((char *)m_cRole, "video_encoder.h263",\
158 OMX_MAX_STRINGNAME_SIZE);
159 codec_type = OMX_VIDEO_CodingH263;
160 m_codec = SWVENC_CODEC_H263;
161 }
162 else
163 {
164 DEBUG_PRINT_ERROR("ERROR: Unknown Component");
165 eRet = OMX_ErrorInvalidComponentName;
166 RETURN(eRet);
167 }
168
169 #ifdef ENABLE_GET_SYNTAX_HDR
170 get_syntaxhdr_enable = true;
171 DEBUG_PRINT_HIGH("Get syntax header enabled");
172 #endif
173
174 callBackInfo.pfn_empty_buffer_done = swvenc_empty_buffer_done_cb;
175 callBackInfo.pfn_fill_buffer_done = swvenc_fill_buffer_done_cb;
176 callBackInfo.pfn_event_notification = swvenc_handle_event_cb;
177 callBackInfo.p_client = (void*)this;
178
179 SWVENC_STATUS sRet = swvenc_init(&m_hSwVenc, m_codec, &callBackInfo);
180 if (sRet != SWVENC_S_SUCCESS)
181 {
182 DEBUG_PRINT_ERROR("swvenc_init returned %d, ret insufficient resources",
183 sRet);
184 RETURN(OMX_ErrorInsufficientResources);
185 }
186
187 m_stopped = true;
188
189 //Intialise the OMX layer variables
190 memset(&m_pCallbacks,0,sizeof(OMX_CALLBACKTYPE));
191
192 OMX_INIT_STRUCT(&m_sPortParam, OMX_PORT_PARAM_TYPE);
193 m_sPortParam.nPorts = 0x2;
194 m_sPortParam.nStartPortNumber = (OMX_U32) PORT_INDEX_IN;
195
196 OMX_INIT_STRUCT(&m_sPortParam_audio, OMX_PORT_PARAM_TYPE);
197 m_sPortParam_audio.nPorts = 0;
198 m_sPortParam_audio.nStartPortNumber = 0;
199
200 OMX_INIT_STRUCT(&m_sPortParam_img, OMX_PORT_PARAM_TYPE);
201 m_sPortParam_img.nPorts = 0;
202 m_sPortParam_img.nStartPortNumber = 0;
203
204 OMX_INIT_STRUCT(&m_sParamBitrate, OMX_VIDEO_PARAM_BITRATETYPE);
205 m_sParamBitrate.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
206 m_sParamBitrate.eControlRate = OMX_Video_ControlRateVariableSkipFrames;
207 m_sParamBitrate.nTargetBitrate = 64000;
208
209 OMX_INIT_STRUCT(&m_sConfigBitrate, OMX_VIDEO_CONFIG_BITRATETYPE);
210 m_sConfigBitrate.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
211 m_sConfigBitrate.nEncodeBitrate = 64000;
212
213 OMX_INIT_STRUCT(&m_sConfigFramerate, OMX_CONFIG_FRAMERATETYPE);
214 m_sConfigFramerate.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
215 m_sConfigFramerate.xEncodeFramerate = 30 << 16;
216
217 OMX_INIT_STRUCT(&m_sConfigIntraRefreshVOP, OMX_CONFIG_INTRAREFRESHVOPTYPE);
218 m_sConfigIntraRefreshVOP.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
219 m_sConfigIntraRefreshVOP.IntraRefreshVOP = OMX_FALSE;
220
221 OMX_INIT_STRUCT(&m_sConfigFrameRotation, OMX_CONFIG_ROTATIONTYPE);
222 m_sConfigFrameRotation.nPortIndex = (OMX_U32) PORT_INDEX_IN;
223 m_sConfigFrameRotation.nRotation = 0;
224
225 OMX_INIT_STRUCT(&m_sSessionQuantization, OMX_VIDEO_PARAM_QUANTIZATIONTYPE);
226 m_sSessionQuantization.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
227 m_sSessionQuantization.nQpI = 9;
228 m_sSessionQuantization.nQpP = 6;
229 m_sSessionQuantization.nQpB = 2;
230
231 OMX_INIT_STRUCT(&m_sSessionQPRange, OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE);
232 m_sSessionQPRange.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
233 m_sSessionQPRange.minIQP = 2;
234 m_sSessionQPRange.minPQP = 2;
235 m_sSessionQPRange.minBQP = 2;
236
237 OMX_INIT_STRUCT(&m_sParamProfileLevel, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
238 m_sParamProfileLevel.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
239
240 OMX_INIT_STRUCT(&m_sIntraperiod, QOMX_VIDEO_INTRAPERIODTYPE);
241 m_sIntraperiod.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
242 m_sIntraperiod.nPFrames = (m_sConfigFramerate.xEncodeFramerate * 2) - 1;
243
244 OMX_INIT_STRUCT(&m_sErrorCorrection, OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE);
245 m_sErrorCorrection.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
246 m_sErrorCorrection.bEnableDataPartitioning = OMX_FALSE;
247 m_sErrorCorrection.bEnableHEC = OMX_FALSE;
248 m_sErrorCorrection.bEnableResync = OMX_FALSE;
249 m_sErrorCorrection.bEnableRVLC = OMX_FALSE;
250 m_sErrorCorrection.nResynchMarkerSpacing = 0;
251
252 OMX_INIT_STRUCT(&m_sIntraRefresh, OMX_VIDEO_PARAM_INTRAREFRESHTYPE);
253 m_sIntraRefresh.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
254 m_sIntraRefresh.eRefreshMode = OMX_VIDEO_IntraRefreshMax;
255
256 if (codec_type == OMX_VIDEO_CodingMPEG4)
257 {
258 m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_MPEG4ProfileSimple;
259 m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_MPEG4Level0;
260 } else if (codec_type == OMX_VIDEO_CodingH263)
261 {
262 m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_H263ProfileBaseline;
263 m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_H263Level10;
264 }
265
266 /* set the profile and level */
267 Ret = swvenc_set_profile_level(m_sParamProfileLevel.eProfile,
268 m_sParamProfileLevel.eLevel);
269 if (Ret != SWVENC_S_SUCCESS)
270 {
271 DEBUG_PRINT_ERROR("%s, swvenc_set_rc_mode failed (%d)",
272 __FUNCTION__, Ret);
273 RETURN(OMX_ErrorUndefined);
274 }
275
276 // Initialize the video parameters for input port
277 OMX_INIT_STRUCT(&m_sInPortDef, OMX_PARAM_PORTDEFINITIONTYPE);
278 m_sInPortDef.nPortIndex= (OMX_U32) PORT_INDEX_IN;
279 m_sInPortDef.bEnabled = OMX_TRUE;
280 m_sInPortDef.bPopulated = OMX_FALSE;
281 m_sInPortDef.eDomain = OMX_PortDomainVideo;
282 m_sInPortDef.eDir = OMX_DirInput;
283 m_sInPortDef.format.video.cMIMEType = (char *)"YUV420";
284 m_sInPortDef.format.video.nFrameWidth = OMX_CORE_QCIF_WIDTH;
285 m_sInPortDef.format.video.nFrameHeight = OMX_CORE_QCIF_HEIGHT;
286 m_sInPortDef.format.video.nStride = OMX_CORE_QCIF_WIDTH;
287 m_sInPortDef.format.video.nSliceHeight = OMX_CORE_QCIF_HEIGHT;
288 m_sInPortDef.format.video.nBitrate = 64000;
289 m_sInPortDef.format.video.xFramerate = 15 << 16;
290 m_sInPortDef.format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)
291 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
292 m_sInPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
293
294 /* set the frame size */
295 Prop.id = SWVENC_PROPERTY_ID_FRAME_SIZE;
296 Prop.info.frame_size.height = m_sInPortDef.format.video.nFrameHeight;
297 Prop.info.frame_size.width = m_sInPortDef.format.video.nFrameWidth;
298
299 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
300 if (Ret != SWVENC_S_SUCCESS)
301 {
302 DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
303 __FUNCTION__, Ret);
304 RETURN(OMX_ErrorUnsupportedSetting);
305 }
306
307 /* set the frame attributes */
308 Prop.id = SWVENC_PROPERTY_ID_FRAME_ATTRIBUTES;
309 Prop.info.frame_attributes.stride_luma = m_sInPortDef.format.video.nStride;
310 Prop.info.frame_attributes.stride_chroma = m_sInPortDef.format.video.nStride;
311 Prop.info.frame_attributes.offset_luma = 0;
312 Prop.info.frame_attributes.offset_chroma =
313 (m_sInPortDef.format.video.nSliceHeight * m_sInPortDef.format.video.nStride);
314 Prop.info.frame_attributes.size = (Prop.info.frame_attributes.offset_chroma * 3) >> 1;
315
316 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
317 if (Ret != SWVENC_S_SUCCESS)
318 {
319 DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
320 __FUNCTION__, Ret);
321 RETURN(OMX_ErrorUndefined);
322 }
323
324 Ret = swvenc_get_buffer_req(&m_sInPortDef.nBufferCountMin,
325 &m_sInPortDef.nBufferCountActual,
326 &m_sInPortDef.nBufferSize,
327 &m_sInPortDef.nBufferAlignment,
328 PORT_INDEX_IN);
329 if (Ret != SWVENC_S_SUCCESS)
330 {
331 DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__,
332 Ret);
333 RETURN(OMX_ErrorUndefined);
334 }
335
336 // Initialize the video parameters for output port
337 OMX_INIT_STRUCT(&m_sOutPortDef, OMX_PARAM_PORTDEFINITIONTYPE);
338 m_sOutPortDef.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
339 m_sOutPortDef.bEnabled = OMX_TRUE;
340 m_sOutPortDef.bPopulated = OMX_FALSE;
341 m_sOutPortDef.eDomain = OMX_PortDomainVideo;
342 m_sOutPortDef.eDir = OMX_DirOutput;
343 m_sOutPortDef.format.video.nFrameWidth = OMX_CORE_QCIF_WIDTH;
344 m_sOutPortDef.format.video.nFrameHeight = OMX_CORE_QCIF_HEIGHT;
345 m_sOutPortDef.format.video.nBitrate = 64000;
346 m_sOutPortDef.format.video.xFramerate = 15 << 16;
347 m_sOutPortDef.format.video.eColorFormat = OMX_COLOR_FormatUnused;
348 if (codec_type == OMX_VIDEO_CodingMPEG4)
349 {
350 m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
351 }
352 else if (codec_type == OMX_VIDEO_CodingH263)
353 {
354 m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingH263;
355 }
356
357 Ret = swvenc_get_buffer_req(&m_sOutPortDef.nBufferCountMin,
358 &m_sOutPortDef.nBufferCountActual,
359 &m_sOutPortDef.nBufferSize,
360 &m_sOutPortDef.nBufferAlignment,
361 PORT_INDEX_OUT);
362 if (Ret != SWVENC_S_SUCCESS)
363 {
364 DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__,
365 Ret);
366 RETURN(OMX_ErrorUndefined);
367 }
368
369 // Initialize the video color format for input port
370 OMX_INIT_STRUCT(&m_sInPortFormat, OMX_VIDEO_PARAM_PORTFORMATTYPE);
371 m_sInPortFormat.nPortIndex = (OMX_U32) PORT_INDEX_IN;
372 m_sInPortFormat.nIndex = 0;
373 m_sInPortFormat.eColorFormat = (OMX_COLOR_FORMATTYPE)
374 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
375 m_sInPortFormat.eCompressionFormat = OMX_VIDEO_CodingUnused;
376
377 // Initialize the compression format for output port
378 OMX_INIT_STRUCT(&m_sOutPortFormat, OMX_VIDEO_PARAM_PORTFORMATTYPE);
379 m_sOutPortFormat.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
380 m_sOutPortFormat.nIndex = 0;
381 m_sOutPortFormat.eColorFormat = OMX_COLOR_FormatUnused;
382 if (codec_type == OMX_VIDEO_CodingMPEG4)
383 {
384 m_sOutPortFormat.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
385 } else if (codec_type == OMX_VIDEO_CodingH263)
386 {
387 m_sOutPortFormat.eCompressionFormat = OMX_VIDEO_CodingH263;
388 }
389
390 // mandatory Indices for kronos test suite
391 OMX_INIT_STRUCT(&m_sPriorityMgmt, OMX_PRIORITYMGMTTYPE);
392
393 OMX_INIT_STRUCT(&m_sInBufSupplier, OMX_PARAM_BUFFERSUPPLIERTYPE);
394 m_sInBufSupplier.nPortIndex = (OMX_U32) PORT_INDEX_IN;
395
396 OMX_INIT_STRUCT(&m_sOutBufSupplier, OMX_PARAM_BUFFERSUPPLIERTYPE);
397 m_sOutBufSupplier.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
398
399 OMX_INIT_STRUCT(&m_sConfigQP, OMX_QCOM_VIDEO_CONFIG_QP);
400 m_sConfigQP.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
401
402 // mp4 specific init
403 OMX_INIT_STRUCT(&m_sParamMPEG4, OMX_VIDEO_PARAM_MPEG4TYPE);
404 m_sParamMPEG4.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
405 m_sParamMPEG4.eProfile = OMX_VIDEO_MPEG4ProfileSimple;
406 m_sParamMPEG4.eLevel = OMX_VIDEO_MPEG4Level0;
407 m_sParamMPEG4.nSliceHeaderSpacing = 0;
408 m_sParamMPEG4.bSVH = OMX_FALSE;
409 m_sParamMPEG4.bGov = OMX_FALSE;
410 // 2 second intra period for default outport fps
411 m_sParamMPEG4.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1);
412 m_sParamMPEG4.bACPred = OMX_TRUE;
413 // delta = 2 @ 15 fps
414 m_sParamMPEG4.nTimeIncRes = 30;
415 // pframe and iframe
416 m_sParamMPEG4.nAllowedPictureTypes = 2;
417 // number of video packet headers per vop
418 m_sParamMPEG4.nHeaderExtension = 1;
419 m_sParamMPEG4.bReversibleVLC = OMX_FALSE;
420
421 // h263 specific init
422 OMX_INIT_STRUCT(&m_sParamH263, OMX_VIDEO_PARAM_H263TYPE);
423 m_sParamH263.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
424 // 2 second intra period for default outport fps
425 m_sParamH263.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1);
426 m_sParamH263.nBFrames = 0;
427 m_sParamH263.eProfile = OMX_VIDEO_H263ProfileBaseline;
428 m_sParamH263.eLevel = OMX_VIDEO_H263Level10;
429 m_sParamH263.bPLUSPTYPEAllowed = OMX_FALSE;
430 m_sParamH263.nAllowedPictureTypes = 2;
431 m_sParamH263.bForceRoundingTypeToZero = OMX_TRUE;
432 m_sParamH263.nPictureHeaderRepetition = 0;
433 m_sParamH263.nGOBHeaderInterval = 1;
434
435 // av-timer init (for ims-vt)
436 OMX_INIT_STRUCT(&m_sParamAVTimerTimestampMode, QOMX_ENABLETYPE);
437 m_sParamAVTimerTimestampMode.bEnable = OMX_FALSE;
438
439 m_state = OMX_StateLoaded;
440 m_sExtraData = 0;
441 m_sParamConsumerUsage |= (OMX_U32)GRALLOC_USAGE_SW_READ_OFTEN;
442
443 if (codec_type == OMX_VIDEO_CodingMPEG4)
444 {
445 m_capability.max_height = OMX_CORE_720P_HEIGHT;
446 m_capability.max_width = OMX_CORE_720P_WIDTH;
447 }
448 else if (codec_type == OMX_VIDEO_CodingH263)
449 {
450 m_capability.max_height = OMX_CORE_FWVGA_HEIGHT;
451 m_capability.max_width = OMX_CORE_FWVGA_WIDTH;
452 }
453
454 m_capability.min_height = 32;
455 m_capability.min_width = 32;
456
457 if (eRet == OMX_ErrorNone)
458 {
459 if (pipe(fds))
460 {
461 DEBUG_PRINT_ERROR("ERROR: pipe creation failed");
462 eRet = OMX_ErrorInsufficientResources;
463 }
464 else
465 {
466 if ((fds[0] == 0) || (fds[1] == 0))
467 {
468 if (pipe(fds))
469 {
470 DEBUG_PRINT_ERROR("ERROR: pipe creation failed");
471 eRet = OMX_ErrorInsufficientResources;
472 }
473 }
474 if (eRet == OMX_ErrorNone)
475 {
476 m_pipe_in = fds[0];
477 m_pipe_out = fds[1];
478 }
479 }
480
481 if (pthread_create(&msg_thread_id,0, message_thread_enc, this) < 0)
482 {
483 eRet = OMX_ErrorInsufficientResources;
484 msg_thread_created = false;
485 }
486 else
487 {
488 msg_thread_created = true;
489 }
490 }
491
492 DEBUG_PRINT_HIGH("Component_init return value = 0x%x", eRet);
493
494 EXIT_FUNC();
495
496 {
497 VendorExtensionStore *extStore = const_cast<VendorExtensionStore *>(&mVendorExtensionStore);
498 init_sw_vendor_extensions(*extStore);
499 mVendorExtensionStore.dumpExtensions((const char *)m_nkind);
500 }
501
502 RETURN(eRet);
503 }
504
set_parameter(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE paramIndex,OMX_IN OMX_PTR paramData)505 OMX_ERRORTYPE omx_venc::set_parameter
506 (
507 OMX_IN OMX_HANDLETYPE hComp,
508 OMX_IN OMX_INDEXTYPE paramIndex,
509 OMX_IN OMX_PTR paramData
510 )
511 {
512 ENTER_FUNC();
513
514 OMX_ERRORTYPE eRet = OMX_ErrorNone;
515 SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
516 SWVENC_PROPERTY Prop;
517 bool bResult;
518 unsigned int stride, scanlines;
519
520 (void)hComp;
521
522 if (m_state == OMX_StateInvalid)
523 {
524 DEBUG_PRINT_ERROR("ERROR: Set Param in Invalid State");
525 RETURN(OMX_ErrorInvalidState);
526 }
527 if (paramData == NULL)
528 {
529 DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData");
530 RETURN(OMX_ErrorBadParameter);
531 }
532
533 /* set_parameter can be called in loaded state or disabled port */
534 if ( (m_state == OMX_StateLoaded) ||
535 (m_sInPortDef.bEnabled == OMX_FALSE) ||
536 (m_sOutPortDef.bEnabled == OMX_FALSE)
537 )
538 {
539 DEBUG_PRINT_LOW("Set Parameter called in valid state");
540 }
541 else
542 {
543 DEBUG_PRINT_ERROR("ERROR: Set Parameter called in Invalid State");
544 RETURN(OMX_ErrorIncorrectStateOperation);
545 }
546
547 switch ((int)paramIndex)
548 {
549 case OMX_IndexParamPortDefinition:
550 {
551 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
552 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
553 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
554 (int)portDefn->format.video.nFrameHeight,
555 (int)portDefn->format.video.nFrameWidth);
556
557 if (PORT_INDEX_IN == portDefn->nPortIndex)
558 {
559 if (!dev_is_video_session_supported(portDefn->format.video.nFrameWidth,
560 portDefn->format.video.nFrameHeight))
561 {
562 DEBUG_PRINT_ERROR("video session not supported");
563 omx_report_unsupported_setting();
564 RETURN(OMX_ErrorUnsupportedSetting);
565 }
566 DEBUG_PRINT_LOW("i/p actual cnt requested = %u", portDefn->nBufferCountActual);
567 DEBUG_PRINT_LOW("i/p min cnt requested = %u", portDefn->nBufferCountMin);
568 DEBUG_PRINT_LOW("i/p buffersize requested = %u", portDefn->nBufferSize);
569 if (portDefn->nBufferCountMin > portDefn->nBufferCountActual)
570 {
571 DEBUG_PRINT_ERROR("ERROR: (In_PORT) Min buffers (%u) > actual count (%u)",
572 portDefn->nBufferCountMin, portDefn->nBufferCountActual);
573 RETURN(OMX_ErrorUnsupportedSetting);
574 }
575
576 /* set the frame size */
577 Prop.id = SWVENC_PROPERTY_ID_FRAME_SIZE;
578 Prop.info.frame_size.height = portDefn->format.video.nFrameHeight;
579 Prop.info.frame_size.width = portDefn->format.video.nFrameWidth;
580
581 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
582 if (Ret != SWVENC_S_SUCCESS)
583 {
584 DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
585 __FUNCTION__, Ret);
586 RETURN(OMX_ErrorUnsupportedSetting);
587 }
588
589 /* set the input frame-rate */
590 if (portDefn->format.video.xFramerate != 0)
591 {
592 Ret = swvenc_set_frame_rate(portDefn->format.video.xFramerate >> 16);
593 if (Ret != SWVENC_S_SUCCESS)
594 {
595 DEBUG_PRINT_ERROR("%s, swvenc_set_frame_rate failed (%d)",
596 __FUNCTION__, Ret);
597 RETURN(OMX_ErrorUnsupportedSetting);
598 }
599 }
600
601 /* set the frame attributes */
602 stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, portDefn->format.video.nFrameWidth);
603 //Slice height doesn't get updated so chroma offset calculation becomes incorrect .
604 //Using FrameHeight Instead , just for omx-test-app .
605 //scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, portDefn->format.video.nSliceHeight);
606 scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, portDefn->format.video.nFrameHeight);
607 Prop.id = SWVENC_PROPERTY_ID_FRAME_ATTRIBUTES;
608 Prop.info.frame_attributes.stride_luma = stride;
609 Prop.info.frame_attributes.stride_chroma = stride;
610 Prop.info.frame_attributes.offset_luma = 0;
611 Prop.info.frame_attributes.offset_chroma = scanlines * stride;
612 Prop.info.frame_attributes.size =
613 VENUS_BUFFER_SIZE(COLOR_FMT_NV12,
614 portDefn->format.video.nFrameWidth,
615 portDefn->format.video.nFrameHeight);
616
617 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
618 if (Ret != SWVENC_S_SUCCESS)
619 {
620 DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
621 __FUNCTION__, Ret);
622 RETURN(OMX_ErrorUnsupportedSetting);
623 }
624
625 DEBUG_PRINT_LOW("i/p previous actual cnt = %u", m_sInPortDef.nBufferCountActual);
626 DEBUG_PRINT_LOW("i/p previous min cnt = %u", m_sInPortDef.nBufferCountMin);
627 DEBUG_PRINT_LOW("i/p previous buffersize = %u", m_sInPortDef.nBufferSize);
628
629 memcpy(&m_sInPortDef, portDefn,sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
630
631 /* update the input buffer requirement */
632 Ret = swvenc_get_buffer_req(&m_sInPortDef.nBufferCountMin,
633 &m_sInPortDef.nBufferCountActual,
634 &m_sInPortDef.nBufferSize,
635 &m_sInPortDef.nBufferAlignment,
636 portDefn->nPortIndex);
637 if (Ret != SWVENC_S_SUCCESS)
638 {
639 DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__,
640 Ret);
641 RETURN(OMX_ErrorUndefined);
642 }
643
644 if (portDefn->nBufferCountActual > m_sInPortDef.nBufferCountActual)
645 {
646 m_sInPortDef.nBufferCountActual = portDefn->nBufferCountActual;
647 }
648 if (portDefn->nBufferSize > m_sInPortDef.nBufferSize)
649 {
650 m_sInPortDef.nBufferSize = portDefn->nBufferSize;
651 }
652
653 DEBUG_PRINT_LOW("i/p new actual cnt = %u", m_sInPortDef.nBufferCountActual);
654 DEBUG_PRINT_LOW("i/p new min cnt = %u", m_sInPortDef.nBufferCountMin);
655 DEBUG_PRINT_LOW("i/p new buffersize = %u", m_sInPortDef.nBufferSize);
656
657 // when rotation is setting before portdefinition, if need flip dimensions
658 // in port flip will be set here
659 if (m_bDimensionsNeedFlip && !m_bIsInFlipDone) {
660 DEBUG_PRINT_HIGH("flip in port dimension(for swcodec) in portdefinition");
661 OMX_ERRORTYPE err = swvenc_do_flip_inport();
662 if (err != OMX_ErrorNone) {
663 DEBUG_PRINT_ERROR("%s, swvenc_do_flip_inport falied (%d)",
664 __FUNCTION__, err);
665 RETURN(err);
666 }
667 m_bIsInFlipDone = true;
668 }
669 m_bIsInFrameSizeSet = true;
670 }
671 else if (PORT_INDEX_OUT == portDefn->nPortIndex)
672 {
673 DEBUG_PRINT_LOW("o/p actual cnt requested = %u", portDefn->nBufferCountActual);
674 DEBUG_PRINT_LOW("o/p min cnt requested = %u", portDefn->nBufferCountMin);
675 DEBUG_PRINT_LOW("o/p buffersize requested = %u", portDefn->nBufferSize);
676 if (portDefn->nBufferCountMin > portDefn->nBufferCountActual)
677 {
678 DEBUG_PRINT_ERROR("ERROR: (Out_PORT) Min buffers (%u) > actual count (%u)",
679 portDefn->nBufferCountMin, portDefn->nBufferCountActual);
680 RETURN(OMX_ErrorUnsupportedSetting);
681 }
682
683 /* set the output bit-rate */
684 Ret = swvenc_set_bit_rate(portDefn->format.video.nBitrate);
685 if (Ret != SWVENC_S_SUCCESS)
686 {
687 DEBUG_PRINT_ERROR("%s, swvenc_set_bit_rate failed (%d)",
688 __FUNCTION__, Ret);
689 RETURN(OMX_ErrorUnsupportedSetting);
690 }
691
692 DEBUG_PRINT_LOW("o/p previous actual cnt = %u", m_sOutPortDef.nBufferCountActual);
693 DEBUG_PRINT_LOW("o/p previous min cnt = %u", m_sOutPortDef.nBufferCountMin);
694 DEBUG_PRINT_LOW("o/p previous buffersize = %u", m_sOutPortDef.nBufferSize);
695
696 /* set the buffer requirement */
697 bResult = dev_set_buf_req(&portDefn->nBufferCountMin,
698 &portDefn->nBufferCountActual,
699 &portDefn->nBufferSize,
700 portDefn->nPortIndex);
701 if (bResult != true)
702 {
703 DEBUG_PRINT_ERROR("%s, dev_set_buf_req failed",
704 __FUNCTION__);
705 RETURN(OMX_ErrorUnsupportedSetting);
706 }
707 memcpy(&m_sOutPortDef, portDefn,sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
708
709 /* update the output buffer requirement */
710 Ret = swvenc_get_buffer_req(&m_sOutPortDef.nBufferCountMin,
711 &m_sOutPortDef.nBufferCountActual,
712 &m_sOutPortDef.nBufferSize,
713 &m_sOutPortDef.nBufferAlignment,
714 portDefn->nPortIndex);
715 if (Ret != SWVENC_S_SUCCESS)
716 {
717 DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__,
718 Ret);
719 RETURN(OMX_ErrorUndefined);
720 }
721
722 if (portDefn->nBufferCountActual > m_sOutPortDef.nBufferCountActual)
723 {
724 m_sOutPortDef.nBufferCountActual = portDefn->nBufferCountActual;
725 }
726 if (portDefn->nBufferSize > m_sOutPortDef.nBufferSize)
727 {
728 m_sOutPortDef.nBufferSize = portDefn->nBufferSize;
729 }
730
731 DEBUG_PRINT_LOW("o/p new actual cnt = %u", m_sOutPortDef.nBufferCountActual);
732 DEBUG_PRINT_LOW("o/p new min cnt = %u", m_sOutPortDef.nBufferCountMin);
733 DEBUG_PRINT_LOW("o/p new buffersize = %u", m_sOutPortDef.nBufferSize);
734 // when rotation is setting before portdefinition, if need flip dimensions
735 // out port flip will be set here
736 if (m_bDimensionsNeedFlip && !m_bIsOutFlipDone) {
737 DEBUG_PRINT_HIGH("flip out port dimension in portdefinition");
738 OMX_ERRORTYPE err = swvenc_do_flip_outport();
739 m_bIsOutFlipDone = true;
740 DEBUG_PRINT_HIGH("Out Port Definition: rotation (%d), flipped WxH (%d x %d)",
741 m_sConfigFrameRotation.nRotation,
742 m_sOutPortDef.format.video.nFrameWidth,
743 m_sOutPortDef.format.video.nFrameHeight);
744 }
745 m_bIsOutFrameSizeSet = true;
746 }
747 else
748 {
749 DEBUG_PRINT_ERROR("ERROR: Set_parameter: Bad Port idx %d",
750 (int)portDefn->nPortIndex);
751 eRet = OMX_ErrorBadPortIndex;
752 }
753 m_sConfigFramerate.xEncodeFramerate = portDefn->format.video.xFramerate;
754 m_sConfigBitrate.nEncodeBitrate = portDefn->format.video.nBitrate;
755 m_sParamBitrate.nTargetBitrate = portDefn->format.video.nBitrate;
756 break;
757 }
758
759 case OMX_IndexParamVideoPortFormat:
760 {
761 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
762 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
763 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d",
764 portFmt->eColorFormat);
765 SWVENC_COLOR_FORMAT color_format;
766
767 /* set the driver with the corresponding values */
768 if (PORT_INDEX_IN == portFmt->nPortIndex)
769 {
770 if (portFmt->eColorFormat ==
771 ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FormatAndroidOpaque))
772 {
773 /* meta_mode = 2 (kMetadataBufferTypeGrallocSource) */
774 m_sInPortFormat.eColorFormat =
775 (OMX_COLOR_FORMATTYPE) QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
776 color_format = SWVENC_COLOR_FORMAT_NV12;
777 mUseProxyColorFormat = true;
778 m_input_msg_id = OMX_COMPONENT_GENERATE_ETB_OPQ;
779 }
780 else
781 {
782 m_sInPortFormat.eColorFormat = portFmt->eColorFormat;
783 if ((portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) ||
784 (portFmt->eColorFormat ==
785 ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m)))
786 {
787 color_format = SWVENC_COLOR_FORMAT_NV12;
788 }
789 else if (portFmt->eColorFormat ==
790 ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FormatYVU420SemiPlanar))
791 {
792 color_format = SWVENC_COLOR_FORMAT_NV21;
793 }
794 else
795 {
796 DEBUG_PRINT_ERROR("%s: OMX_IndexParamVideoPortFormat %d invalid",
797 __FUNCTION__,
798 portFmt->eColorFormat);
799 RETURN(OMX_ErrorBadParameter);
800 }
801 m_input_msg_id = OMX_COMPONENT_GENERATE_ETB;
802 mUseProxyColorFormat = false;
803 }
804 m_sInPortDef.format.video.eColorFormat = m_sInPortFormat.eColorFormat;
805 /* set the input color format */
806 Prop.id = SWVENC_PROPERTY_ID_COLOR_FORMAT;
807 Prop.info.color_format = color_format;
808 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
809 if (Ret != SWVENC_S_SUCCESS)
810 {
811 DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
812 __FUNCTION__, Ret);
813 RETURN(OMX_ErrorUnsupportedSetting);
814 }
815
816 /* set the input frame-rate */
817 if (portFmt->xFramerate != 0)
818 {
819 Ret = swvenc_set_frame_rate(portFmt->xFramerate >> 16);
820 if (Ret != SWVENC_S_SUCCESS)
821 {
822 DEBUG_PRINT_ERROR("%s, swvenc_set_frame_rate failed (%d)",
823 __FUNCTION__, Ret);
824 //RETURN(OMX_ErrorUnsupportedSetting);
825 }
826 m_sInPortFormat.xFramerate = portFmt->xFramerate;
827 }
828 }
829 break;
830 }
831
832 case OMX_IndexParamVideoInit:
833 {
834 OMX_PORT_PARAM_TYPE* pParam = (OMX_PORT_PARAM_TYPE*)(paramData);
835 DEBUG_PRINT_LOW("Set OMX_IndexParamVideoInit called");
836 break;
837 }
838
839 case OMX_IndexParamVideoBitrate:
840 {
841 OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
842 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoBitrate");
843
844 if (m_max_allowed_bitrate_check)
845 {
846 //TBD: to add bitrate check
847 }
848
849 /* set the output bit-rate */
850 Ret = swvenc_set_bit_rate(pParam->nTargetBitrate);
851 if (Ret != SWVENC_S_SUCCESS)
852 {
853 DEBUG_PRINT_ERROR("%s, swvenc_set_bit_rate failed (%d)",
854 __FUNCTION__, Ret);
855 RETURN(OMX_ErrorUnsupportedSetting);
856 }
857
858 /* set the RC-mode */
859 Ret = swvenc_set_rc_mode(pParam->eControlRate);
860 if (Ret != SWVENC_S_SUCCESS)
861 {
862 DEBUG_PRINT_ERROR("%s, swvenc_set_rc_mode failed (%d)",
863 __FUNCTION__, Ret);
864 RETURN(OMX_ErrorUnsupportedSetting);
865 }
866
867 m_sParamBitrate.nTargetBitrate = pParam->nTargetBitrate;
868 m_sParamBitrate.eControlRate = pParam->eControlRate;
869 m_sConfigBitrate.nEncodeBitrate = pParam->nTargetBitrate;
870 m_sInPortDef.format.video.nBitrate = pParam->nTargetBitrate;
871 m_sOutPortDef.format.video.nBitrate = pParam->nTargetBitrate;
872 DEBUG_PRINT_LOW("bitrate = %u", m_sOutPortDef.format.video.nBitrate);
873 break;
874 }
875
876 case OMX_IndexParamVideoMpeg4:
877 {
878 OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
879
880 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4");
881
882 if (pParam->nBFrames)
883 {
884 DEBUG_PRINT_ERROR("Warning: B frames not supported");
885 }
886
887 /* set the intra period */
888 Ret = swvenc_set_intra_period(pParam->nPFrames,pParam->nBFrames);
889 if (Ret != SWVENC_S_SUCCESS)
890 {
891 DEBUG_PRINT_ERROR("%s, swvenc_set_intra_period failed (%d)",
892 __FUNCTION__, Ret);
893 RETURN(OMX_ErrorUnsupportedSetting);
894 }
895 else
896 {
897 m_sIntraperiod.nPFrames = pParam->nPFrames;
898 m_sIntraperiod.nBFrames = pParam->nBFrames;
899 }
900
901 /* set profile/level */
902 if (pParam->eProfile && pParam->eLevel)
903 {
904 DEBUG_PRINT_LOW("pParam->eProfile : %d, pParam->eLevel : %d", pParam->eProfile, pParam->eLevel);
905 Ret = swvenc_set_profile_level(pParam->eProfile, pParam->eLevel);
906 if (Ret != SWVENC_S_SUCCESS)
907 {
908 DEBUG_PRINT_ERROR("%sm swvenc_set_profile_level failed (%d)",
909 __FUNCTION__, Ret);
910 RETURN(OMX_ErrorUnsupportedSetting);
911 }
912 else
913 {
914 m_sParamProfileLevel.eProfile = pParam->eProfile;
915 m_sParamProfileLevel.eLevel = pParam->eLevel;
916 }
917 }
918
919 // NOTE: m_sParamMPEG4.eProfile/eLevel may be overwritten to 0 if client didn't set them
920 memcpy(&m_sParamMPEG4, pParam, sizeof(struct OMX_VIDEO_PARAM_MPEG4TYPE));
921 break;
922 }
923
924 case OMX_IndexParamVideoH263:
925 {
926 OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
927
928 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263");
929
930 /* set the intra period */
931 Ret = swvenc_set_intra_period(pParam->nPFrames,pParam->nBFrames);
932 if (Ret != SWVENC_S_SUCCESS)
933 {
934 DEBUG_PRINT_ERROR("%s, swvenc_set_intra_period failed (%d)",
935 __FUNCTION__, Ret);
936 RETURN(OMX_ErrorUnsupportedSetting);
937 }
938 else
939 {
940 m_sIntraperiod.nPFrames = pParam->nPFrames;
941 m_sIntraperiod.nBFrames = pParam->nBFrames;
942 }
943
944 /* set profile/level */
945 if (pParam->eProfile && pParam->eLevel)
946 {
947 DEBUG_PRINT_LOW("pParam->eProfile : %d, pParam->eLevel : %d", pParam->eProfile, pParam->eLevel);
948 Ret = swvenc_set_profile_level(pParam->eProfile, pParam->eLevel);
949 if (Ret != SWVENC_S_SUCCESS)
950 {
951 DEBUG_PRINT_ERROR("%sm swvenc_set_profile_level failed (%d)",
952 __FUNCTION__, Ret);
953 RETURN(OMX_ErrorUnsupportedSetting);
954 }
955 else
956 {
957 m_sParamProfileLevel.eProfile = pParam->eProfile;
958 m_sParamProfileLevel.eLevel = pParam->eLevel;
959 }
960 }
961
962 // NOTE: m_sParamH263.eProfile/eLevel may be overwritten to 0 if client didn't set them
963 memcpy(&m_sParamH263,pParam, sizeof(struct OMX_VIDEO_PARAM_H263TYPE));
964 break;
965 }
966
967 case OMX_IndexParamVideoProfileLevelCurrent:
968 {
969 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
970
971 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoProfileLevelCurrent");
972
973 /* set the profile and level */
974 Ret = swvenc_set_profile_level(pParam->eProfile,pParam->eLevel);
975 if (Ret != SWVENC_S_SUCCESS)
976 {
977 DEBUG_PRINT_ERROR("%s, swvenc_set_rc_mode failed (%d)",
978 __FUNCTION__, Ret);
979 RETURN(OMX_ErrorUnsupportedSetting);
980 }
981
982
983 m_sParamProfileLevel.eProfile = pParam->eProfile;
984 m_sParamProfileLevel.eLevel = pParam->eLevel;
985
986 if (SWVENC_CODEC_MPEG4 == m_codec)
987 {
988 m_sParamMPEG4.eProfile = (OMX_VIDEO_MPEG4PROFILETYPE)m_sParamProfileLevel.eProfile;
989 m_sParamMPEG4.eLevel = (OMX_VIDEO_MPEG4LEVELTYPE)m_sParamProfileLevel.eLevel;
990 DEBUG_PRINT_LOW("MPEG4 profile = %d, level = %d", m_sParamMPEG4.eProfile,
991 m_sParamMPEG4.eLevel);
992 }
993 else if (SWVENC_CODEC_H263 == m_codec)
994 {
995 m_sParamH263.eProfile = (OMX_VIDEO_H263PROFILETYPE)m_sParamProfileLevel.eProfile;
996 m_sParamH263.eLevel = (OMX_VIDEO_H263LEVELTYPE)m_sParamProfileLevel.eLevel;
997 DEBUG_PRINT_LOW("H263 profile = %d, level = %d", m_sParamH263.eProfile,
998 m_sParamH263.eLevel);
999 }
1000 break;
1001 }
1002
1003 case OMX_IndexParamStandardComponentRole:
1004 {
1005 OMX_PARAM_COMPONENTROLETYPE *comp_role;
1006 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
1007 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
1008 comp_role->cRole);
1009
1010 if ((m_state == OMX_StateLoaded)&&
1011 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
1012 {
1013 DEBUG_PRINT_LOW("Set Parameter called in valid state");
1014 }
1015 else
1016 {
1017 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
1018 RETURN(OMX_ErrorIncorrectStateOperation);
1019 }
1020
1021 if (SWVENC_CODEC_MPEG4 == m_codec)
1022 {
1023 if (!strncmp((const char*)comp_role->cRole,"video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
1024 {
1025 strlcpy((char*)m_cRole,"video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
1026 }
1027 else
1028 {
1029 DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s", comp_role->cRole);
1030 eRet = OMX_ErrorUnsupportedSetting;
1031 }
1032 }
1033 else if (SWVENC_CODEC_H263 == m_codec)
1034 {
1035 if (!strncmp((const char*)comp_role->cRole,"video_encoder.h263",OMX_MAX_STRINGNAME_SIZE))
1036 {
1037 strlcpy((char*)m_cRole,"video_encoder.h263",OMX_MAX_STRINGNAME_SIZE);
1038 }
1039 else
1040 {
1041 DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s", comp_role->cRole);
1042 eRet =OMX_ErrorUnsupportedSetting;
1043 }
1044 }
1045 else
1046 {
1047 DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %s", m_nkind);
1048 eRet = OMX_ErrorInvalidComponentName;
1049 }
1050 break;
1051 }
1052
1053 case OMX_IndexParamPriorityMgmt:
1054 {
1055 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt");
1056 if (m_state != OMX_StateLoaded) {
1057 DEBUG_PRINT_ERROR("ERROR: Set Parameter called in Invalid State");
1058 RETURN(OMX_ErrorIncorrectStateOperation);
1059 }
1060 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
1061 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %u",
1062 priorityMgmtype->nGroupID);
1063
1064 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %u",
1065 priorityMgmtype->nGroupPriority);
1066
1067 m_sPriorityMgmt.nGroupID = priorityMgmtype->nGroupID;
1068 m_sPriorityMgmt.nGroupPriority = priorityMgmtype->nGroupPriority;
1069
1070 break;
1071 }
1072
1073 case OMX_IndexParamCompBufferSupplier:
1074 {
1075 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier");
1076 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
1077 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
1078 bufferSupplierType->eBufferSupplier);
1079 if ( (bufferSupplierType->nPortIndex == 0) ||
1080 (bufferSupplierType->nPortIndex ==1)
1081 )
1082 {
1083 m_sInBufSupplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
1084 }
1085 else
1086 {
1087 eRet = OMX_ErrorBadPortIndex;
1088 }
1089
1090 break;
1091
1092 }
1093
1094 case OMX_IndexParamVideoQuantization:
1095 {
1096 // this is applicable only for RC-off case
1097 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoQuantization");
1098 OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData;
1099 if (session_qp->nPortIndex == PORT_INDEX_OUT)
1100 {
1101 Prop.id = SWVENC_PROPERTY_ID_QP;
1102 Prop.info.qp.qp_i = session_qp->nQpI;
1103 Prop.info.qp.qp_p = session_qp->nQpP;
1104 Prop.info.qp.qp_b = session_qp->nQpB;
1105
1106 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
1107 if (Ret != SWVENC_S_SUCCESS)
1108 {
1109 DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
1110 __FUNCTION__, Ret);
1111 RETURN(OMX_ErrorUnsupportedSetting);
1112 }
1113
1114 m_sSessionQuantization.nQpI = session_qp->nQpI;
1115 m_sSessionQuantization.nQpP = session_qp->nQpP;
1116 m_sSessionQuantization.nQpB = session_qp->nQpB;
1117 }
1118 else
1119 {
1120 DEBUG_PRINT_ERROR("ERROR: Unsupported port Index for Session QP setting");
1121 eRet = OMX_ErrorBadPortIndex;
1122 }
1123 break;
1124 }
1125
1126 case OMX_QcomIndexParamVideoIPBQPRange:
1127 {
1128 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoIPBQPRange");
1129 OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE *session_qp_range = (OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE*) paramData;
1130 if (session_qp_range->nPortIndex == PORT_INDEX_OUT)
1131 {
1132 Prop.id = SWVENC_PROPERTY_ID_QP_RANGE;
1133 Prop.info.qp_range.min_qp_packed = ((session_qp_range->minBQP << 16) |
1134 (session_qp_range->minPQP << 8) |
1135 (session_qp_range->minIQP << 0));
1136 Prop.info.qp_range.max_qp_packed = ((session_qp_range->maxBQP << 16) |
1137 (session_qp_range->maxPQP << 8) |
1138 (session_qp_range->maxIQP << 0));
1139
1140 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
1141 if (Ret != SWVENC_S_SUCCESS)
1142 {
1143 DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
1144 __FUNCTION__, Ret);
1145 RETURN(OMX_ErrorUnsupportedSetting);
1146 }
1147
1148 m_sSessionQPRange.minIQP = session_qp_range->minIQP;
1149 m_sSessionQPRange.maxIQP = session_qp_range->maxIQP;
1150 m_sSessionQPRange.minPQP = session_qp_range->minPQP;
1151 m_sSessionQPRange.maxPQP = session_qp_range->maxPQP;
1152 m_sSessionQPRange.minBQP = session_qp_range->minBQP;
1153 m_sSessionQPRange.maxBQP = session_qp_range->maxBQP;
1154 }
1155 else
1156 {
1157 DEBUG_PRINT_ERROR("ERROR: Unsupported port Index for Session QP range setting");
1158 eRet = OMX_ErrorBadPortIndex;
1159 }
1160 break;
1161 }
1162
1163 case OMX_QcomIndexPortDefn:
1164 {
1165 OMX_QCOM_PARAM_PORTDEFINITIONTYPE* pParam =
1166 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE*)paramData;
1167 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexPortDefn");
1168 if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN)
1169 {
1170 if (pParam->nMemRegion > OMX_QCOM_MemRegionInvalid &&
1171 pParam->nMemRegion < OMX_QCOM_MemRegionMax)
1172 {
1173 m_use_input_pmem = OMX_TRUE;
1174 }
1175 else
1176 {
1177 m_use_input_pmem = OMX_FALSE;
1178 }
1179 }
1180 else if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_OUT)
1181 {
1182 if (pParam->nMemRegion > OMX_QCOM_MemRegionInvalid &&
1183 pParam->nMemRegion < OMX_QCOM_MemRegionMax)
1184 {
1185 m_use_output_pmem = OMX_TRUE;
1186 }
1187 else
1188 {
1189 m_use_output_pmem = OMX_FALSE;
1190 }
1191 }
1192 else
1193 {
1194 DEBUG_PRINT_ERROR("ERROR: SetParameter called on unsupported Port Index for QcomPortDefn");
1195 RETURN(OMX_ErrorBadPortIndex);
1196 }
1197 break;
1198 }
1199
1200 case OMX_IndexParamVideoErrorCorrection:
1201 {
1202 DEBUG_PRINT_LOW("OMX_IndexParamVideoErrorCorrection");
1203 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* pParam =
1204 (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData;
1205
1206 /* HEC */
1207 if (m_codec == SWVENC_CODEC_MPEG4)
1208 {
1209 Prop.id = SWVENC_PROPERTY_ID_MPEG4_HEC;
1210 Prop.info.mpeg4_hec = pParam->bEnableHEC;
1211
1212 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
1213 if (Ret != SWVENC_S_SUCCESS)
1214 {
1215 DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
1216 __FUNCTION__, Ret);
1217 RETURN(OMX_ErrorUndefined);
1218 }
1219
1220 /* Data partitioning */
1221 Prop.id = SWVENC_PROPERTY_ID_MPEG4_DP;
1222 Prop.info.mpeg4_dp = pParam->bEnableDataPartitioning;
1223
1224 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
1225 if (Ret != SWVENC_S_SUCCESS)
1226 {
1227 DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
1228 __FUNCTION__, Ret);
1229 RETURN(OMX_ErrorUndefined);
1230 }
1231 }
1232
1233 /* RVLC */
1234 if (pParam->bEnableRVLC)
1235 {
1236 DEBUG_PRINT_ERROR("%s, RVLC not support", __FUNCTION__);
1237 }
1238
1239 /* Re-sync Marker */
1240 Prop.id = SWVENC_PROPERTY_ID_SLICE_CONFIG;
1241 if ( (m_codec != SWVENC_CODEC_H263) && (pParam->bEnableDataPartitioning) )
1242 {
1243 DEBUG_PRINT_ERROR("DataPartioning are not Supported for this codec");
1244 break;
1245 }
1246 if ( (m_codec != SWVENC_CODEC_H263) && (pParam->nResynchMarkerSpacing) )
1247 {
1248 Prop.info.slice_config.mode = SWVENC_SLICE_MODE_BYTE;
1249 Prop.info.slice_config.size = pParam->nResynchMarkerSpacing;
1250 }
1251 else if ( (SWVENC_CODEC_H263 == m_codec) && (pParam->bEnableResync) )
1252 {
1253 Prop.info.slice_config.mode = SWVENC_SLICE_MODE_GOB;
1254 Prop.info.slice_config.size = 0;
1255 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
1256 if (Ret != SWVENC_S_SUCCESS)
1257 {
1258 DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
1259 __FUNCTION__, Ret);
1260 RETURN(OMX_ErrorUndefined);
1261 }
1262 }
1263 else
1264 {
1265 Prop.info.slice_config.mode = SWVENC_SLICE_MODE_OFF;
1266 Prop.info.slice_config.size = 0;
1267 }
1268
1269 memcpy(&m_sErrorCorrection,pParam, sizeof(m_sErrorCorrection));
1270 break;
1271 }
1272
1273 case OMX_IndexParamVideoIntraRefresh:
1274 {
1275 DEBUG_PRINT_LOW("set_param:OMX_IndexParamVideoIntraRefresh");
1276 OMX_VIDEO_PARAM_INTRAREFRESHTYPE* pParam =
1277 (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData;
1278
1279 Ret = swvenc_set_intra_refresh(pParam);
1280 if (Ret != SWVENC_S_SUCCESS)
1281 {
1282 DEBUG_PRINT_ERROR("%s, swvenc_set_intra_refresh failed (%d)",
1283 __FUNCTION__, Ret);
1284 RETURN(OMX_ErrorUnsupportedSetting);
1285 }
1286
1287 memcpy(&m_sIntraRefresh, pParam, sizeof(m_sIntraRefresh));
1288 break;
1289 }
1290
1291 case OMX_QcomIndexParamVideoMetaBufferMode:
1292 {
1293 StoreMetaDataInBuffersParams *pParam =
1294 (StoreMetaDataInBuffersParams*)paramData;
1295 DEBUG_PRINT_HIGH("set_parameter:OMX_QcomIndexParamVideoMetaBufferMode: "
1296 "port_index = %u, meta_mode = %d", pParam->nPortIndex, pParam->bStoreMetaData);
1297
1298 if (pParam->nPortIndex == PORT_INDEX_IN)
1299 {
1300 if (pParam->bStoreMetaData != meta_mode_enable)
1301 {
1302 meta_mode_enable = pParam->bStoreMetaData;
1303 if (!meta_mode_enable)
1304 {
1305 Ret = swvenc_get_buffer_req(&m_sOutPortDef.nBufferCountMin,
1306 &m_sOutPortDef.nBufferCountActual,
1307 &m_sOutPortDef.nBufferSize,
1308 &m_sOutPortDef.nBufferAlignment,
1309 m_sOutPortDef.nPortIndex);
1310 if (Ret != SWVENC_S_SUCCESS)
1311 {
1312 DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__,
1313 Ret);
1314 eRet = OMX_ErrorUndefined;
1315 break;
1316 }
1317 }
1318 }
1319 }
1320 else if (pParam->nPortIndex == PORT_INDEX_OUT && secure_session)
1321 {
1322 if (pParam->bStoreMetaData != meta_mode_enable)
1323 {
1324 meta_mode_enable = pParam->bStoreMetaData;
1325 }
1326 }
1327 else
1328 {
1329 if (pParam->bStoreMetaData)
1330 {
1331 DEBUG_PRINT_ERROR("set_parameter: metamode is "
1332 "valid for input port only");
1333 eRet = OMX_ErrorUnsupportedIndex;
1334 }
1335 }
1336 }
1337 break;
1338
1339 case OMX_QcomIndexParamIndexExtraDataType:
1340 {
1341 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType");
1342 QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData;
1343 OMX_U32 mask = 0;
1344
1345 if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo)
1346 {
1347 if (pParam->nPortIndex == PORT_INDEX_OUT)
1348 {
1349 mask = VEN_EXTRADATA_SLICEINFO;
1350
1351 DEBUG_PRINT_HIGH("SliceInfo extradata %s",
1352 ((pParam->bEnabled == OMX_TRUE) ? "enabled" : "disabled"));
1353 }
1354 else
1355 {
1356 DEBUG_PRINT_ERROR("set_parameter: Slice information is "
1357 "valid for output port only");
1358 eRet = OMX_ErrorUnsupportedIndex;
1359 break;
1360 }
1361 }
1362 else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderMBInfo)
1363 {
1364 if (pParam->nPortIndex == PORT_INDEX_OUT)
1365 {
1366 mask = VEN_EXTRADATA_MBINFO;
1367
1368 DEBUG_PRINT_HIGH("MBInfo extradata %s",
1369 ((pParam->bEnabled == OMX_TRUE) ? "enabled" : "disabled"));
1370 }
1371 else
1372 {
1373 DEBUG_PRINT_ERROR("set_parameter: MB information is "
1374 "valid for output port only");
1375 eRet = OMX_ErrorUnsupportedIndex;
1376 break;
1377 }
1378 }
1379 else
1380 {
1381 DEBUG_PRINT_ERROR("set_parameter: unsupported extrdata index (%x)",
1382 pParam->nIndex);
1383 eRet = OMX_ErrorUnsupportedIndex;
1384 break;
1385 }
1386
1387
1388 if (pParam->bEnabled == OMX_TRUE)
1389 {
1390 m_sExtraData |= mask;
1391 }
1392 else
1393 {
1394 m_sExtraData &= ~mask;
1395 }
1396
1397 #if 0
1398 // TBD: add setprop to swvenc once the support is added
1399 if (handle->venc_set_param((OMX_PTR)!!(m_sExtraData & mask),
1400 (OMX_INDEXTYPE)pParam->nIndex) != true)
1401 {
1402 DEBUG_PRINT_ERROR("ERROR: Setting Extradata (%x) failed", pParam->nIndex);
1403 RETURN(OMX_ErrorUnsupportedSetting);
1404 }
1405 else
1406 #endif
1407 {
1408 m_sOutPortDef.nPortIndex = PORT_INDEX_OUT;
1409 bResult = dev_get_buf_req(&m_sOutPortDef.nBufferCountMin,
1410 &m_sOutPortDef.nBufferCountActual,
1411 &m_sOutPortDef.nBufferSize,
1412 m_sOutPortDef.nPortIndex);
1413 if (false == bResult)
1414 {
1415 DEBUG_PRINT_ERROR("dev_get_buf_req failed");
1416 eRet = OMX_ErrorUndefined;
1417 break;
1418 }
1419
1420 DEBUG_PRINT_HIGH("updated out_buf_req: buffer cnt=%u, "
1421 "count min=%u, buffer size=%u",
1422 m_sOutPortDef.nBufferCountActual,
1423 m_sOutPortDef.nBufferCountMin,
1424 m_sOutPortDef.nBufferSize);
1425 }
1426 break;
1427 }
1428
1429 case OMX_QcomIndexParamVideoMaxAllowedBitrateCheck:
1430 {
1431 QOMX_EXTNINDEX_PARAMTYPE* pParam =
1432 (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
1433 if (pParam->nPortIndex == PORT_INDEX_OUT)
1434 {
1435 m_max_allowed_bitrate_check =
1436 ((pParam->bEnable == OMX_TRUE) ? true : false);
1437 DEBUG_PRINT_HIGH("set_parameter: max allowed bitrate check %s",
1438 ((pParam->bEnable == OMX_TRUE) ? "enabled" : "disabled"));
1439 }
1440 else
1441 {
1442 DEBUG_PRINT_ERROR("ERROR: OMX_QcomIndexParamVideoMaxAllowedBitrateCheck "
1443 " called on wrong port(%u)", pParam->nPortIndex);
1444 RETURN(OMX_ErrorBadPortIndex);
1445 }
1446 break;
1447 }
1448
1449 case OMX_QcomIndexEnableSliceDeliveryMode:
1450 {
1451 QOMX_EXTNINDEX_PARAMTYPE* pParam =
1452 (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
1453 if (pParam->nPortIndex == PORT_INDEX_OUT)
1454 {
1455 //TBD: add setprop to swvenc once the support is added
1456 #if 0
1457 if (!handle->venc_set_param(paramData,
1458 (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode)) {
1459 DEBUG_PRINT_ERROR("ERROR: Request for setting slice delivery mode failed");
1460 RETURN( OMX_ErrorUnsupportedSetting;
1461 }
1462 #endif
1463 {
1464 DEBUG_PRINT_ERROR("ERROR: Request for setting slice delivery mode failed");
1465 RETURN(OMX_ErrorUnsupportedSetting);
1466 }
1467 }
1468 else
1469 {
1470 DEBUG_PRINT_ERROR("ERROR: OMX_QcomIndexEnableSliceDeliveryMode "
1471 "called on wrong port(%u)", pParam->nPortIndex);
1472 RETURN(OMX_ErrorBadPortIndex);
1473 }
1474 break;
1475 }
1476
1477 case OMX_QcomIndexEnableH263PlusPType:
1478 {
1479 QOMX_EXTNINDEX_PARAMTYPE* pParam =
1480 (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
1481 DEBUG_PRINT_LOW("OMX_QcomIndexEnableH263PlusPType");
1482 if (pParam->nPortIndex == PORT_INDEX_OUT)
1483 {
1484 DEBUG_PRINT_ERROR("ERROR: Request for setting PlusPType failed");
1485 RETURN(OMX_ErrorUnsupportedSetting);
1486 }
1487 else
1488 {
1489 DEBUG_PRINT_ERROR("ERROR: OMX_QcomIndexEnableH263PlusPType "
1490 "called on wrong port(%u)", pParam->nPortIndex);
1491 RETURN(OMX_ErrorBadPortIndex);
1492 }
1493 break;
1494 }
1495
1496 case OMX_QcomIndexParamPeakBitrate:
1497 {
1498 DEBUG_PRINT_ERROR("ERROR: Setting peak bitrate");
1499 RETURN(OMX_ErrorUnsupportedSetting);
1500 break;
1501 }
1502
1503 case QOMX_IndexParamVideoInitialQp:
1504 {
1505 // TBD: applicable to RC-on case only
1506 DEBUG_PRINT_ERROR("ERROR: Setting Initial QP for RC-on case");
1507 RETURN(OMX_ErrorNone);
1508 break;
1509 }
1510
1511
1512 case OMX_QcomIndexParamSetMVSearchrange:
1513 {
1514 DEBUG_PRINT_ERROR("ERROR: Setting Searchrange");
1515 RETURN(OMX_ErrorUnsupportedSetting);
1516 break;
1517 }
1518
1519 case OMX_QTIIndexParamEnableAVTimerTimestamps:
1520 {
1521 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
1522 QOMX_ENABLETYPE *pParam = (QOMX_ENABLETYPE *)paramData;
1523 m_bUseAVTimerTimestamps = pParam->bEnable == OMX_TRUE;
1524 DEBUG_PRINT_INFO("AVTimer timestamps %s", m_bUseAVTimerTimestamps ? "enabled" : "disabled");
1525 break;
1526 }
1527
1528 default:
1529 {
1530 DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %d", paramIndex);
1531 eRet = OMX_ErrorUnsupportedIndex;
1532 break;
1533 }
1534 }
1535
1536 RETURN(eRet);
1537 }
1538
set_config(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE configIndex,OMX_IN OMX_PTR configData)1539 OMX_ERRORTYPE omx_venc::set_config
1540 (
1541 OMX_IN OMX_HANDLETYPE hComp,
1542 OMX_IN OMX_INDEXTYPE configIndex,
1543 OMX_IN OMX_PTR configData
1544 )
1545 {
1546 ENTER_FUNC();
1547
1548 SWVENC_STATUS SwStatus;
1549
1550 (void)hComp;
1551
1552 if (configData == NULL)
1553 {
1554 DEBUG_PRINT_ERROR("ERROR: param is null");
1555 RETURN(OMX_ErrorBadParameter);
1556 }
1557
1558 if (m_state == OMX_StateInvalid)
1559 {
1560 DEBUG_PRINT_ERROR("ERROR: config called in Invalid state");
1561 RETURN(OMX_ErrorIncorrectStateOperation);
1562 }
1563
1564 switch ((int)configIndex)
1565 {
1566 case OMX_IndexConfigVideoBitrate:
1567 {
1568 OMX_VIDEO_CONFIG_BITRATETYPE* pParam =
1569 reinterpret_cast<OMX_VIDEO_CONFIG_BITRATETYPE*>(configData);
1570 DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoBitrate (%u)", pParam->nEncodeBitrate);
1571
1572 if (pParam->nPortIndex == PORT_INDEX_OUT)
1573 {
1574 SwStatus = swvenc_set_bit_rate(pParam->nEncodeBitrate);
1575 if (SwStatus != SWVENC_S_SUCCESS)
1576 {
1577 DEBUG_PRINT_ERROR("%s, swvenc_set_bit_rate failed (%d)",
1578 __FUNCTION__, SwStatus);
1579 RETURN(OMX_ErrorUnsupportedSetting);
1580 }
1581
1582 m_sConfigBitrate.nEncodeBitrate = pParam->nEncodeBitrate;
1583 m_sParamBitrate.nTargetBitrate = pParam->nEncodeBitrate;
1584 m_sOutPortDef.format.video.nBitrate = pParam->nEncodeBitrate;
1585 }
1586 else
1587 {
1588 DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex);
1589 RETURN(OMX_ErrorBadPortIndex);
1590 }
1591 break;
1592 }
1593 case OMX_IndexConfigVideoFramerate:
1594 {
1595 OMX_CONFIG_FRAMERATETYPE* pParam =
1596 reinterpret_cast<OMX_CONFIG_FRAMERATETYPE*>(configData);
1597 DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoFramerate (0x%x)", pParam->xEncodeFramerate);
1598
1599 if (pParam->nPortIndex == PORT_INDEX_OUT)
1600 {
1601 SwStatus = swvenc_set_frame_rate(pParam->xEncodeFramerate >> 16);
1602 if (SwStatus != SWVENC_S_SUCCESS)
1603 {
1604 DEBUG_PRINT_ERROR("%s, swvenc_set_frame_rate failed (%d)",
1605 __FUNCTION__, SwStatus);
1606 RETURN(OMX_ErrorUnsupportedSetting);
1607 }
1608
1609 m_sConfigFramerate.xEncodeFramerate = pParam->xEncodeFramerate;
1610 m_sOutPortDef.format.video.xFramerate = pParam->xEncodeFramerate;
1611 m_sOutPortFormat.xFramerate = pParam->xEncodeFramerate;
1612 }
1613 else
1614 {
1615 DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex);
1616 RETURN(OMX_ErrorBadPortIndex);
1617 }
1618 break;
1619 }
1620 case QOMX_IndexConfigVideoIntraperiod:
1621 {
1622 QOMX_VIDEO_INTRAPERIODTYPE* pParam =
1623 reinterpret_cast<QOMX_VIDEO_INTRAPERIODTYPE*>(configData);
1624 DEBUG_PRINT_HIGH("set_config(): QOMX_IndexConfigVideoIntraperiod");
1625
1626 if (pParam->nPortIndex == PORT_INDEX_OUT)
1627 {
1628 if (pParam->nBFrames > 0)
1629 {
1630 DEBUG_PRINT_ERROR("B frames not supported");
1631 RETURN(OMX_ErrorUnsupportedSetting);
1632 }
1633
1634 DEBUG_PRINT_HIGH("Old: P/B frames = %u/%u, New: P/B frames = %u/%u",
1635 m_sIntraperiod.nPFrames, m_sIntraperiod.nBFrames,
1636 pParam->nPFrames, pParam->nBFrames);
1637 if (m_sIntraperiod.nBFrames != pParam->nBFrames)
1638 {
1639 DEBUG_PRINT_HIGH("Dynamically changing B-frames not supported");
1640 RETURN(OMX_ErrorUnsupportedSetting);
1641 }
1642
1643 /* set the intra period */
1644 SwStatus = swvenc_set_intra_period(pParam->nPFrames,pParam->nBFrames);
1645 if (SwStatus != SWVENC_S_SUCCESS)
1646 {
1647 DEBUG_PRINT_ERROR("%s, swvenc_set_intra_period failed (%d)",
1648 __FUNCTION__, SwStatus);
1649 RETURN(OMX_ErrorUnsupportedSetting);
1650 }
1651
1652 m_sIntraperiod.nPFrames = pParam->nPFrames;
1653 m_sIntraperiod.nBFrames = pParam->nBFrames;
1654 m_sIntraperiod.nIDRPeriod = pParam->nIDRPeriod;
1655
1656 if (m_sOutPortFormat.eCompressionFormat == OMX_VIDEO_CodingMPEG4)
1657 {
1658 m_sParamMPEG4.nPFrames = pParam->nPFrames;
1659 if (m_sParamMPEG4.eProfile != OMX_VIDEO_MPEG4ProfileSimple)
1660 {
1661 m_sParamMPEG4.nBFrames = pParam->nBFrames;
1662 }
1663 else
1664 {
1665 m_sParamMPEG4.nBFrames = 0;
1666 }
1667 }
1668 else if (m_sOutPortFormat.eCompressionFormat == OMX_VIDEO_CodingH263)
1669 {
1670 m_sParamH263.nPFrames = pParam->nPFrames;
1671 }
1672 }
1673 else
1674 {
1675 DEBUG_PRINT_ERROR("ERROR: (QOMX_IndexConfigVideoIntraperiod) Unsupported port index: %u", pParam->nPortIndex);
1676 RETURN(OMX_ErrorBadPortIndex);
1677 }
1678
1679 break;
1680 }
1681 case OMX_IndexConfigVideoIntraVOPRefresh:
1682 {
1683 OMX_CONFIG_INTRAREFRESHVOPTYPE* pParam =
1684 reinterpret_cast<OMX_CONFIG_INTRAREFRESHVOPTYPE*>(configData);
1685 DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoIntraVOPRefresh");
1686
1687 if (pParam->nPortIndex == PORT_INDEX_OUT)
1688 {
1689
1690 SWVENC_PROPERTY Prop;
1691
1692 Prop.id = SWVENC_PROPERTY_ID_IFRAME_REQUEST;
1693
1694 SwStatus = swvenc_setproperty(m_hSwVenc, &Prop);
1695 if (SwStatus != SWVENC_S_SUCCESS)
1696 {
1697 DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
1698 __FUNCTION__, SwStatus);
1699 RETURN(OMX_ErrorUnsupportedSetting);
1700 }
1701
1702 m_sConfigIntraRefreshVOP.IntraRefreshVOP = pParam->IntraRefreshVOP;
1703 }
1704 else
1705 {
1706 DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex);
1707 RETURN(OMX_ErrorBadPortIndex);
1708 }
1709 break;
1710 }
1711 case OMX_IndexConfigCommonRotate:
1712 {
1713 if (m_codec == SWVENC_CODEC_H263) {
1714 OMX_CONFIG_ROTATIONTYPE *pParam =
1715 reinterpret_cast<OMX_CONFIG_ROTATIONTYPE *>(configData);
1716 DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigCommonRotate");
1717 m_bIsRotationSupported = true;
1718
1719 // XXX: diffrent from h/w encoder rotation, h/w encoder only need to update out
1720 // port info. For h/w encoder, rotation is processed in h/w encoder firmware, this
1721 // is after ETB, so input info doesn't change. While s/w encoder rotation is
1722 // processed before ETB, so need to change in port info.
1723 if (pParam->nPortIndex != PORT_INDEX_IN) {
1724 DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u",
1725 (unsigned int)pParam->nPortIndex);
1726 RETURN(OMX_ErrorBadPortIndex);
1727 }
1728 if (pParam->nRotation == 0 ||
1729 pParam->nRotation == 90 ||
1730 pParam->nRotation == 180 ||
1731 pParam->nRotation == 270) {
1732 DEBUG_PRINT_HIGH("set_config(): Rotation Angle %u",
1733 (unsigned int)pParam->nRotation);
1734 if (m_pIpbuffers == nullptr) {
1735 // m_pIpbuffers is used to store original ipbuffer, because after rotation,
1736 // will send new rotated ipbuffer to encoder, in EBD will also get new
1737 // ipbuffer. so we can restore original ipbuffer from to m_pIpbuffers and
1738 // return it to framework
1739 m_pIpbuffers = new SWVENC_IPBUFFER[m_sInPortDef.nBufferCountActual];
1740 }
1741 if (m_pIpbuffers == nullptr) {
1742 DEBUG_PRINT_ERROR("create ipbuffer array failed");
1743 return OMX_ErrorUndefined;
1744 }
1745 } else {
1746 DEBUG_PRINT_ERROR("ERROR: Unsupported Rotation Angle %u",
1747 (unsigned int)pParam->nRotation);
1748 RETURN(OMX_ErrorUnsupportedSetting);
1749 }
1750 if (m_sConfigFrameRotation.nRotation == pParam->nRotation) {
1751 DEBUG_PRINT_HIGH("set_config(): rotation (%d) not changed", pParam->nRotation);
1752 break;
1753 }
1754
1755 OMX_S32 rotation_diff = pParam->nRotation - m_sConfigFrameRotation.nRotation;
1756 if (rotation_diff < 0)
1757 rotation_diff = -rotation_diff;
1758 if (rotation_diff == 90 || rotation_diff == 270) {
1759 // in the case that rotation angle is 90 or 270 degree, if original buffer size
1760 // is 640x480, after rotation, rotated buffer size will be 480x640, so need to
1761 // flip dimensions in such cases.
1762 m_bDimensionsNeedFlip = true;
1763 OMX_ERRORTYPE err = OMX_ErrorNone;
1764 // flip and set new dimensions must be called after real dimension set
1765 if (m_bIsInFrameSizeSet && !m_bIsInFlipDone) {
1766 err = swvenc_do_flip_inport();
1767 if (err != OMX_ErrorNone) {
1768 DEBUG_PRINT_ERROR("set_config(): flipping failed");
1769 RETURN(err);
1770 }
1771
1772 m_bIsInFlipDone = true;
1773 } else {
1774 DEBUG_PRINT_HIGH("set_config(): in port frame size isn't set, will do flip later");
1775 }
1776 if (m_bIsOutFrameSizeSet && !m_bIsOutFlipDone) {
1777 err = swvenc_do_flip_outport();
1778 m_bIsOutFlipDone = true;
1779 DEBUG_PRINT_HIGH("set_config(): out port flip done, rotation (%d), flipped WxH (%d x %d)",
1780 pParam->nRotation,
1781 m_sOutPortDef.format.video.nFrameWidth,
1782 m_sOutPortDef.format.video.nFrameHeight);
1783 } else {
1784 DEBUG_PRINT_HIGH("set_config(): out port frame size isn't set, will do flip later");
1785 }
1786 } else {
1787 m_bDimensionsNeedFlip = false;
1788 DEBUG_PRINT_HIGH("set_config(): rotation (%d), no need to flip WxH",
1789 pParam->nRotation);
1790 }
1791
1792 // save rotation angle
1793 m_sConfigFrameRotation.nRotation = pParam->nRotation;
1794 break;
1795 } else {
1796 DEBUG_PRINT_ERROR("ERROR: rotation is not supported for current codec");
1797 RETURN(OMX_ErrorUnsupportedSetting);
1798
1799
1800 }
1801 }
1802 case OMX_IndexConfigAndroidVendorExtension:
1803 {
1804 OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext =
1805 reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(configData);
1806 OMX_ERRORTYPE err = set_vendor_extension_config(ext);
1807 RETURN(err);
1808 }
1809 default:
1810 DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex);
1811 RETURN(OMX_ErrorUnsupportedSetting);
1812 break;
1813 }
1814
1815 EXIT_FUNC();
1816
1817 RETURN(OMX_ErrorNone);
1818 }
1819
swvenc_do_flip_inport()1820 OMX_ERRORTYPE omx_venc::swvenc_do_flip_inport() {
1821 ENTER_FUNC();
1822 OMX_U32 inWidth = m_sInPortDef.format.video.nFrameWidth;
1823 OMX_U32 inHeight = m_sInPortDef.format.video.nFrameHeight;
1824
1825 // set new dimensions to encoder
1826 SWVENC_PROPERTY Prop;
1827 SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
1828 Prop.id = SWVENC_PROPERTY_ID_FRAME_SIZE;
1829 Prop.info.frame_size.height = inWidth;
1830 Prop.info.frame_size.width = inHeight;
1831
1832 DEBUG_PRINT_HIGH("setting flipped dimensions to swencoder, WxH (%d x %d)",
1833 inWidth, inHeight);
1834 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
1835 if (Ret != SWVENC_S_SUCCESS) {
1836 // currently, set dimensions to encoder can only be called when encoder is
1837 // in init state, while setVendorParameter() in ACodec can be called when
1838 // OMX component is in Executing state, in this case, encoder is in ready
1839 // state, will report unsupported error.
1840 DEBUG_PRINT_ERROR("ERROR: setting new dimension to encoder failed (%d)",
1841 Ret);
1842 return OMX_ErrorUnsupportedSetting;
1843 }
1844
1845 // don't flip in port dimensions m_sInPortDef.format.video.nFrameWidth(mFrameHeight)
1846 // app may require this dimensions by get_parameter
1847
1848 // update attributes, here dimensions are flipped, so use inHeight for calculating
1849 // stride, inWidth for scanlines, and swapp parameters in venus size calculation
1850 int stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, inHeight);
1851 int scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, inWidth);
1852 Prop.id = SWVENC_PROPERTY_ID_FRAME_ATTRIBUTES;
1853 Prop.info.frame_attributes.stride_luma = stride;
1854 Prop.info.frame_attributes.stride_chroma = stride;
1855 Prop.info.frame_attributes.offset_luma = 0;
1856 Prop.info.frame_attributes.offset_chroma = scanlines * stride;
1857 Prop.info.frame_attributes.size =
1858 VENUS_BUFFER_SIZE(COLOR_FMT_NV12, inHeight, inWidth);
1859
1860 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
1861 if (Ret != SWVENC_S_SUCCESS) {
1862 DEBUG_PRINT_ERROR("ERROR: update frame attributes failed (%d)", Ret);
1863 return OMX_ErrorUnsupportedSetting;
1864 }
1865
1866 // till now, attributes of omx input port is different from sw encoder input port,
1867 // omx input port stores original attributes, sw encoder input port stores flipped
1868 // attributes. no need to update buffer requirements from sw encoder here, but need
1869 // to update in output port, omx output port should also store flipped attrinutes
1870
1871 EXIT_FUNC();
1872 return OMX_ErrorNone;
1873 }
1874
swvenc_do_flip_outport()1875 OMX_ERRORTYPE omx_venc::swvenc_do_flip_outport() {
1876 ENTER_FUNC();
1877 // for out port, no need to set dimensions to encoder
1878 OMX_U32 outWidth = m_sOutPortDef.format.video.nFrameWidth;
1879 OMX_U32 outHeight = m_sOutPortDef.format.video.nFrameHeight;
1880
1881 // update out port info
1882 m_sOutPortDef.format.video.nFrameWidth = outHeight;
1883 m_sOutPortDef.format.video.nFrameHeight = outWidth;
1884
1885 // attributes in sw encoder has been updated after flipping dimensions, so need to update
1886 // omx out port buffer requirements, they should have the same attributes
1887 DEBUG_PRINT_LOW("flip outport, o/p previous actual cnt = %u", m_sOutPortDef.nBufferCountActual);
1888 DEBUG_PRINT_LOW("flip outport, o/p previous min cnt = %u", m_sOutPortDef.nBufferCountMin);
1889 DEBUG_PRINT_LOW("flip outport, o/p previous buffersize = %u", m_sOutPortDef.nBufferSize);
1890
1891 SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
1892 Ret = swvenc_get_buffer_req(&m_sOutPortDef.nBufferCountMin,
1893 &m_sOutPortDef.nBufferCountActual,
1894 &m_sOutPortDef.nBufferSize,
1895 &m_sOutPortDef.nBufferAlignment,
1896 PORT_INDEX_OUT);
1897 if (Ret != SWVENC_S_SUCCESS) {
1898 DEBUG_PRINT_ERROR("ERROR: %s, flip outport swvenc_get_buffer_req failed(%d)", __FUNCTION__,
1899 Ret);
1900 return OMX_ErrorUndefined;
1901 }
1902
1903 DEBUG_PRINT_LOW("flip outport, o/p new actual cnt = %u", m_sOutPortDef.nBufferCountActual);
1904 DEBUG_PRINT_LOW("flip outport, o/p new min cnt = %u", m_sOutPortDef.nBufferCountMin);
1905 DEBUG_PRINT_LOW("flip outport, o/p new buffersize = %u", m_sOutPortDef.nBufferSize);
1906
1907 EXIT_FUNC();
1908 return OMX_ErrorNone;
1909 }
1910
swvenc_do_rotate(int fd,SWVENC_IPBUFFER & ipbuffer,OMX_U32 index)1911 bool omx_venc::swvenc_do_rotate(int fd, SWVENC_IPBUFFER & ipbuffer, OMX_U32 index) {
1912 // declarations and definitions of variables rotation needs
1913 private_handle_t *privateHandle = nullptr;
1914
1915 int s_width = m_sInPortDef.format.video.nFrameWidth;
1916 int s_height = m_sInPortDef.format.video.nFrameHeight;
1917 int d_width = m_bDimensionsNeedFlip ? s_height : s_width;
1918 int d_height = m_bDimensionsNeedFlip ? s_width : s_height;
1919
1920 uint32_t rotation = m_sConfigFrameRotation.nRotation;
1921
1922 uint32_t usage = GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_READ_OFTEN |
1923 GraphicBuffer::USAGE_SW_WRITE_OFTEN | GraphicBuffer::USAGE_HW_RENDER;
1924 uint32_t dstusage = GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_HW_VIDEO_ENCODER |
1925 GraphicBuffer::USAGE_HW_RENDER | GraphicBuffer::USAGE_SW_READ_OFTEN |
1926 GraphicBuffer::USAGE_SW_WRITE_OFTEN;
1927
1928 int src_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, s_width);
1929 int src_scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, s_height);
1930 int src_size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, s_width, s_height);
1931 int dst_size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, d_width, d_height);
1932
1933 uint32_t format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS;
1934
1935 // privateHandle is created for creating GraphicBuffer in rotation case
1936 privateHandle = new private_handle_t(fd, ipbuffer.size, usage, BUFFER_TYPE_VIDEO, format,
1937 src_stride, src_scanlines);
1938 if (privateHandle == nullptr) {
1939 DEBUG_PRINT_ERROR("failed to create private handle");
1940 return false;
1941 }
1942
1943 sp<GraphicBuffer> srcBuffer = new GraphicBuffer(s_width, s_height, format, 1, usage,
1944 src_stride, (native_handle_t *)privateHandle, false);
1945 if (srcBuffer.get() == NULL) {
1946 DEBUG_PRINT_ERROR("create source buffer failed");
1947 swvenc_delete_pointer(privateHandle);
1948 return false;
1949 }
1950
1951 // reuse dstBuffer
1952 if (dstBuffer.get() == NULL) {
1953 dstBuffer = new GraphicBuffer(d_width, d_height, format, dstusage);
1954 }
1955 if (dstBuffer.get() == NULL) {
1956 DEBUG_PRINT_ERROR("create destination buffer failed");
1957 swvenc_delete_pointer(privateHandle);
1958 return false;
1959 }
1960 SWVENC_STATUS ret = swvenc_rotateFrame(s_width, s_height, d_height, d_width,
1961 rotation, srcBuffer->getNativeBuffer(), dstBuffer->getNativeBuffer());
1962
1963 if (ret == SWVENC_S_SUCCESS) {
1964 void *buf = nullptr;
1965 if (dstBuffer->lock(dstusage, &buf) == 0 && buf != nullptr) {
1966 DEBUG_PRINT_HIGH("store original ipbuffer[p_buffer(%p), size(%d), filled_length(%d)], new ipbuffer[p_buffer(%p), size(%d), filled_length(%d)]",
1967 ipbuffer.p_buffer,
1968 ipbuffer.size,
1969 ipbuffer.filled_length,
1970 (unsigned char *)buf,
1971 dst_size,
1972 dst_size);
1973 if (index >= m_sInPortDef.nBufferCountActual) {
1974 DEBUG_PRINT_ERROR("incorrect buffer index");
1975 swvenc_delete_pointer(privateHandle);
1976 return false;
1977 }
1978 m_pIpbuffers[index].size = ipbuffer.size;
1979 m_pIpbuffers[index].filled_length = ipbuffer.filled_length;
1980 m_pIpbuffers[index].p_buffer = ipbuffer.p_buffer;
1981 ipbuffer.size = dst_size;
1982 ipbuffer.filled_length = dst_size;
1983 ipbuffer.p_buffer = (unsigned char *)buf;
1984 dstBuffer->unlock();
1985 DEBUG_PRINT_HIGH("copy rotated buffer successfully");
1986 } else {
1987 DEBUG_PRINT_ERROR("copy rotated buffer failed");
1988 swvenc_delete_pointer(privateHandle);
1989 return false;
1990 }
1991 } else {
1992 DEBUG_PRINT_ERROR("rotate failed");
1993 swvenc_delete_pointer(privateHandle);
1994 return false;
1995 }
1996
1997 swvenc_delete_pointer(privateHandle);
1998 return true;
1999 }
2000
component_deinit(OMX_IN OMX_HANDLETYPE hComp)2001 OMX_ERRORTYPE omx_venc::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
2002 {
2003 ENTER_FUNC();
2004
2005 OMX_U32 i = 0;
2006 DEBUG_PRINT_HIGH("omx_venc(): Inside component_deinit()");
2007
2008 (void)hComp;
2009
2010 if (m_bIsRotationSupported) {
2011 swvenc_rotation_deinit();
2012 if (m_pIpbuffers != nullptr) {
2013 delete [] m_pIpbuffers;
2014 }
2015 }
2016
2017 if (OMX_StateLoaded != m_state)
2018 {
2019 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",
2020 m_state);
2021 }
2022 if (m_out_mem_ptr)
2023 {
2024 DEBUG_PRINT_LOW("Freeing the Output Memory");
2025 for (i=0; i< m_sOutPortDef.nBufferCountActual; i++ )
2026 {
2027 free_output_buffer (&m_out_mem_ptr[i]);
2028 }
2029 free(m_out_mem_ptr);
2030 m_out_mem_ptr = NULL;
2031 }
2032
2033 /* Check if the input buffers have to be cleaned up */
2034 if ( m_inp_mem_ptr && !meta_mode_enable )
2035 {
2036 DEBUG_PRINT_LOW("Freeing the Input Memory");
2037 for (i=0; i<m_sInPortDef.nBufferCountActual; i++)
2038 {
2039 free_input_buffer (&m_inp_mem_ptr[i]);
2040 }
2041
2042 free(m_inp_mem_ptr);
2043 m_inp_mem_ptr = NULL;
2044 }
2045
2046 /* Reset counters in msg queues */
2047 m_ftb_q.m_size=0;
2048 m_cmd_q.m_size=0;
2049 m_etb_q.m_size=0;
2050 m_ftb_q.m_read = m_ftb_q.m_write =0;
2051 m_cmd_q.m_read = m_cmd_q.m_write =0;
2052 m_etb_q.m_read = m_etb_q.m_write =0;
2053
2054 DEBUG_PRINT_HIGH("Calling swvenc_deinit()");
2055 swvenc_deinit(m_hSwVenc);
2056
2057 if (msg_thread_created) {
2058 msg_thread_created = false;
2059 msg_thread_stop = true;
2060 post_message(this, OMX_COMPONENT_CLOSE_MSG);
2061 DEBUG_PRINT_HIGH("omx_video: Waiting on Msg Thread exit");
2062 pthread_join(msg_thread_id,NULL);
2063 }
2064 DEBUG_PRINT_HIGH("OMX_Venc:Component Deinit");
2065
2066 RETURN(OMX_ErrorNone);
2067 }
2068
dev_stop(void)2069 OMX_U32 omx_venc::dev_stop(void)
2070 {
2071 ENTER_FUNC();
2072
2073 SWVENC_STATUS Ret;
2074
2075 if (false == m_stopped)
2076 {
2077 Ret = swvenc_stop(m_hSwVenc);
2078 if (Ret != SWVENC_S_SUCCESS)
2079 {
2080 DEBUG_PRINT_ERROR("%s, swvenc_stop failed (%d)",
2081 __FUNCTION__, Ret);
2082 RETURN(-1);
2083 }
2084 set_format = false;
2085 m_stopped = true;
2086
2087 /* post STOP_DONE event as start is synchronus */
2088 post_event (0, OMX_ErrorNone, OMX_COMPONENT_GENERATE_STOP_DONE);
2089 }
2090
2091 RETURN(0);
2092 }
2093
dev_pause(void)2094 OMX_U32 omx_venc::dev_pause(void)
2095 {
2096 ENTER_FUNC();
2097 // nothing to be done for sw encoder
2098
2099 RETURN(true);
2100 }
2101
dev_resume(void)2102 OMX_U32 omx_venc::dev_resume(void)
2103 {
2104 ENTER_FUNC();
2105 // nothing to be done for sw encoder
2106
2107 RETURN(true);
2108 }
2109
dev_start(void)2110 OMX_U32 omx_venc::dev_start(void)
2111 {
2112 ENTER_FUNC();
2113 SWVENC_STATUS Ret;
2114 Ret = swvenc_start(m_hSwVenc);
2115 if (Ret != SWVENC_S_SUCCESS)
2116 {
2117 DEBUG_PRINT_ERROR("%s, swvenc_start failed (%d)",
2118 __FUNCTION__, Ret);
2119 RETURN(-1);
2120 }
2121
2122 m_stopped = false;
2123 if (m_bIsRotationSupported){
2124 Ret = swvenc_rotation_init();
2125 if (Ret == SWVENC_S_UNSUPPORTED) {
2126 DEBUG_PRINT_ERROR("ERROR: Rotation not supported for this target");
2127 m_bIsRotationSupported = false;
2128 }
2129 }
2130 RETURN(0);
2131 }
2132
dev_flush(unsigned port)2133 OMX_U32 omx_venc::dev_flush(unsigned port)
2134 {
2135 ENTER_FUNC();
2136 SWVENC_STATUS Ret;
2137
2138 (void)port;
2139 Ret = swvenc_flush(m_hSwVenc);
2140 if (Ret != SWVENC_S_SUCCESS)
2141 {
2142 DEBUG_PRINT_ERROR("%s, swvenc_flush failed (%d)",
2143 __FUNCTION__, Ret);
2144 RETURN(-1);
2145 }
2146
2147 RETURN(0);
2148 }
2149
dev_start_done(void)2150 OMX_U32 omx_venc::dev_start_done(void)
2151 {
2152 ENTER_FUNC();
2153
2154 /* post START_DONE event as start is synchronus */
2155 post_event (0, OMX_ErrorNone, OMX_COMPONENT_GENERATE_START_DONE);
2156
2157 RETURN(0);
2158 }
2159
dev_set_message_thread_id(pthread_t tid)2160 OMX_U32 omx_venc::dev_set_message_thread_id(pthread_t tid)
2161 {
2162 ENTER_FUNC();
2163
2164 // nothing to be done for sw encoder
2165 (void)tid;
2166
2167 RETURN(true);
2168 }
2169
dev_use_buf(unsigned port)2170 bool omx_venc::dev_use_buf(unsigned port)
2171 {
2172 ENTER_FUNC();
2173 (void)port;
2174 RETURN(true);
2175 }
2176
dev_handle_empty_eos_buffer(void)2177 bool omx_venc::dev_handle_empty_eos_buffer(void)
2178 {
2179 ENTER_FUNC();
2180 SWVENC_STATUS Ret;
2181 SWVENC_IPBUFFER ipbuffer;
2182 ipbuffer.p_buffer = NULL;
2183 ipbuffer.filled_length =0;
2184 ipbuffer.flags = SWVENC_FLAG_EOS;
2185 Ret = swvenc_emptythisbuffer(m_hSwVenc, &ipbuffer);
2186 if (Ret != SWVENC_S_SUCCESS)
2187 {
2188 DEBUG_PRINT_ERROR("%s, swvenc_emptythisbuffer failed (%d)",
2189 __FUNCTION__, Ret);
2190 RETURN(false);
2191 }
2192 RETURN(true);
2193 }
2194
dev_free_buf(void * buf_addr,unsigned port)2195 bool omx_venc::dev_free_buf(void *buf_addr,unsigned port)
2196 {
2197 ENTER_FUNC();
2198
2199 (void)buf_addr;
2200 (void)port;
2201
2202 RETURN(true);
2203 }
2204
dev_empty_buf(void * buffer,void * pmem_data_buf,unsigned index,unsigned fd)2205 bool omx_venc::dev_empty_buf
2206 (
2207 void *buffer,
2208 void *pmem_data_buf,
2209 unsigned index,
2210 unsigned fd
2211 )
2212 {
2213 ENTER_FUNC();
2214
2215 SWVENC_STATUS Ret;
2216 SWVENC_IPBUFFER ipbuffer;
2217 OMX_BUFFERHEADERTYPE *bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
2218 unsigned int size = 0, filled_length, offset = 0;
2219 SWVENC_COLOR_FORMAT color_format;
2220 SWVENC_PROPERTY prop;
2221
2222 (void)pmem_data_buf;
2223 (void)index;
2224
2225 if (meta_mode_enable)
2226 {
2227 LEGACY_CAM_METADATA_TYPE *meta_buf = NULL;
2228 meta_buf = (LEGACY_CAM_METADATA_TYPE *)bufhdr->pBuffer;
2229 if(m_sInPortDef.format.video.eColorFormat == ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FormatAndroidOpaque))
2230 {
2231 DEBUG_PRINT_LOW("dev_empty_buf: color_format is QOMX_COLOR_FormatAndroidOpaque");
2232 set_format = true;
2233 }
2234 if(!meta_buf)
2235 {
2236 if (!bufhdr->nFilledLen && (bufhdr->nFlags & OMX_BUFFERFLAG_EOS))
2237 {
2238 ipbuffer.p_buffer= bufhdr->pBuffer;
2239 ipbuffer.size = bufhdr->nAllocLen;
2240 ipbuffer.filled_length = bufhdr->nFilledLen;
2241 DEBUG_PRINT_LOW("dev_empty_buf: empty EOS buffer");
2242 }
2243 else
2244 {
2245 return false;
2246 }
2247 }
2248 else
2249 {
2250 if (meta_buf->buffer_type == LEGACY_CAM_SOURCE)
2251 {
2252 offset = meta_buf->meta_handle->data[1];
2253 size = meta_buf->meta_handle->data[2];
2254 if (set_format && (meta_buf->meta_handle->numFds + meta_buf->meta_handle->numInts > 5))
2255 {
2256 m_sInPortFormat.eColorFormat = (OMX_COLOR_FORMATTYPE)meta_buf->meta_handle->data[5];
2257 }
2258 ipbuffer.p_buffer = (unsigned char *)mmap(NULL, size, PROT_READ|PROT_WRITE,MAP_SHARED, fd, offset);
2259 if (ipbuffer.p_buffer == MAP_FAILED)
2260 {
2261 DEBUG_PRINT_ERROR("mmap() failed for fd %d of size %d",fd,size);
2262 RETURN(false);
2263 }
2264 ipbuffer.size = size;
2265 ipbuffer.filled_length = size;
2266 }
2267 else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource)
2268 {
2269 VideoGrallocMetadata *meta_buf = (VideoGrallocMetadata *)bufhdr->pBuffer;
2270 private_handle_t *handle = (private_handle_t *)meta_buf->pHandle;
2271 size = handle->size;
2272 if (m_bUseAVTimerTimestamps) {
2273 uint64_t avTimerTimestampNs = bufhdr->nTimeStamp * 1000;
2274 if (getMetaData(handle, GET_VT_TIMESTAMP, &avTimerTimestampNs) == 0
2275 && avTimerTimestampNs > 0) {
2276 bufhdr->nTimeStamp = avTimerTimestampNs / 1000;
2277 DEBUG_PRINT_LOW("AVTimer TS: %llu us", (unsigned long long)bufhdr->nTimeStamp);
2278 }
2279 }
2280 if (set_format)
2281 {
2282 DEBUG_PRINT_LOW("color format = 0x%x",handle->format);
2283 if (((OMX_COLOR_FORMATTYPE)handle->format) != m_sInPortFormat.eColorFormat)
2284 {
2285 if(handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE)
2286 {
2287 m_sInPortFormat.eColorFormat = (OMX_COLOR_FORMATTYPE)
2288 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2289 }
2290 else
2291 {
2292 DEBUG_PRINT_ERROR("%s: OMX_IndexParamVideoPortFormat 0x%x invalid",
2293 __FUNCTION__,handle->format);
2294 RETURN(false);
2295 }
2296 }
2297 }
2298 ipbuffer.p_buffer = (unsigned char *)mmap(NULL, size, PROT_READ|PROT_WRITE,MAP_SHARED, fd, offset);
2299 if (ipbuffer.p_buffer == MAP_FAILED)
2300 {
2301 DEBUG_PRINT_ERROR("mmap() failed for fd %d of size %d",fd,size);
2302 RETURN(false);
2303 }
2304 ipbuffer.size = size;
2305 ipbuffer.filled_length = size;
2306 }
2307 else
2308 {
2309 //handles the use case for surface encode
2310 ipbuffer.p_buffer = bufhdr->pBuffer;
2311 ipbuffer.size = bufhdr->nAllocLen;
2312 ipbuffer.filled_length = bufhdr->nFilledLen;
2313 }
2314 if (set_format)
2315 {
2316 set_format = false;
2317 m_sInPortDef.format.video.eColorFormat = m_sInPortFormat.eColorFormat;
2318 Ret = swvenc_set_color_format(m_sInPortFormat.eColorFormat);
2319 if (Ret != SWVENC_S_SUCCESS)
2320 {
2321 DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
2322 __FUNCTION__, Ret);
2323 RETURN(false);
2324 }
2325 }
2326 }
2327 }
2328 else
2329 {
2330 ipbuffer.p_buffer = bufhdr->pBuffer;
2331 ipbuffer.size = bufhdr->nAllocLen;
2332 ipbuffer.filled_length = bufhdr->nFilledLen;
2333 }
2334 ipbuffer.flags = 0;
2335 if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
2336 {
2337 ipbuffer.flags |= SWVENC_FLAG_EOS;
2338 }
2339 ipbuffer.timestamp = bufhdr->nTimeStamp;
2340 ipbuffer.p_client_data = (unsigned char *)bufhdr;
2341
2342 DEBUG_PRINT_LOW("ETB: p_buffer (%p) size (%d) filled_len (%d) flags (0x%X) timestamp (%lld) clientData (%p)",
2343 ipbuffer.p_buffer,
2344 ipbuffer.size,
2345 ipbuffer.filled_length,
2346 (unsigned int)ipbuffer.flags,
2347 ipbuffer.timestamp,
2348 ipbuffer.p_client_data);
2349
2350 if (m_debug.in_buffer_log)
2351 {
2352 swvenc_input_log_buffers((const char*)ipbuffer.p_buffer, ipbuffer.filled_length);
2353 }
2354
2355 if (m_bIsRotationSupported && m_sConfigFrameRotation.nRotation != 0) {
2356 if(!swvenc_do_rotate((int)fd, ipbuffer, (OMX_U32)index)) {
2357 DEBUG_PRINT_ERROR("rotate failed");
2358 return OMX_ErrorUndefined;
2359 }
2360 }
2361
2362 Ret = swvenc_emptythisbuffer(m_hSwVenc, &ipbuffer);
2363 if (Ret != SWVENC_S_SUCCESS)
2364 {
2365 DEBUG_PRINT_ERROR("%s, swvenc_emptythisbuffer failed (%d)",
2366 __FUNCTION__, Ret);
2367 RETURN(false);
2368 }
2369
2370 RETURN(true);
2371 }
2372
dev_fill_buf(void * buffer,void * pmem_data_buf,unsigned index,unsigned fd)2373 bool omx_venc::dev_fill_buf
2374 (
2375 void *buffer,
2376 void *pmem_data_buf,
2377 unsigned index,
2378 unsigned fd
2379 )
2380 {
2381 ENTER_FUNC();
2382
2383 SWVENC_STATUS Ret;
2384
2385 SWVENC_OPBUFFER opbuffer;
2386 OMX_BUFFERHEADERTYPE *bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
2387
2388 (void)pmem_data_buf;
2389 (void)index;
2390 (void)fd;
2391
2392 opbuffer.p_buffer = bufhdr->pBuffer;
2393 opbuffer.size = bufhdr->nAllocLen;
2394 opbuffer.filled_length = bufhdr->nFilledLen;
2395 opbuffer.flags = bufhdr->nFlags;
2396 opbuffer.timestamp = bufhdr->nTimeStamp;
2397 opbuffer.p_client_data = (unsigned char *)bufhdr;
2398 opbuffer.frame_type = SWVENC_FRAME_TYPE_I;
2399
2400 DEBUG_PRINT_LOW("FTB: p_buffer (%p) size (%d) filled_len (%d) flags (0x%X) timestamp (%lld) clientData (%p)",
2401 opbuffer.p_buffer,
2402 opbuffer.size,
2403 opbuffer.filled_length,
2404 opbuffer.flags,
2405 opbuffer.timestamp,
2406 opbuffer.p_client_data);
2407
2408 if ( false == m_bSeqHdrRequested)
2409 {
2410 if (dev_get_seq_hdr(opbuffer.p_buffer, opbuffer.size, &opbuffer.filled_length))
2411 {
2412 bufhdr->nFilledLen = opbuffer.filled_length;
2413 bufhdr->nOffset = 0;
2414 bufhdr->nTimeStamp = 0;
2415 bufhdr->nFlags = OMX_BUFFERFLAG_CODECCONFIG;
2416
2417 DEBUG_PRINT_LOW("sending FBD with codec config");
2418 m_bSeqHdrRequested = true;
2419 post_event ((unsigned long)bufhdr,0,OMX_COMPONENT_GENERATE_FBD);
2420 }
2421 else
2422 {
2423 DEBUG_PRINT_ERROR("ERROR: couldn't get sequence header");
2424 post_event(OMX_EventError,OMX_ErrorUndefined,OMX_COMPONENT_GENERATE_EVENT);
2425 }
2426 }
2427 else
2428 {
2429 Ret = swvenc_fillthisbuffer(m_hSwVenc, &opbuffer);
2430 if (Ret != SWVENC_S_SUCCESS)
2431 {
2432 DEBUG_PRINT_ERROR("%s, swvenc_fillthisbuffer failed (%d)",
2433 __FUNCTION__, Ret);
2434 RETURN(false);
2435 }
2436 }
2437
2438 RETURN(true);
2439 }
2440
dev_get_seq_hdr(void * buffer,unsigned size,unsigned * hdrlen)2441 bool omx_venc::dev_get_seq_hdr
2442 (
2443 void *buffer,
2444 unsigned size,
2445 unsigned *hdrlen
2446 )
2447 {
2448 ENTER_FUNC();
2449
2450 SWVENC_STATUS Ret;
2451 SWVENC_OPBUFFER Buffer;
2452
2453 Buffer.p_buffer = (unsigned char*) buffer;
2454 Buffer.size = size;
2455
2456 Ret = swvenc_getsequenceheader(m_hSwVenc, &Buffer);
2457 if (Ret != SWVENC_S_SUCCESS)
2458 {
2459 DEBUG_PRINT_ERROR("%s, swvenc_getsequenceheader failed (%d)",
2460 __FUNCTION__, Ret);
2461 RETURN(false);
2462 }
2463
2464 *hdrlen = Buffer.filled_length;
2465
2466 RETURN(true);
2467 }
2468
dev_get_capability_ltrcount(OMX_U32 * min,OMX_U32 * max,OMX_U32 * step_size)2469 bool omx_venc::dev_get_capability_ltrcount
2470 (
2471 OMX_U32 *min,
2472 OMX_U32 *max,
2473 OMX_U32 *step_size
2474 )
2475 {
2476 ENTER_FUNC();
2477
2478 (void)min;
2479 (void)max;
2480 (void)step_size;
2481
2482 DEBUG_PRINT_ERROR("Get Capability LTR Count is not supported");
2483
2484 RETURN(false);
2485 }
2486
dev_get_vui_timing_info(OMX_U32 * enabled)2487 bool omx_venc::dev_get_vui_timing_info(OMX_U32 *enabled)
2488 {
2489 ENTER_FUNC();
2490
2491 (void)enabled;
2492 DEBUG_PRINT_ERROR("Get vui timing information is not supported");
2493
2494 RETURN(false);
2495 }
2496
dev_get_vqzip_sei_info(OMX_U32 * enabled)2497 bool omx_venc::dev_get_vqzip_sei_info(OMX_U32 *enabled)
2498 {
2499 ENTER_FUNC();
2500
2501 (void)enabled;
2502 DEBUG_PRINT_ERROR("Get vqzip sei info is not supported");
2503
2504 RETURN(false);
2505 }
2506
dev_get_peak_bitrate(OMX_U32 * peakbitrate)2507 bool omx_venc::dev_get_peak_bitrate(OMX_U32 *peakbitrate)
2508 {
2509 //TBD: store the peak bitrate in class and return here;
2510 ENTER_FUNC();
2511
2512 (void)peakbitrate;
2513 DEBUG_PRINT_ERROR("Get peak bitrate is not supported");
2514
2515 RETURN(false);
2516 }
2517
dev_get_batch_size(OMX_U32 * size)2518 bool omx_venc::dev_get_batch_size(OMX_U32 *size)
2519 {
2520 ENTER_FUNC();
2521
2522 (void)size;
2523
2524 DEBUG_PRINT_ERROR("Get batch size is not supported");
2525
2526 RETURN(false);
2527 }
2528
dev_get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE * profileLevelType)2529 OMX_ERRORTYPE omx_venc::dev_get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2530 {
2531 ENTER_FUNC();
2532 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2533
2534 if (profileLevelType == NULL)
2535 {
2536 DEBUG_PRINT_ERROR("p_profilelevel = NULL");
2537 return OMX_ErrorBadParameter;
2538 }
2539
2540 if (profileLevelType->nPortIndex == 1) {
2541 if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263)
2542 {
2543 if (profileLevelType->nProfileIndex == 0)
2544 {
2545 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2546 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2547
2548 DEBUG_PRINT_HIGH("H.263 baseline profile, level 70");
2549 }
2550 else
2551 {
2552 DEBUG_PRINT_LOW("dev_get_supported_profile_level:nProfileIndex ret NoMore %u",
2553 (unsigned int)profileLevelType->nProfileIndex);
2554 eRet = OMX_ErrorNoMore;
2555 }
2556 }
2557 else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4)
2558 {
2559 if (profileLevelType->nProfileIndex == 0)
2560 {
2561 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2562 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level6;
2563
2564 DEBUG_PRINT_LOW("MPEG-4 simple profile, level 6");
2565 }
2566 else
2567 {
2568 DEBUG_PRINT_LOW("dev_get_supported_profile_level:nProfileIndex ret NoMore %u",
2569 (unsigned int)profileLevelType->nProfileIndex);
2570 eRet = OMX_ErrorNoMore;
2571 }
2572 }
2573 else
2574 {
2575 DEBUG_PRINT_ERROR("get_parameter: dev_get_supported_profile_level ret NoMore");
2576 eRet = OMX_ErrorNoMore;
2577 }
2578 }
2579 else
2580 {
2581 DEBUG_PRINT_ERROR("get_parameter: dev_get_supported_profile_level should be queried on Input port only %u",
2582 (unsigned int)profileLevelType->nPortIndex);
2583 eRet = OMX_ErrorBadPortIndex;
2584 }
2585 return eRet;
2586 }
2587
dev_get_supported_color_format(unsigned index,OMX_U32 * colorFormat)2588 bool omx_venc::dev_get_supported_color_format(unsigned index, OMX_U32 *colorFormat) {
2589 // we support two formats
2590 // index 0 - Venus flavour of YUV420SP
2591 // index 1 - opaque which internally maps to YUV420SP
2592 // index 2 - vannilla YUV420SP
2593 // this can be extended in the future
2594 int supportedFormats[] = {
2595 [0] = QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m,
2596 [1] = QOMX_COLOR_FormatYVU420SemiPlanar,
2597 [2] = QOMX_COLOR_FormatAndroidOpaque,
2598 [3] = OMX_COLOR_FormatYUV420SemiPlanar,
2599 };
2600
2601 if (index > (sizeof(supportedFormats)/sizeof(*supportedFormats) - 1))
2602 return false;
2603 *colorFormat = supportedFormats[index];
2604 return true;
2605 }
2606
dev_loaded_start()2607 bool omx_venc::dev_loaded_start()
2608 {
2609 ENTER_FUNC();
2610 RETURN(true);
2611 }
2612
dev_loaded_stop()2613 bool omx_venc::dev_loaded_stop()
2614 {
2615 ENTER_FUNC();
2616 RETURN(true);
2617 }
2618
dev_loaded_start_done()2619 bool omx_venc::dev_loaded_start_done()
2620 {
2621 ENTER_FUNC();
2622 RETURN(true);
2623 }
2624
dev_loaded_stop_done()2625 bool omx_venc::dev_loaded_stop_done()
2626 {
2627 ENTER_FUNC();
2628 RETURN(true);
2629 }
2630
is_streamon_done(OMX_U32 port)2631 bool omx_venc::is_streamon_done(OMX_U32 port)
2632 {
2633 if (PORT_INDEX_OUT <= port)
2634 ENTER_FUNC();
2635 RETURN(false);
2636 }
2637
dev_get_buf_req(OMX_U32 * min_buff_count,OMX_U32 * actual_buff_count,OMX_U32 * buff_size,OMX_U32 port)2638 bool omx_venc::dev_get_buf_req(OMX_U32 *min_buff_count,
2639 OMX_U32 *actual_buff_count,
2640 OMX_U32 *buff_size,
2641 OMX_U32 port)
2642 {
2643 ENTER_FUNC();
2644
2645 bool bRet = true;
2646 OMX_PARAM_PORTDEFINITIONTYPE *PortDef;
2647
2648 if (PORT_INDEX_IN == port)
2649 {
2650 PortDef = &m_sInPortDef;
2651 }
2652 else if (PORT_INDEX_OUT == port)
2653 {
2654 PortDef = &m_sOutPortDef;
2655 }
2656 else
2657 {
2658 DEBUG_PRINT_ERROR("ERROR: %s, Unsupported parameter", __FUNCTION__);
2659 bRet = false;
2660 }
2661
2662 if (true == bRet)
2663 {
2664 *min_buff_count = PortDef->nBufferCountMin;
2665 *actual_buff_count = PortDef->nBufferCountActual;
2666 *buff_size = PortDef->nBufferSize;
2667 }
2668
2669 RETURN(true);
2670 }
2671
dev_set_buf_req(OMX_U32 const * min_buff_count,OMX_U32 const * actual_buff_count,OMX_U32 const * buff_size,OMX_U32 port)2672 bool omx_venc::dev_set_buf_req
2673 (
2674 OMX_U32 const *min_buff_count,
2675 OMX_U32 const *actual_buff_count,
2676 OMX_U32 const *buff_size,
2677 OMX_U32 port
2678 )
2679 {
2680 ENTER_FUNC();
2681
2682 SWVENC_STATUS Ret;
2683 OMX_PARAM_PORTDEFINITIONTYPE *PortDef;
2684
2685 (void)min_buff_count;
2686 if (PORT_INDEX_IN == port)
2687 {
2688 PortDef = &m_sInPortDef;
2689 }
2690 else if (PORT_INDEX_OUT == port)
2691 {
2692 PortDef = &m_sOutPortDef;
2693 }
2694 else
2695 {
2696 DEBUG_PRINT_ERROR("ERROR: %s, Unsupported parameter", __FUNCTION__);
2697 RETURN(false);
2698 }
2699
2700 if (*actual_buff_count < PortDef->nBufferCountMin)
2701 {
2702 DEBUG_PRINT_ERROR("ERROR: %s, (actual,min) buffer count (%d, %d)",
2703 __FUNCTION__, *actual_buff_count, PortDef->nBufferCountMin);
2704 RETURN(false);
2705 }
2706 if (false == meta_mode_enable)
2707 {
2708 if (*buff_size < PortDef->nBufferSize)
2709 {
2710 DEBUG_PRINT_ERROR("ERROR: %s, (new,old) buffer count (%d, %d)",
2711 __FUNCTION__, *actual_buff_count, PortDef->nBufferCountMin);
2712 RETURN(false);
2713 }
2714 }
2715
2716 RETURN(true);
2717 }
2718
dev_is_video_session_supported(OMX_U32 width,OMX_U32 height)2719 bool omx_venc::dev_is_video_session_supported(OMX_U32 width, OMX_U32 height)
2720 {
2721 ENTER_FUNC();
2722
2723 if ( (width * height < m_capability.min_width * m_capability.min_height) ||
2724 (width * height > m_capability.max_width * m_capability.max_height)
2725 )
2726 {
2727 DEBUG_PRINT_ERROR(
2728 "Unsupported Resolution WxH = (%u)x(%u) Supported Range = min (%d)x(%d) - max (%d)x(%d)",
2729 width, height,
2730 m_capability.min_width, m_capability.min_height,
2731 m_capability.max_width, m_capability.max_height);
2732 RETURN(false);
2733 }
2734
2735 RETURN(true);
2736 }
2737
dev_buffer_ready_to_queue(OMX_BUFFERHEADERTYPE * buffer)2738 bool omx_venc::dev_buffer_ready_to_queue(OMX_BUFFERHEADERTYPE *buffer)
2739 {
2740 ENTER_FUNC();
2741
2742 (void)buffer;
2743 RETURN(true);
2744 }
dev_handle_output_extradata(void * buffer,int fd)2745 int omx_venc::dev_handle_output_extradata(void *buffer, int fd)
2746 {
2747 ENTER_FUNC();
2748
2749 (void)buffer;
2750 (void)fd;
2751
2752 RETURN(true);
2753 }
2754
dev_handle_input_extradata(void * buffer,int fd,int index)2755 int omx_venc::dev_handle_input_extradata(void *buffer, int fd, int index)
2756 {
2757 ENTER_FUNC();
2758
2759 (void)buffer;
2760 (void)fd;
2761 (void)index;
2762
2763 RETURN(true);
2764 }
2765
dev_set_extradata_cookie(void * buffer)2766 void omx_venc::dev_set_extradata_cookie(void *buffer)
2767 {
2768 ENTER_FUNC();
2769
2770 (void)buffer;
2771 }
2772
dev_set_format(int color)2773 int omx_venc::dev_set_format(int color)
2774 {
2775 ENTER_FUNC();
2776
2777 (void)color;
2778
2779 RETURN(true);
2780 //return handle->venc_set_format(color);
2781 }
2782
dev_get_dimensions(OMX_U32 index,OMX_U32 * width,OMX_U32 * height)2783 bool omx_venc::dev_get_dimensions(OMX_U32 index, OMX_U32 *width, OMX_U32 *height)
2784 {
2785 ENTER_FUNC();
2786
2787 (void)index;
2788 (void)width;
2789 (void)height;
2790
2791 RETURN(true);
2792 }
2793
dev_color_align(OMX_BUFFERHEADERTYPE * buffer,OMX_U32 width,OMX_U32 height)2794 bool omx_venc::dev_color_align(OMX_BUFFERHEADERTYPE *buffer,
2795 OMX_U32 width, OMX_U32 height)
2796 {
2797 ENTER_FUNC();
2798
2799 if(secure_session) {
2800 DEBUG_PRINT_ERROR("Cannot align colors in secure session.");
2801 RETURN(false);
2802 }
2803 return swvenc_color_align(buffer, width,height);
2804 }
2805
is_secure_session()2806 bool omx_venc::is_secure_session()
2807 {
2808 ENTER_FUNC();
2809
2810 RETURN(secure_session);
2811 }
2812
dev_get_output_log_flag()2813 bool omx_venc::dev_get_output_log_flag()
2814 {
2815 ENTER_FUNC();
2816
2817 RETURN(m_debug.out_buffer_log == 1);
2818 }
2819
dev_output_log_buffers(const char * buffer,int bufferlen,uint64_t ts)2820 int omx_venc::dev_output_log_buffers(const char *buffer, int bufferlen, uint64_t ts)
2821 {
2822 (void) ts;
2823 ENTER_FUNC();
2824
2825 if (m_debug.out_buffer_log && !m_debug.outfile)
2826 {
2827 int size = 0;
2828 int width = m_sInPortDef.format.video.nFrameWidth;
2829 int height = m_sInPortDef.format.video.nFrameHeight;
2830 if(SWVENC_CODEC_MPEG4 == m_codec)
2831 {
2832 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX,
2833 "%s/output_enc_%d_%d_%p.m4v",
2834 m_debug.log_loc, width, height, this);
2835 }
2836 else if(SWVENC_CODEC_H263 == m_codec)
2837 {
2838 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX,
2839 "%s/output_enc_%d_%d_%p.263",
2840 m_debug.log_loc, width, height, this);
2841 }
2842 if ((size > PROPERTY_VALUE_MAX) || (size < 0))
2843 {
2844 DEBUG_PRINT_ERROR("Failed to open output file: %s for logging as size:%d",
2845 m_debug.outfile_name, size);
2846 RETURN(-1);
2847 }
2848 DEBUG_PRINT_LOW("output filename = %s", m_debug.outfile_name);
2849 m_debug.outfile = fopen(m_debug.outfile_name, "ab");
2850 if (!m_debug.outfile)
2851 {
2852 DEBUG_PRINT_ERROR("Failed to open output file: %s for logging errno:%d",
2853 m_debug.outfile_name, errno);
2854 m_debug.outfile_name[0] = '\0';
2855 RETURN(-1);
2856 }
2857 }
2858 if (m_debug.outfile && buffer && bufferlen)
2859 {
2860 DEBUG_PRINT_LOW("%s buffer length: %d", __func__, bufferlen);
2861 fwrite(buffer, bufferlen, 1, m_debug.outfile);
2862 }
2863
2864 RETURN(0);
2865 }
2866
swvenc_input_log_buffers(const char * buffer,int bufferlen)2867 int omx_venc::swvenc_input_log_buffers(const char *buffer, int bufferlen)
2868 {
2869 int width = m_sInPortDef.format.video.nFrameWidth;
2870 int height = m_sInPortDef.format.video.nFrameHeight;
2871 int stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
2872 int scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
2873 char *temp = (char*)buffer;
2874
2875 if (!m_debug.infile)
2876 {
2877 int size = snprintf(m_debug.infile_name, PROPERTY_VALUE_MAX,
2878 "%s/input_enc_%d_%d_%p.yuv",
2879 m_debug.log_loc, width, height, this);
2880 if ((size > PROPERTY_VALUE_MAX) || (size < 0))
2881 {
2882 DEBUG_PRINT_ERROR("Failed to open input file: %s for logging size:%d",
2883 m_debug.infile_name, size);
2884 RETURN(-1);
2885 }
2886 DEBUG_PRINT_LOW("input filename = %s", m_debug.infile_name);
2887 m_debug.infile = fopen (m_debug.infile_name, "ab");
2888 if (!m_debug.infile)
2889 {
2890 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging",
2891 m_debug.infile_name);
2892 m_debug.infile_name[0] = '\0';
2893 RETURN(-1);
2894 }
2895 }
2896 if (m_debug.infile && buffer && bufferlen)
2897 {
2898 DEBUG_PRINT_LOW("%s buffer length: %d", __func__, bufferlen);
2899 for (int i = 0; i < height; i++)
2900 {
2901 fwrite(temp, width, 1, m_debug.infile);
2902 temp += stride;
2903 }
2904 temp = (char*)(buffer + (stride * scanlines));
2905 for(int i = 0; i < height/2; i++)
2906 {
2907 fwrite(temp, width, 1, m_debug.infile);
2908 temp += stride;
2909 }
2910 }
2911
2912 RETURN(0);
2913 }
2914
dev_extradata_log_buffers(char * buffer)2915 int omx_venc::dev_extradata_log_buffers(char *buffer)
2916 {
2917 ENTER_FUNC();
2918
2919 (void)buffer;
2920
2921 RETURN(true);
2922 //return handle->venc_extradata_log_buffers(buffer);
2923 }
2924
swvenc_get_buffer_req(OMX_U32 * min_buff_count,OMX_U32 * actual_buff_count,OMX_U32 * buff_size,OMX_U32 * buff_alignment,OMX_U32 port)2925 SWVENC_STATUS omx_venc::swvenc_get_buffer_req
2926 (
2927 OMX_U32 *min_buff_count,
2928 OMX_U32 *actual_buff_count,
2929 OMX_U32 *buff_size,
2930 OMX_U32 *buff_alignment,
2931 OMX_U32 port
2932 )
2933 {
2934 ENTER_FUNC();
2935
2936 SWVENC_PROPERTY Prop;
2937 SWVENC_STATUS Ret;
2938 OMX_PARAM_PORTDEFINITIONTYPE *PortDef;
2939
2940 Prop.id = SWVENC_PROPERTY_ID_BUFFER_REQ;
2941 if (PORT_INDEX_IN == port)
2942 {
2943 Prop.info.buffer_req.type = SWVENC_BUFFER_INPUT;
2944 }
2945 else if (PORT_INDEX_OUT == port)
2946 {
2947 Prop.info.buffer_req.type = SWVENC_BUFFER_OUTPUT;
2948 }
2949 else
2950 {
2951 DEBUG_PRINT_ERROR("ERROR: %s, Unsupported parameter", __FUNCTION__);
2952 RETURN(SWVENC_S_INVALID_PARAMETERS);
2953 }
2954
2955 Ret = swvenc_getproperty(m_hSwVenc, &Prop);
2956 if (Ret != SWVENC_S_SUCCESS)
2957 {
2958 DEBUG_PRINT_ERROR("ERROR: %s, swvenc_setproperty failed (%d)", __FUNCTION__,
2959 Ret);
2960 RETURN(SWVENC_S_INVALID_PARAMETERS);
2961 }
2962
2963 *buff_size = Prop.info.buffer_req.size;
2964 *min_buff_count = Prop.info.buffer_req.mincount;
2965 *actual_buff_count = Prop.info.buffer_req.mincount;
2966 *buff_alignment = Prop.info.buffer_req.alignment;
2967
2968 RETURN(Ret);
2969 }
2970
swvenc_empty_buffer_done_cb(SWVENC_HANDLE swvenc,SWVENC_IPBUFFER * p_ipbuffer,void * p_client)2971 SWVENC_STATUS omx_venc::swvenc_empty_buffer_done_cb
2972 (
2973 SWVENC_HANDLE swvenc,
2974 SWVENC_IPBUFFER *p_ipbuffer,
2975 void *p_client
2976 )
2977 {
2978 ENTER_FUNC();
2979
2980 (void)swvenc;
2981 SWVENC_STATUS eRet = SWVENC_S_SUCCESS;
2982 omx_venc *omx = reinterpret_cast<omx_venc*>(p_client);
2983
2984 if (p_ipbuffer == NULL)
2985 {
2986 eRet = SWVENC_S_FAILURE;
2987 }
2988 else
2989 {
2990 omx->swvenc_empty_buffer_done(p_ipbuffer);
2991 }
2992 return eRet;
2993 }
2994
swvenc_empty_buffer_done(SWVENC_IPBUFFER * p_ipbuffer)2995 SWVENC_STATUS omx_venc::swvenc_empty_buffer_done
2996 (
2997 SWVENC_IPBUFFER *p_ipbuffer
2998 )
2999 {
3000 SWVENC_STATUS eRet = SWVENC_S_SUCCESS;
3001 OMX_ERRORTYPE error = OMX_ErrorNone;
3002 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
3003
3004 //omx_video *omx = reinterpret_cast<omx_video*>(p_client);
3005 omxhdr = (OMX_BUFFERHEADERTYPE*)p_ipbuffer->p_client_data;
3006
3007 DEBUG_PRINT_LOW("EBD: clientData (%p)", p_ipbuffer->p_client_data);
3008
3009 if ( (omxhdr == NULL) ||
3010 ( ((OMX_U32)(omxhdr - m_inp_mem_ptr) >m_sInPortDef.nBufferCountActual) &&
3011 ((OMX_U32)(omxhdr - meta_buffer_hdr) >m_sInPortDef.nBufferCountActual)
3012 )
3013 )
3014 {
3015 omxhdr = NULL;
3016 error = OMX_ErrorUndefined;
3017 }
3018
3019 if (m_pIpbuffers != nullptr) {
3020 int index = omxhdr - ((mUseProxyColorFormat && !mUsesColorConversion) ? meta_buffer_hdr : m_inp_mem_ptr);
3021 DEBUG_PRINT_HIGH("restore ipbuffer[p_buffer(%p), size(%d), filled_length(%d)] to original ipbuffer[p_buffer(%p), size(%d), filled_length(%d)]",
3022 p_ipbuffer->p_buffer,
3023 p_ipbuffer->size,
3024 p_ipbuffer->filled_length,
3025 m_pIpbuffers[index].p_buffer,
3026 m_pIpbuffers[index].size,
3027 m_pIpbuffers[index].filled_length);
3028 p_ipbuffer->size = m_pIpbuffers[index].size;
3029 p_ipbuffer->filled_length = m_pIpbuffers[index].filled_length;
3030 p_ipbuffer->p_buffer = m_pIpbuffers[index].p_buffer;
3031 }
3032
3033 if (omxhdr != NULL)
3034 {
3035 // unmap the input buffer->pBuffer
3036 omx_release_meta_buffer(omxhdr);
3037 #ifdef _ANDROID_ICS_
3038 if (meta_mode_enable)
3039 {
3040 LEGACY_CAM_METADATA_TYPE *meta_buf = NULL;
3041 unsigned int size = 0;
3042 meta_buf = (LEGACY_CAM_METADATA_TYPE *)omxhdr->pBuffer;
3043 if (meta_buf)
3044 {
3045 if (meta_buf->buffer_type == LEGACY_CAM_SOURCE)
3046 {
3047 size = meta_buf->meta_handle->data[2];
3048 }
3049 else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource)
3050 {
3051 VideoGrallocMetadata *meta_buf = (VideoGrallocMetadata *)omxhdr->pBuffer;
3052 private_handle_t *handle = (private_handle_t *)meta_buf->pHandle;
3053 size = handle->size;
3054 }
3055 }
3056 int status = munmap(p_ipbuffer->p_buffer, size);
3057 DEBUG_PRINT_HIGH("Unmapped pBuffer <%p> size <%d> status <%d>", p_ipbuffer->p_buffer, size, status);
3058 }
3059 #endif
3060 post_event ((unsigned long)omxhdr,error,OMX_COMPONENT_GENERATE_EBD);
3061 }
3062
3063 RETURN(eRet);
3064 }
3065
swvenc_fill_buffer_done_cb(SWVENC_HANDLE swvenc,SWVENC_OPBUFFER * p_opbuffer,void * p_client)3066 SWVENC_STATUS omx_venc::swvenc_fill_buffer_done_cb
3067 (
3068 SWVENC_HANDLE swvenc,
3069 SWVENC_OPBUFFER *p_opbuffer,
3070 void *p_client
3071 )
3072 {
3073 ENTER_FUNC();
3074
3075 SWVENC_STATUS eRet = SWVENC_S_SUCCESS;
3076 OMX_ERRORTYPE error = OMX_ErrorNone;
3077 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
3078 omx_video *omx = reinterpret_cast<omx_video*>(p_client);
3079
3080 (void)swvenc;
3081
3082 if (p_opbuffer != NULL)
3083 {
3084 omxhdr = (OMX_BUFFERHEADERTYPE*)p_opbuffer->p_client_data;
3085 }
3086
3087 if ( (p_opbuffer != NULL) &&
3088 ((OMX_U32)(omxhdr - omx->m_out_mem_ptr) < omx->m_sOutPortDef.nBufferCountActual)
3089 )
3090 {
3091 DEBUG_PRINT_LOW("FBD: clientData (%p) buffer (%p) filled_lengh (%d) flags (0x%x) ts (%lld)",
3092 p_opbuffer->p_client_data,
3093 p_opbuffer->p_buffer,
3094 p_opbuffer->filled_length,
3095 p_opbuffer->flags,
3096 p_opbuffer->timestamp);
3097
3098 if (p_opbuffer->filled_length <= omxhdr->nAllocLen)
3099 {
3100 omxhdr->pBuffer = p_opbuffer->p_buffer;
3101 omxhdr->nFilledLen = p_opbuffer->filled_length;
3102 omxhdr->nOffset = 0;
3103 omxhdr->nTimeStamp = p_opbuffer->timestamp;
3104 omxhdr->nFlags = 0;
3105 if (SWVENC_FRAME_TYPE_I == p_opbuffer->frame_type)
3106 {
3107 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
3108 }
3109 if (SWVENC_FLAG_EOS & p_opbuffer->flags)
3110 {
3111 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
3112 }
3113 if(omxhdr->nFilledLen)
3114 {
3115 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
3116 }
3117 DEBUG_PRINT_LOW("o/p flag = 0x%x", omxhdr->nFlags);
3118
3119 /* Use buffer case */
3120 if (omx->output_use_buffer && !omx->m_use_output_pmem)
3121 {
3122 DEBUG_PRINT_LOW("memcpy() for o/p Heap UseBuffer");
3123 memcpy( omxhdr->pBuffer,
3124 (p_opbuffer->p_buffer),
3125 p_opbuffer->filled_length );
3126 }
3127 }
3128 else
3129 {
3130 omxhdr->nFilledLen = 0;
3131 }
3132
3133 }
3134 else
3135 {
3136 omxhdr = NULL;
3137 error = OMX_ErrorUndefined;
3138 }
3139
3140 omx->post_event ((unsigned long)omxhdr,error,OMX_COMPONENT_GENERATE_FBD);
3141
3142 RETURN(eRet);
3143 }
3144
swvenc_handle_event_cb(SWVENC_HANDLE swvenc,SWVENC_EVENT event,void * p_client)3145 SWVENC_STATUS omx_venc::swvenc_handle_event_cb
3146 (
3147 SWVENC_HANDLE swvenc,
3148 SWVENC_EVENT event,
3149 void *p_client
3150 )
3151 {
3152 ENTER_FUNC();
3153
3154 SWVENC_STATUS eRet = SWVENC_S_SUCCESS;
3155 omx_video *omx = reinterpret_cast<omx_video*>(p_client);
3156
3157 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
3158
3159 (void)swvenc;
3160
3161 if (omx == NULL || p_client == NULL)
3162 {
3163 DEBUG_PRINT_ERROR("ERROR: %s invalid i/p params", __FUNCTION__);
3164 RETURN(SWVENC_S_NULL_POINTER);
3165 }
3166
3167 DEBUG_PRINT_LOW("swvenc_handle_event_cb - event = %d", event);
3168
3169 switch (event)
3170 {
3171 case SWVENC_EVENT_FLUSH_DONE:
3172 {
3173 DEBUG_PRINT_ERROR("SWVENC_EVENT_FLUSH_DONE input_flush_progress %d output_flush_progress %d",
3174 omx->input_flush_progress, omx->output_flush_progress);
3175 if (omx->input_flush_progress)
3176 {
3177 omx->post_event ((unsigned)NULL, SWVENC_S_SUCCESS,
3178 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
3179 }
3180 if (omx->output_flush_progress)
3181 {
3182 omx->post_event ((unsigned)NULL, SWVENC_S_SUCCESS,
3183 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
3184 }
3185 break;
3186 }
3187
3188 case SWVENC_EVENT_FATAL_ERROR:
3189 {
3190 DEBUG_PRINT_ERROR("ERROR: SWVENC_EVENT_FATAL_ERROR");
3191 omx->omx_report_error();
3192 break;
3193 }
3194
3195 default:
3196 DEBUG_PRINT_HIGH("Unknown event received : %d", event);
3197 break;
3198 }
3199
3200 RETURN(eRet);
3201 }
3202
swvenc_set_rc_mode(OMX_VIDEO_CONTROLRATETYPE eControlRate)3203 SWVENC_STATUS omx_venc::swvenc_set_rc_mode
3204 (
3205 OMX_VIDEO_CONTROLRATETYPE eControlRate
3206 )
3207 {
3208 ENTER_FUNC();
3209
3210 SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
3211 SWVENC_RC_MODE rc_mode;
3212 SWVENC_PROPERTY Prop;
3213
3214 switch (eControlRate)
3215 {
3216 case OMX_Video_ControlRateDisable:
3217 rc_mode = SWVENC_RC_MODE_NONE;
3218 break;
3219 case OMX_Video_ControlRateVariableSkipFrames:
3220 rc_mode = SWVENC_RC_MODE_VBR_VFR;
3221 break;
3222 case OMX_Video_ControlRateVariable:
3223 rc_mode = SWVENC_RC_MODE_VBR_CFR;
3224 break;
3225 case OMX_Video_ControlRateConstantSkipFrames:
3226 rc_mode = SWVENC_RC_MODE_CBR_VFR;
3227 break;
3228 case OMX_Video_ControlRateConstant:
3229 rc_mode = SWVENC_RC_MODE_CBR_CFR;
3230 break;
3231 default:
3232 DEBUG_PRINT_ERROR("ERROR: UNKNOWN RC MODE");
3233 Ret = SWVENC_S_FAILURE;
3234 break;
3235 }
3236
3237 if (SWVENC_S_SUCCESS == Ret)
3238 {
3239 Prop.id = SWVENC_PROPERTY_ID_RC_MODE;
3240 Prop.info.rc_mode = rc_mode;
3241 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
3242 if (Ret != SWVENC_S_SUCCESS)
3243 {
3244 DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
3245 __FUNCTION__, Ret);
3246 RETURN(SWVENC_S_FAILURE);
3247 }
3248 }
3249
3250 RETURN(Ret);
3251 }
3252
swvenc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)3253 SWVENC_STATUS omx_venc::swvenc_set_profile_level
3254 (
3255 OMX_U32 eProfile,
3256 OMX_U32 eLevel
3257 )
3258 {
3259 ENTER_FUNC();
3260
3261 SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
3262 SWVENC_PROPERTY Prop;
3263 SWVENC_PROFILE Profile;
3264 SWVENC_LEVEL Level;
3265
3266 /* set the profile */
3267 if (SWVENC_CODEC_MPEG4 == m_codec)
3268 {
3269 switch (eProfile)
3270 {
3271 case OMX_VIDEO_MPEG4ProfileSimple:
3272 Profile.mpeg4 = SWVENC_PROFILE_MPEG4_SIMPLE;
3273 break;
3274 case OMX_VIDEO_MPEG4ProfileAdvancedSimple:
3275 Profile.mpeg4 = SWVENC_PROFILE_MPEG4_ADVANCED_SIMPLE;
3276 break;
3277 default:
3278 DEBUG_PRINT_ERROR("ERROR: UNKNOWN PROFILE");
3279 Ret = SWVENC_S_FAILURE;
3280 break;
3281 }
3282 switch (eLevel)
3283 {
3284 case OMX_VIDEO_MPEG4Level0:
3285 Level.mpeg4 = SWVENC_LEVEL_MPEG4_0;
3286 break;
3287 case OMX_VIDEO_MPEG4Level0b:
3288 Level.mpeg4 = SWVENC_LEVEL_MPEG4_0B;
3289 break;
3290 case OMX_VIDEO_MPEG4Level1:
3291 Level.mpeg4 = SWVENC_LEVEL_MPEG4_1;
3292 break;
3293 case OMX_VIDEO_MPEG4Level2:
3294 Level.mpeg4 = SWVENC_LEVEL_MPEG4_2;
3295 break;
3296 case OMX_VIDEO_MPEG4Level3:
3297 Level.mpeg4 = SWVENC_LEVEL_MPEG4_3;
3298 break;
3299 case OMX_VIDEO_MPEG4Level4:
3300 Level.mpeg4 = SWVENC_LEVEL_MPEG4_4;
3301 break;
3302 case OMX_VIDEO_MPEG4Level4a:
3303 Level.mpeg4 = SWVENC_LEVEL_MPEG4_4A;
3304 break;
3305 case OMX_VIDEO_MPEG4Level5:
3306 Level.mpeg4 = SWVENC_LEVEL_MPEG4_5;
3307 break;
3308 case OMX_VIDEO_MPEG4Level6:
3309 Level.mpeg4 = SWVENC_LEVEL_MPEG4_6;
3310 break;
3311 default:
3312 DEBUG_PRINT_ERROR("ERROR: UNKNOWN LEVEL");
3313 Ret = SWVENC_S_FAILURE;
3314 break;
3315 }
3316 }
3317 else if (SWVENC_CODEC_H263 == m_codec)
3318 {
3319 switch (eProfile)
3320 {
3321 case OMX_VIDEO_H263ProfileBaseline:
3322 Profile.h263 = SWVENC_PROFILE_H263_BASELINE;
3323 break;
3324 default:
3325 DEBUG_PRINT_ERROR("ERROR: UNKNOWN PROFILE");
3326 Ret = SWVENC_S_FAILURE;
3327 break;
3328 }
3329 switch (eLevel)
3330 {
3331 case OMX_VIDEO_H263Level10:
3332 Level.h263 = SWVENC_LEVEL_H263_10;
3333 break;
3334 case OMX_VIDEO_H263Level20:
3335 Level.h263 = SWVENC_LEVEL_H263_20;
3336 break;
3337 case OMX_VIDEO_H263Level30:
3338 Level.h263 = SWVENC_LEVEL_H263_30;
3339 break;
3340 case OMX_VIDEO_H263Level40:
3341 Level.h263 = SWVENC_LEVEL_H263_40;
3342 break;
3343 case OMX_VIDEO_H263Level50:
3344 Level.h263 = SWVENC_LEVEL_H263_50;
3345 break;
3346 case OMX_VIDEO_H263Level60:
3347 Level.h263 = SWVENC_LEVEL_H263_60;
3348 break;
3349 case OMX_VIDEO_H263Level70:
3350 Level.h263 = SWVENC_LEVEL_H263_70;
3351 break;
3352 default:
3353 DEBUG_PRINT_ERROR("ERROR: UNKNOWN LEVEL");
3354 Ret = SWVENC_S_FAILURE;
3355 break;
3356 }
3357 }
3358 else
3359 {
3360 DEBUG_PRINT_ERROR("ERROR: UNSUPPORTED CODEC");
3361 Ret = SWVENC_S_FAILURE;
3362 }
3363
3364 if (SWVENC_S_SUCCESS == Ret)
3365 {
3366 Prop.id = SWVENC_PROPERTY_ID_PROFILE;
3367 Prop.info.profile = Profile;
3368
3369 /* set the profile */
3370 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
3371 if (Ret != SWVENC_S_SUCCESS)
3372 {
3373 DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
3374 __FUNCTION__, Ret);
3375 RETURN(SWVENC_S_FAILURE);
3376 }
3377
3378 /* set the level */
3379 Prop.id = SWVENC_PROPERTY_ID_LEVEL;
3380 Prop.info.level = Level;
3381
3382 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
3383 if (Ret != SWVENC_S_SUCCESS)
3384 {
3385 DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
3386 __FUNCTION__, Ret);
3387 RETURN(SWVENC_S_FAILURE);
3388 }
3389 }
3390
3391 RETURN(Ret);
3392 }
3393
swvenc_set_intra_refresh(OMX_VIDEO_PARAM_INTRAREFRESHTYPE * IntraRefresh)3394 SWVENC_STATUS omx_venc::swvenc_set_intra_refresh
3395 (
3396 OMX_VIDEO_PARAM_INTRAREFRESHTYPE *IntraRefresh
3397 )
3398 {
3399 ENTER_FUNC();
3400
3401 SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
3402 SWVENC_IR_CONFIG ir_config;
3403 SWVENC_PROPERTY Prop;
3404
3405 switch (IntraRefresh->eRefreshMode)
3406 {
3407 case OMX_VIDEO_IntraRefreshCyclic:
3408 Prop.info.ir_config.mode = SWVENC_IR_MODE_CYCLIC;
3409 break;
3410 case OMX_VIDEO_IntraRefreshAdaptive:
3411 Prop.info.ir_config.mode = SWVENC_IR_MODE_ADAPTIVE;
3412 break;
3413 case OMX_VIDEO_IntraRefreshBoth:
3414 Prop.info.ir_config.mode = SWVENC_IR_MODE_CYCLIC_ADAPTIVE;
3415 break;
3416 case OMX_VIDEO_IntraRefreshRandom:
3417 Prop.info.ir_config.mode = SWVENC_IR_MODE_RANDOM;
3418 break;
3419 default:
3420 DEBUG_PRINT_ERROR("ERROR: UNKNOWN INTRA REFRESH MODE");
3421 Ret = SWVENC_S_FAILURE;
3422 break;
3423 }
3424
3425 if (SWVENC_S_SUCCESS == Ret)
3426 {
3427 Prop.id = SWVENC_PROPERTY_ID_IR_CONFIG;
3428 Prop.info.ir_config.cir_mbs = IntraRefresh->nCirMBs;
3429
3430 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
3431 if (Ret != SWVENC_S_SUCCESS)
3432 {
3433 DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
3434 __FUNCTION__, Ret);
3435 Ret = SWVENC_S_FAILURE;
3436 }
3437 }
3438
3439 RETURN(Ret);
3440 }
3441
swvenc_set_frame_rate(OMX_U32 nFrameRate)3442 SWVENC_STATUS omx_venc::swvenc_set_frame_rate
3443 (
3444 OMX_U32 nFrameRate
3445 )
3446 {
3447 ENTER_FUNC();
3448
3449 SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
3450 SWVENC_PROPERTY Prop;
3451
3452 Prop.id = SWVENC_PROPERTY_ID_FRAME_RATE;
3453 Prop.info.frame_rate = nFrameRate;
3454
3455 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
3456 if (Ret != SWVENC_S_SUCCESS)
3457 {
3458 DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
3459 __FUNCTION__, Ret);
3460 Ret = SWVENC_S_FAILURE;
3461 }
3462
3463 RETURN(Ret);
3464 }
3465
swvenc_set_bit_rate(OMX_U32 nTargetBitrate)3466 SWVENC_STATUS omx_venc::swvenc_set_bit_rate
3467 (
3468 OMX_U32 nTargetBitrate
3469 )
3470 {
3471 ENTER_FUNC();
3472
3473 SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
3474 SWVENC_PROPERTY Prop;
3475
3476 Prop.id = SWVENC_PROPERTY_ID_TARGET_BITRATE;
3477 Prop.info.target_bitrate = nTargetBitrate;
3478
3479 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
3480 if (Ret != SWVENC_S_SUCCESS)
3481 {
3482 DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
3483 __FUNCTION__, Ret);
3484 Ret = SWVENC_S_FAILURE;
3485 }
3486
3487 RETURN(Ret);
3488 }
3489
swvenc_set_intra_period(OMX_U32 nPFrame,OMX_U32 nBFrame)3490 SWVENC_STATUS omx_venc::swvenc_set_intra_period
3491 (
3492 OMX_U32 nPFrame,
3493 OMX_U32 nBFrame
3494 )
3495 {
3496 ENTER_FUNC();
3497
3498 SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
3499 SWVENC_PROPERTY Prop;
3500
3501 Prop.id = SWVENC_PROPERTY_ID_INTRA_PERIOD;
3502 Prop.info.intra_period.pframes = nPFrame;
3503 Prop.info.intra_period.bframes = nBFrame;
3504
3505 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
3506 if (Ret != SWVENC_S_SUCCESS)
3507 {
3508 DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
3509 __FUNCTION__, Ret);
3510 Ret = SWVENC_S_FAILURE;
3511 }
3512
3513 RETURN(Ret);
3514 }
3515
swvenc_color_align(OMX_BUFFERHEADERTYPE * buffer,OMX_U32 width,OMX_U32 height)3516 bool omx_venc::swvenc_color_align(OMX_BUFFERHEADERTYPE *buffer, OMX_U32 width,
3517 OMX_U32 height)
3518 {
3519 OMX_U32 y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width),
3520 y_scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height),
3521 uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, width),
3522 uv_scanlines = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height),
3523 src_chroma_offset = width * height;
3524
3525 if (buffer->nAllocLen >= VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height)) {
3526 OMX_U8* src_buf = buffer->pBuffer, *dst_buf = buffer->pBuffer;
3527 //Do chroma first, so that we can convert it in-place
3528 src_buf += width * height;
3529 dst_buf += y_stride * y_scanlines;
3530 for (int line = height / 2 - 1; line >= 0; --line) {
3531 memmove(dst_buf + line * uv_stride,
3532 src_buf + line * width,
3533 width);
3534 }
3535
3536 dst_buf = src_buf = buffer->pBuffer;
3537 //Copy the Y next
3538 for (int line = height - 1; line > 0; --line) {
3539 memmove(dst_buf + line * y_stride,
3540 src_buf + line * width,
3541 width);
3542 }
3543 } else {
3544 DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \
3545 Insufficient bufferLen=%u v/s Required=%u",
3546 (unsigned int)(width*height), (unsigned int)src_chroma_offset, (unsigned int)buffer->nAllocLen,
3547 VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height));
3548 return false;
3549 }
3550
3551 return true;
3552 }
3553
swvenc_set_color_format(OMX_COLOR_FORMATTYPE color_format)3554 SWVENC_STATUS omx_venc::swvenc_set_color_format
3555 (
3556 OMX_COLOR_FORMATTYPE color_format
3557 )
3558 {
3559 ENTER_FUNC();
3560 SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
3561 SWVENC_COLOR_FORMAT swvenc_color_format;
3562 SWVENC_PROPERTY Prop;
3563 if ((color_format == OMX_COLOR_FormatYUV420SemiPlanar) ||
3564 (color_format == ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m)))
3565 {
3566 swvenc_color_format = SWVENC_COLOR_FORMAT_NV12;
3567 }
3568 else if (color_format == ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FormatYVU420SemiPlanar))
3569 {
3570 swvenc_color_format = SWVENC_COLOR_FORMAT_NV21;
3571 }
3572 else
3573 {
3574 DEBUG_PRINT_ERROR("%s: color_format %d invalid",__FUNCTION__,color_format);
3575 RETURN(SWVENC_S_FAILURE);
3576 }
3577 /* set the input color format */
3578 Prop.id = SWVENC_PROPERTY_ID_COLOR_FORMAT;
3579 Prop.info.color_format = swvenc_color_format;
3580 Ret = swvenc_setproperty(m_hSwVenc, &Prop);
3581 if (Ret != SWVENC_S_SUCCESS)
3582 {
3583 DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
3584 __FUNCTION__, Ret);
3585 Ret = SWVENC_S_FAILURE;
3586 }
3587 RETURN(Ret);
3588 }
3589
3590 // don't use init_vendor_extensions() from omx_video_extensions.hpp, sw component doesn't support
3591 // all the vendor extensions like hw component
init_sw_vendor_extensions(VendorExtensionStore & store)3592 void omx_venc::init_sw_vendor_extensions(VendorExtensionStore &store) {
3593 ADD_EXTENSION("qti-ext-enc-preprocess-rotate", OMX_IndexConfigCommonRotate, OMX_DirOutput)
3594 ADD_PARAM_END("angle", OMX_AndroidVendorValueInt32)
3595
3596 ADD_EXTENSION("qti-ext-enc-timestamp-source-avtimer", OMX_QTIIndexParamEnableAVTimerTimestamps,
3597 OMX_DirOutput)
3598 ADD_PARAM_END("enable", OMX_AndroidVendorValueInt32)
3599 }
3600