From 70d9664fb25946afb062e674b365ea7a5348869d Mon Sep 17 00:00:00 2001 From: Dmitry Kovalev Date: Tue, 11 Feb 2014 21:12:23 -0800 Subject: [PATCH] Adding API to get vpx encoder/decoder interface. Change-Id: I137e5e6585356792913e1e84da6c0a439c5153a5 --- examples/decode_to_md5.c | 10 ++-- examples/decode_with_drops.c | 10 ++-- examples/postproc.c | 17 ++++--- examples/simple_decoder.c | 10 ++-- examples/simple_encoder.c | 38 ++++++++++------ examples/twopass_encoder.c | 41 ++++++++++------- examples/vpx_temporal_scalable_patterns.c | 34 ++++---------- tools_common.c | 76 +++++++++++++++++++++++++++---- tools_common.h | 15 +++++- vpxdec.c | 69 ++++++++++------------------ vpxenc.c | 67 ++++++++------------------- vpxenc.h | 4 +- 12 files changed, 209 insertions(+), 182 deletions(-) diff --git a/examples/decode_to_md5.c b/examples/decode_to_md5.c index 077513c..aabac60 100644 --- a/examples/decode_to_md5.c +++ b/examples/decode_to_md5.c @@ -82,9 +82,9 @@ int main(int argc, char **argv) { int frame_cnt = 0; FILE *outfile = NULL; vpx_codec_ctx_t codec; - vpx_codec_iface_t *iface = NULL; VpxVideoReader *reader = NULL; const VpxVideoInfo *info = NULL; + const VpxInterface *decoder = NULL; exec_name = argv[0]; @@ -100,13 +100,13 @@ int main(int argc, char **argv) { info = vpx_video_reader_get_info(reader); - iface = get_codec_interface(info->codec_fourcc); - if (!iface) + decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc); + if (!decoder) die("Unknown input codec."); - printf("Using %s\n", vpx_codec_iface_name(iface)); + printf("Using %s\n", vpx_codec_iface_name(decoder->interface())); - if (vpx_codec_dec_init(&codec, iface, NULL, 0)) + if (vpx_codec_dec_init(&codec, decoder->interface(), NULL, 0)) die_codec(&codec, "Failed to initialize decoder"); while (vpx_video_reader_read_frame(reader)) { diff --git a/examples/decode_with_drops.c b/examples/decode_with_drops.c index e8fc076..c6f7d43 100644 --- a/examples/decode_with_drops.c +++ b/examples/decode_with_drops.c @@ -76,7 +76,7 @@ int main(int argc, char **argv) { int frame_cnt = 0; FILE *outfile = NULL; vpx_codec_ctx_t codec; - vpx_codec_iface_t *iface = NULL; + const VpxInterface *decoder = NULL; VpxVideoReader *reader = NULL; const VpxVideoInfo *info = NULL; int n = 0; @@ -104,13 +104,13 @@ int main(int argc, char **argv) { info = vpx_video_reader_get_info(reader); - iface = get_codec_interface(info->codec_fourcc); - if (!iface) + decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc); + if (!decoder) die("Unknown input codec."); - printf("Using %s\n", vpx_codec_iface_name(iface)); + printf("Using %s\n", vpx_codec_iface_name(decoder->interface())); - if (vpx_codec_dec_init(&codec, iface, NULL, 0)) + if (vpx_codec_dec_init(&codec, decoder->interface(), NULL, 0)) die_codec(&codec, "Failed to initialize decoder."); while (vpx_video_reader_read_frame(reader)) { diff --git a/examples/postproc.c b/examples/postproc.c index 7281f1e..2912fe6 100644 --- a/examples/postproc.c +++ b/examples/postproc.c @@ -64,8 +64,8 @@ int main(int argc, char **argv) { FILE *outfile = NULL; vpx_codec_ctx_t codec; vpx_codec_err_t res; - vpx_codec_iface_t *iface = NULL; VpxVideoReader *reader = NULL; + const VpxInterface *decoder = NULL; const VpxVideoInfo *info = NULL; exec_name = argv[0]; @@ -82,17 +82,16 @@ int main(int argc, char **argv) { info = vpx_video_reader_get_info(reader); - iface = get_codec_interface(info->codec_fourcc); - if (!iface) + decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc); + if (!decoder) die("Unknown input codec."); - printf("Using %s\n", vpx_codec_iface_name(iface)); + printf("Using %s\n", vpx_codec_iface_name(decoder->interface())); - res = vpx_codec_dec_init(&codec, iface, NULL, VPX_CODEC_USE_POSTPROC); - if (res == VPX_CODEC_INCAPABLE) { - printf("NOTICE: Postproc not supported.\n"); - res = vpx_codec_dec_init(&codec, iface, NULL, 0); - } + res = vpx_codec_dec_init(&codec, decoder->interface(), NULL, + VPX_CODEC_USE_POSTPROC); + if (res == VPX_CODEC_INCAPABLE) + die_codec(&codec, "Postproc not supported by this decoder."); if (res) die_codec(&codec, "Failed to initialize decoder."); diff --git a/examples/simple_decoder.c b/examples/simple_decoder.c index 4dc9308..b0ca77d 100644 --- a/examples/simple_decoder.c +++ b/examples/simple_decoder.c @@ -101,8 +101,8 @@ int main(int argc, char **argv) { int frame_cnt = 0; FILE *outfile = NULL; vpx_codec_ctx_t codec; - vpx_codec_iface_t *iface = NULL; VpxVideoReader *reader = NULL; + const VpxInterface *decoder = NULL; const VpxVideoInfo *info = NULL; exec_name = argv[0]; @@ -119,13 +119,13 @@ int main(int argc, char **argv) { info = vpx_video_reader_get_info(reader); - iface = get_codec_interface(info->codec_fourcc); - if (!iface) + decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc); + if (!decoder) die("Unknown input codec."); - printf("Using %s\n", vpx_codec_iface_name(iface)); + printf("Using %s\n", vpx_codec_iface_name(decoder->interface())); - if (vpx_codec_dec_init(&codec, iface, NULL, 0)) + if (vpx_codec_dec_init(&codec, decoder->interface(), NULL, 0)) die_codec(&codec, "Failed to initialize decoder."); while (vpx_video_reader_read_frame(reader)) { diff --git a/examples/simple_encoder.c b/examples/simple_encoder.c index 5076054..2e7c7a6 100644 --- a/examples/simple_encoder.c +++ b/examples/simple_encoder.c @@ -86,18 +86,16 @@ #include #define VPX_CODEC_DISABLE_COMPAT 1 -#include "vpx/vp8cx.h" #include "vpx/vpx_encoder.h" #include "./tools_common.h" #include "./video_writer.h" -#define interface (vpx_codec_vp8_cx()) - static const char *exec_name; void usage_exit() { - fprintf(stderr, "Usage: %s \n", exec_name); + fprintf(stderr, "Usage: %s \n", + exec_name); exit(EXIT_FAILURE); } @@ -110,17 +108,27 @@ int main(int argc, char **argv) { vpx_codec_err_t res; VpxVideoInfo info = {0}; VpxVideoWriter *writer = NULL; + const VpxInterface *encoder = NULL; const int fps = 30; // TODO(dkovalev) add command line argument const int bitrate = 200; // kbit/s TODO(dkovalev) add command line argument + const char *const codec_arg = argv[1]; + const char *const width_arg = argv[2]; + const char *const height_arg = argv[3]; + const char *const infile_arg = argv[4]; + const char *const outfile_arg = argv[5]; exec_name = argv[0]; - if (argc != 5) + if (argc != 6) die("Invalid number of arguments"); - info.codec_fourcc = VP8_FOURCC; - info.frame_width = strtol(argv[1], NULL, 0); - info.frame_height = strtol(argv[2], NULL, 0); + encoder = get_vpx_encoder_by_name(codec_arg); + if (!encoder) + die("Unsupported codec."); + + info.codec_fourcc = encoder->fourcc; + info.frame_width = strtol(width_arg, NULL, 0); + info.frame_height = strtol(height_arg, NULL, 0); info.time_base.numerator = 1; info.time_base.denominator = fps; @@ -136,9 +144,9 @@ int main(int argc, char **argv) { die("Failed to allocate image."); } - printf("Using %s\n", vpx_codec_iface_name(interface)); + printf("Using %s\n", vpx_codec_iface_name(encoder->interface())); - res = vpx_codec_enc_config_default(interface, &cfg, 0); + res = vpx_codec_enc_config_default(encoder->interface(), &cfg, 0); if (res) die_codec(&codec, "Failed to get default codec config."); @@ -148,14 +156,14 @@ int main(int argc, char **argv) { cfg.g_timebase.den = info.time_base.denominator; cfg.rc_target_bitrate = bitrate; - writer = vpx_video_writer_open(argv[4], kContainerIVF, &info); + writer = vpx_video_writer_open(outfile_arg, kContainerIVF, &info); if (!writer) - die("Failed to open %s for writing.", argv[4]); + die("Failed to open %s for writing.", outfile_arg); - if (!(infile = fopen(argv[3], "rb"))) - die("Failed to open %s for reading.", argv[3]); + if (!(infile = fopen(infile_arg, "rb"))) + die("Failed to open %s for reading.", infile_arg); - if (vpx_codec_enc_init(&codec, interface, &cfg, 0)) + if (vpx_codec_enc_init(&codec, encoder->interface(), &cfg, 0)) die_codec(&codec, "Failed to initialize encoder"); while (vpx_img_read(&raw, infile)) { diff --git a/examples/twopass_encoder.c b/examples/twopass_encoder.c index 93b6150..f16db66 100644 --- a/examples/twopass_encoder.c +++ b/examples/twopass_encoder.c @@ -53,18 +53,16 @@ #include #define VPX_CODEC_DISABLE_COMPAT 1 -#include "vpx/vp8cx.h" #include "vpx/vpx_encoder.h" #include "./tools_common.h" #include "./video_writer.h" -#define interface (vpx_codec_vp8_cx()) - static const char *exec_name; void usage_exit() { - fprintf(stderr, "Usage: %s \n", exec_name); + fprintf(stderr, "Usage: %s \n", + exec_name); exit(EXIT_FAILURE); } @@ -130,18 +128,29 @@ int main(int argc, char **argv) { vpx_codec_err_t res; vpx_fixed_buf_t stats = {0}; VpxVideoInfo info = {0}; + const VpxInterface *encoder = NULL; int pass; const int fps = 30; // TODO(dkovalev) add command line argument const int bitrate = 200; // kbit/s TODO(dkovalev) add command line argument - - if (argc != 5) + const char *const codec_arg = argv[1]; + const char *const width_arg = argv[2]; + const char *const height_arg = argv[3]; + const char *const infile_arg = argv[4]; + const char *const outfile_arg = argv[5]; + exec_name = argv[0]; + + if (argc != 6) die("Invalid number of arguments."); - info.codec_fourcc = VP8_FOURCC; + encoder = get_vpx_encoder_by_name(codec_arg); + if (!encoder) + die("Unsupported codec."); + + info.codec_fourcc = encoder->fourcc; info.time_base.numerator = 1; info.time_base.denominator = fps; - info.frame_width = strtol(argv[1], NULL, 0); - info.frame_height = strtol(argv[2], NULL, 0); + info.frame_width = strtol(width_arg, NULL, 0); + info.frame_height = strtol(height_arg, NULL, 0); if (info.frame_width <= 0 || info.frame_height <= 0 || @@ -155,13 +164,13 @@ int main(int argc, char **argv) { die("Failed to allocate image", info.frame_width, info.frame_height); } - writer = vpx_video_writer_open(argv[4], kContainerIVF, &info); + writer = vpx_video_writer_open(outfile_arg, kContainerIVF, &info); if (!writer) - die("Failed to open %s for writing", argv[4]); + die("Failed to open %s for writing", outfile_arg); - printf("Using %s\n", vpx_codec_iface_name(interface)); + printf("Using %s\n", vpx_codec_iface_name(encoder->interface())); - res = vpx_codec_enc_config_default(interface, &cfg, 0); + res = vpx_codec_enc_config_default(encoder->interface(), &cfg, 0); if (res) die_codec(&codec, "Failed to get default codec config."); @@ -181,10 +190,10 @@ int main(int argc, char **argv) { cfg.rc_twopass_stats_in = stats; } - if (!(infile = fopen(argv[3], "rb"))) - die("Failed to open %s for reading", argv[3]); + if (!(infile = fopen(infile_arg, "rb"))) + die("Failed to open %s for reading", infile_arg); - if (vpx_codec_enc_init(&codec, interface, &cfg, 0)) + if (vpx_codec_enc_init(&codec, encoder->interface(), &cfg, 0)) die_codec(&codec, "Failed to initialize encoder"); while (vpx_img_read(&raw, infile)) { diff --git a/examples/vpx_temporal_scalable_patterns.c b/examples/vpx_temporal_scalable_patterns.c index 11d331b..c40450e 100644 --- a/examples/vpx_temporal_scalable_patterns.c +++ b/examples/vpx_temporal_scalable_patterns.c @@ -360,9 +360,7 @@ int main(int argc, char **argv) { int flag_periodicity = 1; int max_intra_size_pct; vpx_svc_layer_id_t layer_id = {0, 0}; - char *codec_type; - vpx_codec_iface_t *(*interface)(void); - unsigned int fourcc; + const VpxInterface *encoder = NULL; struct VpxInputContext input_ctx = {0}; exec_name = argv[0]; @@ -373,23 +371,11 @@ int main(int argc, char **argv) { argv[0]); } - codec_type = argv[3]; - if (strncmp(codec_type, "vp9", 3) == 0) { -#if CONFIG_VP9_ENCODER - interface = vpx_codec_vp9_cx; - fourcc = VP9_FOURCC; -#else - die("Encoder vp9 selected but not configured"); -#endif - } else { -#if CONFIG_VP8_ENCODER - interface = vpx_codec_vp8_cx; - fourcc = VP8_FOURCC; -#else - die("Encoder vp8 selected but not configured"); -#endif - } - printf("Using %s\n", vpx_codec_iface_name(interface())); + encoder = get_vpx_encoder_by_name(argv[3]); + if (!encoder) + die("Unsupported codec."); + + printf("Using %s\n", vpx_codec_iface_name(encoder->interface())); width = strtol(argv[4], NULL, 0); height = strtol(argv[5], NULL, 0); @@ -411,7 +397,7 @@ int main(int argc, char **argv) { } // Populate encoder configuration. - res = vpx_codec_enc_config_default(interface(), &cfg, 0); + res = vpx_codec_enc_config_default(encoder->interface(), &cfg, 0); if (res) { printf("Failed to get config: %s\n", vpx_codec_err_to_string(res)); return EXIT_FAILURE; @@ -467,7 +453,7 @@ int main(int argc, char **argv) { for (i = 0; i < cfg.ts_number_layers; ++i) { char file_name[PATH_MAX]; VpxVideoInfo info; - info.codec_fourcc = fourcc; + info.codec_fourcc = encoder->fourcc; info.frame_width = cfg.g_w; info.frame_height = cfg.g_h; info.time_base.numerator = cfg.g_timebase.num; @@ -482,12 +468,12 @@ int main(int argc, char **argv) { cfg.ss_number_layers = 1; // Initialize codec. - if (vpx_codec_enc_init(&codec, interface(), &cfg, 0)) + if (vpx_codec_enc_init(&codec, encoder->interface(), &cfg, 0)) die_codec(&codec, "Failed to initialize encoder"); vpx_codec_control(&codec, VP8E_SET_CPUUSED, -6); vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, 1); - if (strncmp(codec_type, "vp9", 3) == 0) { + if (strncmp(encoder->name, "vp9", 3) == 0) { vpx_codec_control(&codec, VP8E_SET_CPUUSED, 3); vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, 0); if (vpx_codec_control(&codec, VP9E_SET_SVC, 1)) { diff --git a/tools_common.c b/tools_common.c index 5354687..5a1b701 100644 --- a/tools_common.c +++ b/tools_common.c @@ -15,6 +15,10 @@ #include #include +#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER +#include "vpx/vp8cx.h" +#endif + #if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER #include "vpx/vp8dx.h" #endif @@ -144,19 +148,75 @@ int read_yuv_frame(struct VpxInputContext *input_ctx, vpx_image_t *yuv_frame) { return shortread; } -vpx_codec_iface_t *get_codec_interface(unsigned int fourcc) { - switch (fourcc) { +static const VpxInterface vpx_encoders[] = { +#if CONFIG_VP8_ENCODER + {"vp8", VP8_FOURCC, &vpx_codec_vp8_cx}, +#endif + +#if CONFIG_VP9_ENCODER + {"vp9", VP9_FOURCC, &vpx_codec_vp9_cx}, +#endif +}; + +int get_vpx_encoder_count() { + return sizeof(vpx_encoders) / sizeof(vpx_encoders[0]); +} + +const VpxInterface *get_vpx_encoder_by_index(int i) { + return &vpx_encoders[i]; +} + +const VpxInterface *get_vpx_encoder_by_name(const char *name) { + int i; + + for (i = 0; i < get_vpx_encoder_count(); ++i) { + const VpxInterface *encoder = get_vpx_encoder_by_index(i); + if (strcmp(encoder->name, name) == 0) + return encoder; + } + + return NULL; +} + +static const VpxInterface vpx_decoders[] = { #if CONFIG_VP8_DECODER - case VP8_FOURCC: - return vpx_codec_vp8_dx(); + {"vp8", VP8_FOURCC, &vpx_codec_vp8_dx}, #endif + #if CONFIG_VP9_DECODER - case VP9_FOURCC: - return vpx_codec_vp9_dx(); + {"vp9", VP9_FOURCC, &vpx_codec_vp9_dx}, #endif - default: - return NULL; +}; + +int get_vpx_decoder_count() { + return sizeof(vpx_decoders) / sizeof(vpx_decoders[0]); +} + +const VpxInterface *get_vpx_decoder_by_index(int i) { + return &vpx_decoders[i]; +} + +const VpxInterface *get_vpx_decoder_by_name(const char *name) { + int i; + + for (i = 0; i < get_vpx_decoder_count(); ++i) { + const VpxInterface *const decoder = get_vpx_decoder_by_index(i); + if (strcmp(decoder->name, name) == 0) + return decoder; } + + return NULL; +} + +const VpxInterface *get_vpx_decoder_by_fourcc(uint32_t fourcc) { + int i; + + for (i = 0; i < get_vpx_decoder_count(); ++i) { + const VpxInterface *const decoder = get_vpx_decoder_by_index(i); + if (decoder->fourcc == fourcc) + return decoder; + } + return NULL; } diff --git a/tools_common.h b/tools_common.h index 0f60c4c..da87b6d 100644 --- a/tools_common.h +++ b/tools_common.h @@ -123,7 +123,20 @@ uint32_t mem_get_le32(const void *data); int read_yuv_frame(struct VpxInputContext *input_ctx, vpx_image_t *yuv_frame); -vpx_codec_iface_t *get_codec_interface(unsigned int fourcc); +typedef struct VpxInterface { + const char *const name; + const uint32_t fourcc; + vpx_codec_iface_t *(*const interface)(); +} VpxInterface; + +int get_vpx_encoder_count(); +const VpxInterface *get_vpx_encoder_by_index(int i); +const VpxInterface *get_vpx_encoder_by_name(const char *name); + +int get_vpx_decoder_count(); +const VpxInterface *get_vpx_decoder_by_index(int i); +const VpxInterface *get_vpx_decoder_by_name(const char *name); +const VpxInterface *get_vpx_decoder_by_fourcc(uint32_t fourcc); // TODO(dkovalev): move this function to vpx_image.{c, h}, so it will be part // of vpx_image_t support diff --git a/vpxdec.c b/vpxdec.c index 98d1550..7f85fc9 100644 --- a/vpxdec.c +++ b/vpxdec.c @@ -37,19 +37,6 @@ static const char *exec_name; -static const struct { - char const *name; - vpx_codec_iface_t *(*iface)(void); - uint32_t fourcc; -} ifaces[] = { -#if CONFIG_VP8_DECODER - {"vp8", vpx_codec_vp8_dx, VP8_FOURCC}, -#endif -#if CONFIG_VP9_DECODER - {"vp9", vpx_codec_vp9_dx, VP9_FOURCC}, -#endif -}; - struct VpxDecInputContext { struct VpxInputContext *vpx_input_ctx; struct WebmInputContext *webm_ctx; @@ -170,10 +157,11 @@ void usage_exit() { ); fprintf(stderr, "\nIncluded decoders:\n\n"); - for (i = 0; i < sizeof(ifaces) / sizeof(ifaces[0]); i++) + for (i = 0; i < get_vpx_decoder_count(); ++i) { + const VpxInterface *const decoder = get_vpx_decoder_by_index(i); fprintf(stderr, " %-6s - %s\n", - ifaces[i].name, - vpx_codec_iface_name(ifaces[i].iface())); + decoder->name, vpx_codec_iface_name(decoder->interface())); + } exit(EXIT_FAILURE); } @@ -300,11 +288,12 @@ int file_is_raw(struct VpxInputContext *input) { int i; if (mem_get_le32(buf) < 256 * 1024 * 1024) { - for (i = 0; i < sizeof(ifaces) / sizeof(ifaces[0]); i++) { - if (!vpx_codec_peek_stream_info(ifaces[i].iface(), + for (i = 0; i < get_vpx_decoder_count(); ++i) { + const VpxInterface *const decoder = get_vpx_decoder_by_index(i); + if (!vpx_codec_peek_stream_info(decoder->interface(), buf + 4, 32 - 4, &si)) { is_raw = 1; - input->fourcc = ifaces[i].fourcc; + input->fourcc = decoder->fourcc; input->width = si.w; input->height = si.h; input->framerate.numerator = 30; @@ -441,7 +430,6 @@ static FILE *open_outfile(const char *name) { int main_loop(int argc, const char **argv_) { vpx_codec_ctx_t decoder; char *fn = NULL; - int i; uint8_t *buf = NULL; size_t bytes_in_buffer = 0, buffer_size = 0; FILE *infile; @@ -450,7 +438,8 @@ int main_loop(int argc, const char **argv_) { int stop_after = 0, postproc = 0, summary = 0, quiet = 1; int arg_skip = 0; int ec_enabled = 0; - vpx_codec_iface_t *iface = NULL; + const VpxInterface *interface = NULL; + const VpxInterface *fourcc_interface = NULL; unsigned long dx_time = 0; struct arg arg; char **argv, **argi, **argj; @@ -493,17 +482,9 @@ int main_loop(int argc, const char **argv_) { arg.argv_step = 1; if (arg_match(&arg, &codecarg, argi)) { - int j, k = -1; - - for (j = 0; j < sizeof(ifaces) / sizeof(ifaces[0]); j++) - if (!strcmp(ifaces[j].name, arg.val)) - k = j; - - if (k >= 0) - iface = ifaces[k].iface(); - else - die("Error: Unrecognized argument (%s) to --codec\n", - arg.val); + interface = get_vpx_decoder_by_name(arg.val); + if (!interface) + die("Error: Unrecognized argument (%s) to --codec\n", arg.val); } else if (arg_match(&arg, &looparg, argi)) { // no-op } else if (arg_match(&arg, &outputfile, argi)) @@ -660,24 +641,20 @@ int main_loop(int argc, const char **argv_) { } } - /* Try to determine the codec from the fourcc. */ - for (i = 0; i < sizeof(ifaces) / sizeof(ifaces[0]); i++) - if (vpx_input_ctx.fourcc == ifaces[i].fourcc) { - vpx_codec_iface_t *vpx_iface = ifaces[i].iface(); + fourcc_interface = get_vpx_decoder_by_fourcc(vpx_input_ctx.fourcc); + if (interface && fourcc_interface && interface != fourcc_interface) + warn("Header indicates codec: %s\n", fourcc_interface->name); + else + interface = fourcc_interface; - if (iface && iface != vpx_iface) - warn("Header indicates codec: %s\n", ifaces[i].name); - else - iface = vpx_iface; - - break; - } + if (!interface) + interface = get_vpx_decoder_by_index(0); dec_flags = (postproc ? VPX_CODEC_USE_POSTPROC : 0) | (ec_enabled ? VPX_CODEC_USE_ERROR_CONCEALMENT : 0); - if (vpx_codec_dec_init(&decoder, iface ? iface : ifaces[0].iface(), &cfg, - dec_flags)) { - fprintf(stderr, "Failed to initialize decoder: %s\n", vpx_codec_error(&decoder)); + if (vpx_codec_dec_init(&decoder, interface->interface(), &cfg, dec_flags)) { + fprintf(stderr, "Failed to initialize decoder: %s\n", + vpx_codec_error(&decoder)); return EXIT_FAILURE; } diff --git a/vpxenc.c b/vpxenc.c index 5e36fd9..73b3144 100644 --- a/vpxenc.c +++ b/vpxenc.c @@ -61,24 +61,6 @@ static size_t wrap_fwrite(const void *ptr, size_t size, size_t nmemb, static const char *exec_name; -static const struct codec_item { - char const *name; - vpx_codec_iface_t *(*iface)(void); - vpx_codec_iface_t *(*dx_iface)(void); - unsigned int fourcc; -} codecs[] = { -#if CONFIG_VP8_ENCODER && CONFIG_VP8_DECODER - {"vp8", &vpx_codec_vp8_cx, &vpx_codec_vp8_dx, VP8_FOURCC}, -#elif CONFIG_VP8_ENCODER && !CONFIG_VP8_DECODER - {"vp8", &vpx_codec_vp8_cx, NULL, VP8_FOURCC}, -#endif -#if CONFIG_VP9_ENCODER && CONFIG_VP9_DECODER - {"vp9", &vpx_codec_vp9_cx, &vpx_codec_vp9_dx, VP9_FOURCC}, -#elif CONFIG_VP9_ENCODER && !CONFIG_VP9_DECODER - {"vp9", &vpx_codec_vp9_cx, NULL, VP9_FOURCC}, -#endif -}; - static void warn_or_exit_on_errorv(vpx_codec_ctx_t *ctx, int fatal, const char *s, va_list ap) { if (ctx->err) { @@ -462,14 +444,13 @@ void usage_exit() { fprintf(stderr, "\nStream timebase (--timebase):\n" " The desired precision of timestamps in the output, expressed\n" " in fractional seconds. Default is 1/1000.\n"); - fprintf(stderr, "\n" - "Included encoders:\n" - "\n"); + fprintf(stderr, "\nIncluded encoders:\n\n"); - for (i = 0; i < sizeof(codecs) / sizeof(codecs[0]); i++) + for (i = 0; i < get_vpx_encoder_count(); ++i) { + const VpxInterface *const encoder = get_vpx_encoder_by_index(i); fprintf(stderr, " %-6s - %s\n", - codecs[i].name, - vpx_codec_iface_name(codecs[i].iface())); + encoder->name, vpx_codec_iface_name(encoder->interface())); + } exit(EXIT_FAILURE); } @@ -666,7 +647,7 @@ static void parse_global_config(struct VpxEncoderConfig *global, char **argv) { /* Initialize default parameters */ memset(global, 0, sizeof(*global)); - global->codec = codecs; + global->codec = get_vpx_encoder_by_index(0); global->passes = 0; global->use_i420 = 1; /* Assign default deadline to good quality */ @@ -676,18 +657,9 @@ static void parse_global_config(struct VpxEncoderConfig *global, char **argv) { arg.argv_step = 1; if (arg_match(&arg, &codecarg, argi)) { - int j, k = -1; - - for (j = 0; j < sizeof(codecs) / sizeof(codecs[0]); j++) - if (!strcmp(codecs[j].name, arg.val)) - k = j; - - if (k >= 0) - global->codec = codecs + k; - else - die("Error: Unrecognized argument (%s) to --codec\n", - arg.val); - + global->codec = get_vpx_encoder_by_name(arg.val); + if (!global->codec) + die("Error: Unrecognized argument (%s) to --codec\n", arg.val); } else if (arg_match(&arg, &passes, argi)) { global->passes = arg_parse_uint(&arg); @@ -750,7 +722,7 @@ static void parse_global_config(struct VpxEncoderConfig *global, char **argv) { #if CONFIG_VP9_ENCODER // Make default VP9 passes = 2 until there is a better quality 1-pass // encoder - global->passes = (global->codec->iface == vpx_codec_vp9_cx ? 2 : 1); + global->passes = strcmp(global->codec->name, "vp9") == 0 ? 2 : 1; #else global->passes = 1; #endif @@ -830,7 +802,7 @@ static struct stream_state *new_stream(struct VpxEncoderConfig *global, vpx_codec_err_t res; /* Populate encoder configuration */ - res = vpx_codec_enc_config_default(global->codec->iface(), + res = vpx_codec_enc_config_default(global->codec->interface(), &stream->config.cfg, global->usage); if (res) @@ -874,15 +846,15 @@ static int parse_stream_params(struct VpxEncoderConfig *global, struct stream_config *config = &stream->config; int eos_mark_found = 0; - /* Handle codec specific options */ + // Handle codec specific options if (0) { #if CONFIG_VP8_ENCODER - } else if (global->codec->iface == vpx_codec_vp8_cx) { + } else if (strcmp(global->codec->name, "vp8") == 0) { ctrl_args = vp8_args; ctrl_args_map = vp8_arg_ctrl_map; #endif #if CONFIG_VP9_ENCODER - } else if (global->codec->iface == vpx_codec_vp9_cx) { + } else if (strcmp(global->codec->name, "vp9") == 0) { ctrl_args = vp9_args; ctrl_args_map = vp9_arg_ctrl_map; #endif @@ -1090,7 +1062,7 @@ static void show_stream_config(struct stream_state *stream, if (stream->index == 0) { fprintf(stderr, "Codec: %s\n", - vpx_codec_iface_name(global->codec->iface())); + vpx_codec_iface_name(global->codec->interface())); fprintf(stderr, "Source file: %s Format: %s\n", input->filename, input->use_i420 ? "I420" : "YV12"); } @@ -1214,7 +1186,7 @@ static void initialize_encoder(struct stream_state *stream, flags |= global->out_part ? VPX_CODEC_USE_OUTPUT_PARTITION : 0; /* Construct Encoder Context */ - vpx_codec_enc_init(&stream->encoder, global->codec->iface(), + vpx_codec_enc_init(&stream->encoder, global->codec->interface(), &stream->config.cfg, flags); ctx_exit_on_error(&stream->encoder, "Failed to initialize encoder"); @@ -1234,7 +1206,8 @@ static void initialize_encoder(struct stream_state *stream, #if CONFIG_DECODERS if (global->test_decode != TEST_DECODE_OFF) { - vpx_codec_dec_init(&stream->decoder, global->codec->dx_iface(), NULL, 0); + const VpxInterface *decoder = get_vpx_decoder_by_name(global->codec->name); + vpx_codec_dec_init(&stream->decoder, decoder->interface(), NULL, 0); } #endif } @@ -1420,14 +1393,14 @@ static float usec_to_fps(uint64_t usec, unsigned int frames) { static void test_decode(struct stream_state *stream, enum TestDecodeFatality fatal, - const struct codec_item *codec) { + const VpxInterface *codec) { vpx_image_t enc_img, dec_img; if (stream->mismatch_seen) return; /* Get the internal reference frame */ - if (codec->fourcc == VP8_FOURCC) { + if (strcmp(codec->name, "vp8") == 0) { struct vpx_ref_frame ref_enc, ref_dec; int width, height; diff --git a/vpxenc.h b/vpxenc.h index 5103ee6..1e6acaa 100644 --- a/vpxenc.h +++ b/vpxenc.h @@ -22,9 +22,11 @@ enum TestDecodeFatality { TEST_DECODE_WARN, }; +struct VpxInterface; + /* Configuration elements common to all streams. */ struct VpxEncoderConfig { - const struct codec_item *codec; + const struct VpxInterface *codec; int passes; int pass; int usage; -- 2.7.4