mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-27 11:24:05 +00:00
Move input reading functions to yuv_input module.
Adds function read_yuv_frame and moves functions fill_after_frame and read_and_fill_frame_data from encoderstate to yuv_input.
This commit is contained in:
parent
4a7b86a43b
commit
970d0ec182
|
@ -150,6 +150,7 @@
|
|||
<ClCompile Include="..\..\src\sao.c" />
|
||||
<ClCompile Include="..\..\src\scalinglist.c" />
|
||||
<ClCompile Include="..\..\src\search.c" />
|
||||
<ClCompile Include="..\..\src\yuv_input.c" />
|
||||
<ClInclude Include="..\..\src\checkpoint.h" />
|
||||
<ClInclude Include="..\..\src\cli.h" />
|
||||
<ClInclude Include="..\..\src\cu.h" />
|
||||
|
|
|
@ -195,6 +195,9 @@
|
|||
<ClCompile Include="..\..\src\rate_control.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\yuv_input.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\global.h">
|
||||
|
|
|
@ -107,6 +107,7 @@ OBJS = \
|
|||
encoder_state-geometry.o \
|
||||
image.o \
|
||||
videoframe.o \
|
||||
yuv_input.o \
|
||||
strategies/strategies-picture.o \
|
||||
strategies/strategies-nal.o \
|
||||
strategies/strategies-dct.o \
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "encoderstate.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
@ -44,6 +43,7 @@
|
|||
#include "sao.h"
|
||||
#include "rdo.h"
|
||||
#include "rate_control.h"
|
||||
#include "yuv_input.h"
|
||||
|
||||
int encoder_state_match_children_of_previous_frame(encoder_state_t * const state) {
|
||||
int i;
|
||||
|
@ -860,45 +860,6 @@ void encode_one_frame(encoder_state_t * const state)
|
|||
//threadqueue_flush(main_state->encoder_control->threadqueue);
|
||||
}
|
||||
|
||||
static void fill_after_frame(unsigned height, unsigned array_width,
|
||||
unsigned array_height, pixel_t *data)
|
||||
{
|
||||
pixel_t* p = data + height * array_width;
|
||||
pixel_t* end = data + array_width * array_height;
|
||||
|
||||
while (p < end) {
|
||||
// Fill the line by copying the line above.
|
||||
memcpy(p, p - array_width, array_width);
|
||||
p += array_width;
|
||||
}
|
||||
}
|
||||
|
||||
static int read_and_fill_frame_data(FILE *file,
|
||||
unsigned width, unsigned height,
|
||||
unsigned array_width, pixel_t *data)
|
||||
{
|
||||
pixel_t* p = data;
|
||||
pixel_t* end = data + array_width * height;
|
||||
pixel_t fill_char;
|
||||
unsigned i;
|
||||
|
||||
while (p < end) {
|
||||
// Read the beginning of the line from input.
|
||||
if (width != fread(p, sizeof(unsigned char), width, file))
|
||||
return 0;
|
||||
|
||||
// Fill the rest with the last pixel value.
|
||||
fill_char = p[width - 1];
|
||||
|
||||
for (i = width; i < array_width; ++i) {
|
||||
p[i] = fill_char;
|
||||
}
|
||||
|
||||
p += array_width;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int read_one_frame(FILE* file, const encoder_state_t * const state, image_t *img_out)
|
||||
{
|
||||
unsigned width = state->encoder_control->in.real_width;
|
||||
|
@ -924,45 +885,27 @@ int read_one_frame(FILE* file, const encoder_state_t * const state, image_t *img
|
|||
}
|
||||
|
||||
// If GOP is present but no pictures found
|
||||
if (state->global->frame &&
|
||||
if (state->global->frame &&
|
||||
state->encoder_control->cfg->gop_len &&
|
||||
!gop_pictures_available) {
|
||||
int i;
|
||||
unsigned y_size = width * height;
|
||||
unsigned uv_size = (width >> 1) * (height >> 1);
|
||||
|
||||
for (i = 0; i < state->encoder_control->cfg->gop_len; i++, gop_pictures_available++) {
|
||||
if (state->encoder_control->cfg->frames && state->global->frame + gop_pictures_available >= state->encoder_control->cfg->frames) {
|
||||
for (int i = 0; i < state->encoder_control->cfg->gop_len; i++, gop_pictures_available++) {
|
||||
if (state->encoder_control->cfg->frames
|
||||
&& state->global->frame + gop_pictures_available >= state->encoder_control->cfg->frames) {
|
||||
if (gop_pictures_available) {
|
||||
gop_skip_frames = state->encoder_control->cfg->gop_len - gop_pictures_available;
|
||||
break;
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
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.
|
||||
if(!read_and_fill_frame_data(file, width, height, array_width, gop_pictures[i].source->y) ||
|
||||
!read_and_fill_frame_data(file, width >> 1, height >> 1, array_width >> 1, gop_pictures[i].source->u) ||
|
||||
!read_and_fill_frame_data(file, width >> 1, height >> 1, array_width >> 1, gop_pictures[i].source->v)) {
|
||||
if (gop_pictures_available) { gop_skip_frames = state->encoder_control->cfg->gop_len - gop_pictures_available; break; }
|
||||
else return 0;
|
||||
}
|
||||
} else {
|
||||
// Otherwise the data can be read directly to the array.
|
||||
if(y_size != fread(gop_pictures[i].source->y, sizeof(unsigned char), y_size, file) ||
|
||||
uv_size != fread(gop_pictures[i].source->u, sizeof(unsigned char), uv_size, file) ||
|
||||
uv_size != fread(gop_pictures[i].source->v, sizeof(unsigned char), uv_size, file)) {
|
||||
if (gop_pictures_available) { gop_skip_frames = state->encoder_control->cfg->gop_len - gop_pictures_available; break; }
|
||||
else return 0;
|
||||
if (!read_yuv_frame(file, width, height, array_width, array_height, gop_pictures[i].source)) {
|
||||
if (gop_pictures_available) {
|
||||
gop_skip_frames = state->encoder_control->cfg->gop_len - gop_pictures_available;
|
||||
break;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (height != array_height) {
|
||||
fill_after_frame(height, array_width, array_height, gop_pictures[i].source->y);
|
||||
fill_after_frame(height >> 1, array_width >> 1, array_height >> 1, gop_pictures[i].source->u);
|
||||
fill_after_frame(height >> 1, array_width >> 1, array_height >> 1, gop_pictures[i].source->v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If GOP is present, fetch the data from our GOP picture buffer
|
||||
|
@ -984,37 +927,9 @@ int read_one_frame(FILE* file, const encoder_state_t * const state, image_t *img
|
|||
memcpy(img_out->v, gop_pictures[cur_gop].source->v, (width >> 1) * (height >> 1));
|
||||
gop_pictures_available--;
|
||||
} else {
|
||||
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.
|
||||
if (!read_and_fill_frame_data(file, width, height, array_width,
|
||||
img_out->y) ||
|
||||
!read_and_fill_frame_data(file, width >> 1, height >> 1, array_width >> 1,
|
||||
img_out->u) ||
|
||||
!read_and_fill_frame_data(file, width >> 1, height >> 1, array_width >> 1,
|
||||
img_out->v))
|
||||
return 0;
|
||||
} else {
|
||||
// Otherwise the data can be read directly to the array.
|
||||
unsigned y_size = width * height;
|
||||
unsigned uv_size = (width >> 1) * (height >> 1);
|
||||
if (y_size != fread(img_out->y, sizeof(unsigned char),
|
||||
y_size, file) ||
|
||||
uv_size != fread(img_out->u, sizeof(unsigned char),
|
||||
uv_size, file) ||
|
||||
uv_size != fread(img_out->v, sizeof(unsigned char),
|
||||
uv_size, file))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (height != array_height) {
|
||||
fill_after_frame(height, array_width, array_height,
|
||||
img_out->y);
|
||||
fill_after_frame(height >> 1, array_width >> 1, array_height >> 1,
|
||||
img_out->u);
|
||||
fill_after_frame(height >> 1, array_width >> 1, array_height >> 1,
|
||||
img_out->v);
|
||||
}
|
||||
return read_yuv_frame(file, width, height, array_width, array_height, img_out);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
120
src/yuv_input.c
Normal file
120
src/yuv_input.c
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*****************************************************************************
|
||||
* This file is part of Kvazaar HEVC encoder.
|
||||
*
|
||||
* Copyright (C) 2013-2015 Tampere University of Technology and others (see
|
||||
* COPYING file).
|
||||
*
|
||||
* Kvazaar is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Kvazaar is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with Kvazaar. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* \file
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "yuv_input.h"
|
||||
|
||||
static void fill_after_frame(unsigned height, unsigned array_width,
|
||||
unsigned array_height, pixel_t *data)
|
||||
{
|
||||
pixel_t* p = data + height * array_width;
|
||||
pixel_t* end = data + array_width * array_height;
|
||||
|
||||
while (p < end) {
|
||||
// Fill the line by copying the line above.
|
||||
memcpy(p, p - array_width, array_width);
|
||||
p += array_width;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int read_and_fill_frame_data(FILE *file,
|
||||
unsigned width, unsigned height,
|
||||
unsigned array_width, pixel_t *data)
|
||||
{
|
||||
pixel_t* p = data;
|
||||
pixel_t* end = data + array_width * height;
|
||||
pixel_t fill_char;
|
||||
unsigned i;
|
||||
|
||||
while (p < end) {
|
||||
// Read the beginning of the line from input.
|
||||
if (width != fread(p, sizeof(unsigned char), width, file))
|
||||
return 0;
|
||||
|
||||
// Fill the rest with the last pixel value.
|
||||
fill_char = p[width - 1];
|
||||
|
||||
for (i = width; i < array_width; ++i) {
|
||||
p[i] = fill_char;
|
||||
}
|
||||
|
||||
p += array_width;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Read a single frame from a file.
|
||||
*
|
||||
* Read luma and chroma values from file. Extend pixels if the image buffer
|
||||
* is larger than the input image.
|
||||
*
|
||||
* \param file input file
|
||||
* \param input_width width of the input video in pixels
|
||||
* \param input_height height of the input video in pixels
|
||||
* \param array_width width of the image buffer in pixels
|
||||
* \param array_height height of the image buffer in pixels
|
||||
* \param img_out image buffer
|
||||
*
|
||||
* \return 1 on success, 0 on failure
|
||||
*/
|
||||
int read_yuv_frame(FILE* file,
|
||||
unsigned input_width, unsigned input_height,
|
||||
unsigned array_width, unsigned array_height,
|
||||
image_t *img_out)
|
||||
{
|
||||
const unsigned y_size = input_width * input_height;
|
||||
const unsigned uv_input_width = input_width / 2;
|
||||
const unsigned uv_input_height = input_height / 2;
|
||||
const unsigned uv_size = uv_input_width * uv_input_height;
|
||||
|
||||
const unsigned uv_array_width = array_width / 2;
|
||||
const unsigned uv_array_height = array_height / 2;
|
||||
|
||||
if (input_width == array_width) {
|
||||
// No need to extend pixels.
|
||||
const size_t pixel_size = sizeof(unsigned char);
|
||||
if (fread(img_out->y, pixel_size, y_size, file) != y_size) return 0;
|
||||
if (fread(img_out->u, pixel_size, uv_size, file) != uv_size) return 0;
|
||||
if (fread(img_out->v, pixel_size, uv_size, file) != uv_size) return 0;
|
||||
} else {
|
||||
// Need to copy pixels to fill the image in horizontal direction.
|
||||
if (!read_and_fill_frame_data(file, input_width, input_height, array_width, img_out->y)) return 0;
|
||||
if (!read_and_fill_frame_data(file, uv_input_width, uv_input_height, uv_array_width, img_out->u)) return 0;
|
||||
if (!read_and_fill_frame_data(file, uv_input_width, uv_input_height, uv_array_width, img_out->v)) return 0;
|
||||
}
|
||||
|
||||
if (input_height != array_height) {
|
||||
// Need to copy pixels to fill the image in vertical direction.
|
||||
fill_after_frame(input_height, array_width, array_height, img_out->y);
|
||||
fill_after_frame(uv_input_height, uv_array_width, uv_array_height, img_out->u);
|
||||
fill_after_frame(uv_input_height, uv_array_width, uv_array_height, img_out->v);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
36
src/yuv_input.h
Normal file
36
src/yuv_input.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*****************************************************************************
|
||||
* This file is part of Kvazaar HEVC encoder.
|
||||
*
|
||||
* Copyright (C) 2013-2015 Tampere University of Technology and others (see
|
||||
* COPYING file).
|
||||
*
|
||||
* Kvazaar is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Kvazaar is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with Kvazaar. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef YUV_INPUT_H_
|
||||
#define YUV_INPUT_H_
|
||||
|
||||
/*
|
||||
* \file
|
||||
* \brief Functions related to reading YUV input.
|
||||
*/
|
||||
|
||||
#include "global.h"
|
||||
|
||||
int read_yuv_frame(FILE* file,
|
||||
unsigned input_width, unsigned input_height,
|
||||
unsigned array_width, unsigned array_height,
|
||||
image_t *img_out);
|
||||
|
||||
#endif // YUV_INPUT_H_
|
Loading…
Reference in a new issue