@ -31,7 +31,6 @@
typedef struct GMEContext {
const AVClass * class ;
Music_Emu * music_emu ;
gme_info_t * info ; ///< selected track
/* options */
int track_index ;
@ -55,12 +54,16 @@ static void add_meta(AVFormatContext *s, const char *name, const char *value)
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 ) ;
@ -71,20 +74,30 @@ static int load_metadata(AVFormatContext *s)
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 " ) ;
@ -103,6 +116,7 @@ static int read_header_gme(AVFormatContext *s)
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 ;
}
@ -112,20 +126,24 @@ static int read_header_gme(AVFormatContext *s)
}
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 ;
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 ;
@ -153,14 +171,6 @@ static int read_packet_gme(AVFormatContext *s, AVPacket *pkt)
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 ;
}
static int read_seek_gme ( AVFormatContext * s , int stream_idx , int64_t ts , int flags )
{
GMEContext * gme = s - > priv_data ;