diff --git a/examples.mk b/examples.mk index f1cc42bf7..28430a611 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 @@ -36,6 +42,7 @@ vpxenc.SRCS += vpx_ports/vpx_timer.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_VP8_ENCODER) += vp8_scalable_patterns.c @@ -99,13 +106,7 @@ vp8cx_set_ref.DESCRIPTION = VP8 set encoder reference frame # C file is provided, not generated automatically. UTILS-$(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 99d581c19..df7718b70 100644 --- a/vpxenc.c +++ b/vpxenc.c @@ -47,6 +47,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) @@ -1635,6 +1636,7 @@ struct stream_state { uint64_t cx_time; size_t nbytes; stats_io_t stats; + struct vpx_image *img; vpx_codec_ctx_t decoder; vpx_ref_frame_t ref_enc; vpx_ref_frame_t ref_dec; @@ -2050,11 +2052,15 @@ static void validate_stream_config(struct stream_state *stream) { 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; + } } @@ -2244,6 +2250,28 @@ 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[VPX_PLANE_Y], img->stride[VPX_PLANE_Y], + img->planes[VPX_PLANE_U], img->stride[VPX_PLANE_U], + img->planes[VPX_PLANE_V], img->stride[VPX_PLANE_V], + img->d_w, img->d_h, + stream->img->planes[VPX_PLANE_Y], + stream->img->stride[VPX_PLANE_Y], + stream->img->planes[VPX_PLANE_U], + stream->img->stride[VPX_PLANE_U], + stream->img->planes[VPX_PLANE_V], + stream->img->stride[VPX_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, (unsigned long)(next_frame_start - frame_start), @@ -2500,6 +2528,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));