mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-29 19:37:30 +01:00
FFmpeg: expose block/frame size, rename totalFrames for clarity
This commit is contained in:
parent
85d34a7901
commit
cdfd47eb7b
@ -278,8 +278,8 @@ void seek_ffmpeg(VGMSTREAM *vgmstream, int32_t num_sample) {
|
||||
}
|
||||
|
||||
/* todo fix this properly */
|
||||
if (data->totalFrames) {
|
||||
ts = (int)ts * (data->formatCtx->duration) / data->totalFrames;
|
||||
if (data->totalSamples) {
|
||||
ts = (int)ts * (data->formatCtx->duration) / data->totalSamples;
|
||||
} else {
|
||||
data->samplesToDiscard = num_sample;
|
||||
ts = 0;
|
||||
|
@ -5,7 +5,7 @@
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
|
||||
/* internal sizes, can be any value */
|
||||
#define FFMPEG_DEFAULT_BLOCK_SIZE 2048
|
||||
#define FFMPEG_DEFAULT_BUFFER_SIZE 2048
|
||||
#define FFMPEG_DEFAULT_IO_BUFFER_SIZE 128 * 1024
|
||||
|
||||
static int init_seek(ffmpeg_codec_data * data);
|
||||
@ -54,7 +54,7 @@ VGMSTREAM * init_vgmstream_ffmpeg_offset(STREAMFILE *streamFile, uint64_t start,
|
||||
vgmstream->codec_data = data;
|
||||
vgmstream->channels = data->channels;
|
||||
vgmstream->sample_rate = data->sampleRate;
|
||||
vgmstream->num_samples = data->totalFrames;
|
||||
vgmstream->num_samples = data->totalSamples;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->meta_type = meta_FFmpeg;
|
||||
@ -337,13 +337,18 @@ ffmpeg_codec_data * init_ffmpeg_faux_riff(STREAMFILE *streamFile, int64_t fmt_of
|
||||
|
||||
/* try to guess frames/samples (duration isn't always set) */
|
||||
tb.num = 1; tb.den = data->codecCtx->sample_rate;
|
||||
data->totalFrames = av_rescale_q(stream->duration, stream->time_base, tb);
|
||||
if (data->totalFrames < 0)
|
||||
data->totalFrames = 0; /* caller must consider this */
|
||||
data->totalSamples = av_rescale_q(stream->duration, stream->time_base, tb);
|
||||
if (data->totalSamples < 0)
|
||||
data->totalSamples = 0; /* caller must consider this */
|
||||
|
||||
data->blockAlign = data->codecCtx->block_align;
|
||||
data->frameSize = data->codecCtx->frame_size;
|
||||
if(data->frameSize == 0) /* some formats don't set frame_size but can get on request, and vice versa */
|
||||
data->frameSize = av_get_audio_frame_duration(data->codecCtx,0);
|
||||
|
||||
/* setup decode buffer */
|
||||
data->samplesPerBlock = FFMPEG_DEFAULT_BLOCK_SIZE;
|
||||
data->sampleBuffer = av_malloc( data->samplesPerBlock * (data->bitsPerSample / 8) * data->channels );
|
||||
data->sampleBufferBlock = FFMPEG_DEFAULT_BUFFER_SIZE;
|
||||
data->sampleBuffer = av_malloc( data->sampleBufferBlock * (data->bitsPerSample / 8) * data->channels );
|
||||
if (!data->sampleBuffer)
|
||||
goto fail;
|
||||
|
||||
@ -409,6 +414,7 @@ static int init_seek(ffmpeg_codec_data * data) {
|
||||
if (!found_first) { /* first found */
|
||||
found_first = 1;
|
||||
pos = pkt->pos;
|
||||
ts = pkt->dts;
|
||||
continue;
|
||||
} else { /* second found */
|
||||
size = pkt->pos - pos; /* coded, pkt->size is decoded size */
|
||||
@ -416,6 +422,11 @@ static int init_seek(ffmpeg_codec_data * data) {
|
||||
}
|
||||
}
|
||||
|
||||
/* apparently some (non-audio?) streams start with a DTS before 0, but some read_seeks expect 0, which would disrupt the index
|
||||
* we may need to keep start_ts around, since avstream/codec/format isn't always set */
|
||||
if (ts != 0)
|
||||
goto fail;
|
||||
|
||||
/* add index 0 */
|
||||
ret = av_add_index_entry(stream, pos, ts, size, distance, AVINDEX_KEYFRAME);
|
||||
if ( ret < 0 )
|
||||
|
@ -210,7 +210,7 @@ VGMSTREAM * init_vgmstream_mp4_aac_ffmpeg(STREAMFILE *streamFile) {
|
||||
vgmstream = allocate_vgmstream(ffmpeg_data->channels,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->num_samples = ffmpeg_data->totalFrames; /* todo compare with FFD num_samples*/
|
||||
vgmstream->num_samples = ffmpeg_data->totalSamples; /* todo FFD num_samples is different from this */
|
||||
vgmstream->sample_rate = ffmpeg_data->sampleRate;
|
||||
vgmstream->channels = ffmpeg_data->channels;
|
||||
if (loop_flag) {
|
||||
|
@ -133,13 +133,11 @@ VGMSTREAM * init_vgmstream_ps3_msf(STREAMFILE *streamFile) {
|
||||
vgmstream->meta_type = meta_FFmpeg;
|
||||
vgmstream->codec_data = ffmpeg_data;
|
||||
|
||||
vgmstream->num_samples = ffmpeg_data->totalFrames;
|
||||
if (loop_flag) {
|
||||
int atrac3_frame = 1024;
|
||||
int block_align = (codec_id == 0x4 ? 96 : codec_id == 0x5 ? 152 : 192) * channel_count;
|
||||
/* int block_align = ffmpeg_data->codecCtx->block_align; *//* is this always set? */
|
||||
vgmstream->loop_start_sample = (loop_start / block_align) * atrac3_frame;
|
||||
vgmstream->loop_end_sample = (loop_end / block_align) * atrac3_frame;
|
||||
vgmstream->num_samples = ffmpeg_data->totalSamples;
|
||||
|
||||
if (loop_flag && ffmpeg_data->blockAlign > 0) {
|
||||
vgmstream->loop_start_sample = (loop_start / ffmpeg_data->blockAlign) * ffmpeg_data->frameSize;
|
||||
vgmstream->loop_end_sample = (loop_end / ffmpeg_data->blockAlign) * ffmpeg_data->frameSize;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -155,12 +153,14 @@ VGMSTREAM * init_vgmstream_ps3_msf(STREAMFILE *streamFile) {
|
||||
vgmstream->meta_type = meta_FFmpeg;
|
||||
vgmstream->codec_data = ffmpeg_data;
|
||||
|
||||
/* todo check CBR better (frame_size=0?) */
|
||||
/* TODO check CBR better (bitrate % X != 0?) */
|
||||
if (ffmpeg_data->bitrate == 0)
|
||||
goto fail;
|
||||
|
||||
/* vgmstream->num_samples = ffmpeg_data->totalFrames; */ /* duration is not set/innacurate for MP3 in FFMpeg */
|
||||
/* vgmstream->num_samples = ffmpeg_data->totalSamples; */ /* duration may not be set/inaccurate */
|
||||
vgmstream->num_samples = (int64_t)data_size * ffmpeg_data->sampleRate * 8 / ffmpeg_data->bitrate;
|
||||
if (loop_flag) {
|
||||
int frame_size = ffmpeg_data->codecCtx->frame_size;
|
||||
int frame_size = ffmpeg_data->frameSize;
|
||||
vgmstream->loop_start_sample = (int64_t)loop_start * ffmpeg_data->sampleRate * 8 / ffmpeg_data->bitrate;
|
||||
vgmstream->loop_start_sample -= vgmstream->loop_start_sample==frame_size ? frame_size
|
||||
: vgmstream->loop_start_sample % frame_size;
|
||||
|
@ -402,7 +402,7 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
|
||||
ffmpeg_data = init_ffmpeg_offset(streamFile, 0, streamFile->get_size(streamFile) );
|
||||
if ( !ffmpeg_data ) goto fail;
|
||||
|
||||
sample_count = ffmpeg_data->totalFrames; /* fact_sample_count */
|
||||
sample_count = ffmpeg_data->totalSamples; /* fact_sample_count */
|
||||
/* the encoder introduces some garbage (usually silent) samples to skip before the stream
|
||||
* loop values include the skip samples but fact_sample_count doesn't; add them back to fix some edge loops */
|
||||
if (fact_sample_skip > 0)
|
||||
|
@ -295,7 +295,7 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
vgmstream->num_samples = ffmpeg_data->totalFrames;
|
||||
vgmstream->num_samples = ffmpeg_data->totalSamples;
|
||||
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = loop_start;
|
||||
|
@ -1072,7 +1072,7 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
|
||||
ffmpeg_codec_data *data = (ffmpeg_codec_data *) vgmstream->codec_data;
|
||||
if (data) {
|
||||
/* must know the full block size for edge loops */
|
||||
return data->samplesPerBlock;
|
||||
return data->sampleBufferBlock;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -868,13 +868,16 @@ typedef struct {
|
||||
int bitsPerSample;
|
||||
int floatingPoint;
|
||||
int sampleRate;
|
||||
int64_t totalFrames; // sample count, or 0 if unknown
|
||||
int bitrate;
|
||||
// extra info: 0 if unknown or not fixed
|
||||
int64_t totalSamples; // estimated count (may not be accurate for some demuxers)
|
||||
int64_t blockAlign; // coded block of bytes, counting channels (the block can be joint stereo)
|
||||
int64_t frameSize; // decoded samples per block
|
||||
|
||||
// Intermediate buffer
|
||||
// Intermediate byte buffer
|
||||
uint8_t *sampleBuffer;
|
||||
// max samples a block can held (can be less or more than samples per decoded frame)
|
||||
size_t samplesPerBlock;
|
||||
// max samples we can held (can be less or more than frameSize)
|
||||
size_t sampleBufferBlock;
|
||||
|
||||
// FFmpeg context used for metadata
|
||||
AVCodec *codec;
|
||||
|
Loading…
x
Reference in New Issue
Block a user