4 ** $VER: mpegutil.c 1.11 (1.11.97)
5 ** mpegvideo.datatype 1.11
7 ** mpeg utility functions
9 ** Written 1996/1997 by Roland 'Gizzy' Mainz
16 #include <aros/debug.h>
23 /* project includes */
24 #include "mpegvideo.h"
25 #include "mpegproto.h"
28 /* Bit masks used by bit i/o operations. */
32 0x00000000, 0x80000000, 0xc0000000, 0xe0000000,
33 0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000,
34 0xff000000, 0xff800000, 0xffc00000, 0xffe00000,
35 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000,
36 0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000,
37 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00,
38 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0,
39 0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe,
47 0xffffffff, 0x7fffffff, 0x3fffffff, 0x1fffffff,
48 0x0fffffff, 0x07ffffff, 0x03ffffff, 0x01ffffff,
49 0x00ffffff, 0x007fffff, 0x003fffff, 0x001fffff,
50 0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff,
51 0x0000ffff, 0x00007fff, 0x00003fff, 0x00001fff,
52 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff,
53 0x000000ff, 0x0000007f, 0x0000003f, 0x0000001f,
54 0x0000000f, 0x00000007, 0x00000003, 0x00000001,
62 0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8,
63 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80,
64 0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800,
65 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000,
66 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000,
67 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000,
68 0xff000000, 0xfe000000, 0xfc000000, 0xf8000000,
69 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000,
77 0x80000000, 0x40000000, 0x20000000, 0x10000000,
78 0x08000000, 0x04000000, 0x02000000, 0x01000000,
79 0x00800000, 0x00400000, 0x00200000, 0x00100000,
80 0x00080000, 0x00040000, 0x00020000, 0x00010000,
81 0x00008000, 0x00004000, 0x00002000, 0x00001000,
82 0x00000800, 0x00000400, 0x00000200, 0x00000100,
83 0x00000080, 0x00000040, 0x00000020, 0x00000010,
84 0x00000008, 0x00000004, 0x00000002, 0x00000001,
90 *--------------------------------------------------------------
92 * correct_underflow --
94 * Called when buffer does not have sufficient data to
95 * satisfy request for bits.
96 * Calls get_more_data, an application specific routine
97 * required to fill the buffer with more data.
103 * buf_length and buffer fields in curVidStream structure
106 *--------------------------------------------------------------
110 void correct_underflow( struct MPEGVideoInstData
*mvid
)
114 D(bug("[mpegvideo.datatype] %s()\n", __PRETTY_FUNCTION__
));
116 status
= get_more_data( mvid
, (curVidStream
-> buf_start
), (curVidStream
-> max_buf_length
), (int *)(&bufLength
), (unsigned int **)(&bitBuffer
) );
120 error_printf( mvid
, "Unexpected read error (status = %x).\n", status
);
122 myexit( mvid
, RETURN_ERROR
, ERROR_SEEK_ERROR
);
126 if( (status
== 0) && (bufLength
< 1) )
128 error_printf( mvid
, "\nImproper or missing sequence end code. Done ! (status=%x, bufLength = %d)\n", status
, bufLength
);
130 myexit( mvid
, RETURN_WARN
, ERROR_SEEK_ERROR
);
134 curBits
= *bitBuffer
<< bitOffset
;
139 *--------------------------------------------------------------
143 * Compares next num bits to low order position in mask.
144 * Buffer pointer is NOT advanced.
147 * TRUE, FALSE, or error code.
152 *--------------------------------------------------------------
156 int next_bits( struct MPEGVideoInstData
*mvid
, int num
, unsigned int mask
)
160 /* Get next num bits, no buffer pointer advance. */
161 show_bitsn( num
, stream
);
163 /* Compare bit stream and mask. Set return value to TRUE if equal, FALSE if differs. */
164 return( (int)(mask
== stream
) );
169 *--------------------------------------------------------------
173 * Assumes that bit stream is at begining of extension
174 * data. Parses off extension data into dynamically
175 * allocated space until start code is hit.
178 * Pointer to dynamically allocated memory containing
182 * Bit stream irreversibly parsed.
184 *--------------------------------------------------------------
188 char *get_ext_data( struct MPEGVideoInstData
*mvid
)
195 D(bug("[mpegvideo.datatype] %s()\n", __PRETTY_FUNCTION__
));
197 /* Set initial ext data buffer size. */
200 /* Allocate ext data buffer. */
201 dataPtr
= (char *)mymalloc( mvid
, size
);
203 /* Initialize marker to keep place in ext data buffer. */
206 /* While next data is not start code... */
207 while( !next_bits( mvid
, 24, 0x000001 ) )
209 /* Get next byte of ext data. */
212 /* Put ext data into ext data buffer. Advance marker. */
213 dataPtr
[ marker
] = (char)data
;
216 /* If end of ext data buffer reached, resize data buffer. */
219 size
+= EXT_BUF_SIZE
;
220 dataPtr
= (char *)myrealloc( mvid
, dataPtr
, size
);
224 /* Realloc data buffer to free any extra space. */
225 dataPtr
= (char *)myrealloc( mvid
, dataPtr
, marker
);
227 /* Return pointer to ext data buffer. */
233 *--------------------------------------------------------------
237 * Parses off bitstream until start code reached. When done
238 * next 4 bytes of bitstream will be start code. Bit offset
245 * Bit stream irreversibly parsed.
247 *--------------------------------------------------------------
251 int next_start_code( struct MPEGVideoInstData
*mvid
)
257 D(bug("[mpegvideo.datatype] %s()\n", __PRETTY_FUNCTION__
));
259 /* If insufficient buffer length, correct underflow. */
260 if( bufLength
< SSP
)
262 correct_underflow( mvid
);
265 /* If bit offset not zero, reset and advance buffer pointer. */
266 byteoff
= bitOffset
% CHAR_BIT
;
270 /* Align to byte boundary */
271 flush_bits( (CHAR_BIT
- byteoff
) );
274 /* Set state = 0U. */
277 /* While buffer has data ... */
278 while( bufLength
> 0 )
280 /* If insufficient data exists, correct underflow. */
281 if( bufLength
< SSP
)
283 correct_underflow( mvid
);
286 /* If next byte is zero... */
291 /* If state < 2U, advance state. */
297 /* If next byte is one... */
302 /* If (state == 2U), advance state (state = 3U) (i.e. start code found),
303 * otherwise, reset state to zero.
305 state
= (state
== 2U)?(3U):(0U);
309 /* Otherwise byte is neither 1 or 0, reset state to 0U. */
314 /* If state == 3U (i.e. start code found)... */
317 /* Set buffer pointer back and reset length & bit offsets so next bytes will be beginning of start code. */
318 bitOffset
= bitOffset
- 24;
322 bitOffset
= 32 + bitOffset
;
327 curBits
= *bitBuffer
<< bitOffset
;
329 D(bug("[mpegvideo.datatype] %s: ok\n", __PRETTY_FUNCTION__
));
330 /* Return success. */
335 D(bug("[mpegvideo.datatype] %s: underflow\n", __PRETTY_FUNCTION__
));
336 /* Return underflow error. */
342 *--------------------------------------------------------------
344 * get_extra_bit_info --
346 * Parses off extra bit info stream into dynamically
347 * allocated memory. Extra bit info is indicated by
348 * a flag bit set to 1, followed by 8 bits of data.
349 * This continues until the flag bit is zero. Assumes
350 * that bit stream set to first flag bit in extra
354 * Pointer to dynamically allocated memory with extra
355 * bit info in it. Flag bits are NOT included.
358 * Bit stream irreversibly parsed.
360 *--------------------------------------------------------------
364 char *get_extra_bit_info( struct MPEGVideoInstData
*mvid
)
371 D(bug("[mpegvideo.datatype] %s()\n", __PRETTY_FUNCTION__
));
373 /* Get first flag bit. */
376 /* If flag is false, return NULL pointer (i.e. no extra bit info). */
382 /* Initialize size of extra bit info buffer and allocate. */
384 dataPtr
= (char *)mymalloc( mvid
, size
);
386 /* Reset marker to hold place in buffer. */
389 /* While flag bit is true. */
392 /* Get next 8 bits of data. */
395 /* Place in extra bit info buffer. */
396 dataPtr
[ marker
] = (char)data
;
399 /* If buffer is full, reallocate. */
402 size
+= EXT_BUF_SIZE
;
403 dataPtr
= (char *)myrealloc( mvid
, dataPtr
, size
);
406 /* Get next flag bit. */
410 /* Reallocate buffer to free extra space. */
411 dataPtr
= (char *)myrealloc( mvid
, dataPtr
, marker
);
413 /* Return pointer to extra bit info buffer. */
418 long stream_pos( struct MPEGVideoInstData
*mvid
)
420 return( (long)(((mvid
-> mvid_ReadMarkPos
) + ((UBYTE
*)bitBuffer
- (mvid
-> mvid_ReadMark
))) + (bitOffset
/ CHAR_BIT
)) );