📄 sei.c
字号:
}
else
fp = fopen( map_file_name, "ab" );
get_mem2D(&y, img->height, img->width);
#endif
get_mem2D(&map_sp, img->height/16, img->width/16);
if (fb->picbuf_short[2]->used!=0) possible_spare_pic_num = 2;
else possible_spare_pic_num = 1;
// loop over the spare pictures
for (m=0; m<possible_spare_pic_num; m++)
{
// clear the temporal bitstream buffer
tmpBitstream->bits_to_go = 8;
tmpBitstream->byte_pos = 0;
tmpBitstream->byte_buf = 0;
memset( tmpBitstream->streamBuffer, 0, MAXRTPPAYLOADLEN);
// set delta_spare_frame_num
// the order of the following lines cannot be changed.
if (m==0)
CandidateSpareFrameNum = seiSparePicturePayload.target_frame_num - 1; // TargetFrameNum - 1;
else
CandidateSpareFrameNum = SpareFrameNum - 1;
if ( CandidateSpareFrameNum < 0 ) CandidateSpareFrameNum = MAX_FN - 1;
SpareFrameNum = fb->picbuf_short[m+1]->frame_num_256;
delta_spare_frame_num = CandidateSpareFrameNum - SpareFrameNum;
assert( delta_spare_frame_num == 0 );
// calculate the spare macroblock map of one spare picture
// the results are stored into map_sp[][]
for (i=0; i < img->height/16; i++)
for (j=0; j < img->width/16; j++)
{
tmp = 0;
for (i0=0; i0<16; i0++)
for (j0=0; j0<16; j0++)
tmp+=abs(fb->picbuf_short[m+1]->Refbuf11[(i*16+i0)*img->width+j*16+j0]-
fb->picbuf_short[0]->Refbuf11[(i*16+i0)*img->width+j*16+j0]);
tmp = (tmp<=threshold1? 255 : 0);
map_sp[i][j] = (tmp==0? 1 : 0);
#ifdef WRITE_MAP_IMAGE
// if (m==0)
{
for (i0=0; i0<16; i0++)
for (j0=0; j0<16; j0++)
y[i*16+i0][j*16+j0]=tmp;
}
#endif
}
// based on map_sp[][], compose the spare picture information
// and write the spare picture information to a temp bitstream
tmp = 0;
for (i=0; i < img->height/16; i++)
for (j=0; j < img->width/16; j++)
if (map_sp[i][j]==0) tmp++;
if ( tmp > threshold2 )
ref_area_indicator = 0;
else if ( !CompressSpareMBMap(map_sp, tmpBitstream) )
ref_area_indicator = 1;
else
ref_area_indicator = 2;
// printf( "ref_area_indicator = %d\n", ref_area_indicator );
#ifdef WRITE_MAP_IMAGE
// write the map to a file
// if (m==0)
{
// write the map image
for (i=0; i < img->height; i++)
for (j=0; j < img->width; j++)
{
if ( ref_area_indicator == 0 ) fputc(255, fp);
else fputc(y[i][j], fp);
}
for (k=0; k < 2; k++)
for (i=0; i < img->height/2; i++)
for (j=0; j < img->width/2; j++)
fputc(128, fp);
}
#endif
// Finnally, write the current spare picture information to
// the global variable: seiSparePicturePayload
ComposeSparePictureMessage(delta_spare_frame_num, ref_area_indicator, tmpBitstream);
seiSparePicturePayload.num_spare_pics++;
} // END for (m=0; m<2; m++)
free_mem2D( map_sp );
free( tmpBitstream->streamBuffer );
free( tmpBitstream );
#ifdef WRITE_MAP_IMAGE
free_mem2D( y );
fclose( fp );
#undef WRITE_MAP_IMAGE
#endif
*/
}
/*!
************************************************************************
* \brief
* compose the spare picture information.
* \param delta_spare_frame_num
* see FCD
* \param ref_area_indicator
* Indicate how to represent the spare mb map
* \param tmpBitstream
* pointer to a buffer to save the payload
* \par Output
* bitstream: the composed spare picture payload are
* ready to put into the sei_message.
************************************************************************
*/
void ComposeSparePictureMessage(int delta_spare_frame_num, int ref_area_indicator, Bitstream *tmpBitstream)
{
Bitstream *bitstream = seiSparePicturePayload.data;
SyntaxElement sym;
sym.type = SE_HEADER;
sym.mapping = ue_linfo;
sym.value1 = delta_spare_frame_num;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
sym.value1 = ref_area_indicator;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
AppendTmpbits2Buf( bitstream, tmpBitstream );
}
/*!
************************************************************************
* \brief
* test if the compressed spare mb map will occupy less mem and
* fill the payload buffer.
* \param map_sp
* in which the spare picture information are stored.
* \param bitstream
* pointer to a buffer to save the payload
* \return
* TRUE: If it is compressed version, \n
* FALSE: If it is not compressed.
************************************************************************
*/
Boolean CompressSpareMBMap(unsigned char **map_sp, Bitstream *bitstream)
{
int j, k;
int noc, bit0, bit1, bitc;
SyntaxElement sym;
int x, y, left, right, bottom, top, directx, directy;
// this is the size of the uncompressed mb map:
int size_uncompressed = (img->height/16) * (img->width/16);
int size_compressed = 0;
Boolean ret;
// initialization
sym.type = SE_HEADER;
sym.mapping = ue_linfo;
noc = 0;
bit0 = 0;
bit1 = 1;
bitc = bit0;
// compress the map, the result goes to the temporal bitstream buffer
x = ( img->width/16 - 1 ) / 2;
y = ( img->height/16 - 1 ) / 2;
left = right = x;
top = bottom = y;
directx = 0;
directy = 1;
for (j=0; j<img->height/16; j++)
for (k=0; k<img->width/16; k++)
{
// check current mb
if ( map_sp[y][x] == bitc ) noc++;
else
{
sym.value1 = noc;
size_compressed += writeSyntaxElement2Buf_UVLC(&sym, bitstream); // the return value indicate the num of bits written
noc=0;
}
// go to the next mb:
if ( directx == -1 && directy == 0 )
{
if (x > left) x--;
else if (x == 0)
{
y = bottom + 1;
bottom++;
directx = 1;
directy = 0;
}
else if (x == left)
{
x--;
left--;
directx = 0;
directy = 1;
}
}
else if ( directx == 1 && directy == 0 )
{
if (x < right) x++;
else if (x == img->width/16 - 1)
{
y = top - 1;
top--;
directx = -1;
directy = 0;
}
else if (x == right)
{
x++;
right++;
directx = 0;
directy = -1;
}
}
else if ( directx == 0 && directy == -1 )
{
if ( y > top) y--;
else if (y == 0)
{
x = left - 1;
left--;
directx = 0;
directy = 1;
}
else if (y == top)
{
y--;
top--;
directx = -1;
directy = 0;
}
}
else if ( directx == 0 && directy == 1 )
{
if (y < bottom) y++;
else if (y == img->height/16 - 1)
{
x = right+1;
right++;
directx = 0;
directy = -1;
}
else if (y == bottom)
{
y++;
bottom++;
directx = 1;
directy = 0;
}
}
}
if (noc!=0)
{
sym.value1 = noc;
size_compressed += writeSyntaxElement2Buf_UVLC(&sym, bitstream);
}
ret = (size_compressed<size_uncompressed? TRUE : FALSE);
if ( !ret ) // overwrite the streambuffer with the original mb map
{
// write the mb map to payload bit by bit
bitstream->byte_buf = 0;
bitstream->bits_to_go = 8;
bitstream->byte_pos = 0;
for (j=0; j<img->height/16; j++)
{
for (k=0; k<img->width/16; k++)
{
bitstream->byte_buf <<= 1;
if (map_sp[j][k]) bitstream->byte_buf |= 1;
bitstream->bits_to_go--;
if (bitstream->bits_to_go==0)
{
bitstream->bits_to_go = 8;
bitstream->streamBuffer[bitstream->byte_pos++]=bitstream->byte_buf;
bitstream->byte_buf = 0;
}
}
}
}
return ret;
}
/*!
************************************************************************
* \brief
* Finalize the spare picture SEI payload.
* The spare picture paylaod will be ready for encapsulation, and it
* should be called before current picture packetized.
* \par Input
* seiSparePicturePayload.data: points to the payload starting from
* delta_spare_frame_num. (See FCD)
* \par Output
* seiSparePicturePayload.data is updated, pointing to the whole spare
* picture information: spare_picture( PayloadSize ) (See FCD)
* Make sure it is byte aligned.
************************************************************************
*/
void FinalizeSpareMBMap()
{
int CurrFrameNum = img->number % MAX_FN;
int delta_frame_num;
SyntaxElement sym;
Bitstream *dest, *source;
sym.type = SE_HEADER;
sym.mapping = ue_linfo;
source = seiSparePicturePayload.data;
dest = malloc(sizeof(Bitstream));
if ( dest == NULL ) no_mem_exit("FinalizeSpareMBMap: dest");
dest->streamBuffer = malloc(MAXRTPPAYLOADLEN);
if ( dest->streamBuffer == NULL ) no_mem_exit("FinalizeSpareMBMap: dest->streamBuffer");
dest->bits_to_go = 8;
dest->byte_pos = 0;
dest->byte_buf = 0;
memset( dest->streamBuffer, 0, MAXRTPPAYLOADLEN);
// delta_frame_num
delta_frame_num = CurrFrameNum - seiSparePicturePayload.target_frame_num;
if ( delta_frame_num < 0 ) delta_frame_num += MAX_FN;
sym.value1 = delta_frame_num;
writeSyntaxElement2Buf_UVLC(&sym, dest);
// num_spare_pics_minus1
sym.value1 = seiSparePicturePayload.num_spare_pics - 1;
writeSyntaxElement2Buf_UVLC(&sym, dest);
// copy the other bits
AppendTmpbits2Buf( dest, source);
// make sure the payload is byte aligned, stuff bits are 10..0
if ( dest->bits_to_go != 8 )
{
(dest->byte_buf) <<= 1;
dest->byte_buf |= 1;
dest->bits_to_go--;
if ( dest->bits_to_go != 0 ) (dest->byte_buf) <<= (dest->bits_to_go);
dest->bits_to_go = 8;
dest->streamBuffer[dest->byte_pos++]=dest->byte_buf;
dest->byte_buf = 0;
}
seiSparePicturePayload.payloadSize = dest->byte_pos;
// the payload is ready now
seiSparePicturePayload.data = dest;
free( source->streamBuffer );
free( source );
}
/*
**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* \functions on subseq information sei messages
* \brief
* JVT-D098
* \author
* Dong Tian <tian@cs.tut.fi>
**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
Boolean seiHasSubseqInfo = FALSE;
subseq_information_struct seiSubseqInfo[MAX_LAYER_NUMBER];
/*!
************************************************************************
* \brief
* init subseqence info
************************************************************************
*/
void InitSubseqInfo(int currLayer)
{
static unsigned short id = 0;
seiHasSubseqInfo = TRUE;
seiSubseqInfo[currLayer].subseq_layer_num = currLayer;
seiSubseqInfo[currLayer].subseq_id = id++;
seiSubseqInfo[currLayer].last_picture_flag = 0;
seiSubseqInfo[currLayer].stored_frame_cnt = -1;
seiSubseqInfo[currLayer].payloadSize = 0;
seiSubseqInfo[currLayer].data = malloc( sizeof(Bitstream) );
if ( seiSubseqInfo[currLayer].data == NULL ) no_mem_exit("InitSubseqInfo: seiSubseqInfo[currLayer].data");
seiSubseqInfo[currLayer].data->streamBuffer = malloc( MAXRTPPAYLOADLEN );
if ( seiSubseqInfo[currLayer].data->streamBuffer == NULL ) no_mem_exit("InitSubseqInfo: seiSubseqInfo[currLayer].data->streamBuffer");
seiSubseqInfo[currLayer].data->bits_to_go = 8;
seiSubseqInfo[currLayer].data->byte_pos = 0;
seiSubseqInfo[currLayer].data->byte_buf = 0;
memset( seiSubseqInfo[currLayer].data->streamBuffer, 0, MAXRTPPAYLOADLEN );
}
/*!
************************************************************************
* \brief
* update subseqence info
************************************************************************
*/
void UpdateSubseqInfo(int currLayer)
{
if (img->type != B_SLICE)
{
seiSubseqInfo[currLayer].stored_frame_cnt ++;
seiSubseqInfo[currLayer].stored_frame_cnt = seiSubseqInfo[currLayer].stored_frame_cnt % MAX_FN;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -