Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/* systems.c, systems-specific routines */
/* 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 <stdio.h>
#include <stdlib.h>
#include "config.h"
#include "global.h"
/* initialize buffer, call once before first getbits or showbits */
/* parse system layer, ignore everything we don't need */
void Next_Packet
()
{
unsigned int code
;
int l
;
for(;;)
{
code
= Get_Long
();
/* remove system layer byte stuffing */
while ((code
& 0xffffff00) != 0x100)
code
= (code
<<8) | Get_Byte
();
switch(code
)
{
case PACK_START_CODE
: /* pack header */
/* skip pack header (system_clock_reference and mux_rate) */
ld
->Rdptr
+= 8;
break;
case VIDEO_ELEMENTARY_STREAM
:
code
= Get_Word
(); /* packet_length */
ld
->Rdmax
= ld
->Rdptr
+ code
;
code
= Get_Byte
();
if((code
>>6)==0x02)
{
ld
->Rdptr
++;
code
=Get_Byte
(); /* parse PES_header_data_length */
ld
->Rdptr
+=code
; /* advance pointer by PES_header_data_length */
printf("MPEG-2 PES packet\n");
return;
}
else if(code
==0xff)
{
/* parse MPEG-1 packet header */
while((code
=Get_Byte
())== 0xFF);
}
/* stuffing bytes */
if(code
>=0x40)
{
if(code
>=0x80)
{
fprintf(stderr
,"Error in packet header\n");
exit(1);
}
/* skip STD_buffer_scale */
ld
->Rdptr
++;
code
= Get_Byte
();
}
if(code
>=0x30)
{
if(code
>=0x40)
{
fprintf(stderr
,"Error in packet header\n");
exit(1);
}
/* skip presentation and decoding time stamps */
ld
->Rdptr
+= 9;
}
else if(code
>=0x20)
{
/* skip presentation time stamps */
ld
->Rdptr
+= 4;
}
else if(code
!=0x0f)
{
fprintf(stderr
,"Error in packet header\n");
exit(1);
}
return;
case ISO_END_CODE
: /* end */
/* simulate a buffer full of sequence end codes */
l
= 0;
while (l
<2048)
{
ld
->Rdbfr
[l
++] = SEQUENCE_END_CODE
>>24;
ld
->Rdbfr
[l
++] = SEQUENCE_END_CODE
>>16;
ld
->Rdbfr
[l
++] = SEQUENCE_END_CODE
>>8;
ld
->Rdbfr
[l
++] = SEQUENCE_END_CODE
&0xff;
}
ld
->Rdptr
= ld
->Rdbfr
;
ld
->Rdmax
= ld
->Rdbfr
+ 2048;
return;
default:
if(code
>=SYSTEM_START_CODE
)
{
/* skip system headers and non-video packets*/
code
= Get_Word
();
ld
->Rdptr
+= code
;
}
else
{
fprintf(stderr
,"Unexpected startcode %08x in system layer\n",code
);
exit(1);
}
break;
}
}
}
void Flush_Buffer32
()
{
int Incnt
;
ld
->Bfr
= 0;
Incnt
= ld
->Incnt
;
Incnt
-= 32;
if (System_Stream_Flag
&& (ld
->Rdptr
>= ld
->Rdmax
-4))
{
while (Incnt
<= 24)
{
if (ld
->Rdptr
>= ld
->Rdmax
)
Next_Packet
();
ld
->Bfr
|= Get_Byte
() << (24 - Incnt
);
Incnt
+= 8;
}
}
else
{
while (Incnt
<= 24)
{
if (ld
->Rdptr
>= ld
->Rdbfr
+2048)
Fill_Buffer
();
ld
->Bfr
|= *ld
->Rdptr
++ << (24 - Incnt
);
Incnt
+= 8;
}
}
ld
->Incnt
= Incnt
;
#ifdef VERIFY
ld
->Bitcnt
+= 32;
#endif /* VERIFY */
}
unsigned int Get_Bits32
()
{
unsigned int l
;
l
= Show_Bits
(32);
Flush_Buffer32
();
return l
;
}
int Get_Long
()
{
int i
;
i
= Get_Word
();
return (i
<<16) | Get_Word
();
}