git.y1.nz

fbui

Framebuffer-based graphical environment
download: https://git.y1.nz/archives/fbui.tar.gz
README | Files | Log | Refs

libfbui/MPEG/subspic.c

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

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.