[FFmpeg-devel] [PATCH] libmodplug: add metadata support.
Clément Bœsch
ubitux at gmail.com
Thu Oct 6 01:19:18 CEST 2011
---
libavformat/libmodplug.c | 58 ++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 56 insertions(+), 2 deletions(-)
diff --git a/libavformat/libmodplug.c b/libavformat/libmodplug.c
index 29a3f4f..5275f9e 100644
--- a/libavformat/libmodplug.c
+++ b/libavformat/libmodplug.c
@@ -19,11 +19,11 @@
/**
* @file
* ModPlug demuxer
-* @todo metadata
*/
#include <libmodplug/modplug.h>
#include "libavutil/opt.h"
+#include "libavutil/avstring.h"
#include "avformat.h"
typedef struct ModPlugContext {
@@ -68,6 +68,59 @@ static const AVOption options[] = {
} \
} while (0)
+#define ADD_META_MULTIPLE_ENTRIES(entry_name, fname) do { \
+ if (n_## entry_name ##s) { \
+ unsigned i, n = 0; \
+ \
+ for (i = 0; i < n_## entry_name ##s; i++) { \
+ char item_name[64] = {0}; \
+ fname(f, i, item_name); \
+ if (!*item_name) \
+ continue; \
+ if (n) \
+ av_dict_set(&s->metadata, #entry_name, "\n", AV_DICT_APPEND); \
+ av_dict_set(&s->metadata, #entry_name, item_name, AV_DICT_APPEND); \
+ n++; \
+ } \
+ \
+ extra = av_asprintf(", %u/%u " #entry_name "%s", \
+ n, n_## entry_name ##s, n > 1 ? "s" : ""); \
+ if (!extra) \
+ return AVERROR(ENOMEM); \
+ av_dict_set(&s->metadata, "extra info", extra, AV_DICT_APPEND); \
+ av_free(extra); \
+ } \
+} while (0)
+
+static int modplug_load_metadata(AVFormatContext *s)
+{
+ ModPlugContext *modplug = s->priv_data;
+ ModPlugFile *f = modplug->f;
+ char *extra;
+ const char *name = ModPlug_GetName(f);
+ const char *msg = ModPlug_GetMessage(f);
+
+ unsigned n_instruments = ModPlug_NumInstruments(f);
+ unsigned n_samples = ModPlug_NumSamples(f);
+ unsigned n_patterns = ModPlug_NumPatterns(f);
+ unsigned n_channels = ModPlug_NumChannels(f);
+
+ if (name && *name) av_dict_set(&s->metadata, "name", name, 0);
+ if (msg && *msg) av_dict_set(&s->metadata, "message", msg, 0);
+
+ extra = av_asprintf("%u pattern%s, %u channel%s",
+ n_patterns, n_patterns > 1 ? "s" : "",
+ n_channels, n_channels > 1 ? "s" : "");
+ if (!extra)
+ return AVERROR(ENOMEM);
+ av_dict_set(&s->metadata, "extra info", extra, AV_DICT_DONT_STRDUP_VAL);
+
+ ADD_META_MULTIPLE_ENTRIES(instrument, ModPlug_InstrumentName);
+ ADD_META_MULTIPLE_ENTRIES(sample, ModPlug_SampleName);
+
+ return 0;
+}
+
static int modplug_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
AVStream *st;
@@ -129,7 +182,8 @@ static int modplug_read_header(AVFormatContext *s, AVFormatParameters *ap)
st->codec->codec_id = CODEC_ID_PCM_S16LE;
st->codec->channels = settings.mChannels;
st->codec->sample_rate = settings.mFrequency;
- return 0;
+
+ return modplug_load_metadata(s);
}
static int modplug_read_packet(AVFormatContext *s, AVPacket *pkt)
--
1.7.7
More information about the ffmpeg-devel
mailing list