summaryrefslogtreecommitdiff
path: root/vpxenc.c
diff options
context:
space:
mode:
authorJohn Koleszar <jkoleszar@google.com>2012-03-01 12:50:40 -0800
committerJohn Koleszar <jkoleszar@google.com>2013-02-27 08:22:40 -0800
commit34882b9bf538dc726fe9bec9dee2e45b8d8ea222 (patch)
treeedbf4991cb9a84c52dc142925ed7590594cfc1f5 /vpxenc.c
parent800ad0b886ce6776712c1835878e500ffd43af64 (diff)
downloadlibvpx-34882b9bf538dc726fe9bec9dee2e45b8d8ea222.tar
libvpx-34882b9bf538dc726fe9bec9dee2e45b8d8ea222.tar.gz
libvpx-34882b9bf538dc726fe9bec9dee2e45b8d8ea222.tar.bz2
libvpx-34882b9bf538dc726fe9bec9dee2e45b8d8ea222.zip
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. Change-Id: Ic7026810b13be030826be80dc6f7fc4aaf0c35d0
Diffstat (limited to 'vpxenc.c')
-rw-r--r--vpxenc.c41
1 files changed, 36 insertions, 5 deletions
diff --git a/vpxenc.c b/vpxenc.c
index 2f3b6356d..7597e3cbb 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)
@@ -1642,6 +1643,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;
@@ -2061,11 +2063,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;
+ }
}
@@ -2258,6 +2264,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),
@@ -2518,6 +2546,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));