On date Friday 2011-12-02 00:37:57 +0100, Thomas Kühnel encoded:
> Updated.

> From 040334eeec0349c9f09852d0b8f5c42ad6eb0331 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Thomas=20K=C3=BChnel?= <[email protected]>
> Date: Fri, 23 Sep 2011 22:51:42 +0200
> Subject: [PATCH 3/3] avprobe: Print frame-based metadata
> 
> ---
>  avprobe.c        |   56 +++++++++++++++++++++++++++++++++++++++++++++++++++--
>  doc/avprobe.texi |    7 ++++++
>  2 files changed, 60 insertions(+), 3 deletions(-)
> 
> diff --git a/avprobe.c b/avprobe.c
> index 992f07c..ef43986 100644
> --- a/avprobe.c
> +++ b/avprobe.c
> @@ -35,6 +35,7 @@ const int program_birth_year = 2007;
>  static int do_show_format  = 0;
>  static int do_show_packets = 0;
>  static int do_show_streams = 0;
> +static int do_show_frames  = 0;
>  
>  static int show_value_unit              = 0;
>  static int use_value_prefix             = 0;
> @@ -150,14 +151,60 @@ static void show_packet(AVFormatContext *fmt_ctx, 
> AVPacket *pkt)
>      printf("[/PACKET]\n");
>  }
>  
> +static int show_frame(AVFormatContext *fmt_ctx, AVPacket *pkt)
> +{
> +    AVFrame frame;
> +    int got_frame = 0;
> +    char val_str[128];
> +    AVDictionaryEntry *tag = NULL;
> +    AVCodecContext *dec_ctx = fmt_ctx->streams[pkt->stream_index]->codec;
> +
> +    if (dec_ctx->codec_type != AVMEDIA_TYPE_VIDEO ||
> +        avcodec_decode_video2(dec_ctx, &frame, &got_frame, pkt) <= 0 ||
> +        !got_frame)
> +        return got_frame;

I would prefer to keep the show_frame() logic dumb, it should only
show a frame, decoding should be better left in the calling code (this
way you also avoid a function call when type != VIDEO).

> +
> +    printf("[FRAME]\n");
> +    
> +    printf("pict_type=%c\n",              
> av_get_picture_type_char(frame.pict_type));
> +    printf("coded_picture_number=%d\n",   frame.coded_picture_number);
> +    printf("display_picture_number=%d\n", frame.display_picture_number);
> +    printf("interlaced_frame=%d\n",       frame.interlaced_frame);
> +    printf("top_field_first=%d\n",        frame.top_field_first);
> +    printf("repeat_pict=%d\n",            frame.repeat_pict);
> +    printf("reference=%d\n",              frame.reference);
> +    printf("key_frame=%d\n",              frame.key_frame);
> +    printf("pts=%s\n",                    ts_value_string (val_str, 
> sizeof(val_str), frame.pts));
> +
> +    while ((tag = av_dict_get(frame.metadata, "", tag, 
> AV_DICT_IGNORE_SUFFIX)))
> +        printf("TAG:%s=%s\n", tag->key, tag->value);
> +    printf("[/FRAME]\n");
> +
> +    return got_frame;
> +}
> +
>  static void show_packets(AVFormatContext *fmt_ctx)
>  {
>      AVPacket pkt;
> +    int i;
>  
>      av_init_packet(&pkt);
>  
> -    while (!av_read_frame(fmt_ctx, &pkt))
> -        show_packet(fmt_ctx, &pkt);
> +    while (!av_read_frame(fmt_ctx, &pkt)) {
> +        if (do_show_packets)
> +            show_packet(fmt_ctx, &pkt);
> +        if (do_show_frames)
> +            if (show_frame(fmt_ctx, &pkt))
> +                av_destruct_packet(&pkt);
> +    }
> +    av_init_packet(&pkt);
> +    pkt.data = NULL;
> +    pkt.size = 0;
> +    //Flush remaining frames that are cached in the decoder
> +    for (i = 0; i < fmt_ctx->nb_streams; i++) {
> +        pkt.stream_index = i;
> +        while (show_frame(fmt_ctx, &pkt));
> +    }
>  }
>  
>  static void show_stream(AVFormatContext *fmt_ctx, int stream_idx)
> @@ -315,7 +362,7 @@ static int probe_file(const char *filename)
>      if ((ret = open_input_file(&fmt_ctx, filename)))
>          return ret;
>  
> -    if (do_show_packets)
> +    if (do_show_packets || do_show_frames)
>          show_packets(fmt_ctx);
>  
>      if (do_show_streams)
> @@ -325,6 +372,8 @@ static int probe_file(const char *filename)
>      if (do_show_format)
>          show_format(fmt_ctx);
>  
> +    for (i = 0; i < fmt_ctx->nb_streams; i++)
> +        avcodec_close(fmt_ctx->streams[i]->codec);
>      av_close_input_file(fmt_ctx);
>      return 0;
>  }
> @@ -389,6 +438,7 @@ static const OptionDef options[] = {
>      { "show_format",  OPT_BOOL, {(void*)&do_show_format} , "show 
> format/container info" },
>      { "show_packets", OPT_BOOL, {(void*)&do_show_packets}, "show packets 
> info" },
>      { "show_streams", OPT_BOOL, {(void*)&do_show_streams}, "show streams 
> info" },
> +    { "show_frames",  OPT_BOOL, {(void*)&do_show_frames} , "show frames 
> info" },
>      { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, 
> {(void*)opt_default}, "generic catch all option", "" },
>      { NULL, },
>  };
> diff --git a/doc/avprobe.texi b/doc/avprobe.texi
> index 8955e1f..796ceee 100644
> --- a/doc/avprobe.texi
> +++ b/doc/avprobe.texi
> @@ -108,6 +108,13 @@ multimedia stream.
>  Each media stream information is printed within a dedicated section
>  with name "STREAM".
>  
> +@item -show_frames
> +Show information about each frame contained in the input multimedia
                          ^^^^^^^^^^

maybe *video frame* to stress the fact that the shown frames are
video only.

> +stream.
> +
> +The information for each single frame is printed within a dedicated
> +section with name "FRAME".
> +
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to