diff options
author | Deb Mukherjee <debargha@google.com> | 2014-06-12 16:53:13 -0700 |
---|---|---|
committer | Deb Mukherjee <debargha@google.com> | 2014-07-05 16:00:54 -0700 |
commit | 5820c5d614a9efdba545f24f446d4605a62f40f2 (patch) | |
tree | cce18d663237a38b22c206aba649c7783c45c545 /y4minput.c | |
parent | 3643544fe0b6ff217a75f598b5257cf2c72a8908 (diff) | |
download | libvpx-5820c5d614a9efdba545f24f446d4605a62f40f2.tar libvpx-5820c5d614a9efdba545f24f446d4605a62f40f2.tar.gz libvpx-5820c5d614a9efdba545f24f446d4605a62f40f2.tar.bz2 libvpx-5820c5d614a9efdba545f24f446d4605a62f40f2.zip |
Adds support for reading and writing 10/12-bit y4m
The y4m extension used is the same as the one used in ffmpeg/x264.
The patch is adapted from the highbitdepth branch.
Also adds unit tests for y4m header parsing and md5 check
of the raw frame data, as well as y4m writing.
[build fix for Mac/VS by not using tuples with strings]
Change-Id: I40897ee37d289e4b6cea6fedc67047d692b8cb46
Diffstat (limited to 'y4minput.c')
-rw-r--r-- | y4minput.c | 125 |
1 files changed, 115 insertions, 10 deletions
diff --git a/y4minput.c b/y4minput.c index 90c5310a1..b005b71d3 100644 --- a/y4minput.c +++ b/y4minput.c @@ -737,15 +737,52 @@ int y4m_input_open(y4m_input *_y4m, FILE *_fin, char *_skip, int _nskip, return -1; } _y4m->vpx_fmt = VPX_IMG_FMT_I420; - _y4m->vpx_bps = 12; + _y4m->bps = 12; + _y4m->bit_depth = 8; 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; _y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h + 2 * ((_y4m->pic_w + 1) / 2) * ((_y4m->pic_h + 1) / 2); - /*Natively supported: no conversion required.*/ + /* 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, "420p10") == 0) { + _y4m->src_c_dec_h = 2; + _y4m->dst_c_dec_h = 2; + _y4m->src_c_dec_v = 2; + _y4m->dst_c_dec_v = 2; + _y4m->dst_buf_read_sz = 2 * (_y4m->pic_w * _y4m->pic_h + + 2 * ((_y4m->pic_w + 1) / 2) * + ((_y4m->pic_h + 1) / 2)); + /* Natively supported: no conversion required. */ + _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0; + _y4m->convert = y4m_convert_null; + _y4m->bit_depth = 10; + _y4m->bps = 15; + _y4m->vpx_fmt = VPX_IMG_FMT_I42016; + if (only_420) { + fprintf(stderr, "Unsupported conversion from 420p10 to 420jpeg\n"); + return -1; + } + } else if (strcmp(_y4m->chroma_type, "420p12") == 0) { + _y4m->src_c_dec_h = 2; + _y4m->dst_c_dec_h = 2; + _y4m->src_c_dec_v = 2; + _y4m->dst_c_dec_v = 2; + _y4m->dst_buf_read_sz = 2 * (_y4m->pic_w * _y4m->pic_h + + 2 * ((_y4m->pic_w + 1) / 2) * + ((_y4m->pic_h + 1) / 2)); + /* Natively supported: no conversion required. */ + _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0; + _y4m->convert = y4m_convert_null; + _y4m->bit_depth = 12; + _y4m->bps = 18; + _y4m->vpx_fmt = VPX_IMG_FMT_I42016; + if (only_420) { + fprintf(stderr, "Unsupported conversion from 420p12 to 420jpeg\n"); + return -1; + } } else if (strcmp(_y4m->chroma_type, "420mpeg2") == 0) { _y4m->src_c_dec_h = _y4m->dst_c_dec_h = _y4m->src_c_dec_v = _y4m->dst_c_dec_v = 2; _y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h; @@ -786,7 +823,7 @@ int y4m_input_open(y4m_input *_y4m, FILE *_fin, char *_skip, int _nskip, _y4m->convert = y4m_convert_422_420jpeg; } else { _y4m->vpx_fmt = VPX_IMG_FMT_I422; - _y4m->vpx_bps = 16; + _y4m->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 @@ -794,7 +831,39 @@ int y4m_input_open(y4m_input *_y4m, FILE *_fin, char *_skip, int _nskip, /*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, "422p10") == 0) { + _y4m->src_c_dec_h = 2; + _y4m->src_c_dec_v = 1; + _y4m->vpx_fmt = VPX_IMG_FMT_I42216; + _y4m->bps = 20; + _y4m->bit_depth = 10; + _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 = 2 * (_y4m->pic_w * _y4m->pic_h + + 2 * ((_y4m->pic_w + 1) / 2) * _y4m->pic_h); + _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0; + _y4m->convert = y4m_convert_null; + if (only_420) { + fprintf(stderr, "Unsupported conversion from 422p10 to 420jpeg\n"); + return -1; + } + } else if (strcmp(_y4m->chroma_type, "422p12") == 0) { + _y4m->src_c_dec_h = 2; + _y4m->src_c_dec_v = 1; + _y4m->vpx_fmt = VPX_IMG_FMT_I42216; + _y4m->bps = 24; + _y4m->bit_depth = 12; + _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 = 2 * (_y4m->pic_w * _y4m->pic_h + + 2 * ((_y4m->pic_w + 1) / 2) * _y4m->pic_h); + _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0; + _y4m->convert = y4m_convert_null; + if (only_420) { + fprintf(stderr, "Unsupported conversion from 422p12 to 420jpeg\n"); + return -1; + } } else if (strcmp(_y4m->chroma_type, "411") == 0) { _y4m->src_c_dec_h = 4; _y4m->dst_c_dec_h = 2; @@ -823,7 +892,7 @@ int y4m_input_open(y4m_input *_y4m, FILE *_fin, char *_skip, int _nskip, _y4m->convert = y4m_convert_444_420jpeg; } else { _y4m->vpx_fmt = VPX_IMG_FMT_I444; - _y4m->vpx_bps = 24; + _y4m->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; @@ -831,6 +900,36 @@ int y4m_input_open(y4m_input *_y4m, FILE *_fin, char *_skip, int _nskip, _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0; _y4m->convert = y4m_convert_null; } + } else if (strcmp(_y4m->chroma_type, "444p10") == 0) { + _y4m->src_c_dec_h = 1; + _y4m->src_c_dec_v = 1; + _y4m->vpx_fmt = VPX_IMG_FMT_I44416; + _y4m->bps = 30; + _y4m->bit_depth = 10; + _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 = 2 * 3 * _y4m->pic_w * _y4m->pic_h; + _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0; + _y4m->convert = y4m_convert_null; + if (only_420) { + fprintf(stderr, "Unsupported conversion from 444p10 to 420jpeg\n"); + return -1; + } + } else if (strcmp(_y4m->chroma_type, "444p12") == 0) { + _y4m->src_c_dec_h = 1; + _y4m->src_c_dec_v = 1; + _y4m->vpx_fmt = VPX_IMG_FMT_I44416; + _y4m->bps = 36; + _y4m->bit_depth = 12; + _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 = 2 * 3 * _y4m->pic_w * _y4m->pic_h; + _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0; + _y4m->convert = y4m_convert_null; + if (only_420) { + fprintf(stderr, "Unsupported conversion from 444p12 to 420jpeg\n"); + return -1; + } } else if (strcmp(_y4m->chroma_type, "444alpha") == 0) { _y4m->src_c_dec_h = 1; _y4m->src_c_dec_v = 1; @@ -847,7 +946,7 @@ int y4m_input_open(y4m_input *_y4m, FILE *_fin, char *_skip, int _nskip, _y4m->convert = y4m_convert_444_420jpeg; } else { _y4m->vpx_fmt = VPX_IMG_FMT_444A; - _y4m->vpx_bps = 32; + _y4m->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; @@ -871,7 +970,10 @@ int y4m_input_open(y4m_input *_y4m, FILE *_fin, char *_skip, int _nskip, _y4m->dst_buf_sz = _y4m->pic_w * _y4m->pic_h + 2 * ((_y4m->pic_w + _y4m->dst_c_dec_h - 1) / _y4m->dst_c_dec_h) * ((_y4m->pic_h + _y4m->dst_c_dec_v - 1) / _y4m->dst_c_dec_v); - _y4m->dst_buf = (unsigned char *)malloc(_y4m->dst_buf_sz); + if (_y4m->bit_depth == 8) + _y4m->dst_buf = (unsigned char *)malloc(_y4m->dst_buf_sz); + else + _y4m->dst_buf = (unsigned char *)malloc(2 * _y4m->dst_buf_sz); _y4m->aux_buf = (unsigned char *)malloc(_y4m->aux_buf_sz); return 0; } @@ -887,6 +989,7 @@ int y4m_input_fetch_frame(y4m_input *_y4m, FILE *_fin, vpx_image_t *_img) { int c_w; int c_h; int c_sz; + int bytes_per_sample = _y4m->bit_depth > 8 ? 2 : 1; /*Read and skip the frame header.*/ if (!file_read(frame, 6, _fin)) return 0; if (memcmp(frame, "FRAME", 5)) { @@ -924,14 +1027,16 @@ int y4m_input_fetch_frame(y4m_input *_y4m, FILE *_fin, vpx_image_t *_img) { _img->h = _img->d_h = _y4m->pic_h; _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; + _img->bps = _y4m->bps; /*Set up the buffer pointers.*/ - pic_sz = _y4m->pic_w * _y4m->pic_h; + pic_sz = _y4m->pic_w * _y4m->pic_h * bytes_per_sample; c_w = (_y4m->pic_w + _y4m->dst_c_dec_h - 1) / _y4m->dst_c_dec_h; + c_w *= bytes_per_sample; 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] = _img->stride[PLANE_ALPHA] = _y4m->pic_w; + _img->stride[PLANE_Y] = _img->stride[PLANE_ALPHA] = + _y4m->pic_w * bytes_per_sample; _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; |