From 090f4d4b5ac7f78ac29f95d440168c989ad89ed7 Mon Sep 17 00:00:00 2001 From: Deb Mukherjee Date: Wed, 16 Jul 2014 09:37:13 -0700 Subject: [PATCH] Adds support for raw yuv files for 422/444 Adds support for raw yuv inputs in 422/444 sampling for use in profiles 1 and 3. New options added to vpxenc are: --i422 and --i444, which are to be used in conjunction with --width, --height, and --fps for proper raw yuv handling. A new option is added to vpxdec: --rawvideo, which enforces raw yuv video output for the bit-stream decoded irrespective of 420, 422 or 444 sampling. The existing options --i420 and --yv12 are specialized for use only for 420 content. Change-Id: I2e3028380709afa673bf2e2c25ad5e271a626055 --- tools_common.c | 2 +- vpxdec.c | 29 ++++++++++++++++++++++++++++- vpxenc.c | 32 +++++++++++++++++++++++++++----- vpxenc.h | 9 ++++++++- 4 files changed, 64 insertions(+), 8 deletions(-) diff --git a/tools_common.c b/tools_common.c index 8825528..b481579 100644 --- a/tools_common.c +++ b/tools_common.c @@ -83,7 +83,7 @@ int read_yuv_frame(struct VpxInputContext *input_ctx, vpx_image_t *yuv_frame) { struct FileTypeDetectionBuffer *detect = &input_ctx->detect; int plane = 0; int shortread = 0; - const int bytespp = (input_ctx->fmt & VPX_IMG_FMT_HIGH) ? 2 : 1; + const int bytespp = (yuv_frame->fmt & VPX_IMG_FMT_HIGH) ? 2 : 1; for (plane = 0; plane < 3; ++plane) { uint8_t *ptr; diff --git a/vpxdec.c b/vpxdec.c index 1b1cb05..58cd03e 100644 --- a/vpxdec.c +++ b/vpxdec.c @@ -55,6 +55,8 @@ static const arg_def_t use_i420 = ARG_DEF(NULL, "i420", 0, "Output raw I420 frames"); static const arg_def_t flipuvarg = ARG_DEF(NULL, "flipuv", 0, "Flip the chroma planes in the output"); +static const arg_def_t rawvideo = ARG_DEF(NULL, "rawvideo", 0, + "Output raw YUV frames"); static const arg_def_t noblitarg = ARG_DEF(NULL, "noblit", 0, "Don't process the decoded frames"); static const arg_def_t progressarg = ARG_DEF(NULL, "progress", 0, @@ -87,7 +89,7 @@ static const arg_def_t md5arg = ARG_DEF(NULL, "md5", 0, "Compute the MD5 sum of the decoded frame"); static const arg_def_t *all_args[] = { - &codecarg, &use_yv12, &use_i420, &flipuvarg, &noblitarg, + &codecarg, &use_yv12, &use_i420, &flipuvarg, &rawvideo, &noblitarg, &progressarg, &limitarg, &skiparg, &postprocarg, &summaryarg, &outputfile, &threadsarg, &verbosearg, &scalearg, &fb_arg, &md5arg, &error_concealment, &continuearg, @@ -507,6 +509,8 @@ int main_loop(int argc, const char **argv_) { int single_file; int use_y4m = 1; + int opt_yv12 = 0; + int opt_i420 = 0; vpx_codec_dec_cfg_t cfg = {0}; #if CONFIG_VP8_DECODER vp8_postproc_cfg_t vp8_pp_cfg = {0}; @@ -557,9 +561,13 @@ int main_loop(int argc, const char **argv_) { else if (arg_match(&arg, &use_yv12, argi)) { use_y4m = 0; flipuv = 1; + opt_yv12 = 1; } else if (arg_match(&arg, &use_i420, argi)) { use_y4m = 0; flipuv = 0; + opt_i420 = 1; + } else if (arg_match(&arg, &rawvideo, argi)) { + use_y4m = 0; } else if (arg_match(&arg, &flipuvarg, argi)) flipuv = 1; else if (arg_match(&arg, &noblitarg, argi)) @@ -918,6 +926,25 @@ int main_loop(int argc, const char **argv_) { } else { fputs(buf, outfile); } + } else { + if (frame_out == 1) { + // Check if --yv12 or --i420 options are consistent with the + // bit-stream decoded + if (opt_i420) { + if (img->fmt != VPX_IMG_FMT_I420 && + img->fmt != VPX_IMG_FMT_I42016) { + fprintf(stderr, "Cannot produce i420 output for bit-stream.\n"); + goto fail; + } + } + if (opt_yv12) { + if ((img->fmt != VPX_IMG_FMT_I420 && + img->fmt != VPX_IMG_FMT_YV12) || img->bit_depth != 8) { + fprintf(stderr, "Cannot produce yv12 output for bit-stream.\n"); + goto fail; + } + } + } } if (do_md5) { diff --git a/vpxenc.c b/vpxenc.c index fcb4368..d4bb034 100644 --- a/vpxenc.c +++ b/vpxenc.c @@ -133,6 +133,10 @@ static const arg_def_t use_yv12 = ARG_DEF(NULL, "yv12", 0, "Input file is YV12 "); static const arg_def_t use_i420 = ARG_DEF(NULL, "i420", 0, "Input file is I420 (default)"); +static const arg_def_t use_i422 = ARG_DEF(NULL, "i422", 0, + "Input file is I422"); +static const arg_def_t use_i444 = ARG_DEF(NULL, "i444", 0, + "Input file is I444"); static const arg_def_t codecarg = ARG_DEF(NULL, "codec", 1, "Codec to use"); static const arg_def_t passes = ARG_DEF("p", "passes", 1, @@ -233,7 +237,8 @@ static const arg_def_t lag_in_frames = ARG_DEF(NULL, "lag-in-frames", 1, "Max number of frames to lag"); static const arg_def_t *global_args[] = { - &use_yv12, &use_i420, &usage, &threads, &profile, + &use_yv12, &use_i420, &use_i422, &use_i444, + &usage, &threads, &profile, &width, &height, #if CONFIG_WEBM_IO &stereo_mode, @@ -636,7 +641,7 @@ static void parse_global_config(struct VpxEncoderConfig *global, char **argv) { memset(global, 0, sizeof(*global)); global->codec = get_vpx_encoder_by_index(0); global->passes = 0; - global->use_i420 = 1; + global->color_type = I420; /* Assign default deadline to good quality */ global->deadline = VPX_DL_GOOD_QUALITY; @@ -669,9 +674,13 @@ static void parse_global_config(struct VpxEncoderConfig *global, char **argv) { else if (arg_match(&arg, &rt_dl, argi)) global->deadline = VPX_DL_REALTIME; else if (arg_match(&arg, &use_yv12, argi)) - global->use_i420 = 0; + global->color_type = YV12; else if (arg_match(&arg, &use_i420, argi)) - global->use_i420 = 1; + global->color_type = I420; + else if (arg_match(&arg, &use_i422, argi)) + global->color_type = I422; + else if (arg_match(&arg, &use_i444, argi)) + global->color_type = I444; else if (arg_match(&arg, &quietarg, argi)) global->quiet = 1; else if (arg_match(&arg, &verbosearg, argi)) @@ -1593,7 +1602,20 @@ int main(int argc, const char **argv_) { argv = argv_dup(argc - 1, argv_ + 1); parse_global_config(&global, argv); - input.fmt = global.use_i420 ? VPX_IMG_FMT_I420 : VPX_IMG_FMT_YV12; + switch (global.color_type) { + case I420: + input.fmt = VPX_IMG_FMT_I420; + break; + case I422: + input.fmt = VPX_IMG_FMT_I422; + break; + case I444: + input.fmt = VPX_IMG_FMT_I444; + break; + case YV12: + input.fmt = VPX_IMG_FMT_YV12; + break; + } { /* Now parse each stream's parameters. Using a local scope here diff --git a/vpxenc.h b/vpxenc.h index a8c3722..3d6728e 100644 --- a/vpxenc.h +++ b/vpxenc.h @@ -22,6 +22,13 @@ enum TestDecodeFatality { TEST_DECODE_WARN, }; +typedef enum { + I420, // 4:2:0 8+ bit-depth + I422, // 4:2:2 8+ bit-depth + I444, // 4:4:4 8+ bit-depth + YV12, // 4:2:0 with uv flipped, only 8-bit depth +} ColorInputType; + struct VpxInterface; /* Configuration elements common to all streams. */ @@ -31,7 +38,7 @@ struct VpxEncoderConfig { int pass; int usage; int deadline; - int use_i420; + ColorInputType color_type; int quiet; int verbose; int limit; -- 2.7.4