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 "mfc_interface.h" 29 #include "SsbSipMfcApi.h" 30 31 #define _MFCLIB_MAGIC_NUMBER 0x92241000 32 33 #define USR_DATA_START_CODE (0x000001B2) 34 #define VOP_START_CODE (0x000001B6) 35 #define MP4_START_CODE (0x000001) 36 37 static void getAByte(char *buff, int *code) 38 { 39 int byte; 40 41 *code = (*code << 8); 42 byte = (int)*buff; 43 byte &= 0xFF; 44 *code |= byte; 45 } 46 47 static mfc_packed_mode isPBPacked(_MFCLIB *pCtx, int length) 48 { 49 char *strmBuffer = NULL; 50 char *strmBufferEnd = NULL; 51 int startCode = 0xFFFFFFFF; 52 53 strmBuffer = (char *)pCtx->virStrmBuf; 54 strmBufferEnd = (char *)pCtx->virStrmBuf + length; 55 56 while (1) { 57 while (startCode != USR_DATA_START_CODE) { 58 if (startCode == VOP_START_CODE) { 59 LOGV("isPBPacked: VOP START Found !!.....return\n"); 60 LOGV("isPBPacked: Non Packed PB\n"); 61 return MFC_UNPACKED_PB; 62 } 63 getAByte(strmBuffer, &startCode); 64 strmBuffer++; 65 if (strmBuffer >= strmBufferEnd) 66 goto out; 67 } 68 LOGV("isPBPacked: User Data Found !!\n"); 69 70 do { 71 if (*strmBuffer == 'p') { 72 LOGI("isPBPacked: Packed PB\n"); 73 return MFC_PACKED_PB; 74 } 75 getAByte(strmBuffer, &startCode); 76 strmBuffer++; 77 if (strmBuffer >= strmBufferEnd) 78 goto out; 79 } while ((startCode >> 8) != MP4_START_CODE); 80 } 81 82 out: 83 LOGV("isPBPacked: Non Packed PB\n"); 84 return MFC_UNPACKED_PB; 85 } 86 87 void *SsbSipMfcDecOpen(void *value) 88 { 89 int hMFCOpen; 90 unsigned int mapped_addr; 91 _MFCLIB *pCTX; 92 mfc_common_args DecArg; 93 int ret_code; 94 95 pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB)); 96 if (pCTX == NULL) { 97 LOGE("SsbSipMfcDecOpen: malloc failed.\n"); 98 return NULL; 99 } 100 memset(pCTX, 0, sizeof(_MFCLIB)); 101 102 hMFCOpen = open(S5PC110_MFC_DEV_NAME, O_RDWR | O_NDELAY); 103 if (hMFCOpen < 0) { 104 LOGE("SsbSipMfcDecOpen: MFC Open failure\n"); 105 return NULL; 106 } 107 108 if (*(unsigned int *)value == NO_CACHE || 109 *(unsigned int *)value == CACHE) { 110 DecArg.args.buf_type = *(unsigned int *)value; 111 ret_code = ioctl(hMFCOpen, IOCTL_MFC_BUF_CACHE, &DecArg); 112 if (DecArg.ret_code != MFC_RET_OK) { 113 LOGE("SsbSipMfcDecOpenExt: IOCTL_MFC_BUF_CACHE (%d) failed\n", DecArg.ret_code); 114 } 115 } else { 116 LOGE("SsbSipMfcDecOpenExt: value is invalid, value: %d\n", *(int *)value); 117 } 118 119 mapped_addr = (unsigned int)mmap(0, MMAP_BUFFER_SIZE_MMAP, PROT_READ | PROT_WRITE, MAP_SHARED, hMFCOpen, 0); 120 if (!mapped_addr) { 121 LOGE("SsbSipMfcDecOpen: FIMV5.0 driver address mapping failed\n"); 122 return NULL; 123 } 124 125 pCTX->magic = _MFCLIB_MAGIC_NUMBER; 126 pCTX->hMFC = hMFCOpen; 127 pCTX->mapped_addr = mapped_addr; 128 pCTX->inter_buff_status = MFC_USE_NONE; 129 130 return (void *)pCTX; 131 } 132 133 SSBSIP_MFC_ERROR_CODE SsbSipMfcDecInit(void *openHandle, SSBSIP_MFC_CODEC_TYPE codec_type, int Frameleng) 134 { 135 int ret_code; 136 int packedPB = MFC_UNPACKED_PB; 137 mfc_common_args DecArg; 138 _MFCLIB *pCTX; 139 140 if (openHandle == NULL) { 141 LOGE("SsbSipMfcDecSetConfig: openHandle is NULL\n"); 142 return MFC_RET_INVALID_PARAM; 143 } 144 145 pCTX = (_MFCLIB *)openHandle; 146 memset(&DecArg, 0x00, sizeof(DecArg)); 147 148 if ((codec_type != MPEG4_DEC) && 149 (codec_type != H264_DEC) && 150 (codec_type != H263_DEC) && 151 (codec_type != MPEG1_DEC) && 152 (codec_type != MPEG2_DEC) && 153 (codec_type != FIMV1_DEC) && 154 (codec_type != FIMV2_DEC) && 155 (codec_type != FIMV3_DEC) && 156 (codec_type != FIMV4_DEC) && 157 (codec_type != XVID_DEC) && 158 (codec_type != VC1RCV_DEC) && 159 (codec_type != VC1_DEC)) { 160 LOGE("SsbSipMfcDecOpen: Undefined codec type.\n"); 161 return MFC_RET_INVALID_PARAM; 162 } 163 164 pCTX->codec_type = codec_type; 165 166 if ((pCTX->codec_type == MPEG4_DEC) || 167 (pCTX->codec_type == FIMV1_DEC) || 168 (pCTX->codec_type == FIMV2_DEC) || 169 (pCTX->codec_type == FIMV3_DEC) || 170 (pCTX->codec_type == FIMV4_DEC) || 171 (pCTX->codec_type == XVID_DEC)) 172 packedPB = isPBPacked(pCTX, Frameleng); 173 174 /* init args */ 175 DecArg.args.dec_init.in_codec_type = pCTX->codec_type; 176 DecArg.args.dec_init.in_strm_size = Frameleng; 177 DecArg.args.dec_init.in_strm_buf = pCTX->phyStrmBuf; 178 DecArg.args.dec_init.in_packed_PB = packedPB; 179 180 /* mem alloc args */ 181 DecArg.args.dec_init.in_mapped_addr = pCTX->mapped_addr; 182 183 ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_DEC_INIT, &DecArg); 184 if (DecArg.ret_code != MFC_RET_OK) { 185 LOGE("SsbSipMfcDecInit: IOCTL_MFC_DEC_INIT (%d) failed\n", DecArg.ret_code); 186 return MFC_RET_DEC_INIT_FAIL; 187 } 188 189 pCTX->decOutInfo.img_width = DecArg.args.dec_init.out_img_width; 190 pCTX->decOutInfo.img_height = DecArg.args.dec_init.out_img_height; 191 pCTX->decOutInfo.buf_width = DecArg.args.dec_init.out_buf_width; 192 pCTX->decOutInfo.buf_height = DecArg.args.dec_init.out_buf_height; 193 194 /* by RainAde : crop information */ 195 pCTX->decOutInfo.crop_top_offset = DecArg.args.dec_init.out_crop_top_offset; 196 pCTX->decOutInfo.crop_bottom_offset = DecArg.args.dec_init.out_crop_bottom_offset; 197 pCTX->decOutInfo.crop_left_offset = DecArg.args.dec_init.out_crop_left_offset; 198 pCTX->decOutInfo.crop_right_offset = DecArg.args.dec_init.out_crop_right_offset; 199 200 pCTX->virFrmBuf.luma = DecArg.args.dec_init.out_u_addr.luma; 201 pCTX->virFrmBuf.chroma = DecArg.args.dec_init.out_u_addr.chroma; 202 203 pCTX->phyFrmBuf.luma = DecArg.args.dec_init.out_p_addr.luma; 204 pCTX->phyFrmBuf.chroma = DecArg.args.dec_init.out_p_addr.chroma; 205 pCTX->sizeFrmBuf.luma = DecArg.args.dec_init.out_frame_buf_size.luma; 206 pCTX->sizeFrmBuf.chroma = DecArg.args.dec_init.out_frame_buf_size.chroma; 207 pCTX->inter_buff_status |= MFC_USE_YUV_BUFF; 208 209 return MFC_RET_OK; 210 } 211 212 SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExe(void *openHandle, int lengthBufFill) 213 { 214 int ret_code; 215 int Yoffset; 216 int Coffset; 217 _MFCLIB *pCTX; 218 mfc_common_args DecArg; 219 220 if (openHandle == NULL) { 221 LOGE("SsbSipMfcDecExe: openHandle is NULL\n"); 222 return MFC_RET_INVALID_PARAM; 223 } 224 225 if ((lengthBufFill < 0) || (lengthBufFill > MAX_DECODER_INPUT_BUFFER_SIZE)) { 226 LOGE("SsbSipMfcDecExe: lengthBufFill is invalid. (lengthBufFill=%d)\n", lengthBufFill); 227 return MFC_RET_INVALID_PARAM; 228 } 229 230 pCTX = (_MFCLIB *)openHandle; 231 memset(&DecArg, 0x00, sizeof(DecArg)); 232 233 DecArg.args.dec_exe.in_codec_type = pCTX->codec_type; 234 DecArg.args.dec_exe.in_strm_buf = pCTX->phyStrmBuf; 235 DecArg.args.dec_exe.in_strm_size = lengthBufFill; 236 DecArg.args.dec_exe.in_frm_buf.luma = pCTX->phyFrmBuf.luma; 237 DecArg.args.dec_exe.in_frm_buf.chroma = pCTX->phyFrmBuf.chroma; 238 DecArg.args.dec_exe.in_frm_size.luma = pCTX->sizeFrmBuf.luma; 239 DecArg.args.dec_exe.in_frm_size.chroma = pCTX->sizeFrmBuf.chroma; 240 DecArg.args.dec_exe.in_frametag = pCTX->in_frametag; 241 242 ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_DEC_EXE, &DecArg); 243 if (DecArg.ret_code != MFC_RET_OK) { 244 LOGE("SsbSipMfcDecExe: IOCTL_MFC_DEC_EXE failed(ret : %d)\n", DecArg.ret_code); 245 return MFC_RET_DEC_EXE_ERR; 246 } 247 248 Yoffset = DecArg.args.dec_exe.out_display_Y_addr - DecArg.args.dec_exe.in_frm_buf.luma; 249 Coffset = DecArg.args.dec_exe.out_display_C_addr - DecArg.args.dec_exe.in_frm_buf.chroma; 250 251 pCTX->decOutInfo.YPhyAddr = (void *)(DecArg.args.dec_exe.out_display_Y_addr); 252 pCTX->decOutInfo.CPhyAddr = (void *)(DecArg.args.dec_exe.out_display_C_addr); 253 pCTX->decOutInfo.YVirAddr = (void *)(pCTX->virFrmBuf.luma + Yoffset); 254 pCTX->decOutInfo.CVirAddr = (void *)(pCTX->virFrmBuf.chroma + Coffset); 255 pCTX->decOutInfo.timestamp_top = DecArg.args.dec_exe.out_timestamp_top; 256 pCTX->decOutInfo.timestamp_bottom = DecArg.args.dec_exe.out_timestamp_bottom; 257 pCTX->decOutInfo.consumedByte = DecArg.args.dec_exe.out_consume_bytes; 258 pCTX->decOutInfo.res_change = DecArg.args.dec_exe.out_res_change; 259 pCTX->decOutInfo.crop_top_offset = DecArg.args.dec_exe.out_crop_top_offset; 260 pCTX->decOutInfo.crop_bottom_offset = DecArg.args.dec_exe.out_crop_bottom_offset; 261 pCTX->decOutInfo.crop_left_offset = DecArg.args.dec_exe.out_crop_left_offset; 262 pCTX->decOutInfo.crop_right_offset = DecArg.args.dec_exe.out_crop_right_offset; 263 pCTX->out_frametag_top = DecArg.args.dec_exe.out_frametag_top; 264 pCTX->out_frametag_bottom = DecArg.args.dec_exe.out_frametag_bottom; 265 pCTX->displayStatus = DecArg.args.dec_exe.out_display_status; 266 267 return MFC_RET_OK; 268 } 269 270 SSBSIP_MFC_ERROR_CODE SsbSipMfcDecClose(void *openHandle) 271 { 272 int ret_code; 273 _MFCLIB *pCTX; 274 mfc_common_args free_arg; 275 276 if (openHandle == NULL) { 277 LOGE("SsbSipMfcDecClose: openHandle is NULL\n"); 278 return MFC_RET_INVALID_PARAM; 279 } 280 281 pCTX = (_MFCLIB *)openHandle; 282 283 if (pCTX->inter_buff_status & MFC_USE_YUV_BUFF) { 284 free_arg.args.mem_free.u_addr = pCTX->virFrmBuf.luma; 285 ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); 286 free_arg.args.mem_free.u_addr = pCTX->virFrmBuf.chroma; 287 ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); 288 } 289 290 if (pCTX->inter_buff_status & MFC_USE_STRM_BUFF) { 291 free_arg.args.mem_free.u_addr = pCTX->virStrmBuf; 292 ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); 293 } 294 295 pCTX->inter_buff_status = MFC_USE_NONE; 296 297 munmap((void *)pCTX->mapped_addr, MMAP_BUFFER_SIZE_MMAP); 298 close(pCTX->hMFC); 299 free(pCTX); 300 301 return MFC_RET_OK; 302 } 303 304 void *SsbSipMfcDecGetInBuf(void *openHandle, void **phyInBuf, int inputBufferSize) 305 { 306 int ret_code; 307 _MFCLIB *pCTX; 308 mfc_common_args user_addr_arg, phys_addr_arg; 309 310 if (inputBufferSize < 0) { 311 LOGE("SsbSipMfcDecGetInBuf: inputBufferSize = %d is invalid\n", inputBufferSize); 312 return NULL; 313 } 314 315 if (openHandle == NULL) { 316 LOGE("SsbSipMfcDecGetInBuf: openHandle is NULL\n"); 317 return NULL; 318 } 319 320 pCTX = (_MFCLIB *)openHandle; 321 322 user_addr_arg.args.mem_alloc.codec_type = pCTX->codec_type; 323 user_addr_arg.args.mem_alloc.buff_size = inputBufferSize; 324 user_addr_arg.args.mem_alloc.mapped_addr = pCTX->mapped_addr; 325 ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_IN_BUF, &user_addr_arg); 326 if (ret_code < 0) { 327 LOGE("SsbSipMfcDecGetInBuf: IOCTL_MFC_GET_IN_BUF failed\n"); 328 return NULL; 329 } 330 pCTX->virStrmBuf = user_addr_arg.args.mem_alloc.out_uaddr; 331 pCTX->phyStrmBuf = user_addr_arg.args.mem_alloc.out_paddr; 332 pCTX->sizeStrmBuf = inputBufferSize; 333 pCTX->inter_buff_status |= MFC_USE_STRM_BUFF; 334 335 *phyInBuf = (void *)pCTX->phyStrmBuf; 336 337 return (void *)pCTX->virStrmBuf; 338 } 339 340 SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, void *phyInBuf, void *virInBuf, int inputBufferSize) 341 { 342 _MFCLIB *pCTX; 343 344 if (openHandle == NULL) { 345 LOGE("SsbSipMfcDecSetInBuf: openHandle is NULL\n"); 346 return MFC_RET_INVALID_PARAM; 347 } 348 349 pCTX = (_MFCLIB *)openHandle; 350 351 pCTX->phyStrmBuf = (int)phyInBuf; 352 pCTX->virStrmBuf = (int)virInBuf; 353 pCTX->sizeStrmBuf = inputBufferSize; 354 return MFC_RET_OK; 355 } 356 357 SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecGetOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info) 358 { 359 _MFCLIB *pCTX; 360 361 if (openHandle == NULL) { 362 LOGE("SsbSipMfcDecGetOutBuf: openHandle is NULL\n"); 363 return MFC_GETOUTBUF_DISPLAY_END; 364 } 365 366 pCTX = (_MFCLIB *)openHandle; 367 368 output_info->YPhyAddr = pCTX->decOutInfo.YPhyAddr; 369 output_info->CPhyAddr = pCTX->decOutInfo.CPhyAddr; 370 371 output_info->YVirAddr = pCTX->decOutInfo.YVirAddr; 372 output_info->CVirAddr = pCTX->decOutInfo.CVirAddr; 373 374 output_info->img_width = pCTX->decOutInfo.img_width; 375 output_info->img_height= pCTX->decOutInfo.img_height; 376 377 output_info->buf_width = pCTX->decOutInfo.buf_width; 378 output_info->buf_height= pCTX->decOutInfo.buf_height; 379 380 /* by RainAde : for crop information */ 381 output_info->crop_top_offset = pCTX->decOutInfo.crop_top_offset; 382 output_info->crop_bottom_offset= pCTX->decOutInfo.crop_bottom_offset; 383 output_info->crop_left_offset = pCTX->decOutInfo.crop_left_offset; 384 output_info->crop_right_offset= pCTX->decOutInfo.crop_right_offset; 385 386 if (pCTX->displayStatus == 0) 387 return MFC_GETOUTBUF_DISPLAY_END; 388 else if (pCTX->displayStatus == 1) 389 return MFC_GETOUTBUF_DISPLAY_DECODING; 390 else if (pCTX->displayStatus == 2) 391 return MFC_GETOUTBUF_DISPLAY_ONLY; 392 else 393 return MFC_GETOUTBUF_DECODING_ONLY; 394 } 395 396 SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value) 397 { 398 int ret_code; 399 _MFCLIB *pCTX; 400 mfc_common_args DecArg; 401 SSBSIP_MFC_IMG_RESOLUTION *img_resolution; 402 403 if (openHandle == NULL) { 404 LOGE("SsbSipMfcDecSetConfig: openHandle is NULL\n"); 405 return MFC_RET_INVALID_PARAM; 406 } 407 408 if (value == NULL) { 409 LOGE("SsbSipMfcDecSetConfig: value is NULL\n"); 410 return MFC_RET_INVALID_PARAM; 411 } 412 413 pCTX = (_MFCLIB *)openHandle; 414 memset(&DecArg, 0x00, sizeof(DecArg)); 415 416 switch (conf_type) { 417 case MFC_DEC_SETCONF_POST_ENABLE: 418 case MFC_DEC_SETCONF_EXTRA_BUFFER_NUM: 419 case MFC_DEC_SETCONF_DISPLAY_DELAY: 420 case MFC_DEC_SETCONF_IS_LAST_FRAME: 421 case MFC_DEC_SETCONF_SLICE_ENABLE: 422 case MFC_DEC_SETCONF_CRC_ENABLE: 423 DecArg.args.set_config.in_config_param = conf_type; 424 DecArg.args.set_config.in_config_value[0] = *((unsigned int *)value); 425 DecArg.args.set_config.in_config_value[1] = 0; 426 break; 427 428 case MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT: 429 img_resolution = (SSBSIP_MFC_IMG_RESOLUTION *)value; 430 DecArg.args.set_config.in_config_param = conf_type; 431 DecArg.args.set_config.in_config_value[0] = img_resolution->width; 432 DecArg.args.set_config.in_config_value[1] = img_resolution->height; 433 break; 434 435 case MFC_DEC_SETCONF_FRAME_TAG: 436 pCTX->in_frametag = *((int *)value); 437 return MFC_RET_OK; 438 439 default: 440 LOGE("SsbSipMfcDecSetConfig: No such conf_type is supported.\n"); 441 return MFC_RET_INVALID_PARAM; 442 } 443 444 ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_SET_CONFIG, &DecArg); 445 if (DecArg.ret_code != MFC_RET_OK) { 446 LOGE("SsbSipMfcDecSetConfig: IOCTL_MFC_SET_CONFIG failed(ret : %d, conf_type: %d)\n", DecArg.ret_code, conf_type); 447 return MFC_RET_DEC_SET_CONF_FAIL; 448 } 449 450 return MFC_RET_OK; 451 } 452 453 SSBSIP_MFC_ERROR_CODE SsbSipMfcDecGetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value) 454 { 455 int ret_code; 456 _MFCLIB *pCTX; 457 mfc_common_args DecArg; 458 459 SSBSIP_MFC_IMG_RESOLUTION *img_resolution; 460 SSBSIP_MFC_CROP_INFORMATION *crop_information; 461 MFC_CRC_DATA *crc_data; 462 463 if (openHandle == NULL) { 464 LOGE("SsbSipMfcDecGetConfig: openHandle is NULL\n"); 465 return MFC_RET_FAIL; 466 } 467 468 if (value == NULL) { 469 LOGE("SsbSipMfcDecGetConfig: value is NULL\n"); 470 return MFC_RET_FAIL; 471 } 472 473 pCTX = (_MFCLIB *)openHandle; 474 memset(&DecArg, 0x00, sizeof(DecArg)); 475 476 switch (conf_type) { 477 case MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT: 478 img_resolution = (SSBSIP_MFC_IMG_RESOLUTION *)value; 479 img_resolution->width = pCTX->decOutInfo.img_width; 480 img_resolution->height = pCTX->decOutInfo.img_height; 481 img_resolution->buf_width = pCTX->decOutInfo.buf_width; 482 img_resolution->buf_height = pCTX->decOutInfo.buf_height; 483 break; 484 485 /* Added by RainAde */ 486 case MFC_DEC_GETCONF_CROP_INFO: 487 crop_information = (SSBSIP_MFC_CROP_INFORMATION*)value; 488 crop_information->crop_top_offset = pCTX->decOutInfo.crop_top_offset; 489 crop_information->crop_bottom_offset= pCTX->decOutInfo.crop_bottom_offset; 490 crop_information->crop_left_offset = pCTX->decOutInfo.crop_left_offset; 491 crop_information->crop_right_offset= pCTX->decOutInfo.crop_right_offset; 492 break; 493 494 case MFC_DEC_GETCONF_CRC_DATA: 495 crc_data = (MFC_CRC_DATA *)value; 496 497 DecArg.args.get_config.in_config_param = conf_type; 498 499 ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_CONFIG, &DecArg); 500 if (DecArg.ret_code != MFC_RET_OK) { 501 LOGE("SsbSipMfcDecGetConfig: IOCTL_MFC_GET_CONFIG failed(ret : %d, conf_type: %d)\n", DecArg.ret_code, conf_type); 502 return MFC_RET_DEC_GET_CONF_FAIL; 503 } 504 crc_data->luma0 = DecArg.args.get_config.out_config_value[0]; 505 crc_data->chroma0 = DecArg.args.get_config.out_config_value[1]; 506 break; 507 508 case MFC_DEC_GETCONF_FRAME_TAG: 509 *((unsigned int *)value) = pCTX->out_frametag_top; 510 break; 511 512 default: 513 LOGE("SsbSipMfcDecGetConfig: No such conf_type is supported.\n"); 514 return MFC_RET_INVALID_PARAM; 515 } 516 517 return MFC_RET_OK; 518 } 519