+
+struct writer {
+ const char *name;
+ const char *item_sep; ///< separator between key/value couples
+ const char *items_sep; ///< separator between sets of key/value couples
+ const char *section_sep; ///< separator between sections (streams, packets, ...)
+ const char *header, *footer;
+ void (*print_header)(const char *);
+ void (*print_footer)(const char *);
+ void (*print_fmt_f)(const char *, const char *, ...);
+ void (*print_int_f)(const char *, int);
+ void (*show_tags)(struct writer *w, AVDictionary *dict);
+};
+
+
+/* Default output */
+
+static void default_print_header(const char *section)
+{
+ printf("[%s]\n", section);
+}
+
+static void default_print_fmt(const char *key, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ printf("%s=", key);
+ vprintf(fmt, ap);
+ va_end(ap);
+}
+
+static void default_print_int(const char *key, int value)
+{
+ printf("%s=%d", key, value);
+}
+
+static void default_print_footer(const char *section)
+{
+ printf("\n[/%s]", section);
+}
+
+
+/* Print helpers */
+
+#define print_fmt0(k, f, ...) w->print_fmt_f(k, f, __VA_ARGS__)
+#define print_fmt( k, f, ...) do { \
+ if (w->item_sep) \
+ printf("%s", w->item_sep); \
+ w->print_fmt_f(k, f, __VA_ARGS__); \
+} while (0)
+
+#define print_int0(k, v) w->print_int_f(k, v)
+#define print_int( k, v) do { \
+ if (w->item_sep) \
+ printf("%s", w->item_sep); \
+ print_int0(k, v); \
+} while (0)
+
+#define print_str0(k, v) print_fmt0(k, "%s", v)
+#define print_str( k, v) print_fmt (k, "%s", v)
+
+
+static void show_packet(struct writer *w, AVFormatContext *fmt_ctx, AVPacket *pkt, int packet_idx)