📄 filehandle.c
字号:
{ // RTP: CABAC
eep = &((currSlice->partArr[0]).ee_cabac);
currStream = (currSlice->partArr[0]).bitstream;
assert (currStream->bits_to_go == 8);
assert (currStream->byte_buf == 0);
header_len=RTPSliceHeader(); // generate the slice header
// 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++;
arienco_start_encoding(eep, currStream->streamBuffer, &(currStream->byte_pos));
if(input->partition_mode != PAR_DP_1)
{
for (i=1; i<currSlice->max_part_nr; i++)
{
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);
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;
}
default:
snprintf(errortext, ET_SIZE, "Output File Mode %d not supported", input->of_mode);
error(errortext,1);
return 1;
}
}
/*!
************************************************************************
* \brief
* This function terminates a slice
* \return
* 0 if OK, \n
* 1 in case of error
************************************************************************
*/
int terminate_slice()
{
int bytes_written;
Bitstream *currStream;
Slice *currSlice = img->currentSlice;
EncodingEnvironmentPtr eep;
int i;
int byte_pos, bits_to_go, start_data;
byte buffer;
int LastPartition;
int cabac_byte_pos=0, uvlc_byte_pos=0, empty_bytes=0;
int rtp_bytes_written;
// Mainly flushing of everything
// Add termination symbol, etc.
switch(input->of_mode)
{
case PAR_OF_26L:
if (input->symbol_mode == UVLC)
{
// Current TML File Format
// Enforce byte alignment of next header: zero bit stuffing
currStream = (currSlice->partArr[0]).bitstream;
if (currStream->bits_to_go < 8)
{ // trailing bits to process
currStream->byte_buf <<= currStream->bits_to_go;
currStream->streamBuffer[currStream->byte_pos++]=currStream->byte_buf;
currStream->bits_to_go = 8;
}
bytes_written = currStream->byte_pos;
stat->bit_ctr += 8*bytes_written; // actually written bits
#ifdef H26L_LIB
memcpy(&memout[memoutlength], currStream->streamBuffer, bytes_written);
memoutlength += bytes_written;
#else
fwrite (currStream->streamBuffer, 1, bytes_written, out);
#endif
currStream->stored_bits_to_go = 8; // store bits_to_go
currStream->stored_byte_buf = currStream->byte_buf; // store current byte
currStream->stored_byte_pos = 0; // reset byte position
}
else
{
// CABAC File Format
eep = &((currSlice->partArr[0]).ee_cabac);
currStream = (currSlice->partArr[0]).bitstream;
// terminate the arithmetic code
arienco_done_encoding(eep);
// Add Number of MBs of this slice to the header
// Save current state of Bitstream
currStream = (currSlice->partArr[0]).bitstream;
byte_pos = currStream->byte_pos;
bits_to_go = currStream->bits_to_go;
buffer = currStream->byte_buf;
// Go to the reserved bits
currStream->byte_pos = (currStream->header_len)/8;
currStream->bits_to_go = 8-(currStream->header_len)%8;
currStream->byte_buf = currStream->header_byte_buffer;
// Ad Info about last MB
LastMBInSlice();
// And write the header to the output
bytes_written = currStream->byte_pos;
if (currStream->bits_to_go < 8) // trailing bits to process
{
currStream->byte_buf <<= currStream->bits_to_go;
currStream->streamBuffer[currStream->byte_pos++]=currStream->byte_buf;
bytes_written++;
currStream->bits_to_go = 8;
}
#ifdef H26L_LIB
memcpy(&memout[memoutlength], currStream->streamBuffer, bytes_written);
memoutlength += bytes_written;
#else
fwrite (currStream->streamBuffer, 1, bytes_written, out);
#endif
stat->bit_ctr += 8*bytes_written;
// Go back to the end of the stream
currStream->byte_pos = byte_pos;
currStream->bits_to_go = bits_to_go;
currStream->byte_buf = buffer;
// Find startposition of databitstream
start_data = (currStream->header_len+31)/8;
if ((currStream->header_len+31)%8 != 0)
start_data++;
bytes_written = currStream->byte_pos - start_data; // number of written bytes
stat->bit_ctr += 8*bytes_written; // actually written bits
#ifdef H26L_LIB
memcpy(&memout[memoutlength], currStream->streamBuffer+start_data,
bytes_written);
memoutlength += bytes_written;
#else
fwrite ((currStream->streamBuffer+start_data), 1, bytes_written, out);
#endif
}
return 0;
case PAR_OF_RTP:
for (i=0; i<currSlice->max_part_nr; i++)
{
if (input->symbol_mode == CABAC)
{
eep = &((currSlice->partArr[i]).ee_cabac);
arienco_done_encoding(eep);
}
currStream = (currSlice->partArr[i]).bitstream;
if (currStream->bits_to_go < 8) // trailing bits to process
{
currStream->byte_buf <<= currStream->bits_to_go;
currStream->streamBuffer[currStream->byte_pos++]=currStream->byte_buf;
currStream->bits_to_go = 8;
}
bytes_written = currStream->byte_pos; // number of written bytes
assert (bytes_written != 0);
if (bytes_written != 0) // at least one bit in the partition -- something to do
{
int Marker;
int FirstBytePacketType;
// Determine First Byte of RTP payload
switch (input->partition_mode)
{
case PAR_DP_1:
FirstBytePacketType = 0;
break;
case PAR_DP_3:
FirstBytePacketType = i+1; // See VCEG-N72
break;
default:
assert (0==1);
}
if (input->symbol_mode == CABAC && i == 0)
{
//! Add Number of MBs of this slice to the header
//! Save current state of Bitstream
byte_pos = currStream->byte_pos; //last byte in the stream
//! Go to the reserved bits
currStream->byte_pos = cabac_byte_pos = (currStream->header_len)/8;
currStream->bits_to_go = 8-(currStream->header_len)%8;
currStream->byte_buf = currStream->header_byte_buffer;
cabac_byte_pos += ((31-currStream->bits_to_go)/8);
if ((31-currStream->bits_to_go)%8 != 0)
cabac_byte_pos++;
cabac_byte_pos++; //! that's the position where we started to write CABAC code
//! Ad Info about last MB
LastMBInSlice();
if (currStream->bits_to_go < 8) //! trailing bits to process
{
currStream->byte_buf <<= currStream->bits_to_go;
currStream->streamBuffer[currStream->byte_pos++]=currStream->byte_buf;
}
uvlc_byte_pos = currStream->byte_pos; //! that's the first byte after the UVLC header data
currStream->byte_pos = byte_pos; //! where we were before this last_MB thing
empty_bytes = cabac_byte_pos - uvlc_byte_pos; //! These bytes contain no information
//! They were reserved for writing the last_MB information but were not used
for(byte_pos=uvlc_byte_pos; byte_pos<=currStream->byte_pos-empty_bytes; byte_pos++)
currStream->streamBuffer[byte_pos]=currStream->streamBuffer[byte_pos+empty_bytes]; //shift the bitstreams
bytes_written = byte_pos;
//! TO 02.11.2001 I'm sure this can be done much more elegant, but that's the way it works.
//! If anybody understands what happens here please feel free to change this!
}
// Calculate RTP payload's First Byte
if (input->partition_mode==PAR_DP_1)
FirstBytePacketType = 0;
else
FirstBytePacketType = i+1;
assert (FirstBytePacketType == 0); //! This has to go as soon as data partitioning is to be tested
// Calculate the Marker bit
LastPartition=0;
if (input->partition_mode == PAR_DP_3)
{
if (currSlice->partArr[1].bitstream->byte_pos > 0) // something in partition 1
LastPartition=1;
if (currSlice->partArr[2].bitstream->byte_pos > 0) // something in partition 2
LastPartition=2;
}
Marker = 0;
if (img->current_mb_nr == img->total_number_mb) // last MB is in this slice
if ((input->partition_mode==PAR_DP_1) || // Single SLice
(input->partition_mode==PAR_DP_3 && i == LastPartition )) // Last partition containing bits
Marker = 1;
// and write the RTP packet
rtp_bytes_written = RTPWriteBits (Marker, FirstBytePacketType, currStream->streamBuffer, bytes_written, out);
}
stat->bit_ctr += 8*bytes_written;
// Provide the next partition with a 'fresh' buffer
currStream->stored_bits_to_go = 8;
currStream->stored_byte_buf = 0;
currStream->stored_byte_pos = 0;
currStream->bits_to_go = 8;
currStream->byte_buf = 0;
currStream->byte_pos = 0;
}
return 0;
default:
snprintf(errortext, ET_SIZE, "Output File Mode %d not supported", input->of_mode);
error(errortext,1);
return 1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -