Merge "Y4M input support for 4:2:2, 4:4:4, 4:4:4:4" into experimental

This commit is contained in:
John Koleszar 2013-05-06 22:20:00 -07:00 committed by Gerrit Code Review
commit f46fb71eb6
5 changed files with 96 additions and 40 deletions

1
configure vendored
View File

@ -250,6 +250,7 @@ EXPERIMENT_LIST="
multiple_arf
code_zerogroup
sb8x8
non420
"
CONFIG_LIST="
external_build

View File

@ -55,9 +55,11 @@ extern "C" {
VPX_IMG_FMT_YV12 = VPX_IMG_FMT_PLANAR | VPX_IMG_FMT_UV_FLIP | 1, /**< planar YVU */
VPX_IMG_FMT_I420 = VPX_IMG_FMT_PLANAR | 2,
VPX_IMG_FMT_VPXYV12 = VPX_IMG_FMT_PLANAR | VPX_IMG_FMT_UV_FLIP | 3, /** < planar 4:2:0 format with vpx color space */
VPX_IMG_FMT_VPXI420 = VPX_IMG_FMT_PLANAR | 4 /** < planar 4:2:0 format with vpx color space */
}
vpx_img_fmt_t; /**< alias for enum vpx_img_fmt */
VPX_IMG_FMT_VPXI420 = VPX_IMG_FMT_PLANAR | 4,
VPX_IMG_FMT_I422 = VPX_IMG_FMT_PLANAR | 5,
VPX_IMG_FMT_I444 = VPX_IMG_FMT_PLANAR | 6,
VPX_IMG_FMT_444A = VPX_IMG_FMT_PLANAR | VPX_IMG_FMT_HAS_ALPHA | 7
} vpx_img_fmt_t; /**< alias for enum vpx_img_fmt */
#if !defined(VPX_CODEC_DISABLE_COMPAT) || !VPX_CODEC_DISABLE_COMPAT
#define IMG_FMT_PLANAR VPX_IMG_FMT_PLANAR /**< \deprecated Use #VPX_IMG_FMT_PLANAR */

View File

@ -326,6 +326,7 @@ struct input_state {
unsigned int h;
struct vpx_rational framerate;
int use_i420;
int only_i420;
};
@ -1793,7 +1794,8 @@ void open_input_file(struct input_state *input) {
if (input->detect.buf_read == 4
&& file_is_y4m(input->file, &input->y4m, input->detect.buf)) {
if (y4m_input_open(&input->y4m, input->file, input->detect.buf, 4) >= 0) {
if (y4m_input_open(&input->y4m, input->file, input->detect.buf, 4,
input->only_i420) >= 0) {
input->file_type = FILE_TYPE_Y4M;
input->w = input->y4m.pic_w;
input->h = input->y4m.pic_h;
@ -2517,6 +2519,7 @@ int main(int argc, const char **argv_) {
input.framerate.num = 30;
input.framerate.den = 1;
input.use_i420 = 1;
input.only_i420 = 1;
/* First parse the global configuration values, because we want to apply
* other parameters on top of the default configuration provided by the
@ -2551,6 +2554,12 @@ int main(int argc, const char **argv_) {
if (!input.fn)
usage_exit();
#if CONFIG_NON420
/* Decide if other chroma subsamplings than 4:2:0 are supported */
if (global.codec->fourcc == VP9_FOURCC)
input.only_i420 = 0;
#endif
for (pass = global.pass ? global.pass - 1 : 0; pass < global.passes; pass++) {
int frames_in = 0, seen_frames = 0;
int64_t estimated_time_left = -1;

View File

@ -659,7 +659,8 @@ static void y4m_convert_null(y4m_input *_y4m, unsigned char *_dst,
unsigned char *_aux) {
}
int y4m_input_open(y4m_input *_y4m, FILE *_fin, char *_skip, int _nskip) {
int y4m_input_open(y4m_input *_y4m, FILE *_fin, char *_skip, int _nskip,
int only_420) {
char buffer[80];
int ret;
int i;
@ -701,6 +702,8 @@ int y4m_input_open(y4m_input *_y4m, FILE *_fin, char *_skip, int _nskip) {
"Only progressive scan handled.\n");
return -1;
}
_y4m->vpx_fmt = VPX_IMG_FMT_I420;
_y4m->vpx_bps = 12;
if (strcmp(_y4m->chroma_type, "420") == 0 ||
strcmp(_y4m->chroma_type, "420jpeg") == 0) {
_y4m->src_c_dec_h = _y4m->dst_c_dec_h = _y4m->src_c_dec_v = _y4m->dst_c_dec_v = 2;
@ -734,16 +737,30 @@ int y4m_input_open(y4m_input *_y4m, FILE *_fin, char *_skip, int _nskip) {
_y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 2 * ((_y4m->pic_w + 1) / 2) * _y4m->pic_h;
_y4m->convert = y4m_convert_422jpeg_420jpeg;
} else if (strcmp(_y4m->chroma_type, "422") == 0) {
_y4m->src_c_dec_h = _y4m->dst_c_dec_h = 2;
_y4m->src_c_dec_h = 2;
_y4m->src_c_dec_v = 1;
_y4m->dst_c_dec_v = 2;
_y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h;
/*Chroma filter required: read into the aux buf first.
We need to make two filter passes, so we need some extra space in the
aux buffer.*/
_y4m->aux_buf_read_sz = 2 * ((_y4m->pic_w + 1) / 2) * _y4m->pic_h;
_y4m->aux_buf_sz = _y4m->aux_buf_read_sz + ((_y4m->pic_w + 1) / 2) * _y4m->pic_h;
_y4m->convert = y4m_convert_422_420jpeg;
if (only_420) {
_y4m->dst_c_dec_h = 2;
_y4m->dst_c_dec_v = 2;
_y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h;
/*Chroma filter required: read into the aux buf first.
We need to make two filter passes, so we need some extra space in the
aux buffer.*/
_y4m->aux_buf_read_sz = 2 * ((_y4m->pic_w + 1) / 2) * _y4m->pic_h;
_y4m->aux_buf_sz = _y4m->aux_buf_read_sz +
((_y4m->pic_w + 1) / 2) * _y4m->pic_h;
_y4m->convert = y4m_convert_422_420jpeg;
} else {
_y4m->vpx_fmt = VPX_IMG_FMT_I422;
_y4m->vpx_bps = 16;
_y4m->dst_c_dec_h = _y4m->src_c_dec_h;
_y4m->dst_c_dec_v = _y4m->src_c_dec_v;
_y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h
+ 2 * ((_y4m->pic_w + 1) / 2) * _y4m->pic_h;
/*Natively supported: no conversion required.*/
_y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0;
_y4m->convert = y4m_convert_null;
}
} else if (strcmp(_y4m->chroma_type, "411") == 0) {
_y4m->src_c_dec_h = 4;
_y4m->dst_c_dec_h = 2;
@ -758,29 +775,52 @@ int y4m_input_open(y4m_input *_y4m, FILE *_fin, char *_skip, int _nskip) {
_y4m->convert = y4m_convert_411_420jpeg;
} else if (strcmp(_y4m->chroma_type, "444") == 0) {
_y4m->src_c_dec_h = 1;
_y4m->dst_c_dec_h = 2;
_y4m->src_c_dec_v = 1;
_y4m->dst_c_dec_v = 2;
_y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h;
/*Chroma filter required: read into the aux buf first.
We need to make two filter passes, so we need some extra space in the
aux buffer.*/
_y4m->aux_buf_read_sz = 2 * _y4m->pic_w * _y4m->pic_h;
_y4m->aux_buf_sz = _y4m->aux_buf_read_sz + ((_y4m->pic_w + 1) / 2) * _y4m->pic_h;
_y4m->convert = y4m_convert_444_420jpeg;
if (only_420) {
_y4m->dst_c_dec_h = 2;
_y4m->dst_c_dec_v = 2;
_y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h;
/*Chroma filter required: read into the aux buf first.
We need to make two filter passes, so we need some extra space in the
aux buffer.*/
_y4m->aux_buf_read_sz = 2 * _y4m->pic_w * _y4m->pic_h;
_y4m->aux_buf_sz = _y4m->aux_buf_read_sz +
((_y4m->pic_w + 1) / 2) * _y4m->pic_h;
_y4m->convert = y4m_convert_444_420jpeg;
} else {
_y4m->vpx_fmt = VPX_IMG_FMT_I444;
_y4m->vpx_bps = 24;
_y4m->dst_c_dec_h = _y4m->src_c_dec_h;
_y4m->dst_c_dec_v = _y4m->src_c_dec_v;
_y4m->dst_buf_read_sz = 3 * _y4m->pic_w * _y4m->pic_h;
/*Natively supported: no conversion required.*/
_y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0;
_y4m->convert = y4m_convert_null;
}
} else if (strcmp(_y4m->chroma_type, "444alpha") == 0) {
_y4m->src_c_dec_h = 1;
_y4m->dst_c_dec_h = 2;
_y4m->src_c_dec_v = 1;
_y4m->dst_c_dec_v = 2;
_y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h;
/*Chroma filter required: read into the aux buf first.
We need to make two filter passes, so we need some extra space in the
aux buffer.
The extra plane also gets read into the aux buf.
It will be discarded.*/
_y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 3 * _y4m->pic_w * _y4m->pic_h;
_y4m->convert = y4m_convert_444_420jpeg;
if (only_420) {
_y4m->dst_c_dec_h = 2;
_y4m->dst_c_dec_v = 2;
_y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h;
/*Chroma filter required: read into the aux buf first.
We need to make two filter passes, so we need some extra space in the
aux buffer.
The extra plane also gets read into the aux buf.
It will be discarded.*/
_y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 3 * _y4m->pic_w * _y4m->pic_h;
_y4m->convert = y4m_convert_444_420jpeg;
} else {
_y4m->vpx_fmt = VPX_IMG_FMT_444A;
_y4m->vpx_bps = 32;
_y4m->dst_c_dec_h = _y4m->src_c_dec_h;
_y4m->dst_c_dec_v = _y4m->src_c_dec_v;
_y4m->dst_buf_read_sz = 4 * _y4m->pic_w * _y4m->pic_h;
/*Natively supported: no conversion required.*/
_y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0;
_y4m->convert = y4m_convert_null;
}
} else if (strcmp(_y4m->chroma_type, "mono") == 0) {
_y4m->src_c_dec_h = _y4m->src_c_dec_v = 0;
_y4m->dst_c_dec_h = _y4m->dst_c_dec_v = 2;
@ -847,22 +887,23 @@ int y4m_input_fetch_frame(y4m_input *_y4m, FILE *_fin, vpx_image_t *_img) {
sizes, which would require a separate fread call for every row.*/
memset(_img, 0, sizeof(*_img));
/*Y4M has the planes in Y'CbCr order, which libvpx calls Y, U, and V.*/
_img->fmt = IMG_FMT_I420;
_img->fmt = _y4m->vpx_fmt;
_img->w = _img->d_w = _y4m->pic_w;
_img->h = _img->d_h = _y4m->pic_h;
/*This is hard-coded to 4:2:0 for now, as that's all VP8 supports.*/
_img->x_chroma_shift = 1;
_img->y_chroma_shift = 1;
_img->bps = 12;
_img->x_chroma_shift = _y4m->dst_c_dec_h >> 1;
_img->y_chroma_shift = _y4m->dst_c_dec_v >> 1;
_img->bps = _y4m->vpx_bps;
/*Set up the buffer pointers.*/
pic_sz = _y4m->pic_w * _y4m->pic_h;
c_w = (_y4m->pic_w + _y4m->dst_c_dec_h - 1) / _y4m->dst_c_dec_h;
c_h = (_y4m->pic_h + _y4m->dst_c_dec_v - 1) / _y4m->dst_c_dec_v;
c_sz = c_w * c_h;
_img->stride[PLANE_Y] = _y4m->pic_w;
_img->stride[PLANE_Y] = _img->stride[PLANE_ALPHA] = _y4m->pic_w;
_img->stride[PLANE_U] = _img->stride[PLANE_V] = c_w;
_img->planes[PLANE_Y] = _y4m->dst_buf;
_img->planes[PLANE_U] = _y4m->dst_buf + pic_sz;
_img->planes[PLANE_V] = _y4m->dst_buf + pic_sz + c_sz;
_img->planes[PLANE_ALPHA] = _y4m->dst_buf + pic_sz + 2 * c_sz;
return 1;
}

View File

@ -51,9 +51,12 @@ struct y4m_input {
y4m_convert_func convert;
unsigned char *dst_buf;
unsigned char *aux_buf;
enum vpx_img_fmt vpx_fmt;
int vpx_bps;
};
int y4m_input_open(y4m_input *_y4m, FILE *_fin, char *_skip, int _nskip);
int y4m_input_open(y4m_input *_y4m, FILE *_fin, char *_skip, int _nskip,
int only_420);
void y4m_input_close(y4m_input *_y4m);
int y4m_input_fetch_frame(y4m_input *_y4m, FILE *_fin, vpx_image_t *img);