libmodplug: add metadata support.
This commit is contained in:
@ -19,10 +19,10 @@
|
|||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
* ModPlug demuxer
|
* ModPlug demuxer
|
||||||
* @todo metadata
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libmodplug/modplug.h>
|
#include <libmodplug/modplug.h>
|
||||||
|
#include "libavutil/avstring.h"
|
||||||
#include "libavutil/opt.h"
|
#include "libavutil/opt.h"
|
||||||
#include "avformat.h"
|
#include "avformat.h"
|
||||||
|
|
||||||
@ -68,6 +68,59 @@ static const AVOption options[] = {
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} 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)
|
static int modplug_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
||||||
{
|
{
|
||||||
AVStream *st;
|
AVStream *st;
|
||||||
@ -127,7 +180,8 @@ static int modplug_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
|||||||
st->codec->codec_id = CODEC_ID_PCM_S16LE;
|
st->codec->codec_id = CODEC_ID_PCM_S16LE;
|
||||||
st->codec->channels = settings.mChannels;
|
st->codec->channels = settings.mChannels;
|
||||||
st->codec->sample_rate = settings.mFrequency;
|
st->codec->sample_rate = settings.mFrequency;
|
||||||
return 0;
|
|
||||||
|
return modplug_load_metadata(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int modplug_read_packet(AVFormatContext *s, AVPacket *pkt)
|
static int modplug_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||||
|
Reference in New Issue
Block a user