typedef struct GMEContext {
const AVClass *class;
Music_Emu *music_emu;
- gme_info_t *info; ///< selected track
/* options */
int track_index;
av_dict_set(&s->metadata, name, value, 0);
}
-static int load_metadata(AVFormatContext *s)
+static int load_metadata(AVFormatContext *s, int64_t *duration)
{
GMEContext *gme = s->priv_data;
- gme_info_t *info = gme->info;
+ gme_info_t *info = NULL;
char buf[30];
+ if (gme_track_info(gme->music_emu, &info, gme->track_index))
+ return AVERROR_STREAM_NOT_FOUND;
+
+ *duration = info->length;
add_meta(s, "system", info->system);
add_meta(s, "game", info->game);
add_meta(s, "song", info->song);
snprintf(buf, sizeof(buf), "%d", (int)gme_track_count(gme->music_emu));
add_meta(s, "tracks", buf);
+ gme_free_info(info);
return 0;
}
#define AUDIO_PKT_SIZE 512
+static int read_close_gme(AVFormatContext *s)
+{
+ GMEContext *gme = s->priv_data;
+ gme_delete(gme->music_emu);
+ return 0;
+}
+
static int read_header_gme(AVFormatContext *s)
{
AVStream *st;
AVIOContext *pb = s->pb;
GMEContext *gme = s->priv_data;
int64_t sz = avio_size(pb);
+ int64_t duration;
char *buf;
char dummy;
+ int ret;
if (sz < 0) {
av_log(s, AV_LOG_WARNING, "Could not determine file size\n");
av_log(s, AV_LOG_ERROR, "File size is larger than max_size option "
"value %"PRIi64", consider increasing the max_size option\n",
gme->max_size);
+ av_freep(&buf);
return AVERROR_BUFFER_TOO_SMALL;
}
}
av_freep(&buf);
- if (gme_track_info(gme->music_emu, &gme->info, gme->track_index))
- return AVERROR_STREAM_NOT_FOUND;
-
- if (gme_start_track(gme->music_emu, gme->track_index))
+ ret = load_metadata(s, &duration);
+ if (ret < 0) {
+ read_close_gme(s);
+ return ret;
+ }
+ if (gme_start_track(gme->music_emu, gme->track_index)) {
+ read_close_gme(s);
return AVERROR_UNKNOWN;
-
- load_metadata(s);
+ }
st = avformat_new_stream(s, NULL);
- if (!st)
+ if (!st) {
+ read_close_gme(s);
return AVERROR(ENOMEM);
+ }
avpriv_set_pts_info(st, 64, 1, 1000);
- if (st->duration > 0)
- st->duration = gme->info->length;
+ if (duration > 0)
+ st->duration = duration;
st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
st->codecpar->codec_id = AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE);
st->codecpar->channels = 2;
if (gme_play(gme->music_emu, n_samples, (short *)pkt->data))
return AVERROR_EXTERNAL;
- pkt->size = AUDIO_PKT_SIZE;
-
- return 0;
-}
-static int read_close_gme(AVFormatContext *s)
-{
- GMEContext *gme = s->priv_data;
- gme_free_info(gme->info);
- gme_delete(gme->music_emu);
return 0;
}
return 0;
}
-static int probe_gme(AVProbeData *p)
+static int probe_gme(const AVProbeData *p)
{
// Reads 4 bytes - returns "" if unknown format.
if (gme_identify_header(p->buf)[0]) {