1 /*
2  * util.c --
3  *
4  *      Miscellaneous utility procedures.
5  *
6  */
7 
8 /*
9  * Copyright (c) 1995 The Regents of the University of California.
10  * All rights reserved.
11  *
12  * Permission to use, copy, modify, and distribute this software and its
13  * documentation for any purpose, without fee, and without written agreement is
14  * hereby granted, provided that the above copyright notice and the following
15  * two paragraphs appear in all copies of this software.
16  *
17  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
18  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
19  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
20  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21  *
22  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
23  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
24  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
25  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
26  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
27  */
28 
29 /*
30  * Portions of this software Copyright (c) 1995 Brown University.
31  * All rights reserved.
32  *
33  * Permission to use, copy, modify, and distribute this software and its
34  * documentation for any purpose, without fee, and without written agreement
35  * is hereby granted, provided that the above copyright notice and the
36  * following two paragraphs appear in all copies of this software.
37  *
38  * IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR
39  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
40  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN
41  * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42  *
43  * BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
44  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
45  * PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
46  * BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
47  * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
48  */
49 
50 #include "MPEG.h"
51 
52 #include <stdlib.h>
53 #include "video.h"
54 #include "proto.h"
55 #include "util.h"
56 #ifndef NOCONTROLS
57 #include "ctrlbar.h"
58 #endif
59 
60 /*
61    Changes to make the code reentrant:
62      de-globalized: totNumFrames, realTimeStart, vid_stream, sys_layer,
63         bitOffset, bitLength, bitBuffer, curVidStream
64      setjmp/longjmp replaced
65 
66    Additional changes:
67      only call DestroyVidStream up in mpegVidRsrc, not in correct_underflow
68 
69    -lsh@cs.brown.edu (Loring Holden)
70  */
71 
72 /* Bit masks used by bit i/o operations. */
73 
74 unsigned int nBitMask[] = { 0x00000000, 0x80000000, 0xc0000000, 0xe0000000,
75 			    0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000,
76 			    0xff000000, 0xff800000, 0xffc00000, 0xffe00000,
77 			    0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000,
78 			    0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000,
79 			    0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00,
80 			    0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0,
81 			    0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe};
82 
83 unsigned int bitMask[] = {  0xffffffff, 0x7fffffff, 0x3fffffff, 0x1fffffff,
84 			    0x0fffffff, 0x07ffffff, 0x03ffffff, 0x01ffffff,
85 			    0x00ffffff, 0x007fffff, 0x003fffff, 0x001fffff,
86 			    0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff,
87 			    0x0000ffff, 0x00007fff, 0x00003fff, 0x00001fff,
88 			    0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff,
89 			    0x000000ff, 0x0000007f, 0x0000003f, 0x0000001f,
90 			    0x0000000f, 0x00000007, 0x00000003, 0x00000001};
91 
92 unsigned int rBitMask[] = { 0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8,
93 			    0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80,
94 			    0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800,
95 			    0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000,
96 			    0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000,
97 			    0xfff00000, 0xffe00000, 0xffc00000, 0xff800000,
98 			    0xff000000, 0xfe000000, 0xfc000000, 0xf8000000,
99 			    0xf0000000, 0xe0000000, 0xc0000000, 0x80000000};
100 
101 unsigned int bitTest[] = {  0x80000000, 0x40000000, 0x20000000, 0x10000000,
102 			    0x08000000, 0x04000000, 0x02000000, 0x01000000,
103 			    0x00800000, 0x00400000, 0x00200000, 0x00100000,
104 			    0x00080000, 0x00040000, 0x00020000, 0x00010000,
105 			    0x00008000, 0x00004000, 0x00002000, 0x00001000,
106 			    0x00000800, 0x00000400, 0x00000200, 0x00000100,
107 			    0x00000080, 0x00000040, 0x00000020, 0x00000010,
108 			    0x00000008, 0x00000004, 0x00000002, 0x00000001};
109 
110 
111 /*
112  *--------------------------------------------------------------
113  *
114  * correct_underflow --
115  *
116  *	Called when buffer does not have sufficient data to
117  *      satisfy request for bits.
118  *      Calls get_more_data, an application specific routine
119  *      required to fill the buffer with more data.
120  *
121  * Results:
122  *      None really.
123  *
124  * Side effects:
125  *	buf_length and buffer fields may be changed.
126  *
127  *--------------------------------------------------------------
128  */
129 
correct_underflow(VidStream * vid_stream)130 void correct_underflow( VidStream* vid_stream )
131 {
132   int status;
133 
134   status = get_more_data(vid_stream);
135 
136   if (status  < 0) {
137     if (!quietFlag) {
138       fprintf (stderr, "\n");
139       perror("Unexpected read error.");
140     }
141     exit(1);
142   }
143   else if ((status == 0) && (vid_stream->buf_length < 1)) {
144     if (!quietFlag) {
145       fprintf(stderr, "\nImproper or missing sequence end code.\n");
146     }
147 #ifdef ANALYSIS
148     PrintAllStats(vid_stream);
149 #endif
150 
151     vid_stream->film_has_ended=TRUE;
152     return;
153   }
154 #ifdef UTIL2
155   vid_stream->curBits = *vid_stream->buffer << vid_stream->bit_offset;
156 #else
157   vid_stream->curBits = *vid_stream->buffer;
158 #endif
159 
160 }
161 
162 
163 /*
164  *--------------------------------------------------------------
165  *
166  * next_bits --
167  *
168  *	Compares next num bits to low order position in mask.
169  *      Buffer pointer is NOT advanced.
170  *
171  * Results:
172  *	TRUE, FALSE, or error code.
173  *
174  * Side effects:
175  *	None.
176  *
177  *--------------------------------------------------------------
178  */
179 
next_bits(int num,unsigned int mask,VidStream * vid_stream)180 int next_bits( int num, unsigned int mask, VidStream* vid_stream )
181 {
182   unsigned int stream;
183   int ret_value;
184 
185 #if 0
186   /* If no current stream, return error. */
187   if (vid_stream == NULL)
188     return NO_VID_STREAM;
189 #endif
190 
191   /* Get next num bits, no buffer pointer advance. */
192 
193   show_bitsn(num, stream);
194 
195   /* Compare bit stream and mask. Set return value toTRUE if equal, FALSE if
196      differs.
197   */
198 
199   if (mask == stream) {
200     ret_value = TRUE;
201   } else ret_value = FALSE;
202 
203   /* Return return value. */
204   return ret_value;
205 }
206 
207 
208 /*
209  *--------------------------------------------------------------
210  *
211  * get_ext_data --
212  *
213  *	Assumes that bit stream is at begining of extension
214  *      data. Parses off extension data into dynamically
215  *      allocated space until start code is hit.
216  *
217  * Results:
218  *	Pointer to dynamically allocated memory containing
219  *      extension data.
220  *
221  * Side effects:
222  *	Bit stream irreversibly parsed.
223  *
224  *--------------------------------------------------------------
225  */
226 
get_ext_data(VidStream * vid_stream)227 char* get_ext_data( VidStream* vid_stream )
228 {
229   unsigned int size, marker;
230   char *dataPtr;
231   unsigned int data;
232 
233   /* Set initial ext data buffer size. */
234 
235   size = EXT_BUF_SIZE;
236 
237   /* Allocate ext data buffer. */
238 
239   dataPtr = (char *) malloc(size);
240 
241   /* Initialize marker to keep place in ext data buffer. */
242 
243   marker = 0;
244 
245   /* While next data is not start code... */
246   while (!next_bits(24, 0x000001, vid_stream)) {
247 
248     /* Get next byte of ext data. */
249 
250     get_bits8(data);
251 
252     /* Put ext data into ext data buffer. Advance marker. */
253 
254     dataPtr[marker] = (char) data;
255     marker++;
256 
257     /* If end of ext data buffer reached, resize data buffer. */
258 
259     if (marker == size) {
260       size += EXT_BUF_SIZE;
261       dataPtr = (char *) realloc(dataPtr, size);
262     }
263   }
264 
265   /* Realloc data buffer to free any extra space. */
266 
267   dataPtr = (char *) realloc(dataPtr, marker);
268 
269   /* Return pointer to ext data buffer. */
270   return dataPtr;
271 }
272 
273 
274 /*
275  *--------------------------------------------------------------
276  *
277  * next_start_code --
278  *
279  *	Parses off bitstream until start code reached. When done
280  *      next 4 bytes of bitstream will be start code. Bit offset
281  *      reset to 0.
282  *
283  * Results:
284  *	Status code.
285  *
286  * Side effects:
287  *	Bit stream irreversibly parsed.
288  *
289  *--------------------------------------------------------------
290  */
291 
next_start_code(VidStream * vid_stream)292 int next_start_code( VidStream* vid_stream )
293 {
294   int state;
295   int byteoff;
296   unsigned int data;
297 
298 #if 0
299   /* If no current stream, return error. */
300   if (vid_stream== NULL)
301     return NO_VID_STREAM;
302 #endif
303 
304   /* If insufficient buffer length, correct underflow. */
305 
306   if (vid_stream->buf_length < 4) {
307     correct_underflow(vid_stream);
308   }
309 
310   /* If bit offset not zero, reset and advance buffer pointer. */
311 
312   byteoff = vid_stream->bit_offset % 8;
313 
314   if (byteoff != 0) {
315     flush_bits((8-byteoff));
316   }
317 
318   /* Set state = 0. */
319 
320   state = 0;
321 
322   /* While buffer has data ... */
323 
324   while(vid_stream->buf_length > 0) {
325 
326     /* If insufficient data exists, correct underflow. */
327 
328 
329     if (vid_stream->buf_length < 4) {
330       correct_underflow(vid_stream);
331     }
332 
333     /* If next byte is zero... */
334 
335     get_bits8(data);
336 
337     if (data == 0) {
338 
339       /* If state < 2, advance state. */
340 
341       if (state < 2) state++;
342     }
343 
344     /* If next byte is one... */
345 
346     else if (data == 1) {
347 
348       /* If state == 2, advance state (i.e. start code found). */
349 
350       if (state == 2) state++;
351 
352       /* Otherwise, reset state to zero. */
353 
354       else state = 0;
355     }
356 
357     /* Otherwise byte is neither 1 or 0, reset state to 0. */
358 
359     else {
360       state = 0;
361     }
362 
363     /* If state == 3 (i.e. start code found)... */
364 
365     if (state == 3) {
366 
367       /* Set buffer pointer back and reset length & bit offsets so
368        * next bytes will be beginning of start code.
369        */
370 
371       vid_stream->bit_offset = vid_stream->bit_offset - 24;
372 
373 #ifdef ANALYSIS
374       bitCount -= 24;
375 #endif
376 
377       if (vid_stream->bit_offset < 0) {
378         vid_stream->bit_offset = 32 + vid_stream->bit_offset;
379         vid_stream->buf_length++;
380         vid_stream->buffer--;
381 #ifdef UTIL2
382         vid_stream->curBits = *vid_stream->buffer << vid_stream->bit_offset;
383 #else
384         vid_stream->curBits = *vid_stream->buffer;
385 #endif
386       }
387       else {
388 #ifdef UTIL2
389         vid_stream->curBits = *vid_stream->buffer << vid_stream->bit_offset;
390 #else
391         vid_stream->curBits = *vid_stream->buffer;
392 #endif
393       }
394 
395 #ifdef NO_GRIFF_MODS
396       /* Return success. */
397       return OK;
398 #else /* NO_GRIFF_MODS */
399       show_bits32(data);
400       if ( data==SEQ_START_CODE ||
401 	   data==GOP_START_CODE ||
402 	   data==PICTURE_START_CODE ||
403 	   (data>=SLICE_MIN_START_CODE && data<=SLICE_MAX_START_CODE) ||
404 	   data==EXT_START_CODE ||
405 	   data==USER_START_CODE )
406       {
407         /* Return success. */
408         return OK;
409       }
410       else
411       {
412 	flush_bits32;
413       }
414 #endif /* NO_GRIFF_MODS */
415     }
416   }
417 
418   /* Return underflow error. */
419   return STREAM_UNDERFLOW;
420 }
421 
422 
423 /*
424  *--------------------------------------------------------------
425  *
426  * get_extra_bit_info --
427  *
428  *	Parses off extra bit info stream into dynamically
429  *      allocated memory. Extra bit info is indicated by
430  *      a flag bit set to 1, followed by 8 bits of data.
431  *      This continues until the flag bit is zero. Assumes
432  *      that bit stream set to first flag bit in extra
433  *      bit info stream.
434  *
435  * Results:
436  *	Pointer to dynamically allocated memory with extra
437  *      bit info in it. Flag bits are NOT included.
438  *
439  * Side effects:
440  *	Bit stream irreversibly parsed.
441  *
442  *--------------------------------------------------------------
443  */
444 
get_extra_bit_info(VidStream * vid_stream)445 char* get_extra_bit_info( VidStream* vid_stream )
446 {
447   unsigned int size, marker;
448   char *dataPtr;
449   unsigned int data;
450 
451   /* Get first flag bit. */
452   get_bits1(data);
453 
454   /* If flag is false, return NULL pointer (i.e. no extra bit info). */
455 
456   if (!data) return NULL;
457 
458   /* Initialize size of extra bit info buffer and allocate. */
459 
460   size = EXT_BUF_SIZE;
461   dataPtr = (char *) malloc(size);
462 
463   /* Reset marker to hold place in buffer. */
464 
465   marker = 0;
466 
467   /* While flag bit is true. */
468 
469   while (data) {
470 
471     /* Get next 8 bits of data. */
472     get_bits8(data);
473 
474     /* Place in extra bit info buffer. */
475 
476     dataPtr[marker] = (char) data;
477     marker++;
478 
479     /* If buffer is full, reallocate. */
480 
481     if (marker == size) {
482       size += EXT_BUF_SIZE;
483       dataPtr = (char *) realloc(dataPtr, size);
484     }
485 
486     /* Get next flag bit. */
487     get_bits1(data);
488   }
489 
490   /* Reallocate buffer to free extra space. */
491 
492   dataPtr = (char *) realloc(dataPtr, marker);
493 
494   /* Return pointer to extra bit info buffer. */
495   return dataPtr;
496 }
497 
498 
499 /* EOF */
500