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)
     88 {
     89     int hMFCOpen;
     90     unsigned int mapped_addr;
     91     _MFCLIB *pCTX;
     92 
     93     pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB));
     94     if (pCTX == NULL) {
     95         LOGE("SsbSipMfcDecOpen: malloc failed.\n");
     96         return NULL;
     97     }
     98     memset(pCTX, 0, sizeof(_MFCLIB));
     99 
    100     hMFCOpen = open(S5PC110_MFC_DEV_NAME, O_RDWR | O_NDELAY);
    101     if (hMFCOpen < 0) {
    102         LOGE("SsbSipMfcDecOpen: MFC Open failure\n");
    103         return NULL;
    104     }
    105 
    106     mapped_addr = (unsigned int)mmap(0, MMAP_BUFFER_SIZE_MMAP, PROT_READ | PROT_WRITE, MAP_SHARED, hMFCOpen, 0);
    107     if (!mapped_addr) {
    108         LOGE("SsbSipMfcDecOpen: FIMV5.0 driver address mapping failed\n");
    109         return NULL;
    110     }
    111 
    112     pCTX->magic = _MFCLIB_MAGIC_NUMBER;
    113     pCTX->hMFC = hMFCOpen;
    114     pCTX->mapped_addr = mapped_addr;
    115     pCTX->inter_buff_status = MFC_USE_NONE;
    116 
    117     return (void *)pCTX;
    118 }
    119 
    120 SSBSIP_MFC_ERROR_CODE SsbSipMfcDecInit(void *openHandle, SSBSIP_MFC_CODEC_TYPE codec_type, int Frameleng)
    121 {
    122     int ret_code;
    123     int packedPB = MFC_UNPACKED_PB;
    124     mfc_common_args DecArg;
    125     _MFCLIB *pCTX;
    126 
    127     if (openHandle == NULL) {
    128         LOGE("SsbSipMfcDecSetConfig: openHandle is NULL\n");
    129         return MFC_RET_INVALID_PARAM;
    130     }
    131 
    132     pCTX = (_MFCLIB *)openHandle;
    133     memset(&DecArg, 0x00, sizeof(DecArg));
    134 
    135     if ((codec_type != MPEG4_DEC)  &&
    136         (codec_type != H264_DEC)   &&
    137         (codec_type != H263_DEC)   &&
    138         (codec_type != MPEG1_DEC)  &&
    139         (codec_type != MPEG2_DEC)  &&
    140         (codec_type != FIMV1_DEC)  &&
    141         (codec_type != FIMV2_DEC)  &&
    142         (codec_type != FIMV3_DEC)  &&
    143         (codec_type != FIMV4_DEC)  &&
    144         (codec_type != XVID_DEC)   &&
    145         (codec_type != VC1RCV_DEC) &&
    146         (codec_type != VC1_DEC)) {
    147         LOGE("SsbSipMfcDecOpen: Undefined codec type.\n");
    148         return MFC_RET_INVALID_PARAM;
    149     }
    150 
    151     pCTX->codec_type = codec_type;
    152 
    153     if ((pCTX->codec_type == MPEG4_DEC)   ||
    154         (pCTX->codec_type == FIMV1_DEC) ||
    155         (pCTX->codec_type == FIMV2_DEC) ||
    156         (pCTX->codec_type == FIMV3_DEC) ||
    157         (pCTX->codec_type == FIMV4_DEC) ||
    158         (pCTX->codec_type == XVID_DEC))
    159         packedPB = isPBPacked(pCTX, Frameleng);
    160 
    161     /* init args */
    162     DecArg.args.dec_init.in_codec_type = pCTX->codec_type;
    163     DecArg.args.dec_init.in_strm_size = Frameleng;
    164     DecArg.args.dec_init.in_strm_buf = pCTX->phyStrmBuf;
    165     DecArg.args.dec_init.in_packed_PB = packedPB;
    166 
    167     /* mem alloc args */
    168     DecArg.args.dec_init.in_mapped_addr = pCTX->mapped_addr;
    169 
    170     ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_DEC_INIT, &DecArg);
    171     if (DecArg.ret_code != MFC_RET_OK) {
    172         LOGE("SsbSipMfcDecInit: IOCTL_MFC_DEC_INIT (%d) failed\n", DecArg.ret_code);
    173         return MFC_RET_DEC_INIT_FAIL;
    174     }
    175 
    176     pCTX->decOutInfo.img_width = DecArg.args.dec_init.out_img_width;
    177     pCTX->decOutInfo.img_height = DecArg.args.dec_init.out_img_height;
    178     pCTX->decOutInfo.buf_width = DecArg.args.dec_init.out_buf_width;
    179     pCTX->decOutInfo.buf_height = DecArg.args.dec_init.out_buf_height;
    180 
    181     /* by RainAde : crop information */
    182     pCTX->decOutInfo.crop_top_offset = DecArg.args.dec_init.out_crop_top_offset;
    183     pCTX->decOutInfo.crop_bottom_offset = DecArg.args.dec_init.out_crop_bottom_offset;
    184     pCTX->decOutInfo.crop_left_offset = DecArg.args.dec_init.out_crop_left_offset;
    185     pCTX->decOutInfo.crop_right_offset = DecArg.args.dec_init.out_crop_right_offset;
    186 
    187     pCTX->virFrmBuf.luma = DecArg.args.dec_init.out_u_addr.luma;
    188     pCTX->virFrmBuf.chroma = DecArg.args.dec_init.out_u_addr.chroma;
    189 
    190     pCTX->phyFrmBuf.luma = DecArg.args.dec_init.out_p_addr.luma;
    191     pCTX->phyFrmBuf.chroma = DecArg.args.dec_init.out_p_addr.chroma;
    192     pCTX->sizeFrmBuf.luma = DecArg.args.dec_init.out_frame_buf_size.luma;
    193     pCTX->sizeFrmBuf.chroma = DecArg.args.dec_init.out_frame_buf_size.chroma;
    194     pCTX->inter_buff_status |= MFC_USE_YUV_BUFF;
    195 
    196     return MFC_RET_OK;
    197 }
    198 
    199 SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExe(void *openHandle, int lengthBufFill)
    200 {
    201     int ret_code;
    202     int Yoffset;
    203     int Coffset;
    204     _MFCLIB *pCTX;
    205     mfc_common_args DecArg;
    206 
    207     if (openHandle == NULL) {
    208         LOGE("SsbSipMfcDecExe: openHandle is NULL\n");
    209         return MFC_RET_INVALID_PARAM;
    210     }
    211 
    212     if ((lengthBufFill < 0) || (lengthBufFill > MAX_DECODER_INPUT_BUFFER_SIZE)) {
    213         LOGE("SsbSipMfcDecExe: lengthBufFill is invalid. (lengthBufFill=%d)\n", lengthBufFill);
    214         return MFC_RET_INVALID_PARAM;
    215     }
    216 
    217     pCTX = (_MFCLIB *)openHandle;
    218     memset(&DecArg, 0x00, sizeof(DecArg));
    219 
    220     DecArg.args.dec_exe.in_codec_type = pCTX->codec_type;
    221     DecArg.args.dec_exe.in_strm_buf = pCTX->phyStrmBuf;
    222     DecArg.args.dec_exe.in_strm_size = lengthBufFill;
    223     DecArg.args.dec_exe.in_frm_buf.luma = pCTX->phyFrmBuf.luma;
    224     DecArg.args.dec_exe.in_frm_buf.chroma = pCTX->phyFrmBuf.chroma;
    225     DecArg.args.dec_exe.in_frm_size.luma = pCTX->sizeFrmBuf.luma;
    226     DecArg.args.dec_exe.in_frm_size.chroma = pCTX->sizeFrmBuf.chroma;
    227     DecArg.args.dec_exe.in_frametag = pCTX->in_frametag;
    228 
    229     ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_DEC_EXE, &DecArg);
    230     if (DecArg.ret_code != MFC_RET_OK) {
    231         LOGE("SsbSipMfcDecExe: IOCTL_MFC_DEC_EXE failed(ret : %d)\n", DecArg.ret_code);
    232         return MFC_RET_DEC_EXE_ERR;
    233     }
    234 
    235     Yoffset = DecArg.args.dec_exe.out_display_Y_addr - DecArg.args.dec_exe.in_frm_buf.luma;
    236     Coffset = DecArg.args.dec_exe.out_display_C_addr - DecArg.args.dec_exe.in_frm_buf.chroma;
    237 
    238     pCTX->decOutInfo.YPhyAddr = (void *)(DecArg.args.dec_exe.out_display_Y_addr);
    239     pCTX->decOutInfo.CPhyAddr = (void *)(DecArg.args.dec_exe.out_display_C_addr);
    240     pCTX->decOutInfo.YVirAddr = (void *)(pCTX->virFrmBuf.luma + Yoffset);
    241     pCTX->decOutInfo.CVirAddr = (void *)(pCTX->virFrmBuf.chroma + Coffset);
    242     pCTX->decOutInfo.timestamp_top = DecArg.args.dec_exe.out_timestamp_top;
    243     pCTX->decOutInfo.timestamp_bottom = DecArg.args.dec_exe.out_timestamp_bottom;
    244     pCTX->decOutInfo.consumedByte = DecArg.args.dec_exe.out_consume_bytes;
    245     pCTX->decOutInfo.res_change = DecArg.args.dec_exe.out_res_change;
    246     pCTX->decOutInfo.crop_top_offset = DecArg.args.dec_exe.out_crop_top_offset;
    247     pCTX->decOutInfo.crop_bottom_offset = DecArg.args.dec_exe.out_crop_bottom_offset;
    248     pCTX->decOutInfo.crop_left_offset = DecArg.args.dec_exe.out_crop_left_offset;
    249     pCTX->decOutInfo.crop_right_offset = DecArg.args.dec_exe.out_crop_right_offset;
    250     pCTX->out_frametag_top = DecArg.args.dec_exe.out_frametag_top;
    251     pCTX->out_frametag_bottom = DecArg.args.dec_exe.out_frametag_bottom;
    252     pCTX->displayStatus = DecArg.args.dec_exe.out_display_status;
    253 
    254     return MFC_RET_OK;
    255 }
    256 
    257 SSBSIP_MFC_ERROR_CODE SsbSipMfcDecClose(void *openHandle)
    258 {
    259     int ret_code;
    260     _MFCLIB *pCTX;
    261     mfc_common_args free_arg;
    262 
    263     if (openHandle == NULL) {
    264         LOGE("SsbSipMfcDecClose: openHandle is NULL\n");
    265         return MFC_RET_INVALID_PARAM;
    266     }
    267 
    268     pCTX = (_MFCLIB *)openHandle;
    269 
    270     if (pCTX->inter_buff_status & MFC_USE_YUV_BUFF) {
    271         free_arg.args.mem_free.u_addr = pCTX->virFrmBuf.luma;
    272         ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg);
    273         free_arg.args.mem_free.u_addr = pCTX->virFrmBuf.chroma;
    274         ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg);
    275     }
    276 
    277     if (pCTX->inter_buff_status & MFC_USE_STRM_BUFF) {
    278         free_arg.args.mem_free.u_addr = pCTX->virStrmBuf;
    279         ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg);
    280     }
    281 
    282     pCTX->inter_buff_status = MFC_USE_NONE;
    283 
    284     munmap((void *)pCTX->mapped_addr, MMAP_BUFFER_SIZE_MMAP);
    285     close(pCTX->hMFC);
    286     free(pCTX);
    287 
    288     return MFC_RET_OK;
    289 }
    290 
    291 void *SsbSipMfcDecGetInBuf(void *openHandle, void **phyInBuf, int inputBufferSize)
    292 {
    293     int ret_code;
    294     _MFCLIB *pCTX;
    295     mfc_common_args user_addr_arg, phys_addr_arg;
    296 
    297     if (inputBufferSize < 0) {
    298         LOGE("SsbSipMfcDecGetInBuf: inputBufferSize = %d is invalid\n", inputBufferSize);
    299         return NULL;
    300     }
    301 
    302     if (openHandle == NULL) {
    303         LOGE("SsbSipMfcDecGetInBuf: openHandle is NULL\n");
    304         return NULL;
    305     }
    306 
    307     pCTX = (_MFCLIB *)openHandle;
    308 
    309     user_addr_arg.args.mem_alloc.codec_type = pCTX->codec_type;
    310     user_addr_arg.args.mem_alloc.buff_size = inputBufferSize;
    311     user_addr_arg.args.mem_alloc.mapped_addr = pCTX->mapped_addr;
    312     ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_IN_BUF, &user_addr_arg);
    313     if (ret_code < 0) {
    314         LOGE("SsbSipMfcDecGetInBuf: IOCTL_MFC_GET_IN_BUF failed\n");
    315         return NULL;
    316     }
    317     pCTX->virStrmBuf = user_addr_arg.args.mem_alloc.out_uaddr;
    318     pCTX->phyStrmBuf = user_addr_arg.args.mem_alloc.out_paddr;
    319     pCTX->sizeStrmBuf = inputBufferSize;
    320     pCTX->inter_buff_status |= MFC_USE_STRM_BUFF;
    321 
    322     *phyInBuf = (void *)pCTX->phyStrmBuf;
    323 
    324     return (void *)pCTX->virStrmBuf;
    325 }
    326 
    327 SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, void *phyInBuf, void *virInBuf, int inputBufferSize)
    328 {
    329     _MFCLIB *pCTX;
    330 
    331     if (openHandle == NULL) {
    332         LOGE("SsbSipMfcDecSetInBuf: openHandle is NULL\n");
    333         return MFC_RET_INVALID_PARAM;
    334     }
    335 
    336     pCTX  = (_MFCLIB *)openHandle;
    337 
    338     pCTX->phyStrmBuf = (int)phyInBuf;
    339     pCTX->virStrmBuf = (int)virInBuf;
    340     pCTX->sizeStrmBuf = inputBufferSize;
    341     return MFC_RET_OK;
    342 }
    343 
    344 SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecGetOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info)
    345 {
    346     _MFCLIB *pCTX;
    347 
    348     if (openHandle == NULL) {
    349         LOGE("SsbSipMfcDecGetOutBuf: openHandle is NULL\n");
    350         return MFC_GETOUTBUF_DISPLAY_END;
    351     }
    352 
    353     pCTX = (_MFCLIB *)openHandle;
    354 
    355     output_info->YPhyAddr = pCTX->decOutInfo.YPhyAddr;
    356     output_info->CPhyAddr = pCTX->decOutInfo.CPhyAddr;
    357 
    358     output_info->YVirAddr = pCTX->decOutInfo.YVirAddr;
    359     output_info->CVirAddr = pCTX->decOutInfo.CVirAddr;
    360 
    361     output_info->img_width = pCTX->decOutInfo.img_width;
    362     output_info->img_height= pCTX->decOutInfo.img_height;
    363 
    364     output_info->buf_width = pCTX->decOutInfo.buf_width;
    365     output_info->buf_height= pCTX->decOutInfo.buf_height;
    366 
    367     /* by RainAde : for crop information */
    368     output_info->crop_top_offset = pCTX->decOutInfo.crop_top_offset;
    369     output_info->crop_bottom_offset= pCTX->decOutInfo.crop_bottom_offset;
    370     output_info->crop_left_offset = pCTX->decOutInfo.crop_left_offset;
    371     output_info->crop_right_offset= pCTX->decOutInfo.crop_right_offset;
    372 
    373     if (pCTX->displayStatus == 0)
    374         return MFC_GETOUTBUF_DISPLAY_END;
    375     else if (pCTX->displayStatus == 1)
    376         return MFC_GETOUTBUF_DISPLAY_DECODING;
    377     else if (pCTX->displayStatus == 2)
    378         return MFC_GETOUTBUF_DISPLAY_ONLY;
    379     else
    380         return MFC_GETOUTBUF_DECODING_ONLY;
    381 }
    382 
    383 SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value)
    384 {
    385     int ret_code;
    386     _MFCLIB *pCTX;
    387     mfc_common_args DecArg;
    388     SSBSIP_MFC_IMG_RESOLUTION *img_resolution;
    389 
    390     if (openHandle == NULL) {
    391         LOGE("SsbSipMfcDecSetConfig: openHandle is NULL\n");
    392         return MFC_RET_INVALID_PARAM;
    393     }
    394 
    395     if (value == NULL) {
    396         LOGE("SsbSipMfcDecSetConfig: value is NULL\n");
    397         return MFC_RET_INVALID_PARAM;
    398     }
    399 
    400     pCTX = (_MFCLIB *)openHandle;
    401     memset(&DecArg, 0x00, sizeof(DecArg));
    402 
    403     switch (conf_type) {
    404     case MFC_DEC_SETCONF_POST_ENABLE:
    405     case MFC_DEC_SETCONF_EXTRA_BUFFER_NUM:
    406     case MFC_DEC_SETCONF_DISPLAY_DELAY:
    407     case MFC_DEC_SETCONF_IS_LAST_FRAME:
    408     case MFC_DEC_SETCONF_SLICE_ENABLE:
    409     case MFC_DEC_SETCONF_CRC_ENABLE:
    410         DecArg.args.set_config.in_config_param = conf_type;
    411         DecArg.args.set_config.in_config_value[0] = *((unsigned int *)value);
    412         DecArg.args.set_config.in_config_value[1] = 0;
    413         break;
    414 
    415     case MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT:
    416         img_resolution = (SSBSIP_MFC_IMG_RESOLUTION *)value;
    417         DecArg.args.set_config.in_config_param = conf_type;
    418         DecArg.args.set_config.in_config_value[0] = img_resolution->width;
    419         DecArg.args.set_config.in_config_value[1] = img_resolution->height;
    420         break;
    421 
    422     case MFC_DEC_SETCONF_FRAME_TAG:
    423         pCTX->in_frametag = *((int *)value);
    424         return MFC_RET_OK;
    425 
    426     default:
    427         LOGE("SsbSipMfcDecSetConfig: No such conf_type is supported.\n");
    428         return MFC_RET_INVALID_PARAM;
    429     }
    430 
    431     ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_SET_CONFIG, &DecArg);
    432     if (DecArg.ret_code != MFC_RET_OK) {
    433         LOGE("SsbSipMfcDecSetConfig: IOCTL_MFC_SET_CONFIG failed(ret : %d, conf_type: %d)\n", DecArg.ret_code, conf_type);
    434         return MFC_RET_DEC_SET_CONF_FAIL;
    435     }
    436 
    437     return MFC_RET_OK;
    438 }
    439 
    440 SSBSIP_MFC_ERROR_CODE SsbSipMfcDecGetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value)
    441 {
    442     int ret_code;
    443     _MFCLIB *pCTX;
    444     mfc_common_args DecArg;
    445 
    446     SSBSIP_MFC_IMG_RESOLUTION *img_resolution;
    447     SSBSIP_MFC_CROP_INFORMATION *crop_information;
    448     MFC_CRC_DATA *crc_data;
    449 
    450     if (openHandle == NULL) {
    451         LOGE("SsbSipMfcDecGetConfig: openHandle is NULL\n");
    452         return MFC_RET_FAIL;
    453     }
    454 
    455     if (value == NULL) {
    456         LOGE("SsbSipMfcDecGetConfig: value is NULL\n");
    457         return MFC_RET_FAIL;
    458     }
    459 
    460     pCTX = (_MFCLIB *)openHandle;
    461     memset(&DecArg, 0x00, sizeof(DecArg));
    462 
    463     switch (conf_type) {
    464     case MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT:
    465         img_resolution = (SSBSIP_MFC_IMG_RESOLUTION *)value;
    466         img_resolution->width = pCTX->decOutInfo.img_width;
    467         img_resolution->height = pCTX->decOutInfo.img_height;
    468         img_resolution->buf_width = pCTX->decOutInfo.buf_width;
    469         img_resolution->buf_height = pCTX->decOutInfo.buf_height;
    470         break;
    471 
    472     /* Added by RainAde */
    473     case MFC_DEC_GETCONF_CROP_INFO:
    474         crop_information = (SSBSIP_MFC_CROP_INFORMATION*)value;
    475         crop_information->crop_top_offset = pCTX->decOutInfo.crop_top_offset;
    476         crop_information->crop_bottom_offset= pCTX->decOutInfo.crop_bottom_offset;
    477         crop_information->crop_left_offset = pCTX->decOutInfo.crop_left_offset;
    478         crop_information->crop_right_offset= pCTX->decOutInfo.crop_right_offset;
    479         break;
    480 
    481     case MFC_DEC_GETCONF_CRC_DATA:
    482         crc_data = (MFC_CRC_DATA *)value;
    483 
    484         DecArg.args.get_config.in_config_param = conf_type;
    485 
    486         ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_CONFIG, &DecArg);
    487         if (DecArg.ret_code != MFC_RET_OK) {
    488             LOGE("SsbSipMfcDecGetConfig: IOCTL_MFC_GET_CONFIG failed(ret : %d, conf_type: %d)\n", DecArg.ret_code, conf_type);
    489             return MFC_RET_DEC_GET_CONF_FAIL;
    490         }
    491         crc_data->luma0 = DecArg.args.get_config.out_config_value[0];
    492         crc_data->chroma0 = DecArg.args.get_config.out_config_value[1];
    493         break;
    494 
    495     case MFC_DEC_GETCONF_FRAME_TAG:
    496         *((unsigned int *)value) = pCTX->out_frametag_top;
    497         break;
    498 
    499     default:
    500         LOGE("SsbSipMfcDecGetConfig: No such conf_type is supported.\n");
    501         return MFC_RET_INVALID_PARAM;
    502     }
    503 
    504     return MFC_RET_OK;
    505 }
    506 
    507 int tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos)
    508 {
    509     int pixel_x_m1, pixel_y_m1;
    510     int roundup_x, roundup_y;
    511     int linear_addr0, linear_addr1, bank_addr ;
    512     int x_addr;
    513     int trans_addr;
    514 
    515     pixel_x_m1 = x_size -1;
    516     pixel_y_m1 = y_size -1;
    517 
    518     roundup_x = ((pixel_x_m1 >> 7) + 1);
    519     roundup_y = ((pixel_x_m1 >> 6) + 1);
    520 
    521     x_addr = x_pos >> 2;
    522 
    523     if ((y_size <= y_pos+32) && ( y_pos < y_size) &&
    524         (((pixel_y_m1 >> 5) & 0x1) == 0) && (((y_pos >> 5) & 0x1) == 0)) {
    525         linear_addr0 = (((y_pos & 0x1f) <<4) | (x_addr & 0xf));
    526         linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 6) & 0x3f));
    527 
    528         if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))
    529             bank_addr = ((x_addr >> 4) & 0x1);
    530         else
    531             bank_addr = 0x2 | ((x_addr >> 4) & 0x1);
    532     } else {
    533         linear_addr0 = (((y_pos & 0x1f) << 4) | (x_addr & 0xf));
    534         linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 5) & 0x7f));
    535 
    536         if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))
    537             bank_addr = ((x_addr >> 4) & 0x1);
    538         else
    539             bank_addr = 0x2 | ((x_addr >> 4) & 0x1);
    540     }
    541 
    542     linear_addr0 = linear_addr0 << 2;
    543     trans_addr = (linear_addr1 <<13) | (bank_addr << 11) | linear_addr0;
    544 
    545     return trans_addr;
    546 }
    547 
    548 void Y_tile_to_linear_4x2(unsigned char *p_linear_addr, unsigned char *p_tiled_addr, unsigned int x_size, unsigned int y_size)
    549 {
    550     int trans_addr;
    551     unsigned int i, j, k, index;
    552     unsigned char data8[4];
    553     unsigned int max_index = x_size * y_size;
    554 
    555     for (i = 0; i < y_size; i = i + 16) {
    556         for (j = 0; j < x_size; j = j + 16) {
    557             trans_addr = tile_4x2_read(x_size, y_size, j, i);
    558             for (k = 0; k < 16; k++) {
    559                 /* limit check - prohibit segmentation fault */
    560                 index = (i * x_size) + (x_size * k) + j;
    561                 /* remove equal condition to solve thumbnail bug */
    562                 if (index + 16 > max_index) {
    563                     continue;
    564                 }
    565 
    566                 data8[0] = p_tiled_addr[trans_addr + 64 * k + 0];
    567                 data8[1] = p_tiled_addr[trans_addr + 64 * k + 1];
    568                 data8[2] = p_tiled_addr[trans_addr + 64 * k + 2];
    569                 data8[3] = p_tiled_addr[trans_addr + 64 * k + 3];
    570 
    571                 p_linear_addr[index] = data8[0];
    572                 p_linear_addr[index + 1] = data8[1];
    573                 p_linear_addr[index + 2] = data8[2];
    574                 p_linear_addr[index + 3] = data8[3];
    575 
    576                 data8[0] = p_tiled_addr[trans_addr + 64 * k + 4];
    577                 data8[1] = p_tiled_addr[trans_addr + 64 * k + 5];
    578                 data8[2] = p_tiled_addr[trans_addr + 64 * k + 6];
    579                 data8[3] = p_tiled_addr[trans_addr + 64 * k + 7];
    580 
    581                 p_linear_addr[index + 4] = data8[0];
    582                 p_linear_addr[index + 5] = data8[1];
    583                 p_linear_addr[index + 6] = data8[2];
    584                 p_linear_addr[index + 7] = data8[3];
    585 
    586                 data8[0] = p_tiled_addr[trans_addr + 64 * k + 8];
    587                 data8[1] = p_tiled_addr[trans_addr + 64 * k + 9];
    588                 data8[2] = p_tiled_addr[trans_addr + 64 * k + 10];
    589                 data8[3] = p_tiled_addr[trans_addr + 64 * k + 11];
    590 
    591                 p_linear_addr[index + 8] = data8[0];
    592                 p_linear_addr[index + 9] = data8[1];
    593                 p_linear_addr[index + 10] = data8[2];
    594                 p_linear_addr[index + 11] = data8[3];
    595 
    596                 data8[0] = p_tiled_addr[trans_addr + 64 * k + 12];
    597                 data8[1] = p_tiled_addr[trans_addr + 64 * k + 13];
    598                 data8[2] = p_tiled_addr[trans_addr + 64 * k + 14];
    599                 data8[3] = p_tiled_addr[trans_addr + 64 * k + 15];
    600 
    601                 p_linear_addr[index + 12] = data8[0];
    602                 p_linear_addr[index + 13] = data8[1];
    603                 p_linear_addr[index + 14] = data8[2];
    604                 p_linear_addr[index + 15] = data8[3];
    605             }
    606         }
    607     }
    608 }
    609 
    610 void CbCr_tile_to_linear_4x2(unsigned char *p_linear_addr, unsigned char *p_tiled_addr, unsigned int x_size, unsigned int y_size)
    611 {
    612     int trans_addr;
    613     unsigned int i, j, k, index;
    614     unsigned char data8[4];
    615 	unsigned int half_y_size = y_size / 2;
    616     unsigned int max_index = x_size * half_y_size;
    617     unsigned char *pUVAddr[2];
    618 
    619     pUVAddr[0] = p_linear_addr;
    620     pUVAddr[1] = p_linear_addr + ((x_size * half_y_size) / 2);
    621 
    622     for (i = 0; i < half_y_size; i = i + 16) {
    623         for (j = 0; j < x_size; j = j + 16) {
    624             trans_addr = tile_4x2_read(x_size, half_y_size, j, i);
    625             for (k = 0; k < 16; k++) {
    626                 /* limit check - prohibit segmentation fault */
    627                 index = (i * x_size) + (x_size * k) + j;
    628                 /* remove equal condition to solve thumbnail bug */
    629                 if (index + 16 > max_index) {
    630                     continue;
    631                 }
    632 
    633 				data8[0] = p_tiled_addr[trans_addr + 64 * k + 0];
    634 				data8[1] = p_tiled_addr[trans_addr + 64 * k + 1];
    635 				data8[2] = p_tiled_addr[trans_addr + 64 * k + 2];
    636 				data8[3] = p_tiled_addr[trans_addr + 64 * k + 3];
    637 
    638 				pUVAddr[index%2][index/2] = data8[0];
    639 				pUVAddr[(index+1)%2][(index+1)/2] = data8[1];
    640 				pUVAddr[(index+2)%2][(index+2)/2] = data8[2];
    641 				pUVAddr[(index+3)%2][(index+3)/2] = data8[3];
    642 
    643 				data8[0] = p_tiled_addr[trans_addr + 64 * k + 4];
    644 				data8[1] = p_tiled_addr[trans_addr + 64 * k + 5];
    645 				data8[2] = p_tiled_addr[trans_addr + 64 * k + 6];
    646 				data8[3] = p_tiled_addr[trans_addr + 64 * k + 7];
    647 
    648 				pUVAddr[(index+4)%2][(index+4)/2] = data8[0];
    649 				pUVAddr[(index+5)%2][(index+5)/2] = data8[1];
    650 				pUVAddr[(index+6)%2][(index+6)/2] = data8[2];
    651 				pUVAddr[(index+7)%2][(index+7)/2] = data8[3];
    652 
    653 				data8[0] = p_tiled_addr[trans_addr + 64 * k + 8];
    654 				data8[1] = p_tiled_addr[trans_addr + 64 * k + 9];
    655 				data8[2] = p_tiled_addr[trans_addr + 64 * k + 10];
    656 				data8[3] = p_tiled_addr[trans_addr + 64 * k + 11];
    657 
    658 				pUVAddr[(index+8)%2][(index+8)/2] = data8[0];
    659 				pUVAddr[(index+9)%2][(index+9)/2] = data8[1];
    660 				pUVAddr[(index+10)%2][(index+10)/2] = data8[2];
    661 				pUVAddr[(index+11)%2][(index+11)/2] = data8[3];
    662 
    663 				data8[0] = p_tiled_addr[trans_addr + 64 * k + 12];
    664 				data8[1] = p_tiled_addr[trans_addr + 64 * k + 13];
    665 				data8[2] = p_tiled_addr[trans_addr + 64 * k + 14];
    666 				data8[3] = p_tiled_addr[trans_addr + 64 * k + 15];
    667 
    668 				pUVAddr[(index+12)%2][(index+12)/2] = data8[0];
    669 				pUVAddr[(index+13)%2][(index+13)/2] = data8[1];
    670 				pUVAddr[(index+14)%2][(index+14)/2] = data8[2];
    671 				pUVAddr[(index+15)%2][(index+15)/2] = data8[3];
    672             }
    673         }
    674     }
    675 }
    676