mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-27 11:24:05 +00:00
Add extraction of fields according to source scan type
This commit is contained in:
parent
581ff95412
commit
68fcc67a16
|
@ -169,27 +169,42 @@ int main(int argc, char *argv[])
|
|||
uint32_t frames_done = 0;
|
||||
double psnr_sum[3] = { 0.0, 0.0, 0.0 };
|
||||
|
||||
int8_t field_parity = 0;
|
||||
kvz_picture *frame_in = NULL;
|
||||
|
||||
for (;;) {
|
||||
|
||||
kvz_picture *img_in = NULL;
|
||||
if (!feof(input) && (opts->frames == 0 || frames_read < opts->frames)) {
|
||||
|
||||
if (!feof(input) && (opts->frames == 0 || frames_read < opts->frames || field_parity == 1) ) {
|
||||
// Try to read an input frame.
|
||||
img_in = api->picture_alloc(encoder->in.width, encoder->in.height);
|
||||
if (!img_in) {
|
||||
if(field_parity == 0) frame_in = api->picture_alloc(opts->config->width, opts->config->height);
|
||||
if (!frame_in) {
|
||||
fprintf(stderr, "Failed to allocate image.\n");
|
||||
goto exit_failure;
|
||||
}
|
||||
|
||||
if (yuv_io_read(input, opts->config->width, opts->config->height, img_in)) {
|
||||
frames_read += 1;
|
||||
} else {
|
||||
// EOF or some error
|
||||
api->picture_free(img_in);
|
||||
img_in = NULL;
|
||||
if (!feof(input)) {
|
||||
fprintf(stderr, "Failed to read a frame %d\n", frames_read);
|
||||
goto exit_failure;
|
||||
if (field_parity == 0){
|
||||
if (yuv_io_read(input, opts->config->width, opts->config->height, frame_in)) {
|
||||
frames_read += 1;
|
||||
img_in = frame_in;
|
||||
} else {
|
||||
// EOF or some error
|
||||
api->picture_free(img_in);
|
||||
img_in = NULL;
|
||||
if (!feof(input)) {
|
||||
fprintf(stderr, "Failed to read a frame %d\n", frames_read);
|
||||
goto exit_failure;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (encoder->cfg->source_scan_type != 0){
|
||||
img_in = api->picture_alloc(encoder->in.width, encoder->in.height);
|
||||
yuv_io_extract_field(frame_in, encoder->cfg->source_scan_type, field_parity, img_in);
|
||||
if (field_parity == 1) api->picture_free(frame_in);
|
||||
field_parity ^= 1; //0->1 or 1->0
|
||||
}
|
||||
}
|
||||
|
||||
kvz_data_chunk* chunks_out = NULL;
|
||||
|
|
|
@ -474,8 +474,11 @@ void encoder_control_free(encoder_control_t *const encoder) {
|
|||
}
|
||||
|
||||
void encoder_control_input_init(encoder_control_t * const encoder,
|
||||
const int32_t width, const int32_t height)
|
||||
const int32_t width, int32_t height)
|
||||
{
|
||||
// Halve for interlaced content
|
||||
if (encoder->in.source_scan_type != 0) height /= 2;
|
||||
|
||||
encoder->in.width = width;
|
||||
encoder->in.height = height;
|
||||
encoder->in.real_width = width;
|
||||
|
|
41
src/yuv_io.c
41
src/yuv_io.c
|
@ -203,3 +203,44 @@ int yuv_io_write(FILE* file,
|
|||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Separate a single field from a frame.
|
||||
*
|
||||
* \param frame_in input frame to extract field from
|
||||
* \param source_scan_type scan type of input material (0: progressive, 1:top field first, 2:bottom field first)
|
||||
* \param field parity
|
||||
* \param field_out
|
||||
*
|
||||
* \return 1 on success, 0 on failure
|
||||
*/
|
||||
int yuv_io_extract_field(const kvz_picture *frame_in, unsigned source_scan_type, unsigned field_parity, kvz_picture *field_out)
|
||||
{
|
||||
if ((source_scan_type != 1) && (source_scan_type != 2)) return 0;
|
||||
if ((field_parity != 0) && (field_parity != 1)) return 0;
|
||||
|
||||
unsigned offset = 0;
|
||||
if (source_scan_type == 2) offset = frame_in->stride;
|
||||
|
||||
//Luma
|
||||
for (int i = 0; i < field_out->height; ++i){
|
||||
kvz_pixel *row_in = frame_in->y + CLIP(0, frame_in->height - 1, 2 * i) * frame_in->stride + offset;
|
||||
kvz_pixel *row_out = field_out->y + i * field_out->stride + offset;
|
||||
memcpy(row_out, row_in, sizeof(kvz_pixel) * frame_in->width);
|
||||
}
|
||||
|
||||
//Chroma
|
||||
for (int i = 0; i < field_out->height / 2; ++i){
|
||||
kvz_pixel *row_in = frame_in->u + CLIP(0, frame_in->height / 2 - 1, 2 * i) * frame_in->stride / 2 + offset / 2;
|
||||
kvz_pixel *row_out = field_out->u + i * field_out->stride / 2 + offset / 2;
|
||||
memcpy(row_out, row_in, sizeof(kvz_pixel) * frame_in->width / 2);
|
||||
}
|
||||
|
||||
for (int i = 0; i < field_out->height / 2; ++i){
|
||||
kvz_pixel *row_in = frame_in->v + CLIP(0, frame_in->height / 2 - 1, 2 * i) * frame_in->stride / 2 + offset / 2;
|
||||
kvz_pixel *row_out = field_out->v + i * field_out->stride / 2 + offset / 2;
|
||||
memcpy(row_out, row_in, sizeof(kvz_pixel) * frame_in->width / 2);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -39,4 +39,6 @@ int yuv_io_write(FILE* file,
|
|||
const kvz_picture *img,
|
||||
unsigned output_width, unsigned output_height);
|
||||
|
||||
int yuv_io_extract_field(const kvz_picture *frame_in, unsigned source_scan_type, unsigned field_parity, kvz_picture *field_out);
|
||||
|
||||
#endif // YUV_IO_H_
|
||||
|
|
Loading…
Reference in a new issue