From de2c4ab78eac2b75eca6a46a2d7c1843f2ac82e5 Mon Sep 17 00:00:00 2001 From: Yusuke Nakamura Date: Tue, 4 Feb 2014 19:50:39 +0900 Subject: [PATCH] Avoid reading one extra frame at the end of the input file. --- src/encmain.c | 8 ++++++-- src/encoder.c | 37 ++++++++++++++++++++++--------------- src/encoder.h | 2 +- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/encmain.c b/src/encmain.c index 30f5a4d5..54ff9343 100644 --- a/src/encmain.c +++ b/src/encmain.c @@ -181,12 +181,16 @@ int main(int argc, char *argv[]) encoder->in.cur_pic->pred_v = MALLOC(pixel, (cfg->width * cfg->height) >> 2); // Start coding cycle while data on input and not on the last frame - while(!feof(input) && (!cfg->frames || encoder->frame < cfg->frames)) { + while(!cfg->frames || encoder->frame < cfg->frames) { int32_t diff; double temp_psnr[3]; // Read one frame from the input - read_one_frame(input, encoder); + if (!read_one_frame(input, encoder)) { + if (!feof(input)) + printf("Failed to read a frame %d\n", encoder->frame); + break; + } // The actual coding happens here, after this function we have a coded frame encode_one_frame(encoder); diff --git a/src/encoder.c b/src/encoder.c index 477d3578..07d5f760 100644 --- a/src/encoder.c +++ b/src/encoder.c @@ -447,7 +447,7 @@ void fill_after_frame(FILE *file, unsigned height, unsigned array_width, } } -void read_and_fill_frame_data(FILE *file, unsigned width, unsigned height, +int read_and_fill_frame_data(FILE *file, unsigned width, unsigned height, unsigned array_width, pixel *data) { pixel* p = data; @@ -457,7 +457,8 @@ void read_and_fill_frame_data(FILE *file, unsigned width, unsigned height, while (p < end) { // Read the beginning of the line from input. - fread(p, sizeof(unsigned char), width, file); + if (width != fread(p, sizeof(unsigned char), width, file)) + return 0; // Fill the rest with the last pixel value. fill_char = p[width - 1]; @@ -468,9 +469,10 @@ void read_and_fill_frame_data(FILE *file, unsigned width, unsigned height, p += array_width; } + return 1; } -void read_one_frame(FILE* file, encoder_control* encoder) +int read_one_frame(FILE* file, encoder_control* encoder) { encoder_input* in = &encoder->in; unsigned width = in->real_width; @@ -480,20 +482,24 @@ void read_one_frame(FILE* file, encoder_control* encoder) if (width != array_width) { // In the case of frames not being aligned on 8 bit borders, bits need to be copied to fill them in. - read_and_fill_frame_data(file, width, height, array_width, - in->cur_pic->y_data); - read_and_fill_frame_data(file, width >> 1, height >> 1, array_width >> 1, - in->cur_pic->u_data); - read_and_fill_frame_data(file, width >> 1, height >> 1, array_width >> 1, - in->cur_pic->v_data); + if (!read_and_fill_frame_data(file, width, height, array_width, + in->cur_pic->y_data) || + !read_and_fill_frame_data(file, width >> 1, height >> 1, array_width >> 1, + in->cur_pic->u_data) || + !read_and_fill_frame_data(file, width >> 1, height >> 1, array_width >> 1, + in->cur_pic->v_data)) + return 0; } else { // Otherwise the data can be read directly to the array. - fread(in->cur_pic->y_data, sizeof(unsigned char), - width * height, file); - fread(in->cur_pic->u_data, sizeof(unsigned char), - (width >> 1) * (height >> 1), file); - fread(in->cur_pic->v_data, sizeof(unsigned char), - (width >> 1) * (height >> 1), file); + unsigned y_size = width * height; + unsigned uv_size = (width >> 1) * (height >> 1); + if (y_size != fread(in->cur_pic->y_data, sizeof(unsigned char), + y_size, file) || + uv_size != fread(in->cur_pic->u_data, sizeof(unsigned char), + uv_size, file) || + uv_size != fread(in->cur_pic->v_data, sizeof(unsigned char), + uv_size, file)) + return 0; } if (height != array_height) { @@ -504,6 +510,7 @@ void read_one_frame(FILE* file, encoder_control* encoder) fill_after_frame(file, height >> 1, array_width >> 1, array_height >> 1, in->cur_pic->v_data); } + return 1; } /** diff --git a/src/encoder.h b/src/encoder.h index 7edd94dc..939d51b5 100644 --- a/src/encoder.h +++ b/src/encoder.h @@ -86,7 +86,7 @@ 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); -void read_one_frame(FILE *file, encoder_control *encoder); +int read_one_frame(FILE *file, encoder_control *encoder); void encode_seq_parameter_set(encoder_control *encoder); void encode_pic_parameter_set(encoder_control *encoder);