www.pudn.com > wm2.5.zip > bitstream.c
/*
***********************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2004, Advanced Audio Video Coding Standard, Part II
*
* DISCLAIMER OF WARRANTY
*
* These software programs are available to the users without any
* license fee or royalty on an "as is" basis. The AVS disclaims
* any and all warranties, whether express, implied, or statutory,
* including any implied warranties of merchantability or of fitness
* for a particular purpose. In no event shall the contributors or
* the AVS be liable for any incidental, punitive, or consequential
* damages of any kind whatsoever arising from the use of this program.
*
* This disclaimer of warranty extends to the user of this program
* and user's customers, employees, agents, transferees, successors,
* and assigns.
*
* The AVS does not represent or warrant that the program furnished
* hereunder are free of infringement of any third-party patents.
* Commercial implementations of AVS, including shareware, may be
* subject to royalty fees to patent holders. Information regarding
* the AVS patent policy is available from the AVS Web site at
* http://www.avs.org.cn
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY.
************************************************************************
*/
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "malloc.h"
#include "types.h"
#include "global.h"
#include "define.h"
#include "bitstream.h"
#include "vlc.h"
#include "nalu.h" //WJP FOR NAL
//WJP FOR SLICE
unsigned char bit[8] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
OutputStream ORABS;
OutputStream *pORABS = &ORABS;
//WJP END
/*
*************************************************************************
* Function:allocate memory for the coded picture data
* Input:
* Output:
* Return:
*************************************************************************
*/
void AllocateBitstream(void)
{
//added by MAZHAN
//const int buffer_size = (pgImage->img_width * pgImage->img_width * 4);
//bugs fixed....zhan ma 12.23
const int buffer_size = (pgImage->img_width * pgImage->img_height * 4);
if ((pgcurrBitStream->streamBuffer = (Byte *) calloc(buffer_size, sizeof(Byte))) == NULL)
no_mem_exit ("malloc_slice: StreamBuffer");
pgcurrBitStream->bits_to_go = 8;
}
/*
*************************************************************************
* Function:free the allocated memory for the coded picture data
* Input:
* Output:
* Return:
*************************************************************************
*/
void FreeBitstream(void)
{
if (pgcurrBitStream->streamBuffer)
free(pgcurrBitStream->streamBuffer);
}
/*
*************************************************************************
* Function:initialize the coded picture buffer
* Input:
* Output:
* Return:
*************************************************************************
*/
void Init_Bitstream(void)
{
pgcurrBitStream->bits_to_go = 8;
pgcurrBitStream->byte_buf = 0;
pgcurrBitStream->byte_pos = 0;
}
/*
*************************************************************************
* Function:
* Input:
* Output:
* Return:
*************************************************************************
*/
int write_1_bit(OutputStream *p,int b)
{
int i;
if(p->iBitOffset==6)
{
i = p->uPreBytes & 0x003fffff;
if(i == 0)
{
p->buf[p->iBytePosition] = 0x02;
p->iBytePosition++;
p->iBitOffset = 0;
p->uPreBytes = 0x00000002;
p->iNumOfStuffBits += 2;
p->iBitsCount += 2;
printf("emulation\n");//²âÊÔ
}
}
if(p->iBytePosition == SVA_STREAM_BUF_SIZE)
{
i = fwrite(p->buf,1,SVA_STREAM_BUF_SIZE,pgcurrBitStream->f);
if(i!=SVA_STREAM_BUF_SIZE)
{
printf ("Fatal: write file error, exit (-1)\n");
exit (-1);
}
p->iBytePosition = 0;
p->iBitOffset = 0;
}
p->uPreBytes <<= 1;
if(b)
{
p->buf[p->iBytePosition] |= bit[p->iBitOffset];
p->uPreBytes |= 1;
}
else
{
p->buf[p->iBytePosition] &= (~bit[p->iBitOffset]);
}
p->iBitOffset++;
if(p->iBitOffset==8)
{
p->iBitOffset = 0;
p->iBytePosition++;
}
p->iBitsCount++;
return 0;
}
/*
*
*/
int write_n_bit(OutputStream *p,int b,int n)
{
if(n>30)
return 1;
while(n>0)
{
write_1_bit(p,b&(0x01<<(n-1)));
n--;
}
return 0;
}
/*
*************************************************************************
* Function:
* Input:
* Output:
* Return:
*************************************************************************
*/
int write_align_stuff(OutputStream *p)
{
unsigned char c;
if(p->iBitOffset == 0)
return 0;
c = 0xff << ( 7 - p->iBitOffset );
p->buf[p->iBytePosition] = (c & p->buf[p->iBytePosition])|(0x80>>(p->iBitOffset));
p->iBitsCount += 8 - p->iBitOffset;
p->uPreBytes = (p->uPreBytes << (8 - p->iBitOffset)) & c;
p->iNumOfStuffBits += 8 - p->iBitOffset;
p->iBitOffset = 0;
p->iBytePosition++;
return 0;
}
/*
*************************************************************************
* Function:
* Input:
* Output:
* Return:
*************************************************************************
*/
int write_start_code(OutputStream *p,unsigned char code)
{
int i;
if(p->iBitOffset)
write_align_stuff(p);
if(p->iBytePosition >= SVA_STREAM_BUF_SIZE-4 && p->iBytePosition >0 )
{
i = fwrite(p->buf,1,p->iBytePosition,pgcurrBitStream->f);
if(i != p->iBytePosition)
{
printf ("\nWrite file error");
exit (-1);
}
p->iBytePosition = 0;
p->iBitOffset = 0;
}
p->buf[p->iBytePosition ] = 0;
p->buf[p->iBytePosition+1] = 0;
p->buf[p->iBytePosition+2] = 1;
p->buf[p->iBytePosition+3] = code;
//printf("this start code is %x \n",code);
p->iBytePosition += 4;
p->iBitsCount += 32;
p->uPreBytes = (unsigned int)code + 256;
return 0;
}
/*
*************************************************************************
* Function:Write bit steam to file
* Input:
* Output:
* Return: none
* Attention:Modified by Jianpeng Wang
*************************************************************************
*/
void WriteBitstreamtoFile(void)
{
int i,j=0;
int nal_payload_len;
NALU_t *nalu;//WJP FOR NAL
//Form_RBSP(pgcurrBitStream);//WJP FOR NAL
//WJP FOR NAL
for(i=0;Position_of_Slice_in_PicBuf[i]>=0;i++)
{
if(Position_of_Slice_in_PicBuf[i+1]<0)
nal_payload_len = pgcurrBitStream->byte_pos - Position_of_Slice_in_PicBuf[i];
else
nal_payload_len = Position_of_Slice_in_PicBuf[i+1]-Position_of_Slice_in_PicBuf[i];
nalu = AllocNALU(nal_payload_len+1);
Form_NALU(nalu, NALU_TYPE_SLICE, NAL_REF_IDC_REF, pgcurrBitStream->streamBuffer+Position_of_Slice_in_PicBuf[i], nal_payload_len);
gTotalBits += 8*Write_NALU2File(nalu,pgcurrBitStream->f);
FreeNALU(nalu);
}
//END
}
//WJP END
/*
*************************************************************************
* Function:
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
void error(char *text, int code)
{
fprintf(stderr, "%s\n", text);
exit(code);
}
/*
*************************************************************************
* Function:
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
void no_mem_exit(char *where)
{
printf("Could not allocate memory: %s",where);
error ("Could not allocate memory", 100);
}
/*
*************************************************************************
* Function:
* Input:
* Output:
* Return:
* Attention:Mainly flushing of everything Add termination symbol, etc.
*************************************************************************
*/
//void terminate_sequence(void)//WJP FOR SLICE
//{
//write_start_code(pORABS, 0xb1); WJP FOR NAL
/*
if(pORABS->iBitOffset)
fwrite(pORABS->buf,1,pORABS->iBytePosition+1,pgcurrBitStream->f);
else
fwrite(pORABS->buf,1,pORABS->iBytePosition ,pgcurrBitStream->f);
return;
*/
//}
/*
*************************************************************************
* Function: write rbsp_trailing_bits
* Input:
* Output:
* Return:
* Attention:Mainly flushing of everything Add termination symbol, etc.
*************************************************************************
*/
void Form_RBSP(Bitstream *currBitStream)//WJP FOR NAL
{
currBitStream->byte_buf <<= 1;
currBitStream->byte_buf |= 1;
currBitStream->bits_to_go--;
currBitStream->byte_buf <<= currBitStream->bits_to_go;
currBitStream->streamBuffer[currBitStream->byte_pos++] = currBitStream->byte_buf;
currBitStream->bits_to_go = 8;
currBitStream->byte_buf = 0;
return ;
}