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