blob: 518ed7c1ae2d678fc2d45fc0bb30113c57878462 [file] [log] [blame]
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001/*
2 *
Jiho Chang38ef2572012-06-01 20:58:55 +00003 * Copyright 2012 Samsung Electronics S.LSI Co. LTD
Jiho Chang20d3e6e2012-03-24 03:43:08 +09004 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/*
19 * @file Exynos_OMX_H264enc.c
20 * @brief
21 * @author SeungBeom Kim (sbcrux.kim@samsung.com)
Jiho Chang38ef2572012-06-01 20:58:55 +000022 * @version 2.0.0
Jiho Chang20d3e6e2012-03-24 03:43:08 +090023 * @history
Jiho Chang38ef2572012-06-01 20:58:55 +000024 * 2012.02.20 : Create
Jiho Chang20d3e6e2012-03-24 03:43:08 +090025 */
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30
31#include "Exynos_OMX_Macros.h"
32#include "Exynos_OMX_Basecomponent.h"
33#include "Exynos_OMX_Baseport.h"
34#include "Exynos_OMX_Venc.h"
35#include "Exynos_OSAL_ETC.h"
36#include "Exynos_OSAL_Semaphore.h"
37#include "Exynos_OSAL_Thread.h"
38#include "Exynos_OSAL_Android.h"
39#include "library_register.h"
40#include "Exynos_OMX_H264enc.h"
41#include "ExynosVideoApi.h"
Jiho Chang38ef2572012-06-01 20:58:55 +000042#include "Exynos_OSAL_SharedMemory.h"
43#include "Exynos_OSAL_Event.h"
44
45/* To use CSC_METHOD_HW in EXYNOS OMX, gralloc should allocate physical memory using FIMC */
46/* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */
Jiho Chang20d3e6e2012-03-24 03:43:08 +090047#include "csc.h"
48
49#undef EXYNOS_LOG_TAG
50#define EXYNOS_LOG_TAG "EXYNOS_H264_ENC"
51#define EXYNOS_LOG_OFF
Jiho Chang38ef2572012-06-01 20:58:55 +000052//#define EXYNOS_TRACE_ON
Jiho Chang20d3e6e2012-03-24 03:43:08 +090053#include "Exynos_OSAL_Log.h"
54
55/* H.264 Encoder Supported Levels & profiles */
56EXYNOS_OMX_VIDEO_PROFILELEVEL supportedAVCProfileLevels[] ={
57 {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1},
58 {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1b},
59 {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel11},
60 {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel12},
61 {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel13},
62 {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel2},
63 {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel21},
64 {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel22},
65 {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel3},
66 {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel31},
67 {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel32},
68 {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel4},
Jiho Chang800a8d72012-04-26 13:25:31 -070069 {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel41},
70 {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel42},
Jiho Chang20d3e6e2012-03-24 03:43:08 +090071
72 {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1},
73 {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1b},
74 {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel11},
75 {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel12},
76 {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel13},
77 {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel2},
78 {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel21},
79 {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel22},
80 {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel3},
81 {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel31},
82 {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel32},
83 {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel4},
Jiho Chang800a8d72012-04-26 13:25:31 -070084 {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel41},
85 {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel42},
Jiho Chang20d3e6e2012-03-24 03:43:08 +090086
87 {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1},
88 {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1b},
89 {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel11},
90 {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel12},
91 {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel13},
92 {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel2},
93 {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel21},
94 {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel22},
95 {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel3},
96 {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel31},
97 {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel32},
Jiho Chang800a8d72012-04-26 13:25:31 -070098 {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel4},
99 {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel41},
100 {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel42}};
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900101
Jiho Chang800a8d72012-04-26 13:25:31 -0700102static OMX_U32 OMXAVCProfileToProfileIDC(OMX_VIDEO_AVCPROFILETYPE profile)
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900103{
Jiho Chang800a8d72012-04-26 13:25:31 -0700104 OMX_U32 ret = 0;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900105
Jiho Chang800a8d72012-04-26 13:25:31 -0700106 if (profile == OMX_VIDEO_AVCProfileBaseline)
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900107 ret = 0;
Jiho Chang800a8d72012-04-26 13:25:31 -0700108 else if (profile == OMX_VIDEO_AVCProfileMain)
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900109 ret = 2;
Jiho Chang800a8d72012-04-26 13:25:31 -0700110 else if (profile == OMX_VIDEO_AVCProfileHigh)
111 ret = 4;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900112
113 return ret;
114}
115
Jiho Chang800a8d72012-04-26 13:25:31 -0700116static OMX_U32 OMXAVCLevelToLevelIDC(OMX_VIDEO_AVCLEVELTYPE level)
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900117{
Jiho Chang800a8d72012-04-26 13:25:31 -0700118 OMX_U32 ret = 11; //default OMX_VIDEO_AVCLevel4
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900119
120 if (level == OMX_VIDEO_AVCLevel1)
Jiho Chang800a8d72012-04-26 13:25:31 -0700121 ret = 0;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900122 else if (level == OMX_VIDEO_AVCLevel1b)
Jiho Chang800a8d72012-04-26 13:25:31 -0700123 ret = 1;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900124 else if (level == OMX_VIDEO_AVCLevel11)
Jiho Chang800a8d72012-04-26 13:25:31 -0700125 ret = 2;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900126 else if (level == OMX_VIDEO_AVCLevel12)
Jiho Chang800a8d72012-04-26 13:25:31 -0700127 ret = 3;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900128 else if (level == OMX_VIDEO_AVCLevel13)
Jiho Chang800a8d72012-04-26 13:25:31 -0700129 ret = 4;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900130 else if (level == OMX_VIDEO_AVCLevel2)
Jiho Chang800a8d72012-04-26 13:25:31 -0700131 ret = 5;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900132 else if (level == OMX_VIDEO_AVCLevel21)
Jiho Chang800a8d72012-04-26 13:25:31 -0700133 ret = 6;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900134 else if (level == OMX_VIDEO_AVCLevel22)
Jiho Chang800a8d72012-04-26 13:25:31 -0700135 ret = 7;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900136 else if (level == OMX_VIDEO_AVCLevel3)
Jiho Chang800a8d72012-04-26 13:25:31 -0700137 ret = 8;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900138 else if (level == OMX_VIDEO_AVCLevel31)
Jiho Chang800a8d72012-04-26 13:25:31 -0700139 ret = 9;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900140 else if (level == OMX_VIDEO_AVCLevel32)
Jiho Chang800a8d72012-04-26 13:25:31 -0700141 ret = 10;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900142 else if (level == OMX_VIDEO_AVCLevel4)
Jiho Chang800a8d72012-04-26 13:25:31 -0700143 ret = 11;
144 else if (level == OMX_VIDEO_AVCLevel41)
145 ret = 12;
146 else if (level == OMX_VIDEO_AVCLevel42)
147 ret = 13;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900148
149 return ret;
150}
151
Jiho Chang800a8d72012-04-26 13:25:31 -0700152static OMX_U8 *FindDelimiter(OMX_U8 *pBuffer, OMX_U32 size)
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900153{
154 OMX_U32 i;
155
156 for (i = 0; i < size - 3; i++) {
157 if ((pBuffer[i] == 0x00) &&
158 (pBuffer[i + 1] == 0x00) &&
159 (pBuffer[i + 2] == 0x00) &&
160 (pBuffer[i + 3] == 0x01))
161 return (pBuffer + i);
162 }
163
164 return NULL;
165}
166
Jiho Chang800a8d72012-04-26 13:25:31 -0700167static void Print_H264Enc_Param(ExynosVideoEncParam *pEncParam)
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900168{
169 ExynosVideoEncCommonParam *pCommonParam = &pEncParam->commonParam;
170 ExynosVideoEncH264Param *pH264Param = &pEncParam->codecParam.h264;
171
172 /* common parameters */
173 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SourceWidth : %d", pCommonParam->SourceWidth);
174 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SourceHeight : %d", pCommonParam->SourceHeight);
175 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "IDRPeriod : %d", pCommonParam->IDRPeriod);
176 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SliceMode : %d", pCommonParam->SliceMode);
177 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "RandomIntraMBRefresh : %d", pCommonParam->RandomIntraMBRefresh);
178 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Bitrate : %d", pCommonParam->Bitrate);
179 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameQp : %d", pCommonParam->FrameQp);
180 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameQp_P : %d", pCommonParam->FrameQp_P);
181 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "QSCodeMax : %d", pCommonParam->QSCodeMax);
182 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "QSCodeMin : %d", pCommonParam->QSCodeMin);
183 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PadControlOn : %d", pCommonParam->PadControlOn);
184 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "LumaPadVal : %d", pCommonParam->LumaPadVal);
185 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "CbPadVal : %d", pCommonParam->CbPadVal);
186 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "CrPadVal : %d", pCommonParam->CrPadVal);
187 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameMap : %d", pCommonParam->FrameMap);
188
189 /* H.264 specific parameters */
190 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "ProfileIDC : %d", pH264Param->ProfileIDC);
191 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "LevelIDC : %d", pH264Param->LevelIDC);
192 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameQp_B : %d", pH264Param->FrameQp_B);
193 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameRate : %d", pH264Param->FrameRate);
194 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SliceArgument : %d", pH264Param->SliceArgument);
195 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "NumberBFrames : %d", pH264Param->NumberBFrames);
196 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "NumberReferenceFrames : %d", pH264Param->NumberReferenceFrames);
197 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "NumberRefForPframes : %d", pH264Param->NumberRefForPframes);
198 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "LoopFilterDisable : %d", pH264Param->LoopFilterDisable);
199 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "LoopFilterAlphaC0Offset : %d", pH264Param->LoopFilterAlphaC0Offset);
200 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "LoopFilterBetaOffset : %d", pH264Param->LoopFilterBetaOffset);
201 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SymbolMode : %d", pH264Param->SymbolMode);
202 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PictureInterlace : %d", pH264Param->PictureInterlace);
203 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Transform8x8Mode : %d", pH264Param->Transform8x8Mode);
204 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "DarkDisable : %d", pH264Param->DarkDisable);
205 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SmoothDisable : %d", pH264Param->SmoothDisable);
206 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "StaticDisable : %d", pH264Param->StaticDisable);
207 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "ActivityDisable : %d", pH264Param->ActivityDisable);
208
209 /* rate control related parameters */
210 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "EnableFRMRateControl : %d", pCommonParam->EnableFRMRateControl);
Jiho Chang800a8d72012-04-26 13:25:31 -0700211 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "EnableMBRateControl : %d", pCommonParam->EnableMBRateControl);
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900212 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "CBRPeriodRf : %d", pCommonParam->CBRPeriodRf);
213}
214
Jiho Chang800a8d72012-04-26 13:25:31 -0700215static void Set_H264Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900216{
217 EXYNOS_OMX_BASEPORT *pExynosInputPort = NULL;
218 EXYNOS_OMX_BASEPORT *pExynosOutputPort = NULL;
219 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
220 EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
Jiho Chang38ef2572012-06-01 20:58:55 +0000221 EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = NULL;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900222
223 ExynosVideoEncParam *pEncParam = NULL;
224 ExynosVideoEncCommonParam *pCommonParam = NULL;
225 ExynosVideoEncH264Param *pH264Param = NULL;
226
227 pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
228 pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
Jiho Chang38ef2572012-06-01 20:58:55 +0000229 pMFCH264Handle = &pH264Enc->hMFCH264Handle;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900230 pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
231 pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
232
Jiho Chang38ef2572012-06-01 20:58:55 +0000233 pEncParam = &pMFCH264Handle->encParam;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900234 pCommonParam = &pEncParam->commonParam;
235 pH264Param = &pEncParam->codecParam.h264;
236 pEncParam->eCompressionFormat = VIDEO_CODING_AVC;
237 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "eCompressionFormat: %d", pEncParam->eCompressionFormat);
238
239 /* common parameters */
240 pCommonParam->SourceWidth = pExynosOutputPort->portDefinition.format.video.nFrameWidth;
241 pCommonParam->SourceHeight = pExynosOutputPort->portDefinition.format.video.nFrameHeight;
242 pCommonParam->IDRPeriod = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1;
243 pCommonParam->SliceMode = 0;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900244 pCommonParam->Bitrate = pExynosOutputPort->portDefinition.format.video.nBitrate;
245 pCommonParam->FrameQp = pVideoEnc->quantization.nQpI;
246 pCommonParam->FrameQp_P = pVideoEnc->quantization.nQpP;
247 pCommonParam->QSCodeMax = 51;
248 pCommonParam->QSCodeMin = 10;
249 pCommonParam->PadControlOn = 0; /* 0: disable, 1: enable */
250 pCommonParam->LumaPadVal = 0;
251 pCommonParam->CbPadVal = 0;
252 pCommonParam->CrPadVal = 0;
253
SeungBeom Kime1b99ca2012-11-16 13:03:45 +0900254 if (pVideoEnc->intraRefresh.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic) {
255 /* Cyclic Mode */
256 pCommonParam->RandomIntraMBRefresh = pVideoEnc->intraRefresh.nCirMBs;
257 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "RandomIntraMBRefresh: %d", pCommonParam->RandomIntraMBRefresh);
258 } else {
259 /* Don't support "Adaptive" and "Cyclic + Adaptive" */
260 pCommonParam->RandomIntraMBRefresh = 0;
261 }
262
SeungBeom Kim33d60442012-08-07 16:22:29 -0700263 if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
264 if (pVideoEnc->ANBColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)
265 pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12;
266 if (pVideoEnc->ANBColorFormat == OMX_SEC_COLOR_FormatNV12Tiled)
267 pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12_TILED;
268 } else {
269 switch ((EXYNOS_OMX_COLOR_FORMATTYPE)pExynosInputPort->portDefinition.format.video.eColorFormat) {
270 case OMX_COLOR_FormatYUV420SemiPlanar:
271 case OMX_COLOR_FormatYUV420Planar: /* Converted to NV12 in Exynos_CSC_InputData */
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900272#ifdef USE_METADATABUFFERTYPE
SeungBeom Kim33d60442012-08-07 16:22:29 -0700273 case OMX_COLOR_FormatAndroidOpaque:
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900274#endif
SeungBeom Kim33d60442012-08-07 16:22:29 -0700275 pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12;
276 break;
277 case OMX_SEC_COLOR_FormatNV21Linear:
278 pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV21;
279 break;
280 case OMX_SEC_COLOR_FormatNV12Tiled:
281 default:
282 pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12_TILED;
283 break;
284 }
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900285 }
286
287 /* H.264 specific parameters */
288 pH264Param->ProfileIDC = OMXAVCProfileToProfileIDC(pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].eProfile); /*0: OMX_VIDEO_AVCProfileMain */
289 pH264Param->LevelIDC = OMXAVCLevelToLevelIDC(pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].eLevel); /*40: OMX_VIDEO_AVCLevel4 */
290 pH264Param->FrameQp_B = pVideoEnc->quantization.nQpB;
291 pH264Param->FrameRate = (pExynosInputPort->portDefinition.format.video.xFramerate) >> 16;
292 pH264Param->SliceArgument = 0; /* Slice mb/byte size number */
293 pH264Param->NumberBFrames = 0; /* 0 ~ 2 */
294 pH264Param->NumberReferenceFrames = 1;
295 pH264Param->NumberRefForPframes = 1;
296 pH264Param->LoopFilterDisable = 1; /* 1: Loop Filter Disable, 0: Filter Enable */
297 pH264Param->LoopFilterAlphaC0Offset = 0;
298 pH264Param->LoopFilterBetaOffset = 0;
299 pH264Param->SymbolMode = 0; /* 0: CAVLC, 1: CABAC */
300 pH264Param->PictureInterlace = 0;
301 pH264Param->Transform8x8Mode = 0; /* 0: 4x4, 1: allow 8x8 */
302 pH264Param->DarkDisable = 1;
303 pH264Param->SmoothDisable = 1;
304 pH264Param->StaticDisable = 1;
305 pH264Param->ActivityDisable = 1;
306
307 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]: 0x%x", pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]);
308 /* rate control related parameters */
309 switch (pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]) {
SeungBeom Kimd4819ad2012-09-05 15:35:55 +0900310 case OMX_Video_ControlRateDisable:
311 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode DBR");
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900312 pCommonParam->EnableFRMRateControl = 0; /* 0: Disable, 1: Frame level RC */
Jiho Chang800a8d72012-04-26 13:25:31 -0700313 pCommonParam->EnableMBRateControl = 0; /* 0: Disable, 1:MB level RC */
SeungBeom Kimd4819ad2012-09-05 15:35:55 +0900314 pCommonParam->CBRPeriodRf = 100;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900315 break;
316 case OMX_Video_ControlRateConstant:
317 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode CBR");
318 pCommonParam->EnableFRMRateControl = 1; /* 0: Disable, 1: Frame level RC */
Jiho Chang800a8d72012-04-26 13:25:31 -0700319 pCommonParam->EnableMBRateControl = 1; /* 0: Disable, 1:MB level RC */
SeungBeom Kimd4819ad2012-09-05 15:35:55 +0900320 pCommonParam->CBRPeriodRf = 9;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900321 break;
SeungBeom Kimd4819ad2012-09-05 15:35:55 +0900322 case OMX_Video_ControlRateVariable:
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900323 default: /*Android default */
324 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode VBR");
SeungBeom Kimd4819ad2012-09-05 15:35:55 +0900325 pCommonParam->EnableFRMRateControl = 1; /* 0: Disable, 1: Frame level RC */
326 pCommonParam->EnableMBRateControl = 1; /* 0: Disable, 1:MB level RC */
327 pCommonParam->CBRPeriodRf = 100;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900328 break;
329 }
330
331 Print_H264Enc_Param(pEncParam);
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900332}
333
Jiho Chang800a8d72012-04-26 13:25:31 -0700334static void Change_H264Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900335{
336 EXYNOS_OMX_BASEPORT *pExynosInputPort = NULL;
337 EXYNOS_OMX_BASEPORT *pExynosOutputPort = NULL;
338 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
339 EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
Jiho Chang38ef2572012-06-01 20:58:55 +0000340 EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = NULL;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900341
342 ExynosVideoEncOps *pEncOps = NULL;
343 ExynosVideoEncParam *pEncParam = NULL;
344 ExynosVideoEncCommonParam *pCommonParam = NULL;
345 ExynosVideoEncH264Param *pH264Param = NULL;
346
347 int setParam = 0;
348
349 pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
350 pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
Jiho Chang38ef2572012-06-01 20:58:55 +0000351 pMFCH264Handle = &pH264Enc->hMFCH264Handle;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900352 pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
353 pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
Jiho Chang38ef2572012-06-01 20:58:55 +0000354 pEncOps = pMFCH264Handle->pEncOps;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900355
Jiho Chang38ef2572012-06-01 20:58:55 +0000356 pEncParam = &pMFCH264Handle->encParam;
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900357 pCommonParam = &pEncParam->commonParam;
358 pH264Param = &pEncParam->codecParam.h264;
359
360 if (pVideoEnc->IntraRefreshVOP == OMX_TRUE) {
361 setParam = VIDEO_FRAME_I;
362 pEncOps->Set_FrameType(pH264Enc->hMFCH264Handle.hMFCHandle, setParam);
363 pVideoEnc->IntraRefreshVOP = OMX_FALSE;
364 }
365 if (pCommonParam->IDRPeriod != (int)pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1) {
366 setParam = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1;
367 pEncOps->Set_IDRPeriod(pH264Enc->hMFCH264Handle.hMFCHandle, setParam);
368 }
369 if (pCommonParam->Bitrate != (int)pExynosOutputPort->portDefinition.format.video.nBitrate) {
370 setParam = pExynosOutputPort->portDefinition.format.video.nBitrate;
371 pEncOps->Set_BitRate(pH264Enc->hMFCH264Handle.hMFCHandle, setParam);
372 }
SeungBeom Kima7fc5932012-11-20 12:33:33 +0900373 if (pH264Param->FrameRate != (int)((pExynosInputPort->portDefinition.format.video.xFramerate) >> 16)) {
Jiho Chang20d3e6e2012-03-24 03:43:08 +0900374 setParam = (pExynosInputPort->portDefinition.format.video.xFramerate) >> 16;
375 pEncOps->Set_FrameRate(pH264Enc->hMFCH264Handle.hMFCHandle, setParam);
376 }
377
378 Set_H264Enc_Param(pExynosComponent);
379}
380
Jiho Chang38ef2572012-06-01 20:58:55 +0000381OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, OMX_PTR addr[], OMX_U32 size[])
382{
383 OMX_ERRORTYPE ret = OMX_ErrorNone;
384
385EXIT:
386 return ret;
387}
388
Jiho Chang38ef2572012-06-01 20:58:55 +0000389OMX_ERRORTYPE GetCodecOutputPrivateData(OMX_PTR codecBuffer, OMX_PTR *pVirtAddr, OMX_U32 *dataSize)
390{
391 OMX_ERRORTYPE ret = OMX_ErrorNone;
392 ExynosVideoBuffer *pCodecBuffer;
393
394 if (codecBuffer == NULL) {
395 ret = OMX_ErrorBadParameter;
396 goto EXIT;
397 }
398
399 pCodecBuffer = (ExynosVideoBuffer *)codecBuffer;
400
401 if (pVirtAddr != NULL)
402 *pVirtAddr = pCodecBuffer->planes[0].addr;
403
404 if (dataSize != NULL)
405 *dataSize = pCodecBuffer->planes[0].allocSize;
406
407 pCodecBuffer = (ExynosVideoBuffer *)codecBuffer;
408
409EXIT:
410 return ret;
411}
412
413OMX_ERRORTYPE H264CodecOpen(EXYNOS_H264ENC_HANDLE *pH264Enc)
414{
415 OMX_ERRORTYPE ret = OMX_ErrorNone;
416
417 ExynosVideoEncOps *pEncOps = NULL;
418 ExynosVideoEncBufferOps *pInbufOps = NULL;
419 ExynosVideoEncBufferOps *pOutbufOps = NULL;
420
421 FunctionIn();
422
423 if (pH264Enc == NULL) {
424 ret = OMX_ErrorBadParameter;
425 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
426 goto EXIT;
427 }
428
Jiho Chang38ef2572012-06-01 20:58:55 +0000429 /* alloc ops structure */
430 pEncOps = (ExynosVideoEncOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncOps));
431 pInbufOps = (ExynosVideoEncBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncBufferOps));
432 pOutbufOps = (ExynosVideoEncBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncBufferOps));
433
434 if ((pEncOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
435 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate encoder ops buffer");
436 ret = OMX_ErrorInsufficientResources;
437 goto EXIT;
438 }
439
440 pH264Enc->hMFCH264Handle.pEncOps = pEncOps;
441 pH264Enc->hMFCH264Handle.pInbufOps = pInbufOps;
442 pH264Enc->hMFCH264Handle.pOutbufOps = pOutbufOps;
443
444 /* function pointer mapping */
445 pEncOps->nSize = sizeof(ExynosVideoEncOps);
446 pInbufOps->nSize = sizeof(ExynosVideoEncBufferOps);
447 pOutbufOps->nSize = sizeof(ExynosVideoEncBufferOps);
448
449 Exynos_Video_Register_Encoder(pEncOps, pInbufOps, pOutbufOps);
450
451 /* check mandatory functions for encoder ops */
452 if ((pEncOps->Init == NULL) || (pEncOps->Finalize == NULL) ||
453 (pEncOps->Set_FrameTag == NULL) || (pEncOps->Get_FrameTag == NULL)) {
454 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied");
455 ret = OMX_ErrorInsufficientResources;
456 goto EXIT;
457 }
458
459 /* check mandatory functions for buffer ops */
460 if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) ||
461 (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) ||
462 (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) ||
463 (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) ||
464 (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) {
465 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied");
466 ret = OMX_ErrorInsufficientResources;
467 goto EXIT;
468 }
469
470 /* alloc context, open, querycap */
SeungBeom Kimc94beae2012-07-05 14:59:40 +0900471 pH264Enc->hMFCH264Handle.hMFCHandle = pH264Enc->hMFCH264Handle.pEncOps->Init(V4L2_MEMORY_DMABUF);
Jiho Chang38ef2572012-06-01 20:58:55 +0000472 if (pH264Enc->hMFCH264Handle.hMFCHandle == NULL) {
473 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer");
474 ret = OMX_ErrorInsufficientResources;
475 goto EXIT;
476 }
477
478 ret = OMX_ErrorNone;
479
480EXIT:
SeungBeom Kim44025232012-07-04 09:33:20 +0900481 if (ret != OMX_ErrorNone) {
482 if (pEncOps != NULL) {
483 Exynos_OSAL_Free(pEncOps);
484 pH264Enc->hMFCH264Handle.pEncOps = NULL;
485 }
486 if (pInbufOps != NULL) {
487 Exynos_OSAL_Free(pInbufOps);
488 pH264Enc->hMFCH264Handle.pInbufOps = NULL;
489 }
490 if (pOutbufOps != NULL) {
491 Exynos_OSAL_Free(pOutbufOps);
492 pH264Enc->hMFCH264Handle.pOutbufOps = NULL;
493 }
494 }
495
Jiho Chang38ef2572012-06-01 20:58:55 +0000496 FunctionOut();
497
498 return ret;
499}
500
501OMX_ERRORTYPE H264CodecClose(EXYNOS_H264ENC_HANDLE *pH264Enc)
502{
503 OMX_ERRORTYPE ret = OMX_ErrorNone;
504 void *hMFCHandle = NULL;
505 ExynosVideoEncOps *pEncOps = NULL;
506 ExynosVideoEncBufferOps *pInbufOps = NULL;
507 ExynosVideoEncBufferOps *pOutbufOps = NULL;
508
SeungBeom Kim3e79a272012-07-03 20:03:59 +0900509 FunctionIn();
510
Jiho Chang38ef2572012-06-01 20:58:55 +0000511 if (pH264Enc == NULL) {
512 ret = OMX_ErrorBadParameter;
513 goto EXIT;
514 }
515
516 hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
517 pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
518 pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps;
519 pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
520
521 if (hMFCHandle != NULL) {
522 pEncOps->Finalize(hMFCHandle);
523 hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle = NULL;
524 }
525 if (pOutbufOps != NULL) {
526 Exynos_OSAL_Free(pOutbufOps);
527 pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps = NULL;
528 }
529 if (pInbufOps != NULL) {
530 Exynos_OSAL_Free(pInbufOps);
531 pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps = NULL;
532 }
533 if (pEncOps != NULL) {
534 Exynos_OSAL_Free(pEncOps);
535 pEncOps = pH264Enc->hMFCH264Handle.pEncOps = NULL;
536 }
537
538 ret = OMX_ErrorNone;
539
540EXIT:
541 FunctionOut();
542
543 return ret;
544}
545
546OMX_ERRORTYPE H264CodecStart(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
547{
548 OMX_ERRORTYPE ret = OMX_ErrorNone;
549 void *hMFCHandle = NULL;
550 ExynosVideoEncOps *pEncOps = NULL;
551 ExynosVideoEncBufferOps *pInbufOps = NULL;
552 ExynosVideoEncBufferOps *pOutbufOps = NULL;
553 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
554 EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
555
556 FunctionIn();
557
558 if (pOMXComponent == NULL) {
559 ret = OMX_ErrorBadParameter;
560 goto EXIT;
561 }
562
563 pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
564 if (pVideoEnc == NULL) {
565 ret = OMX_ErrorBadParameter;
566 goto EXIT;
567 }
568
569 pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
570 if (pH264Enc == NULL) {
571 ret = OMX_ErrorBadParameter;
572 goto EXIT;
573 }
574
575 hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
576 pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
577 pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps;
578 pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
579
580 if (nPortIndex == INPUT_PORT_INDEX)
581 pInbufOps->Run(hMFCHandle);
582 else if (nPortIndex == OUTPUT_PORT_INDEX)
583 pOutbufOps->Run(hMFCHandle);
584
585 ret = OMX_ErrorNone;
586
587EXIT:
588 FunctionOut();
589
590 return ret;
591}
592
593OMX_ERRORTYPE H264CodecStop(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
594{
595 OMX_ERRORTYPE ret = OMX_ErrorNone;
596 void *hMFCHandle = NULL;
597 ExynosVideoEncOps *pEncOps = NULL;
598 ExynosVideoEncBufferOps *pInbufOps = NULL;
599 ExynosVideoEncBufferOps *pOutbufOps = NULL;
600 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
601 EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
602
603 FunctionIn();
604
605 if (pOMXComponent == NULL) {
606 ret = OMX_ErrorBadParameter;
607 goto EXIT;
608 }
609
610 pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
611 if (pVideoEnc == NULL) {
612 ret = OMX_ErrorBadParameter;
613 goto EXIT;
614 }
615 pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
616 if (pH264Enc == NULL) {
617 ret = OMX_ErrorBadParameter;
618 goto EXIT;
619 }
620
621 hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
622 pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
623 pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps;
624 pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
625
626 if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL))
627 pInbufOps->Stop(hMFCHandle);
628 else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL))
629 pOutbufOps->Stop(hMFCHandle);
630
631 ret = OMX_ErrorNone;
632
633EXIT:
634 FunctionOut();
635
636 return ret;
637}
638
639OMX_ERRORTYPE H264CodecOutputBufferProcessRun(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
640{
641 OMX_ERRORTYPE ret = OMX_ErrorNone;
642 void *hMFCHandle = NULL;
643 ExynosVideoEncOps *pEncOps = NULL;
644 ExynosVideoEncBufferOps *pInbufOps = NULL;
645 ExynosVideoEncBufferOps *pOutbufOps = NULL;
646 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
647 EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
648
649 FunctionIn();
650
651 if (pOMXComponent == NULL) {
652 ret = OMX_ErrorBadParameter;
653 goto EXIT;
654 }
655
656 pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
657 if (pVideoEnc == NULL) {
658 ret = OMX_ErrorBadParameter;
659 goto EXIT;
660 }
661 pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
662 if (pH264Enc == NULL) {
663 ret = OMX_ErrorBadParameter;
664 goto EXIT;
665 }
666
667 hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
668 pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
669 pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps;
670 pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
671
672 if (nPortIndex == INPUT_PORT_INDEX) {
673 if (pH264Enc->bSourceStart == OMX_FALSE) {
674 Exynos_OSAL_SignalSet(pH264Enc->hSourceStartEvent);
675 Exynos_OSAL_SleepMillisec(0);
676 }
677 }
678
679 if (nPortIndex == OUTPUT_PORT_INDEX) {
680 if (pH264Enc->bDestinationStart == OMX_FALSE) {
681 Exynos_OSAL_SignalSet(pH264Enc->hDestinationStartEvent);
682 Exynos_OSAL_SleepMillisec(0);
683 }
684 }
685
686 ret = OMX_ErrorNone;
687
688EXIT:
689 FunctionOut();
690
691 return ret;
692}
693
SeungBeom Kimf8d511a2013-08-02 10:05:22 +0900694OMX_ERRORTYPE H264CodecRegistCodecBuffers(
695 OMX_COMPONENTTYPE *pOMXComponent,
696 OMX_U32 nPortIndex,
697 OMX_U32 nBufferCnt)
698{
699 OMX_ERRORTYPE ret = OMX_ErrorNone;
700 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
701 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
702 EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
703 void *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
704 CODEC_ENC_BUFFER **ppCodecBuffer = NULL;
705 ExynosVideoEncBufferOps *pBufOps = NULL;
706 ExynosVideoPlane *pPlanes = NULL;
707
708 OMX_U32 nPlaneCnt = 0;
709 int i, j;
710
711 FunctionIn();
712
713 if (nPortIndex == INPUT_PORT_INDEX) {
714 ppCodecBuffer = &(pVideoEnc->pMFCEncInputBuffer[0]);
715 nPlaneCnt = MFC_INPUT_BUFFER_PLANE;
716 pBufOps = pH264Enc->hMFCH264Handle.pInbufOps;
717 } else {
718 ppCodecBuffer = &(pVideoEnc->pMFCEncOutputBuffer[0]);
719 nPlaneCnt = MFC_OUTPUT_BUFFER_PLANE;
720 pBufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
721 }
722
723 pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt);
724 if (pPlanes == NULL) {
725 ret = OMX_ErrorInsufficientResources;
726 goto EXIT;
727 }
728
729 /* Register buffer */
730 for (i = 0; i < nBufferCnt; i++) {
731 for (j = 0; j < nPlaneCnt; j++) {
732 pPlanes[j].addr = ppCodecBuffer[i]->pVirAddr[j];
733 pPlanes[j].fd = ppCodecBuffer[i]->fd[j];
734 pPlanes[j].allocSize = ppCodecBuffer[i]->bufferSize[j];
735 }
736
737 if (pBufOps->Register(hMFCHandle, pPlanes, nPlaneCnt) != VIDEO_ERROR_NONE) {
738 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "PORT[%d]: Failed to Register buffer", nPortIndex);
739 ret = OMX_ErrorInsufficientResources;
740 Exynos_OSAL_Free(pPlanes);
741 goto EXIT;
742 }
743 }
744
745 Exynos_OSAL_Free(pPlanes);
746
747 ret = OMX_ErrorNone;
748
749EXIT:
750 FunctionOut();
751
752 return ret;
753}
754
Jiho Chang38ef2572012-06-01 20:58:55 +0000755OMX_ERRORTYPE H264CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
756{
757 OMX_ERRORTYPE ret = OMX_ErrorNone;
758 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
759 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
760 EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
761 void *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
762 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
763 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
764 int i, nOutbufs;
Jiho Chang38ef2572012-06-01 20:58:55 +0000765
766 ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
767 ExynosVideoEncBufferOps *pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps;
768 ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
769
770 FunctionIn();
771
SeungBeom Kimf8d511a2013-08-02 10:05:22 +0900772 if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) {
773 ret = OMX_ErrorBadPortIndex;
774 goto EXIT;
775 }
776
Jiho Chang38ef2572012-06-01 20:58:55 +0000777 if ((nPortIndex == INPUT_PORT_INDEX) &&
778 (pH264Enc->bSourceStart == OMX_TRUE)) {
Jiho Chang38ef2572012-06-01 20:58:55 +0000779 Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
Jiho Chang38ef2572012-06-01 20:58:55 +0000780
781 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
782 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]);
SeungBeom Kim91f44a52012-07-04 15:01:54 +0900783 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]);
784 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]);
Jiho Chang38ef2572012-06-01 20:58:55 +0000785
786 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]);
787 }
788
789 pInbufOps->Clear_Queue(hMFCHandle);
790 } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
791 (pH264Enc->bDestinationStart == OMX_TRUE)) {
792 OMX_U32 dataLen[2] = {0, 0};
793 ExynosVideoBuffer *pBuffer = NULL;
Jiho Chang38ef2572012-06-01 20:58:55 +0000794
SeungBeom Kim3e79a272012-07-03 20:03:59 +0900795 Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
Jiho Chang38ef2572012-06-01 20:58:55 +0000796
797 for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
798 pOutbufOps->Get_Buffer(hMFCHandle, i, &pBuffer);
799 Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR)pBuffer);
800 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncOutputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncOutputBuffer[i]);
SeungBeom Kim91f44a52012-07-04 15:01:54 +0900801 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]);
802 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]);
Jiho Chang38ef2572012-06-01 20:58:55 +0000803 }
804 pOutbufOps->Clear_Queue(hMFCHandle);
805 } else {
806 ret = OMX_ErrorBadParameter;
807 goto EXIT;
808 }
809
810EXIT:
811 FunctionOut();
812
813 return ret;
814}
815
816OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
817{
818 OMX_ERRORTYPE ret = OMX_ErrorNone;
819 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
820 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
821 EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
822 EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = &pH264Enc->hMFCH264Handle;
823 void *hMFCHandle = pMFCH264Handle->hMFCHandle;
824 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
825 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
826 OMX_U32 oneFrameSize = pSrcInputData->dataLen;
827
828 ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
829 ExynosVideoEncBufferOps *pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps;
830 ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
SeungBeom Kim833233f2012-07-04 14:13:28 +0900831 ExynosVideoEncParam *pEncParam = NULL;
832
833 ExynosVideoGeometry bufferConf;
834 OMX_U32 inputBufferNumber = 0;
835 int i, nOutbufs;
Jiho Chang38ef2572012-06-01 20:58:55 +0000836
837 FunctionIn();
838
839 if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
SeungBeom Kim54cbf392012-07-04 09:56:12 +0900840 OMX_BUFFERHEADERTYPE *OMXBuffer = NULL;
841 OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
842 if (OMXBuffer == NULL) {
Jiho Chang38ef2572012-06-01 20:58:55 +0000843 ret = OMX_ErrorUndefined;
844 goto EXIT;
845 }
Jiho Chang38ef2572012-06-01 20:58:55 +0000846
SeungBeom Kim54cbf392012-07-04 09:56:12 +0900847 OMXBuffer->nTimeStamp = pSrcInputData->timeStamp;
848 OMXBuffer->nFlags = pSrcInputData->nFlags;
849 Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer);
Jiho Chang38ef2572012-06-01 20:58:55 +0000850
851 ret = OMX_ErrorNone;
852 goto EXIT;
853 }
854
SeungBeom Kim833233f2012-07-04 14:13:28 +0900855 Set_H264Enc_Param(pExynosComponent);
856 pEncParam = &pMFCH264Handle->encParam;
857 if (pEncOps->Set_EncParam) {
858 if(pEncOps->Set_EncParam(pH264Enc->hMFCH264Handle.hMFCHandle, pEncParam) != VIDEO_ERROR_NONE) {
859 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
860 ret = OMX_ErrorInsufficientResources;
861 goto EXIT;
862 }
863 }
Jiho Chang38ef2572012-06-01 20:58:55 +0000864
SeungBeom Kim1021eb32013-06-04 16:37:06 +0900865 if (pMFCH264Handle->bPrependSpsPpsToIdr == OMX_TRUE) {
866 if (pEncOps->Enable_PrependSpsPpsToIdr)
867 pEncOps->Enable_PrependSpsPpsToIdr(pH264Enc->hMFCH264Handle.hMFCHandle);
868 else
869 Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "%s: Not supported control: Enable_PrependSpsPpsToIdr", __func__);
870 }
871
SeungBeom Kim833233f2012-07-04 14:13:28 +0900872 /* input buffer info: only 3 config values needed */
873 Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
SeungBeom Kim33d60442012-08-07 16:22:29 -0700874 bufferConf.eColorFormat = pEncParam->commonParam.FrameMap;//VIDEO_COLORFORMAT_NV12;
SeungBeom Kim833233f2012-07-04 14:13:28 +0900875 bufferConf.nFrameWidth = pExynosInputPort->portDefinition.format.video.nFrameWidth;
876 bufferConf.nFrameHeight = pExynosInputPort->portDefinition.format.video.nFrameHeight;
877 pInbufOps->Set_Shareable(hMFCHandle);
878 if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
SeungBeom Kim5b462292012-09-15 12:01:55 +0900879 inputBufferNumber = MAX_INPUTBUFFER_NUM_DYNAMIC;
SeungBeom Kim833233f2012-07-04 14:13:28 +0900880 } else if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
881 inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX;
882 }
Jiho Chang38ef2572012-06-01 20:58:55 +0000883
SeungBeom Kimfa894812012-07-11 19:00:42 +0900884 if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
885 /* should be done before prepare input buffer */
886 if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
887 ret = OMX_ErrorInsufficientResources;
888 goto EXIT;
889 }
SeungBeom Kim833233f2012-07-04 14:13:28 +0900890 }
891
892 /* set input buffer geometry */
893 if (pInbufOps->Set_Geometry) {
894 if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
895 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
896 ret = OMX_ErrorInsufficientResources;
897 goto EXIT;
898 }
899 }
900
901 /* setup input buffer */
902 if (pInbufOps->Setup(hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) {
903 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
904 ret = OMX_ErrorInsufficientResources;
905 goto EXIT;
906 }
907
SeungBeom Kim91f44a52012-07-04 15:01:54 +0900908 ExynosVideoPlane planes[MFC_INPUT_BUFFER_PLANE];
909 int plane;
910
Jiho Chang38ef2572012-06-01 20:58:55 +0000911 if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
SeungBeom Kimf8d511a2013-08-02 10:05:22 +0900912 ret = H264CodecRegistCodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX);
913 if (ret != OMX_ErrorNone)
914 goto EXIT;
Jiho Chang38ef2572012-06-01 20:58:55 +0000915 } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
SeungBeom Kim833233f2012-07-04 14:13:28 +0900916 if (pExynosInputPort->bStoreMetaData == OMX_TRUE) {
SeungBeom Kim91f44a52012-07-04 15:01:54 +0900917 /*************/
918 /* TBD */
919 /*************/
920 /* Does not require any actions. */
921 } else {
922 ret = OMX_ErrorNotImplemented;
923 goto EXIT;
SeungBeom Kim833233f2012-07-04 14:13:28 +0900924 }
Jiho Chang38ef2572012-06-01 20:58:55 +0000925 }
926
Jiho Chang38ef2572012-06-01 20:58:55 +0000927 pH264Enc->hMFCH264Handle.bConfiguredMFCSrc = OMX_TRUE;
928 ret = OMX_ErrorNone;
929
930EXIT:
931 FunctionOut();
932
933 return ret;
934}
935
936OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
937{
938 OMX_ERRORTYPE ret = OMX_ErrorNone;
939 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
940 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
941 EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
942 EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = &pH264Enc->hMFCH264Handle;
943 void *hMFCHandle = pMFCH264Handle->hMFCHandle;
SeungBeom Kim833233f2012-07-04 14:13:28 +0900944 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
945 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
Jiho Chang38ef2572012-06-01 20:58:55 +0000946
947 ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
948 ExynosVideoEncBufferOps *pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps;
949 ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
SeungBeom Kim833233f2012-07-04 14:13:28 +0900950 ExynosVideoGeometry bufferConf;
SeungBeom Kim833233f2012-07-04 14:13:28 +0900951 int i, nOutbufs;
Jiho Chang38ef2572012-06-01 20:58:55 +0000952
953 FunctionIn();
954
SeungBeom Kim833233f2012-07-04 14:13:28 +0900955 int OutBufferSize = pExynosOutputPort->portDefinition.format.video.nFrameWidth * pExynosOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2;
956 /* set geometry for output (dst) */
957 if (pOutbufOps->Set_Geometry) {
958 /* output buffer info: only 2 config values needed */
959 bufferConf.eCompressionFormat = VIDEO_CODING_AVC;
960 bufferConf.nSizeImage = OutBufferSize;
961
962 if (pOutbufOps->Set_Geometry(pH264Enc->hMFCH264Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
963 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
Jiho Chang38ef2572012-06-01 20:58:55 +0000964 ret = OMX_ErrorInsufficientResources;
965 goto EXIT;
966 }
967 }
968
SeungBeom Kim833233f2012-07-04 14:13:28 +0900969 /* should be done before prepare output buffer */
970 if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
971 ret = OMX_ErrorInsufficientResources;
972 goto EXIT;
973 }
Jiho Chang38ef2572012-06-01 20:58:55 +0000974
SeungBeom Kim833233f2012-07-04 14:13:28 +0900975 pOutbufOps->Set_Shareable(hMFCHandle);
976 int SetupBufferNumber = 0;
977 if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY)
978 SetupBufferNumber = MFC_OUTPUT_BUFFER_NUM_MAX;
979 else
980 SetupBufferNumber = pExynosOutputPort->portDefinition.nBufferCountActual;
SeungBeom Kim5b462292012-09-15 12:01:55 +0900981 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SetupBufferNumber:%d", SetupBufferNumber);
SeungBeom Kim833233f2012-07-04 14:13:28 +0900982
983 if (pOutbufOps->Setup(pH264Enc->hMFCH264Handle.hMFCHandle, SetupBufferNumber) != VIDEO_ERROR_NONE) {
984 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
985 ret = OMX_ErrorInsufficientResources;
986 goto EXIT;
987 }
988
989 OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0};
990 if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
SeungBeom Kimf8d511a2013-08-02 10:05:22 +0900991 OMX_U32 nPlaneSize[MFC_OUTPUT_BUFFER_PLANE] = {0};
992 nPlaneSize[0] = OutBufferSize;
993 ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, MFC_OUTPUT_BUFFER_NUM_MAX, nPlaneSize);
994 if (ret != OMX_ErrorNone)
995 goto EXIT;
996
997 ret = H264CodecRegistCodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, MFC_OUTPUT_BUFFER_NUM_MAX);
998 if (ret != OMX_ErrorNone)
999 goto EXIT;
1000
1001 /* Enqueue output buffer */
SeungBeom Kim833233f2012-07-04 14:13:28 +09001002 for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
SeungBeom Kim91f44a52012-07-04 15:01:54 +09001003 pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr,
1004 (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
SeungBeom Kim833233f2012-07-04 14:13:28 +09001005 }
1006 } else if ((pExynosOutputPort->bufferProcessType & BUFFER_SHARE) == BUFFER_SHARE) {
SeungBeom Kimf8d511a2013-08-02 10:05:22 +09001007 /* Register output buffer */
SeungBeom Kim833233f2012-07-04 14:13:28 +09001008 /*************/
1009 /* TBD */
1010 /*************/
SeungBeom Kimd4ec0f62014-10-10 15:05:34 +09001011 ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
SeungBeom Kim91f44a52012-07-04 15:01:54 +09001012 ExynosVideoPlane plane;
SeungBeom Kim833233f2012-07-04 14:13:28 +09001013 for (i = 0; i < pExynosOutputPort->portDefinition.nBufferCountActual; i++) {
SeungBeom Kim91f44a52012-07-04 15:01:54 +09001014 plane.addr = pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer;
1015 plane.fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[0];
1016 plane.allocSize = OutBufferSize;
1017 if (pOutbufOps->Register(hMFCHandle, &plane, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
SeungBeom Kimf8d511a2013-08-02 10:05:22 +09001018 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
SeungBeom Kim833233f2012-07-04 14:13:28 +09001019 ret = OMX_ErrorInsufficientResources;
1020 goto EXIT;
1021 }
SeungBeom Kimd4ec0f62014-10-10 15:05:34 +09001022 codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)&pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer,
SeungBeom Kim91f44a52012-07-04 15:01:54 +09001023 (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
SeungBeom Kimd4ec0f62014-10-10 15:05:34 +09001024 if (codecReturn != VIDEO_ERROR_NONE) {
1025 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Output buffer that has been entered is invalid.");
1026 ret = OMX_ErrorUndefined;
1027 goto EXIT;
1028 }
SeungBeom Kim833233f2012-07-04 14:13:28 +09001029 }
1030 }
1031
1032 /* start header encoding */
1033 if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
1034 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
1035 ret = OMX_ErrorInsufficientResources;
1036 goto EXIT;
1037 }
1038
1039 if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
1040 OMX_BUFFERHEADERTYPE *OMXBuffer = NULL;
1041 ExynosVideoBuffer *pVideoBuffer = NULL;
1042
1043 OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
1044 if (OMXBuffer == OMX_ErrorNone) {
1045 ret = OMX_ErrorUndefined;
1046 goto EXIT;
1047 }
1048
1049 if ((pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle)) == NULL) {
1050 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pOutbufOps->Dequeue", __FUNCTION__, __LINE__);
1051 ret = OMX_ErrorUndefined;
1052 goto EXIT;
1053 }
1054
1055 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "dst:0x%x, src:0x%x, dataSize:%d",
1056 OMXBuffer->pBuffer,
1057 pVideoBuffer->planes[0].addr,
1058 pVideoBuffer->planes[0].dataSize);
SeungBeom Kim91f44a52012-07-04 15:01:54 +09001059 Exynos_OSAL_Memcpy(OMXBuffer->pBuffer, pVideoBuffer->planes[0].addr, pVideoBuffer->planes[0].dataSize);
SeungBeom Kim833233f2012-07-04 14:13:28 +09001060 OMXBuffer->nFilledLen = pVideoBuffer->planes[0].dataSize;
1061 OMXBuffer->nOffset = 0;
1062 OMXBuffer->nTimeStamp = 0;
1063 OMXBuffer->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
1064 OMXBuffer->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1065 Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer);
1066
1067 pVideoEnc->bFirstOutput = OMX_TRUE;
1068 ret = OMX_ErrorNone;
1069
1070 H264CodecStop(pOMXComponent, OUTPUT_PORT_INDEX);
1071 }
Jiho Chang38ef2572012-06-01 20:58:55 +00001072 pH264Enc->hMFCH264Handle.bConfiguredMFCDst = OMX_TRUE;
1073
Jiho Chang38ef2572012-06-01 20:58:55 +00001074 ret = OMX_ErrorNone;
1075
1076EXIT:
1077 FunctionOut();
1078
1079 return ret;
1080}
1081
Jiho Chang800a8d72012-04-26 13:25:31 -07001082OMX_ERRORTYPE Exynos_H264Enc_GetParameter(
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001083 OMX_IN OMX_HANDLETYPE hComponent,
1084 OMX_IN OMX_INDEXTYPE nParamIndex,
1085 OMX_INOUT OMX_PTR pComponentParameterStructure)
1086{
1087 OMX_ERRORTYPE ret = OMX_ErrorNone;
1088 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1089 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1090
1091 FunctionIn();
1092
1093 if (hComponent == NULL || pComponentParameterStructure == NULL) {
1094 ret = OMX_ErrorBadParameter;
1095 goto EXIT;
1096 }
1097 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1098 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1099 if (ret != OMX_ErrorNone) {
1100 goto EXIT;
1101 }
1102 if (pOMXComponent->pComponentPrivate == NULL) {
1103 ret = OMX_ErrorBadParameter;
1104 goto EXIT;
1105 }
1106
1107 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1108 if (pExynosComponent->currentState == OMX_StateInvalid ) {
1109 ret = OMX_ErrorInvalidState;
1110 goto EXIT;
1111 }
1112
1113 switch (nParamIndex) {
1114 case OMX_IndexParamVideoAvc:
1115 {
1116 OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure;
1117 OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL;
1118 EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
1119
1120 ret = Exynos_OMX_Check_SizeVersion(pDstAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
1121 if (ret != OMX_ErrorNone) {
1122 goto EXIT;
1123 }
1124
1125 if (pDstAVCComponent->nPortIndex >= ALL_PORT_NUM) {
1126 ret = OMX_ErrorBadPortIndex;
1127 goto EXIT;
1128 }
1129
1130 pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1131 pSrcAVCComponent = &pH264Enc->AVCComponent[pDstAVCComponent->nPortIndex];
1132
1133 Exynos_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
1134 }
1135 break;
1136 case OMX_IndexParamStandardComponentRole:
1137 {
1138 OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
1139 ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
1140 if (ret != OMX_ErrorNone) {
1141 goto EXIT;
1142 }
1143
1144 Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_ENC_ROLE);
1145 }
1146 break;
1147 case OMX_IndexParamVideoProfileLevelQuerySupported:
1148 {
1149 OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
1150 EXYNOS_OMX_VIDEO_PROFILELEVEL *pProfileLevel = NULL;
1151 OMX_U32 maxProfileLevelNum = 0;
1152
1153 ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1154 if (ret != OMX_ErrorNone) {
1155 goto EXIT;
1156 }
1157
1158 if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1159 ret = OMX_ErrorBadPortIndex;
1160 goto EXIT;
1161 }
1162
1163 pProfileLevel = supportedAVCProfileLevels;
1164 maxProfileLevelNum = sizeof(supportedAVCProfileLevels) / sizeof(EXYNOS_OMX_VIDEO_PROFILELEVEL);
1165
1166 if (pDstProfileLevel->nProfileIndex >= maxProfileLevelNum) {
1167 ret = OMX_ErrorNoMore;
1168 goto EXIT;
1169 }
1170
1171 pProfileLevel += pDstProfileLevel->nProfileIndex;
1172 pDstProfileLevel->eProfile = pProfileLevel->profile;
1173 pDstProfileLevel->eLevel = pProfileLevel->level;
1174 }
1175 break;
1176 case OMX_IndexParamVideoProfileLevelCurrent:
1177 {
1178 OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
1179 OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL;
1180 EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
1181
1182 ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1183 if (ret != OMX_ErrorNone) {
1184 goto EXIT;
1185 }
1186
1187 if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1188 ret = OMX_ErrorBadPortIndex;
1189 goto EXIT;
1190 }
1191
1192 pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1193 pSrcAVCComponent = &pH264Enc->AVCComponent[pDstProfileLevel->nPortIndex];
1194
1195 pDstProfileLevel->eProfile = pSrcAVCComponent->eProfile;
1196 pDstProfileLevel->eLevel = pSrcAVCComponent->eLevel;
1197 }
1198 break;
1199 case OMX_IndexParamVideoErrorCorrection:
1200 {
1201 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
1202 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
1203 EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
1204
1205 ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
1206 if (ret != OMX_ErrorNone) {
1207 goto EXIT;
1208 }
1209
1210 if (pDstErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) {
1211 ret = OMX_ErrorBadPortIndex;
1212 goto EXIT;
1213 }
1214
1215 pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1216 pSrcErrorCorrectionType = &pH264Enc->errorCorrectionType[OUTPUT_PORT_INDEX];
1217
1218 pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1219 pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1220 pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1221 pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1222 pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1223 }
1224 break;
1225 default:
1226 ret = Exynos_OMX_VideoEncodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
1227 break;
1228 }
1229EXIT:
1230 FunctionOut();
1231
1232 return ret;
1233}
1234
Jiho Chang800a8d72012-04-26 13:25:31 -07001235OMX_ERRORTYPE Exynos_H264Enc_SetParameter(
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001236 OMX_IN OMX_HANDLETYPE hComponent,
1237 OMX_IN OMX_INDEXTYPE nIndex,
1238 OMX_IN OMX_PTR pComponentParameterStructure)
1239{
1240 OMX_ERRORTYPE ret = OMX_ErrorNone;
1241 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1242 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1243
1244 FunctionIn();
1245
1246 if (hComponent == NULL || pComponentParameterStructure == NULL) {
1247 ret = OMX_ErrorBadParameter;
1248 goto EXIT;
1249 }
1250 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1251 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1252 if (ret != OMX_ErrorNone) {
1253 goto EXIT;
1254 }
1255 if (pOMXComponent->pComponentPrivate == NULL) {
1256 ret = OMX_ErrorBadParameter;
1257 goto EXIT;
1258 }
1259
1260 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1261 if (pExynosComponent->currentState == OMX_StateInvalid ) {
1262 ret = OMX_ErrorInvalidState;
1263 goto EXIT;
1264 }
1265
1266 switch (nIndex) {
1267 case OMX_IndexParamVideoAvc:
1268 {
1269 OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL;
1270 OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure;
1271 EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
1272
1273 ret = Exynos_OMX_Check_SizeVersion(pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
1274 if (ret != OMX_ErrorNone) {
1275 goto EXIT;
1276 }
1277
1278 if (pSrcAVCComponent->nPortIndex >= ALL_PORT_NUM) {
1279 ret = OMX_ErrorBadPortIndex;
1280 goto EXIT;
1281 }
1282
1283 pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1284 pDstAVCComponent = &pH264Enc->AVCComponent[pSrcAVCComponent->nPortIndex];
1285
1286 Exynos_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
1287 }
1288 break;
1289 case OMX_IndexParamStandardComponentRole:
1290 {
1291 OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
1292
1293 ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
1294 if (ret != OMX_ErrorNone) {
1295 goto EXIT;
1296 }
1297
1298 if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1299 ret = OMX_ErrorIncorrectStateOperation;
1300 goto EXIT;
1301 }
1302
1303 if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_ENC_ROLE)) {
1304 pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
1305 } else {
1306 ret = OMX_ErrorBadParameter;
1307 goto EXIT;
1308 }
1309 }
1310 break;
1311 case OMX_IndexParamVideoProfileLevelCurrent:
1312 {
1313 OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
1314 OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL;
1315 EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
1316
1317 ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
SeungBeom Kim3e79a272012-07-03 20:03:59 +09001318 if (ret != OMX_ErrorNone)
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001319 goto EXIT;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001320
1321 if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1322 ret = OMX_ErrorBadPortIndex;
1323 goto EXIT;
1324 }
1325
1326 pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1327
1328 pDstAVCComponent = &pH264Enc->AVCComponent[pSrcProfileLevel->nPortIndex];
1329 pDstAVCComponent->eProfile = pSrcProfileLevel->eProfile;
1330 pDstAVCComponent->eLevel = pSrcProfileLevel->eLevel;
1331 }
1332 break;
1333 case OMX_IndexParamVideoErrorCorrection:
1334 {
1335 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
1336 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
1337 EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
1338
1339 ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
1340 if (ret != OMX_ErrorNone) {
1341 goto EXIT;
1342 }
1343
1344 if (pSrcErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) {
1345 ret = OMX_ErrorBadPortIndex;
1346 goto EXIT;
1347 }
1348
1349 pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1350 pDstErrorCorrectionType = &pH264Enc->errorCorrectionType[OUTPUT_PORT_INDEX];
1351
1352 pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1353 pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1354 pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1355 pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1356 pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1357 }
1358 break;
SeungBeom Kim1021eb32013-06-04 16:37:06 +09001359 case OMX_IndexParamPrependSPSPPSToIDR:
1360 {
1361 EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1362
1363 ret = Exynos_OSAL_SetPrependSPSPPSToIDR(pComponentParameterStructure, &(pH264Enc->hMFCH264Handle.bPrependSpsPpsToIdr));
1364 }
1365 break;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001366 default:
1367 ret = Exynos_OMX_VideoEncodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
1368 break;
1369 }
1370EXIT:
1371 FunctionOut();
1372
1373 return ret;
1374}
1375
Jiho Chang800a8d72012-04-26 13:25:31 -07001376OMX_ERRORTYPE Exynos_H264Enc_GetConfig(
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001377 OMX_HANDLETYPE hComponent,
1378 OMX_INDEXTYPE nIndex,
1379 OMX_PTR pComponentConfigStructure)
1380{
1381 OMX_ERRORTYPE ret = OMX_ErrorNone;
1382 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1383 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1384 EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
1385
1386 FunctionIn();
1387
1388 if (hComponent == NULL || pComponentConfigStructure == NULL) {
1389 ret = OMX_ErrorBadParameter;
1390 goto EXIT;
1391 }
1392 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1393 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1394 if (ret != OMX_ErrorNone) {
1395 goto EXIT;
1396 }
1397 if (pOMXComponent->pComponentPrivate == NULL) {
1398 ret = OMX_ErrorBadParameter;
1399 goto EXIT;
1400 }
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001401 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1402 if (pExynosComponent->currentState == OMX_StateInvalid) {
1403 ret = OMX_ErrorInvalidState;
1404 goto EXIT;
1405 }
1406 pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1407
1408 switch (nIndex) {
1409 case OMX_IndexConfigVideoAVCIntraPeriod:
1410 {
1411 OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pAVCIntraPeriod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pComponentConfigStructure;
1412 OMX_U32 portIndex = pAVCIntraPeriod->nPortIndex;
1413
1414 if ((portIndex != OUTPUT_PORT_INDEX)) {
1415 ret = OMX_ErrorBadPortIndex;
1416 goto EXIT;
1417 } else {
1418 pAVCIntraPeriod->nIDRPeriod = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1;
1419 pAVCIntraPeriod->nPFrames = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames;
1420 }
1421 }
1422 break;
1423 default:
1424 ret = Exynos_OMX_VideoEncodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
1425 break;
1426 }
1427
1428EXIT:
1429 FunctionOut();
1430
1431 return ret;
1432}
1433
Jiho Chang800a8d72012-04-26 13:25:31 -07001434OMX_ERRORTYPE Exynos_H264Enc_SetConfig(
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001435 OMX_HANDLETYPE hComponent,
1436 OMX_INDEXTYPE nIndex,
1437 OMX_PTR pComponentConfigStructure)
1438{
1439 OMX_ERRORTYPE ret = OMX_ErrorNone;
1440 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1441 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1442 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
1443 EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
1444
1445 FunctionIn();
1446
1447 if (hComponent == NULL || pComponentConfigStructure == NULL) {
1448 ret = OMX_ErrorBadParameter;
1449 goto EXIT;
1450 }
1451 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1452 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1453 if (ret != OMX_ErrorNone) {
1454 goto EXIT;
1455 }
1456 if (pOMXComponent->pComponentPrivate == NULL) {
1457 ret = OMX_ErrorBadParameter;
1458 goto EXIT;
1459 }
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001460 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1461 if (pExynosComponent->currentState == OMX_StateInvalid) {
1462 ret = OMX_ErrorInvalidState;
1463 goto EXIT;
1464 }
1465
SeungBeom Kim3e79a272012-07-03 20:03:59 +09001466 pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001467 pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1468
1469 switch (nIndex) {
1470 case OMX_IndexConfigVideoIntraPeriod:
1471 {
1472 EXYNOS_OMX_VIDEOENC_COMPONENT *pVEncBase = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle);
1473 OMX_U32 nPFrames = (*((OMX_U32 *)pComponentConfigStructure)) - 1;
1474
1475 pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames = nPFrames;
1476
1477 ret = OMX_ErrorNone;
1478 }
1479 break;
1480 case OMX_IndexConfigVideoAVCIntraPeriod:
1481 {
1482 OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pAVCIntraPeriod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pComponentConfigStructure;
1483 OMX_U32 portIndex = pAVCIntraPeriod->nPortIndex;
1484
1485 if ((portIndex != OUTPUT_PORT_INDEX)) {
1486 ret = OMX_ErrorBadPortIndex;
1487 goto EXIT;
1488 } else {
1489 if (pAVCIntraPeriod->nIDRPeriod == (pAVCIntraPeriod->nPFrames + 1))
1490 pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames = pAVCIntraPeriod->nPFrames;
1491 else {
1492 ret = OMX_ErrorBadParameter;
1493 goto EXIT;
1494 }
1495 }
1496 }
1497 break;
1498 default:
1499 ret = Exynos_OMX_VideoEncodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
1500 break;
1501 }
1502
1503EXIT:
1504 if (ret == OMX_ErrorNone)
1505 pVideoEnc->configChange = OMX_TRUE;
1506
1507 FunctionOut();
1508
1509 return ret;
1510}
1511
Jiho Chang800a8d72012-04-26 13:25:31 -07001512OMX_ERRORTYPE Exynos_H264Enc_GetExtensionIndex(
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001513 OMX_IN OMX_HANDLETYPE hComponent,
1514 OMX_IN OMX_STRING cParameterName,
1515 OMX_OUT OMX_INDEXTYPE *pIndexType)
1516{
1517 OMX_ERRORTYPE ret = OMX_ErrorNone;
1518 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1519 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1520
1521 FunctionIn();
1522
1523 if (hComponent == NULL) {
1524 ret = OMX_ErrorBadParameter;
1525 goto EXIT;
1526 }
1527 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1528 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1529 if (ret != OMX_ErrorNone) {
1530 goto EXIT;
1531 }
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001532 if (pOMXComponent->pComponentPrivate == NULL) {
1533 ret = OMX_ErrorBadParameter;
1534 goto EXIT;
1535 }
1536 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001537 if ((cParameterName == NULL) || (pIndexType == NULL)) {
1538 ret = OMX_ErrorBadParameter;
1539 goto EXIT;
1540 }
1541 if (pExynosComponent->currentState == OMX_StateInvalid) {
1542 ret = OMX_ErrorInvalidState;
1543 goto EXIT;
1544 }
1545 if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_VIDEO_INTRAPERIOD) == 0) {
1546 *pIndexType = OMX_IndexConfigVideoIntraPeriod;
1547 ret = OMX_ErrorNone;
SeungBeom Kim1021eb32013-06-04 16:37:06 +09001548 } else if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_PREPEND_SPSPPS_TO_IDR) == 0) {
1549 *pIndexType = OMX_IndexParamPrependSPSPPSToIDR;
1550 ret = OMX_ErrorNone;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001551 } else {
1552 ret = Exynos_OMX_VideoEncodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
1553 }
1554
1555EXIT:
1556 FunctionOut();
1557
1558 return ret;
1559}
1560
Jiho Chang800a8d72012-04-26 13:25:31 -07001561OMX_ERRORTYPE Exynos_H264Enc_ComponentRoleEnum(OMX_HANDLETYPE hComponent, OMX_U8 *cRole, OMX_U32 nIndex)
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001562{
1563 OMX_ERRORTYPE ret = OMX_ErrorNone;
1564 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1565 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1566
1567 FunctionIn();
1568
1569 if ((hComponent == NULL) || (cRole == NULL)) {
1570 ret = OMX_ErrorBadParameter;
1571 goto EXIT;
1572 }
1573 if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
1574 Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_H264_ENC_ROLE);
1575 ret = OMX_ErrorNone;
1576 } else {
1577 ret = OMX_ErrorNoMore;
1578 }
1579
1580EXIT:
1581 FunctionOut();
1582
1583 return ret;
1584}
1585
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001586/* MFC Init */
Jiho Chang800a8d72012-04-26 13:25:31 -07001587OMX_ERRORTYPE Exynos_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent)
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001588{
Jiho Chang38ef2572012-06-01 20:58:55 +00001589 OMX_ERRORTYPE ret = OMX_ErrorNone;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001590 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
Jiho Chang38ef2572012-06-01 20:58:55 +00001591 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1592 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1593 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1594 EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;;
SeungBeom Kim1021eb32013-06-04 16:37:06 +09001595 EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = NULL;
Jiho Chang38ef2572012-06-01 20:58:55 +00001596 OMX_PTR hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
1597 OMX_COLOR_FORMATTYPE eColorFormat;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001598
Jiho Chang38ef2572012-06-01 20:58:55 +00001599 ExynosVideoEncOps *pEncOps = NULL;
1600 ExynosVideoEncBufferOps *pInbufOps = NULL;
1601 ExynosVideoEncBufferOps *pOutbufOps = NULL;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001602
Jiho Chang38ef2572012-06-01 20:58:55 +00001603 int i = 0;
1604
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001605 FunctionIn();
1606
Jiho Chang38ef2572012-06-01 20:58:55 +00001607 pH264Enc->hMFCH264Handle.bConfiguredMFCSrc = OMX_FALSE;
1608 pH264Enc->hMFCH264Handle.bConfiguredMFCDst = OMX_FALSE;
Jiho Chang38ef2572012-06-01 20:58:55 +00001609 pExynosComponent->bUseFlagEOF = OMX_TRUE;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001610 pExynosComponent->bSaveFlagEOS = OMX_FALSE;
SeungBeom Kim81a947b2013-01-16 15:23:19 +09001611 pExynosComponent->bBehaviorEOS = OMX_FALSE;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001612
Jiho Chang38ef2572012-06-01 20:58:55 +00001613 eColorFormat = pExynosInputPort->portDefinition.format.video.eColorFormat;
Jiho Chang38ef2572012-06-01 20:58:55 +00001614 if (pExynosInputPort->bStoreMetaData == OMX_TRUE) {
1615 if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) {
1616 pExynosInputPort->bufferProcessType = BUFFER_COPY;
SeungBeom Kim3e79a272012-07-03 20:03:59 +09001617 } else {
Jiho Chang38ef2572012-06-01 20:58:55 +00001618 pExynosInputPort->bufferProcessType = BUFFER_SHARE;
1619 }
SeungBeom Kim833233f2012-07-04 14:13:28 +09001620 } else {
1621 pExynosInputPort->bufferProcessType = BUFFER_COPY;
Jiho Chang38ef2572012-06-01 20:58:55 +00001622 }
Jiho Chang800a8d72012-04-26 13:25:31 -07001623
Jiho Chang38ef2572012-06-01 20:58:55 +00001624 /* H.264 Codec Open */
1625 ret = H264CodecOpen(pH264Enc);
1626 if (ret != OMX_ErrorNone) {
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001627 goto EXIT;
1628 }
SeungBeom Kim1021eb32013-06-04 16:37:06 +09001629 pMFCH264Handle = &pH264Enc->hMFCH264Handle;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001630
Jiho Chang38ef2572012-06-01 20:58:55 +00001631 pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
1632 pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps;
1633 pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001634
Jiho Chang38ef2572012-06-01 20:58:55 +00001635 if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1636 Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
1637 Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1638 } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
1639 /*************/
1640 /* TBD */
1641 /*************/
1642 /* Does not require any actions. */
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001643 }
1644
Jiho Chang38ef2572012-06-01 20:58:55 +00001645 pH264Enc->bSourceStart = OMX_FALSE;
1646 Exynos_OSAL_SignalCreate(&pH264Enc->hSourceStartEvent);
Jiho Chang38ef2572012-06-01 20:58:55 +00001647 pH264Enc->bDestinationStart = OMX_FALSE;
1648 Exynos_OSAL_SignalCreate(&pH264Enc->hDestinationStartEvent);
1649
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001650 Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP);
1651 Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
1652 pH264Enc->hMFCH264Handle.indexTimestamp = 0;
Jiho Chang38ef2572012-06-01 20:58:55 +00001653 pH264Enc->hMFCH264Handle.outputIndexTimestamp = 0;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001654
Jiho Chang38ef2572012-06-01 20:58:55 +00001655 pExynosComponent->getAllDelayBuffer = OMX_FALSE;
1656
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001657EXIT:
1658 FunctionOut();
1659
1660 return ret;
1661}
1662
1663/* MFC Terminate */
Jiho Chang800a8d72012-04-26 13:25:31 -07001664OMX_ERRORTYPE Exynos_H264Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001665{
1666 OMX_ERRORTYPE ret = OMX_ErrorNone;
1667 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1668 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle);
Jiho Chang38ef2572012-06-01 20:58:55 +00001669 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1670 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1671 EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1672 OMX_PTR hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
1673
1674 ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
1675 ExynosVideoEncBufferOps *pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps;
1676 ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
1677
SeungBeom Kim91f44a52012-07-04 15:01:54 +09001678 int i = 0, plane = 0;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001679
1680 FunctionIn();
1681
Jiho Chang38ef2572012-06-01 20:58:55 +00001682 Exynos_OSAL_SignalTerminate(pH264Enc->hDestinationStartEvent);
1683 pH264Enc->hDestinationStartEvent = NULL;
1684 pH264Enc->bDestinationStart = OMX_FALSE;
1685 Exynos_OSAL_SignalTerminate(pH264Enc->hSourceStartEvent);
1686 pH264Enc->hSourceStartEvent = NULL;
1687 pH264Enc->bSourceStart = OMX_FALSE;
1688
SeungBeom Kim833233f2012-07-04 14:13:28 +09001689 if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
SeungBeom Kimf8d511a2013-08-02 10:05:22 +09001690 Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
SeungBeom Kim833233f2012-07-04 14:13:28 +09001691 Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
1692 Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
1693 } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
1694 /*************/
1695 /* TBD */
1696 /*************/
1697 /* Does not require any actions. */
1698 }
1699
Jiho Chang38ef2572012-06-01 20:58:55 +00001700 if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
SeungBeom Kimf8d511a2013-08-02 10:05:22 +09001701 Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX);
SeungBeom Kim3e79a272012-07-03 20:03:59 +09001702 Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
Jiho Chang38ef2572012-06-01 20:58:55 +00001703 Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
SeungBeom Kimc2eff702013-11-08 12:33:36 +09001704 pVideoEnc->bFirstInput = OMX_TRUE;
Jiho Chang38ef2572012-06-01 20:58:55 +00001705 } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
1706 /*************/
1707 /* TBD */
1708 /*************/
1709 /* Does not require any actions. */
1710 }
Jiho Chang38ef2572012-06-01 20:58:55 +00001711 H264CodecClose(pH264Enc);
1712
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001713EXIT:
1714 FunctionOut();
1715
1716 return ret;
1717}
1718
Jiho Chang38ef2572012-06-01 20:58:55 +00001719OMX_ERRORTYPE Exynos_H264Enc_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001720{
Jiho Chang38ef2572012-06-01 20:58:55 +00001721 OMX_ERRORTYPE ret = OMX_ErrorNone;
1722 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1723 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1724 EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1725 void *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
1726 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1727 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1728 OMX_U32 oneFrameSize = pSrcInputData->dataLen;
Jiho Chang38ef2572012-06-01 20:58:55 +00001729 ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
1730 ExynosVideoEncBufferOps *pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps;
1731 ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
1732 ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001733 int i;
1734
Jiho Chang38ef2572012-06-01 20:58:55 +00001735 FunctionIn();
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001736
SeungBeom Kim833233f2012-07-04 14:13:28 +09001737 if (pH264Enc->hMFCH264Handle.bConfiguredMFCSrc == OMX_FALSE) {
1738 ret = H264CodecSrcSetup(pOMXComponent, pSrcInputData);
1739 if ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)
1740 goto EXIT;
1741 }
Jiho Chang38ef2572012-06-01 20:58:55 +00001742 if (pH264Enc->hMFCH264Handle.bConfiguredMFCDst == OMX_FALSE) {
1743 ret = H264CodecDstSetup(pOMXComponent);
SeungBeom Kimd4ec0f62014-10-10 15:05:34 +09001744 if (ret != OMX_ErrorNone) {
1745 goto EXIT;
1746 }
Jiho Chang38ef2572012-06-01 20:58:55 +00001747 }
1748
SeungBeom Kima7fc5932012-11-20 12:33:33 +09001749 if (pVideoEnc->configChange == OMX_TRUE) {
1750 Change_H264Enc_Param(pExynosComponent);
1751 pVideoEnc->configChange = OMX_FALSE;
1752 }
Jiho Chang38ef2572012-06-01 20:58:55 +00001753 if ((pSrcInputData->dataLen >= 0) ||
1754 ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
SeungBeom Kim5b462292012-09-15 12:01:55 +09001755 OMX_U32 nAllocLen[MFC_INPUT_BUFFER_PLANE] = {0, 0};
SeungBeom Kim833233f2012-07-04 14:13:28 +09001756 OMX_U32 pMFCYUVDataSize[MFC_INPUT_BUFFER_PLANE] = {NULL, NULL};
SeungBeom Kim91f44a52012-07-04 15:01:54 +09001757 ExynosVideoPlane planes[MFC_INPUT_BUFFER_PLANE];
1758 int plane;
Jiho Chang38ef2572012-06-01 20:58:55 +00001759
1760 pExynosComponent->timeStamp[pH264Enc->hMFCH264Handle.indexTimestamp] = pSrcInputData->timeStamp;
1761 pExynosComponent->nFlags[pH264Enc->hMFCH264Handle.indexTimestamp] = pSrcInputData->nFlags;
1762 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "input timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x", pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pH264Enc->hMFCH264Handle.indexTimestamp, pSrcInputData->nFlags);
1763 pEncOps->Set_FrameTag(hMFCHandle, pH264Enc->hMFCH264Handle.indexTimestamp);
1764 pH264Enc->hMFCH264Handle.indexTimestamp++;
1765 pH264Enc->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP;
1766
1767 /* queue work for input buffer */
James Dongb8d6caa2012-08-02 15:42:19 -07001768 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Exynos_H264Enc_SrcIn(): oneFrameSize: %d, bufferHeader: 0x%x", oneFrameSize, pSrcInputData->bufferHeader);
SeungBeom Kim91f44a52012-07-04 15:01:54 +09001769 pMFCYUVDataSize[0] = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight;
1770 pMFCYUVDataSize[1] = pMFCYUVDataSize[0] / 2;
SeungBeom Kim833233f2012-07-04 14:13:28 +09001771
SeungBeom Kim91f44a52012-07-04 15:01:54 +09001772#ifdef USE_METADATABUFFERTYPE
SeungBeom Kim5b462292012-09-15 12:01:55 +09001773 nAllocLen[0] = ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameWidth) *
1774 ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameHeight);
1775 nAllocLen[1] = ALIGN(nAllocLen[0]/2,256);
SeungBeom Kim833233f2012-07-04 14:13:28 +09001776
SeungBeom Kim5b462292012-09-15 12:01:55 +09001777 if ((pExynosInputPort->bStoreMetaData == OMX_TRUE) &&
1778 (pExynosInputPort->bufferProcessType == BUFFER_SHARE)) {
1779 codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
1780 (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer,
1781 (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.fd,
1782 (unsigned int *)nAllocLen, (unsigned int *)pMFCYUVDataSize,
1783 MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
1784 } else {
SeungBeom Kim91f44a52012-07-04 15:01:54 +09001785 codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer,
1786 (unsigned int *)pMFCYUVDataSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
Jiho Chang38ef2572012-06-01 20:58:55 +00001787 }
SeungBeom Kim5b462292012-09-15 12:01:55 +09001788#else
1789 codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer,
1790 (unsigned int *)pMFCYUVDataSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
SeungBeom Kim91f44a52012-07-04 15:01:54 +09001791#endif
Jiho Chang38ef2572012-06-01 20:58:55 +00001792 if (codecReturn != VIDEO_ERROR_NONE) {
1793 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pInbufOps->Enqueue", __FUNCTION__, __LINE__);
1794 ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001795 goto EXIT;
1796 }
SeungBeom Kim833233f2012-07-04 14:13:28 +09001797 H264CodecStart(pOMXComponent, INPUT_PORT_INDEX);
1798 if (pH264Enc->bSourceStart == OMX_FALSE) {
1799 pH264Enc->bSourceStart = OMX_TRUE;
1800 Exynos_OSAL_SignalSet(pH264Enc->hSourceStartEvent);
1801 Exynos_OSAL_SleepMillisec(0);
1802 }
1803 if (pH264Enc->bDestinationStart == OMX_FALSE) {
1804 pH264Enc->bDestinationStart = OMX_TRUE;
1805 Exynos_OSAL_SignalSet(pH264Enc->hDestinationStartEvent);
1806 Exynos_OSAL_SleepMillisec(0);
1807 }
Jiho Chang800a8d72012-04-26 13:25:31 -07001808 }
1809
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001810 ret = OMX_ErrorNone;
1811
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001812EXIT:
Jiho Chang38ef2572012-06-01 20:58:55 +00001813 FunctionOut();
1814
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001815 return ret;
1816}
1817
Jiho Chang38ef2572012-06-01 20:58:55 +00001818OMX_ERRORTYPE Exynos_H264Enc_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001819{
Jiho Chang38ef2572012-06-01 20:58:55 +00001820 OMX_ERRORTYPE ret = OMX_ErrorNone;
1821 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1822 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1823 EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1824 void *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
1825 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1826 ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
1827 ExynosVideoEncBufferOps *pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps;
1828 ExynosVideoBuffer *pVideoBuffer;
SeungBeom Kim5b462292012-09-15 12:01:55 +09001829 ExynosVideoBuffer videoBuffer;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001830
1831 FunctionIn();
1832
SeungBeom Kim5b462292012-09-15 12:01:55 +09001833 if ((pExynosInputPort->bStoreMetaData == OMX_TRUE) &&
1834 (pExynosInputPort->bufferProcessType == BUFFER_SHARE)) {
1835 if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE)
1836 pVideoBuffer = &videoBuffer;
1837 else
1838 pVideoBuffer = NULL;
1839 } else {
1840 pVideoBuffer = pInbufOps->Dequeue(hMFCHandle);
1841 }
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001842
Jiho Chang38ef2572012-06-01 20:58:55 +00001843 pSrcOutputData->dataLen = 0;
1844 pSrcOutputData->usedDataLen = 0;
1845 pSrcOutputData->remainDataLen = 0;
1846 pSrcOutputData->nFlags = 0;
1847 pSrcOutputData->timeStamp = 0;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001848
Jiho Chang38ef2572012-06-01 20:58:55 +00001849 if (pVideoBuffer == NULL) {
1850 pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL;
1851 pSrcOutputData->allocSize = 0;
1852 pSrcOutputData->pPrivate = NULL;
1853 pSrcOutputData->bufferHeader = NULL;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001854 } else {
SeungBeom Kim91f44a52012-07-04 15:01:54 +09001855 int plane = 0;
1856 for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
1857 pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
1858 pSrcOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
1859 }
SeungBeom Kim833233f2012-07-04 14:13:28 +09001860 pSrcOutputData->allocSize = pVideoBuffer->planes[0].allocSize +
Jiho Chang38ef2572012-06-01 20:58:55 +00001861 pVideoBuffer->planes[1].allocSize +
1862 pVideoBuffer->planes[2].allocSize;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001863
Jiho Chang38ef2572012-06-01 20:58:55 +00001864 if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1865 int i = 0;
SeungBeom Kim91f44a52012-07-04 15:01:54 +09001866 while (pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[0] != pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]) {
Jiho Chang38ef2572012-06-01 20:58:55 +00001867 if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
1868 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - Lost buffer", __FUNCTION__, __LINE__);
1869 ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
1870 goto EXIT;
1871 }
1872 i++;
1873 }
SeungBeom Kim91f44a52012-07-04 15:01:54 +09001874 pVideoEnc->pMFCEncInputBuffer[i]->dataSize = 0;
Jiho Chang38ef2572012-06-01 20:58:55 +00001875 pSrcOutputData->pPrivate = pVideoEnc->pMFCEncInputBuffer[i];
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001876 }
Jiho Chang38ef2572012-06-01 20:58:55 +00001877
1878 /* For Share Buffer */
1879 pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001880 }
1881
Jiho Chang38ef2572012-06-01 20:58:55 +00001882 ret = OMX_ErrorNone;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001883
1884EXIT:
1885 FunctionOut();
1886
1887 return ret;
1888}
1889
Jiho Chang38ef2572012-06-01 20:58:55 +00001890OMX_ERRORTYPE Exynos_H264Enc_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001891{
Jiho Chang38ef2572012-06-01 20:58:55 +00001892 OMX_ERRORTYPE ret = OMX_ErrorNone;
1893 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1894 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1895 EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1896 void *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
1897 ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
1898 ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
1899 OMX_U32 dataLen = 0;
1900 ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001901
1902 FunctionIn();
1903
Jiho Chang38ef2572012-06-01 20:58:55 +00001904 if (pDstInputData->buffer.singlePlaneBuffer.dataBuffer == NULL) {
1905 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
1906 ret = OMX_ErrorBadParameter;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001907 goto EXIT;
1908 }
Jiho Chang38ef2572012-06-01 20:58:55 +00001909
SeungBeom Kim91f44a52012-07-04 15:01:54 +09001910 codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)&pDstInputData->buffer.singlePlaneBuffer.dataBuffer,
SeungBeom Kim833233f2012-07-04 14:13:28 +09001911 (unsigned int *)&dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader);
Jiho Chang38ef2572012-06-01 20:58:55 +00001912
1913 if (codecReturn != VIDEO_ERROR_NONE) {
1914 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pOutbufOps->Enqueue", __FUNCTION__, __LINE__);
1915 ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
1916 goto EXIT;
1917 }
SeungBeom Kim833233f2012-07-04 14:13:28 +09001918 H264CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
Jiho Chang38ef2572012-06-01 20:58:55 +00001919
1920 ret = OMX_ErrorNone;
1921
1922EXIT:
1923 FunctionOut();
1924
1925 return ret;
1926}
1927
1928OMX_ERRORTYPE Exynos_H264Enc_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
1929{
1930 OMX_ERRORTYPE ret = OMX_ErrorNone;
1931 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1932 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1933 EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1934 void *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
1935 ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
1936 ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
1937 ExynosVideoBuffer *pVideoBuffer;
1938 ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
1939 ExynosVideoGeometry bufferGeometry;
1940 OMX_S32 indexTimestamp = 0;
1941
1942 FunctionIn();
1943
1944 if (pH264Enc->bDestinationStart == OMX_FALSE) {
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001945 ret = OMX_ErrorNone;
1946 goto EXIT;
1947 }
1948
Jiho Chang38ef2572012-06-01 20:58:55 +00001949 if ((pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle)) == NULL) {
1950 ret = OMX_ErrorNone;
1951 goto EXIT;
1952 }
1953
1954 pH264Enc->hMFCH264Handle.outputIndexTimestamp++;
1955 pH264Enc->hMFCH264Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
1956
1957 pDstOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr;
SeungBeom Kim91f44a52012-07-04 15:01:54 +09001958 pDstOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd;
Jiho Chang38ef2572012-06-01 20:58:55 +00001959 pDstOutputData->allocSize = pVideoBuffer->planes[0].allocSize;
1960 pDstOutputData->dataLen = pVideoBuffer->planes[0].dataSize;
1961 pDstOutputData->remainDataLen = pVideoBuffer->planes[0].dataSize;
1962 pDstOutputData->usedDataLen = 0;
1963 pDstOutputData->pPrivate = pVideoBuffer;
1964 /* For Share Buffer */
1965 pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
1966
1967 if (pVideoEnc->bFirstOutput == OMX_FALSE) {
1968 OMX_U8 *p = NULL;
1969 int iSpsSize = 0;
1970 int iPpsSize = 0;
1971
1972 /* Calculate sps/pps size if needed */
1973 p = FindDelimiter((OMX_U8 *)(pDstOutputData->buffer.singlePlaneBuffer.dataBuffer + 4),
1974 pDstOutputData->dataLen - 4);
1975
1976 iSpsSize = (unsigned int)p - (unsigned int)pDstOutputData->buffer.singlePlaneBuffer.dataBuffer;
1977 pH264Enc->hMFCH264Handle.headerData.pHeaderSPS =
1978 (OMX_PTR)pDstOutputData->buffer.singlePlaneBuffer.dataBuffer;
1979 pH264Enc->hMFCH264Handle.headerData.SPSLen = iSpsSize;
SeungBeom Kim3e79a272012-07-03 20:03:59 +09001980
Jiho Chang38ef2572012-06-01 20:58:55 +00001981 iPpsSize = pDstOutputData->dataLen - iSpsSize;
1982 pH264Enc->hMFCH264Handle.headerData.pHeaderPPS =
1983 (OMX_U8 *)pDstOutputData->buffer.singlePlaneBuffer.dataBuffer + iSpsSize;
1984 pH264Enc->hMFCH264Handle.headerData.PPSLen = iPpsSize;
SeungBeom Kim3e79a272012-07-03 20:03:59 +09001985
Jiho Chang38ef2572012-06-01 20:58:55 +00001986 pDstOutputData->timeStamp = 0;
1987 pDstOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
1988 pDstOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
SeungBeom Kim833233f2012-07-04 14:13:28 +09001989 pVideoEnc->bFirstOutput = OMX_TRUE;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001990 } else {
Jiho Chang38ef2572012-06-01 20:58:55 +00001991 indexTimestamp = pEncOps->Get_FrameTag(pH264Enc->hMFCH264Handle.hMFCHandle);
1992 if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
1993 pDstOutputData->timeStamp = pExynosComponent->timeStamp[pH264Enc->hMFCH264Handle.outputIndexTimestamp];
1994 pDstOutputData->nFlags = pExynosComponent->nFlags[pH264Enc->hMFCH264Handle.outputIndexTimestamp];
1995 } else {
1996 pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
1997 pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp];
1998 }
Jiho Chang20d3e6e2012-03-24 03:43:08 +09001999
Jiho Chang38ef2572012-06-01 20:58:55 +00002000 pDstOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
2001 if (pVideoBuffer->frameType == VIDEO_FRAME_I)
2002 pDstOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
2003 }
2004
2005 if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
SeungBeom Kim81a947b2013-01-16 15:23:19 +09002006 (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) &&
2007 (pExynosComponent->bBehaviorEOS == OMX_FALSE))) {
SeungBeom Kim833233f2012-07-04 14:13:28 +09002008 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%x displayStatus:%d, nFlags0x%x", pExynosComponent, displayStatus, pDstOutputData->nFlags);
Jiho Chang38ef2572012-06-01 20:58:55 +00002009 pDstOutputData->remainDataLen = 0;
2010 }
SeungBeom Kim81a947b2013-01-16 15:23:19 +09002011 if (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) &&
2012 (pExynosComponent->bBehaviorEOS == OMX_TRUE))
2013 pExynosComponent->bBehaviorEOS = OMX_FALSE;
Jiho Chang38ef2572012-06-01 20:58:55 +00002014
2015 ret = OMX_ErrorNone;
2016
2017EXIT:
2018 FunctionOut();
2019
2020 return ret;
2021}
2022
2023OMX_ERRORTYPE Exynos_H264Enc_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
2024{
2025 OMX_ERRORTYPE ret = OMX_ErrorNone;
2026 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2027 EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2028 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2029
2030 FunctionIn();
2031
2032 if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2033 ret = OMX_ErrorNone;
2034 goto EXIT;
2035 }
2036 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2037 ret = OMX_ErrorNone;
2038 goto EXIT;
2039 }
2040
2041 ret = Exynos_H264Enc_SrcIn(pOMXComponent, pSrcInputData);
2042 if (ret != OMX_ErrorNone) {
2043 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - SrcIn -> event is thrown to client", __FUNCTION__, __LINE__);
2044 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2045 pExynosComponent->callbackData,
2046 OMX_EventError, ret, 0, NULL);
2047 }
2048
2049EXIT:
2050 FunctionOut();
2051
2052 return ret;
2053}
2054
2055OMX_ERRORTYPE Exynos_H264Enc_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
2056{
2057 OMX_ERRORTYPE ret = OMX_ErrorNone;
2058 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2059 EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2060 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2061
2062 FunctionIn();
2063
2064 if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2065 ret = OMX_ErrorNone;
2066 goto EXIT;
2067 }
2068
2069 if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
2070 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2071 ret = OMX_ErrorNone;
2072 goto EXIT;
2073 }
2074 }
Jiho Chang38ef2572012-06-01 20:58:55 +00002075 if ((pH264Enc->bSourceStart == OMX_FALSE) &&
2076 (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
2077 Exynos_OSAL_SignalWait(pH264Enc->hSourceStartEvent, DEF_MAX_WAIT_TIME);
2078 Exynos_OSAL_SignalReset(pH264Enc->hSourceStartEvent);
2079 }
2080
2081 ret = Exynos_H264Enc_SrcOut(pOMXComponent, pSrcOutputData);
2082 if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) {
2083 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - SrcOut -> event is thrown to client", __FUNCTION__, __LINE__);
2084 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2085 pExynosComponent->callbackData,
2086 OMX_EventError, ret, 0, NULL);
2087 }
2088
2089EXIT:
2090 FunctionOut();
2091
2092 return ret;
2093}
2094
2095OMX_ERRORTYPE Exynos_H264Enc_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
2096{
2097 OMX_ERRORTYPE ret = OMX_ErrorNone;
2098 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2099 EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2100 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2101
2102 FunctionIn();
2103
2104 if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2105 ret = OMX_ErrorNone;
2106 goto EXIT;
2107 }
2108 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2109 ret = OMX_ErrorNone;
2110 goto EXIT;
2111 }
Jiho Chang38ef2572012-06-01 20:58:55 +00002112 if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
2113 if ((pH264Enc->bDestinationStart == OMX_FALSE) &&
2114 (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2115 Exynos_OSAL_SignalWait(pH264Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2116 Exynos_OSAL_SignalReset(pH264Enc->hDestinationStartEvent);
2117 }
2118 }
Jiho Chang38ef2572012-06-01 20:58:55 +00002119 if (pH264Enc->hMFCH264Handle.bConfiguredMFCDst == OMX_TRUE) {
2120 ret = Exynos_H264Enc_DstIn(pOMXComponent, pDstInputData);
2121 if (ret != OMX_ErrorNone) {
2122 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - DstIn -> event is thrown to client", __FUNCTION__, __LINE__);
2123 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2124 pExynosComponent->callbackData,
2125 OMX_EventError, ret, 0, NULL);
2126 }
2127 }
2128
2129EXIT:
2130 FunctionOut();
2131
2132 return ret;
2133}
2134
2135OMX_ERRORTYPE Exynos_H264Enc_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
2136{
2137 OMX_ERRORTYPE ret = OMX_ErrorNone;
2138 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2139 EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2140 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2141
2142 FunctionIn();
2143
2144 if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2145 ret = OMX_ErrorNone;
2146 goto EXIT;
2147 }
2148 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2149 ret = OMX_ErrorNone;
2150 goto EXIT;
2151 }
2152
2153 if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
2154 if ((pH264Enc->bDestinationStart == OMX_FALSE) &&
2155 (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2156 Exynos_OSAL_SignalWait(pH264Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2157 Exynos_OSAL_SignalReset(pH264Enc->hDestinationStartEvent);
2158 }
2159 }
Jiho Chang38ef2572012-06-01 20:58:55 +00002160 ret = Exynos_H264Enc_DstOut(pOMXComponent, pDstOutputData);
2161 if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) {
2162 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - DstOut -> event is thrown to client", __FUNCTION__, __LINE__);
2163 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2164 pExynosComponent->callbackData,
2165 OMX_EventError, ret, 0, NULL);
Jiho Chang20d3e6e2012-03-24 03:43:08 +09002166 }
2167
2168EXIT:
2169 FunctionOut();
2170
2171 return ret;
2172}
2173
2174OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName)
2175{
2176 OMX_ERRORTYPE ret = OMX_ErrorNone;
2177 OMX_COMPONENTTYPE *pOMXComponent = NULL;
2178 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
2179 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
2180 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
2181 EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
2182 int i = 0;
2183
2184 FunctionIn();
2185
2186 if ((hComponent == NULL) || (componentName == NULL)) {
2187 ret = OMX_ErrorBadParameter;
2188 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
2189 goto EXIT;
2190 }
2191 if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_ENC, componentName) != 0) {
2192 ret = OMX_ErrorBadParameter;
2193 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
2194 goto EXIT;
2195 }
2196
2197 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2198 ret = Exynos_OMX_VideoEncodeComponentInit(pOMXComponent);
2199 if (ret != OMX_ErrorNone) {
2200 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
2201 goto EXIT;
2202 }
2203 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2204 pExynosComponent->codecType = HW_VIDEO_ENC_CODEC;
2205
2206 pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
2207 if (pExynosComponent->componentName == NULL) {
2208 Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
2209 ret = OMX_ErrorInsufficientResources;
2210 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2211 goto EXIT;
2212 }
2213 Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
2214
2215 pH264Enc = Exynos_OSAL_Malloc(sizeof(EXYNOS_H264ENC_HANDLE));
2216 if (pH264Enc == NULL) {
2217 Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
2218 ret = OMX_ErrorInsufficientResources;
2219 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2220 goto EXIT;
2221 }
2222 Exynos_OSAL_Memset(pH264Enc, 0, sizeof(EXYNOS_H264ENC_HANDLE));
2223 pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
2224 pVideoEnc->hCodecHandle = (OMX_HANDLETYPE)pH264Enc;
Jiho Chang38ef2572012-06-01 20:58:55 +00002225 pVideoEnc->quantization.nQpI = 20;
2226 pVideoEnc->quantization.nQpP = 20;
2227 pVideoEnc->quantization.nQpB = 20;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09002228
2229 Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H264_ENC);
2230 /* Set componentVersion */
2231 pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2232 pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2233 pExynosComponent->componentVersion.s.nRevision = REVISION_NUMBER;
2234 pExynosComponent->componentVersion.s.nStep = STEP_NUMBER;
2235 /* Set specVersion */
2236 pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2237 pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2238 pExynosComponent->specVersion.s.nRevision = REVISION_NUMBER;
2239 pExynosComponent->specVersion.s.nStep = STEP_NUMBER;
2240
Jiho Chang20d3e6e2012-03-24 03:43:08 +09002241 /* Input port */
2242 pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2243 pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2244 pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2245 pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2246 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
2247 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
2248 Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2249 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
2250 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
2251 pExynosPort->portDefinition.bEnabled = OMX_TRUE;
Jiho Chang38ef2572012-06-01 20:58:55 +00002252 pExynosPort->bufferProcessType = BUFFER_COPY;
2253 pExynosPort->portWayType = WAY2_PORT;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09002254
2255 /* Output port */
2256 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2257 pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2258 pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2259 pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2260 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
2261 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
2262 Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2263 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/avc");
2264 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
2265 pExynosPort->portDefinition.bEnabled = OMX_TRUE;
SeungBeom Kim833233f2012-07-04 14:13:28 +09002266 pExynosPort->bufferProcessType = BUFFER_SHARE;
Jiho Chang38ef2572012-06-01 20:58:55 +00002267 pExynosPort->portWayType = WAY2_PORT;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09002268
2269 for(i = 0; i < ALL_PORT_NUM; i++) {
2270 INIT_SET_SIZE_VERSION(&pH264Enc->AVCComponent[i], OMX_VIDEO_PARAM_AVCTYPE);
2271 pH264Enc->AVCComponent[i].nPortIndex = i;
2272 pH264Enc->AVCComponent[i].eProfile = OMX_VIDEO_AVCProfileBaseline;
2273 pH264Enc->AVCComponent[i].eLevel = OMX_VIDEO_AVCLevel31;
2274
2275 pH264Enc->AVCComponent[i].nPFrames = 20;
2276 }
2277
Jiho Chang800a8d72012-04-26 13:25:31 -07002278 pOMXComponent->GetParameter = &Exynos_H264Enc_GetParameter;
2279 pOMXComponent->SetParameter = &Exynos_H264Enc_SetParameter;
2280 pOMXComponent->GetConfig = &Exynos_H264Enc_GetConfig;
2281 pOMXComponent->SetConfig = &Exynos_H264Enc_SetConfig;
2282 pOMXComponent->GetExtensionIndex = &Exynos_H264Enc_GetExtensionIndex;
2283 pOMXComponent->ComponentRoleEnum = &Exynos_H264Enc_ComponentRoleEnum;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09002284 pOMXComponent->ComponentDeInit = &Exynos_OMX_ComponentDeinit;
2285
Jiho Chang38ef2572012-06-01 20:58:55 +00002286 pExynosComponent->exynos_codec_componentInit = &Exynos_H264Enc_Init;
2287 pExynosComponent->exynos_codec_componentTerminate = &Exynos_H264Enc_Terminate;
2288
2289 pVideoEnc->exynos_codec_srcInputProcess = &Exynos_H264Enc_srcInputBufferProcess;
2290 pVideoEnc->exynos_codec_srcOutputProcess = &Exynos_H264Enc_srcOutputBufferProcess;
2291 pVideoEnc->exynos_codec_dstInputProcess = &Exynos_H264Enc_dstInputBufferProcess;
2292 pVideoEnc->exynos_codec_dstOutputProcess = &Exynos_H264Enc_dstOutputBufferProcess;
2293
2294 pVideoEnc->exynos_codec_start = &H264CodecStart;
2295 pVideoEnc->exynos_codec_stop = &H264CodecStop;
2296 pVideoEnc->exynos_codec_bufferProcessRun = &H264CodecOutputBufferProcessRun;
2297 pVideoEnc->exynos_codec_enqueueAllBuffer = &H264CodecEnQueueAllBuffer;
2298
2299 pVideoEnc->exynos_checkInputFrame = NULL;
2300 pVideoEnc->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData;
2301 pVideoEnc->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
Jiho Chang38ef2572012-06-01 20:58:55 +00002302
2303 pVideoEnc->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
2304 if (pVideoEnc->hSharedMemory == NULL) {
2305 Exynos_OSAL_Free(pH264Enc);
2306 pH264Enc = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
2307 Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
2308 ret = OMX_ErrorInsufficientResources;
2309 goto EXIT;
2310 }
Jiho Chang20d3e6e2012-03-24 03:43:08 +09002311
2312 pExynosComponent->currentState = OMX_StateLoaded;
2313
2314 ret = OMX_ErrorNone;
2315
2316EXIT:
2317 FunctionOut();
2318
2319 return ret;
2320}
2321
2322OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent)
2323{
Jiho Chang38ef2572012-06-01 20:58:55 +00002324 OMX_ERRORTYPE ret = OMX_ErrorNone;
2325 OMX_COMPONENTTYPE *pOMXComponent = NULL;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09002326 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
Jiho Chang38ef2572012-06-01 20:58:55 +00002327 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09002328 EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
2329
2330 FunctionIn();
2331
2332 if (hComponent == NULL) {
2333 ret = OMX_ErrorBadParameter;
2334 goto EXIT;
2335 }
2336 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2337 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
Jiho Chang38ef2572012-06-01 20:58:55 +00002338 pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
2339
2340 Exynos_OSAL_SharedMemory_Close(pVideoEnc->hSharedMemory);
Jiho Chang20d3e6e2012-03-24 03:43:08 +09002341
2342 Exynos_OSAL_Free(pExynosComponent->componentName);
2343 pExynosComponent->componentName = NULL;
2344
Jiho Chang38ef2572012-06-01 20:58:55 +00002345 pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09002346 if (pH264Enc != NULL) {
2347 Exynos_OSAL_Free(pH264Enc);
Jiho Chang38ef2572012-06-01 20:58:55 +00002348 pH264Enc = pVideoEnc->hCodecHandle = NULL;
Jiho Chang20d3e6e2012-03-24 03:43:08 +09002349 }
2350
2351 ret = Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
2352 if (ret != OMX_ErrorNone) {
2353 goto EXIT;
2354 }
2355
2356 ret = OMX_ErrorNone;
2357
2358EXIT:
2359 FunctionOut();
2360
2361 return ret;
2362}