Encoding of IPCM sequences working (only for input sequence with width and height divisible with 64)

This commit is contained in:
Marko Viitanen 2012-06-11 15:26:32 +03:00
parent e7cc5f8990
commit ee3a2744ef
5 changed files with 137 additions and 44 deletions

View file

@ -121,7 +121,7 @@
/* input init */
encoder->frame = 0;
encoder->QP = 1;
encoder->QP = 10;
init_encoder_input(&encoder->in, input, cfg->width, cfg->height);
/* Start coding cycle */

View file

@ -32,6 +32,7 @@ void init_encoder_control(encoder_control* control,bitstream* output)
void init_encoder_input(encoder_input* input,FILE* inputfile, uint32_t width, uint32_t height)
{
int i;
input->file = inputfile;
input->width = width;
input->height = height;
@ -50,18 +51,28 @@ void init_encoder_input(encoder_input* input,FILE* inputfile, uint32_t width, ui
input->cur_pic.yData = (uint8_t *)malloc(width*height);
input->cur_pic.uData = (uint8_t *)malloc((width*height)>>2);
input->cur_pic.vData = (uint8_t *)malloc((width*height)>>2);
/* Allocate memory for CU info */
input->cur_pic.CU = (CU_info*)malloc((MAX_DEPTH+1)*sizeof(CU_info*));
for(i=0; i < MAX_DEPTH+1; i++)
{
input->cur_pic.CU[i] = (CU_info*)malloc((input->height_in_LCU<<2)*(input->width_in_LCU<<2)*sizeof(CU_info));
memset(input->cur_pic.CU[i], 0, (input->height_in_LCU<<2)*(input->width_in_LCU<<2)*sizeof(CU_info));
}
}
void encode_one_frame(encoder_control* encoder)
{
//output parameters before first frame
/* output parameters before first frame */
if(encoder->frame == 0)
{
encode_seq_parameter_set(encoder);
bitstream_align(encoder->stream);
bitstream_flush(encoder->stream);
nal_write(encoder->output, encoder->stream->buffer, encoder->stream->buffer_pos, 1, NAL_SEQ_PARAMETER_SET, 0);
nal_write(encoder->output, encoder->stream->buffer, encoder->stream->buffer_pos, 1, NAL_SEQ_PARAMETER_SET, 1);
bitstream_clear_buffer(encoder->stream);
encode_pic_parameter_set(encoder);
@ -70,10 +81,11 @@ void encode_one_frame(encoder_control* encoder)
nal_write(encoder->output, encoder->stream->buffer, encoder->stream->buffer_pos, 1, NAL_PIC_PARAMETER_SET, 0);
bitstream_clear_buffer(encoder->stream);
/* First slice is IDR */
cabac_start(&cabac);
encoder->in.cur_pic.type = NAL_IDR_SLICE;
encode_slice_header(encoder);
bitstream_align(encoder->stream);
bitstream_align(encoder->stream);
encode_slice_data(encoder);
cabac_flush(&cabac);
bitstream_align(encoder->stream);
@ -81,18 +93,19 @@ void encode_one_frame(encoder_control* encoder)
nal_write(encoder->output, encoder->stream->buffer, encoder->stream->buffer_pos, 0, NAL_IDR_SLICE, 0);
bitstream_clear_buffer(encoder->stream);
}
else
else if(encoder->frame < 3)
{
/*
cabac_start(&cabac);
encoder->in.cur_pic.type = NAL_NONIDR_SLICE;
encode_slice_header(encoder);
bitstream_align(encoder->stream);
encode_slice_data(encoder);
cabac_flush(&cabac);
bitstream_align(encoder->stream);
bitstream_flush(encoder->stream);
nal_write(encoder->output, encoder->stream->buffer, encoder->stream->buffer_pos, 0, NAL_IDR_SLICE, 0);
nal_write(encoder->output, encoder->stream->buffer, encoder->stream->buffer_pos, 0, NAL_NONIDR_SLICE, 0);
bitstream_clear_buffer(encoder->stream);
*/
}
}
}
void encode_pic_parameter_set(encoder_control* encoder)
@ -181,11 +194,12 @@ void encode_seq_parameter_set(encoder_control* encoder)
//IF PCM
WRITE_U(encoder->stream, 1, 1, "pcm_loop_filter_disable_flag");
//endif
WRITE_U(encoder->stream, 0, 1, "temporal_id_nesting_flag");
WRITE_UE(encoder->stream, 0, "num_short_term_ref_pic_sets");
WRITE_U(encoder->stream, 0, 1, "long_term_ref_pics_present_flag");
WRITE_U(encoder->stream, 0, 2, "tiles_or_entropy_coding_sync_idc");
WRITE_U(encoder->stream, 0, 1, "sps_extension_flag");
WRITE_U(encoder->stream, 0, 1, "temporal_id_nesting_flag");
WRITE_UE(encoder->stream, 0, "num_short_term_ref_pic_sets");
WRITE_U(encoder->stream, 0, 1, "long_term_ref_pics_present_flag");
WRITE_U(encoder->stream, 0, 2, "tiles_or_entropy_coding_sync_idc");
WRITE_U(encoder->stream, 0, 1, "sps_extension_flag");
//WRITE_U(encoder->stream, 0, 8, "stuffing");
}
void encode_slice_header(encoder_control* encoder)
@ -204,13 +218,18 @@ void encode_slice_header(encoder_control* encoder)
WRITE_U(encoder->stream, 1, 1, "pic_output_flag");
//end if
//if( IdrPicFlag ) <- nal_unit_type == 5
WRITE_UE(encoder->stream, encoder->frame&1, "idr_pic_id");
if(encoder->in.cur_pic.type == NAL_IDR_SLICE)
{
WRITE_UE(encoder->stream, encoder->frame&3, "idr_pic_id");
WRITE_U(encoder->stream, 0, 1, "no_output_of_prior_pics_flag");
//else
/*
}
else
{
WRITE_U(encoder->stream, encoder->frame, 8, "pic_order_cnt_lsb");
WRITE_U(encoder->stream, 1, 1, "short_term_ref_pic_set_sps_flag");
WRITE_UE(encoder->stream, 0, "short_term_ref_pic_set_idx");
*/
}
//end if
//end if
/*
@ -228,34 +247,33 @@ cabac_ctx PartSizeSCModel;
void encode_slice_data(encoder_control* encoder)
{
uint16_t xCtb,yCtb;
cxt_init(&g_SplitFlagSCModel[0], encoder->QP, INIT_SPLIT_FLAG[0][0]);
cxt_init(&g_SplitFlagSCModel[1], encoder->QP, INIT_SPLIT_FLAG[0][1]);
cxt_init(&g_SplitFlagSCModel[2], encoder->QP, INIT_SPLIT_FLAG[0][2]);
//cxt_init(&PCMFlagSCModel, encoder->QP, 0);
/* Initialize contexts */
cxt_init(&g_SplitFlagSCModel[0], encoder->QP, INIT_SPLIT_FLAG[SLICE_I][0]);
cxt_init(&g_SplitFlagSCModel[1], encoder->QP, INIT_SPLIT_FLAG[SLICE_I][1]);
cxt_init(&g_SplitFlagSCModel[2], encoder->QP, INIT_SPLIT_FLAG[SLICE_I][2]);
cxt_init(&PartSizeSCModel, encoder->QP, 154);
g_SplitFlagSCModel[1].ucState = 47;
//SplitFlagSCModel.ucState = 15;
//PCMFlagSCModel.ucState = 0;
//PartSizeSCModel.ucState = 30;
//cxt_init(&cabac.ctx, 26, 87);
//g_SplitFlagSCModel[1].ucState = 47;
//g_SplitFlagSCModel[2].ucState = 36;
for(yCtb = 0; yCtb < encoder->in.height_in_LCU<<2; yCtb+=4)
for(yCtb = 0; yCtb < encoder->in.height_in_LCU; yCtb++)
{
uint8_t lastCUy = (yCtb == (encoder->in.height_in_LCU<<2)-1)?1:0;
for(xCtb = 0; xCtb < encoder->in.width_in_LCU<<2; xCtb+=4)
uint8_t lastCUy = (yCtb == (encoder->in.height_in_LCU-1))?1:0;
for(xCtb = 0; xCtb < encoder->in.width_in_LCU; xCtb++)
{
uint8_t lastCUx = (xCtb == (encoder->in.width_in_LCU<<2)-1)?1:0;
uint8_t lastCUx = (xCtb == (encoder->in.width_in_LCU-1))?1:0;
uint8_t depth = 0;
encode_coding_tree(encoder, xCtb,yCtb, depth);
encode_coding_tree(encoder, xCtb<<2,yCtb<<2, depth);
//Terminating bit
if(!lastCUx || !lastCUy)
{
cabac_encodeBinTrm(&cabac, 0);
}
else
{
cabac_encodeBinTrm(&cabac, 1);
}
}
}
}
@ -264,33 +282,81 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
{
int i,x,y;
uint8_t split_flag = (depth!=1)?1:0;
uint8_t split_model = 0;
//ToDo: GET REAL VALUE
if(xCtb > 0 && GET_SPLITDATA(&encoder->in.cur_pic.CU[depth][(xCtb>>(MAX_DEPTH-depth))-1+(yCtb>>(MAX_DEPTH-depth))*(encoder->in.width_in_LCU<<MAX_DEPTH)]) == 1)
{
split_model++;
}
//ToDo:
if(yCtb > 0 && xCtb > 0)
if(yCtb > 0 && GET_SPLITDATA(&encoder->in.cur_pic.CU[depth][(xCtb>>(MAX_DEPTH-depth))+((yCtb>>(MAX_DEPTH-depth))-1)*(encoder->in.width_in_LCU<<MAX_DEPTH)]) == 1)
{
split_model++;
}
cabac.ctx = &g_SplitFlagSCModel[split_model];
if((yCtb > 0 && xCtb > 0))
{
SplitFlagSCModel = &g_SplitFlagSCModel[2];
printf("Model: 2\n");
}
else if(yCtb > 0 || xCtb > 0)
{
SplitFlagSCModel = &g_SplitFlagSCModel[1];
printf("Model: 1\n");
}
else
{
SplitFlagSCModel = &g_SplitFlagSCModel[0];
printf("Model: 0\n");
}
cabac.ctx = SplitFlagSCModel;
cabac.ctx = SplitFlagSCModel;//&g_SplitFlagSCModel[split_model];
if(depth == 1)
{
cabac.ctx = &g_SplitFlagSCModel[0];
}
if(depth != 2)
/*
if((yCtb > 0 && xCtb > 0))
{
SplitFlagSCModel = &g_SplitFlagSCModel[2];
printf("Model: 2\n");
}
else if(yCtb > 0 || xCtb > 0)
{
SplitFlagSCModel = &g_SplitFlagSCModel[1];
printf("Model: 1\n");
}
else
{
SplitFlagSCModel = &g_SplitFlagSCModel[0];
printf("Model: 0\n");
}
cabac.ctx = SplitFlagSCModel;//&g_SplitFlagSCModel[split_model];
if(depth == 1)
{
cabac.ctx = &g_SplitFlagSCModel[0];
}
*/
if(depth != MAX_DEPTH)
{
SET_SPLITDATA(&encoder->in.cur_pic.CU[depth][xCtb>>(MAX_DEPTH-depth)+(yCtb>>(MAX_DEPTH-depth))*(encoder->in.width_in_LCU<<MAX_DEPTH)],split_flag);
CABAC_BIN(&cabac, split_flag, "SplitFlag");
if(split_flag)
{
uint8_t change = 2;
uint8_t change = 1<<(MAX_DEPTH-1-depth);
encode_coding_tree(encoder,xCtb,yCtb,depth+1);
encode_coding_tree(encoder,xCtb+change,yCtb,depth+1);
encode_coding_tree(encoder,xCtb,yCtb+change,depth+1);
@ -315,7 +381,7 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
printf("\tIPCMFlag = 1\n");
cabac_finish(&cabac);
WRITE_U(cabac.stream, 1, 1, "stop_bit");
WRITE_U(cabac.stream, 0, 1, "numSubseqIPCM_flag");
WRITE_U(cabac.stream, 0, 1, "numSubseqIPCM_flag");
bitstream_align(cabac.stream);
/* PCM sample */
{

View file

@ -24,6 +24,7 @@
#define MIN(a,b) (((a)<(b))?(a):(b))
#define LCU_WIDTH 64 /*!< Largest Coding Unit */
#define MAX_DEPTH 2
#define VERSION_STRING "0.1 "
#define VERSION 0.1

View file

@ -13,7 +13,7 @@
#ifndef __NAL_H
#define __NAL_H
enum { NAL_IDR_SLICE = 0x45, NAL_SEQ_PARAMETER_SET = 7, NAL_PIC_PARAMETER_SET = 8 };
enum { NAL_NONIDR_SLICE = 0x41,NAL_IDR_SLICE = 0x45, NAL_SEQ_PARAMETER_SET = 7, NAL_PIC_PARAMETER_SET = 8 };
void nal_write(FILE* output, uint8_t* buffer, uint32_t buffer_len, uint8_t nal_ref, uint8_t nal_type, uint8_t temporal_id);

View file

@ -20,6 +20,30 @@
* @{
*/
enum { CU_NOTSET = 0, CU_SKIP, CU_SPLIT, CU_INTRA, CU_INTER};
#define GET_SPLITDATA(CU) (((CU)->type==CU_SPLIT)?0:( (uint32_t)(CU)->typedata ))
#define SET_SPLITDATA(CU,flag) { (CU)->type=CU_SPLIT; (CU)->typedata=(void*)(flag); }
/*!
\brief Struct for CU info
*/
typedef struct
{
uint8_t mode;
uint32_t cost;
} CU_info_intra;
/*!
\brief Struct for CU info
*/
typedef struct
{
uint8_t type;
void* typedata;
} CU_info;
/*!
\brief Struct which contains all picture data
*/
@ -31,6 +55,8 @@ typedef struct
int width; /*!< \brief Picture width */
int height; /*!< \brief Picture height */
uint8_t referenced; /*!< \brief Is this picture referenced */
CU_info** CU; /*!< \brief info for each CU at each depth */
uint8_t type;
} picture;
/*!