This commit is contained in:
Marko Viitanen 2014-02-03 17:20:36 +02:00
commit d1b093c2ee
12 changed files with 174 additions and 54 deletions

View file

@ -67,15 +67,18 @@ int floor_log2(unsigned int n) {
/**
* \brief Initialize the Exp Golomb code table with desired number of values
* \param len table length to init
* \return 1 on success, 0 on failure
*
* Allocates g_exp_table with len*sizeof(bit_table) and fills it with exponential golomb codes
*/
void init_exp_golomb(uint32_t len)
int init_exp_golomb(uint32_t len)
{
uint32_t code_num;
uint32_t M;
uint32_t info;
g_exp_table = (bit_table*)malloc(len*sizeof(bit_table));
if(!g_exp_table)
return 0;
for (code_num = 0; code_num < len; code_num++) {
M = (uint32_t)floor_log2(code_num + 1);
@ -83,12 +86,55 @@ void init_exp_golomb(uint32_t len)
g_exp_table[code_num].len = M * 2 + 1;
g_exp_table[code_num].value = (1<<M) | info;
}
return 1;
}
/**
* \brief Clear bitstream
* \brief Create and initialize a new bitstream
*/
void bitstream_init(bitstream *stream)
bitstream *create_bitstream(int32_t width)
{
bitstream *stream = malloc(sizeof(bitstream));
if (!stream) {
fprintf(stderr, "Failed to allocate the bitstream object!\n");
return stream;
}
// Initialize the bitstream
bitstream_reinit(stream);
// Initialize buffer-related values
stream->output = NULL;
stream->buffer = NULL;
stream->buffer_pos = 0;
stream->bufferlen = 0;
// Alloc 2kB*width for bitstream buffer (for one coded frame)
bitstream_alloc(stream, 1024*2*width);
if (!stream->buffer) {
fprintf(stderr, "Failed to allocate the bitstream buffer!\n");
goto creation_failure;
}
//Clear buffer just to be sure
bitstream_clear_buffer(stream);
// Return the created bitstream
return stream;
creation_failure:
// In case of failure, free whatever was allocated
free(stream->buffer);
free(stream);
return NULL;
}
/**
* \brief Reinitialize bitstream
*/
void bitstream_reinit(bitstream *stream)
{
stream->cur_byte = 0;
stream->cur_bit = 0;
@ -103,9 +149,8 @@ void bitstream_init(bitstream *stream)
void bitstream_alloc(bitstream *stream, uint32_t alloc)
{
stream->buffer = (uint8_t*)malloc(alloc);
stream->bufferlen = alloc;
//Clear just to be sure
bitstream_clear_buffer(stream);
if (stream->buffer)
stream->bufferlen = alloc;
}
/**
@ -225,6 +270,5 @@ void bitstream_flush(bitstream *stream)
}
}
//Stream flushed, zero out the values
bitstream_init(stream);
bitstream_reinit(stream);
}

View file

@ -48,10 +48,11 @@ extern bit_table *g_exp_table;
int floor_log2(unsigned int n);
bitstream *create_bitstream(int32_t width);
void bitstream_alloc(bitstream* stream, uint32_t alloc);
void bitstream_free(bitstream *stream);
void bitstream_clear_buffer(bitstream* stream);
void bitstream_init(bitstream* stream);
void bitstream_reinit(bitstream *stream);
void bitstream_put(bitstream* stream, uint32_t data, uint8_t bits);
/* Use macros to force inlining */
@ -62,7 +63,7 @@ void bitstream_put(bitstream* stream, uint32_t data, uint8_t bits);
void bitstream_align(bitstream* stream);
void bitstream_align_zero(bitstream* stream);
void bitstream_flush(bitstream* stream);
void init_exp_golomb(uint32_t len);
int init_exp_golomb(uint32_t len);
/* In debug mode print out some extra info */

View file

@ -35,6 +35,11 @@
config *config_alloc()
{
config *cfg = (config *)malloc(sizeof(config));
if (!cfg) {
fprintf(stderr, "Failed to allocate a config object!\n");
return cfg;
}
memset(cfg, 0, sizeof(config));
return cfg;
}
@ -72,6 +77,26 @@ int config_destroy(config *cfg)
return 1;
}
/**
* \brief Allocates memory space for a string, and copies it
* \param char * string to copy
* \return a pointer to the copied string on success, null on failure
*/
char *copy_string(char *string)
{
// Allocate +1 for \0
char *allocated_string = (char *)malloc(strlen(string) + 1);
if (!allocated_string) {
fprintf(stderr, "Failed to allocate a string!\n");
return allocated_string;
}
// Copy the string to the new buffer
memcpy(allocated_string, string, strlen(string) + 1);
return allocated_string;
}
/**
* \brief Read configuration options from argv to the config struct
* \param cfg config object
@ -95,17 +120,13 @@ int config_read(config *cfg,int argc, char *argv[])
arg++;
switch(option) {
case 'i': // Input
// Allocate +1 for \0
cfg->input = (char *)malloc(strlen(argv[arg]) + 1);
memcpy(cfg->input, argv[arg], strlen(argv[arg]) + 1);
cfg->input = copy_string(argv[arg]);
break;
case 'o': // Output
cfg->output = (char *)malloc(strlen(argv[arg]) + 1);
memcpy(cfg->output, argv[arg], strlen(argv[arg]) + 1);
cfg->output = copy_string(argv[arg]);
break;
case 'd': // Debug
cfg->debug = (char *)malloc(strlen(argv[arg]) + 1);
memcpy(cfg->debug, argv[arg], strlen(argv[arg]) + 1);
cfg->debug = copy_string(argv[arg]);
break;
case 'w': // width
cfg->width = atoi(argv[arg]);

View file

@ -66,13 +66,13 @@ int main(int argc, char *argv[])
config *cfg = NULL; //!< Global configuration
FILE *input = NULL; //!< input file (YUV)
FILE *output = NULL; //!< output file (HEVC NAL stream)
encoder_control *encoder = NULL; //!< Encoder control struct
double psnr[3] = { 0.0, 0.0, 0.0 };
uint64_t curpos = 0;
uint64_t lastpos = 0;
#ifdef _DEBUG
FILE *recout = fopen("encrec_832x480_60.yuv","wb"); //!< reconstructed YUV output (only on debug mode)
#endif
encoder_control *encoder = (encoder_control*)malloc(sizeof(encoder_control));
// Windows needs all of the standard in/outputs to be set to _O_BINARY
#ifdef _WIN32
@ -85,7 +85,7 @@ int main(int argc, char *argv[])
cfg = config_alloc();
// If problem with configuration, print banner and shutdown
if (!config_init(cfg) || !config_read(cfg,argc,argv)) {
if (!cfg || !config_init(cfg) || !config_read(cfg,argc,argv)) {
fprintf(stderr, "/***********************************************/\r\n");
fprintf(stderr, " * Kvazaar HEVC Encoder v. " VERSION_STRING "*\r\n");
fprintf(stderr, " * Tampere University of Technology 2014 *\r\n");
@ -101,8 +101,9 @@ int main(int argc, char *argv[])
fprintf(stderr, " 1: all pictures are intra\r\n");
fprintf(stderr, " 2-N: every Nth picture is intra\r\n");
config_destroy(cfg);
free(encoder);
if (cfg)
config_destroy(cfg);
return EXIT_FAILURE;
}
@ -148,27 +149,12 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
// Initialization
init_tables();
init_exp_golomb(4096*8); //Allocate and init exp golomb table
scalinglist_init();
init_encoder_control(encoder, (bitstream*)malloc(sizeof(bitstream)));
encoder->ref = picture_list_init(MAX_REF_PIC_COUNT);
encoder = init_encoder_control(cfg);
if (!encoder)
return EXIT_FAILURE;
// Init bitstream
bitstream_init(encoder->stream);
encoder->stream->buffer_pos = 0;
encoder->stream->output = 0;
// Alloc 2kB*width for bitstream buffer (for one coded frame)
bitstream_alloc(encoder->stream, 1024*2*cfg->width);
// Config pointer to encoder struct
encoder->cfg = cfg;
// Set output file
encoder->output = output;
// Set CABAC output bitstream
cabac.stream = encoder->stream;
// input init (TODO: read from commandline / config)
encoder->bitdepth = 8;

View file

@ -229,10 +229,80 @@ void free_tables(void)
free(g_sig_last_scan[2][i]);
}
}
void init_encoder_control(encoder_control* control,bitstream* output)
encoder_control *init_encoder_control(config *cfg)
{
control->stream = output;
encoder_control *enc_c = NULL;
bitstream *stream = NULL;
picture_list *pic_list = NULL;
if (!cfg) {
fprintf(stderr, "Config object must not be null!\n");
goto init_failure;
}
// Allocate the main struct
enc_c = malloc(sizeof(encoder_control));
if(!enc_c){
fprintf(stderr, "Failed to allocate encoder_control!\n");
goto init_failure;
}
// Config pointer to encoder struct
enc_c->cfg = cfg;
// input init (TODO: read from commandline / config)
enc_c->bitdepth = 8;
enc_c->frame = 0;
enc_c->QP = enc_c->cfg->qp;
enc_c->in.video_format = FORMAT_420;
// deblocking filter
enc_c->deblock_enable = 1;
enc_c->beta_offset_div2 = 0;
enc_c->tc_offset_div2 = 0;
// SAO
enc_c->sao_enable = 1;
// Allocate the bitstream struct
stream = create_bitstream(enc_c->cfg->width);
if (!stream) {
fprintf(stderr, "Failed to allocate the bitstream object!\n");
goto init_failure;
}
enc_c->stream = stream;
// Set CABAC output bitstream
cabac.stream = enc_c->stream;
// Initialize tables
init_tables();
//Allocate and init exp golomb table
if (!init_exp_golomb(4096*8)) {
fprintf(stderr, "Failed to allocate the exp golomb code table, shutting down!\n");
goto init_failure;
}
// Initialize the scaling list
scalinglist_init();
pic_list = picture_list_init(MAX_REF_PIC_COUNT);
if(!pic_list) {
fprintf(stderr, "Failed to allocate the picture list!\n");
goto init_failure;
}
enc_c->ref = pic_list;
return enc_c;
init_failure:
// Free everything allocated in this function
free(pic_list);
free(stream);
free(enc_c);
return NULL;
}
void init_encoder_input(encoder_input *input, FILE *inputfile,
@ -1315,7 +1385,7 @@ void encode_coding_tree(encoder_control *encoder, uint16_t x_ctb,
}
/**
* Table 9-35 Binarization for intra_chroma_pred_mode
* Table 9-35 - Binarization for intra_chroma_pred_mode
* intra_chroma_pred_mode bin_string
* 4 0
* 0 100

View file

@ -82,7 +82,7 @@ typedef struct
void init_tables(void);
void free_tables(void);
void init_encoder_control(encoder_control *control, bitstream *output);
encoder_control *init_encoder_control(config *cfg);
void init_encoder_input(encoder_input *input, FILE* inputfile,
int32_t width, int32_t height);
void encode_one_frame(encoder_control *encoder);

View file

@ -441,4 +441,3 @@ uint8_t inter_get_merge_cand(encoder_control *encoder, int32_t x_cu, int32_t y_c
return candidates;
}

View file

@ -236,4 +236,3 @@ SUITE(sad_tests)
sad_setup(0);
}