怎么样使用xvid进行编码?
/*****************************************************************************
* Application notes :
*
* A sequence of raw YUV I420 pics or YUV I420 PGM file format is encoded
* The speed is measured and frames' PSNR are taken from core.
*
* The program is plain C and needs no libraries except for libxvidcore,
* and maths-lib.
*
* Use ./xvid_encraw -help for a list of options
*
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/time.h>
#include "xvid.h"
#undef READ_PNM
/*****************************************************************************
* Quality presets
****************************************************************************/
static const int motion_presets[] = {
/* quality 0 */
0,
/* quality 1 */
XVID_ME_ADVANCEDDIAMOND16,
/* quality 2 */
XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16,
/* quality 3 */
XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 |
XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8,
/* quality 4 */
XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 |
XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8 |
XVID_ME_CHROMA_PVOP | XVID_ME_CHROMA_BVOP,
/* quality 5 */
XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 |
XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8 |
XVID_ME_CHROMA_PVOP | XVID_ME_CHROMA_BVOP,
/* quality 6 */
XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 | XVID_ME_EXTSEARCH16 |
XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8 | XVID_ME_EXTSEARCH8 |
XVID_ME_CHROMA_PVOP | XVID_ME_CHROMA_BVOP,
};
#define ME_ELEMENTS (sizeof(motion_presets)/sizeof(motion_presets[0]))
static const int vop_presets[] = {
/* quality 0 */
0,
/* quality 1 */
0,
/* quality 2 */
XVID_VOP_HALFPEL,
/* quality 3 */
XVID_VOP_HALFPEL | XVID_VOP_INTER4V,
/* quality 4 */
XVID_VOP_HALFPEL | XVID_VOP_INTER4V,
/* quality 5 */
XVID_VOP_HALFPEL | XVID_VOP_INTER4V |
XVID_VOP_TRELLISQUANT,
/* quality 6 */
XVID_VOP_HALFPEL | XVID_VOP_INTER4V |
XVID_VOP_TRELLISQUANT | XVID_VOP_HQACPRED,
};
#define VOP_ELEMENTS (sizeof(vop_presets)/sizeof(vop_presets[0]))
/*****************************************************************************
* Command line global variables
****************************************************************************/
#define MAX_ZONES 64
static xvid_enc_zone_t ZONES[MAX_ZONES];
static int NUM_ZONES = 0;
/* Maximum number of frames to encode */
#define ABS_MAXFRAMENR 9999
static int ARG_STATS = 0;
static int ARG_DUMP = 0;
static int ARG_LUMIMASKING = 0;
static int ARG_BITRATE = 0;
static int ARG_SINGLE = 1;
static char *ARG_PASS1 = 0;
static char *ARG_PASS2 = 0;
static int ARG_QUALITY = ME_ELEMENTS - 1;
static float ARG_FRAMERATE = 25.00f;
static int ARG_MAXFRAMENR = ABS_MAXFRAMENR;
static int ARG_MAXKEYINTERVAL = 0;
static char *ARG_INPUTFILE = NULL;
static int ARG_INPUTTYPE = 0;
static int ARG_SAVEMPEGSTREAM = 0;
static int ARG_SAVEINDIVIDUAL = 0;
static int XDIM = 352;
static int YDIM = 288;
//static int XDIM = 176;
//static int YDIM = 144;
static int ARG_BQRATIO = 150;
static int ARG_BQOFFSET = 100;
static int ARG_MAXBFRAMES = 0;
static int ARG_PACKED = 0;
static int ARG_DEBUG = 0;
static int ARG_VOPDEBUG = 0;
static int ARG_GREYSCALE = 0;
static int ARG_QTYPE = 0;
static int ARG_QMATRIX = 0;
static int ARG_GMC = 0;
static int ARG_INTERLACING = 0;
static int ARG_QPEL = 0;
static int ARG_TURBO = 0;
static int ARG_VHQMODE = 0;
static int ARG_BVHQ = 0;
static int ARG_CLOSED_GOP = 0;
#define IMAGE_SIZE(x,y) ((x)*(y)*3/2)
#define SMALL_EPS (1e-10)
/****************************************************************************
* Nasty global vars ;-)
***************************************************************************/
/* Internal structures (handles) for encoding and decoding */
static void *enc_handle = NULL;
static unsigned char qmatrix_intra[64];
static unsigned char qmatrix_inter[64];
/*****************************************************************************
* Local prototypes
****************************************************************************/
/* PGM related functions */
/* Encoder related functions */
static int enc_init(int use_assembler);
static int enc_stop();
static int enc_main(unsigned char *image,
unsigned char *bitstream,
int *key,
int *stats_type,
int *stats_quant,
int *stats_length,
int stats[3]);
/*****************************************************************************
* Routines for encoding: init encoder, frame step, release encoder
****************************************************************************/
#define FRAMERATE_INCR 1001
/* Initialize encoder for first use, pass all needed parameters to the codec */
static int
enc_init(int use_assembler)
{
int xerr;
//xvid_plugin_cbr_t cbr;
xvid_plugin_single_t single;
xvid_plugin_2pass1_t rc2pass1;
xvid_plugin_2pass2_t rc2pass2;
//xvid_plugin_fixed_t rcfixed;
xvid_enc_plugin_t plugins[7];
xvid_gbl_init_t xvid_gbl_init;
xvid_enc_create_t xvid_enc_create;
/*------------------------------------------------------------------------
* XviD core initialization
*----------------------------------------------------------------------*/
/* Set version -- version checking will done by xvidcore */
memset(&xvid_gbl_init, 0, sizeof(xvid_gbl_init));
xvid_gbl_init.version = XVID_VERSION;
xvid_gbl_init.debug = ARG_DEBUG;
/* Do we have to enable ASM optimizations ? */
if (use_assembler) {
#ifdef ARCH_IS_IA64
xvid_gbl_init.cpu_flags = XVID_CPU_FORCE | XVID_CPU_ASM;
#else
xvid_gbl_init.cpu_flags = 0;
#endif
} else {
xvid_gbl_init.cpu_flags = XVID_CPU_FORCE;
}
/* Initialize XviD core -- Should be done once per __process__ */
xvid_global(NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL);
/*------------------------------------------------------------------------
* XviD encoder initialization
*----------------------------------------------------------------------*/
/* Version again */
memset(&xvid_enc_create, 0, sizeof(xvid_enc_create));
xvid_enc_create.version = XVID_VERSION;
/* Width and Height of input frames */
xvid_enc_create.width = XDIM;
xvid_enc_create.height = YDIM;
xvid_enc_create.profile = XVID_PROFILE_AS_L4;
/* init plugins */
xvid_enc_create.zones = ZONES;
xvid_enc_create.num_zones = NUM_ZONES;
xvid_enc_create.plugins = plugins;
xvid_enc_create.num_plugins = 0;
if (ARG_SINGLE) {
memset(&single, 0, sizeof(xvid_plugin_single_t));
single.version = XVID_VERSION;
single.bitrate = ARG_BITRATE;
plugins[xvid_enc_create.num_plugins].func = xvid_plugin_single;
plugins[xvid_enc_create.num_plugins].param = &single;
xvid_enc_create.num_plugins++;
}
if (ARG_PASS2) {
memset(&rc2pass2, 0, sizeof(xvid_plugin_2pass2_t));
rc2pass2.version = XVID_VERSION;
rc2pass2.filename = ARG_PASS2;
rc2pass2.bitrate = ARG_BITRATE;
/*An example of activating VBV could look like this
rc2pass2.vbv_size = 3145728;
rc2pass2.vbv_initial = 2359296;
rc2pass2.vbv_maxrate = 4000000;
rc2pass2.vbv_peakrate = 10000000;
*/
plugins[xvid_enc_create.num_plugins].func = xvid_plugin_2pass2;
plugins[xvid_enc_create.num_plugins].param = &rc2pass2;
xvid_enc_create.num_plugins++;
}
if (ARG_PASS1) {
memset(&rc2pass1, 0, sizeof(xvid_plugin_2pass1_t));
rc2pass1.version = XVID_VERSION;
rc2pass1.filename = ARG_PASS1;
plugins[xvid_enc_create.num_plugins].func = xvid_plugin_2pass1;
plugins[xvid_enc_create.num_plugins].param = &rc2pass1;
xvid_enc_create.num_plugins++;
}
if (ARG_LUMIMASKING) {
plugins[xvid_enc_create.num_plugins].func = xvid_plugin_lumimasking;
plugins[xvid_enc_create.num_plugins].param = NULL;
xvid_enc_create.num_plugins++;
}
if (ARG_DUMP) {
plugins[xvid_enc_create.num_plugins].func = xvid_plugin_dump;
plugins[xvid_enc_create.num_plugins].param = NULL;
xvid_enc_create.num_plugins++;
}
#if 0
if (ARG_DEBUG) {
plugins[xvid_enc_create.num_plugins].func = rawenc_debug;
plugins[xvid_enc_create.num_plugins].param = NULL;
xvid_enc_create.num_plugins++;
}
#endif
/* No fancy thread tests */
xvid_enc_create.num_threads = 0;
/* Frame rate - Do some quick float fps = fincr/fbase hack */
if ((ARG_FRAMERATE - (int) ARG_FRAMERATE) < SMALL_EPS) {
xvid_enc_create.fincr = 1;
xvid_enc_create.fbase = (int) ARG_FRAMERATE;
} else {
xvid_enc_create.fincr = FRAMERATE_INCR;
xvid_enc_create.fbase = (int) (FRAMERATE_INCR * ARG_FRAMERATE);
}
/* Maximum key frame interval */
if (ARG_MAXKEYINTERVAL > 0) {
xvid_enc_create.max_key_interval = ARG_MAXKEYINTERVAL;
}else {
xvid_enc_create.max_key_interval = (int) ARG_FRAMERATE *10;
}
/* Bframes settings */
xvid_enc_create.max_bframes = ARG_MAXBFRAMES;
xvid_enc_create.bquant_ratio = ARG_BQRATIO;
xvid_enc_create.bquant_offset = ARG_BQOFFSET;
/* Dropping ratio frame -- we don't need that */
xvid_enc_create.frame_drop_ratio = 0;
/* Global encoder options */
xvid_enc_create.global = 0;
if (ARG_PACKED)
xvid_enc_create.global |= XVID_GLOBAL_PACKED;
if (ARG_CLOSED_GOP)
xvid_enc_create.global |= XVID_GLOBAL_CLOSED_GOP;
if (ARG_STATS)
xvid_enc_create.global |= XVID_GLOBAL_EXTRASTATS_ENABLE;
/* I use a small value here, since will not encode whole movies, but short clips */
xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL);
/* Retrieve the encoder instance from the structure */
enc_handle = xvid_enc_create.handle;
return (xerr);
}
static int
enc_stop()
{
int xerr;
/* Destroy the encoder instance */
xerr = xvid_encore(enc_handle, XVID_ENC_DESTROY, NULL, NULL);
return (xerr);
}
static int
enc_main(unsigned char *image,
unsigned char *bitstream,
int *key,
int *stats_type,
int *stats_quant,
int *stats_length,
int sse[3])
{
int ret;
xvid_enc_frame_t xvid_enc_frame;
xvid_enc_stats_t xvid_enc_stats;
/* Version for the frame and the stats */
memset(&xvid_enc_frame, 0, sizeof(xvid_enc_frame));
xvid_enc_frame.version = XVID_VERSION;
memset(&xvid_enc_stats, 0, sizeof(xvid_enc_stats));
xvid_enc_stats.version = XVID_VERSION;
/* Bind output buffer */
xvid_enc_frame.bitstream = bitstream;
xvid_enc_frame.length = -1;
/* Initialize input image fields */
if (image) {
xvid_enc_frame.input.plane[0] = image;
#ifndef READ_PNM
if (ARG_INPUTTYPE==2)
xvid_enc_frame.input.csp = XVID_CSP_YV12;
else
xvid_enc_frame.input.csp = XVID_CSP_I420;
xvid_enc_frame.input.stride[0] = XDIM;
#else
xvid_enc_frame.input.csp = XVID_CSP_BGR;
xvid_enc_frame.input.stride[0] = XDIM*3;
#endif
} else {
xvid_enc_frame.input.csp = XVID_CSP_NULL;
}
/* Set up core's general features */
xvid_enc_frame.vol_flags = 0;
if (ARG_STATS)
xvid_enc_frame.vol_flags |= XVID_VOL_EXTRASTATS;
if (ARG_QTYPE)
xvid_enc_frame.vol_flags |= XVID_VOL_MPEGQUANT;
if (ARG_QPEL)
xvid_enc_frame.vol_flags |= XVID_VOL_QUARTERPEL;
if (ARG_GMC)
xvid_enc_frame.vol_flags |= XVID_VOL_GMC;
if (ARG_INTERLACING)
xvid_enc_frame.vol_flags |= XVID_VOL_INTERLACING;
/* Set up core's general features */
xvid_enc_frame.vop_flags = vop_presets[ARG_QUALITY];
if (ARG_VOPDEBUG) {
xvid_enc_frame.vop_flags |= XVID_VOP_DEBUG;
}
if (ARG_GREYSCALE) {
xvid_enc_frame.vop_flags |= XVID_VOP_GREYSCALE;
}
/* Frame type -- let core decide for us */
xvid_enc_frame.type = XVID_TYPE_AUTO;
/* Force the right quantizer -- It is internally managed by RC plugins */
xvid_enc_frame.quant = 0;
/* Set up motion estimation flags */
xvid_enc_frame.motion = motion_presets[ARG_QUALITY];
if (ARG_GMC)
xvid_enc_frame.motion |= XVID_ME_GME_REFINE;
if (ARG_QPEL)
xvid_enc_frame.motion |= XVID_ME_QUARTERPELREFINE16;
if (ARG_QPEL && (xvid_enc_frame.vop_flags & XVID_VOP_INTER4V))
xvid_enc_frame.motion |= XVID_ME_QUARTERPELREFINE8;
if (ARG_TURBO)
xvid_enc_frame.motion |= XVID_ME_FASTREFINE16 | XVID_ME_FASTREFINE8 |
XVID_ME_SKIP_DELTASEARCH | XVID_ME_FAST_MODEINTERPOLATE |
XVID_ME_BFRAME_EARLYSTOP;
if (ARG_BVHQ)
xvid_enc_frame.vop_flags |= XVID_VOP_RD_BVOP;
switch (ARG_VHQMODE) /* this is the same code as for vfw */
{
case 1: /* VHQ_MODE_DECISION */
xvid_enc_frame.vop_flags |= XVID_VOP_MODEDECISION_RD;
break;
case 2: /* VHQ_LIMITED_SEARCH */
xvid_enc_frame.vop_flags |= XVID_VOP_MODEDECISION_RD;
xvid_enc_frame.motion |= XVID_ME_HALFPELREFINE16_RD;
xvid_enc_frame.motion |= XVID_ME_QUARTERPELREFINE16_RD;
break;
case 3: /* VHQ_MEDIUM_SEARCH */
xvid_enc_frame.vop_flags |= XVID_VOP_MODEDECISION_RD;
xvid_enc_frame.motion |= XVID_ME_HALFPELREFINE16_RD;
xvid_enc_frame.motion |= XVID_ME_HALFPELREFINE8_RD;
xvid_enc_frame.motion |= XVID_ME_QUARTERPELREFINE16_RD;
xvid_enc_frame.motion |= XVID_ME_QUARTERPELREFINE8_RD;
xvid_enc_frame.motion |= XVID_ME_CHECKPREDICTION_RD;
break;
case 4: /* VHQ_WIDE_SEARCH */
xvid_enc_frame.vop_flags |= XVID_VOP_MODEDECISION_RD;
xvid_enc_frame.motion |= XVID_ME_HALFPELREFINE16_RD;
xvid_enc_frame.motion |= XVID_ME_HALFPELREFINE8_RD;
xvid_enc_frame.motion |= XVID_ME_QUARTERPELREFINE16_RD;
xvid_enc_frame.motion |= XVID_ME_QUARTERPELREFINE8_RD;
xvid_enc_frame.motion |= XVID_ME_CHECKPREDICTION_RD;
xvid_enc_frame.motion |= XVID_ME_EXTSEARCH_RD;
break;
default :
break;
}
if (ARG_QMATRIX) {
/* We don't use special matrices */
xvid_enc_frame.quant_intra_matrix = qmatrix_intra;
xvid_enc_frame.quant_inter_matrix = qmatrix_inter;
}
else {
/* We don't use special matrices */
xvid_enc_frame.quant_intra_matrix = NULL;
xvid_enc_frame.quant_inter_matrix = NULL;
}
/* Encode the frame */
ret = xvid_encore(enc_handle, XVID_ENC_ENCODE, &xvid_enc_frame,
&xvid_enc_stats);
*key = (xvid_enc_frame.out_flags & XVID_KEYFRAME);
*stats_type = xvid_enc_stats.type;
*stats_quant = xvid_enc_stats.quant;
*stats_length = xvid_enc_stats.length;
sse[0] = xvid_enc_stats.sse_y;
sse[1] = xvid_enc_stats.sse_u;
sse[2] = xvid_enc_stats.sse_v;
return (ret);
}
#define SRC_FILE "/opt/yuvsource/cif/foreman_cif90.yuv"
//#define SRC_FILE "/opt/yuvsource/qcif/foreman_qcif.yuv"
#define OUT_FILE "cif_tmp.m4d"
#define NUMS 90
typedef struct _m4v_head {
int magic;
int size;
}m4v_head;
int main(int argc, char *argv[])
{
FILE *fp = NULL;
FILE *fp1 = NULL;
int fd;
int i, nbytes;
char image[XDIM*YDIM*3/2], w_buf[XDIM*YDIM*3/2];
struct stat tat;
/*parameters used by xvid*/
int key;
int stats_type;
int stats_quant;
int stats_length;
int sse[3];
int m4v_size;
memset(w_buf, 0, sizeof(w_buf));
fp1 = fopen(OUT_FILE, "wb");
if (NULL == (fp=fopen(SRC_FILE, "rb")))
{
printf("fail open file to read/n");
return -1;
}
fd = fileno(fp);
fstat(fd, &tat);
if (tat.st_size != sizeof(image)*90)
{
printf("not exact file size/n");
return -1;
}
enc_init(0);
for (i=0; i<NUMS; i++)
{
nbytes = fread(image, 1, sizeof(image), fp);
if (nbytes != sizeof(image))
{
printf("fail to read/n");
return -1;
}
m4v_size = enc_main(image,w_buf,&key,&stats_type,&stats_quant,&stats_length,sse);
//memcpy(w_buf, &head, sizeof(head));
fwrite(w_buf,1,m4v_size,fp1);
printf("index[%d] length is %d/n", i, m4v_size);
}
fclose(fp);
fclose(fp1);
enc_stop();
return 0;
}
本文地址:http://www.45fan.com/dnjc/70924.html