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