⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssbsipmpeg4encode.c

📁 s3c6400 video code,you play video smooth with it,it is hardware codec
💻 C
字号:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#include <errno.h>
#include <sys/time.h>

#include "MfcDriver.h"
#include "MfcDrvParams.h"

#include "SsbSipMpeg4Encode.h"
#include "SsbSipLogMsg.h"


#define _MFCLIB_MPEG4_ENC_MAGIC_NUMBER		0x92242002

typedef struct
{
	int   	magic;
	int  	hOpen;
	int     fInit;
	int     enc_strm_size;
	int		enc_hdr_size;
	int		strmType;
	
	unsigned int  	width, height;
	unsigned int  	framerate, bitrate;
	unsigned int  	gop_num;
	unsigned char	*mapped_addr;
} _MFCLIB_MPEG4_ENC;


typedef struct {
	int width;
	int height;
	int frameRateRes;
	int frameRateDiv;
	int gopNum;
	int bitrate;
} enc_info_t;


void *SsbSipMPEG4EncodeInit(int strmType, unsigned int uiWidth,     unsigned int uiHeight,
                           unsigned int uiFramerate, unsigned int uiBitrate_kbps,
                           unsigned int uiGOPNum)
{
	_MFCLIB_MPEG4_ENC	*pCTX;
	int					hOpen;
	int					cmd;
	unsigned char		*addr;


	switch(strmType) {
		case SSBSIPMFCENC_MPEG4:
			cmd = IOCTL_MFC_MPEG4_ENC_INIT;
			break;
		case SSBSIPMFCENC_H263:
			cmd = IOCTL_MFC_H263_ENC_INIT;
			break;
		default:
			LOG_MSG(LOG_ERROR, "SsbSipMPEG4EncodeInit", "stream type is not defined\n");
			return NULL;
	}

	//////////////////////////////
	/////     CreateFile     /////
	//////////////////////////////
	hOpen = open(MFC_DEV_NAME, O_RDWR|O_NDELAY);
	if (hOpen < 0) {
		LOG_MSG(LOG_ERROR, "SsbSipMPEG4EncodeInit", "MFC Open failure.\n");
		return NULL;
	}

	//////////////////////////////////////////
	//	Mapping the MFC Input/Output Buffer	//
	//////////////////////////////////////////
	// mapping shared in/out buffer between application and MFC device driver
	addr = (unsigned char *) mmap(0, BUF_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, hOpen, 0);
	if (addr == NULL) {
		LOG_MSG(LOG_ERROR, "SsbSipMPEG4EncodeInit", "MFC Mmap failure.\n");
		return NULL;
	}

	pCTX = (_MFCLIB_MPEG4_ENC *) malloc(sizeof(_MFCLIB_MPEG4_ENC));
	if (pCTX == NULL) {
		LOG_MSG(LOG_ERROR, "SsbSipMPEG4EncodeInit", "malloc failed.\n");
		close(hOpen);
		return NULL;
	}
	memset(pCTX, 0, sizeof(_MFCLIB_MPEG4_ENC));

	pCTX->magic = _MFCLIB_MPEG4_ENC_MAGIC_NUMBER;
	pCTX->hOpen = hOpen;
	pCTX->fInit = 0;
	pCTX->mapped_addr	= addr;
	pCTX->strmType		= strmType;

	pCTX->width     = uiWidth;
	pCTX->height    = uiHeight;
	pCTX->framerate = uiFramerate;
	pCTX->bitrate   = uiBitrate_kbps;
	pCTX->gop_num   = uiGOPNum;

	pCTX->enc_strm_size = 0;

	return (void *) pCTX;
}


int SsbSipMPEG4EncodeExe(void *openHandle)
{
	_MFCLIB_MPEG4_ENC	*pCTX;
	int					r;
	int					cmd_init, cmd_exe;
	MFC_ARGS			mfc_args;


	////////////////////////////////
	//  Input Parameter Checking  //
	////////////////////////////////
	if (openHandle == NULL) {
		LOG_MSG(LOG_ERROR, "SsbSipMPEG4EncodeExe", "openHandle is NULL\n");
		return SSBSIP_MPEG4_ENC_RET_ERR_INVALID_HANDLE;
	}

	pCTX  = (_MFCLIB_MPEG4_ENC *) openHandle;

	switch(pCTX->strmType) {
		case SSBSIPMFCENC_MPEG4:
			cmd_init 	= IOCTL_MFC_MPEG4_ENC_INIT;
			cmd_exe		= IOCTL_MFC_MPEG4_ENC_EXE;
			break;
		case SSBSIPMFCENC_H263:
			cmd_init	= IOCTL_MFC_H263_ENC_INIT;
			cmd_exe 	= IOCTL_MFC_H263_ENC_EXE;
			break;
		default:
			LOG_MSG(LOG_ERROR, "SsbSipMPEG4EncodeExe", "stream type is not defined\n");
			return -1;
	}

	if (!pCTX->fInit) {
		mfc_args.enc_init.in_width		= pCTX->width;
		mfc_args.enc_init.in_height		= pCTX->height;
		mfc_args.enc_init.in_bitrate	= pCTX->bitrate;
		mfc_args.enc_init.in_gopNum		= pCTX->gop_num;
		mfc_args.enc_init.in_frameRateRes	= pCTX->framerate;
		mfc_args.enc_init.in_frameRateDiv	= 0;


		////////////////////////////////////////////////
		/////          (DeviceIoControl)           /////
		/////       IOCTL_MFC_MPEG4_DEC_INIT        /////
		////////////////////////////////////////////////
		r = ioctl(pCTX->hOpen, cmd_init, &mfc_args); 
		if ((r < 0) || (mfc_args.enc_init.ret_code < 0)) {
			LOG_MSG(LOG_ERROR, "SsbSipMPEG4EncodeInit", "IOCTL_MFC_MPEG4_ENC_INIT failed.\n");
			return SSBSIP_MPEG4_ENC_RET_ERR_ENCODE_FAIL;
		}

		pCTX->fInit = 1;

		return SSBSIP_MPEG4_ENC_RET_OK;
	}

	/////////////////////////////////////////////////
	/////           (DeviceIoControl)           /////
	/////       IOCTL_MFC_MPEG4_DEC_EXE         /////
	/////////////////////////////////////////////////
	r = ioctl(pCTX->hOpen, cmd_exe, &mfc_args);
	if ((r < 0) || (mfc_args.enc_exe.ret_code < 0)) {
		return SSBSIP_MPEG4_ENC_RET_ERR_ENCODE_FAIL;
	}

	// Encoded stream size is saved. (This value is returned in SsbSipMPEG4EncodeGetOutBuf)
	pCTX->enc_strm_size = mfc_args.enc_exe.out_encoded_size;

	if((mfc_args.enc_exe.out_header_size > 0) && (cmd_exe == IOCTL_MFC_MPEG4_ENC_EXE)) {
		pCTX->enc_hdr_size = mfc_args.enc_exe.out_header_size;
		LOG_MSG(LOG_TRACE, "SsbSipMPEG4EncodeExe", "HEADER SIZE = %d\n", pCTX->enc_hdr_size);
	}
	

	return SSBSIP_MPEG4_ENC_RET_OK;
}


int SsbSipMPEG4EncodeDeInit(void *openHandle)
{
	_MFCLIB_MPEG4_ENC  *pCTX;


	////////////////////////////////
	//  Input Parameter Checking  //
	////////////////////////////////
	if (openHandle == NULL) {
		LOG_MSG(LOG_ERROR, "SsbSipMPEG4EncodeDeInit", "openHandle is NULL\n");
		return SSBSIP_MPEG4_ENC_RET_ERR_INVALID_HANDLE;
	}

	pCTX  = (_MFCLIB_MPEG4_ENC *) openHandle;

	munmap(pCTX->mapped_addr, BUF_SIZE);
	close(pCTX->hOpen);


	return SSBSIP_MPEG4_ENC_RET_OK;
}


void *SsbSipMPEG4EncodeGetInBuf(void *openHandle, long size)
{
	_MFCLIB_MPEG4_ENC	*pCTX;
	int					r;
	MFC_ARGS			mfc_args;
	

	////////////////////////////////
	//  Input Parameter Checking  //
	////////////////////////////////
	if (openHandle == NULL) {
		LOG_MSG(LOG_ERROR, "SsbSipMPEG4EncodeGetInBuf", "openHandle is NULL\n");
		return NULL;
	}
	if ((size < 0) || (size > 0x100000)) {
		LOG_MSG(LOG_ERROR, "SsbSipMPEG4EncodeGetInBuf", "size is invalid. (size=%d)\n", size);
		return NULL;
	}

	pCTX  = (_MFCLIB_MPEG4_ENC *) openHandle;


	/////////////////////////////////////////////////
	/////           (DeviceIoControl)           /////
	/////     IOCTL_MFC_GET_INPUT_BUF_ADDR      /////
	/////////////////////////////////////////////////
	mfc_args.get_buf_addr.in_usr_data = (int)pCTX->mapped_addr;
	r = ioctl(pCTX->hOpen, IOCTL_MFC_GET_FRAM_BUF_ADDR, &mfc_args);
	if ((r < 0) || (mfc_args.get_buf_addr.ret_code < 0)) {
		LOG_MSG(LOG_ERROR, "SsbSipMPEG4EncodeGetInBuf", "Failed in get FRAM_BUF address\n");
		return NULL;
	}

	return (void *)mfc_args.get_buf_addr.out_buf_addr;
}


void *SsbSipMPEG4EncodeGetOutBuf(void *openHandle, long *size)
{
	_MFCLIB_MPEG4_ENC	*pCTX;
	int					r;
	MFC_ARGS			mfc_args;


	////////////////////////////////
	//  Input Parameter Checking  //
	////////////////////////////////
	if (openHandle == NULL) {
		LOG_MSG(LOG_ERROR, "SsbSipMPEG4EncodeGetOutBuf", "openHandle is NULL\n");
		return NULL;
	}
	if (size == NULL) {
		LOG_MSG(LOG_ERROR, "SsbSipMPEG4EncodeGetOutBuf", "size is NULL.\n");
		return NULL;
	}

	pCTX  = (_MFCLIB_MPEG4_ENC *) openHandle;

	/////////////////////////////////////////////////
	/////           (DeviceIoControl)           /////
	/////      IOCTL_MFC_GET_STRM_BUF_ADDR      /////
	/////////////////////////////////////////////////
	mfc_args.get_buf_addr.in_usr_data = (int)pCTX->mapped_addr;
	r = ioctl(pCTX->hOpen, IOCTL_MFC_GET_LINE_BUF_ADDR, &mfc_args);
	if ((r < 0) || (mfc_args.get_buf_addr.ret_code < 0)) {
		LOG_MSG(LOG_ERROR, "SsbSipMPEG4EncodeGetOutBuf", "Failed in get LINE_BUF address.\n");
		return NULL;
	}

	*size = pCTX->enc_strm_size;

	return (void *)mfc_args.get_buf_addr.out_buf_addr;
}


int SsbSipMPEG4EncodeSetConfig(void *openHandle, MPEG4_ENC_CONF conf_type, void *value)
{
	_MFCLIB_MPEG4_ENC  	*pCTX;
	MFC_ARGS			mfc_args;
	int					r;

	unsigned int		num_slices[2];
	

	////////////////////////////////
	//  Input Parameter Checking  //
	////////////////////////////////
	if (openHandle == NULL) {
		LOG_MSG(LOG_ERROR, "SsbSipMPEG4DecodeSetConfig", "openHandle is NULL\n");
		return SSBSIP_MPEG4_ENC_RET_ERR_INVALID_HANDLE;
	}
	if (value == NULL) {
		LOG_MSG(LOG_ERROR, "SsbSipMPEG4DecodeSetConfig", "value is NULL\n");
		return SSBSIP_MPEG4_ENC_RET_ERR_INVALID_PARAM;
	}

	pCTX  = (_MFCLIB_MPEG4_ENC *) openHandle;

	switch (conf_type) {
	case SET_H263_MULTIPLE_SLICE:
		ioctl(pCTX->hOpen, IOCTL_MFC_SET_H263_MULTIPLE_SLICE);
		break;

	case MPEG4_ENC_SETCONF_H263_NUM_SLICES:

		if (pCTX->strmType == SSBSIPMFCENC_MPEG4) {
			LOG_MSG(LOG_ERROR, "SsbSipMPEG4DecodeSetConfig", "MPEG4_ENC_SETCONF_H263_NUM_SLICES is only for H.263 encoding.\n");
			return SSBSIP_MPEG4_ENC_RET_ERR_SETCONF_FAIL;
		}

		num_slices[0] = ((unsigned int *) value)[0];
		num_slices[1] = ((unsigned int *) value)[1];
		mfc_args.set_config.in_config_param     = MFC_SET_CONFIG_ENC_SLICE_MODE;
		mfc_args.set_config.in_config_value[0]  = num_slices[0];
		mfc_args.set_config.in_config_value[1]  = num_slices[1];

		r = ioctl(pCTX->hOpen, IOCTL_MFC_SET_CONFIG, &mfc_args);
		if ((r < 0) || (mfc_args.set_config.ret_code < 0)) {
			LOG_MSG(LOG_ERROR, "SsbSipMPEG4DecodeSetConfig", "Error in MPEG4_ENC_SETCONF_H263_NUM_SLICES.\n");
			return SSBSIP_MPEG4_ENC_RET_ERR_SETCONF_FAIL;
		}
		break;

	case MPEG4_ENC_SETCONF_H263_ANNEX:

		if (pCTX->strmType == SSBSIPMFCENC_MPEG4) {
			LOG_MSG(LOG_ERROR, "SsbSipMPEG4DecodeSetConfig", "MPEG4_ENC_SETCONF_H263_ANNEX is only for H.263 encoding.\n");
			return SSBSIP_MPEG4_ENC_RET_ERR_SETCONF_FAIL;
		}

		mfc_args.set_config.in_config_param     = MFC_SET_CONFIG_ENC_H263_PARAM;
		mfc_args.set_config.in_config_value[0]  = *((unsigned int *) value);
		mfc_args.set_config.in_config_value[1]  = 0;

		r = ioctl(pCTX->hOpen, IOCTL_MFC_SET_CONFIG, &mfc_args);
		if ((r < 0) || (mfc_args.set_config.ret_code < 0)) {
			LOG_MSG(LOG_ERROR, "SsbSipMPEG4DecodeSetConfig", "Error in MPEG4_ENC_SETCONF_H263_ANNEX.\n");
			return SSBSIP_MPEG4_ENC_RET_ERR_SETCONF_FAIL;
		}
		break;

	case MPEG4_ENC_SETCONF_PARAM_CHANGE:

		mfc_args.set_config.in_config_param     = MFC_SET_CONFIG_ENC_PARAM_CHANGE;
		mfc_args.set_config.in_config_value[0]  = ((unsigned int *) value)[0];
		mfc_args.set_config.in_config_value[1]  = ((unsigned int *) value)[1];

		r = ioctl(pCTX->hOpen, IOCTL_MFC_SET_CONFIG, &mfc_args);
		if ((r < 0) || (mfc_args.set_config.ret_code < 0)) {
			LOG_MSG(LOG_ERROR, "SsbSipMPEG4DecodeSetConfig", "Error in MPEG4_ENC_SETCONF_PARAM_CHANGE.\n");
			return SSBSIP_MPEG4_ENC_RET_ERR_SETCONF_FAIL;
		}
		break;

	case MPEG4_ENC_SETCONF_CUR_PIC_OPT:

		mfc_args.set_config.in_config_param     = MFC_SET_CONFIG_ENC_CUR_PIC_OPT;
		mfc_args.set_config.in_config_value[0]  = ((unsigned int *) value)[0];
		mfc_args.set_config.in_config_value[1]  = ((unsigned int *) value)[1];

		r = ioctl(pCTX->hOpen, IOCTL_MFC_SET_CONFIG, &mfc_args);
		if ((r < 0) || (mfc_args.set_config.ret_code < 0)) {
			LOG_MSG(LOG_ERROR, "SsbSipMPEG4DecodeSetConfig", "Error in MPEG4_ENC_SETCONF_CUR_PIC_OPT.\n");
			return SSBSIP_MPEG4_ENC_RET_ERR_SETCONF_FAIL;
		}
		break;

	default:
		LOG_MSG(LOG_ERROR, "SsbSipMPEG4DecodeSetConfig", "No such conf_type is supported.\n");
		return SSBSIP_MPEG4_ENC_RET_ERR_SETCONF_FAIL;
	}

	return SSBSIP_MPEG4_ENC_RET_OK;
}




int SsbSipMPEG4EncodeGetConfig(void *openHandle, MPEG4_ENC_CONF conf_type, void *value)
{
	_MFCLIB_MPEG4_ENC  *pCTX;


	////////////////////////////////
	//  Input Parameter Checking  //
	////////////////////////////////
	if (openHandle == NULL) {
		return -1;
	}

	pCTX  = (_MFCLIB_MPEG4_ENC *) openHandle;


	switch (conf_type) {

	case MPEG4_ENC_GETCONF_HEADER_SIZE:
		*((int *)value) = pCTX->enc_hdr_size;
		break;
	
	default:
		break;
	}


	return SSBSIP_MPEG4_ENC_RET_OK;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -