]> granicus.if.org Git - libvpx/commitdiff
vpxenc: support scaling prior to encoding
authorJohn Koleszar <jkoleszar@google.com>
Thu, 1 Mar 2012 20:50:40 +0000 (12:50 -0800)
committerJohn Koleszar <jkoleszar@google.com>
Thu, 1 Mar 2012 22:44:24 +0000 (14:44 -0800)
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

examples.mk
vpxenc.c

index 518608d72e07cd813d0faf14cddd76cec34dd35d..268218a28398b6ad0439ed997150063f1f7e405e 100644 (file)
@@ -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
 
index 7d6758a7d6678fda6165ea7423d659a18fdc0e19..c237008ee9060333296c0dd921be52b64613a712 100644 (file)
--- 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));