www.pudn.com > lencod.rar > bitstream.c
/* *********************************************************************** * COPYRIGHT AND WARRANTY INFORMATION * * Copyright 2003, 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. ************************************************************************ */ /* ************************************************************************************* * File name: * Function: Annex B Byte Stream format NAL Unit writing routines * ************************************************************************************* */ #include#include #include #include #include "global.h" #include "bitstream.h" #define MAXHEADERSIZE 100 #include "vlc.h" static FILE *f = NULL; // the output file CopyRight CopyRights, *cp = &CopyRights; CameraParamters CameraParameter, *camera = &CameraParameter; //////////////////////////////////////////////////////////////////////////////// #ifdef SVA_START_CODE_EMULATION unsigned char bit[8] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; OutputStream ORABS; OutputStream *pORABS = &ORABS; void OpenORABS(OutputStream *p,char *fname) { p->f = fopen(fname,"wb"); if(p->f==NULL){printf ("\nCan't open file %s",fname);exit(-1);} p->uPreBytes = 0xffffffff; p->iBytePosition = 0; p->iBitOffset = 0; p->iNumOfStuffBits = 0; p->iBitsCount = 0; } void CloseORABS(OutputStream *p) { if(p->iBitOffset) fwrite(p->buf,1,p->iBytePosition+1,p->f); else fwrite(p->buf,1,p->iBytePosition ,p->f); fclose(p->f); } void FlushORABS(OutputStream *p) { fflush(p->f); } int write_1_bit(OutputStream *p,int b) { int i; //qhg 20060327 delete //demo needed. Because de-emulation is used in startslice, it is unecessary to do it here // 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; // } // } if(p->iBytePosition == SVA_STREAM_BUF_SIZE) { i = fwrite(p->buf,1,SVA_STREAM_BUF_SIZE,p->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; } // deleted by Yulj /* 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; }*/ // added by Yulj 2004.07.16 // one bit "1" is added to the end of stream, then some bits "0" are added to bytealigned position. int write_align_stuff(OutputStream *p) { unsigned char c; c = 0xff << ( 8 - 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; } //---end 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,p->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; p->iBytePosition += 4; p->iBitsCount += 32; p->uPreBytes = (unsigned int)code + 256; return 0; } /* ************************************************************************* * Function:Open the output file for the bytestream * Input: The filename of the file to be opened * Output: * Return: none.Function terminates the program in case of an error * Attention: ************************************************************************* */ void OpenBitStreamFile(char *Filename) { OpenORABS(pORABS,Filename); } void CloseBitStreamFile() { CloseORABS(pORABS); } /* ************************************************************************* * Function:Write sequence header information * Input: * Output: * Return: sequence header length, including stuffing bits * Attention: ************************************************************************* */ int WriteSequenceHeader() { Bitstream *bitstream; byte SequenceHeader[MAXHEADERSIZE]; int bitscount=0; int stuffbits; int i,j,k; if ((bitstream=calloc(1, sizeof(Bitstream)))==NULL) no_mem_exit("Seuqence Header: bitstream"); bitstream->streamBuffer = SequenceHeader; bitstream->bits_to_go = 8; input->profile_id = 0x20; input->level_id = 0x42; input->display_horizontal_size = input->img_width; input->display_vertical_size = input->img_height; input->sample_precision=1;//add by xfwang 2004.7.29 input->bbv_buffer_size=4096;//here we random give a value,but in fact it is not true. bitscount+=u_v(32,"seqence start code",0x1b0,bitstream); bitscount+=u_v(8,"profile_id",input->profile_id,bitstream); bitscount+=u_v(8,"level_id",input->level_id,bitstream); bitscount+=u_v(1,"progressive_sequence",input->progressive_sequence,bitstream); bitscount+=u_v(14,"picture width",input->img_width,bitstream); bitscount+=u_v(14,"picture height",input->img_height,bitstream); bitscount+=u_v(2,"chroma foramt",input->chroma_format,bitstream); bitscount+=u_v(3,"sample precision",input->sample_precision,bitstream); bitscount+=u_v(4,"aspect ratio information",input->aspect_ratio_information,bitstream); bitscount+=u_v(4,"frame rate code",input->frame_rate_code,bitstream); //input->bit_rate_lower = input->bit_rate_upper = 0; //xyji 12.23 bitscount+=u_v(18,"bit rate lower",input->bit_rate_lower,bitstream); bitscount+=u_v(1,"marker bit",1,bitstream); bitscount+=u_v(12,"bit rate upper",input->bit_rate_upper,bitstream); bitscount+=u_v(1,"low delay",input->low_delay,bitstream); bitscount+=u_v(1,"marker bit",1,bitstream); bitscount+=u_v(18,"bbv buffer size",input->bbv_buffer_size,bitstream); bitscount+=u_v(3,"reserved bits",0,bitstream); k = bitscount >> 3; j = bitscount % 8; stuffbits = 8-(bitscount%8); if (stuffbits<8) bitscount+=u_v(stuffbits,"stuff bits for byte align",0,bitstream); write_start_code(pORABS, 0xb0); for(i=4;i streamBuffer = SequenceHeader; bitstream->bits_to_go = 8; bitscount+=u_v(24,"start code prefix",1,bitstream); if(input->img_width > 2800) bitscount+=u_v(3, "slice vertical position extension",0,bitstream); bitscount+=u_v(8, "slice start code",slice_nr,bitstream); if (!input->fixed_picture_qp) { bitscount += u_v(1,"fixed_slice_qp",1,bitstream); bitscount += u_v(6,"slice_qp",slice_qp,bitstream); } k = bitscount >> 3; j = bitscount % 8; stuffbits = 8-(bitscount%8); if (stuffbits<8) bitscount+=u_v(stuffbits,"stuff bits for byte align",0,bitstream); write_start_code(pORABS, (unsigned char) slice_nr); for(i=4;i video_format=1; input->video_range=1; input->display_horizontal_size=1920; input->display_vertical_size=1280; bitstream->streamBuffer = SequenceDisplayExtension; bitstream->bits_to_go = 8; bitscount+=u_v(32,"sequence display extension start code",0x1b5,bitstream); bitscount+=u_v(4,"extension id",2,bitstream); bitscount+=u_v(3,"video format",input->video_format,bitstream); bitscount+=u_v(1,"video range",input->video_range,bitstream); bitscount+=u_v(1,"color description",input->color_description,bitstream); if(input->color_description) { bitscount+=u_v(8,"color primaries",input->color_primaries,bitstream); bitscount+=u_v(8,"transfer characteristics",input->transfer_characteristics,bitstream); bitscount+=u_v(8,"matrix coefficients",input->matrix_coefficients,bitstream); } bitscount+=u_v(14,"display horizontal size",input->display_horizontal_size,bitstream); //xyji 12.23 bitscount+=u_v(1,"marker bit",1,bitstream); bitscount+=u_v(14,"display vertical size", input->display_vertical_size,bitstream); //xyji 12.23 bitscount+=u_v(2,"reserved bits",0,bitstream); k = bitscount >> 3; j = bitscount % 8; stuffbits = 8-(bitscount%8); if (stuffbits<8) { bitscount+=u_v(stuffbits,"stuff bits for byte align",0,bitstream); } write_start_code(pORABS, 0xb5); for(i=4;i streamBuffer = CopyrightExtension; bitstream->bits_to_go = 8; bitscount+=u_v(32,"copyright extension start code",0x1b5,bitstream); bitscount+=u_v(4,"extension id",4,bitstream); bitscount+=u_v(3,"copyright flag",cp->copyright_flag,bitstream); bitscount+=u_v(1,"copyright id",cp->copyright_id,bitstream); bitscount+=u_v(1,"original or copy",cp->original_or_copy,bitstream); bitscount+=u_v(64,"copyright number",cp->copyright_number,bitstream); k = bitscount >> 3; j = bitscount % 8; stuffbits = 8-(bitscount%8); if (stuffbits<8) { bitscount+=u_v(stuffbits,"stuff bits for byte align",0,bitstream); } write_start_code(pORABS, 0xb5); for(i=4;i streamBuffer = CameraParametersExtension; bitstream->bits_to_go = 8; bitscount+=u_v(32,"camera parameters extension start code",0x1b5,bitstream); bitscount+=u_v(4,"extension id",11,bitstream); bitscount+=u_v(1,"reserved",0,bitstream); bitscount+=u_v(7,"camera id",camera->camera_id,bitstream); bitscount+=u_v(22,"height_of_image_device",camera->height_of_image_device,bitstream); bitscount+=u_v(22,"focal_length",camera->focal_length,bitstream); bitscount+=u_v(22,"f_number",camera->f_number,bitstream); bitscount+=u_v(22,"vertical_angle_of_view",camera->vertical_angle_of_view,bitstream); bitscount+=u_v(32,"camera_position_x",camera->camera_direction_x,bitstream); bitscount+=u_v(32,"camera_position_y",camera->camera_direction_y,bitstream); bitscount+=u_v(22,"camera_position_z",camera->camera_direction_z,bitstream); bitscount+=u_v(22,"camera_direction_x",camera->camera_direction_x,bitstream); bitscount+=u_v(22,"camera_direction_y",camera->camera_direction_y,bitstream); bitscount+=u_v(22,"camera_direction_z",camera->camera_direction_z,bitstream); bitscount+=u_v(22,"image_plane_vertical_x",camera->image_plane_vertical_x,bitstream); bitscount+=u_v(22,"image_plane_vertical_y",camera->image_plane_vertical_y,bitstream); bitscount+=u_v(32,"image_plane_vertical_z",camera->image_plane_vertical_z,bitstream); k = bitscount >> 3; j = bitscount % 8; stuffbits = 8-(bitscount%8); if (stuffbits<8) { bitscount+=u_v(stuffbits,"stuff bits for byte align",0,bitstream); } write_start_code(pORABS, 0xb5); for(i=4;i streamBuffer = UserData; bitstream->bits_to_go = 8; bitscount += u_v(32,"user data start code", 0x1b2,bitstream); write_start_code(pORABS, 0xb2); while (*userdata) { write_n_bit(pORABS,*userdata,8); bitscount += u_v(8,"user data", *userdata++,bitstream); } write_align_stuff(pORABS); // fwrite(UserData,1,bitscount/8,f); free(bitstream); return bitscount; } /* ************************************************************************* * Function:Write bit steam to file * Input: * Output: * Return: none * Attention: ************************************************************************* */ void WriteBitstreamtoFile() { int n, i; n = currBitStream->byte_pos; // deleted by jlzheng 6.30 /* if(currBitStream->streamBuffer[0]==0 && currBitStream->streamBuffer[1]==0 && currBitStream->streamBuffer[2]==1) { write_start_code(pORABS, currBitStream->streamBuffer[3]); for(i=4;i streamBuffer[i],8); } } else { for(i=0;i streamBuffer[i],8); }*/ // added by jlzheng 6.30 for(i=0;i streamBuffer[i]==0 && currBitStream->streamBuffer[i+1]==0 && currBitStream->streamBuffer[i+2]==1) { write_start_code(pORABS, currBitStream->streamBuffer[i+3]); i=i+4; } write_n_bit(pORABS, currBitStream->streamBuffer[i],8); } write_align_stuff(pORABS); //can be comment, it is uncessary to stuff here qhg 20060327 //bytecount = fwrite(currBitStream->streamBuffer,1,currBitStream->byte_pos,f); stat->bit_ctr += 8*n; } #endif ///////////////////////////////////////////////////////////////////////////////////////////// /* ************************************************************************* * Function: * Input: * Output: * Return: * Attention: ************************************************************************* */ void error(char *text, int code) { fprintf(stderr, "%s\n", text); exit(code); } /* ************************************************************************* * Function: * Input: * Output: * Return: * Attention: ************************************************************************* */ int start_sequence() { int len = 0; char id_string[255] = "AVS test stream"; OpenBitStreamFile(input->outfile); len = WriteSequenceHeader(); len += WriteSequenceDisplayExtension(); if (strlen(id_string) > 1) len += WriteUserData(id_string); return len; } /* ************************************************************************* * Function: * Input: * Output: * Return: * Attention:Mainly flushing of everything Add termination symbol, etc. ************************************************************************* */ int terminate_sequence() { int len; len = WriteSequenceEnd(); CloseBitStreamFile(); return len; // make lint happy }