Browse code

libmodplug: add metadata support.

Clément Bœsch authored on 2011/10/06 08:19:02
Showing 1 changed files
... ...
@@ -19,10 +19,10 @@
19 19
 /**
20 20
 * @file
21 21
 * ModPlug demuxer
22
-* @todo metadata
23 22
 */
24 23
 
25 24
 #include <libmodplug/modplug.h>
25
+#include "libavutil/avstring.h"
26 26
 #include "libavutil/opt.h"
27 27
 #include "avformat.h"
28 28
 
... ...
@@ -68,6 +68,59 @@ static const AVOption options[] = {
68 68
     }                                                       \
69 69
 } while (0)
70 70
 
71
+#define ADD_META_MULTIPLE_ENTRIES(entry_name, fname) do {                      \
72
+    if (n_## entry_name ##s) {                                                 \
73
+        unsigned i, n = 0;                                                     \
74
+                                                                               \
75
+        for (i = 0; i < n_## entry_name ##s; i++) {                            \
76
+            char item_name[64] = {0};                                          \
77
+            fname(f, i, item_name);                                            \
78
+            if (!*item_name)                                                   \
79
+                continue;                                                      \
80
+            if (n)                                                             \
81
+                av_dict_set(&s->metadata, #entry_name, "\n", AV_DICT_APPEND);  \
82
+            av_dict_set(&s->metadata, #entry_name, item_name, AV_DICT_APPEND); \
83
+            n++;                                                               \
84
+        }                                                                      \
85
+                                                                               \
86
+        extra = av_asprintf(", %u/%u " #entry_name "%s",                       \
87
+                            n, n_## entry_name ##s, n > 1 ? "s" : "");         \
88
+        if (!extra)                                                            \
89
+            return AVERROR(ENOMEM);                                            \
90
+        av_dict_set(&s->metadata, "extra info", extra, AV_DICT_APPEND);        \
91
+        av_free(extra);                                                        \
92
+    }                                                                          \
93
+} while (0)
94
+
95
+static int modplug_load_metadata(AVFormatContext *s)
96
+{
97
+    ModPlugContext *modplug = s->priv_data;
98
+    ModPlugFile *f = modplug->f;
99
+    char *extra;
100
+    const char *name = ModPlug_GetName(f);
101
+    const char *msg  = ModPlug_GetMessage(f);
102
+
103
+    unsigned n_instruments = ModPlug_NumInstruments(f);
104
+    unsigned n_samples     = ModPlug_NumSamples(f);
105
+    unsigned n_patterns    = ModPlug_NumPatterns(f);
106
+    unsigned n_channels    = ModPlug_NumChannels(f);
107
+
108
+    if (name && *name) av_dict_set(&s->metadata, "name",    name, 0);
109
+    if (msg  && *msg)  av_dict_set(&s->metadata, "message", msg,  0);
110
+
111
+    extra = av_asprintf("%u pattern%s, %u channel%s",
112
+                        n_patterns, n_patterns > 1 ? "s" : "",
113
+                        n_channels, n_channels > 1 ? "s" : "");
114
+    if (!extra)
115
+        return AVERROR(ENOMEM);
116
+    av_dict_set(&s->metadata, "extra info", extra, AV_DICT_DONT_STRDUP_VAL);
117
+
118
+    ADD_META_MULTIPLE_ENTRIES(instrument, ModPlug_InstrumentName);
119
+    ADD_META_MULTIPLE_ENTRIES(sample,     ModPlug_SampleName);
120
+
121
+    return 0;
122
+}
123
+
71 124
 static int modplug_read_header(AVFormatContext *s, AVFormatParameters *ap)
72 125
 {
73 126
     AVStream *st;
... ...
@@ -127,7 +180,8 @@ static int modplug_read_header(AVFormatContext *s, AVFormatParameters *ap)
127 127
     st->codec->codec_id    = CODEC_ID_PCM_S16LE;
128 128
     st->codec->channels    = settings.mChannels;
129 129
     st->codec->sample_rate = settings.mFrequency;
130
-    return 0;
130
+
131
+    return modplug_load_metadata(s);
131 132
 }
132 133
 
133 134
 static int modplug_read_packet(AVFormatContext *s, AVPacket *pkt)