mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-14 18:47:39 +01:00
Minor fixes and cleanup
This commit is contained in:
parent
47be992b4b
commit
609bfb5d61
@ -63,14 +63,13 @@ void decode_ffmpeg(VGMSTREAM *vgmstream,
|
||||
sample * outbuf, int32_t samples_to_do, int channels) {
|
||||
ffmpeg_codec_data *data = (ffmpeg_codec_data *) vgmstream->codec_data;
|
||||
|
||||
int bytesPerSample;
|
||||
int bytesPerFrame;
|
||||
int frameSize;
|
||||
int dataSize;
|
||||
|
||||
int bytesToRead;
|
||||
int bytesRead;
|
||||
|
||||
int errcode;
|
||||
|
||||
uint8_t *targetBuf;
|
||||
|
||||
AVFormatContext *formatCtx;
|
||||
@ -78,25 +77,24 @@ void decode_ffmpeg(VGMSTREAM *vgmstream,
|
||||
AVPacket *lastReadPacket;
|
||||
AVFrame *lastDecodedFrame;
|
||||
|
||||
int streamIndex;
|
||||
|
||||
int bytesConsumedFromDecodedFrame;
|
||||
|
||||
int readNextPacket;
|
||||
int endOfStream;
|
||||
int endOfAudio;
|
||||
|
||||
int toConsume;
|
||||
|
||||
int framesReadNow;
|
||||
|
||||
|
||||
/* ignore decode attempts at EOF */
|
||||
if ((data->totalFrames && data->framesRead >= data->totalFrames) || data->endOfStream || data->endOfAudio) {
|
||||
memset(outbuf, 0, samples_to_do * channels * sizeof(sample));
|
||||
return;
|
||||
}
|
||||
|
||||
frameSize = data->channels * (data->bitsPerSample / 8);
|
||||
dataSize = 0;
|
||||
bytesPerSample = data->bitsPerSample / 8;
|
||||
bytesPerFrame = channels * bytesPerSample;
|
||||
frameSize = data->channels * bytesPerSample;
|
||||
|
||||
bytesToRead = samples_to_do * frameSize;
|
||||
bytesRead = 0;
|
||||
@ -109,8 +107,6 @@ void decode_ffmpeg(VGMSTREAM *vgmstream,
|
||||
lastReadPacket = data->lastReadPacket;
|
||||
lastDecodedFrame = data->lastDecodedFrame;
|
||||
|
||||
streamIndex = data->streamIndex;
|
||||
|
||||
bytesConsumedFromDecodedFrame = data->bytesConsumedFromDecodedFrame;
|
||||
|
||||
readNextPacket = data->readNextPacket;
|
||||
@ -120,15 +116,18 @@ void decode_ffmpeg(VGMSTREAM *vgmstream,
|
||||
/* keep reading and decoding packets until the requested number of samples (in bytes) */
|
||||
while (bytesRead < bytesToRead) {
|
||||
int planeSize;
|
||||
int planar = av_sample_fmt_is_planar(codecCtx->sample_fmt);
|
||||
dataSize = av_samples_get_buffer_size(&planeSize, codecCtx->channels,
|
||||
lastDecodedFrame->nb_samples,
|
||||
codecCtx->sample_fmt, 1);
|
||||
|
||||
int planar;
|
||||
int dataSize;
|
||||
int toConsume;
|
||||
int errcode;
|
||||
|
||||
|
||||
/* size of previous frame */
|
||||
dataSize = av_samples_get_buffer_size(&planeSize, codecCtx->channels, lastDecodedFrame->nb_samples, codecCtx->sample_fmt, 1);
|
||||
if (dataSize < 0)
|
||||
dataSize = 0;
|
||||
|
||||
/* read packet */
|
||||
/* read new frame + packets when requested */
|
||||
while (readNextPacket && !endOfAudio) {
|
||||
if (!endOfStream) {
|
||||
av_packet_unref(lastReadPacket);
|
||||
@ -139,10 +138,11 @@ void decode_ffmpeg(VGMSTREAM *vgmstream,
|
||||
if (formatCtx->pb && formatCtx->pb->error)
|
||||
break;
|
||||
}
|
||||
if (lastReadPacket->stream_index != streamIndex)
|
||||
continue; /* ignore non audio streams */
|
||||
if (lastReadPacket->stream_index != data->streamIndex)
|
||||
continue; /* ignore non-selected streams */
|
||||
}
|
||||
|
||||
/* send compressed packet to decoder (NULL at EOF to "drain") */
|
||||
if ((errcode = avcodec_send_packet(codecCtx, endOfStream ? NULL : lastReadPacket)) < 0) {
|
||||
if (errcode != AVERROR(EAGAIN)) {
|
||||
goto end;
|
||||
@ -152,13 +152,14 @@ void decode_ffmpeg(VGMSTREAM *vgmstream,
|
||||
readNextPacket = 0;
|
||||
}
|
||||
|
||||
/* decode packet */
|
||||
/* decode packets into frame (checking if we have bytes to consume from previous frame) */
|
||||
if (dataSize <= bytesConsumedFromDecodedFrame) {
|
||||
if (endOfStream && endOfAudio)
|
||||
break;
|
||||
|
||||
bytesConsumedFromDecodedFrame = 0;
|
||||
|
||||
/* receive uncompressed data from decoder */
|
||||
if ((errcode = avcodec_receive_frame(codecCtx, lastDecodedFrame)) < 0) {
|
||||
if (errcode == AVERROR_EOF) {
|
||||
endOfAudio = 1;
|
||||
@ -173,18 +174,17 @@ void decode_ffmpeg(VGMSTREAM *vgmstream,
|
||||
}
|
||||
}
|
||||
|
||||
/* size of current frame */
|
||||
dataSize = av_samples_get_buffer_size(&planeSize, codecCtx->channels, lastDecodedFrame->nb_samples, codecCtx->sample_fmt, 1);
|
||||
|
||||
if (dataSize < 0)
|
||||
dataSize = 0;
|
||||
}
|
||||
|
||||
toConsume = FFMIN((dataSize - bytesConsumedFromDecodedFrame), (bytesToRead - bytesRead));
|
||||
|
||||
/* discard packet if needed (fully or partially) */
|
||||
/* discard decoded frame if needed (fully or partially) */
|
||||
if (data->samplesToDiscard) {
|
||||
int samplesToConsume;
|
||||
int bytesPerFrame = ((data->bitsPerSample / 8) * channels);
|
||||
|
||||
/* discard all if there are more samples to do than the packet's samples */
|
||||
if (data->samplesToDiscard >= dataSize / bytesPerFrame) {
|
||||
@ -206,13 +206,13 @@ void decode_ffmpeg(VGMSTREAM *vgmstream,
|
||||
}
|
||||
}
|
||||
|
||||
/* copy packet to buffer (mux channels if needed) */
|
||||
/* copy decoded frame to buffer (mux channels if needed) */
|
||||
planar = av_sample_fmt_is_planar(codecCtx->sample_fmt);
|
||||
if (!planar || channels == 1) {
|
||||
memmove(targetBuf + bytesRead, (lastDecodedFrame->data[0] + bytesConsumedFromDecodedFrame), toConsume);
|
||||
}
|
||||
else {
|
||||
uint8_t * out = (uint8_t *) targetBuf + bytesRead;
|
||||
int bytesPerSample = data->bitsPerSample / 8;
|
||||
int bytesConsumedPerPlane = bytesConsumedFromDecodedFrame / channels;
|
||||
int toConsumePerPlane = toConsume / channels;
|
||||
int s, ch;
|
||||
@ -252,7 +252,7 @@ void reset_ffmpeg(VGMSTREAM *vgmstream) {
|
||||
ffmpeg_codec_data *data = (ffmpeg_codec_data *) vgmstream->codec_data;
|
||||
|
||||
if (data->formatCtx) {
|
||||
avformat_seek_file(data->formatCtx, -1, 0, 0, 0, AVSEEK_FLAG_ANY);
|
||||
avformat_seek_file(data->formatCtx, data->streamIndex, 0, 0, 0, AVSEEK_FLAG_ANY);
|
||||
}
|
||||
if (data->codecCtx) {
|
||||
avcodec_flush_buffers(data->codecCtx);
|
||||
@ -294,7 +294,7 @@ void seek_ffmpeg(VGMSTREAM *vgmstream, int32_t num_sample) {
|
||||
ts = 0;
|
||||
}
|
||||
|
||||
avformat_seek_file(data->formatCtx, -1, ts - 1000, ts, ts, AVSEEK_FLAG_ANY);
|
||||
avformat_seek_file(data->formatCtx, data->streamIndex, ts - 1000, ts, ts, AVSEEK_FLAG_ANY);
|
||||
avcodec_flush_buffers(data->codecCtx);
|
||||
#endif /* ifndef VGM_USE_FFMPEG_ACCURATE_LOOPING */
|
||||
|
||||
@ -306,7 +306,7 @@ void seek_ffmpeg(VGMSTREAM *vgmstream, int32_t num_sample) {
|
||||
data->framesRead = 0;
|
||||
ts = 0;
|
||||
|
||||
avformat_seek_file(data->formatCtx, -1, ts, ts, ts, AVSEEK_FLAG_ANY);
|
||||
avformat_seek_file(data->formatCtx, data->streamIndex, ts, ts, ts, AVSEEK_FLAG_ANY);
|
||||
avcodec_flush_buffers(data->codecCtx);
|
||||
#endif /* ifdef VGM_USE_FFMPEG_ACCURATE_LOOPING */
|
||||
|
||||
|
@ -4,7 +4,9 @@
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
|
||||
/* internal sizes, can be any value */
|
||||
#define FFMPEG_DEFAULT_BLOCK_SIZE 2048
|
||||
#define FFMPEG_DEFAULT_IO_BUFFER_SIZE 128 * 1024
|
||||
|
||||
static void init_seek(ffmpeg_codec_data * data);
|
||||
|
||||
@ -57,10 +59,19 @@ VGMSTREAM * init_vgmstream_ffmpeg_offset(STREAMFILE *streamFile, uint64_t start,
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->meta_type = meta_FFmpeg;
|
||||
|
||||
/* this may happen for some streams */
|
||||
if (vgmstream->num_samples <= 0)
|
||||
goto fail;
|
||||
|
||||
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
free_ffmpeg(data);
|
||||
if (vgmstream) {
|
||||
vgmstream->codec_data = NULL;
|
||||
close_vgmstream(vgmstream);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -73,10 +84,9 @@ static int ffmpeg_read(void *opaque, uint8_t *buf, int buf_size)
|
||||
{
|
||||
ffmpeg_codec_data *data = (ffmpeg_codec_data *) opaque;
|
||||
uint64_t offset = data->offset;
|
||||
int max_to_copy;
|
||||
int max_to_copy = 0;
|
||||
int ret;
|
||||
if (data->header_insert_block) {
|
||||
max_to_copy = 0;
|
||||
if (offset < data->header_size) {
|
||||
max_to_copy = (int)(data->header_size - offset);
|
||||
if (max_to_copy > buf_size) {
|
||||
@ -125,7 +135,11 @@ static int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence)
|
||||
return data->size + data->header_size;
|
||||
}
|
||||
whence &= ~(AVSEEK_SIZE | AVSEEK_FORCE);
|
||||
/* false offsets, on reads data->start will be added */
|
||||
switch (whence) {
|
||||
case SEEK_SET:
|
||||
break;
|
||||
|
||||
case SEEK_CUR:
|
||||
offset += data->offset;
|
||||
break;
|
||||
@ -162,6 +176,7 @@ ffmpeg_codec_data * init_ffmpeg_faux_riff(STREAMFILE *streamFile, int64_t fmt_of
|
||||
int errcode, i;
|
||||
|
||||
int streamIndex;
|
||||
AVStream *stream;
|
||||
AVCodecParameters *codecPar;
|
||||
|
||||
AVRational tb;
|
||||
@ -219,10 +234,10 @@ ffmpeg_codec_data * init_ffmpeg_faux_riff(STREAMFILE *streamFile, int64_t fmt_of
|
||||
|
||||
|
||||
/* setup IO, attempt to autodetect format and gather some info */
|
||||
data->buffer = av_malloc(128 * 1024);
|
||||
data->buffer = av_malloc(FFMPEG_DEFAULT_IO_BUFFER_SIZE);
|
||||
if (!data->buffer) goto fail;
|
||||
|
||||
data->ioCtx = avio_alloc_context(data->buffer, 128 * 1024, 0, data, ffmpeg_read, ffmpeg_write, ffmpeg_seek);
|
||||
data->ioCtx = avio_alloc_context(data->buffer, FFMPEG_DEFAULT_IO_BUFFER_SIZE, 0, data, ffmpeg_read, ffmpeg_write, ffmpeg_seek);
|
||||
if (!data->ioCtx) goto fail;
|
||||
|
||||
data->formatCtx = avformat_alloc_context();
|
||||
@ -239,16 +254,19 @@ ffmpeg_codec_data * init_ffmpeg_faux_riff(STREAMFILE *streamFile, int64_t fmt_of
|
||||
streamIndex = -1;
|
||||
|
||||
for (i = 0; i < data->formatCtx->nb_streams; ++i) {
|
||||
codecPar = data->formatCtx->streams[i]->codecpar;
|
||||
if (codecPar->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
streamIndex = i;
|
||||
break;
|
||||
stream = data->formatCtx->streams[i];
|
||||
codecPar = stream->codecpar;
|
||||
if (streamIndex < 0 && codecPar->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
streamIndex = i; /* select first audio stream found */
|
||||
} else {
|
||||
stream->discard = AVDISCARD_ALL; /* disable demuxing unneded streams */
|
||||
}
|
||||
}
|
||||
|
||||
if (streamIndex < 0) goto fail;
|
||||
|
||||
data->streamIndex = streamIndex;
|
||||
stream = data->formatCtx->streams[streamIndex];
|
||||
|
||||
|
||||
/* prepare codec and frame/packet buffers */
|
||||
@ -257,7 +275,7 @@ ffmpeg_codec_data * init_ffmpeg_faux_riff(STREAMFILE *streamFile, int64_t fmt_of
|
||||
|
||||
if ((errcode = avcodec_parameters_to_context(data->codecCtx, codecPar)) < 0) goto fail;
|
||||
|
||||
av_codec_set_pkt_timebase(data->codecCtx, data->formatCtx->streams[streamIndex]->time_base);
|
||||
av_codec_set_pkt_timebase(data->codecCtx, stream->time_base);
|
||||
|
||||
data->codec = avcodec_find_decoder(data->codecCtx->codec_id);
|
||||
if (!data->codec) goto fail;
|
||||
@ -320,10 +338,9 @@ 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(data->formatCtx->streams[streamIndex]->duration, data->formatCtx->streams[streamIndex]->time_base, tb);
|
||||
data->totalFrames = av_rescale_q(stream->duration, stream->time_base, tb);
|
||||
if (data->totalFrames < 0)
|
||||
data->totalFrames = 0;
|
||||
|
||||
data->totalFrames = 0; /* caller must consider this */
|
||||
|
||||
/* setup decode buffer */
|
||||
data->samplesPerBlock = FFMPEG_DEFAULT_BLOCK_SIZE;
|
||||
@ -386,7 +403,7 @@ static void init_seek(ffmpeg_codec_data * data) {
|
||||
|
||||
/* add index 0 */
|
||||
stream = data->formatCtx->streams[data->streamIndex];
|
||||
av_add_index_entry(stream, pkt->pos, ts, pkt->size, 0, AVINDEX_KEYFRAME); /* todo distance*/
|
||||
av_add_index_entry(stream, pkt->pos, ts, pkt->size, 0, AVINDEX_KEYFRAME);
|
||||
|
||||
/* move back to beginning, since we just consumed packets */
|
||||
avformat_seek_file(data->formatCtx, data->streamIndex, ts, ts, ts, AVSEEK_FLAG_ANY);
|
||||
|
Loading…
Reference in New Issue
Block a user