Home | History | Annotate | Download | only in src
      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