📄 filehandle.c
字号:
/*
***********************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2001, International Telecommunications Union, Geneva
*
* DISCLAIMER OF WARRANTY
*
* These software programs are available to the user without any
* license fee or royalty on an "as is" basis. The ITU 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
* contributor or the ITU 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 ITU does not represent or warrant that the programs furnished
* hereunder are free of infringement of any third-party patents.
* Commercial implementations of ITU-T Recommendations, including
* shareware, may be subject to royalty fees to patent holders.
* Information regarding the ITU-T patent policy is available from
* the ITU Web site at http://www.itu.int.
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE ITU-T PATENT POLICY.
************************************************************************
*/
/*!
**************************************************************************************
* \file
* filehandle.c
* \brief
* Handles the operations how to write
* the generated symbols on the interim file format or some
* other specified output formats
* \author
* Main contributors (see contributors.h for copyright, address and affiliation details)
* - Thomas Stockhammer <stockhammer@ei.tum.de>
* - Detlev Marpe <marpe@hhi.de>
***************************************************************************************
*/
#include "contributors.h"
#include <string.h>
#include <math.h>
#include <time.h>
#include <sys/timeb.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "global.h"
#include "header.h"
#include "rtp.h"
// Global Varibales
static FILE *out; //!< output file
/*
The implemented solution for a unified picture header
*/
/*!
************************************************************************
* \brief
* Error handling procedure. Print error message to stderr and exit
* with supplied code.
* \param text
* Error message
* \param code
* Exit code
************************************************************************
*/
void error(char *text, int code)
{
fprintf(stderr, "%s\n", text);
exit(code);
}
/*!
************************************************************************
* \brief
* This function opens the output files and generates the
* appropriate sequence header
************************************************************************
*/
int start_sequence()
{
int len;
switch(input->of_mode)
{
case PAR_OF_26L:
#ifndef H26L_LIB
if ((out=fopen(input->outfile,"wb"))==NULL)
{
snprintf(errortext, ET_SIZE, "Error open file %s \n",input->outfile);
error(errortext,1);
}
#endif
len = SequenceHeader(out);
return 0;
case PAR_OF_RTP:
if ((out=fopen(input->outfile,"wb"))==NULL)
{
snprintf(errortext, ET_SIZE, "Error open file %s \n",input->outfile);
error(errortext,1);
}
len = SequenceHeader(out);
return len;
default:
snprintf(errortext, ET_SIZE, "Output File Mode %d not supported", input->of_mode);
error(errortext,1);
return 1;
}
}
/*!
************************************************************************
* \brief
* This function terminates the sequence and closes the
* output files
************************************************************************
*/
int terminate_sequence()
{
Bitstream *currStream;
// Mainly flushing of everything
// Add termination symbol, etc.
switch(input->of_mode)
{
case PAR_OF_26L:
currStream = ((img->currentSlice)->partArr[0]).bitstream;
if (input->symbol_mode == UVLC)
{
// Current TML File Format
// Get the trailing bits of the last slice
currStream->bits_to_go = currStream->stored_bits_to_go;
currStream->byte_pos = currStream->stored_byte_pos;
currStream->byte_buf = currStream->stored_byte_buf;
if (currStream->bits_to_go < 8) // there are bits left in the last byte
currStream->streamBuffer[currStream->byte_pos++] = currStream->byte_buf;
// Write all remaining bits to output bitstream file
#ifdef H26L_LIB
memcpy(&memout[memoutlength], currStream->streamBuffer,
currStream->byte_pos);
memoutlength += currStream->byte_pos;
#else
fwrite (currStream->streamBuffer, 1, currStream->byte_pos, out);
fclose(out);
#endif
}
else
{
// CABAC File Format
fclose(out);
}
return 0;
case PAR_OF_RTP:
fclose (out);
return 0;
default:
snprintf(errortext, ET_SIZE, "Output File Mode %d not supported", input->of_mode);
error(errortext,1);
return 1;
}
}
/*!
************************************************************************
* \brief
* This function generates the appropriate slice
* header
*
* \return number of bits used for the picture header, including the PSC.
*
* \par Side effects:
* Adds picture header symbols to the symbol buffer
*
* \par Remarks:
* THIS IS AN INTERIM SOLUTION FOR A PICTURE HEADER, see VCEG-M79
* \par
* Generates the Picture Header out of the information in img_par and inp-par,
* and writes it to the symbol buffer. The structure of the Picture Header
* is discussed in VCEG-M79. It is implemented as discussed there. In addition,
* it is preceeded by a picture start code, a UVLC-codeword of LEN=31 and INFO = 0.
* It would have been possible to put information into this codeword, similar
* to designs earlier than TML 5.9. But it is deemed that the waste of 15
* data bits is acceptable considering the advantages of being able to search
* for a picture header quickly and easily, by looking for 30 consecutive, byte-
* aligned zero bits.
* \par
* The accounting of the header length (variable len) relies on the side effect
* of writeUVLCSymbol() that sets len and info in the symbol variable parameter
************************************************************************
*/
int start_slice(SyntaxElement *sym)
{
EncodingEnvironmentPtr eep;
Slice *currSlice = img->currentSlice;
Bitstream *currStream;
int header_len;
int i;
switch(input->of_mode)
{
case PAR_OF_26L:
if (input->symbol_mode == UVLC)
{
currStream = (currSlice->partArr[0]).bitstream;
// the information given in the SliceHeader is far not enought if we want to be able
// to do some errorconcealment.
// So write PictureHeader and SliceHeader in any case.
header_len = PictureHeader(); // Picture Header
header_len += SliceHeader (0); // Slice Header without Start Code
return header_len;
}
else
{ // H.26: CABAC File Format
eep = &((currSlice->partArr[0]).ee_cabac);
currStream = (currSlice->partArr[0]).bitstream;
assert (currStream->bits_to_go == 8);
assert (currStream->byte_buf == 0);
assert (currStream->byte_pos == 0);
memset(currStream->streamBuffer, 0, 12); // fill first 12 bytes with zeros (debug only)
// the information given in the SliceHeader is far not enought if we want to be able
// to do some errorconcealment.
// So write PictureHeader and SliceHeader in any case.
header_len = PictureHeader(); // Picture Header
header_len += SliceHeader (0); // Slice Header without Start Code
// Note that PictureHeader() and SliceHeader() set the buffer pointers as a side effect
// Hence no need for adjusting it manually (and preserving space to be patched later
// reserve bits for d_MB_Nr
currStream->header_len = header_len;
currStream->header_byte_buffer = currStream->byte_buf;
currStream->byte_pos += ((31-currStream->bits_to_go)/8);
if ((31-currStream->bits_to_go)%8 != 0)
currStream->byte_pos++;
currStream->bits_to_go = 8;
currStream->byte_pos++;
// If there is an absolute need to communicate the partition size, this would be
// the space to insert it
arienco_start_encoding(eep, currStream->streamBuffer, &(currStream->byte_pos));
// initialize context models
init_contexts_MotionInfo(currSlice->mot_ctx, 1);
init_contexts_TextureInfo(currSlice->tex_ctx, 1);
return header_len;
}
case PAR_OF_RTP:
if (img->current_mb_nr == 0) // new picture
RTPUpdateTimestamp (img->tr);
if (input->symbol_mode == UVLC)
{
header_len=RTPSliceHeader(); // generate the slice header
currStream = currSlice->partArr[0].bitstream;
if (header_len % 8 != 0)
{
currStream->byte_buf <<= currStream->bits_to_go;
currStream->bits_to_go=8;
currStream->streamBuffer[currStream->byte_pos++]=currStream->byte_buf;
currStream->byte_buf=0;
}
return header_len;
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -