[libav-devel] [PATCH] avprobe: json serialization output

Luca Barbato lu_zero at gentoo.org
Sun Sep 11 22:30:07 CEST 2011


Introduce -json to trigger json-ish output instead of ini-ish output
---
 avprobe.c |  149 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 144 insertions(+), 5 deletions(-)

diff --git a/avprobe.c b/avprobe.c
index 5e83916..c89f669 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_json_output = 0;
 
 static int show_value_unit              = 0;
 static int use_value_prefix             = 0;
@@ -130,6 +131,25 @@ static const char *media_type_string(enum AVMediaType media_type)
     }
 }
 
+static void show_packet_json(AVFormatContext *fmt_ctx, AVPacket *pkt)
+{
+    char val_str[128];
+    AVStream *st = fmt_ctx->streams[pkt->stream_index];
+
+    printf("{");
+    printf("\"codec_type\":\"%s\", "   , media_type_string(st->codec->codec_type));
+    printf("\"stream_index\":%d, " , pkt->stream_index);
+    printf("\"pts\":%s, "          , ts_value_string  (val_str, sizeof(val_str), pkt->pts));
+    printf("\"pts_time\":%s, "     , time_value_string(val_str, sizeof(val_str), pkt->pts, &st->time_base));
+    printf("\"dts\":%s, "          , ts_value_string  (val_str, sizeof(val_str), pkt->dts));
+    printf("\"dts_time\":%s, "     , time_value_string(val_str, sizeof(val_str), pkt->dts, &st->time_base));
+    printf("\"duration\":%s, "     , ts_value_string  (val_str, sizeof(val_str), pkt->duration));
+    printf("\"duration_time\":%s, ", time_value_string(val_str, sizeof(val_str), pkt->duration, &st->time_base));
+    printf("\"size\":%s, "         , value_string     (val_str, sizeof(val_str), pkt->size, unit_byte_str));
+    printf("\"pos\":%"PRId64", "   , pkt->pos);
+    printf("\"flags\":\"%c\""        , pkt->flags & AV_PKT_FLAG_KEY ? 'K' : '_');
+    printf("}\n");
+}
 static void show_packet(AVFormatContext *fmt_ctx, AVPacket *pkt)
 {
     char val_str[128];
@@ -156,8 +176,92 @@ static void show_packets(AVFormatContext *fmt_ctx)
 
     av_init_packet(&pkt);
 
-    while (!av_read_frame(fmt_ctx, &pkt))
-        show_packet(fmt_ctx, &pkt);
+    if (!do_json_output)
+        while (!av_read_frame(fmt_ctx, &pkt))
+            show_packet(fmt_ctx, &pkt);
+    else
+        while (!av_read_frame(fmt_ctx, &pkt))
+            show_packet_json(fmt_ctx, &pkt);
+
+}
+
+static void show_stream_json(AVFormatContext *fmt_ctx, int stream_idx)
+{
+    AVStream *stream = fmt_ctx->streams[stream_idx];
+    AVCodecContext *dec_ctx;
+    AVCodec *dec;
+    char val_str[128];
+    AVDictionaryEntry *tag = NULL;
+    AVRational display_aspect_ratio;
+
+    printf("{ ");
+
+    printf("\"index\":%d, ",        stream->index);
+
+    if ((dec_ctx = stream->codec)) {
+        if ((dec = dec_ctx->codec)) {
+            printf("\"codec_name\":\"%s\", ",         dec->name);
+            printf("\"codec_long_name\":\"%s\", ",    dec->long_name);
+        } else {
+            printf("\"codec_name\":\"unknown\", ");
+        }
+
+        printf("\"codec_type\":\"%s\", ",         media_type_string(dec_ctx->codec_type));
+        printf("\"codec_time_base\":\"%d/%d\", ", dec_ctx->time_base.num, dec_ctx->time_base.den);
+
+        /* print AVI/FourCC tag */
+        av_get_codec_tag_string(val_str, sizeof(val_str), dec_ctx->codec_tag);
+        printf("\"codec_tag_string\":\"%s\", ", val_str);
+        printf("\"codec_tag\":\"0x%04x\", ", dec_ctx->codec_tag);
+
+        switch (dec_ctx->codec_type) {
+        case AVMEDIA_TYPE_VIDEO:
+            printf("\"width\":%d, ",                   dec_ctx->width);
+            printf("\"height\":%d, ",                  dec_ctx->height);
+            printf("\"has_b_frames\":%d, ",            dec_ctx->has_b_frames);
+            if (dec_ctx->sample_aspect_ratio.num) {
+                printf("\"sample_aspect_ratio\":\"%d:%d\", ", dec_ctx->sample_aspect_ratio.num,
+                                                      dec_ctx->sample_aspect_ratio.den);
+                av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
+                          dec_ctx->width  * dec_ctx->sample_aspect_ratio.num,
+                          dec_ctx->height * dec_ctx->sample_aspect_ratio.den,
+                          1024*1024);
+                printf("\"display_aspect_ratio\":\"%d:%d\", ", display_aspect_ratio.num,
+                                                       display_aspect_ratio.den);
+            }
+            printf("\"pix_fmt\":\"%s\", ",                 dec_ctx->pix_fmt != PIX_FMT_NONE ?
+                   av_pix_fmt_descriptors[dec_ctx->pix_fmt].name : "unknown");
+            printf("\"level\":\%d, ",                   dec_ctx->level);
+            break;
+
+        case AVMEDIA_TYPE_AUDIO:
+            printf("\"sample_rate\":\"%s\", ",             value_string(val_str, sizeof(val_str),
+                                                                dec_ctx->sample_rate,
+                                                                unit_hertz_str));
+            printf("\"channels\":%d, ",                dec_ctx->channels);
+            printf("\"bits_per_sample\":%d, ",         av_get_bits_per_sample(dec_ctx->codec_id));
+            break;
+        }
+    } else {
+        printf("\"codec_type\":\"unknown\",");
+    }
+
+    if (fmt_ctx->iformat->flags & AVFMT_SHOW_IDS)
+        printf("\"id\":\"0x%x\", ", stream->id);
+    printf("\"r_frame_rate\":\"%d/%d\", ",         stream->r_frame_rate.num,   stream->r_frame_rate.den);
+    printf("\"avg_frame_rate\":\"%d/%d\", ",       stream->avg_frame_rate.num, stream->avg_frame_rate.den);
+    printf("\"time_base\":\"%d/%d\", ",            stream->time_base.num,      stream->time_base.den);
+    printf("\"start_time\":\"%s\", ",   time_value_string(val_str, sizeof(val_str), stream->start_time,
+                                                  &stream->time_base));
+    printf("\"duration\":\"%s\", ",     time_value_string(val_str, sizeof(val_str), stream->duration,
+                                                  &stream->time_base));
+    if (stream->nb_frames)
+        printf("\"nb_frames\":%"PRId64", ",    stream->nb_frames);
+
+    while ((tag = av_dict_get(stream->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
+        printf("\"TAG:%s\"=\"%s\", ", tag->key, tag->value);
+
+    printf("}");
 }
 
 static void show_stream(AVFormatContext *fmt_ctx, int stream_idx)
@@ -239,6 +343,31 @@ static void show_stream(AVFormatContext *fmt_ctx, int stream_idx)
     printf("[/STREAM]\n");
 }
 
+static void show_format_json(AVFormatContext *fmt_ctx)
+{
+    AVDictionaryEntry *tag = NULL;
+    char val_str[128];
+
+    printf("{");
+
+    printf("\"filename\":\"%s\", ",         fmt_ctx->filename);
+    printf("\"nb_streams\":%d, ",       fmt_ctx->nb_streams);
+    printf("\"format_name\":\"%s\", ",      fmt_ctx->iformat->name);
+    printf("\"format_long_name\":\"%s\", ", fmt_ctx->iformat->long_name);
+    printf("\"start_time\":\"%s\", ",       time_value_string(val_str, sizeof(val_str), fmt_ctx->start_time,
+                                                      &AV_TIME_BASE_Q));
+    printf("\"duration\":\"%s\", ",         time_value_string(val_str, sizeof(val_str), fmt_ctx->duration,
+                                                      &AV_TIME_BASE_Q));
+    printf("\"size\":\"%s\", ",             value_string(val_str, sizeof(val_str), fmt_ctx->file_size,
+                                                 unit_byte_str));
+    printf("\"bit_rate\":\"%s\", ",         value_string(val_str, sizeof(val_str), fmt_ctx->bit_rate,
+                                                 unit_bit_per_second_str));
+
+    while ((tag = av_dict_get(fmt_ctx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
+        printf("\"TAG:%s\":\"%s\", ", tag->key, tag->value);
+
+    printf("}\n");
+}
 static void show_format(AVFormatContext *fmt_ctx)
 {
     AVDictionaryEntry *tag = NULL;
@@ -319,11 +448,20 @@ static int probe_file(const char *filename)
         show_packets(fmt_ctx);
 
     if (do_show_streams)
-        for (i = 0; i < fmt_ctx->nb_streams; i++)
-            show_stream(fmt_ctx, i);
+        if (!do_json_output)
+            for (i = 0; i < fmt_ctx->nb_streams; i++)
+                show_stream(fmt_ctx, i);
+        else
+           for (i = 0; i < fmt_ctx->nb_streams; i++)
+                show_stream_json(fmt_ctx, i);
+
 
     if (do_show_format)
-        show_format(fmt_ctx);
+        if (!do_json_output)
+            show_format(fmt_ctx);
+        else
+            show_format_json(fmt_ctx);
+
 
     av_close_input_file(fmt_ctx);
     return 0;
@@ -391,6 +529,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" },
+    { "json", OPT_BOOL, {(void*)&do_json_output}, "output in json format" },
     { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
     { NULL, },
 };
-- 
1.7.6.1



More information about the libav-devel mailing list