Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1375573
  • 博文数量: 244
  • 博客积分: 10311
  • 博客等级: 上将
  • 技术积分: 3341
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-14 21:50
文章分类

全部博文(244)

文章存档

2013年(6)

2012年(5)

2011年(16)

2010年(11)

2009年(172)

2008年(34)

分类: LINUX

2009-06-01 20:30:30

/*****************************************************************************************************
linux_m4v.c
gcc -o linux_m4v linux_m4v.c -lc -lm -lxvidcore
*******************************************************************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "xvid_encode.h"
void *enc_handle = NULL;
int done = 0;
int
enc_main(unsigned char *image,
   unsigned char *bitstream,
   int *key,
   int *stats_type,
   int *stats_quant,
   int *stats_length,
   int sse[3]);
int
enc_stop();
int
enc_init(int use_assembler);
double
msecond();
 
 
#define VIDEO_PALETTE_JPEG  21
struct vdIn {
 int fd;
 char *videodevice ;
 struct video_capability videocap;
 struct video_picture videopict;
 struct video_window videowin;
 int framesizeIn ;
 int bppIn;
 int  hdrwidth;
 int  hdrheight;
 int  formatIn;
};
struct vdIn videoIn;
int init_videoIn (struct vdIn *vd, char *device, int width, int height,int format);
static int GetDepth (int format);
static int GetVideoPict (struct vdIn *vd);
static int SetVideoPict (struct vdIn *vd);

int main(int argc,char *argv[])
{
 char *device;
 
 int format = VIDEO_PALETTE_YUV420P;
 int width = 352;
   int height = 288;
 int i;
 unsigned char r_buffer[304128];
 unsigned char* mp4_buffer;
 double enctime;
 double totalenctime = 0.;
 float totalPSNR[3] = {0., 0., 0.};
 device = "/dev/video0";
 ARG_OUTPUTFILE = "test.m4v";
 int use_assembler = 1;
 int result;
 int totalsize;
 int m4v_size;
 int key;
 int stats_type;
 int stats_quant;
 int stats_length;
 int input_num;
 int output_num;
 char filename[256];
 FILE *out_file = NULL;
 memset (&videoIn, 0, sizeof (struct vdIn));
   if (init_videoIn(&videoIn, device, width, height,format) != 0)
       printf (" damned encore rate !!\n");
 /* xvid init */
 ARG_SAVEMPEGSTREAM = 1;
 ARG_SAVEINDIVIDUAL = 0;
 
 XDIM = width;
 YDIM = height;
 mp4_buffer = (unsigned char *) malloc(IMAGE_SIZE(XDIM, YDIM) * 2);
 
 totalsize = 0;
 result = 0;
 result = enc_init(0);
 if (result != 0) {
  fprintf(stderr, "Encore INIT problem, return value %d\n",result);
  goto release_all;
 }
/* i=read(videoIn.fd,r_buffer,304128);
 printf("i read : %d\n",i);
 if(i<0){
  printf("error read!\n");
  close(videoIn.fd);
  return -1;
  }
*/
 input_num = 0;    /* input frame counter */
 output_num = 0;

 
 if (ARG_SAVEMPEGSTREAM && ARG_OUTPUTFILE) {
  if ((out_file = fopen(ARG_OUTPUTFILE, "w+b")) == NULL) {
   fprintf(stderr, "Error opening output file %s\n", ARG_OUTPUTFILE);
   goto release_all;
  }
 } else {
  out_file = NULL;
 }
 
 
 /* Xvid encode */
 do {
  char *type;
  int sse[3];
  i=read(videoIn.fd,r_buffer,304128);
  printf("i read : %d\n",i);
  if(i<0){
   printf("error read!\n");
   close(videoIn.fd);
   return -1;
  }
  if (input_num >= ARG_MAXFRAMENR) {
   //result = 1;
   done = 1;
  }
  enctime = msecond();
  m4v_size =enc_main(!result ? (unsigned char*)r_buffer:0,mp4_buffer, &key, &stats_type,&stats_quant, &stats_length, sse);
  enctime = msecond() - enctime;
  printf("m4v_size is %d \n",m4v_size);
 if (m4v_size < 0) {
   printf("erro in encode....\n");
  }
  /* Update encoding time stats */
  totalenctime += enctime;
  totalsize += m4v_size;
 if (m4v_size > 0 && ARG_SAVEMPEGSTREAM) {
   /* Save single files */
   if (ARG_SAVEINDIVIDUAL) {
    FILE *out;
    sprintf(filename, "%sframe%05d.m4v", filepath, output_num);
    out = fopen(filename, "w+b");
    fwrite(mp4_buffer, m4v_size, 1, out);
    fclose(out);
    output_num++;
   }
   /* Save ES stream */
   if (ARG_OUTPUTFILE && out_file)
    fwrite(mp4_buffer, 1, m4v_size, out_file);
  }
  input_num++;

 } while (!done);

 
 if(m4v_size<0){
  printf("error write_jpeg!\n");
  close(videoIn.fd);
  fclose(out_file);
  return -1;
  }
 printf("OK.\n");
release_all:
 if (enc_handle) {
  result = enc_stop();
  if (result)
   fprintf(stderr, "Encore RELEASE problem return value %d\n",
     result);
 }

 fclose(out_file);
 close(videoIn.fd);
 return 0;
}
int init_videoIn (struct vdIn *vd, char *device, int width, int height,
       int format)
{
 int erreur;
 vd->hdrwidth = width;
   vd->hdrheight = height;
   vd->formatIn = format;
   vd->bppIn = GetDepth (vd->formatIn);
 
 if ((vd->fd = open (device, O_RDWR)) == -1){
      printf("ERROR opening V4L interface\n");
  close(vd->fd);
  return -1;
  }
 if (ioctl (vd->fd, VIDIOCGCAP, &(vd->videocap)) == -1){
      printf("ERROR opening video_capability interface\n");
  close(vd->fd);
  return -1;
  }
   printf ("Camera found: %s \n", vd->videocap.name);
 erreur = GetVideoPict (vd);
 vd->videopict.palette = vd->formatIn;
   vd->videopict.depth = GetDepth (vd->formatIn);
   vd->bppIn = GetDepth (vd->formatIn);
 
    vd->framesizeIn = (vd->hdrwidth * vd->hdrheight * vd->bppIn) >> 3;
  
   erreur = SetVideoPict (vd);
   erreur = GetVideoPict (vd);
   if (vd->formatIn != vd->videopict.palette ||
        vd->bppIn != vd->videopict.depth){
      printf("ERROR set video_picture interface\n");
  close(vd->fd);
  return -1;
  }
   if (erreur < 0){
      printf("ERROR set palette \n");
  close(vd->fd);
  return -1;
  }
 if (ioctl (vd->fd, VIDIOCGWIN, &(vd->videowin)) < 0)
  perror ("VIDIOCGWIN failed \n");
       vd->videowin.height = vd->hdrheight;
      vd->videowin.width = vd->hdrwidth;
      if (ioctl (vd->fd, VIDIOCSWIN, &(vd->videowin)) < 0)
  perror ("VIDIOCSWIN failed \n");
 if (ioctl (vd->fd, VIDIOCGWIN, &(vd->videowin)) < 0)
  perror ("VIDIOCGWIN failed \n");
      printf ("VIDIOCSWIN height %d  width %d \n",
       vd->videowin.height, vd->videowin.width);
 return 0;
}
static int
GetDepth (int format)
{
  int depth;
  switch (format)
    {
  
   case VIDEO_PALETTE_JPEG:
      {
 depth = 8; 
      }
      break;
    case VIDEO_PALETTE_RAW:
      {
 depth = 8; 
      }
      break;
    case VIDEO_PALETTE_YUV420P:
      {
 //depth = (8 * 3) >> 1;
 depth = 24;
      }
      break;
    case VIDEO_PALETTE_RGB565:
      depth = 16;
      break;
    case VIDEO_PALETTE_RGB24:
      depth = 24;
      break;
    case VIDEO_PALETTE_RGB32:
      {
 depth = 32;
      }
      break;
    default:
      depth = -1;
      break;
    }
  return depth;
}
static int
GetVideoPict (struct vdIn *vd)
{
  if (ioctl (vd->fd, VIDIOCGPICT, &vd->videopict) < 0){
      printf("ERROR opening video_capability interface\n");
  close(vd->fd);
  return -1;
  }

  printf ("VIDIOCGPICT brightnes=%d hue=%d color=%d contrast=%d whiteness=%d"
   "depth=%d palette=%d\n", vd->videopict.brightness,
   vd->videopict.hue, vd->videopict.colour, vd->videopict.contrast,
   vd->videopict.whiteness, vd->videopict.depth,
   vd->videopict.palette);
  return 0;
}
static int
SetVideoPict (struct vdIn *vd)
{
  if (ioctl (vd->fd, VIDIOCSPICT, &vd->videopict) < 0){
      printf("ERROR set video_capability interface\n");
  close(vd->fd);
  return -1;
  }
  printf ("VIDIOCSPICT brightnes=%d hue=%d color=%d contrast=%d whiteness=%d"
   "depth=%d palette=%d\n", vd->videopict.brightness,
   vd->videopict.hue, vd->videopict.colour, vd->videopict.contrast,
   vd->videopict.whiteness, vd->videopict.depth,
   vd->videopict.palette);
  return 0;
}
double
msecond()
{
 struct timeval tv;
 gettimeofday(&tv, 0);
 return (tv.tv_sec * 1.0e3 + tv.tv_usec * 1.0e-3);
}
#define FRAMERATE_INCR 1001
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 = 0;
 
 
 /* Do we have to enable ASM optimizations ? */
 if (use_assembler) {
  xvid_gbl_init.cpu_flags = 0;
 }
 
 /* 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_S_L3;
 
 /* init plugins  */
     xvid_enc_create.zones = NULL;
     xvid_enc_create.num_zones = 0;
 
 xvid_enc_create.plugins = NULL;
 xvid_enc_create.num_plugins = 0;
 
 /* 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 = 0;
 xvid_enc_create.bquant_ratio = 150;
 xvid_enc_create.bquant_offset = 100;
 
 /* Dropping ratio frame -- we don't need that */
 xvid_enc_create.frame_drop_ratio = 0;
 
 /* Global encoder options */
 xvid_enc_create.global = 0;
 
 /* 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);
}
int
enc_stop()
{
 int xerr;
 /* Destroy the encoder instance */
 xerr = xvid_encore(enc_handle, XVID_ENC_DESTROY, NULL, NULL);
 return (xerr);
}
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);
}
 /********************************xvid_encode.h**********************************/
#ifndef XVID_ENCODE_H
#define XVID_ENCODE_H
#include
#include
#include
#include
#include
#include "xvid.h"
#define ABS_MAXFRAMENR 9999
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]))

static int ARG_STATS = 0;
static int ARG_DUMP = 0;
static int ARG_LUMIMASKING = 0;
static int ARG_BITRATE = 0;
static int ARG_SINGLE = 0;
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 char *ARG_OUTPUTFILE = NULL;
static int XDIM = 0;
static int YDIM = 0;
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 MAX_ZONES   64
static xvid_enc_zone_t ZONES[MAX_ZONES];
static int NUM_ZONES = 0;
#define SMALL_EPS (1e-10)
#define FRAMERATE_INCR 1001
static unsigned char qmatrix_intra[64];
static unsigned char qmatrix_inter[64];
static char filepath[256] = "./";
#define IMAGE_SIZE(x,y) ((x)*(y)*3/2)
 
#endif

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/neohuo/archive/2006/07/10/899728.aspx
阅读(2413) | 评论(0) | 转发(5) |
给主人留下些什么吧!~~