📄 parser.c
字号:
#include "parser.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#if defined(WIN32) || defined(UNDER_CE)
#include <windows.h>
//#include <io.h>
#else
#include <sys/timeb.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#endif
#include <assert.h>
#include "image.h"
#include "global.h"
//#include "rtp.h"
#include "memalloc.h"
#include "mbuffer.h"
//#include "leaky_bucket.h"
#include "annexb.h"
#include "parset.h"
#include "sei.h"
#include "nalu.h"
struct img_par *img;
struct inp_par *input;
int global_init_done = 0;
extern StorablePicture* dec_picture;
void init_memory_operation_array(MemoryOperation_t *mem_ope)
{
int items;
memory_operation_size = 0;
return;
}
void init_write_reg_array(Register_t *h264_reg)
{
int items;
h264_reg_size = 0;
return;
}
int init_parser()
{
int error = 0;
input = (struct inp_par *)calloc(1, sizeof(struct inp_par));
img = (struct img_par *)calloc(1, sizeof(struct img_par));
if( img && input )
{
memset( img , 0 , sizeof(struct img_par) );
memset( input , 0 , sizeof(struct inp_par) );
}
else
error = 1;
if( !error )
{
init_old_slice();
malloc_slice(input,img);
init(img);
dec_picture = NULL;
dpb.init_done = 0;
img->type = I_SLICE;
img->dec_ref_pic_marking_buffer = NULL;
}
return error;
}
int parse_stream( char*stream , int length , unsigned int stream_phy,
ImageBufferOperation*mem , int* mcnt , RegisterConfig*reg , int*rcnt )
{
int current_header , error = 0;
static unsigned char temp[1024];
int size = min(sizeof(temp),length);
NALU_t nalu;
memcpy( temp , stream , size );
{
nalu.buf = temp+3;
nalu.len = size-3;
nalu.startcodeprefix_len = 3;
nalu.forbidden_bit = (nalu.buf[0]>>7) & 1;
nalu.nal_reference_idc = (nalu.buf[0]>>5) & 3;
nalu.nal_unit_type = (nalu.buf[0]) & 0x1f;
nalu.max_size = length ;
while (nalu.buf[nalu.len - 1] == 0)
nalu.len--;
CheckZeroByteNonVCL( &nalu, &size ) ;
NALUtoRBSP( &nalu );
}
init_memory_operation_array(memory_operation);
init_write_reg_array(h264_reg);
current_header = parse_current_slice( &nalu );
if (current_header == SOP || current_header == SOS)
{
memcpy( mem , memory_operation , sizeof(MemoryOperation_t)*memory_operation_size );
*mcnt = memory_operation_size;
length = (length+63)/64*64;
config_sps(active_sps);
config_pps(active_pps);
config_slice( stream , stream_phy , length );
write_reg(0x00, current_header == SOP ? 0x101 : 0x01);
memcpy( reg , h264_reg , sizeof(Register_t)*h264_reg_size );
previous_frame_num = img->frame_num;
*rcnt = h264_reg_size;
exit_slice();
}
return error;
}
int parse_getinfo( StreamInfo*info )
{
if( info )
{
info->width = img->new_info.width;
info->height = img->new_info.height;
info->dpbsize = img->new_info.dpb_size;
return 0;
}
return -1;
}
int parse_close(ImageBufferOperation*mem , int* mcnt)
{
int error = 0;
exit_picture();
free_slice(input,img);
free_global_buffers();
init_memory_operation_array(memory_operation);
flush_dpb();
memcpy( mem , memory_operation , sizeof(MemoryOperation_t)*memory_operation_size );
*mcnt = memory_operation_size;
return error;
}
int release_parser()
{
int error = 0;
CleanUpPPS();
free_dpb();
free (input);
free (img);
return error;
}
void malloc_slice(struct inp_par *inp, struct img_par *img)
{
int error = 0;
Slice *currSlice;
img->currentSlice = (Slice *) calloc(1, sizeof(Slice));
if ( (currSlice = img->currentSlice) == NULL)
{
error = 1;
}
if( !error )
{
currSlice->max_part_nr = 3; //! assume data partitioning (worst case) for the following mallocs()
currSlice->partArr = AllocPartition(currSlice->max_part_nr);
}
return;
}
void free_slice(struct inp_par *inp, struct img_par *img)
{
Slice *currSlice = img->currentSlice;
FreePartition (currSlice->partArr, 3);
free(img->currentSlice);
currSlice = NULL;
}
int init_global_buffers()
{
int memory_size=0;
// int i;
if (global_init_done)
{
free_global_buffers();
}
memory_size += get_mem3Dint(&(img->wp_weight), 2, MAX_REFERENCE_PICTURES, 3);
memory_size += get_mem3Dint(&(img->wp_offset), 6, MAX_REFERENCE_PICTURES, 3);
memory_size += get_mem4Dint(&(img->wbp_weight), 6, MAX_REFERENCE_PICTURES, MAX_REFERENCE_PICTURES, 3);
global_init_done = 1;
img->oldFrameSizeInMbs = img->FrameSizeInMbs;
return (memory_size);
}
/*!
************************************************************************
* \brief
* Free allocated memory of frame size related global buffers
* buffers are defined in global.h, allocated memory is allocated in
* int init_global_buffers()
*
* \par Input:
* Input Parameters struct inp_par *inp, Image Parameters struct img_par *img
*
* \par Output:
* none
*
************************************************************************
*/
void free_global_buffers()
{
if (img->wp_weight)
free_mem3Dint(img->wp_weight, 2);
if (img->wp_offset)
free_mem3Dint(img->wp_offset, 6);
if (img->wbp_weight)
free_mem4Dint(img->wbp_weight, 6, MAX_REFERENCE_PICTURES);
global_init_done = 0;
}
void FreePartition (DataPartition *dp, int n)
{
int i;
assert (dp != NULL);
assert (dp->bitstream != NULL);
assert (dp->bitstream->streamBuffer != NULL);
for (i=0; i<n; i++)
{
free (dp[i].bitstream->streamBuffer);
free (dp[i].bitstream);
}
free (dp);
}
DataPartition *AllocPartition(int n)
{
DataPartition *partArr, *dataPart;
int i;
partArr = (DataPartition *) calloc(n, sizeof(DataPartition));
if (partArr == NULL)
{
snprintf(errortext, ET_SIZE, "AllocPartition: Memory allocation for Data Partition failed");
error(errortext, 100);
}
for (i=0; i<n; i++) // loop over all data partitions
{
dataPart = &(partArr[i]);
dataPart->bitstream = (Bitstream *) calloc(1, sizeof(Bitstream));
if (dataPart->bitstream == NULL)
{
snprintf(errortext, ET_SIZE, "AllocPartition: Memory allocation for Bitstream failed");
error(errortext, 100);
}
dataPart->bitstream->streamBuffer = (byte *) calloc(MAX_CODED_FRAME_SIZE, sizeof(byte));
if (dataPart->bitstream->streamBuffer == NULL)
{
snprintf(errortext, ET_SIZE, "AllocPartition: Memory allocation for streamBuffer failed");
error(errortext, 100);
}
}
return partArr;
}
void init_frext(struct img_par *img) //!< image parameters
{
//pel bitdepth init
img->bitdepth_luma_qp_scale = 6*(img->bitdepth_luma - 8);
if(img->bitdepth_luma > img->bitdepth_chroma || active_sps->chroma_format_idc == YUV400)
img->pic_unit_bitsize_on_disk = (img->bitdepth_luma > 8)? 16:8;
else
img->pic_unit_bitsize_on_disk = (img->bitdepth_chroma > 8)? 16:8;
img->dc_pred_value_luma = 1<<(img->bitdepth_luma - 1);
img->max_imgpel_value = (1<<img->bitdepth_luma) - 1;
img->mb_size[0][0] = img->mb_size[0][1] = MB_BLOCK_SIZE;
if (active_sps->chroma_format_idc != YUV400)
{
//for chrominance part
img->bitdepth_chroma_qp_scale = 6 * (img->bitdepth_chroma - 8);
img->dc_pred_value_chroma = (1 << (img->bitdepth_chroma - 1));
img->max_imgpel_value_uv = (1 << img->bitdepth_chroma) - 1;
img->num_blk8x8_uv = (1 << active_sps->chroma_format_idc) & (~(0x1));
img->num_uv_blocks = (img->num_blk8x8_uv >> 1);
img->num_cdc_coeff = (img->num_blk8x8_uv << 1);
img->mb_size[1][0] = img->mb_size[2][0] = img->mb_cr_size_x = (active_sps->chroma_format_idc==YUV420 || active_sps->chroma_format_idc==YUV422)? 8 : 16;
img->mb_size[1][1] = img->mb_size[2][1] = img->mb_cr_size_y = (active_sps->chroma_format_idc==YUV444 || active_sps->chroma_format_idc==YUV422)? 16 : 8;
}
else
{
img->bitdepth_chroma_qp_scale = 0;
img->max_imgpel_value_uv = 0;
img->num_blk8x8_uv = 0;
img->num_uv_blocks = 0;
img->num_cdc_coeff = 0;
img->mb_size[1][0] = img->mb_size[2][0] = img->mb_cr_size_x = 0;
img->mb_size[1][1] = img->mb_size[2][1] = img->mb_cr_size_y = 0;
}
img->mb_size_blk[0][0] = img->mb_size_blk[0][1] = img->mb_size[0][0] >> 2;
img->mb_size_blk[1][0] = img->mb_size_blk[2][0] = img->mb_size[1][0] >> 2;
img->mb_size_blk[1][1] = img->mb_size_blk[2][1] = img->mb_size[1][1] >> 2;
img->mb_size_shift[0][0] = img->mb_size_shift[0][1] = CeilLog2_sf (img->mb_size[0][0]);
img->mb_size_shift[1][0] = img->mb_size_shift[2][0] = CeilLog2_sf (img->mb_size[1][0]);
img->mb_size_shift[1][1] = img->mb_size_shift[2][1] = CeilLog2_sf (img->mb_size[1][1]);
}
void init(struct img_par *img) //!< image parameters
{
img->oldFrameSizeInMbs = -1;
// imgY_ref = NULL;
// imgUV_ref = NULL;
img->recovery_point = 0;
img->recovery_point_found = 0;
img->recovery_poc = 0x7fffffff; /* set to a max value */
#ifdef ENABLE_OUTPUT_TONEMAPPING
init_tone_mapping_sei();
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -