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
This commit is contained in:
Родитель
ca752e3320
Коммит
090f4d4b5a
|
@ -83,7 +83,7 @@ int read_yuv_frame(struct VpxInputContext *input_ctx, vpx_image_t *yuv_frame) {
|
||||||
struct FileTypeDetectionBuffer *detect = &input_ctx->detect;
|
struct FileTypeDetectionBuffer *detect = &input_ctx->detect;
|
||||||
int plane = 0;
|
int plane = 0;
|
||||||
int shortread = 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) {
|
for (plane = 0; plane < 3; ++plane) {
|
||||||
uint8_t *ptr;
|
uint8_t *ptr;
|
||||||
|
|
29
vpxdec.c
29
vpxdec.c
|
@ -55,6 +55,8 @@ static const arg_def_t use_i420 = ARG_DEF(NULL, "i420", 0,
|
||||||
"Output raw I420 frames");
|
"Output raw I420 frames");
|
||||||
static const arg_def_t flipuvarg = ARG_DEF(NULL, "flipuv", 0,
|
static const arg_def_t flipuvarg = ARG_DEF(NULL, "flipuv", 0,
|
||||||
"Flip the chroma planes in the output");
|
"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,
|
static const arg_def_t noblitarg = ARG_DEF(NULL, "noblit", 0,
|
||||||
"Don't process the decoded frames");
|
"Don't process the decoded frames");
|
||||||
static const arg_def_t progressarg = ARG_DEF(NULL, "progress", 0,
|
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");
|
"Compute the MD5 sum of the decoded frame");
|
||||||
|
|
||||||
static const arg_def_t *all_args[] = {
|
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,
|
&progressarg, &limitarg, &skiparg, &postprocarg, &summaryarg, &outputfile,
|
||||||
&threadsarg, &verbosearg, &scalearg, &fb_arg,
|
&threadsarg, &verbosearg, &scalearg, &fb_arg,
|
||||||
&md5arg, &error_concealment, &continuearg,
|
&md5arg, &error_concealment, &continuearg,
|
||||||
|
@ -507,6 +509,8 @@ int main_loop(int argc, const char **argv_) {
|
||||||
|
|
||||||
int single_file;
|
int single_file;
|
||||||
int use_y4m = 1;
|
int use_y4m = 1;
|
||||||
|
int opt_yv12 = 0;
|
||||||
|
int opt_i420 = 0;
|
||||||
vpx_codec_dec_cfg_t cfg = {0};
|
vpx_codec_dec_cfg_t cfg = {0};
|
||||||
#if CONFIG_VP8_DECODER
|
#if CONFIG_VP8_DECODER
|
||||||
vp8_postproc_cfg_t vp8_pp_cfg = {0};
|
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)) {
|
else if (arg_match(&arg, &use_yv12, argi)) {
|
||||||
use_y4m = 0;
|
use_y4m = 0;
|
||||||
flipuv = 1;
|
flipuv = 1;
|
||||||
|
opt_yv12 = 1;
|
||||||
} else if (arg_match(&arg, &use_i420, argi)) {
|
} else if (arg_match(&arg, &use_i420, argi)) {
|
||||||
use_y4m = 0;
|
use_y4m = 0;
|
||||||
flipuv = 0;
|
flipuv = 0;
|
||||||
|
opt_i420 = 1;
|
||||||
|
} else if (arg_match(&arg, &rawvideo, argi)) {
|
||||||
|
use_y4m = 0;
|
||||||
} else if (arg_match(&arg, &flipuvarg, argi))
|
} else if (arg_match(&arg, &flipuvarg, argi))
|
||||||
flipuv = 1;
|
flipuv = 1;
|
||||||
else if (arg_match(&arg, &noblitarg, argi))
|
else if (arg_match(&arg, &noblitarg, argi))
|
||||||
|
@ -918,6 +926,25 @@ int main_loop(int argc, const char **argv_) {
|
||||||
} else {
|
} else {
|
||||||
fputs(buf, outfile);
|
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) {
|
if (do_md5) {
|
||||||
|
|
32
vpxenc.c
32
vpxenc.c
|
@ -133,6 +133,10 @@ static const arg_def_t use_yv12 = ARG_DEF(NULL, "yv12", 0,
|
||||||
"Input file is YV12 ");
|
"Input file is YV12 ");
|
||||||
static const arg_def_t use_i420 = ARG_DEF(NULL, "i420", 0,
|
static const arg_def_t use_i420 = ARG_DEF(NULL, "i420", 0,
|
||||||
"Input file is I420 (default)");
|
"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,
|
static const arg_def_t codecarg = ARG_DEF(NULL, "codec", 1,
|
||||||
"Codec to use");
|
"Codec to use");
|
||||||
static const arg_def_t passes = ARG_DEF("p", "passes", 1,
|
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");
|
"Max number of frames to lag");
|
||||||
|
|
||||||
static const arg_def_t *global_args[] = {
|
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,
|
&width, &height,
|
||||||
#if CONFIG_WEBM_IO
|
#if CONFIG_WEBM_IO
|
||||||
&stereo_mode,
|
&stereo_mode,
|
||||||
|
@ -636,7 +641,7 @@ static void parse_global_config(struct VpxEncoderConfig *global, char **argv) {
|
||||||
memset(global, 0, sizeof(*global));
|
memset(global, 0, sizeof(*global));
|
||||||
global->codec = get_vpx_encoder_by_index(0);
|
global->codec = get_vpx_encoder_by_index(0);
|
||||||
global->passes = 0;
|
global->passes = 0;
|
||||||
global->use_i420 = 1;
|
global->color_type = I420;
|
||||||
/* Assign default deadline to good quality */
|
/* Assign default deadline to good quality */
|
||||||
global->deadline = VPX_DL_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))
|
else if (arg_match(&arg, &rt_dl, argi))
|
||||||
global->deadline = VPX_DL_REALTIME;
|
global->deadline = VPX_DL_REALTIME;
|
||||||
else if (arg_match(&arg, &use_yv12, argi))
|
else if (arg_match(&arg, &use_yv12, argi))
|
||||||
global->use_i420 = 0;
|
global->color_type = YV12;
|
||||||
else if (arg_match(&arg, &use_i420, argi))
|
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))
|
else if (arg_match(&arg, &quietarg, argi))
|
||||||
global->quiet = 1;
|
global->quiet = 1;
|
||||||
else if (arg_match(&arg, &verbosearg, argi))
|
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);
|
argv = argv_dup(argc - 1, argv_ + 1);
|
||||||
parse_global_config(&global, argv);
|
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
|
/* Now parse each stream's parameters. Using a local scope here
|
||||||
|
|
9
vpxenc.h
9
vpxenc.h
|
@ -22,6 +22,13 @@ enum TestDecodeFatality {
|
||||||
TEST_DECODE_WARN,
|
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;
|
struct VpxInterface;
|
||||||
|
|
||||||
/* Configuration elements common to all streams. */
|
/* Configuration elements common to all streams. */
|
||||||
|
@ -31,7 +38,7 @@ struct VpxEncoderConfig {
|
||||||
int pass;
|
int pass;
|
||||||
int usage;
|
int usage;
|
||||||
int deadline;
|
int deadline;
|
||||||
int use_i420;
|
ColorInputType color_type;
|
||||||
int quiet;
|
int quiet;
|
||||||
int verbose;
|
int verbose;
|
||||||
int limit;
|
int limit;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче