Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

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