~ubuntu-branches/ubuntu/saucy/gst-libav1.0/saucy-proposed

« back to all changes in this revision

Viewing changes to gst-libs/ext/libav/avprobe.c

  • Committer: Package Import Robot
  • Author(s): Sebastian Dröge
  • Date: 2013-07-30 09:00:15 UTC
  • mfrom: (1.1.16) (7.1.7 experimental)
  • Revision ID: package-import@ubuntu.com-20130730090015-sc1ou2yssu7q5w4e
Tags: 1.1.3-1
* New upstream development snapshot:
  + debian/control:
    - Build depend on GStreamer and gst-plugins-base >= 1.1.3.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
#include "libavutil/opt.h"
27
27
#include "libavutil/pixdesc.h"
28
28
#include "libavutil/dict.h"
 
29
#include "libavutil/libm.h"
29
30
#include "libavdevice/avdevice.h"
30
31
#include "cmdutils.h"
31
32
 
33
34
const int program_birth_year = 2007;
34
35
 
35
36
static int do_show_format  = 0;
 
37
static AVDictionary *fmt_entries_to_show = NULL;
 
38
static int nb_fmt_entries_to_show;
36
39
static int do_show_packets = 0;
37
40
static int do_show_streams = 0;
38
41
 
42
45
static int use_value_sexagesimal_format = 0;
43
46
 
44
47
/* globals */
45
 
static const OptionDef options[];
 
48
static const OptionDef *options;
46
49
 
47
50
/* AVprobe context */
48
51
static const char *input_filename;
49
52
static AVInputFormat *iformat = NULL;
50
53
 
51
 
static const char *binary_unit_prefixes [] = { "", "Ki", "Mi", "Gi", "Ti", "Pi" };
52
 
static const char *decimal_unit_prefixes[] = { "", "K" , "M" , "G" , "T" , "P"  };
53
 
 
54
 
static const char *unit_second_str          = "s"    ;
55
 
static const char *unit_hertz_str           = "Hz"   ;
56
 
static const char *unit_byte_str            = "byte" ;
57
 
static const char *unit_bit_per_second_str  = "bit/s";
58
 
 
59
 
void exit_program(int ret)
60
 
{
61
 
    exit(ret);
 
54
static const char *const binary_unit_prefixes [] = { "", "Ki", "Mi", "Gi", "Ti", "Pi" };
 
55
static const char *const decimal_unit_prefixes[] = { "", "K" , "M" , "G" , "T" , "P"  };
 
56
 
 
57
static const char unit_second_str[]         = "s"    ;
 
58
static const char unit_hertz_str[]          = "Hz"   ;
 
59
static const char unit_byte_str[]           = "byte" ;
 
60
static const char unit_bit_per_second_str[] = "bit/s";
 
61
 
 
62
static void exit_program(void)
 
63
{
 
64
    av_dict_free(&fmt_entries_to_show);
 
65
}
 
66
 
 
67
/*
 
68
 * The output is structured in array and objects that might contain items
 
69
 * Array could require the objects within to not be named.
 
70
 * Object could require the items within to be named.
 
71
 *
 
72
 * For flat representation the name of each section is saved on prefix so it
 
73
 * can be rendered in order to represent nested structures (e.g. array of
 
74
 * objects for the packets list).
 
75
 *
 
76
 * Within an array each element can need an unique identifier or an index.
 
77
 *
 
78
 * Nesting level is accounted separately.
 
79
 */
 
80
 
 
81
typedef enum {
 
82
    ARRAY,
 
83
    OBJECT
 
84
} ProbeElementType;
 
85
 
 
86
typedef struct {
 
87
    const char *name;
 
88
    ProbeElementType type;
 
89
    int64_t index;
 
90
    int64_t nb_elems;
 
91
} ProbeElement;
 
92
 
 
93
typedef struct {
 
94
    ProbeElement *prefix;
 
95
    int level;
 
96
    void (*print_header)(void);
 
97
    void (*print_footer)(void);
 
98
 
 
99
    void (*print_array_header) (const char *name);
 
100
    void (*print_array_footer) (const char *name);
 
101
    void (*print_object_header)(const char *name);
 
102
    void (*print_object_footer)(const char *name);
 
103
 
 
104
    void (*print_integer) (const char *key, int64_t value);
 
105
    void (*print_string)  (const char *key, const char *value);
 
106
} OutputContext;
 
107
 
 
108
static AVIOContext *probe_out = NULL;
 
109
static OutputContext octx;
 
110
#define AVP_INDENT() avio_printf(probe_out, "%*c", octx.level * 2, ' ')
 
111
 
 
112
/*
 
113
 * Default format, INI
 
114
 *
 
115
 * - all key and values are utf8
 
116
 * - '.' is the subgroup separator
 
117
 * - newlines and the following characters are escaped
 
118
 * - '\' is the escape character
 
119
 * - '#' is the comment
 
120
 * - '=' is the key/value separators
 
121
 * - ':' is not used but usually parsed as key/value separator
 
122
 */
 
123
 
 
124
static void ini_print_header(void)
 
125
{
 
126
    avio_printf(probe_out, "# avprobe output\n\n");
 
127
}
 
128
static void ini_print_footer(void)
 
129
{
 
130
    avio_w8(probe_out, '\n');
 
131
}
 
132
 
 
133
static void ini_escape_print(const char *s)
 
134
{
 
135
    int i = 0;
 
136
    char c = 0;
 
137
 
 
138
    while (c = s[i++]) {
 
139
        switch (c) {
 
140
        case '\r': avio_printf(probe_out, "%s", "\\r"); break;
 
141
        case '\n': avio_printf(probe_out, "%s", "\\n"); break;
 
142
        case '\f': avio_printf(probe_out, "%s", "\\f"); break;
 
143
        case '\b': avio_printf(probe_out, "%s", "\\b"); break;
 
144
        case '\t': avio_printf(probe_out, "%s", "\\t"); break;
 
145
        case '\\':
 
146
        case '#' :
 
147
        case '=' :
 
148
        case ':' : avio_w8(probe_out, '\\');
 
149
        default:
 
150
            if ((unsigned char)c < 32)
 
151
                avio_printf(probe_out, "\\x00%02x", c & 0xff);
 
152
            else
 
153
                avio_w8(probe_out, c);
 
154
        break;
 
155
        }
 
156
    }
 
157
}
 
158
 
 
159
static void ini_print_array_header(const char *name)
 
160
{
 
161
    if (octx.prefix[octx.level -1].nb_elems)
 
162
        avio_printf(probe_out, "\n");
 
163
}
 
164
 
 
165
static void ini_print_object_header(const char *name)
 
166
{
 
167
    int i;
 
168
    ProbeElement *el = octx.prefix + octx.level -1;
 
169
 
 
170
    if (el->nb_elems)
 
171
        avio_printf(probe_out, "\n");
 
172
 
 
173
    avio_printf(probe_out, "[");
 
174
 
 
175
    for (i = 1; i < octx.level; i++) {
 
176
        el = octx.prefix + i;
 
177
        avio_printf(probe_out, "%s.", el->name);
 
178
        if (el->index >= 0)
 
179
            avio_printf(probe_out, "%"PRId64".", el->index);
 
180
    }
 
181
 
 
182
    avio_printf(probe_out, "%s", name);
 
183
    if (el && el->type == ARRAY)
 
184
        avio_printf(probe_out, ".%"PRId64"", el->nb_elems);
 
185
    avio_printf(probe_out, "]\n");
 
186
}
 
187
 
 
188
static void ini_print_integer(const char *key, int64_t value)
 
189
{
 
190
    ini_escape_print(key);
 
191
    avio_printf(probe_out, "=%"PRId64"\n", value);
 
192
}
 
193
 
 
194
 
 
195
static void ini_print_string(const char *key, const char *value)
 
196
{
 
197
    ini_escape_print(key);
 
198
    avio_printf(probe_out, "=");
 
199
    ini_escape_print(value);
 
200
    avio_w8(probe_out, '\n');
 
201
}
 
202
 
 
203
/*
 
204
 * Alternate format, JSON
 
205
 */
 
206
 
 
207
static void json_print_header(void)
 
208
{
 
209
    avio_printf(probe_out, "{");
 
210
}
 
211
static void json_print_footer(void)
 
212
{
 
213
    avio_printf(probe_out, "}\n");
 
214
}
 
215
 
 
216
static void json_print_array_header(const char *name)
 
217
{
 
218
    if (octx.prefix[octx.level -1].nb_elems)
 
219
        avio_printf(probe_out, ",\n");
 
220
    AVP_INDENT();
 
221
    avio_printf(probe_out, "\"%s\" : ", name);
 
222
    avio_printf(probe_out, "[\n");
 
223
}
 
224
 
 
225
static void json_print_array_footer(const char *name)
 
226
{
 
227
    avio_printf(probe_out, "\n");
 
228
    AVP_INDENT();
 
229
    avio_printf(probe_out, "]");
 
230
}
 
231
 
 
232
static void json_print_object_header(const char *name)
 
233
{
 
234
    if (octx.prefix[octx.level -1].nb_elems)
 
235
        avio_printf(probe_out, ",\n");
 
236
    AVP_INDENT();
 
237
    if (octx.prefix[octx.level -1].type == OBJECT)
 
238
        avio_printf(probe_out, "\"%s\" : ", name);
 
239
    avio_printf(probe_out, "{\n");
 
240
}
 
241
 
 
242
static void json_print_object_footer(const char *name)
 
243
{
 
244
    avio_printf(probe_out, "\n");
 
245
    AVP_INDENT();
 
246
    avio_printf(probe_out, "}");
 
247
}
 
248
 
 
249
static void json_print_integer(const char *key, int64_t value)
 
250
{
 
251
    if (octx.prefix[octx.level -1].nb_elems)
 
252
        avio_printf(probe_out, ",\n");
 
253
    AVP_INDENT();
 
254
    avio_printf(probe_out, "\"%s\" : %"PRId64"", key, value);
 
255
}
 
256
 
 
257
static void json_escape_print(const char *s)
 
258
{
 
259
    int i = 0;
 
260
    char c = 0;
 
261
 
 
262
    while (c = s[i++]) {
 
263
        switch (c) {
 
264
        case '\r': avio_printf(probe_out, "%s", "\\r"); break;
 
265
        case '\n': avio_printf(probe_out, "%s", "\\n"); break;
 
266
        case '\f': avio_printf(probe_out, "%s", "\\f"); break;
 
267
        case '\b': avio_printf(probe_out, "%s", "\\b"); break;
 
268
        case '\t': avio_printf(probe_out, "%s", "\\t"); break;
 
269
        case '\\':
 
270
        case '"' : avio_w8(probe_out, '\\');
 
271
        default:
 
272
            if ((unsigned char)c < 32)
 
273
                avio_printf(probe_out, "\\u00%02x", c & 0xff);
 
274
            else
 
275
                avio_w8(probe_out, c);
 
276
        break;
 
277
        }
 
278
    }
 
279
}
 
280
 
 
281
static void json_print_string(const char *key, const char *value)
 
282
{
 
283
    if (octx.prefix[octx.level -1].nb_elems)
 
284
        avio_printf(probe_out, ",\n");
 
285
    AVP_INDENT();
 
286
    avio_w8(probe_out, '\"');
 
287
    json_escape_print(key);
 
288
    avio_printf(probe_out, "\" : \"");
 
289
    json_escape_print(value);
 
290
    avio_w8(probe_out, '\"');
 
291
}
 
292
 
 
293
/*
 
294
 * old-style pseudo-INI
 
295
 */
 
296
static void old_print_object_header(const char *name)
 
297
{
 
298
    char *str, *p;
 
299
 
 
300
    if (!strcmp(name, "tags"))
 
301
        return;
 
302
 
 
303
    str = p = av_strdup(name);
 
304
    while (*p) {
 
305
        *p = toupper(*p);
 
306
        p++;
 
307
    }
 
308
 
 
309
    avio_printf(probe_out, "[%s]\n", str);
 
310
    av_freep(&str);
 
311
}
 
312
 
 
313
static void old_print_object_footer(const char *name)
 
314
{
 
315
    char *str, *p;
 
316
 
 
317
    if (!strcmp(name, "tags"))
 
318
        return;
 
319
 
 
320
    str = p = av_strdup(name);
 
321
    while (*p) {
 
322
        *p = toupper(*p);
 
323
        p++;
 
324
    }
 
325
 
 
326
    avio_printf(probe_out, "[/%s]\n", str);
 
327
    av_freep(&str);
 
328
}
 
329
 
 
330
static void old_print_string(const char *key, const char *value)
 
331
{
 
332
    if (!strcmp(octx.prefix[octx.level - 1].name, "tags"))
 
333
        avio_printf(probe_out, "TAG:");
 
334
    ini_print_string(key, value);
 
335
}
 
336
 
 
337
/*
 
338
 * Simple Formatter for single entries.
 
339
 */
 
340
 
 
341
static void show_format_entry_integer(const char *key, int64_t value)
 
342
{
 
343
    if (key && av_dict_get(fmt_entries_to_show, key, NULL, 0)) {
 
344
        if (nb_fmt_entries_to_show > 1)
 
345
            avio_printf(probe_out, "%s=", key);
 
346
        avio_printf(probe_out, "%"PRId64"\n", value);
 
347
    }
 
348
}
 
349
 
 
350
static void show_format_entry_string(const char *key, const char *value)
 
351
{
 
352
    if (key && av_dict_get(fmt_entries_to_show, key, NULL, 0)) {
 
353
        if (nb_fmt_entries_to_show > 1)
 
354
            avio_printf(probe_out, "%s=", key);
 
355
        avio_printf(probe_out, "%s\n", value);
 
356
    }
 
357
}
 
358
 
 
359
static void probe_group_enter(const char *name, int type)
 
360
{
 
361
    int64_t count = -1;
 
362
 
 
363
    octx.prefix =
 
364
        av_realloc(octx.prefix, sizeof(ProbeElement) * (octx.level + 1));
 
365
 
 
366
    if (!octx.prefix || !name) {
 
367
        fprintf(stderr, "Out of memory\n");
 
368
        exit(1);
 
369
    }
 
370
 
 
371
    if (octx.level) {
 
372
        ProbeElement *parent = octx.prefix + octx.level -1;
 
373
        if (parent->type == ARRAY)
 
374
            count = parent->nb_elems;
 
375
        parent->nb_elems++;
 
376
    }
 
377
 
 
378
    octx.prefix[octx.level++] = (ProbeElement){name, type, count, 0};
 
379
}
 
380
 
 
381
static void probe_group_leave(void)
 
382
{
 
383
    --octx.level;
 
384
}
 
385
 
 
386
static void probe_header(void)
 
387
{
 
388
    if (octx.print_header)
 
389
        octx.print_header();
 
390
    probe_group_enter("root", OBJECT);
 
391
}
 
392
 
 
393
static void probe_footer(void)
 
394
{
 
395
    if (octx.print_footer)
 
396
        octx.print_footer();
 
397
    probe_group_leave();
 
398
}
 
399
 
 
400
 
 
401
static void probe_array_header(const char *name)
 
402
{
 
403
    if (octx.print_array_header)
 
404
        octx.print_array_header(name);
 
405
 
 
406
    probe_group_enter(name, ARRAY);
 
407
}
 
408
 
 
409
static void probe_array_footer(const char *name)
 
410
{
 
411
    probe_group_leave();
 
412
    if (octx.print_array_footer)
 
413
        octx.print_array_footer(name);
 
414
}
 
415
 
 
416
static void probe_object_header(const char *name)
 
417
{
 
418
    if (octx.print_object_header)
 
419
        octx.print_object_header(name);
 
420
 
 
421
    probe_group_enter(name, OBJECT);
 
422
}
 
423
 
 
424
static void probe_object_footer(const char *name)
 
425
{
 
426
    probe_group_leave();
 
427
    if (octx.print_object_footer)
 
428
        octx.print_object_footer(name);
 
429
}
 
430
 
 
431
static void probe_int(const char *key, int64_t value)
 
432
{
 
433
    octx.print_integer(key, value);
 
434
    octx.prefix[octx.level -1].nb_elems++;
 
435
}
 
436
 
 
437
static void probe_str(const char *key, const char *value)
 
438
{
 
439
    octx.print_string(key, value);
 
440
    octx.prefix[octx.level -1].nb_elems++;
 
441
}
 
442
 
 
443
static void probe_dict(AVDictionary *dict, const char *name)
 
444
{
 
445
    AVDictionaryEntry *entry = NULL;
 
446
    if (!dict)
 
447
        return;
 
448
    probe_object_header(name);
 
449
    while ((entry = av_dict_get(dict, "", entry, AV_DICT_IGNORE_SUFFIX))) {
 
450
        probe_str(entry->key, entry->value);
 
451
    }
 
452
    probe_object_footer(name);
62
453
}
63
454
 
64
455
static char *value_string(char *buf, int buf_size, double val, const char *unit)
77
468
        int index;
78
469
 
79
470
        if (unit == unit_byte_str && use_byte_value_binary_prefix) {
80
 
            index = (int) (log(val)/log(2)) / 10;
 
471
            index = (int) log2(val) / 10;
81
472
            index = av_clip(index, 0, FF_ARRAY_ELEMS(binary_unit_prefixes) - 1);
82
473
            val  /= pow(2, index * 10);
83
474
            prefix_string = binary_unit_prefixes[index];
87
478
            val  /= pow(10, index * 3);
88
479
            prefix_string = decimal_unit_prefixes[index];
89
480
        }
90
 
 
91
 
        snprintf(buf, buf_size, "%.3f %s%s", val, prefix_string,
 
481
        snprintf(buf, buf_size, "%.*f%s%s",
 
482
                 index ? 3 : 0, val,
 
483
                 prefix_string,
92
484
                 show_value_unit ? unit : "");
93
485
    } else {
94
 
        snprintf(buf, buf_size, "%f %s", val, show_value_unit ? unit : "");
 
486
        snprintf(buf, buf_size, "%f%s", val, show_value_unit ? unit : "");
95
487
    }
96
488
 
97
489
    return buf;
109
501
    return buf;
110
502
}
111
503
 
112
 
static char *ts_value_string (char *buf, int buf_size, int64_t ts)
 
504
static char *ts_value_string(char *buf, int buf_size, int64_t ts)
113
505
{
114
506
    if (ts == AV_NOPTS_VALUE) {
115
507
        snprintf(buf, buf_size, "N/A");
120
512
    return buf;
121
513
}
122
514
 
 
515
static char *rational_string(char *buf, int buf_size, const char *sep,
 
516
                             const AVRational *rat)
 
517
{
 
518
    snprintf(buf, buf_size, "%d%s%d", rat->num, sep, rat->den);
 
519
    return buf;
 
520
}
 
521
 
 
522
static char *tag_string(char *buf, int buf_size, int tag)
 
523
{
 
524
    snprintf(buf, buf_size, "0x%04x", tag);
 
525
    return buf;
 
526
}
 
527
 
 
528
 
 
529
 
123
530
static const char *media_type_string(enum AVMediaType media_type)
124
531
{
125
532
    switch (media_type) {
137
544
    char val_str[128];
138
545
    AVStream *st = fmt_ctx->streams[pkt->stream_index];
139
546
 
140
 
    printf("[PACKET]\n");
141
 
    printf("codec_type=%s\n", media_type_string(st->codec->codec_type));
142
 
    printf("stream_index=%d\n", pkt->stream_index);
143
 
    printf("pts=%s\n", ts_value_string(val_str, sizeof(val_str), pkt->pts));
144
 
    printf("pts_time=%s\n", time_value_string(val_str, sizeof(val_str),
145
 
                                              pkt->pts, &st->time_base));
146
 
    printf("dts=%s\n", ts_value_string(val_str, sizeof(val_str), pkt->dts));
147
 
    printf("dts_time=%s\n", time_value_string(val_str, sizeof(val_str),
148
 
                                              pkt->dts, &st->time_base));
149
 
    printf("duration=%s\n", ts_value_string(val_str, sizeof(val_str),
150
 
                                            pkt->duration));
151
 
    printf("duration_time=%s\n", time_value_string(val_str, sizeof(val_str),
152
 
                                                   pkt->duration,
153
 
                                                   &st->time_base));
154
 
    printf("size=%s\n", value_string(val_str, sizeof(val_str),
155
 
                                     pkt->size, unit_byte_str));
156
 
    printf("pos=%"PRId64"\n", pkt->pos);
157
 
    printf("flags=%c\n", pkt->flags & AV_PKT_FLAG_KEY ? 'K' : '_');
158
 
    printf("[/PACKET]\n");
 
547
    probe_object_header("packet");
 
548
    probe_str("codec_type", media_type_string(st->codec->codec_type));
 
549
    probe_int("stream_index", pkt->stream_index);
 
550
    probe_str("pts", ts_value_string(val_str, sizeof(val_str), pkt->pts));
 
551
    probe_str("pts_time", time_value_string(val_str, sizeof(val_str),
 
552
                                               pkt->pts, &st->time_base));
 
553
    probe_str("dts", ts_value_string(val_str, sizeof(val_str), pkt->dts));
 
554
    probe_str("dts_time", time_value_string(val_str, sizeof(val_str),
 
555
                                               pkt->dts, &st->time_base));
 
556
    probe_str("duration", ts_value_string(val_str, sizeof(val_str),
 
557
                                             pkt->duration));
 
558
    probe_str("duration_time", time_value_string(val_str, sizeof(val_str),
 
559
                                                    pkt->duration,
 
560
                                                    &st->time_base));
 
561
    probe_str("size", value_string(val_str, sizeof(val_str),
 
562
                                      pkt->size, unit_byte_str));
 
563
    probe_int("pos", pkt->pos);
 
564
    probe_str("flags", pkt->flags & AV_PKT_FLAG_KEY ? "K" : "_");
 
565
    probe_object_footer("packet");
159
566
}
160
567
 
161
568
static void show_packets(AVFormatContext *fmt_ctx)
163
570
    AVPacket pkt;
164
571
 
165
572
    av_init_packet(&pkt);
166
 
 
 
573
    probe_array_header("packets");
167
574
    while (!av_read_frame(fmt_ctx, &pkt))
168
575
        show_packet(fmt_ctx, &pkt);
 
576
    probe_array_footer("packets");
169
577
}
170
578
 
171
579
static void show_stream(AVFormatContext *fmt_ctx, int stream_idx)
172
580
{
173
581
    AVStream *stream = fmt_ctx->streams[stream_idx];
174
582
    AVCodecContext *dec_ctx;
175
 
    AVCodec *dec;
 
583
    const AVCodec *dec;
 
584
    const char *profile;
176
585
    char val_str[128];
177
 
    AVDictionaryEntry *tag = NULL;
178
 
    AVRational display_aspect_ratio;
179
 
 
180
 
    printf("[STREAM]\n");
181
 
 
182
 
    printf("index=%d\n", stream->index);
 
586
    AVRational display_aspect_ratio, *sar = NULL;
 
587
    const AVPixFmtDescriptor *desc;
 
588
 
 
589
    probe_object_header("stream");
 
590
 
 
591
    probe_int("index", stream->index);
183
592
 
184
593
    if ((dec_ctx = stream->codec)) {
185
594
        if ((dec = dec_ctx->codec)) {
186
 
            printf("codec_name=%s\n", dec->name);
187
 
            printf("codec_long_name=%s\n", dec->long_name);
 
595
            probe_str("codec_name", dec->name);
 
596
            probe_str("codec_long_name", dec->long_name);
188
597
        } else {
189
 
            printf("codec_name=unknown\n");
 
598
            probe_str("codec_name", "unknown");
190
599
        }
191
600
 
192
 
        printf("codec_type=%s\n", media_type_string(dec_ctx->codec_type));
193
 
        printf("codec_time_base=%d/%d\n",
194
 
               dec_ctx->time_base.num, dec_ctx->time_base.den);
 
601
        probe_str("codec_type", media_type_string(dec_ctx->codec_type));
 
602
        probe_str("codec_time_base",
 
603
                  rational_string(val_str, sizeof(val_str),
 
604
                                  "/", &dec_ctx->time_base));
195
605
 
196
606
        /* print AVI/FourCC tag */
197
607
        av_get_codec_tag_string(val_str, sizeof(val_str), dec_ctx->codec_tag);
198
 
        printf("codec_tag_string=%s\n", val_str);
199
 
        printf("codec_tag=0x%04x\n", dec_ctx->codec_tag);
 
608
        probe_str("codec_tag_string", val_str);
 
609
        probe_str("codec_tag", tag_string(val_str, sizeof(val_str),
 
610
                                          dec_ctx->codec_tag));
 
611
 
 
612
        /* print profile, if there is one */
 
613
        if (dec && (profile = av_get_profile_name(dec, dec_ctx->profile)))
 
614
            probe_str("profile", profile);
200
615
 
201
616
        switch (dec_ctx->codec_type) {
202
617
        case AVMEDIA_TYPE_VIDEO:
203
 
            printf("width=%d\n", dec_ctx->width);
204
 
            printf("height=%d\n", dec_ctx->height);
205
 
            printf("has_b_frames=%d\n", dec_ctx->has_b_frames);
206
 
            if (dec_ctx->sample_aspect_ratio.num) {
207
 
                printf("sample_aspect_ratio=%d:%d\n",
208
 
                       dec_ctx->sample_aspect_ratio.num,
209
 
                       dec_ctx->sample_aspect_ratio.den);
 
618
            probe_int("width", dec_ctx->width);
 
619
            probe_int("height", dec_ctx->height);
 
620
            probe_int("has_b_frames", dec_ctx->has_b_frames);
 
621
            if (dec_ctx->sample_aspect_ratio.num)
 
622
                sar = &dec_ctx->sample_aspect_ratio;
 
623
            else if (stream->sample_aspect_ratio.num)
 
624
                sar = &stream->sample_aspect_ratio;
 
625
 
 
626
            if (sar) {
 
627
                probe_str("sample_aspect_ratio",
 
628
                          rational_string(val_str, sizeof(val_str), ":", sar));
210
629
                av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
211
 
                          dec_ctx->width  * dec_ctx->sample_aspect_ratio.num,
212
 
                          dec_ctx->height * dec_ctx->sample_aspect_ratio.den,
 
630
                          dec_ctx->width  * sar->num, dec_ctx->height * sar->den,
213
631
                          1024*1024);
214
 
                printf("display_aspect_ratio=%d:%d\n",
215
 
                       display_aspect_ratio.num, display_aspect_ratio.den);
 
632
                probe_str("display_aspect_ratio",
 
633
                          rational_string(val_str, sizeof(val_str), ":",
 
634
                          &display_aspect_ratio));
216
635
            }
217
 
            printf("pix_fmt=%s\n",
218
 
                   dec_ctx->pix_fmt != PIX_FMT_NONE ? av_pix_fmt_descriptors[dec_ctx->pix_fmt].name
219
 
                                                    : "unknown");
220
 
            printf("level=%d\n", dec_ctx->level);
 
636
            desc = av_pix_fmt_desc_get(dec_ctx->pix_fmt);
 
637
            probe_str("pix_fmt", desc ? desc->name : "unknown");
 
638
            probe_int("level", dec_ctx->level);
221
639
            break;
222
640
 
223
641
        case AVMEDIA_TYPE_AUDIO:
224
 
            printf("sample_rate=%s\n", value_string(val_str, sizeof(val_str),
225
 
                                                    dec_ctx->sample_rate,
226
 
                                                    unit_hertz_str));
227
 
            printf("channels=%d\n", dec_ctx->channels);
228
 
            printf("bits_per_sample=%d\n",
229
 
                   av_get_bits_per_sample(dec_ctx->codec_id));
 
642
            probe_str("sample_rate",
 
643
                      value_string(val_str, sizeof(val_str),
 
644
                                   dec_ctx->sample_rate,
 
645
                                   unit_hertz_str));
 
646
            probe_int("channels", dec_ctx->channels);
 
647
            probe_int("bits_per_sample",
 
648
                      av_get_bits_per_sample(dec_ctx->codec_id));
230
649
            break;
231
650
        }
232
651
    } else {
233
 
        printf("codec_type=unknown\n");
 
652
        probe_str("codec_type", "unknown");
234
653
    }
235
654
 
236
655
    if (fmt_ctx->iformat->flags & AVFMT_SHOW_IDS)
237
 
        printf("id=0x%x\n", stream->id);
238
 
    printf("r_frame_rate=%d/%d\n",
239
 
           stream->r_frame_rate.num, stream->r_frame_rate.den);
240
 
    printf("avg_frame_rate=%d/%d\n",
241
 
           stream->avg_frame_rate.num, stream->avg_frame_rate.den);
242
 
    printf("time_base=%d/%d\n",
243
 
           stream->time_base.num, stream->time_base.den);
244
 
    printf("start_time=%s\n",
245
 
           time_value_string(val_str, sizeof(val_str),
246
 
                             stream->start_time, &stream->time_base));
247
 
    printf("duration=%s\n",
248
 
           time_value_string(val_str, sizeof(val_str),
249
 
                             stream->duration, &stream->time_base));
 
656
        probe_int("id", stream->id);
 
657
    probe_str("avg_frame_rate",
 
658
              rational_string(val_str, sizeof(val_str), "/",
 
659
              &stream->avg_frame_rate));
 
660
    if (dec_ctx->bit_rate)
 
661
        probe_str("bit_rate",
 
662
                  value_string(val_str, sizeof(val_str),
 
663
                               dec_ctx->bit_rate, unit_bit_per_second_str));
 
664
    probe_str("time_base",
 
665
              rational_string(val_str, sizeof(val_str), "/",
 
666
              &stream->time_base));
 
667
    probe_str("start_time",
 
668
              time_value_string(val_str, sizeof(val_str),
 
669
                                stream->start_time, &stream->time_base));
 
670
    probe_str("duration",
 
671
              time_value_string(val_str, sizeof(val_str),
 
672
                                stream->duration, &stream->time_base));
250
673
    if (stream->nb_frames)
251
 
        printf("nb_frames=%"PRId64"\n", stream->nb_frames);
252
 
 
253
 
    while ((tag = av_dict_get(stream->metadata, "", tag,
254
 
                              AV_DICT_IGNORE_SUFFIX)))
255
 
        printf("TAG:%s=%s\n", tag->key, tag->value);
256
 
 
257
 
    printf("[/STREAM]\n");
 
674
        probe_int("nb_frames", stream->nb_frames);
 
675
 
 
676
    probe_dict(stream->metadata, "tags");
 
677
 
 
678
    probe_object_footer("stream");
258
679
}
259
680
 
260
681
static void show_format(AVFormatContext *fmt_ctx)
261
682
{
262
 
    AVDictionaryEntry *tag = NULL;
263
683
    char val_str[128];
264
684
    int64_t size = fmt_ctx->pb ? avio_size(fmt_ctx->pb) : -1;
265
685
 
266
 
    printf("[FORMAT]\n");
267
 
 
268
 
    printf("filename=%s\n", fmt_ctx->filename);
269
 
    printf("nb_streams=%d\n", fmt_ctx->nb_streams);
270
 
    printf("format_name=%s\n", fmt_ctx->iformat->name);
271
 
    printf("format_long_name=%s\n", fmt_ctx->iformat->long_name);
272
 
    printf("start_time=%s\n",
273
 
           time_value_string(val_str, sizeof(val_str),
274
 
                             fmt_ctx->start_time, &AV_TIME_BASE_Q));
275
 
    printf("duration=%s\n",
276
 
           time_value_string(val_str, sizeof(val_str),
277
 
                             fmt_ctx->duration, &AV_TIME_BASE_Q));
278
 
    printf("size=%s\n", size >= 0 ? value_string(val_str, sizeof(val_str),
279
 
                                                 size, unit_byte_str)
 
686
    probe_object_header("format");
 
687
    probe_str("filename",         fmt_ctx->filename);
 
688
    probe_int("nb_streams",       fmt_ctx->nb_streams);
 
689
    probe_str("format_name",      fmt_ctx->iformat->name);
 
690
    probe_str("format_long_name", fmt_ctx->iformat->long_name);
 
691
    probe_str("start_time",
 
692
                       time_value_string(val_str, sizeof(val_str),
 
693
                                         fmt_ctx->start_time, &AV_TIME_BASE_Q));
 
694
    probe_str("duration",
 
695
                       time_value_string(val_str, sizeof(val_str),
 
696
                                         fmt_ctx->duration, &AV_TIME_BASE_Q));
 
697
    probe_str("size",
 
698
                       size >= 0 ? value_string(val_str, sizeof(val_str),
 
699
                                                size, unit_byte_str)
280
700
                                  : "unknown");
281
 
    printf("bit_rate=%s\n",
282
 
           value_string(val_str, sizeof(val_str),
283
 
                        fmt_ctx->bit_rate, unit_bit_per_second_str));
284
 
 
285
 
    while ((tag = av_dict_get(fmt_ctx->metadata, "", tag,
286
 
                              AV_DICT_IGNORE_SUFFIX)))
287
 
        printf("TAG:%s=%s\n", tag->key, tag->value);
288
 
 
289
 
    printf("[/FORMAT]\n");
 
701
    probe_str("bit_rate",
 
702
                       value_string(val_str, sizeof(val_str),
 
703
                                    fmt_ctx->bit_rate, unit_bit_per_second_str));
 
704
 
 
705
    probe_dict(fmt_ctx->metadata, "tags");
 
706
 
 
707
    probe_object_footer("format");
290
708
}
291
709
 
292
710
static int open_input_file(AVFormatContext **fmt_ctx_ptr, const char *filename)
319
737
        AVStream *stream = fmt_ctx->streams[i];
320
738
        AVCodec *codec;
321
739
 
322
 
        if (!(codec = avcodec_find_decoder(stream->codec->codec_id))) {
 
740
        if (stream->codec->codec_id == AV_CODEC_ID_PROBE) {
 
741
            fprintf(stderr, "Failed to probe codec for input stream %d\n",
 
742
                    stream->index);
 
743
        } else if (!(codec = avcodec_find_decoder(stream->codec->codec_id))) {
323
744
            fprintf(stderr,
324
745
                    "Unsupported codec with id %d for input stream %d\n",
325
746
                    stream->codec->codec_id, stream->index);
333
754
    return 0;
334
755
}
335
756
 
 
757
static void close_input_file(AVFormatContext **ctx_ptr)
 
758
{
 
759
    int i;
 
760
    AVFormatContext *fmt_ctx = *ctx_ptr;
 
761
 
 
762
    /* close decoder for each stream */
 
763
    for (i = 0; i < fmt_ctx->nb_streams; i++) {
 
764
        AVStream *stream = fmt_ctx->streams[i];
 
765
 
 
766
        avcodec_close(stream->codec);
 
767
    }
 
768
    avformat_close_input(ctx_ptr);
 
769
}
 
770
 
336
771
static int probe_file(const char *filename)
337
772
{
338
773
    AVFormatContext *fmt_ctx;
341
776
    if ((ret = open_input_file(&fmt_ctx, filename)))
342
777
        return ret;
343
778
 
 
779
    if (do_show_format)
 
780
        show_format(fmt_ctx);
 
781
 
 
782
    if (do_show_streams) {
 
783
        probe_array_header("streams");
 
784
        for (i = 0; i < fmt_ctx->nb_streams; i++)
 
785
            show_stream(fmt_ctx, i);
 
786
        probe_array_footer("streams");
 
787
    }
 
788
 
344
789
    if (do_show_packets)
345
790
        show_packets(fmt_ctx);
346
791
 
347
 
    if (do_show_streams)
348
 
        for (i = 0; i < fmt_ctx->nb_streams; i++)
349
 
            show_stream(fmt_ctx, i);
350
 
 
351
 
    if (do_show_format)
352
 
        show_format(fmt_ctx);
353
 
 
354
 
    avformat_close_input(&fmt_ctx);
 
792
    close_input_file(&fmt_ctx);
355
793
    return 0;
356
794
}
357
795
 
362
800
    printf("\n");
363
801
}
364
802
 
365
 
static int opt_format(const char *opt, const char *arg)
 
803
static int opt_format(void *optctx, const char *opt, const char *arg)
366
804
{
367
805
    iformat = av_find_input_format(arg);
368
806
    if (!iformat) {
372
810
    return 0;
373
811
}
374
812
 
 
813
static int opt_output_format(void *optctx, const char *opt, const char *arg)
 
814
{
 
815
 
 
816
    if (!strcmp(arg, "json")) {
 
817
        octx.print_header        = json_print_header;
 
818
        octx.print_footer        = json_print_footer;
 
819
        octx.print_array_header  = json_print_array_header;
 
820
        octx.print_array_footer  = json_print_array_footer;
 
821
        octx.print_object_header = json_print_object_header;
 
822
        octx.print_object_footer = json_print_object_footer;
 
823
 
 
824
        octx.print_integer = json_print_integer;
 
825
        octx.print_string  = json_print_string;
 
826
    } else if (!strcmp(arg, "ini")) {
 
827
        octx.print_header        = ini_print_header;
 
828
        octx.print_footer        = ini_print_footer;
 
829
        octx.print_array_header  = ini_print_array_header;
 
830
        octx.print_object_header = ini_print_object_header;
 
831
 
 
832
        octx.print_integer = ini_print_integer;
 
833
        octx.print_string  = ini_print_string;
 
834
    } else if (!strcmp(arg, "old")) {
 
835
        octx.print_header        = NULL;
 
836
        octx.print_object_header = old_print_object_header;
 
837
        octx.print_object_footer = old_print_object_footer;
 
838
 
 
839
        octx.print_string        = old_print_string;
 
840
    } else {
 
841
        av_log(NULL, AV_LOG_ERROR, "Unsupported formatter %s\n", arg);
 
842
        return AVERROR(EINVAL);
 
843
    }
 
844
    return 0;
 
845
}
 
846
 
 
847
static int opt_show_format_entry(void *optctx, const char *opt, const char *arg)
 
848
{
 
849
    do_show_format = 1;
 
850
    nb_fmt_entries_to_show++;
 
851
    octx.print_header        = NULL;
 
852
    octx.print_footer        = NULL;
 
853
    octx.print_array_header  = NULL;
 
854
    octx.print_array_footer  = NULL;
 
855
    octx.print_object_header = NULL;
 
856
    octx.print_object_footer = NULL;
 
857
 
 
858
    octx.print_integer = show_format_entry_integer;
 
859
    octx.print_string  = show_format_entry_string;
 
860
    av_dict_set(&fmt_entries_to_show, arg, "", 0);
 
861
    return 0;
 
862
}
 
863
 
375
864
static void opt_input_file(void *optctx, const char *arg)
376
865
{
377
866
    if (input_filename) {
385
874
    input_filename = arg;
386
875
}
387
876
 
388
 
static void show_help(void)
 
877
void show_help_default(const char *opt, const char *arg)
389
878
{
390
879
    av_log_set_callback(log_callback_help);
391
880
    show_usage();
392
 
    show_help_options(options, "Main options:\n", 0, 0);
 
881
    show_help_options(options, "Main options:", 0, 0, 0);
393
882
    printf("\n");
394
883
    show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
395
884
}
396
885
 
397
 
static void opt_pretty(void)
 
886
static int opt_pretty(void *optctx, const char *opt, const char *arg)
398
887
{
399
888
    show_value_unit              = 1;
400
889
    use_value_prefix             = 1;
401
890
    use_byte_value_binary_prefix = 1;
402
891
    use_value_sexagesimal_format = 1;
 
892
    return 0;
403
893
}
404
894
 
405
 
static const OptionDef options[] = {
 
895
static const OptionDef real_options[] = {
406
896
#include "cmdutils_common_opts.h"
407
 
    { "f", HAS_ARG, {(void*)opt_format}, "force format", "format" },
408
 
    { "unit", OPT_BOOL, {(void*)&show_value_unit},
 
897
    { "f", HAS_ARG, {.func_arg = opt_format}, "force format", "format" },
 
898
    { "of", HAS_ARG, {.func_arg = opt_output_format}, "output the document either as ini or json", "output_format" },
 
899
    { "unit", OPT_BOOL, {&show_value_unit},
409
900
      "show unit of the displayed values" },
410
 
    { "prefix", OPT_BOOL, {(void*)&use_value_prefix},
 
901
    { "prefix", OPT_BOOL, {&use_value_prefix},
411
902
      "use SI prefixes for the displayed values" },
412
 
    { "byte_binary_prefix", OPT_BOOL, {(void*)&use_byte_value_binary_prefix},
 
903
    { "byte_binary_prefix", OPT_BOOL, {&use_byte_value_binary_prefix},
413
904
      "use binary prefixes for byte units" },
414
 
    { "sexagesimal", OPT_BOOL,  {(void*)&use_value_sexagesimal_format},
 
905
    { "sexagesimal", OPT_BOOL,  {&use_value_sexagesimal_format},
415
906
      "use sexagesimal format HOURS:MM:SS.MICROSECONDS for time units" },
416
 
    { "pretty", 0, {(void*)&opt_pretty},
 
907
    { "pretty", 0, {.func_arg = opt_pretty},
417
908
      "prettify the format of displayed values, make it more human readable" },
418
 
    { "show_format",  OPT_BOOL, {(void*)&do_show_format} , "show format/container info" },
419
 
    { "show_packets", OPT_BOOL, {(void*)&do_show_packets}, "show packets info" },
420
 
    { "show_streams", OPT_BOOL, {(void*)&do_show_streams}, "show streams info" },
421
 
    { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default},
 
909
    { "show_format",  OPT_BOOL, {&do_show_format} , "show format/container info" },
 
910
    { "show_format_entry", HAS_ARG, {.func_arg = opt_show_format_entry},
 
911
      "show a particular entry from the format/container info", "entry" },
 
912
    { "show_packets", OPT_BOOL, {&do_show_packets}, "show packets info" },
 
913
    { "show_streams", OPT_BOOL, {&do_show_streams}, "show streams info" },
 
914
    { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {.func_arg = opt_default},
422
915
      "generic catch all option", "" },
423
916
    { NULL, },
424
917
};
425
918
 
 
919
static int probe_buf_write(void *opaque, uint8_t *buf, int buf_size)
 
920
{
 
921
    printf("%.*s", buf_size, buf);
 
922
    return 0;
 
923
}
 
924
 
 
925
#define AVP_BUFFSIZE 4096
 
926
 
426
927
int main(int argc, char **argv)
427
928
{
428
929
    int ret;
429
 
 
 
930
    uint8_t *buffer = av_malloc(AVP_BUFFSIZE);
 
931
 
 
932
    if (!buffer)
 
933
        exit(1);
 
934
 
 
935
    atexit(exit_program);
 
936
 
 
937
    options = real_options;
430
938
    parse_loglevel(argc, argv, options);
431
939
    av_register_all();
432
940
    avformat_network_init();
436
944
#endif
437
945
 
438
946
    show_banner();
 
947
 
 
948
    octx.print_header = ini_print_header;
 
949
    octx.print_footer = ini_print_footer;
 
950
 
 
951
    octx.print_array_header = ini_print_array_header;
 
952
    octx.print_object_header = ini_print_object_header;
 
953
 
 
954
    octx.print_integer = ini_print_integer;
 
955
    octx.print_string = ini_print_string;
 
956
 
439
957
    parse_options(NULL, argc, argv, options, opt_input_file);
440
958
 
441
959
    if (!input_filename) {
447
965
        exit(1);
448
966
    }
449
967
 
 
968
    probe_out = avio_alloc_context(buffer, AVP_BUFFSIZE, 1, NULL, NULL,
 
969
                                 probe_buf_write, NULL);
 
970
    if (!probe_out)
 
971
        exit(1);
 
972
 
 
973
    probe_header();
450
974
    ret = probe_file(input_filename);
 
975
    probe_footer();
 
976
    avio_flush(probe_out);
 
977
    avio_close(probe_out);
451
978
 
452
979
    avformat_network_deinit();
453
980