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

C/C++

  1. /* #define DEBUG */
  2. /* subspic.c, Frame buffer substitution routines */
  3. /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
  4. /*
  5.  * Disclaimer of Warranty
  6.  *
  7.  * These software programs are available to the user without any license fee or
  8.  * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
  9.  * any and all warranties, whether express, implied, or statuary, including any
  10.  * implied warranties or merchantability or of fitness for a particular
  11.  * purpose.  In no event shall the copyright-holder be liable for any
  12.  * incidental, punitive, or consequential damages of any kind whatsoever
  13.  * arising from the use of these programs.
  14.  *
  15.  * This disclaimer of warranty extends to the user of these programs and user's
  16.  * customers, employees, agents, transferees, successors, and assigns.
  17.  *
  18.  * The MPEG Software Simulation Group does not represent or warrant that the
  19.  * programs furnished hereunder are free of infringement of any third-party
  20.  * patents.
  21.  *
  22.  * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
  23.  * are subject to royalty fees to patent holders.  Many of these patents are
  24.  * general enough such that they are unavoidable regardless of implementation
  25.  * design.
  26.  *
  27.  */
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <fcntl.h>
  31. #include "config.h"
  32. #include "global.h"
  33. /* private prototypes*/
  34. static void Read_Frame _ANSI_ARGS_((char *filename, 
  35.   unsigned char *frame_buffer[], int framenum));
  36. static void Copy_Frame _ANSI_ARGS_((unsigned char *src, unsigned char *dst, 
  37.   int width, int height, int parity, int incr));
  38. static int Read_Components _ANSI_ARGS_ ((char *filename, 
  39.   unsigned char *frame[3], int framenum));
  40. static int Read_Component _ANSI_ARGS_ ((char *fname, unsigned char *frame, 
  41.   int width, int height));
  42. static int Extract_Components _ANSI_ARGS_ ((char *filename,
  43.   unsigned char *frame[3], int framenum));
  44. /* substitute frame buffer routine */
  45. void Substitute_Frame_Buffer (bitstream_framenum, sequence_framenum)
  46. int bitstream_framenum;
  47. int sequence_framenum;
  48. {
  49.   /* static tracking variables */
  50.   static int previous_temporal_reference;
  51.   static int previous_bitstream_framenum;
  52.   static int previous_anchor_temporal_reference;
  53.   static int previous_anchor_bitstream_framenum;
  54.   static int previous_picture_coding_type;
  55.   static int bgate;
  56.   
  57.   /* local temporary variables */
  58.   int substitute_display_framenum;
  59. #ifdef DEBUG
  60.   printf("SUB: seq fn(%d) bitfn(%d) tempref(%d) picstr(%d) type(%d)n", 
  61.     sequence_framenum, bitstream_framenum, temporal_reference, 
  62.     picture_structure, picture_coding_type);
  63. #endif
  64.   /* we don't substitute at the first picture of a sequence */
  65.   if((sequence_framenum!=0)||(Second_Field))
  66.   {
  67.     /* only at the start of the frame */
  68.     if ((picture_structure==FRAME_PICTURE)||(!Second_Field))
  69.     {
  70.       if(picture_coding_type==P_TYPE)
  71.       {
  72.         /* the most recently decoded reference frame needs substituting */
  73.         substitute_display_framenum = bitstream_framenum - 1;
  74.         
  75.         Read_Frame(Substitute_Picture_Filename, forward_reference_frame, 
  76.           substitute_display_framenum);
  77.       }
  78.       /* only the first B frame in a consequitve set of B pictures
  79.          loads a substitute backward_reference_frame since all subsequent
  80.          B frames predict from the same reference pictures */
  81.       else if((picture_coding_type==B_TYPE)&&(bgate!=1))
  82.       {
  83.         substitute_display_framenum = 
  84.           (previous_temporal_reference - temporal_reference) 
  85.             + bitstream_framenum - 1;
  86.         Read_Frame(Substitute_Picture_Filename, backward_reference_frame, 
  87.           substitute_display_framenum);
  88.       }
  89.     } /* P fields can predict from the two most recently decoded fields, even
  90.          from the first field of the same frame being decoded */
  91.     else if(Second_Field && (picture_coding_type==P_TYPE))
  92.     {
  93.       /* our favourite case: the IP field picture pair */
  94.       if((previous_picture_coding_type==I_TYPE)&&(picture_coding_type==P_TYPE))
  95.       {
  96.         substitute_display_framenum = bitstream_framenum;
  97.       }
  98.       else /* our more generic P field picture pair */
  99.       {
  100.         substitute_display_framenum = 
  101.           (temporal_reference - previous_anchor_temporal_reference) 
  102.             + bitstream_framenum - 1;
  103.       }
  104.       Read_Frame(Substitute_Picture_Filename, current_frame, substitute_display_framenum);
  105.     }
  106. #ifdef DEBUG
  107.     else if((picture_coding_type!=B_TYPE)||(picture_coding_type!=D_TYPE))
  108.     {
  109.       printf("NO SUBS FOR THIS PICTUREn");
  110.     }
  111. #endif
  112.   }
  113.   /* set b gate so we don't redundantly load next time around */
  114.   if(picture_coding_type==B_TYPE)
  115.     bgate = 1;
  116.   else
  117.     bgate = 0;
  118.   /* update general tracking variables */
  119.   if((picture_structure==FRAME_PICTURE)||(!Second_Field))
  120.   {
  121.     previous_temporal_reference  = temporal_reference;
  122.     previous_bitstream_framenum  = bitstream_framenum;
  123.   }
  124.   
  125.   /* update reference frame tracking variables */
  126.   if((picture_coding_type!=B_TYPE) && 
  127.     ((picture_structure==FRAME_PICTURE)||Second_Field))
  128.   {
  129.     previous_anchor_temporal_reference  = temporal_reference;
  130.     previous_anchor_bitstream_framenum  = bitstream_framenum;
  131.   }
  132.   previous_picture_coding_type = picture_coding_type;
  133. }
  134. /* Note: fields are only read to serve as the same-frame reference for 
  135.    a second field */
  136. static void Read_Frame(fname,frame,framenum)
  137. char *fname;
  138. unsigned char *frame[];
  139. int framenum;
  140. {
  141.   int parity;
  142.   int rerr = 0;
  143.   int field_mode;
  144.   if(framenum<0)
  145.     printf("ERROR: framenum (%d) is less than zeron", framenum);
  146.   if(Big_Picture_Flag)
  147.     rerr = Extract_Components(fname, substitute_frame, framenum);
  148.   else
  149.     rerr = Read_Components(fname, substitute_frame, framenum);
  150.   if(rerr!=0)
  151.   {
  152.     printf("was unable to substitute framen");
  153.   }
  154.   /* now copy to the appropriate buffer */
  155.   /* first field (which we are attempting to substitute) must be
  156.      of opposite field parity to the current one */
  157.   if((Second_Field)&&(picture_coding_type==P_TYPE))
  158.   {
  159.     parity      = (picture_structure==TOP_FIELD ? 1:0);      
  160.     field_mode  = (picture_structure==FRAME_PICTURE ? 0:1);
  161.   }
  162.   else
  163.   {
  164.     /* Like frame structued pictures, B pictures only substitute an entire frame 
  165.        since both fields always predict from the same frame (with respect 
  166.        to forward/backwards directions) */
  167.     parity = 0;
  168.     field_mode = 0;
  169.   }
  170.   Copy_Frame(substitute_frame[0], frame[0], Coded_Picture_Width, 
  171.     Coded_Picture_Height, parity, field_mode);
  172.   
  173.   Copy_Frame(substitute_frame[1], frame[1], Chroma_Width, Chroma_Height, 
  174.     parity, field_mode);
  175.   
  176.   Copy_Frame(substitute_frame[2], frame[2], Chroma_Width, Chroma_Height,
  177.     parity, field_mode);
  178. #ifdef VERBOSE
  179.   if(Verbose_Flag > NO_LAYER)
  180.     printf("substituted %s %dn",
  181.       (field_mode ? (parity?"bottom field":"bottom field"):"frame"), framenum);
  182. #endif
  183. }
  184. static int Read_Components(filename, frame, framenum) 
  185. char *filename;
  186. unsigned char *frame[3];
  187. int framenum;
  188. {
  189.   int err = 0;
  190.   char outname[FILENAME_LENGTH];
  191.   char name[FILENAME_LENGTH];
  192.   sprintf(outname,filename,framenum);
  193.   sprintf(name,"%s.Y",outname);
  194.   err += Read_Component(name, frame[0], Coded_Picture_Width, 
  195.     Coded_Picture_Height);
  196.   sprintf(name,"%s.U",outname);
  197.   err += Read_Component(name, frame[1], Chroma_Width, Chroma_Height);
  198.   sprintf(name,"%s.V",outname);
  199.   err += Read_Component(name, frame[2], Chroma_Width, Chroma_Height);
  200.   return(err);
  201. }
  202. static int Read_Component(Filename, Frame, Width, Height)
  203. char *Filename;
  204. unsigned char *Frame;
  205. int Width;
  206. int Height;
  207. {
  208.   int Size;
  209.   int Bytes_Read;
  210.   int Infile;
  211.   Size = Width*Height;
  212. #ifdef DEBUG
  213.   printf("SUBS: reading %sn", filename);
  214. #endif
  215.   if(!(Infile=open(Filename,O_RDONLY|O_BINARY))<0)
  216.   {
  217.     printf("ERROR: unable to open reference filename (%s)n", Filename);
  218. return(-1);
  219.   }
  220.   Bytes_Read = read(Infile, Frame, Size);
  221.   
  222.   if(Bytes_Read!=Size)
  223.   {
  224.     printf("was able to read only %d bytes of %d of file %sn",
  225.       Bytes_Read, Size, Filename);
  226.   }
  227.  
  228.   close(Infile); 
  229.   return(0);
  230. }
  231. /* optimization: do not open the big file each time. Open once at start
  232.    of decoder, and close at the very last frame */
  233. /* Note: "big" files were used in E-mail exchanges almost exclusively by the 
  234.    MPEG Committee's syntax validation and conformance ad-hoc groups from 
  235.    the year 1993 until 1995 */
  236. static int Extract_Components(filename, frame, framenum) 
  237. char *filename;
  238. unsigned char *frame[3];
  239. int framenum;
  240. {
  241. /*  int err = 0; */
  242.   FILE *fd;
  243.   int line;
  244.   int size, offset;
  245.   if (!(fd = fopen(filename,"rb")))
  246.   {
  247.     sprintf(Error_Text,"Couldn't open %sn",filename);
  248.     return(-1);
  249.   }
  250.   /* compute size of each frame (in bytes) */
  251.   size = (Coded_Picture_Width*Coded_Picture_Height);
  252.   if(chroma_format==CHROMA444)
  253.     size = (size * 3);
  254.   else if(chroma_format==CHROMA422)
  255.     size = (size * 2);
  256.   else if(chroma_format==CHROMA420)
  257.     size = ((size*3)>>1);
  258.   else
  259.     printf("ERROR: chroma_format (%d) not recognizedn", chroma_format);
  260.   /* compute distance into "big" file */
  261.   offset = size*framenum;
  262. #ifdef DEBUG
  263.   printf("EXTRACTING: frame(%d) offset(%d), size (%d) from %sn", 
  264.     framenum, offset, size, filename);
  265. #endif
  266.   /* seek to location in big file where desired frame begins */
  267.   /* note: this offset cannot exceed a few billion bytes due to the */
  268.   /*       obvious limitations of 32-bit integers */
  269.   fseek(fd, offset, 0);
  270.   /* Y  */
  271.   for (line=0; line<Coded_Picture_Height; line++)
  272.   {
  273.     fread(frame[0]+(line*Coded_Picture_Width),1,Coded_Picture_Width,fd);
  274.   }
  275.   /* Cb */
  276.   for (line=0; line<Chroma_Height; line++)
  277.   {
  278.     fread(frame[1]+(line*Chroma_Width),1,Chroma_Width,fd);
  279.   }
  280.   /* Cr */
  281.   for (line=0; line<Chroma_Height; line++)
  282.   {
  283.     fread(frame[2]+(line*Chroma_Width),1,Chroma_Width,fd);
  284.   }
  285.   fclose(fd);
  286.   return(0);
  287. }
  288. static void Copy_Frame(src, dst, width, height, parity, field_mode)
  289. unsigned char *src;
  290. unsigned char *dst;
  291. int width;
  292. int height;
  293. int parity;        /* field parity (top or bottom) to overwrite */
  294. int field_mode;    /* 0 = frame, 1 = field                      */
  295. {
  296.   int row, col;
  297.   int s, d;
  298.   int incr;
  299.   s = d = 0;
  300. #ifdef DEBUG
  301.   printf("COPYING (w=%d, h=%d, parity=%d, field_mode=%d)n",
  302.     width,height,parity,field_mode);
  303. #endif /* DEBUG */
  304.   if(field_mode)
  305.   {
  306.     incr = 2;
  307.     if(parity==0)
  308.       s += width;
  309.   }
  310.   else
  311.   {
  312.     incr = 1;
  313.   }
  314.   for(row=0; row<height; row+=incr) 
  315.   {
  316.     for(col=0; col<width; col++)
  317.     {
  318.       dst[d+col] = src[s+col];
  319.     }
  320.     
  321.     d += (width*incr);
  322.     s += (width*incr);
  323.   }
  324. }