These value represent the original bitstream size, before any extra
operation, such as rotation or container cropping, may be applied.

Container cropping is one of the ways to encode an odd-size h264 video
in yuv420 color space. Right now, when it is applied, the original frame size
is lost, and there is no way to understand where the cropping took place
(eg. at the bitstream level or at the container level).

Not only analysis might want to preserve that information, but users
may carry out additional padding when it is actually not necessary.

This change allows to preserve all sizes from container and bitstream in
the AVCodecContext. The values are to be considered as follows:
 * coded_width/coded_height: size of the full coded video surface;
 * orig_width/orig_height: size of the video frame to be displayed;
 * width/height: size of the actual video to be displayed.

When container cropping is not present, orig_width/orig_height match
width/height; under no circumstance, they are allowed to be greater than
coded_width/coded_height or smaller than width/height.

Signed-off-by: Vittorio Giovara <[email protected]>
---
 doc/APIchanges       |  4 ++++
 libavcodec/avcodec.h | 11 +++++++++++
 libavcodec/utils.c   | 40 ++++++++++++++++++++++++++--------------
 libavcodec/version.h |  2 +-
 4 files changed, 42 insertions(+), 15 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index cf8d828..78c0acb 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -13,6 +13,10 @@ libavutil:     2014-08-09
 
 API changes, most recent first:
 
+2015-xx-xx - xxxxxxx - lavc 56.18.0 - avcodec.h
+  Add orig_width and orig_height to AVCodecContext to preserve bitstream size
+  when container cropping takes place.
+
 2015-xx-xx - xxxxxxx - lavc 56.13
   Add width, height, coded_width, coded_height and format to
   AVCodecParserContext.
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 8b9e21f..d7d56f3 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -2815,6 +2815,17 @@ typedef struct AVCodecContext {
      * - decoding: Set by libavcodec before calling get_format()
      */
     enum AVPixelFormat sw_pix_fmt;
+
+    /**
+     * Width and height describing the visible region as reported by the
+     * bitstream. May differ from main width and height, since containers
+     * are allowed to perform additional cropping (eg. to signal odd-y420
+     * sizes). These values can't be greater than coded_width/coded_height
+     * and can't be smaller than width/height.
+     * - encoding: Unused.
+     * - decoding: Set by libavcodec.
+     */
+    int orig_width, orig_height;
 } AVCodecContext;
 
 /**
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index a36e960..b744f86 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -136,8 +136,8 @@ int ff_set_dimensions(AVCodecContext *s, int width, int 
height)
 
     if (ret < 0)
         width = height = 0;
-    s->width  = s->coded_width  = width;
-    s->height = s->coded_height = height;
+    s->width  = s->coded_width  = s->orig_width  = width;
+    s->height = s->coded_height = s->orig_height = height;
 
     return ret;
 }
@@ -1095,16 +1095,24 @@ int attribute_align_arg avcodec_open2(AVCodecContext 
*avctx, const AVCodec *code
 
     if (avctx->coded_width && avctx->coded_height && !avctx->width && 
!avctx->height)
         ret = ff_set_dimensions(avctx, avctx->coded_width, 
avctx->coded_height);
-    else if (avctx->width && avctx->height)
+    else if (avctx->width && avctx->height && !avctx->orig_width && 
!avctx->orig_height)
         ret = ff_set_dimensions(avctx, avctx->width, avctx->height);
     if (ret < 0)
         goto free_and_end;
 
-    if ((avctx->coded_width || avctx->coded_height || avctx->width || 
avctx->height)
-        && (  av_image_check_size(avctx->coded_width, avctx->coded_height, 0, 
avctx) < 0
-           || av_image_check_size(avctx->width,       avctx->height,       0, 
avctx) < 0)) {
-        av_log(avctx, AV_LOG_WARNING, "ignoring invalid width/height 
values\n");
-        ff_set_dimensions(avctx, 0, 0);
+    if (avctx->coded_width || avctx->coded_height ||
+        avctx->orig_width  || avctx->orig_height  ||
+        avctx->width       || avctx->height) {
+        if (av_image_check_size(avctx->coded_width,
+                                avctx->coded_height, 0, avctx) < 0 ||
+            av_image_check_size(avctx->orig_width,
+                                avctx->orig_height, 0, avctx) < 0 ||
+            av_image_check_size(avctx->width,
+                                avctx->height, 0, avctx) < 0) {
+            av_log(avctx, AV_LOG_WARNING,
+                   "ignoring invalid width/height values\n");
+            ff_set_dimensions(avctx, 0, 0);
+        }
     }
 
     if (avctx->width > 0 && avctx->height > 0) {
@@ -1983,12 +1991,16 @@ void avcodec_string(char *buf, int buf_size, 
AVCodecContext *enc, int encode)
                      "%dx%d",
                      enc->width, enc->height);
 
-            if (av_log_get_level() >= AV_LOG_VERBOSE &&
-                (enc->width != enc->coded_width ||
-                 enc->height != enc->coded_height))
-                snprintf(buf + strlen(buf), buf_size - strlen(buf),
-                         " (%dx%d)", enc->coded_width, enc->coded_height);
-
+            if (av_log_get_level() >= AV_LOG_VERBOSE) {
+                if ((enc->width != enc->orig_width ||
+                     enc->height != enc->orig_height))
+                    snprintf(buf + strlen(buf), buf_size - strlen(buf),
+                             " (%dx%d)", enc->orig_width, enc->orig_height);
+                if ((enc->orig_width != enc->coded_width ||
+                     enc->orig_height != enc->coded_height))
+                    snprintf(buf + strlen(buf), buf_size - strlen(buf),
+                             " [%dx%d]", enc->coded_width, enc->coded_height);
+            }
             if (enc->sample_aspect_ratio.num) {
                 av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
                           enc->width * enc->sample_aspect_ratio.num,
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 5392e05..816d7ea 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -29,7 +29,7 @@
 #include "libavutil/version.h"
 
 #define LIBAVCODEC_VERSION_MAJOR 56
-#define LIBAVCODEC_VERSION_MINOR 17
+#define LIBAVCODEC_VERSION_MINOR 18
 #define LIBAVCODEC_VERSION_MICRO  0
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
-- 
1.9.3 (Apple Git-50)

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to