mpeg2enc.c
上传用户:ma_junhua
上传日期:2008-04-11
资源大小:2752k
文件大小:15k
开发平台:

C/C++

  1. /* mpeg2enc.c, main() and parameter file reading                            */
  2. /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
  3. /*
  4.  * Disclaimer of Warranty
  5.  *
  6.  * These software programs are available to the user without any license fee or
  7.  * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
  8.  * any and all warranties, whether express, implied, or statuary, including any
  9.  * implied warranties or merchantability or of fitness for a particular
  10.  * purpose.  In no event shall the copyright-holder be liable for any
  11.  * incidental, punitive, or consequential damages of any kind whatsoever
  12.  * arising from the use of these programs.
  13.  *
  14.  * This disclaimer of warranty extends to the user of these programs and user's
  15.  * customers, employees, agents, transferees, successors, and assigns.
  16.  *
  17.  * The MPEG Software Simulation Group does not represent or warrant that the
  18.  * programs furnished hereunder are free of infringement of any third-party
  19.  * patents.
  20.  *
  21.  * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
  22.  * are subject to royalty fees to patent holders.  Many of these patents are
  23.  * general enough such that they are unavoidable regardless of implementation
  24.  * design.
  25.  *
  26.  */
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #define GLOBAL /* used by global.h */
  30. #include "config.h"
  31. #include "global.h"
  32. /* private prototypes */
  33. static void init _ANSI_ARGS_((void));
  34. static void readparmfile _ANSI_ARGS_((char *fname));
  35. static void readquantmat _ANSI_ARGS_((void));
  36. int main(argc,argv)
  37. int argc;
  38. char *argv[];
  39. {
  40.   if (argc!=3)
  41.   {
  42.     printf("n%s, %sn",version,author);
  43.     printf("Usage: mpeg2encode in.par out.m2vn");
  44.     exit(0);
  45.   }
  46.   /* read parameter file */
  47.   readparmfile(argv[1]);
  48.   /* read quantization matrices */
  49.   readquantmat();
  50.   /* open output file */
  51.   if (!(outfile=fopen(argv[2],"wb")))
  52.   {
  53.     sprintf(errortext,"Couldn't create output file %s",argv[2]);
  54.     error(errortext);
  55.   }
  56.   init();
  57.   putseq();
  58.   fclose(outfile);
  59.   fclose(statfile);
  60.   return 0;
  61. }
  62. static void init()
  63. {
  64.   int i, size;
  65.   static int block_count_tab[3] = {6,8,12};
  66.   initbits();
  67.   init_fdct();
  68.   init_idct();
  69.   /* round picture dimensions to nearest multiple of 16 or 32 */
  70.   mb_width = (horizontal_size+15)/16;
  71.   mb_height = prog_seq ? (vertical_size+15)/16 : 2*((vertical_size+31)/32);
  72.   mb_height2 = fieldpic ? mb_height>>1 : mb_height; /* for field pictures */
  73.   width = 16*mb_width;
  74.   height = 16*mb_height;
  75.   chrom_width = (chroma_format==CHROMA444) ? width : width>>1;
  76.   chrom_height = (chroma_format!=CHROMA420) ? height : height>>1;
  77.   height2 = fieldpic ? height>>1 : height;
  78.   width2 = fieldpic ? width<<1 : width;
  79.   chrom_width2 = fieldpic ? chrom_width<<1 : chrom_width;
  80.   
  81.   block_count = block_count_tab[chroma_format-1];
  82.   /* clip table */
  83.   if (!(clp = (unsigned char *)malloc(1024)))
  84.     error("malloc failedn");
  85.   clp+= 384;
  86.   for (i=-384; i<640; i++)
  87.     clp[i] = (i<0) ? 0 : ((i>255) ? 255 : i);
  88.   for (i=0; i<3; i++)
  89.   {
  90.     size = (i==0) ? width*height : chrom_width*chrom_height;
  91.     if (!(newrefframe[i] = (unsigned char *)malloc(size)))
  92.       error("malloc failedn");
  93.     if (!(oldrefframe[i] = (unsigned char *)malloc(size)))
  94.       error("malloc failedn");
  95.     if (!(auxframe[i] = (unsigned char *)malloc(size)))
  96.       error("malloc failedn");
  97.     if (!(neworgframe[i] = (unsigned char *)malloc(size)))
  98.       error("malloc failedn");
  99.     if (!(oldorgframe[i] = (unsigned char *)malloc(size)))
  100.       error("malloc failedn");
  101.     if (!(auxorgframe[i] = (unsigned char *)malloc(size)))
  102.       error("malloc failedn");
  103.     if (!(predframe[i] = (unsigned char *)malloc(size)))
  104.       error("malloc failedn");
  105.   }
  106.   mbinfo = (struct mbinfo *)malloc(mb_width*mb_height2*sizeof(struct mbinfo));
  107.   if (!mbinfo)
  108.     error("malloc failedn");
  109.   blocks =
  110.     (short (*)[64])malloc(mb_width*mb_height2*block_count*sizeof(short [64]));
  111.   if (!blocks)
  112.     error("malloc failedn");
  113.   /* open statistics output file */
  114.   if (statname[0]=='-')
  115.     statfile = stdout;
  116.   else if (!(statfile = fopen(statname,"w")))
  117.   {
  118.     sprintf(errortext,"Couldn't create statistics output file %s",statname);
  119.     error(errortext);
  120.   }
  121. }
  122. void error(text)
  123. char *text;
  124. {
  125.   fprintf(stderr,text);
  126.   putc('n',stderr);
  127.   exit(1);
  128. }
  129. static void readparmfile(fname)
  130. char *fname;
  131. {
  132.   int i;
  133.   int h,m,s,f;
  134.   FILE *fd;
  135.   char line[256];
  136.   static double ratetab[8]=
  137.     {24000.0/1001.0,24.0,25.0,30000.0/1001.0,30.0,50.0,60000.0/1001.0,60.0};
  138.   extern int r,Xi,Xb,Xp,d0i,d0p,d0b; /* rate control */
  139.   extern double avg_act; /* rate control */
  140.   if (!(fd = fopen(fname,"r")))
  141.   {
  142.     sprintf(errortext,"Couldn't open parameter file %s",fname);
  143.     error(errortext);
  144.   }
  145.   fgets(id_string,254,fd);
  146.   fgets(line,254,fd); sscanf(line,"%s",tplorg);
  147.   fgets(line,254,fd); sscanf(line,"%s",tplref);
  148.   fgets(line,254,fd); sscanf(line,"%s",iqname);
  149.   fgets(line,254,fd); sscanf(line,"%s",niqname);
  150.   fgets(line,254,fd); sscanf(line,"%s",statname);
  151.   fgets(line,254,fd); sscanf(line,"%d",&inputtype);
  152.   fgets(line,254,fd); sscanf(line,"%d",&nframes);
  153.   fgets(line,254,fd); sscanf(line,"%d",&frame0);
  154.   fgets(line,254,fd); sscanf(line,"%d:%d:%d:%d",&h,&m,&s,&f);
  155.   fgets(line,254,fd); sscanf(line,"%d",&N);
  156.   fgets(line,254,fd); sscanf(line,"%d",&M);
  157.   fgets(line,254,fd); sscanf(line,"%d",&mpeg1);
  158.   fgets(line,254,fd); sscanf(line,"%d",&fieldpic);
  159.   fgets(line,254,fd); sscanf(line,"%d",&horizontal_size);
  160.   fgets(line,254,fd); sscanf(line,"%d",&vertical_size);
  161.   fgets(line,254,fd); sscanf(line,"%d",&aspectratio);
  162.   fgets(line,254,fd); sscanf(line,"%d",&frame_rate_code);
  163.   fgets(line,254,fd); sscanf(line,"%lf",&bit_rate);
  164.   fgets(line,254,fd); sscanf(line,"%d",&vbv_buffer_size);   
  165.   fgets(line,254,fd); sscanf(line,"%d",&low_delay);     
  166.   fgets(line,254,fd); sscanf(line,"%d",&constrparms);
  167.   fgets(line,254,fd); sscanf(line,"%d",&profile);
  168.   fgets(line,254,fd); sscanf(line,"%d",&level);
  169.   fgets(line,254,fd); sscanf(line,"%d",&prog_seq);
  170.   fgets(line,254,fd); sscanf(line,"%d",&chroma_format);
  171.   fgets(line,254,fd); sscanf(line,"%d",&video_format);
  172.   fgets(line,254,fd); sscanf(line,"%d",&color_primaries);
  173.   fgets(line,254,fd); sscanf(line,"%d",&transfer_characteristics);
  174.   fgets(line,254,fd); sscanf(line,"%d",&matrix_coefficients);
  175.   fgets(line,254,fd); sscanf(line,"%d",&display_horizontal_size);
  176.   fgets(line,254,fd); sscanf(line,"%d",&display_vertical_size);
  177.   fgets(line,254,fd); sscanf(line,"%d",&dc_prec);
  178.   fgets(line,254,fd); sscanf(line,"%d",&topfirst);
  179.   fgets(line,254,fd); sscanf(line,"%d %d %d",
  180.     frame_pred_dct_tab,frame_pred_dct_tab+1,frame_pred_dct_tab+2);
  181.   
  182.   fgets(line,254,fd); sscanf(line,"%d %d %d",
  183.     conceal_tab,conceal_tab+1,conceal_tab+2);
  184.   
  185.   fgets(line,254,fd); sscanf(line,"%d %d %d",
  186.     qscale_tab,qscale_tab+1,qscale_tab+2);
  187.   fgets(line,254,fd); sscanf(line,"%d %d %d",
  188.     intravlc_tab,intravlc_tab+1,intravlc_tab+2);
  189.   fgets(line,254,fd); sscanf(line,"%d %d %d",
  190.     altscan_tab,altscan_tab+1,altscan_tab+2);
  191.   fgets(line,254,fd); sscanf(line,"%d",&repeatfirst);
  192.   fgets(line,254,fd); sscanf(line,"%d",&prog_frame);
  193. /* intra slice interval refresh period */  
  194.   fgets(line,254,fd); sscanf(line,"%d",&P);
  195.   fgets(line,254,fd); sscanf(line,"%d",&r);
  196.   fgets(line,254,fd); sscanf(line,"%lf",&avg_act);
  197.   fgets(line,254,fd); sscanf(line,"%d",&Xi);
  198.   fgets(line,254,fd); sscanf(line,"%d",&Xp);
  199.   fgets(line,254,fd); sscanf(line,"%d",&Xb);
  200.   fgets(line,254,fd); sscanf(line,"%d",&d0i);
  201.   fgets(line,254,fd); sscanf(line,"%d",&d0p);
  202.   fgets(line,254,fd); sscanf(line,"%d",&d0b);
  203.   if (N<1)
  204.     error("N must be positive");
  205.   if (M<1)
  206.     error("M must be positive");
  207.   if (N%M != 0)
  208.     error("N must be an integer multiple of M");
  209.   motion_data = (struct motion_data *)malloc(M*sizeof(struct motion_data));
  210.   if (!motion_data)
  211.     error("malloc failedn");
  212.   for (i=0; i<M; i++)
  213.   {
  214.     fgets(line,254,fd);
  215.     sscanf(line,"%d %d %d %d",
  216.       &motion_data[i].forw_hor_f_code, &motion_data[i].forw_vert_f_code,
  217.       &motion_data[i].sxf, &motion_data[i].syf);
  218.     if (i!=0)
  219.     {
  220.       fgets(line,254,fd);
  221.       sscanf(line,"%d %d %d %d",
  222.         &motion_data[i].back_hor_f_code, &motion_data[i].back_vert_f_code,
  223.         &motion_data[i].sxb, &motion_data[i].syb);
  224.     }
  225.   }
  226.   fclose(fd);
  227.   /* make flags boolean (x!=0 -> x=1) */
  228.   mpeg1 = !!mpeg1;
  229.   fieldpic = !!fieldpic;
  230.   low_delay = !!low_delay;
  231.   constrparms = !!constrparms;
  232.   prog_seq = !!prog_seq;
  233.   topfirst = !!topfirst;
  234.   for (i=0; i<3; i++)
  235.   {
  236.     frame_pred_dct_tab[i] = !!frame_pred_dct_tab[i];
  237.     conceal_tab[i] = !!conceal_tab[i];
  238.     qscale_tab[i] = !!qscale_tab[i];
  239.     intravlc_tab[i] = !!intravlc_tab[i];
  240.     altscan_tab[i] = !!altscan_tab[i];
  241.   }
  242.   repeatfirst = !!repeatfirst;
  243.   prog_frame = !!prog_frame;
  244.   /* make sure MPEG specific parameters are valid */
  245.   range_checks();
  246.   frame_rate = ratetab[frame_rate_code-1];
  247.   /* timecode -> frame number */
  248.   tc0 = h;
  249.   tc0 = 60*tc0 + m;
  250.   tc0 = 60*tc0 + s;
  251.   tc0 = (int)(frame_rate+0.5)*tc0 + f;
  252.   if (!mpeg1)
  253.   {
  254.     profile_and_level_checks();
  255.   }
  256.   else
  257.   {
  258.     /* MPEG-1 */
  259.     if (constrparms)
  260.     {
  261.       if (horizontal_size>768
  262.           || vertical_size>576
  263.           || ((horizontal_size+15)/16)*((vertical_size+15)/16)>396
  264.           || ((horizontal_size+15)/16)*((vertical_size+15)/16)*frame_rate>396*25.0
  265.           || frame_rate>30.0)
  266.       {
  267.         if (!quiet)
  268.           fprintf(stderr,"Warning: setting constrained_parameters_flag = 0n");
  269.         constrparms = 0;
  270.       }
  271.     }
  272.     if (constrparms)
  273.     {
  274.       for (i=0; i<M; i++)
  275.       {
  276.         if (motion_data[i].forw_hor_f_code>4)
  277.         {
  278.           if (!quiet)
  279.             fprintf(stderr,"Warning: setting constrained_parameters_flag = 0n");
  280.           constrparms = 0;
  281.           break;
  282.         }
  283.         if (motion_data[i].forw_vert_f_code>4)
  284.         {
  285.           if (!quiet)
  286.             fprintf(stderr,"Warning: setting constrained_parameters_flag = 0n");
  287.           constrparms = 0;
  288.           break;
  289.         }
  290.         if (i!=0)
  291.         {
  292.           if (motion_data[i].back_hor_f_code>4)
  293.           {
  294.             if (!quiet)
  295.               fprintf(stderr,"Warning: setting constrained_parameters_flag = 0n");
  296.             constrparms = 0;
  297.             break;
  298.           }
  299.           if (motion_data[i].back_vert_f_code>4)
  300.           {
  301.             if (!quiet)
  302.               fprintf(stderr,"Warning: setting constrained_parameters_flag = 0n");
  303.             constrparms = 0;
  304.             break;
  305.           }
  306.         }
  307.       }
  308.     }
  309.   }
  310.   /* relational checks */
  311.   if (mpeg1)
  312.   {
  313.     if (!prog_seq)
  314.     {
  315.       if (!quiet)
  316.         fprintf(stderr,"Warning: setting progressive_sequence = 1n");
  317.       prog_seq = 1;
  318.     }
  319.     if (chroma_format!=CHROMA420)
  320.     {
  321.       if (!quiet)
  322.         fprintf(stderr,"Warning: setting chroma_format = 1 (4:2:0)n");
  323.       chroma_format = CHROMA420;
  324.     }
  325.     if (dc_prec!=0)
  326.     {
  327.       if (!quiet)
  328.         fprintf(stderr,"Warning: setting intra_dc_precision = 0n");
  329.       dc_prec = 0;
  330.     }
  331.     for (i=0; i<3; i++)
  332.       if (qscale_tab[i])
  333.       {
  334.         if (!quiet)
  335.           fprintf(stderr,"Warning: setting qscale_tab[%d] = 0n",i);
  336.         qscale_tab[i] = 0;
  337.       }
  338.     for (i=0; i<3; i++)
  339.       if (intravlc_tab[i])
  340.       {
  341.         if (!quiet)
  342.           fprintf(stderr,"Warning: setting intravlc_tab[%d] = 0n",i);
  343.         intravlc_tab[i] = 0;
  344.       }
  345.     for (i=0; i<3; i++)
  346.       if (altscan_tab[i])
  347.       {
  348.         if (!quiet)
  349.           fprintf(stderr,"Warning: setting altscan_tab[%d] = 0n",i);
  350.         altscan_tab[i] = 0;
  351.       }
  352.   }
  353.   if (!mpeg1 && constrparms)
  354.   {
  355.     if (!quiet)
  356.       fprintf(stderr,"Warning: setting constrained_parameters_flag = 0n");
  357.     constrparms = 0;
  358.   }
  359.   if (prog_seq && !prog_frame)
  360.   {
  361.     if (!quiet)
  362.       fprintf(stderr,"Warning: setting progressive_frame = 1n");
  363.     prog_frame = 1;
  364.   }
  365.   if (prog_frame && fieldpic)
  366.   {
  367.     if (!quiet)
  368.       fprintf(stderr,"Warning: setting field_pictures = 0n");
  369.     fieldpic = 0;
  370.   }
  371.   if (!prog_frame && repeatfirst)
  372.   {
  373.     if (!quiet)
  374.       fprintf(stderr,"Warning: setting repeat_first_field = 0n");
  375.     repeatfirst = 0;
  376.   }
  377.   if (prog_frame)
  378.   {
  379.     for (i=0; i<3; i++)
  380.       if (!frame_pred_dct_tab[i])
  381.       {
  382.         if (!quiet)
  383.           fprintf(stderr,"Warning: setting frame_pred_frame_dct[%d] = 1n",i);
  384.         frame_pred_dct_tab[i] = 1;
  385.       }
  386.   }
  387.   if (prog_seq && !repeatfirst && topfirst)
  388.   {
  389.     if (!quiet)
  390.       fprintf(stderr,"Warning: setting top_field_first = 0n");
  391.     topfirst = 0;
  392.   }
  393.   /* search windows */
  394.   for (i=0; i<M; i++)
  395.   {
  396.     if (motion_data[i].sxf > (4<<motion_data[i].forw_hor_f_code)-1)
  397.     {
  398.       if (!quiet)
  399.         fprintf(stderr,
  400.           "Warning: reducing forward horizontal search width to %dn",
  401.           (4<<motion_data[i].forw_hor_f_code)-1);
  402.       motion_data[i].sxf = (4<<motion_data[i].forw_hor_f_code)-1;
  403.     }
  404.     if (motion_data[i].syf > (4<<motion_data[i].forw_vert_f_code)-1)
  405.     {
  406.       if (!quiet)
  407.         fprintf(stderr,
  408.           "Warning: reducing forward vertical search width to %dn",
  409.           (4<<motion_data[i].forw_vert_f_code)-1);
  410.       motion_data[i].syf = (4<<motion_data[i].forw_vert_f_code)-1;
  411.     }
  412.     if (i!=0)
  413.     {
  414.       if (motion_data[i].sxb > (4<<motion_data[i].back_hor_f_code)-1)
  415.       {
  416.         if (!quiet)
  417.           fprintf(stderr,
  418.             "Warning: reducing backward horizontal search width to %dn",
  419.             (4<<motion_data[i].back_hor_f_code)-1);
  420.         motion_data[i].sxb = (4<<motion_data[i].back_hor_f_code)-1;
  421.       }
  422.       if (motion_data[i].syb > (4<<motion_data[i].back_vert_f_code)-1)
  423.       {
  424.         if (!quiet)
  425.           fprintf(stderr,
  426.             "Warning: reducing backward vertical search width to %dn",
  427.             (4<<motion_data[i].back_vert_f_code)-1);
  428.         motion_data[i].syb = (4<<motion_data[i].back_vert_f_code)-1;
  429.       }
  430.     }
  431.   }
  432. }
  433. static void readquantmat()
  434. {
  435.   int i,v;
  436.   FILE *fd;
  437.   if (iqname[0]=='-')
  438.   {
  439.     /* use default intra matrix */
  440.     load_iquant = 0;
  441.     for (i=0; i<64; i++)
  442.       intra_q[i] = default_intra_quantizer_matrix[i];
  443.   }
  444.   else
  445.   {
  446.     /* read customized intra matrix */
  447.     load_iquant = 1;
  448.     if (!(fd = fopen(iqname,"r")))
  449.     {
  450.       sprintf(errortext,"Couldn't open quant matrix file %s",iqname);
  451.       error(errortext);
  452.     }
  453.     for (i=0; i<64; i++)
  454.     {
  455.       fscanf(fd,"%d",&v);
  456.       if (v<1 || v>255)
  457.         error("invalid value in quant matrix");
  458.       intra_q[i] = v;
  459.     }
  460.     fclose(fd);
  461.   }
  462.   if (niqname[0]=='-')
  463.   {
  464.     /* use default non-intra matrix */
  465.     load_niquant = 0;
  466.     for (i=0; i<64; i++)
  467.       inter_q[i] = 16;
  468.   }
  469.   else
  470.   {
  471.     /* read customized non-intra matrix */
  472.     load_niquant = 1;
  473.     if (!(fd = fopen(niqname,"r")))
  474.     {
  475.       sprintf(errortext,"Couldn't open quant matrix file %s",niqname);
  476.       error(errortext);
  477.     }
  478.     for (i=0; i<64; i++)
  479.     {
  480.       fscanf(fd,"%d",&v);
  481.       if (v<1 || v>255)
  482.         error("invalid value in quant matrix");
  483.       inter_q[i] = v;
  484.     }
  485.     fclose(fd);
  486.   }
  487. }