From: John Koleszar Date: Thu, 1 Mar 2012 20:50:40 +0000 (-0800) Subject: vpxenc: support scaling prior to encoding X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=118b445babe05b8b73bec913acd9c14aa133dee8;p=libvpx vpxenc: support scaling prior to encoding Scales the input of the encoder using libyuv's "box filter". Each stream may have a different width and height specified. If the width (or height) parameter is missing (or is explicitly set to 0) then the value will be calculated based on the specified height (or width) and the input file's dimensions, preserving its aspect ratio. Leaving the height unspecified behaves similarly. Note: This functionality still does not take advantage of the accelerated multi-resolution encoder support with CONFIG_MULTI_RES_ENCODING. Change-Id: Ic7026810b13be030826be80dc6f7fc4aaf0c35d0 --- diff --git a/examples.mk b/examples.mk index 518608d72..268218a28 100644 --- a/examples.mk +++ b/examples.mk @@ -8,6 +8,12 @@ ## be found in the AUTHORS file in the root of the source tree. ## +LIBYUV_SRCS += third_party/libyuv/include/libyuv/basic_types.h \ + third_party/libyuv/include/libyuv/cpu_id.h \ + third_party/libyuv/include/libyuv/scale.h \ + third_party/libyuv/source/row.h \ + third_party/libyuv/source/scale.c \ + third_party/libyuv/source/cpu_id.c # List of examples to build. UTILS are files that are taken from the source # tree directly, and GEN_EXAMPLES are files that are created from the @@ -35,6 +41,7 @@ vpxenc.SRCS += vpx_ports/mem_ops_aligned.h vpxenc.SRCS += libmkv/EbmlIDs.h vpxenc.SRCS += libmkv/EbmlWriter.c vpxenc.SRCS += libmkv/EbmlWriter.h +vpxenc.SRCS += $(LIBYUV_SRCS) vpxenc.GUID = 548DEC74-7A15-4B2B-AFC3-AA102E7C25C1 vpxenc.DESCRIPTION = Full featured encoder UTILS-$(CONFIG_ENCODERS) += vp8_scalable_patterns.c @@ -98,13 +105,7 @@ vp8cx_set_ref.DESCRIPTION = VP8 set encoder reference frame # C file is provided, not generated automatically. GEN_EXAMPLES-$(CONFIG_MULTI_RES_ENCODING) += vp8_multi_resolution_encoder.c -vp8_multi_resolution_encoder.SRCS \ - += third_party/libyuv/include/libyuv/basic_types.h \ - third_party/libyuv/include/libyuv/cpu_id.h \ - third_party/libyuv/include/libyuv/scale.h \ - third_party/libyuv/source/row.h \ - third_party/libyuv/source/scale.c \ - third_party/libyuv/source/cpu_id.c +vp8_multi_resolution_encoder.SRCS += $(LIBYUV_SRCS) vp8_multi_resolution_encoder.GUID = 04f8738e-63c8-423b-90fa-7c2703a374de vp8_multi_resolution_encoder.DESCRIPTION = VP8 Multiple-resolution Encoding diff --git a/vpxenc.c b/vpxenc.c index 7d6758a7d..c237008ee 100644 --- a/vpxenc.c +++ b/vpxenc.c @@ -39,6 +39,7 @@ #include "y4minput.h" #include "libmkv/EbmlWriter.h" #include "libmkv/EbmlIDs.h" +#include "third_party/libyuv/include/libyuv/scale.h" /* Need special handling of these functions on Windows */ #if defined(_MSC_VER) @@ -1530,6 +1531,7 @@ struct stream_state uint64_t cx_time; size_t nbytes; stats_io_t stats; + struct vpx_image *img; }; @@ -1943,11 +1945,17 @@ static void set_stream_dimensions(struct stream_state *stream, unsigned int w, unsigned int h) { - if ((stream->config.cfg.g_w && stream->config.cfg.g_w != w) - ||(stream->config.cfg.g_h && stream->config.cfg.g_h != h)) - fatal("Stream %d: Resizing not yet supported", stream->index); - stream->config.cfg.g_w = w; - stream->config.cfg.g_h = h; + if(!stream->config.cfg.g_w) + { + if(!stream->config.cfg.g_h) + stream->config.cfg.g_w = w; + else + stream->config.cfg.g_w = w * stream->config.cfg.g_h / h; + } + if(!stream->config.cfg.g_h) + { + stream->config.cfg.g_h = h * stream->config.cfg.g_w / w; + } } @@ -2117,6 +2125,26 @@ static void encode_frame(struct stream_state *stream, next_frame_start = (cfg->g_timebase.den * (int64_t)(frames_in) * global->framerate.den) / cfg->g_timebase.num / global->framerate.num; + + /* Scale if necessary */ + if(img && (img->d_w != cfg->g_w || img->d_h != cfg->g_h)) + { + if(!stream->img) + stream->img = vpx_img_alloc(NULL, VPX_IMG_FMT_I420, + cfg->g_w, cfg->g_h, 16); + I420Scale(img->planes[PLANE_Y], img->stride[PLANE_Y], + img->planes[PLANE_U], img->stride[PLANE_U], + img->planes[PLANE_V], img->stride[PLANE_V], + img->d_w, img->d_h, + stream->img->planes[PLANE_Y], stream->img->stride[PLANE_Y], + stream->img->planes[PLANE_U], stream->img->stride[PLANE_U], + stream->img->planes[PLANE_V], stream->img->stride[PLANE_V], + stream->img->d_w, stream->img->d_h, + kFilterBox); + + img = stream->img; + } + vpx_usec_timer_start(&timer); vpx_codec_encode(&stream->encoder, img, frame_start, next_frame_start - frame_start, @@ -2315,6 +2343,9 @@ int main(int argc, const char **argv_) }); /* Update stream configurations from the input file's parameters */ + if(!input.w || !input.h) + fatal("Specify stream dimensions with --width (-w) " + " and --height (-h)"); FOREACH_STREAM(set_stream_dimensions(stream, input.w, input.h)); FOREACH_STREAM(validate_stream_config(stream));