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