On Mon, Feb 23, 2015 at 9:24 PM, Vittorio Giovara
<[email protected]> wrote:
> 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)
>

ping and question: should avframe be equipped with similar variables?
I am starting to think so, but I'd like an opinion on the general
approach first.
-- 
Vittorio
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to