Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/* getbits.c, bit level routines */
/*
* All modifications (mpeg2decode -> mpeg2play) are
* Copyright (C) 1996, Stefan Eckart. All Rights Reserved.
*/
/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
/*
* Disclaimer of Warranty
*
* These software programs are available to the user without any license fee or
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims
* any and all warranties, whether express, implied, or statuary, including any
* implied warranties or merchantability or of fitness for a particular
* purpose. In no event shall the copyright-holder be liable for any
* incidental, punitive, or consequential damages of any kind whatsoever
* arising from the use of these programs.
*
* This disclaimer of warranty extends to the user of these programs and user's
* customers, employees, agents, transferees, successors, and assigns.
*
* The MPEG Software Simulation Group does not represent or warrant that the
* programs furnished hereunder are free of infringement of any third-party
* patents.
*
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
* are subject to royalty fees to patent holders. Many of these patents are
* general enough such that they are unavoidable regardless of implementation
* design.
*
*/
#include <stdlib.h>
#include "drivers/glib.h"
#include "config.h"
#include "global.h"
/* initialize buffer, call once before first getbits or showbits */
void Initialize_Buffer
()
{
ld
->Incnt
= 0;
ld
->Rdptr
= ld
->Rdbfr
+ 2048;
ld
->Rdmax
= ld
->Rdptr
;
#ifdef VERIFY
/* only the verifier uses this particular bit counter
* Bitcnt keeps track of the current parser position with respect
* to the video elementary stream being decoded, regardless
* of whether or not it is wrapped within a systems layer stream
*/
ld
->Bitcnt
= 0;
#endif
ld
->Bfr
= 0;
Flush_Buffer
(0); /* fills valid data into bfr */
}
int read
(int Infile
, void *Rdbfr
, int rdsize
) {
if (ld
->actual_file_ptr
+ 2048 > ld
->end_file_ptr
)
rdsize
= (int)(ld
->end_file_ptr
- ld
->actual_file_ptr
);
if (rdsize
< 0) return 0;
memcpy(Rdbfr
,ld
->actual_file_ptr
,rdsize
);
ld
->actual_file_ptr
+= rdsize
;
return rdsize
;
}
void Fill_Buffer
()
{
int Buffer_Level
;
Buffer_Level
= read
(ld
->Infile
,ld
->Rdbfr
,2048);
ld
->Rdptr
= ld
->Rdbfr
;
if (System_Stream_Flag
)
ld
->Rdmax
-= 2048;
/* end of the bitstream file */
if (Buffer_Level
< 2048)
{
/* just to be safe */
if (Buffer_Level
< 0)
Buffer_Level
= 0;
/* pad until the next to the next 32-bit word boundary */
while (Buffer_Level
& 3)
ld
->Rdbfr
[Buffer_Level
++] = 0;
/* pad the buffer with sequence end codes */
while (Buffer_Level
< 2048)
{
ld
->Rdbfr
[Buffer_Level
++] = SEQUENCE_END_CODE
>>24;
ld
->Rdbfr
[Buffer_Level
++] = SEQUENCE_END_CODE
>>16;
ld
->Rdbfr
[Buffer_Level
++] = SEQUENCE_END_CODE
>>8;
ld
->Rdbfr
[Buffer_Level
++] = SEQUENCE_END_CODE
&0xff;
}
}
}
/* MPEG-1 system layer demultiplexer */
int Get_Byte
()
{
while(ld
->Rdptr
>= ld
->Rdbfr
+2048)
{
read
(ld
->Infile
,ld
->Rdbfr
,2048);
ld
->Rdptr
-= 2048;
ld
->Rdmax
-= 2048;
}
return *ld
->Rdptr
++;
}
/* extract a 16-bit word from the bitstream buffer */
int Get_Word
()
{
int Val
;
Val
= Get_Byte
();
return (Val
<<8) | Get_Byte
();
}
/* return next n bits (right adjusted) without advancing */
unsigned int Show_Bits
(N
)
int N
;
{
return ld
->Bfr
>> (32-N
);
}
/* return next bit (could be made faster than Get_Bits(1)) */
unsigned int Get_Bits1
()
{
return Get_Bits
(1);
}
/* advance by n bits */
void Flush_Buffer
(N
)
int N
;
{
int Incnt
;
ld
->Bfr
<<= N
;
Incnt
= ld
->Incnt
-= N
;
if (Incnt
<= 24)
{
if (System_Stream_Flag
&& (ld
->Rdptr
>= ld
->Rdmax
-4))
{
do
{
if (ld
->Rdptr
>= ld
->Rdmax
)
Next_Packet
();
ld
->Bfr
|= Get_Byte
() << (24 - Incnt
);
Incnt
+= 8;
}
while (Incnt
<= 24);
}
else if (ld
->Rdptr
< ld
->Rdbfr
+2044)
{
do
{
ld
->Bfr
|= *ld
->Rdptr
++ << (24 - Incnt
);
Incnt
+= 8;
}
while (Incnt
<= 24);
}
else
{
do
{
if (ld
->Rdptr
>= ld
->Rdbfr
+2048)
Fill_Buffer
();
ld
->Bfr
|= *ld
->Rdptr
++ << (24 - Incnt
);
Incnt
+= 8;
}
while (Incnt
<= 24);
}
ld
->Incnt
= Incnt
;
}
#ifdef VERIFY
ld
->Bitcnt
+= N
;
#endif /* VERIFY */
}
/* return next n bits (right adjusted) */
unsigned int Get_Bits
(N
)
int N
;
{
unsigned int Val
;
Val
= Show_Bits
(N
);
Flush_Buffer
(N
);
return Val
;
}