mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-27 19:24:06 +00:00
Merge branch 'jeeb-cleanup'
Conflicts: src/encoder.c src/encoder.h
This commit is contained in:
commit
91ff5ff086
|
@ -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);
|
||||
if (stream->buffer)
|
||||
stream->bufferlen = alloc;
|
||||
//Clear just to be sure
|
||||
bitstream_clear_buffer(stream);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -225,6 +270,5 @@ void bitstream_flush(bitstream *stream)
|
|||
}
|
||||
}
|
||||
//Stream flushed, zero out the values
|
||||
bitstream_init(stream);
|
||||
bitstream_reinit(stream);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
35
src/config.c
35
src/config.c
|
@ -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]);
|
||||
|
|
|
@ -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");
|
||||
|
||||
if (cfg)
|
||||
config_destroy(cfg);
|
||||
free(encoder);
|
||||
|
||||
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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -441,4 +441,3 @@ uint8_t inter_get_merge_cand(encoder_control *encoder, int32_t x_cu, int32_t y_c
|
|||
|
||||
return candidates;
|
||||
}
|
||||
|
||||
|
|
|
@ -236,4 +236,3 @@ SUITE(sad_tests)
|
|||
|
||||
sad_setup(0);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue