📄 parset.c
字号:
/*!
**************************************************************************************
* \file
* parset.c
* \brief
* Picture and Sequence Parameter set generation and handling
* \date 25 November 2002
* \author
* Main contributors (see contributors.h for copyright, address and affiliation details)
* - Stephan Wenger <stewe@cs.tu-berlin.de>
*
**************************************************************************************
*/
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "global.h"
#include "contributors.h"
#include "mbuffer.h"
#include "parset.h"
#include "vlc.h"
// Local helpers
static int IdentifyProfile(void);
static int IdentifyLevel(void);
static int GenerateVUISequenceParameters(Bitstream *bitstream);
extern ColocatedParams *Co_located;
pic_parameter_set_rbsp_t *PicParSet[MAXPPS];
static const byte ZZ_SCAN[16] =
{ 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
};
static const byte ZZ_SCAN8[64] =
{ 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
};
/*!
*************************************************************************************
* \brief
* generates a sequence and picture parameter set and stores these in global
* active_sps and active_pps
*
* \return
* A NALU containing the Sequence ParameterSet
*
*************************************************************************************
*/
void GenerateParameterSets (void)
{
int i;
seq_parameter_set_rbsp_t *sps = NULL;
sps = AllocSPS();
for (i=0; i<MAXPPS; i++)
{
PicParSet[i] = NULL;
}
GenerateSequenceParameterSet(sps, 0);
if (input->GenerateMultiplePPS)
{
PicParSet[0] = AllocPPS();
PicParSet[1] = AllocPPS();
PicParSet[2] = AllocPPS();
if (sps->profile_idc >= FREXT_HP)
{
GeneratePictureParameterSet( PicParSet[0], sps, 0, 0, 0, input->cb_qp_index_offset, input->cr_qp_index_offset);
GeneratePictureParameterSet( PicParSet[1], sps, 1, 1, 1, input->cb_qp_index_offset, input->cr_qp_index_offset);
GeneratePictureParameterSet( PicParSet[2], sps, 2, 1, 2, input->cb_qp_index_offset, input->cr_qp_index_offset);
}
else
{
GeneratePictureParameterSet( PicParSet[0], sps, 0, 0, 0, input->chroma_qp_index_offset, 0);
GeneratePictureParameterSet( PicParSet[1], sps, 1, 1, 1, input->chroma_qp_index_offset, 0);
GeneratePictureParameterSet( PicParSet[2], sps, 2, 1, 2, input->chroma_qp_index_offset, 0);
}
}
else
{
PicParSet[0] = AllocPPS();
if (sps->profile_idc >= FREXT_HP)
GeneratePictureParameterSet( PicParSet[0], sps, 0, input->WeightedPrediction, input->WeightedBiprediction,
input->cb_qp_index_offset, input->cr_qp_index_offset);
else
GeneratePictureParameterSet( PicParSet[0], sps, 0, input->WeightedPrediction, input->WeightedBiprediction,
input->chroma_qp_index_offset, 0);
}
active_sps = sps;
active_pps = PicParSet[0];
}
/*!
*************************************************************************************
* \brief
* frees global parameter sets active_sps and active_pps
*
* \return
* A NALU containing the Sequence ParameterSet
*
*************************************************************************************
*/
void FreeParameterSets (void)
{
int i;
for (i=0; i<MAXPPS; i++)
{
if ( NULL != PicParSet[i])
{
FreePPS(PicParSet[i]);
PicParSet[i] = NULL;
}
}
FreeSPS (active_sps);
}
/*!
*************************************************************************************
* \brief
* int GenerateSeq_parameter_set_NALU (void);
*
* \note
* Uses the global variables through GenerateSequenceParameterSet()
* and GeneratePictureParameterSet
*
* \return
* A NALU containing the Sequence ParameterSet
*
*************************************************************************************
*/
NALU_t *GenerateSeq_parameter_set_NALU (void)
{
NALU_t *n = AllocNALU(64000);
int RBSPlen = 0;
int NALUlen;
byte rbsp[MAXRBSPSIZE];
RBSPlen = GenerateSeq_parameter_set_rbsp (active_sps, rbsp);
NALUlen = RBSPtoNALU (rbsp, n, RBSPlen, NALU_TYPE_SPS, NALU_PRIORITY_HIGHEST, 0, 1);
n->startcodeprefix_len = 4;
return n;
}
/*!
*************************************************************************************
* \brief
* NALU_t *GeneratePic_parameter_set_NALU (int PPS_id);
*
* \note
* Uses the global variables through GenerateSequenceParameterSet()
* and GeneratePictureParameterSet
*
* \return
* A NALU containing the Picture Parameter Set
*
*************************************************************************************
*/
NALU_t *GeneratePic_parameter_set_NALU(int PPS_id)
{
NALU_t *n = AllocNALU(64000);
int RBSPlen = 0;
int NALUlen;
byte rbsp[MAXRBSPSIZE];
RBSPlen = GeneratePic_parameter_set_rbsp (PicParSet[PPS_id], rbsp);
NALUlen = RBSPtoNALU (rbsp, n, RBSPlen, NALU_TYPE_PPS, NALU_PRIORITY_HIGHEST, 0, 1);
n->startcodeprefix_len = 4;
return n;
}
/*!
************************************************************************
* \brief
* GenerateSequenceParameterSet: extracts info from global variables and
* generates sequence parameter set structure
*
* \par
* Function reads all kinds of values from several global variables,
* including input-> and image-> and fills in the sps. Many
* values are current hard-coded to defaults.
*
************************************************************************
*/
void GenerateSequenceParameterSet( seq_parameter_set_rbsp_t *sps, //!< Sequence Parameter Set to be filled
int SPS_id //!< SPS ID
)
{
unsigned i;
int SubWidthC [4]= { 1, 2, 2, 1};
int SubHeightC [4]= { 1, 2, 1, 1};
int frext_profile = ((IdentifyProfile()==FREXT_HP) ||
(IdentifyProfile()==FREXT_Hi10P) ||
(IdentifyProfile()==FREXT_Hi422) ||
(IdentifyProfile()==FREXT_Hi444));
// *************************************************************************
// Sequence Parameter Set
// *************************************************************************
assert (sps != NULL);
// Profile and Level should be calculated using the info from the config
// file. Calculation is hidden in IndetifyProfile() and IdentifyLevel()
sps->profile_idc = IdentifyProfile();
sps->level_idc = IdentifyLevel();
// needs to be set according to profile
sps->constrained_set0_flag = 0;
sps->constrained_set1_flag = 0;
sps->constrained_set2_flag = 0;
sps->constrained_set3_flag = 0;
// Parameter Set ID hard coded to zero
sps->seq_parameter_set_id = 0;
// Fidelity Range Extensions stuff
sps->bit_depth_luma_minus8 = input->BitDepthLuma - 8;
sps->bit_depth_chroma_minus8 = input->BitDepthChroma - 8;
img->lossless_qpprime_flag = input->lossless_qpprime_y_zero_flag & (sps->profile_idc==FREXT_Hi444);
img->residue_transform_flag = input->residue_transform_flag;
//! POC stuff:
//! The following values are hard-coded in init_poc(). Apparently,
//! the poc implementation covers only a subset of the poc functionality.
//! Here, the same subset is implemented. Changes in the POC stuff have
//! also to be reflected here
sps->log2_max_frame_num_minus4 = log2_max_frame_num_minus4;
sps->log2_max_pic_order_cnt_lsb_minus4 = log2_max_pic_order_cnt_lsb_minus4;
sps->pic_order_cnt_type = input->pic_order_cnt_type;
sps->num_ref_frames_in_pic_order_cnt_cycle = img->num_ref_frames_in_pic_order_cnt_cycle;
sps->delta_pic_order_always_zero_flag = img->delta_pic_order_always_zero_flag;
sps->offset_for_non_ref_pic = img->offset_for_non_ref_pic;
sps->offset_for_top_to_bottom_field = img->offset_for_top_to_bottom_field;
for (i=0; i<img->num_ref_frames_in_pic_order_cnt_cycle; i++)
{
sps->offset_for_ref_frame[i] = img->offset_for_ref_frame[i];
}
// End of POC stuff
// Number of Reference Frames
sps->num_ref_frames = input->num_ref_frames;
//required_frame_num_update_behaviour_flag hardcoded to zero
sps->gaps_in_frame_num_value_allowed_flag = FALSE; // double check
sps->frame_mbs_only_flag = !(input->PicInterlace || input->MbInterlace);
// Picture size, finally a simple one :-)
sps->pic_width_in_mbs_minus1 = ((input->img_width+img->auto_crop_right)/16) -1;
sps->pic_height_in_map_units_minus1 = (((input->img_height+img->auto_crop_bottom)/16)/ (2 - sps->frame_mbs_only_flag)) - 1;
// a couple of flags, simple
sps->mb_adaptive_frame_field_flag = (FRAME_CODING != input->MbInterlace);
sps->direct_8x8_inference_flag = input->directInferenceFlag;
// Sequence VUI not implemented, signalled as not present
sps->vui_parameters_present_flag = (input->rgb_input_flag && input->yuv_format==3);
sps->chroma_format_idc = input->yuv_format;
// This should be moved somewhere else.
{
int PicWidthInMbs, PicHeightInMapUnits, FrameHeightInMbs;
int width, height;
PicWidthInMbs = (sps->pic_width_in_mbs_minus1 +1);
PicHeightInMapUnits = (sps->pic_height_in_map_units_minus1 +1);
FrameHeightInMbs = ( 2 - sps->frame_mbs_only_flag ) * PicHeightInMapUnits;
width = PicWidthInMbs * MB_BLOCK_SIZE;
height = FrameHeightInMbs * MB_BLOCK_SIZE;
Co_located = alloc_colocated (width, height,sps->mb_adaptive_frame_field_flag);
}
// Fidelity Range Extensions stuff
if(frext_profile)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -