diff options
author | Tuomas Virtanen <katajakasa@gmail.com> | 2018-07-02 10:34:09 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-02 10:34:09 +0300 |
commit | 7aec12156a3dc3df570855cb1c3fa03792f77030 (patch) | |
tree | 6b1d66e504982e24dcf79c710126ce96457c75ef /src | |
parent | f602daa42a2a9135daa9b9a57e177edfb0c767ba (diff) | |
parent | 5973307722d4531dd24ff7ada8ab11111f5ee378 (diff) |
Merge pull request #42 from katajakasa/source-cleanups
Source cleanups + RWOps
Diffstat (limited to 'src')
-rw-r--r-- | src/kitsource.c | 75 |
1 files changed, 62 insertions, 13 deletions
diff --git a/src/kitsource.c b/src/kitsource.c index b13cde6..71a73b0 100644 --- a/src/kitsource.c +++ b/src/kitsource.c @@ -12,6 +12,16 @@ #define AVIO_BUF_SIZE 32768 +static int _ScanSource(AVFormatContext *format_ctx) { + av_opt_set_int(format_ctx, "probesize", INT_MAX, 0); + av_opt_set_int(format_ctx, "analyzeduration", INT_MAX, 0); + if(avformat_find_stream_info(format_ctx, NULL) < 0) { + Kit_SetError("Unable to fetch source information"); + return 1; + } + return 0; +} + Kit_Source* Kit_CreateSourceFromUrl(const char *url) { assert(url != NULL); @@ -27,14 +37,11 @@ Kit_Source* Kit_CreateSourceFromUrl(const char *url) { goto exit_0; } - av_opt_set_int(src->format_ctx, "probesize", INT_MAX, 0); - av_opt_set_int(src->format_ctx, "analyzeduration", INT_MAX, 0); - - // Fetch stream information. This may potentially take a while. - if(avformat_find_stream_info((AVFormatContext *)src->format_ctx, NULL) < 0) { - Kit_SetError("Unable to fetch source information"); + // Scan source information (may seek forwards) + if(_ScanSource(src->format_ctx)) { goto exit_1; } + return src; exit_1: @@ -81,13 +88,8 @@ Kit_Source* Kit_CreateSourceFromCustom(Kit_ReadCallback read_cb, Kit_SeekCallbac goto exit_3; } - // Set probe opts for input scanning - av_opt_set_int(format_ctx, "probesize", INT_MAX, 0); - av_opt_set_int(format_ctx, "analyzeduration", INT_MAX, 0); - - // Fetch stream information. This may potentially take a while. - if(avformat_find_stream_info(format_ctx, NULL) < 0) { - Kit_SetError("Unable to fetch source information"); + // Scan source information (may seek forwards) + if(_ScanSource(format_ctx)) { goto exit_4; } @@ -109,6 +111,53 @@ exit_0: return NULL; } +static int _RWReadCallback(void *userdata, uint8_t *buf, int size) { + return SDL_RWread((SDL_RWops*)userdata, buf, 1, size); +} + +static int64_t _RWGetSize(SDL_RWops *rw_ops) { + int64_t current_pos; + int64_t max_pos; + + // First, see if tell works at all, and fail with -1 if it doesn't. + current_pos = SDL_RWtell(rw_ops); + if(current_pos < 0) { + return -1; + } + + // Seek to end, get pos (this is the size), then return. + if(SDL_RWseek(rw_ops, 0, RW_SEEK_END) < 0) { + return -1; // Seek failed, never mind then + } + max_pos = SDL_RWtell(rw_ops); + SDL_RWseek(rw_ops, current_pos, RW_SEEK_SET); + return max_pos; +} + +static int64_t _RWSeekCallback(void *userdata, int64_t offset, int whence) { + int rw_whence = 0; + + if(whence & AVSEEK_SIZE) + return _RWGetSize(userdata); + if((whence & ~AVSEEK_FORCE) == SEEK_CUR) + rw_whence = RW_SEEK_CUR; + if((whence & ~AVSEEK_FORCE) == SEEK_SET) + rw_whence = RW_SEEK_SET; + if((whence & ~AVSEEK_FORCE) == SEEK_END) + rw_whence = RW_SEEK_END; + + if(SDL_RWseek((SDL_RWops*)userdata, offset, rw_whence) < 0) { + return -1; + } + + return SDL_RWtell((SDL_RWops*)userdata); +} + + +Kit_Source* Kit_CreateSourceFromRW(SDL_RWops *rw_ops) { + return Kit_CreateSourceFromCustom(_RWReadCallback, _RWSeekCallback, rw_ops); +} + void Kit_CloseSource(Kit_Source *src) { assert(src != NULL); AVFormatContext *format_ctx = src->format_ctx; |