[FFmpeg-devel] [PATCH v2 29/36] h264_metadata: Add option to set the level of the stream

Xiang, Haihao haihao.xiang at intel.com
Fri Jun 15 05:49:02 EEST 2018


On Fri, 2018-06-08 at 00:43 +0100, Mark Thompson wrote:
> ---
>  doc/bitstream_filters.texi     |  9 +++++
>  libavcodec/h264_metadata_bsf.c | 90
> ++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 99 insertions(+)
> 
> diff --git a/doc/bitstream_filters.texi b/doc/bitstream_filters.texi
> index 7d7e97503a..d948c6d658 100644
> --- a/doc/bitstream_filters.texi
> +++ b/doc/bitstream_filters.texi
> @@ -215,6 +215,15 @@ insert the string ``hello'' associated with the given
> UUID.
>  @item delete_filler
>  Deletes both filler NAL units and filler SEI messages.
>  
> + at item level
> +Set the level in the SPS.  Refer to H.264 section A.3 and tables A-1
> +to A-5.
> +
> +The argument must be the name of a level (for example, @samp{4.2}), a
> +level_idc value (for example, @samp{42}), or the special name @samp{auto}
> +indicating that the filter should attempt to guess the level from the
> +input stream properties.
> +
>  @end table
>  
>  @section h264_mp4toannexb
> diff --git a/libavcodec/h264_metadata_bsf.c b/libavcodec/h264_metadata_bsf.c
> index 90ad4aad98..cb1a835fb8 100644
> --- a/libavcodec/h264_metadata_bsf.c
> +++ b/libavcodec/h264_metadata_bsf.c
> @@ -25,6 +25,7 @@
>  #include "cbs.h"
>  #include "cbs_h264.h"
>  #include "h264.h"
> +#include "h264_levels.h"
>  #include "h264_sei.h"
>  
>  enum {
> @@ -39,6 +40,11 @@ enum {
>      FLIP_VERTICAL   = 2,
>  };
>  
> +enum {
> +    LEVEL_UNSET = -2,
> +    LEVEL_AUTO  = -1,
> +};
> +
>  typedef struct H264MetadataContext {
>      const AVClass *class;
>  
> @@ -74,6 +80,8 @@ typedef struct H264MetadataContext {
>      int display_orientation;
>      double rotate;
>      int flip;
> +
> +    int level;
>  } H264MetadataContext;
>  
>  
> @@ -208,6 +216,58 @@ static int h264_metadata_update_sps(AVBSFContext *bsf,
>      CROP(bottom, crop_unit_y);
>  #undef CROP
>  
> +    if (ctx->level != LEVEL_UNSET) {
> +        int level_idc;
> +
> +        if (ctx->level == LEVEL_AUTO) {
> +            const H264LevelDescriptor *desc;
> +            int64_t bit_rate;
> +            int width, height;
> +
> +            if (sps->vui.nal_hrd_parameters_present_flag) {
> +                bit_rate = (sps-
> >vui.nal_hrd_parameters.bit_rate_value_minus1[0] + 1) *
> +                     (1 << (sps->vui.nal_hrd_parameters.bit_rate_scale + 6));
> +            } else if (sps->vui.vcl_hrd_parameters_present_flag) {
> +                bit_rate = (sps-
> >vui.vcl_hrd_parameters.bit_rate_value_minus1[0] + 1) *
> +                     (1 << (sps->vui.vcl_hrd_parameters.bit_rate_scale + 6));
> +                // Adjust for VCL vs. NAL limits.
> +                bit_rate = bit_rate * 6 / 5;
> +            } else {
> +                bit_rate = 0;
> +            }
> +
> +            width  = 16 * (sps->pic_width_in_mbs_minus1 + 1);
> +            height = 16 * (sps->pic_height_in_map_units_minus1 + 1) *
> +                (2 - sps->frame_mbs_only_flag);
> +
> +            desc = ff_h264_guess_level(sps->profile_idc, bit_rate,
> +                                       width, height,
> +                                       sps->vui.max_dec_frame_buffering);
> +            if (desc) {
> +                level_idc = desc->level_idc;
> +            } else {
> +                av_log(bsf, AV_LOG_WARNING, "Stream does not appear to "
> +                       "conform to any level: using level 6.2.\n");
> +                level_idc = 62;
> +            }
> +        } else {
> +            level_idc = ctx->level;
> +        }
> +
> +        if (level_idc == 9) {
> +            if (sps->profile_idc == 66 ||
> +                sps->profile_idc == 77 ||
> +                sps->profile_idc == 88) {
> +                sps->level_idc = 10;
> +                sps->constraint_set3_flag = 1;
> +            } else {
> +                sps->level_idc = 9;
> +            }
> +        } else {
> +            sps->level_idc = level_idc;
> +        }
> +    }
> +
>      if (need_vui)
>          sps->vui_parameters_present_flag = 1;
>  
> @@ -683,6 +743,36 @@ static const AVOption h264_metadata_options[] = {
>          0, AV_OPT_TYPE_CONST,
>          { .i64 = FLIP_VERTICAL },   .flags = FLAGS, .unit = "flip" },
>  
> +    { "level", "Set level (table A-1)",
> +        OFFSET(level), AV_OPT_TYPE_INT,
> +        { .i64 = LEVEL_UNSET }, LEVEL_UNSET, 0xff, FLAGS, "level" },
> +    { "auto", "Attempt to guess level from stream properties",
> +        0, AV_OPT_TYPE_CONST,
> +        { .i64 = LEVEL_AUTO }, 0, 0, FLAGS, "level" },

Could you please use the same code style for AV_OPT_TYPE_CONST ?

> +#define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
> +        { .i64 = value }, 0, 0, FLAGS, "level"

Also here.

> +    { LEVEL("1",   10) },
> +    { LEVEL("1b",   9) },
> +    { LEVEL("1.1", 11) },
> +    { LEVEL("1.2", 12) },
> +    { LEVEL("1.3", 13) },
> +    { LEVEL("2",   20) },
> +    { LEVEL("2.1", 21) },
> +    { LEVEL("2.2", 22) },
> +    { LEVEL("3",   30) },
> +    { LEVEL("3.1", 31) },
> +    { LEVEL("3.2", 32) },
> +    { LEVEL("4",   40) },
> +    { LEVEL("4.1", 41) },
> +    { LEVEL("4.2", 42) },
> +    { LEVEL("5",   50) },
> +    { LEVEL("5.1", 51) },
> +    { LEVEL("5.2", 52) },
> +    { LEVEL("6",   60) },
> +    { LEVEL("6.1", 61) },
> +    { LEVEL("6.2", 62) },
> +#undef LEVEL
> +
>      { NULL }
>  };
>  


More information about the ffmpeg-devel mailing list