/*
* Copyright 2010 Samsung Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
//#include <utils/Log.h>
#include "SsbSipMfcApi.h"
#include "mfc_interface.h"
#define _MFCLIB_MAGIC_NUMBER 0x92241001
void *SsbSipMfcEncOpen(void *value)
{
int hMFCOpen;
_MFCLIB *pCTX;
unsigned int mapped_addr;
mfc_common_args EncArg;
int ret_code;
hMFCOpen = open(S5PC110_MFC_DEV_NAME, O_RDWR | O_NDELAY);
if (hMFCOpen < 0) {
fprintf(stderr,"SsbSipMfcEncOpen: MFC Open failure\n");
return NULL;
}
pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB));
if (pCTX == NULL) {
fprintf(stderr,"SsbSipMfcEncOpen: malloc failed.\n");
close(hMFCOpen);
return NULL;
}
if (*(unsigned int *)value == NO_CACHE ||
*(unsigned int *)value == CACHE) {
EncArg.args.buf_type = *(unsigned int *)value;
ret_code = ioctl(hMFCOpen, IOCTL_MFC_BUF_CACHE, &EncArg);
if (EncArg.ret_code != MFC_RET_OK) {
fprintf(stderr,"SsbSipMfcDecOpenExt: IOCTL_MFC_BUF_CACHE (%d) failed\n", EncArg.ret_code);
}
} else {
fprintf(stderr,"SsbSipMfcDecOpenExt: value is invalid, value: %d\n", *(int *)value);
}
mapped_addr = (unsigned int)mmap(0, MMAP_BUFFER_SIZE_MMAP, PROT_READ | PROT_WRITE, MAP_SHARED, hMFCOpen, 0);
if (!mapped_addr) {
fprintf(stderr,"SsbSipMfcEncOpen: FIMV5.0 driver address mapping failed\n");
return NULL;
}
memset(pCTX, 0, sizeof(_MFCLIB));
pCTX->magic = _MFCLIB_MAGIC_NUMBER;
pCTX->hMFC = hMFCOpen;
pCTX->mapped_addr = mapped_addr;
pCTX->inter_buff_status = MFC_USE_NONE;
return (void *)pCTX;
}
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncInit(void *openHandle, void *param)
{
int ret_code;
int dpbBufSize;
_MFCLIB *pCTX;
mfc_common_args EncArg;
mfc_common_args user_addr_arg, phys_addr_arg;
SSBSIP_MFC_ENC_H264_PARAM *h264_arg;
SSBSIP_MFC_ENC_MPEG4_PARAM *mpeg4_arg;
SSBSIP_MFC_ENC_H263_PARAM *h263_arg;
SSBSIP_MFC_CODEC_TYPE codec_type;
pCTX = (_MFCLIB *)openHandle;
memset(&EncArg, 0, sizeof(mfc_common_args));
printf("SsbSipMfcEncInit: Encode Init start\n");
mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM *)param;
codec_type = mpeg4_arg->codecType;
if ((codec_type != MPEG4_ENC) &&
(codec_type != H264_ENC) &&
(codec_type != H263_ENC)) {
fprintf(stderr,"SsbSipMfcEncOpen: Undefined codec type.\n");
return MFC_RET_INVALID_PARAM;
}
pCTX->codec_type = codec_type;
switch (pCTX->codec_type) {
case MPEG4_ENC:
printf("SsbSipMfcEncInit: MPEG4 Encode\n");
mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM *)param;
pCTX->width = mpeg4_arg->SourceWidth;
pCTX->height = mpeg4_arg->SourceHeight;
break;
case H263_ENC:
printf("SsbSipMfcEncInit: H263 Encode\n");
h263_arg = (SSBSIP_MFC_ENC_H263_PARAM *)param;
pCTX->width = h263_arg->SourceWidth;
pCTX->height = h263_arg->SourceHeight;
break;
case H264_ENC:
printf("SsbSipMfcEncInit: H264 Encode\n");
h264_arg = (SSBSIP_MFC_ENC_H264_PARAM *)param;
pCTX->width = h264_arg->SourceWidth;
pCTX->height = h264_arg->SourceHeight;
break;
default:
break;
}
switch (pCTX->codec_type) {
case MPEG4_ENC:
mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM*)param;
EncArg.args.enc_init_mpeg4.in_codec_type = pCTX->codec_type;
EncArg.args.enc_init_mpeg4.in_profile_level = ENC_PROFILE_LEVEL(mpeg4_arg->ProfileIDC, mpeg4_arg->LevelIDC);
EncArg.args.enc_init_mpeg4.in_width = mpeg4_arg->SourceWidth;
EncArg.args.enc_init_mpeg4.in_height = mpeg4_arg->SourceHeight;
EncArg.args.enc_init_mpeg4.in_gop_num = mpeg4_arg->IDRPeriod;
if (mpeg4_arg->DisableQpelME)
EncArg.args.enc_init_mpeg4.in_qpelME_enable = 0;
else
EncArg.args.enc_init_mpeg4.in_qpelME_enable = 1;
EncArg.args.enc_init_mpeg4.in_MS_mode = mpeg4_arg->SliceMode;
EncArg.args.enc_init_mpeg4.in_MS_size = mpeg4_arg->SliceArgument;
if (mpeg4_arg->NumberBFrames > 2) {
fprintf(stderr,"SsbSipMfcEncInit: No such BframeNum is supported.\n");
return MFC_RET_INVALID_PARAM;
}
EncArg.args.enc_init_mpeg4.in_BframeNum = mpeg4_arg->NumberBFrames;
EncArg.args.enc_init_mpeg4.in_mb_refresh = mpeg4_arg->RandomIntraMBRefresh;
/* rate control*/
EncArg.args.enc_init_mpeg4.in_RC_frm_enable = mpeg4_arg->EnableFRMRateControl;
if ((mpeg4_arg->QSCodeMin > 51) || (mpeg4_arg->QSCodeMax > 51)) {
fprintf(stderr,"SsbSipMfcEncInit: No such Min/Max QP is supported.\n");
return MFC_RET_INVALID_PARAM;
}
EncArg.args.enc_init_mpeg4.in_RC_qbound = ENC_RC_QBOUND(mpeg4_arg->QSCodeMin, mpeg4_arg->QSCodeMax);
EncArg.args.enc_init_mpeg4.in_RC_rpara = mpeg4_arg->CBRPeriodRf;
/* pad control */
EncArg.args.enc_init_mpeg4.in_pad_ctrl_on = mpeg4_arg->PadControlOn;
if ((mpeg4_arg->LumaPadVal > 255) || (mpeg4_arg->CbPadVal > 255) || (mpeg4_arg->CrPadVal > 255)) {
fprintf(stderr,"SsbSipMfcEncInit: No such Pad value is supported.\n");
return MFC_RET_INVALID_PARAM;
}
EncArg.args.enc_init_mpeg4.in_luma_pad_val = mpeg4_arg->LumaPadVal;
EncArg.args.enc_init_mpeg4.in_cb_pad_val = mpeg4_arg->CbPadVal;
EncArg.args.enc_init_mpeg4.in_cr_pad_val = mpeg4_arg->CrPadVal;
EncArg.args.enc_init_mpeg4.in_frame_map = mpeg4_arg->FrameMap;
EncArg.args.enc_init_mpeg4.in_time_increament_res = mpeg4_arg->TimeIncreamentRes;
EncArg.args.enc_init_mpeg4.in_time_vop_time_increament = mpeg4_arg->VopTimeIncreament;
EncArg.args.enc_init_mpeg4.in_RC_framerate = (mpeg4_arg->TimeIncreamentRes / mpeg4_arg->VopTimeIncreament);
EncArg.args.enc_init_mpeg4.in_RC_bitrate = mpeg4_arg->Bitrate;
if ((mpeg4_arg->FrameQp > 51) || (mpeg4_arg->FrameQp_P) > 51 || (mpeg4_arg->FrameQp_B > 51)) {
fprintf(stderr,"SsbSipMfcEncInit: No such FrameQp is supported.\n");
return MFC_RET_INVALID_PARAM;
}
EncArg.args.enc_init_mpeg4.in_frame_qp = mpeg4_arg->FrameQp;
if (mpeg4_arg->FrameQp_P)
EncArg.args.enc_init_mpeg4.in_frame_P_qp = mpeg4_arg->FrameQp_P;
else
EncArg.args.enc_init_mpeg4.in_frame_P_qp = mpeg4_arg->FrameQp;
if (mpeg4_arg->FrameQp_B)
EncArg.args.enc_init_mpeg4.in_frame_B_qp = mpeg4_arg->FrameQp_B;
else
EncArg.args.enc_init_mpeg4.in_frame_B_qp = mpeg4_arg->FrameQp;
break;
case H263_ENC:
h263_arg = (SSBSIP_MFC_ENC_H263_PARAM *)param;
EncArg.args.enc_init_mpeg4.in_codec_type = pCTX->codec_type;
EncArg.args.enc_init_mpeg4.in_profile_level = ENC_PROFILE_LEVEL(66, 40);
EncArg.args.enc_init_mpeg4.in_width = h263_arg->SourceWidth;
EncArg.args.enc_init_mpeg4.in_height = h263_arg->SourceHeight;
EncArg.args.enc_init_mpeg4.in_gop_num = h263_arg->IDRPeriod;
EncArg.args.enc_init_mpeg4.in_mb_refresh = h263_arg->RandomIntraMBRefresh;
EncArg.args.enc_init_mpeg4.in_MS_mode = h2