[FFmpeg-devel] [PATCH] ffprobe: generalize nesting model for the default writer

Clément Bœsch ubitux at gmail.com
Fri Sep 28 23:43:50 CEST 2012


On Fri, Sep 28, 2012 at 07:33:45PM +0200, Stefano Sabatini wrote:
> On date Wednesday 2012-09-26 13:11:19 +0200, Stefano Sabatini encoded:
> > This is required by the pending change related to disposition.
> > 
> > "TAGS" section is no more treated like a special case, and thus the
> > prefix name for the TAGS section is changed from "TAG:" to "TAGS:".
> > 
> > This changes the writer output.
> 
> Updated, this time avoiding syntax breaks.
> -- 
> FFmpeg = Fucking & Forgiving Meaningless Powerful Ermetic God

> From 57e19b0661ef825e4c1eeb37e954340843b61449 Mon Sep 17 00:00:00 2001
> From: Stefano Sabatini <stefasab at gmail.com>
> Date: Fri, 28 Sep 2012 17:07:40 +0200
> Subject: [PATCH] ffprobe: drop SECTION_ENTRY macro
> 
> The use of the macro somewhat makes to add new optional fields harder.
> ---
>  ffprobe.c |   35 ++++++++++++++++-------------------
>  1 files changed, 16 insertions(+), 19 deletions(-)
> 
> diff --git a/ffprobe.c b/ffprobe.c
> index d466d5a..38f8323 100644
> --- a/ffprobe.c
> +++ b/ffprobe.c
> @@ -101,26 +101,23 @@ typedef enum {
>      SECTION_ID_STREAM_TAGS
>  } SectionID;
>  
> -#define SECTION_ENTRY(id, name, flags) \
> -    [SECTION_ID_##id] = { SECTION_ID_##id, name, flags }
> -
>  static const struct section sections[] = {
> -    SECTION_ENTRY(ERROR,              "error", 0),
> -    SECTION_ENTRY(FORMAT,             "format", 0),
> -    SECTION_ENTRY(FORMAT_TAGS,        "tags", 0),
> -    SECTION_ENTRY(FRAME,              "frame", 0),
> -    SECTION_ENTRY(FRAMES,             "frames", SECTION_FLAG_IS_ARRAY),
> -    SECTION_ENTRY(FRAME_TAGS,         "tags", 0),
> -    SECTION_ENTRY(LIBRARY_VERSION,    "library_version", 0),
> -    SECTION_ENTRY(LIBRARY_VERSIONS,   "library_versions", SECTION_FLAG_IS_ARRAY),
> -    SECTION_ENTRY(PACKET,             "packet", 0),
> -    SECTION_ENTRY(PACKETS,            "packets", SECTION_FLAG_IS_ARRAY),
> -    SECTION_ENTRY(PACKETS_AND_FRAMES, "packets_and_frames", SECTION_FLAG_IS_ARRAY),
> -    SECTION_ENTRY(PROGRAM_VERSION,    "program_version", 0),
> -    SECTION_ENTRY(ROOT,               "root", SECTION_FLAG_IS_WRAPPER),
> -    SECTION_ENTRY(STREAM,             "stream", 0),
> -    SECTION_ENTRY(STREAMS,            "streams", SECTION_FLAG_IS_ARRAY),
> -    SECTION_ENTRY(STREAM_TAGS,        "tags", 0),
> +    [SECTION_ID_ERROR] = { SECTION_ID_ERROR, "error", 0 },
> +    [SECTION_ID_FORMAT] = { SECTION_ID_FORMAT, "format", 0 },
> +    [SECTION_ID_FORMAT_TAGS] = { SECTION_ID_FORMAT_TAGS, "tags", 0 },
> +    [SECTION_ID_FRAME] = { SECTION_ID_FRAME, "frame", 0 },
> +    [SECTION_ID_FRAMES] = { SECTION_ID_FRAMES, "frames", SECTION_FLAG_IS_ARRAY },
> +    [SECTION_ID_FRAME_TAGS] = { SECTION_ID_FRAME_TAGS, "tags", 0 },
> +    [SECTION_ID_LIBRARY_VERSION] = { SECTION_ID_LIBRARY_VERSION, "library_version", 0 },
> +    [SECTION_ID_LIBRARY_VERSIONS] = { SECTION_ID_LIBRARY_VERSIONS, "library_versions", SECTION_FLAG_IS_ARRAY },
> +    [SECTION_ID_PACKET] = { SECTION_ID_PACKET, "packet", 0 },
> +    [SECTION_ID_PACKETS] = { SECTION_ID_PACKETS, "packets", SECTION_FLAG_IS_ARRAY },
> +    [SECTION_ID_PACKETS_AND_FRAMES] = { SECTION_ID_PACKETS_AND_FRAMES, "packets_and_frames", SECTION_FLAG_IS_ARRAY },
> +    [SECTION_ID_PROGRAM_VERSION] = { SECTION_ID_PROGRAM_VERSION, "program_version", 0 },
> +    [SECTION_ID_ROOT] = { SECTION_ID_ROOT, "root", SECTION_FLAG_IS_WRAPPER },
> +    [SECTION_ID_STREAM] = { SECTION_ID_STREAM, "stream", 0 },
> +    [SECTION_ID_STREAMS] = { SECTION_ID_STREAMS, "streams", SECTION_FLAG_IS_ARRAY },
> +    [SECTION_ID_STREAM_TAGS] = { SECTION_ID_STREAM_TAGS, "tags", 0 },

OK, why not. Can't you drop the "0" now?

nit: too bad to loose some alignment but whatever.

[...]
> From e36d1c06f1ae9f0b1d09d0f7662b4a37ae199332 Mon Sep 17 00:00:00 2001
> From: Stefano Sabatini <stefasab at gmail.com>
> Date: Wed, 26 Sep 2012 12:56:32 +0200
> Subject: [PATCH] ffprobe: generalize nesting model for the default writer
> 
> Regular section fields nested in a regular section are now prefixed by
> the nested section name.
> 
> This is required by the pending change related to disposition.
> ---
>  ffprobe.c |   55 ++++++++++++++++++++++++++++++++++++++++---------------
>  1 files changed, 40 insertions(+), 15 deletions(-)
> 
> diff --git a/ffprobe.c b/ffprobe.c
> index 38f8323..77ddcba 100644
> --- a/ffprobe.c
> +++ b/ffprobe.c
> @@ -79,6 +79,7 @@ struct section {
>  #define SECTION_FLAG_IS_WRAPPER      1 ///< the section only contains other sections, but has no data at its own level
>  #define SECTION_FLAG_IS_ARRAY        2 ///< the section contains an array of elements of the same type
>      int flags;
> +    const char *element_name; ///< name of the contained element, if provided
>  };
>  
>  typedef enum {
> @@ -104,10 +105,10 @@ typedef enum {
>  static const struct section sections[] = {
>      [SECTION_ID_ERROR] = { SECTION_ID_ERROR, "error", 0 },
>      [SECTION_ID_FORMAT] = { SECTION_ID_FORMAT, "format", 0 },
> -    [SECTION_ID_FORMAT_TAGS] = { SECTION_ID_FORMAT_TAGS, "tags", 0 },
> +    [SECTION_ID_FORMAT_TAGS] = { SECTION_ID_FORMAT_TAGS, "tags", 0, .element_name = "tag" },
>      [SECTION_ID_FRAME] = { SECTION_ID_FRAME, "frame", 0 },
>      [SECTION_ID_FRAMES] = { SECTION_ID_FRAMES, "frames", SECTION_FLAG_IS_ARRAY },
> -    [SECTION_ID_FRAME_TAGS] = { SECTION_ID_FRAME_TAGS, "tags", 0 },
> +    [SECTION_ID_FRAME_TAGS] = { SECTION_ID_FRAME_TAGS, "tags", 0, .element_name = "tag" },
>      [SECTION_ID_LIBRARY_VERSION] = { SECTION_ID_LIBRARY_VERSION, "library_version", 0 },
>      [SECTION_ID_LIBRARY_VERSIONS] = { SECTION_ID_LIBRARY_VERSIONS, "library_versions", SECTION_FLAG_IS_ARRAY },
>      [SECTION_ID_PACKET] = { SECTION_ID_PACKET, "packet", 0 },
> @@ -117,7 +118,7 @@ static const struct section sections[] = {
>      [SECTION_ID_ROOT] = { SECTION_ID_ROOT, "root", SECTION_FLAG_IS_WRAPPER },
>      [SECTION_ID_STREAM] = { SECTION_ID_STREAM, "stream", 0 },
>      [SECTION_ID_STREAMS] = { SECTION_ID_STREAMS, "streams", SECTION_FLAG_IS_ARRAY },
> -    [SECTION_ID_STREAM_TAGS] = { SECTION_ID_STREAM_TAGS, "tags", 0 },
> +    [SECTION_ID_STREAM_TAGS] = { SECTION_ID_STREAM_TAGS, "tags", 0, .element_name = "tag" },
>  };
>  
>  static const OptionDef *options;
> @@ -488,6 +489,8 @@ typedef struct DefaultContext {
>      const AVClass *class;
>      int nokey;
>      int noprint_wrappers;
> +    int nested_section[SECTION_MAX_NB_LEVELS];
> +    AVBPrint prefix[SECTION_MAX_NB_LEVELS];
>  } DefaultContext;
>  
>  #define OFFSET(x) offsetof(DefaultContext, x)
> @@ -512,6 +515,25 @@ static inline char *upcase_string(char *dst, size_t dst_size, const char *src)
>      return dst;
>  }
>  
> +static int default_init(WriterContext *wctx)
> +{
> +    DefaultContext *def = wctx->priv;
> +    int i;
> +
> +    for (i = 0; i < SECTION_MAX_NB_LEVELS; i++)
> +        av_bprint_init(&def->prefix[i], 1, AV_BPRINT_SIZE_UNLIMITED);
> +    return 0;
> +}
> +
> +static void default_uninit(WriterContext *wctx)
> +{
> +    DefaultContext *def = wctx->priv;
> +    int i;
> +
> +    for (i = 0; i < SECTION_MAX_NB_LEVELS; i++)
> +        av_bprint_finalize(&def->prefix[i], NULL);
> +}
> +
>  static void default_print_section_header(WriterContext *wctx)
>  {
>      DefaultContext *def = wctx->priv;
> @@ -520,9 +542,16 @@ static void default_print_section_header(WriterContext *wctx)
>      const struct section *parent_section = wctx->level ?
>          wctx->section[wctx->level-1] : NULL;
>  
> -    if (def->noprint_wrappers ||
> -        (parent_section &&
> -         !(parent_section->flags & (SECTION_FLAG_IS_WRAPPER|SECTION_FLAG_IS_ARRAY))))
> +    av_bprint_clear(&def->prefix[wctx->level]);
> +    if (parent_section &&
> +        !(parent_section->flags & (SECTION_FLAG_IS_WRAPPER|SECTION_FLAG_IS_ARRAY))) {
> +        def->nested_section[wctx->level] = 1;
> +        av_bprintf(&def->prefix[wctx->level], "%s%s:", def->prefix[wctx->level-1].str,
> +                   upcase_string(buf, sizeof(buf),
> +                                 av_x_if_null(section->element_name, section->name)));
> +    }
> +
> +    if (def->noprint_wrappers || def->nested_section[wctx->level])
>          return;
>  
>      if (!(section->flags & (SECTION_FLAG_IS_WRAPPER|SECTION_FLAG_IS_ARRAY)))
> @@ -533,13 +562,9 @@ static void default_print_section_footer(WriterContext *wctx)
>  {
>      DefaultContext *def = wctx->priv;
>      const struct section *section = wctx->section[wctx->level];
> -    const struct section *parent_section = wctx->level ?
> -        wctx->section[wctx->level-1] : NULL;
>      char buf[32];
>  
> -    if (def->noprint_wrappers ||
> -        (parent_section &&
> -         !(parent_section->flags & (SECTION_FLAG_IS_WRAPPER|SECTION_FLAG_IS_ARRAY))))
> +    if (def->noprint_wrappers || def->nested_section[wctx->level])
>          return;
>  
>      if (!(section->flags & (SECTION_FLAG_IS_WRAPPER|SECTION_FLAG_IS_ARRAY)))
> @@ -549,11 +574,9 @@ static void default_print_section_footer(WriterContext *wctx)
>  static void default_print_str(WriterContext *wctx, const char *key, const char *value)
>  {
>      DefaultContext *def = wctx->priv;
> -    const struct section *section = wctx->section[wctx->level];
> -    const char *key_prefix = !strcmp(section->name, "tags") ? "TAG:" : "";
>  
>      if (!def->nokey)
> -        printf("%s%s=", key_prefix, key);
> +        printf("%s%s=", def->prefix[wctx->level].str, key);
>      printf("%s\n", value);
>  }
>  
> @@ -562,13 +585,15 @@ static void default_print_int(WriterContext *wctx, const char *key, long long in
>      DefaultContext *def = wctx->priv;
>  
>      if (!def->nokey)
> -        printf("%s=", key);
> +        printf("%s%s=", def->prefix[wctx->level].str, key);
>      printf("%lld\n", value);
>  }
>  
>  static const Writer default_writer = {
>      .name                  = "default",
>      .priv_size             = sizeof(DefaultContext),
> +    .init                  = default_init,
> +    .uninit                = default_uninit,
>      .print_section_header  = default_print_section_header,
>      .print_section_footer  = default_print_section_footer,
>      .print_integer         = default_print_int,

LGTM

-- 
Clément B.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20120928/e89c891c/attachment.asc>


More information about the ffmpeg-devel mailing list