mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-17 23:36:41 +01:00
Added .pos support for .vgmstream (FFmpeg) files not directly supported
The format is LE 4+4 [loop_start loop_end], or LE 4+4+4 [loop_start loop_end num_samples] when FFmpeg can't determine correctly num_samples
This commit is contained in:
parent
e6334e72af
commit
76dc236b41
@ -43,23 +43,52 @@ VGMSTREAM * init_vgmstream_ffmpeg(STREAMFILE *streamFile) {
|
||||
|
||||
VGMSTREAM * init_vgmstream_ffmpeg_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size) {
|
||||
VGMSTREAM *vgmstream = NULL;
|
||||
int loop_flag = 0;
|
||||
int32_t loop_start = 0, loop_end = 0, num_samples = 0;
|
||||
|
||||
/* init ffmpeg */
|
||||
ffmpeg_codec_data *data = init_ffmpeg_offset(streamFile, start, size);
|
||||
if (!data) return NULL;
|
||||
|
||||
vgmstream = allocate_vgmstream(data->channels, 0);
|
||||
|
||||
|
||||
/* try to get .pos data */
|
||||
{
|
||||
uint8_t posbuf[4+4+4];
|
||||
|
||||
if ( read_pos_file(posbuf, 4+4+4, streamFile) ) {
|
||||
loop_start = get_32bitLE(posbuf+0);
|
||||
loop_end = get_32bitLE(posbuf+4);
|
||||
loop_flag = 1; /* incorrect looping will be validated outside */
|
||||
/* FFmpeg can't always determine totalSamples correctly so optionally load it (can be 0/NULL)
|
||||
* won't crash and will output silence if no loop points and bigger than actual stream's samples */
|
||||
num_samples = get_32bitLE(posbuf+8);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* build VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(data->channels, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->loop_flag = 0;
|
||||
vgmstream->loop_flag = loop_flag;
|
||||
vgmstream->codec_data = data;
|
||||
vgmstream->channels = data->channels;
|
||||
vgmstream->sample_rate = data->sampleRate;
|
||||
vgmstream->num_samples = data->totalSamples;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->meta_type = meta_FFmpeg;
|
||||
|
||||
/* this may happen for some streams */
|
||||
if (!num_samples) {
|
||||
num_samples = data->totalSamples;
|
||||
}
|
||||
vgmstream->num_samples = num_samples;
|
||||
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = loop_start;
|
||||
vgmstream->loop_end_sample = loop_end;
|
||||
}
|
||||
|
||||
/* this may happen for some streams if FFmpeg can't determine it */
|
||||
if (vgmstream->num_samples <= 0)
|
||||
goto fail;
|
||||
|
||||
|
@ -350,3 +350,44 @@ fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* open file containing looping data and copy to buffer
|
||||
*
|
||||
* returns true if found and copied
|
||||
*/
|
||||
int read_pos_file(uint8_t * buf, size_t bufsize, STREAMFILE *streamFile) {
|
||||
char posname[PATH_LIMIT];
|
||||
char filename[PATH_LIMIT];
|
||||
/*size_t bytes_read;*/
|
||||
STREAMFILE * streamFilePos= NULL;
|
||||
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
|
||||
if (strlen(filename)+4 > sizeof(posname)) goto fail;
|
||||
|
||||
/* try to open a posfile using variations: "(name.ext).pos" */
|
||||
{
|
||||
strcpy(posname, filename);
|
||||
strcat(posname, ".pos");
|
||||
streamFilePos = streamFile->open(streamFile,posname,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (streamFilePos) goto found;
|
||||
|
||||
goto fail;
|
||||
}
|
||||
|
||||
found:
|
||||
//if (get_streamfile_size(streamFilePos) != bufsize) goto fail;
|
||||
|
||||
/* allow pos files to be of different sizes in case of new features, just fill all we can */
|
||||
memset(buf, 0, bufsize);
|
||||
read_streamfile(buf, 0, bufsize, streamFilePos);
|
||||
|
||||
close_streamfile(streamFilePos);
|
||||
|
||||
return 1;
|
||||
|
||||
fail:
|
||||
if (streamFilePos) close_streamfile(streamFilePos);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -151,5 +151,6 @@ size_t get_streamfile_dos_line(int dst_length, char * dst, off_t offset,
|
||||
|
||||
int read_key_file(uint8_t * buf, size_t bufsize, STREAMFILE *streamFile);
|
||||
|
||||
int read_pos_file(uint8_t * buf, size_t bufsize, STREAMFILE *streamFile);
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user