From 804fceb5e7d6bc4727c2bc5eb3410cdf42571fa5 Mon Sep 17 00:00:00 2001 From: bnnm Date: Mon, 10 Sep 2018 02:19:34 +0200 Subject: [PATCH] Remove custom FFmpeg, as custom IO streamfile can be used instead --- src/coding/coding.h | 2 - src/coding/ffmpeg_decoder.c | 138 ++++++++++-------------------- src/coding/ffmpeg_decoder_utils.c | 30 ------- src/coding/ffmpeg_decoder_utils.h | 28 ------ src/libvgmstream.vcproj | 8 -- src/libvgmstream.vcxproj | 2 - src/libvgmstream.vcxproj.filters | 6 -- src/meta/bik.c | 17 ++-- src/vgmstream.h | 32 ++----- 9 files changed, 57 insertions(+), 206 deletions(-) delete mode 100644 src/coding/ffmpeg_decoder_utils.c delete mode 100644 src/coding/ffmpeg_decoder_utils.h diff --git a/src/coding/coding.h b/src/coding/coding.h index 5bb43701..d5fadc95 100644 --- a/src/coding/coding.h +++ b/src/coding/coding.h @@ -266,8 +266,6 @@ void free_celt_fsb(celt_codec_data *data); /* ffmpeg_decoder */ ffmpeg_codec_data *init_ffmpeg_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size); ffmpeg_codec_data *init_ffmpeg_header_offset(STREAMFILE *streamFile, uint8_t * header, uint64_t header_size, uint64_t start, uint64_t size); -ffmpeg_codec_data *init_ffmpeg_config(STREAMFILE *streamFile, uint8_t * header, uint64_t header_size, uint64_t start, uint64_t size, ffmpeg_custom_config * config); - ffmpeg_codec_data * init_ffmpeg_switch_opus(STREAMFILE *streamFile, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate); void decode_ffmpeg(VGMSTREAM *stream, sample * outbuf, int32_t samples_to_do, int channels); diff --git a/src/coding/ffmpeg_decoder.c b/src/coding/ffmpeg_decoder.c index 37287c87..2f6b833d 100644 --- a/src/coding/ffmpeg_decoder.c +++ b/src/coding/ffmpeg_decoder.c @@ -1,10 +1,9 @@ #include "coding.h" -#include "ffmpeg_decoder_utils.h" #ifdef VGM_USE_FFMPEG /* internal sizes, can be any value */ -#define FFMPEG_DEFAULT_BUFFER_SIZE 2048 +#define FFMPEG_DEFAULT_SAMPLE_BUFFER_SIZE 2048 #define FFMPEG_DEFAULT_IO_BUFFER_SIZE 128 * 1024 @@ -185,49 +184,38 @@ fail: /* ******************************************** */ /* AVIO callback: read stream, handling custom data */ -static int ffmpeg_read(void *opaque, uint8_t *buf, int buf_size) { +static int ffmpeg_read(void *opaque, uint8_t *buf, int read_size) { ffmpeg_codec_data *data = (ffmpeg_codec_data *) opaque; - int ret = 0; + int bytes = 0; int max_to_copy = 0; - //;VGM_LOG("AVIO read: r_off=%"PRIx64", v_off=%"PRIx64", b_size=%x\n", data->real_offset, data->virtual_offset, buf_size);fflush(stdout); - /* clamp reads */ - if (data->virtual_offset + buf_size > data->virtual_size) - buf_size = data->virtual_size - data->virtual_offset; - if (buf_size == 0) - return ret; + if (data->logical_offset + read_size > data->logical_size) + read_size = data->logical_size - data->logical_offset; + if (read_size == 0) + return bytes; /* handle reads on inserted header */ - if (data->header_size) { - if (data->virtual_offset < data->header_size) { - max_to_copy = (int)(data->header_size - data->virtual_offset); - if (max_to_copy > buf_size) { - max_to_copy = buf_size; - } + if (data->header_size && data->logical_offset < data->header_size) { + max_to_copy = (int)(data->header_size - data->logical_offset); + if (max_to_copy > read_size) + max_to_copy = read_size; - //;VGM_LOG("AVIO header: v_off=%lx, h_size=%lx, mtc=%x, b_size=%x\n", (off_t)data->virtual_offset, (off_t)data->header_size, max_to_copy, buf_size);fflush(stdout); - memcpy(buf, data->header_insert_block + data->virtual_offset, max_to_copy); - buf += max_to_copy; - buf_size -= max_to_copy; - data->virtual_offset += max_to_copy; /* adjust for reads below */ + memcpy(buf, data->header_insert_block + data->logical_offset, max_to_copy); + buf += max_to_copy; + read_size -= max_to_copy; + data->logical_offset += max_to_copy; - if (buf_size == 0) { - return max_to_copy; /* offset still in header */ - } + if (read_size == 0) { + return max_to_copy; /* offset still in header */ } } /* main read */ - switch(data->config.type) { - default: ret = ffmpeg_custom_read_standard(data, buf, buf_size); break; - } - data->virtual_offset += ret; - //data->real_offset = ; /* must be updated in function */ - - //;VGM_LOG("AVIO read done: ret=%x, r_off=%"PRIx64", v_off=%"PRIx64"\n", ret + max_to_copy, data->real_offset, data->virtual_offset);fflush(stdout); - //;VGM_LOGB((buf - max_to_copy),ret + max_to_copy,0); - return ret + max_to_copy; + bytes = read_streamfile(buf, data->offset, read_size, data->streamfile); + data->logical_offset += bytes; + data->offset += bytes; + return bytes + max_to_copy; } /* AVIO callback: write stream not needed */ @@ -242,79 +230,50 @@ static int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) { /* get cache'd size */ if (whence & AVSEEK_SIZE) { - //;VGM_LOG("AVIO size: v_size=%"PRIx64", h_size=%"PRIx64", r_size=%"PRIx64", r_start=%"PRIx64"\n", data->virtual_size, data->header_size, data->real_size, data->real_start);fflush(stdout); - return data->virtual_size; + return data->logical_size; } - //;VGM_LOG("AVIO seek: off=%"PRIx64" r_off=%"PRIx64", v_off=%"PRIx64"\n", offset, data->real_offset, data->virtual_offset);fflush(stdout); - whence &= ~(AVSEEK_SIZE | AVSEEK_FORCE); - /* find the final offset FFmpeg sees (within fake header + virtual size) */ switch (whence) { case SEEK_SET: /* absolute */ break; case SEEK_CUR: /* relative to current */ - offset += data->virtual_offset; + offset += data->logical_offset; break; case SEEK_END: /* relative to file end (should be negative) */ - offset += data->virtual_size; + offset += data->logical_size; break; } /* clamp offset; fseek does this too */ - if (offset > data->virtual_size) - offset = data->virtual_size; + if (offset > data->logical_size) + offset = data->logical_size; else if (offset < 0) offset = 0; - /* no change */ - if (data->virtual_offset == offset) { - return ret; - } - /* seeks inside fake header */ if (offset < data->header_size) { - data->virtual_offset = offset; - data->real_offset = data->real_start; + data->logical_offset = offset; + data->offset = data->start; return ret; } /* main seek */ - switch(data->config.type) { - default: offset = ffmpeg_custom_seek_standard(data, offset); break; - } - data->virtual_offset = offset; - //data->real_offset = ; /* must be updated in function */ - - //;VGM_LOG("AVIO seek done: r_off=%"PRIx64", v_off=%"PRIx64"\n", data->real_offset, data->virtual_offset);fflush(stdout); + data->logical_offset = offset; + data->offset = data->start + (offset - data->header_size); return ret; } -/* called on init, not a callback */ //todo rename to ffmpeg_init -static int64_t ffmpeg_size(ffmpeg_codec_data * data) { - int64_t bytes; - switch(data->config.type) { - default: bytes = ffmpeg_custom_size_standard(data); break; - } - - return bytes; -} - - /* ******************************************** */ /* MAIN INIT/DECODER */ /* ******************************************** */ ffmpeg_codec_data * init_ffmpeg_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size) { - return init_ffmpeg_config(streamFile, NULL,0, start,size, NULL); + return init_ffmpeg_header_offset(streamFile, NULL,0, start,size); } -ffmpeg_codec_data * init_ffmpeg_header_offset(STREAMFILE *streamFile, uint8_t * header, uint64_t header_size, uint64_t start, uint64_t size) { - return init_ffmpeg_config(streamFile, header,header_size, start,size, NULL); -} - /** * Manually init FFmpeg, from a fake header / offset. @@ -323,17 +282,17 @@ ffmpeg_codec_data * init_ffmpeg_header_offset(STREAMFILE *streamFile, uint8_t * * This header will be seamlessly inserted before 'start' offset, and total filesize will be 'header_size' + 'size'. * The header buffer will be copied and memory-managed internally. * NULL header can used given if the stream has internal data recognized by FFmpeg at offset. - * Stream index can be passed to FFmpeg, if the format has multiple streams (1=first). + * Stream index can be passed to FFmpeg in the streamFile, if the format has multiple streams (1=first). */ -ffmpeg_codec_data * init_ffmpeg_config(STREAMFILE *streamFile, uint8_t * header, uint64_t header_size, uint64_t start, uint64_t size, ffmpeg_custom_config * config) { +ffmpeg_codec_data * init_ffmpeg_header_offset(STREAMFILE *streamFile, uint8_t * header, uint64_t header_size, uint64_t start, uint64_t size) { char filename[PATH_LIMIT]; ffmpeg_codec_data * data; int errcode, i; - + int targetSubsong = streamFile->stream_index; int streamIndex, streamCount; + AVStream *stream; AVCodecParameters *codecPar = NULL; - AVRational tb; @@ -344,14 +303,9 @@ ffmpeg_codec_data * init_ffmpeg_config(STREAMFILE *streamFile, uint8_t * header, if (!data) return NULL; streamFile->get_name( streamFile, filename, sizeof(filename) ); - data->streamfile = streamFile->open(streamFile, filename, STREAMFILE_DEFAULT_BUFFER_SIZE); if (!data->streamfile) goto fail; - if (config) { - memcpy(&data->config, config, sizeof(ffmpeg_custom_config)); - } - /* ignore bad combos */ if ((header && !header_size) || (!header && header_size)) goto fail; @@ -363,17 +317,15 @@ ffmpeg_codec_data * init_ffmpeg_config(STREAMFILE *streamFile, uint8_t * header, if (!data->header_insert_block) goto fail; } - data->real_start = start; - data->real_offset = data->real_start; - data->real_size = size; - if (data->real_start + data->real_size > get_streamfile_size(streamFile)) { + data->start = start; + data->offset = start; + data->size = size; + if (data->size == 0 || data->start + data->size > get_streamfile_size(streamFile)) { VGM_LOG("FFmpeg: wrong start+size found\n"); - data->real_size = get_streamfile_size(streamFile) - data->real_start; + data->size = get_streamfile_size(streamFile) - data->start; } - data->virtual_offset = 0; - data->virtual_size = ffmpeg_size(data); - data->virtual_base = 0; - if (data->virtual_size == 0) goto fail; + data->logical_offset = 0; + data->logical_size = data->header_size + data->size; /* setup IO, attempt to autodetect format and gather some info */ data->buffer = av_malloc(FFMPEG_DEFAULT_IO_BUFFER_SIZE); @@ -403,7 +355,7 @@ ffmpeg_codec_data * init_ffmpeg_config(STREAMFILE *streamFile, uint8_t * header, streamCount++; /* select Nth audio stream if specified, or first one */ - if (streamIndex < 0 || (data->config.stream_index > 0 && streamCount == data->config.stream_index)) { + if (streamIndex < 0 || (targetSubsong > 0 && streamCount == targetSubsong)) { codecPar = stream->codecpar; streamIndex = i; } @@ -412,7 +364,7 @@ ffmpeg_codec_data * init_ffmpeg_config(STREAMFILE *streamFile, uint8_t * header, if (i != streamIndex) stream->discard = AVDISCARD_ALL; /* disable demuxing for other streams */ } - if (streamCount < data->config.stream_index) goto fail; + if (streamCount < targetSubsong) goto fail; if (streamIndex < 0 || !codecPar) goto fail; data->streamIndex = streamIndex; @@ -499,7 +451,7 @@ ffmpeg_codec_data * init_ffmpeg_config(STREAMFILE *streamFile, uint8_t * header, data->frameSize = av_get_audio_frame_duration(data->codecCtx,0); /* setup decode buffer */ - data->sampleBufferBlock = FFMPEG_DEFAULT_BUFFER_SIZE; + data->sampleBufferBlock = FFMPEG_DEFAULT_SAMPLE_BUFFER_SIZE; data->sampleBuffer = av_malloc( data->sampleBufferBlock * (data->bitsPerSample / 8) * data->channels ); if (!data->sampleBuffer) goto fail; diff --git a/src/coding/ffmpeg_decoder_utils.c b/src/coding/ffmpeg_decoder_utils.c deleted file mode 100644 index 2f718ddf..00000000 --- a/src/coding/ffmpeg_decoder_utils.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "coding.h" -#include "ffmpeg_decoder_utils.h" - -#ifdef VGM_USE_FFMPEG - -/** - * Standard read mode: virtual values are 1:1 but inside a portion of the streamfile (between real_start and real_size). - */ - - -int ffmpeg_custom_read_standard(ffmpeg_codec_data *data, uint8_t *buf, int buf_size) { - size_t bytes = read_streamfile(buf, data->real_offset, buf_size, data->streamfile); - data->real_offset += bytes; - - return bytes; -} - -int64_t ffmpeg_custom_seek_standard(ffmpeg_codec_data *data, int64_t virtual_offset) { - int64_t seek_virtual_offset = virtual_offset - data->header_size; - - data->real_offset = data->real_start + seek_virtual_offset; - return virtual_offset; -} - -int64_t ffmpeg_custom_size_standard(ffmpeg_codec_data *data) { - return data->real_size + data->header_size; -} - - -#endif diff --git a/src/coding/ffmpeg_decoder_utils.h b/src/coding/ffmpeg_decoder_utils.h deleted file mode 100644 index a41a48d5..00000000 --- a/src/coding/ffmpeg_decoder_utils.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _FFMPEG_DECODER_UTILS_ -#define _FFMPEG_DECODER_UTILS_ - -#ifdef VGM_USE_FFMPEG -/* used by ffmpeg_decoder.c, but scattered in other .c files */ - -/** - * Custom read/seek for data transformation. Must handle seeks+reads from virtual offsets, ie.- - * reads "real/file" data, not decodable by FFmpeg, and transforms to decodable "virtual/buffer" data, - * block by block (must seek to closest file offset and adjust on reads). - * - * To simplify, functions won't be called in common cases (seek over filesize, no change in offset, etc), - * and fake header seeks/reads are handled externally. Real offset must be updated internally though. - * - * example (a 0x100 block transforms to a 0x150 block): - * - seek 0: file-offset=0, virtual-offset=0 - * - read 0x150: file-read=0x100 transforms to buffer=0x150 - * - new file-offset=0x100, virtual-offset=0x150 - * - seek 0x310: file-offset=0x200, virtual-offset=0x310 (closest virtual block is 0x150+0x150, + 0x10 adjusted on reads) - */ - -int ffmpeg_custom_read_standard(ffmpeg_codec_data *data, uint8_t *buf, int buf_size); -int64_t ffmpeg_custom_seek_standard(ffmpeg_codec_data *data, int64_t virtual_offset); -int64_t ffmpeg_custom_size_standard(ffmpeg_codec_data *data); - -#endif - -#endif/*_FFMPEG_DECODER_UTILS_*/ diff --git a/src/libvgmstream.vcproj b/src/libvgmstream.vcproj index d28f1812..1018203d 100644 --- a/src/libvgmstream.vcproj +++ b/src/libvgmstream.vcproj @@ -1629,10 +1629,6 @@ - - - - - @@ -127,7 +126,6 @@ - diff --git a/src/libvgmstream.vcxproj.filters b/src/libvgmstream.vcxproj.filters index 0294d4f1..7130e738 100644 --- a/src/libvgmstream.vcxproj.filters +++ b/src/libvgmstream.vcxproj.filters @@ -125,9 +125,6 @@ coding\Header Files - - coding\Header Files - coding\Header Files @@ -1414,9 +1411,6 @@ coding\Source Files - - coding\Source Files - coding\Source Files diff --git a/src/meta/bik.c b/src/meta/bik.c index eecff1f0..a80875fb 100644 --- a/src/meta/bik.c +++ b/src/meta/bik.c @@ -2,16 +2,15 @@ #include "../coding/coding.h" #include "../util.h" -static int bink_get_info(STREAMFILE *streamFile, int * out_total_streams, size_t *out_stream_size, int * out_channel_count, int * out_sample_rate, int * out_num_samples); +static int bink_get_info(STREAMFILE *streamFile, int target_subsong, int * out_total_streams, size_t *out_stream_size, int * out_channel_count, int * out_sample_rate, int * out_num_samples); /* BINK 1/2 - RAD Game Tools movies (audio/video format) */ VGMSTREAM * init_vgmstream_bik(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; int channel_count = 0, loop_flag = 0, sample_rate = 0, num_samples = 0; - int total_subsongs = 0, stream_index = streamFile->stream_index; + int total_subsongs = 0, target_subsong = streamFile->stream_index; size_t stream_size; - /* checks */ /* .bik/bik2/bk2: standard * .bika = fake extension for demuxed audio */ @@ -23,7 +22,7 @@ VGMSTREAM * init_vgmstream_bik(STREAMFILE *streamFile) { (read_32bitBE(0x00,streamFile) & 0xffffff00) != 0x4B423200 ) goto fail; /* find target stream info and samples */ - if (!bink_get_info(streamFile, &total_subsongs, &stream_size, &channel_count, &sample_rate, &num_samples)) + if (!bink_get_info(streamFile, target_subsong, &total_subsongs, &stream_size, &channel_count, &sample_rate, &num_samples)) goto fail; /* build the VGMSTREAM */ @@ -39,11 +38,9 @@ VGMSTREAM * init_vgmstream_bik(STREAMFILE *streamFile) { #ifdef VGM_USE_FFMPEG { - ffmpeg_custom_config cfg = {0}; + /* target_subsong should be passed with the streamFile */ - cfg.stream_index = stream_index; - - vgmstream->codec_data = init_ffmpeg_config(streamFile, NULL,0, 0x0,get_streamfile_size(streamFile), &cfg); + vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, NULL,0, 0x0,get_streamfile_size(streamFile)); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; } @@ -63,12 +60,12 @@ fail: * as they are not in the main header. The header for BINK1 and 2 is the same. * (a ~3 min movie needs ~6000-7000 frames = fseeks, should be fast enough) */ -static int bink_get_info(STREAMFILE *streamFile, int * out_total_subsongs, size_t * out_stream_size, int * out_channel_count, int * out_sample_rate, int * out_num_samples) { +static int bink_get_info(STREAMFILE *streamFile, int target_subsong, int * out_total_subsongs, size_t * out_stream_size, int * out_channel_count, int * out_sample_rate, int * out_num_samples) { uint32_t *offsets = NULL; uint32_t num_frames, num_samples_b = 0; off_t cur_offset; int i, j, sample_rate, channel_count; - int total_subsongs, target_subsong = streamFile->stream_index; + int total_subsongs; size_t stream_size = 0; size_t filesize = get_streamfile_size(streamFile); diff --git a/src/vgmstream.h b/src/vgmstream.h index 54ad323b..38c7ecc7 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -1114,41 +1114,19 @@ typedef struct { } hca_codec_data; #ifdef VGM_USE_FFMPEG -/* Custom FFMPEG modes */ -typedef enum { - FFMPEG_STANDARD, /* default FFmpeg */ -} ffmpeg_custom_t; - -/* config for the above modes */ -typedef struct { - int stream_index; /* FFmpeg's sub-stream (as opposed to an internal stream in custom read/seeks) */ - int codec_endian; - int channels; - - ffmpeg_custom_t type; /* ffmpeg subtype */ - size_t virtual_size; /* external value, if meta needs to know/supply it */ - - /* internal sequences, when needed */ - int sequence; - int samples_done; -} ffmpeg_custom_config; - typedef struct { /*** IO internals ***/ STREAMFILE *streamfile; - uint64_t real_start; // absolute start within the streamfile - uint64_t real_offset; // absolute offset within the streamfile - uint64_t real_size; // max size within the streamfile - uint64_t virtual_offset; // computed offset FFmpeg sees (including fake header) - uint64_t virtual_size; // computed size FFmpeg sees (including fake header) - uint64_t virtual_base; // info/base virtual_offset equivalent to current real_offset, block aligned (*not* including fake header) + uint64_t start; // absolute start within the streamfile + uint64_t offset; // absolute offset within the streamfile + uint64_t size; // max size within the streamfile + uint64_t logical_offset; // computed offset FFmpeg sees (including fake header) + uint64_t logical_size; // computed size FFmpeg sees (including fake header) uint64_t header_size; // fake header (parseable by FFmpeg) prepended on reads uint8_t *header_insert_block; // fake header data (ie. RIFF) - ffmpeg_custom_config config; /* custom config/state */ - /*** "public" API (read-only) ***/ // stream info int channels;