202 lines
4.5 KiB
C
202 lines
4.5 KiB
C
|
/* 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 <io.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 */
|
||
|
}
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
|