1 /* 2 * Copyright 2010 Samsung Electronics Co. LTD 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <stdlib.h> 18 #include <unistd.h> 19 #include <string.h> 20 #include <fcntl.h> 21 22 #include <sys/types.h> 23 #include <sys/stat.h> 24 #include <sys/ioctl.h> 25 #include <sys/mman.h> 26 #include <utils/Log.h> 27 28 #include "SsbSipMfcApi.h" 29 #include "mfc_interface.h" 30 31 #define _MFCLIB_MAGIC_NUMBER 0x92241001 32 33 void *SsbSipMfcEncOpen(void) 34 { 35 int hMFCOpen; 36 _MFCLIB *pCTX; 37 unsigned int mapped_addr; 38 39 hMFCOpen = open(S5PC110_MFC_DEV_NAME, O_RDWR | O_NDELAY); 40 if (hMFCOpen < 0) { 41 LOGE("SsbSipMfcEncOpen: MFC Open failure\n"); 42 return NULL; 43 } 44 45 pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB)); 46 if (pCTX == NULL) { 47 LOGE("SsbSipMfcEncOpen: malloc failed.\n"); 48 close(hMFCOpen); 49 return NULL; 50 } 51 52 mapped_addr = (unsigned int)mmap(0, MMAP_BUFFER_SIZE_MMAP, PROT_READ | PROT_WRITE, MAP_SHARED, hMFCOpen, 0); 53 if (!mapped_addr) { 54 LOGE("SsbSipMfcEncOpen: FIMV5.0 driver address mapping failed\n"); 55 return NULL; 56 } 57 58 memset(pCTX, 0, sizeof(_MFCLIB)); 59 60 pCTX->magic = _MFCLIB_MAGIC_NUMBER; 61 pCTX->hMFC = hMFCOpen; 62 pCTX->mapped_addr = mapped_addr; 63 pCTX->inter_buff_status = MFC_USE_NONE; 64 65 return (void *)pCTX; 66 } 67 68 SSBSIP_MFC_ERROR_CODE SsbSipMfcEncInit(void *openHandle, void *param) 69 { 70 int ret_code; 71 int dpbBufSize; 72 73 _MFCLIB *pCTX; 74 mfc_common_args EncArg; 75 mfc_common_args user_addr_arg, phys_addr_arg; 76 SSBSIP_MFC_ENC_H264_PARAM *h264_arg; 77 SSBSIP_MFC_ENC_MPEG4_PARAM *mpeg4_arg; 78 SSBSIP_MFC_ENC_H263_PARAM *h263_arg; 79 SSBSIP_MFC_CODEC_TYPE codec_type; 80 81 pCTX = (_MFCLIB *)openHandle; 82 memset(&EncArg, 0, sizeof(mfc_common_args)); 83 84 LOGV("SsbSipMfcEncInit: Encode Init start\n"); 85 86 mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM *)param; 87 codec_type = mpeg4_arg->codecType; 88 89 if ((codec_type != MPEG4_ENC) && 90 (codec_type != H264_ENC) && 91 (codec_type != H263_ENC)) { 92 LOGE("SsbSipMfcEncOpen: Undefined codec type.\n"); 93 return MFC_RET_INVALID_PARAM; 94 } 95 96 pCTX->codec_type = codec_type; 97 98 switch (pCTX->codec_type) { 99 case MPEG4_ENC: 100 LOGV("SsbSipMfcEncInit: MPEG4 Encode\n"); 101 mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM *)param; 102 103 pCTX->width = mpeg4_arg->SourceWidth; 104 pCTX->height = mpeg4_arg->SourceHeight; 105 break; 106 107 case H263_ENC: 108 LOGV("SsbSipMfcEncInit: H263 Encode\n"); 109 h263_arg = (SSBSIP_MFC_ENC_H263_PARAM *)param; 110 111 pCTX->width = h263_arg->SourceWidth; 112 pCTX->height = h263_arg->SourceHeight; 113 break; 114 115 case H264_ENC: 116 LOGV("SsbSipMfcEncInit: H264 Encode\n"); 117 h264_arg = (SSBSIP_MFC_ENC_H264_PARAM *)param; 118 119 pCTX->width = h264_arg->SourceWidth; 120 pCTX->height = h264_arg->SourceHeight; 121 break; 122 123 default: 124 break; 125 } 126 127 switch (pCTX->codec_type) { 128 case MPEG4_ENC: 129 mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM*)param; 130 131 EncArg.args.enc_init_mpeg4.in_codec_type = pCTX->codec_type; 132 EncArg.args.enc_init_mpeg4.in_profile_level = ENC_PROFILE_LEVEL(mpeg4_arg->ProfileIDC, mpeg4_arg->LevelIDC); 133 134 EncArg.args.enc_init_mpeg4.in_width = mpeg4_arg->SourceWidth; 135 EncArg.args.enc_init_mpeg4.in_height = mpeg4_arg->SourceHeight; 136 EncArg.args.enc_init_mpeg4.in_gop_num = mpeg4_arg->IDRPeriod; 137 if (mpeg4_arg->DisableQpelME) 138 EncArg.args.enc_init_mpeg4.in_qpelME_enable = 0; 139 else 140 EncArg.args.enc_init_mpeg4.in_qpelME_enable = 1; 141 142 EncArg.args.enc_init_mpeg4.in_MS_mode = mpeg4_arg->SliceMode; 143 EncArg.args.enc_init_mpeg4.in_MS_size = mpeg4_arg->SliceArgument; 144 145 if (mpeg4_arg->NumberBFrames > 2) { 146 LOGE("SsbSipMfcEncInit: No such BframeNum is supported.\n"); 147 return MFC_RET_INVALID_PARAM; 148 } 149 EncArg.args.enc_init_mpeg4.in_BframeNum = mpeg4_arg->NumberBFrames; 150 EncArg.args.enc_init_mpeg4.in_mb_refresh = mpeg4_arg->RandomIntraMBRefresh; 151 152 /* rate control*/ 153 EncArg.args.enc_init_mpeg4.in_RC_frm_enable = mpeg4_arg->EnableFRMRateControl; 154 if ((mpeg4_arg->QSCodeMin > 51) || (mpeg4_arg->QSCodeMax > 51)) { 155 LOGE("SsbSipMfcEncInit: No such Min/Max QP is supported.\n"); 156 return MFC_RET_INVALID_PARAM; 157 } 158 EncArg.args.enc_init_mpeg4.in_RC_qbound = ENC_RC_QBOUND(mpeg4_arg->QSCodeMin, mpeg4_arg->QSCodeMax); 159 EncArg.args.enc_init_mpeg4.in_RC_rpara = mpeg4_arg->CBRPeriodRf; 160 161 /* pad control */ 162 EncArg.args.enc_init_mpeg4.in_pad_ctrl_on = mpeg4_arg->PadControlOn; 163 if ((mpeg4_arg->LumaPadVal > 255) || (mpeg4_arg->CbPadVal > 255) || (mpeg4_arg->CrPadVal > 255)) { 164 LOGE("SsbSipMfcEncInit: No such Pad value is supported.\n"); 165 return MFC_RET_INVALID_PARAM; 166 } 167 EncArg.args.enc_init_mpeg4.in_luma_pad_val = mpeg4_arg->LumaPadVal; 168 EncArg.args.enc_init_mpeg4.in_cb_pad_val = mpeg4_arg->CbPadVal; 169 EncArg.args.enc_init_mpeg4.in_cr_pad_val = mpeg4_arg->CrPadVal; 170 171 EncArg.args.enc_init_mpeg4.in_time_increament_res = mpeg4_arg->TimeIncreamentRes; 172 EncArg.args.enc_init_mpeg4.in_time_vop_time_increament = mpeg4_arg->VopTimeIncreament; 173 EncArg.args.enc_init_mpeg4.in_RC_framerate = (mpeg4_arg->TimeIncreamentRes / mpeg4_arg->VopTimeIncreament); 174 EncArg.args.enc_init_mpeg4.in_RC_bitrate = mpeg4_arg->Bitrate; 175 if ((mpeg4_arg->FrameQp > 51) || (mpeg4_arg->FrameQp_P) > 51 || (mpeg4_arg->FrameQp_B > 51)) { 176 LOGE("SsbSipMfcEncInit: No such FrameQp is supported.\n"); 177 return MFC_RET_INVALID_PARAM; 178 } 179 EncArg.args.enc_init_mpeg4.in_frame_qp = mpeg4_arg->FrameQp; 180 if (mpeg4_arg->FrameQp_P) 181 EncArg.args.enc_init_mpeg4.in_frame_P_qp = mpeg4_arg->FrameQp_P; 182 else 183 EncArg.args.enc_init_mpeg4.in_frame_P_qp = mpeg4_arg->FrameQp; 184 if (mpeg4_arg->FrameQp_B) 185 EncArg.args.enc_init_mpeg4.in_frame_B_qp = mpeg4_arg->FrameQp_B; 186 else 187 EncArg.args.enc_init_mpeg4.in_frame_B_qp = mpeg4_arg->FrameQp; 188 189 break; 190 191 case H263_ENC: 192 h263_arg = (SSBSIP_MFC_ENC_H263_PARAM *)param; 193 194 EncArg.args.enc_init_mpeg4.in_codec_type = pCTX->codec_type; 195 EncArg.args.enc_init_mpeg4.in_profile_level = ENC_PROFILE_LEVEL(66, 40); 196 EncArg.args.enc_init_mpeg4.in_width = h263_arg->SourceWidth; 197 EncArg.args.enc_init_mpeg4.in_height = h263_arg->SourceHeight; 198 EncArg.args.enc_init_mpeg4.in_gop_num = h263_arg->IDRPeriod; 199 EncArg.args.enc_init_mpeg4.in_mb_refresh = h263_arg->RandomIntraMBRefresh; 200 EncArg.args.enc_init_mpeg4.in_MS_mode = h263_arg->SliceMode; 201 EncArg.args.enc_init_mpeg4.in_MS_size = 0; 202 203 /* rate control*/ 204 EncArg.args.enc_init_mpeg4.in_RC_frm_enable = h263_arg->EnableFRMRateControl; 205 if ((h263_arg->QSCodeMin > 51) || (h263_arg->QSCodeMax > 51)) { 206 LOGE("SsbSipMfcEncInit: No such Min/Max QP is supported.\n"); 207 return MFC_RET_INVALID_PARAM; 208 } 209 EncArg.args.enc_init_mpeg4.in_RC_qbound = ENC_RC_QBOUND(h263_arg->QSCodeMin, h263_arg->QSCodeMax); 210 EncArg.args.enc_init_mpeg4.in_RC_rpara = h263_arg->CBRPeriodRf; 211 212 /* pad control */ 213 EncArg.args.enc_init_mpeg4.in_pad_ctrl_on = h263_arg->PadControlOn; 214 if ((h263_arg->LumaPadVal > 255) || (h263_arg->CbPadVal > 255) || (h263_arg->CrPadVal > 255)) { 215 LOGE("SsbSipMfcEncInit: No such Pad value is supported.\n"); 216 return MFC_RET_INVALID_PARAM; 217 } 218 EncArg.args.enc_init_mpeg4.in_luma_pad_val = h263_arg->LumaPadVal; 219 EncArg.args.enc_init_mpeg4.in_cb_pad_val = h263_arg->CbPadVal; 220 EncArg.args.enc_init_mpeg4.in_cr_pad_val = h263_arg->CrPadVal; 221 222 EncArg.args.enc_init_mpeg4.in_RC_framerate = h263_arg->FrameRate; 223 EncArg.args.enc_init_mpeg4.in_RC_bitrate = h263_arg->Bitrate; 224 if (h263_arg->FrameQp > 51) { 225 LOGE("SsbSipMfcEncInit: No such FrameQp is supported.\n"); 226 return MFC_RET_INVALID_PARAM; 227 } 228 EncArg.args.enc_init_mpeg4.in_frame_qp = h263_arg->FrameQp; 229 if (h263_arg->FrameQp_P) 230 EncArg.args.enc_init_mpeg4.in_frame_P_qp = h263_arg->FrameQp_P; 231 else 232 EncArg.args.enc_init_mpeg4.in_frame_P_qp = h263_arg->FrameQp; 233 234 break; 235 236 case H264_ENC: 237 h264_arg = (SSBSIP_MFC_ENC_H264_PARAM *)param; 238 239 EncArg.args.enc_init_h264.in_codec_type = H264_ENC; 240 EncArg.args.enc_init_h264.in_profile_level = ENC_PROFILE_LEVEL(h264_arg->ProfileIDC, h264_arg->LevelIDC); 241 242 EncArg.args.enc_init_h264.in_width = h264_arg->SourceWidth; 243 EncArg.args.enc_init_h264.in_height = h264_arg->SourceHeight; 244 EncArg.args.enc_init_h264.in_gop_num = h264_arg->IDRPeriod; 245 246 if ((h264_arg->NumberRefForPframes > 2) || (h264_arg->NumberReferenceFrames > 2)) { 247 LOGE("SsbSipMfcEncInit: No such ref Num is supported.\n"); 248 return MFC_RET_INVALID_PARAM; 249 } 250 EncArg.args.enc_init_h264.in_reference_num = h264_arg->NumberReferenceFrames; 251 EncArg.args.enc_init_h264.in_ref_num_p = h264_arg->NumberRefForPframes; 252 253 if ((h264_arg->SliceMode == 0) || (h264_arg->SliceMode == 1) || 254 (h264_arg->SliceMode == 2) || (h264_arg->SliceMode == 4)) { 255 EncArg.args.enc_init_h264.in_MS_mode = h264_arg->SliceMode; 256 } else { 257 LOGE("SsbSipMfcEncInit: No such slice mode is supported.\n"); 258 return MFC_RET_INVALID_PARAM; 259 } 260 EncArg.args.enc_init_h264.in_MS_size = h264_arg->SliceArgument; 261 262 if (h264_arg->NumberBFrames > 2) { 263 LOGE("SsbSipMfcEncInit: No such BframeNum is supported.\n"); 264 return MFC_RET_INVALID_PARAM; 265 } 266 EncArg.args.enc_init_h264.in_BframeNum = h264_arg->NumberBFrames; 267 268 EncArg.args.enc_init_h264.in_deblock_filt = h264_arg->LoopFilterDisable; 269 if ((abs(h264_arg->LoopFilterAlphaC0Offset) > 6) || (abs(h264_arg->LoopFilterBetaOffset) > 6)) { 270 LOGE("SsbSipMfcEncInit: No such AlphaC0Offset or BetaOffset is supported.\n"); 271 return MFC_RET_INVALID_PARAM; 272 } 273 EncArg.args.enc_init_h264.in_deblock_alpha_C0 = h264_arg->LoopFilterAlphaC0Offset; 274 EncArg.args.enc_init_h264.in_deblock_beta = h264_arg->LoopFilterBetaOffset; 275 276 EncArg.args.enc_init_h264.in_symbolmode = h264_arg->SymbolMode; 277 EncArg.args.enc_init_h264.in_interlace_mode = h264_arg->PictureInterlace; 278 EncArg.args.enc_init_h264.in_transform8x8_mode = h264_arg->Transform8x8Mode; 279 280 EncArg.args.enc_init_h264.in_mb_refresh = h264_arg->RandomIntraMBRefresh; 281 282 /* pad control */ 283 EncArg.args.enc_init_h264.in_pad_ctrl_on = h264_arg->PadControlOn; 284 if ((h264_arg->LumaPadVal > 255) || (h264_arg->CbPadVal > 255) || (h264_arg->CrPadVal > 255)) { 285 LOGE("SsbSipMfcEncInit: No such Pad value is supported.\n"); 286 return MFC_RET_INVALID_PARAM; 287 } 288 EncArg.args.enc_init_h264.in_luma_pad_val = h264_arg->LumaPadVal; 289 EncArg.args.enc_init_h264.in_cb_pad_val = h264_arg->CbPadVal; 290 EncArg.args.enc_init_h264.in_cr_pad_val = h264_arg->CrPadVal; 291 292 /* rate control*/ 293 EncArg.args.enc_init_h264.in_RC_frm_enable = h264_arg->EnableFRMRateControl; 294 EncArg.args.enc_init_h264.in_RC_mb_enable = h264_arg->EnableMBRateControl; 295 EncArg.args.enc_init_h264.in_RC_framerate = h264_arg->FrameRate; 296 EncArg.args.enc_init_h264.in_RC_bitrate = h264_arg->Bitrate; 297 if (h264_arg->FrameQp > 51) { 298 LOGE("SsbSipMfcEncInit: No such FrameQp is supported.\n"); 299 return MFC_RET_INVALID_PARAM; 300 } 301 EncArg.args.enc_init_h264.in_frame_qp = h264_arg->FrameQp; 302 if (h264_arg->FrameQp_P) 303 EncArg.args.enc_init_h264.in_frame_P_qp = h264_arg->FrameQp_P; 304 else 305 EncArg.args.enc_init_h264.in_frame_P_qp = h264_arg->FrameQp; 306 if (h264_arg->FrameQp_B) 307 EncArg.args.enc_init_h264.in_frame_B_qp = h264_arg->FrameQp_B; 308 else 309 EncArg.args.enc_init_h264.in_frame_B_qp = h264_arg->FrameQp; 310 311 if ((h264_arg->QSCodeMin > 51) || (h264_arg->QSCodeMax > 51)) { 312 LOGE("SsbSipMfcEncInit: No such Min/Max QP is supported.\n"); 313 return MFC_RET_INVALID_PARAM; 314 } 315 EncArg.args.enc_init_h264.in_RC_qbound = ENC_RC_QBOUND(h264_arg->QSCodeMin, h264_arg->QSCodeMax); 316 EncArg.args.enc_init_h264.in_RC_rpara = h264_arg->CBRPeriodRf; 317 EncArg.args.enc_init_h264.in_RC_mb_dark_disable = h264_arg->DarkDisable; 318 EncArg.args.enc_init_h264.in_RC_mb_smooth_disable = h264_arg->SmoothDisable; 319 EncArg.args.enc_init_h264.in_RC_mb_static_disable = h264_arg->StaticDisable; 320 EncArg.args.enc_init_h264.in_RC_mb_activity_disable = h264_arg->ActivityDisable; 321 322 /* default setting */ 323 EncArg.args.enc_init_h264.in_md_interweight_pps = 0; 324 EncArg.args.enc_init_h264.in_md_intraweight_pps = 0; 325 break; 326 327 default: 328 break; 329 } 330 331 EncArg.args.enc_init_mpeg4.in_mapped_addr = pCTX->mapped_addr; 332 333 ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_ENC_INIT, &EncArg); 334 if (EncArg.ret_code != MFC_RET_OK) { 335 LOGE("SsbSipMfcEncInit: IOCTL_MFC_ENC_INIT (%d) failed\n", EncArg.ret_code); 336 return MFC_RET_ENC_INIT_FAIL; 337 } 338 339 pCTX->virStrmBuf = EncArg.args.enc_init_mpeg4.out_u_addr.strm_ref_y; 340 pCTX->phyStrmBuf = EncArg.args.enc_init_mpeg4.out_p_addr.strm_ref_y; 341 pCTX->sizeStrmBuf = MAX_ENCODER_OUTPUT_BUFFER_SIZE; 342 pCTX->encodedHeaderSize = EncArg.args.enc_init_mpeg4.out_header_size; 343 344 pCTX->virMvRefYC = EncArg.args.enc_init_mpeg4.out_u_addr.mv_ref_yc; 345 346 pCTX->inter_buff_status |= MFC_USE_STRM_BUFF; 347 348 return MFC_RET_OK; 349 } 350 351 SSBSIP_MFC_ERROR_CODE SsbSipMfcEncExe(void *openHandle) 352 { 353 int ret_code; 354 _MFCLIB *pCTX; 355 mfc_common_args EncArg; 356 357 if (openHandle == NULL) { 358 LOGE("SsbSipMfcEncExe: openHandle is NULL\n"); 359 return MFC_RET_INVALID_PARAM; 360 } 361 362 pCTX = (_MFCLIB *)openHandle; 363 364 memset(&EncArg, 0x00, sizeof(mfc_common_args)); 365 366 EncArg.args.enc_exe.in_codec_type = pCTX->codec_type; 367 EncArg.args.enc_exe.in_Y_addr = (unsigned int)pCTX->phyFrmBuf.luma; 368 EncArg.args.enc_exe.in_CbCr_addr = (unsigned int)pCTX->phyFrmBuf.chroma; 369 EncArg.args.enc_exe.in_Y_addr_vir = (unsigned int)pCTX->virFrmBuf.luma; 370 EncArg.args.enc_exe.in_CbCr_addr_vir = (unsigned int)pCTX->virFrmBuf.chroma; 371 EncArg.args.enc_exe.in_strm_st = (unsigned int)pCTX->phyStrmBuf; 372 EncArg.args.enc_exe.in_strm_end = (unsigned int)pCTX->phyStrmBuf + pCTX->sizeStrmBuf; 373 EncArg.args.enc_exe.in_frametag = pCTX->in_frametag; 374 375 ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_ENC_EXE, &EncArg); 376 if (EncArg.ret_code != MFC_RET_OK) { 377 LOGE("SsbSipMfcDecExe: IOCTL_MFC_ENC_EXE failed(ret : %d)\n", EncArg.ret_code); 378 return MFC_RET_ENC_EXE_ERR; 379 } 380 381 pCTX->encodedDataSize = EncArg.args.enc_exe.out_encoded_size; 382 pCTX->encodedframeType = EncArg.args.enc_exe.out_frame_type; 383 pCTX->encoded_Y_paddr = EncArg.args.enc_exe.out_encoded_Y_paddr; 384 pCTX->encoded_C_paddr = EncArg.args.enc_exe.out_encoded_C_paddr; 385 pCTX->out_frametag_top = EncArg.args.enc_exe.out_frametag_top; 386 pCTX->out_frametag_bottom = EncArg.args.enc_exe.out_frametag_bottom; 387 388 return MFC_RET_OK; 389 } 390 391 SSBSIP_MFC_ERROR_CODE SsbSipMfcEncClose(void *openHandle) 392 { 393 int ret_code; 394 _MFCLIB *pCTX; 395 mfc_common_args free_arg; 396 397 if (openHandle == NULL) { 398 LOGE("SsbSipMfcEncClose: openHandle is NULL\n"); 399 return MFC_RET_INVALID_PARAM; 400 } 401 402 pCTX = (_MFCLIB *)openHandle; 403 404 if (pCTX->inter_buff_status & MFC_USE_YUV_BUFF) { 405 free_arg.args.mem_free.u_addr = pCTX->virFrmBuf.luma; 406 ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); 407 } 408 409 if (pCTX->inter_buff_status & MFC_USE_STRM_BUFF) { 410 free_arg.args.mem_free.u_addr = pCTX->virStrmBuf; 411 ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); 412 free_arg.args.mem_free.u_addr = pCTX->virMvRefYC; 413 ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); 414 } 415 416 pCTX->inter_buff_status = MFC_USE_NONE; 417 418 munmap((void *)pCTX->mapped_addr, MMAP_BUFFER_SIZE_MMAP); 419 close(pCTX->hMFC); 420 free(pCTX); 421 422 return MFC_RET_OK; 423 } 424 425 SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info) 426 { 427 int ret_code; 428 _MFCLIB *pCTX; 429 mfc_common_args user_addr_arg, phys_addr_arg; 430 int y_size, c_size; 431 int aligned_y_size, aligned_c_size; 432 433 if (openHandle == NULL) { 434 LOGE("SsbSipMfcEncGetInBuf: openHandle is NULL\n"); 435 return MFC_RET_INVALID_PARAM; 436 } 437 438 pCTX = (_MFCLIB *)openHandle; 439 440 user_addr_arg.args.mem_alloc.codec_type = pCTX->codec_type; 441 442 y_size = pCTX->width * pCTX->height; 443 c_size = (pCTX->width * pCTX->height) >> 1; 444 445 aligned_y_size = ALIGN_TO_8KB(ALIGN_TO_128B(pCTX->width) * ALIGN_TO_32B(pCTX->height)); 446 aligned_c_size = ALIGN_TO_8KB(ALIGN_TO_128B(pCTX->width) * ALIGN_TO_32B(pCTX->height/2)); 447 448 /* Allocate luma & chroma buf */ 449 user_addr_arg.args.mem_alloc.buff_size = aligned_y_size + aligned_c_size; 450 user_addr_arg.args.mem_alloc.mapped_addr = pCTX->mapped_addr; 451 ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_IN_BUF, &user_addr_arg); 452 if (ret_code < 0) { 453 LOGE("SsbSipMfcEncGetInBuf: IOCTL_MFC_GET_IN_BUF failed\n"); 454 return MFC_RET_ENC_GET_INBUF_FAIL; 455 } 456 pCTX->virFrmBuf.luma = user_addr_arg.args.mem_alloc.out_uaddr; 457 pCTX->virFrmBuf.chroma = user_addr_arg.args.mem_alloc.out_uaddr + (unsigned int)aligned_y_size; 458 pCTX->phyFrmBuf.luma = user_addr_arg.args.mem_alloc.out_paddr; 459 pCTX->phyFrmBuf.chroma = user_addr_arg.args.mem_alloc.out_paddr + (unsigned int)aligned_y_size; 460 461 pCTX->sizeFrmBuf.luma = (unsigned int)y_size; 462 pCTX->sizeFrmBuf.chroma = (unsigned int)c_size; 463 pCTX->inter_buff_status |= MFC_USE_YUV_BUFF; 464 465 input_info->YPhyAddr = (void*)pCTX->phyFrmBuf.luma; 466 input_info->CPhyAddr = (void*)pCTX->phyFrmBuf.chroma; 467 input_info->YVirAddr = (void*)pCTX->virFrmBuf.luma; 468 input_info->CVirAddr = (void*)pCTX->virFrmBuf.chroma; 469 470 return MFC_RET_OK; 471 } 472 473 SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info) 474 { 475 _MFCLIB *pCTX; 476 477 if (openHandle == NULL) { 478 LOGE("SsbSipMfcEncSetInBuf: openHandle is NULL\n"); 479 return MFC_RET_INVALID_PARAM; 480 } 481 482 LOGV("SsbSipMfcEncSetInBuf: input_info->YPhyAddr & input_info->CPhyAddr should be 64KB aligned\n"); 483 484 pCTX = (_MFCLIB *)openHandle; 485 486 pCTX->phyFrmBuf.luma = (unsigned int)input_info->YPhyAddr; 487 pCTX->phyFrmBuf.chroma = (unsigned int)input_info->CPhyAddr; 488 pCTX->virFrmBuf.luma = (unsigned int)input_info->YVirAddr; 489 pCTX->virFrmBuf.chroma = (unsigned int)input_info->CVirAddr; 490 491 pCTX->sizeFrmBuf.luma = (unsigned int)input_info->YSize; 492 pCTX->sizeFrmBuf.chroma = (unsigned int)input_info->CSize; 493 494 return MFC_RET_OK; 495 } 496 497 SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetOutBuf(void *openHandle, SSBSIP_MFC_ENC_OUTPUT_INFO *output_info) 498 { 499 _MFCLIB *pCTX; 500 501 if (openHandle == NULL) { 502 LOGE("SsbSipMfcEncGetOutBuf: openHandle is NULL\n"); 503 return MFC_RET_INVALID_PARAM; 504 } 505 506 pCTX = (_MFCLIB *)openHandle; 507 508 output_info->headerSize = pCTX->encodedHeaderSize; 509 output_info->dataSize = pCTX->encodedDataSize; 510 output_info->StrmPhyAddr = (void *)pCTX->phyStrmBuf; 511 output_info->StrmVirAddr = (void *)pCTX->virStrmBuf; 512 513 if (pCTX->encodedframeType == 0) 514 output_info->frameType = MFC_FRAME_TYPE_NOT_CODED; 515 else if (pCTX->encodedframeType == 1) 516 output_info->frameType = MFC_FRAME_TYPE_I_FRAME; 517 else if (pCTX->encodedframeType == 2) 518 output_info->frameType = MFC_FRAME_TYPE_P_FRAME; 519 else if (pCTX->encodedframeType == 3) 520 output_info->frameType = MFC_FRAME_TYPE_B_FRAME; 521 else if (pCTX->encodedframeType == 4) 522 output_info->frameType = MFC_FRAME_TYPE_OTHERS; 523 else { 524 LOGE("Strange encoded frame type = %d\n", pCTX->encodedframeType); 525 return MFC_RET_INVALID_PARAM; 526 } 527 528 output_info->encodedYPhyAddr = (void *)pCTX->encoded_Y_paddr; 529 output_info->encodedCPhyAddr = (void *)pCTX->encoded_C_paddr; 530 531 return MFC_RET_OK; 532 } 533 534 SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetOutBuf(void *openHandle, void *phyOutbuf, void *virOutbuf, int outputBufferSize) 535 { 536 _MFCLIB *pCTX; 537 538 if (openHandle == NULL) { 539 LOGE("SsbSipMfcEncSetOutBuf: openHandle is NULL\n"); 540 return MFC_RET_INVALID_PARAM; 541 } 542 543 pCTX = (_MFCLIB *)openHandle; 544 545 pCTX->phyStrmBuf = (int)phyOutbuf; 546 pCTX->virStrmBuf = (int)virOutbuf; 547 pCTX->sizeStrmBuf = outputBufferSize; 548 549 return MFC_RET_OK; 550 } 551 552 SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value) 553 { 554 int ret_code; 555 _MFCLIB *pCTX; 556 mfc_common_args EncArg; 557 558 if (openHandle == NULL) { 559 LOGE("SsbSipMfcEncSetConfig: openHandle is NULL\n"); 560 return MFC_RET_INVALID_PARAM; 561 } 562 563 if (value == NULL) { 564 LOGE("SsbSipMfcEncSetConfig: value is NULL\n"); 565 return MFC_RET_INVALID_PARAM; 566 } 567 568 pCTX = (_MFCLIB *)openHandle; 569 memset(&EncArg, 0x00, sizeof(mfc_common_args)); 570 571 switch (conf_type) { 572 case MFC_ENC_SETCONF_FRAME_TYPE: 573 case MFC_ENC_SETCONF_CHANGE_FRAME_RATE: 574 case MFC_ENC_SETCONF_CHANGE_BIT_RATE: 575 case MFC_ENC_SETCONF_ALLOW_FRAME_SKIP: 576 EncArg.args.set_config.in_config_param = conf_type; 577 EncArg.args.set_config.in_config_value[0] = *((unsigned int *) value); 578 EncArg.args.set_config.in_config_value[1] = 0; 579 break; 580 581 case MFC_ENC_SETCONF_FRAME_TAG: 582 pCTX->in_frametag = *((int *)value); 583 return MFC_RET_OK; 584 585 default: 586 LOGE("SsbSipMfcEncSetConfig: No such conf_type is supported.\n"); 587 return MFC_RET_INVALID_PARAM; 588 } 589 590 ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_SET_CONFIG, &EncArg); 591 if (EncArg.ret_code != MFC_RET_OK) { 592 LOGE("SsbSipMfcEncSetConfig: IOCTL_MFC_SET_CONFIG failed(ret : %d)\n", EncArg.ret_code); 593 return MFC_RET_ENC_SET_CONF_FAIL; 594 } 595 596 return MFC_RET_OK; 597 } 598 599 SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value) 600 { 601 int ret_code; 602 _MFCLIB *pCTX; 603 mfc_common_args EncArg; 604 605 pCTX = (_MFCLIB *)openHandle; 606 607 if (openHandle == NULL) { 608 LOGE("SsbSipMfcEncGetConfig: openHandle is NULL\n"); 609 return MFC_RET_INVALID_PARAM; 610 } 611 if (value == NULL) { 612 LOGE("SsbSipMfcEncGetConfig: value is NULL\n"); 613 return MFC_RET_INVALID_PARAM; 614 } 615 616 pCTX = (_MFCLIB *)openHandle; 617 memset(&EncArg, 0x00, sizeof(mfc_common_args)); 618 619 switch (conf_type) { 620 case MFC_ENC_GETCONF_FRAME_TAG: 621 *((unsigned int *)value) = pCTX->out_frametag_top; 622 break; 623 624 default: 625 LOGE("SsbSipMfcEncGetConfig: No such conf_type is supported.\n"); 626 return MFC_RET_INVALID_PARAM; 627 } 628 629 return MFC_RET_OK; 630 } 631