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