[FFmpeg-cvslog] avformat/mov: check result of avio_seek
ffmpeg | branch: master | Zhang Rui | Thu May 21 11:48:55 2015 +0800| [c886dd2f5875e01a5949fddd0388c965c7766cfb] | committer: Michael Niedermayer avformat/mov: check result of avio_seek Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=c886dd2f5875e01a5949fddd0388c965c7766cfb --- libavformat/mov.c |5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index ed2afd4..f6f07be 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -4240,7 +4240,10 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) mov->found_mdat = 0; if (!mov->next_root_atom) return AVERROR_EOF; -avio_seek(s->pb, mov->next_root_atom, SEEK_SET); +if (avio_seek(s->pb, mov->next_root_atom, SEEK_SET) != mov->next_root_atom) { +av_log(mov->fc, AV_LOG_ERROR, "next root atom offset 0x%"PRIx64": partial file\n", mov->next_root_atom); +return AVERROR_INVALIDDATA; +} mov->next_root_atom = 0; if (mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX }) < 0 || avio_feof(s->pb)) ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avutil/log: modify AV_LOG_MAX_OFFSET for AV_LOG_TRACE
ffmpeg | branch: master | Zhang Rui | Fri Jun 26 16:17:22 2015 +0800| [d38bc6361df6ace27e1b2ae2fc4d8cb0034c] | committer: Michael Niedermayer avutil/log: modify AV_LOG_MAX_OFFSET for AV_LOG_TRACE Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=d38bc6361df6ace27e1b2ae2fc4d8cb0034c --- libavutil/log.h |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavutil/log.h b/libavutil/log.h index db7eb3f..321748c 100644 --- a/libavutil/log.h +++ b/libavutil/log.h @@ -196,13 +196,13 @@ typedef struct AVClass { */ #define AV_LOG_DEBUG48 -#define AV_LOG_MAX_OFFSET (AV_LOG_DEBUG - AV_LOG_QUIET) - /** * Extremely verbose debugging, useful for libav* development. */ #define AV_LOG_TRACE56 +#define AV_LOG_MAX_OFFSET (AV_LOG_TRACE - AV_LOG_QUIET) + /** * @} */ ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] configure: clean whitespace with [:space:]
ffmpeg | branch: master | Zhang Rui | Mon Jul 13 16:22:40 2015 +0800| [f5c281daa8aed4618f94e4131be17e772f6673f8] | committer: Michael Niedermayer configure: clean whitespace with [:space:] https://en.wikibooks.org/wiki/Regular_Expressions/POSIX_Basic_Regular_Expressions Fixes NDKr10e on Cygwin, CC_IDENT for it is defined as Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=f5c281daa8aed4618f94e4131be17e772f6673f8 --- configure |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 741d741..88ee936 100755 --- a/configure +++ b/configure @@ -477,7 +477,7 @@ sh_quote(){ } cleanws(){ -echo "$@" | sed 's/^ *//;s/ */ /g;s/ *$//;s/\\r//g' +echo "$@" | sed 's/^ *//;s/[[:space:]][[:space:]]*/ /g;s/ *$//' } filter(){ ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avutil/fifo: Fix the case where func() returns less bytes than requested in av_fifo_generic_write()
ffmpeg | branch: master | Zhang Rui | Tue Jul 14 14:47:26 2015 +0800| [fcbea93cf8777bbef2a393d26942b5d3c70a448d] | committer: Michael Niedermayer avutil/fifo: Fix the case where func() returns less bytes than requested in av_fifo_generic_write() Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=fcbea93cf8777bbef2a393d26942b5d3c70a448d --- libavutil/fifo.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavutil/fifo.c b/libavutil/fifo.c index 4ff3194..f2fe93d 100644 --- a/libavutil/fifo.c +++ b/libavutil/fifo.c @@ -129,7 +129,8 @@ int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, do { int len = FFMIN(f->end - wptr, size); if (func) { -if (func(src, wptr, len) <= 0) +len = func(src, wptr, len); +if (len <= 0) break; } else { memcpy(wptr, src, len); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avformat/async: support filling with a background thread.
ffmpeg | branch: master | Zhang Rui | Thu Jul 16 15:04:42 2015 +0800| [f477a3f5abc15a9ffa117cd53ca93237a4f4d58c] | committer: Michael Niedermayer avformat/async: support filling with a background thread. Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=f477a3f5abc15a9ffa117cd53ca93237a4f4d58c --- configure|1 + doc/protocols.texi | 12 ++ libavformat/Makefile |1 + libavformat/allformats.c |1 + libavformat/async.c | 387 ++ 5 files changed, 402 insertions(+) diff --git a/configure b/configure index dd84285..1752a35 100755 --- a/configure +++ b/configure @@ -2654,6 +2654,7 @@ x11grab_indev_deps="x11grab" x11grab_xcb_indev_deps="libxcb" # protocols +async_protocol_deps="pthreads" bluray_protocol_deps="libbluray" ffrtmpcrypt_protocol_deps="!librtmp_protocol" ffrtmpcrypt_protocol_deps_any="gcrypt gmp openssl" diff --git a/doc/protocols.texi b/doc/protocols.texi index 453dbcf..f152f5a 100644 --- a/doc/protocols.texi +++ b/doc/protocols.texi @@ -19,6 +19,18 @@ supported protocols. A description of the currently available protocols follows. +@section async + +Asynchronous data filling wrapper for input stream. + +Fill data in a background thread, to decouple I/O operation from demux thread. + +@example +async:@var{URL} +async:http://host/resource +async:cache:http://host/resource +@end example + @section bluray Read BluRay playlist. diff --git a/libavformat/Makefile b/libavformat/Makefile index 479361a..108b6a6 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -496,6 +496,7 @@ OBJS-$(CONFIG_LIBSSH_PROTOCOL) += libssh.o OBJS-$(CONFIG_LIBSMBCLIENT_PROTOCOL) += libsmbclient.o # protocols I/O +OBJS-$(CONFIG_ASYNC_PROTOCOL)+= async.o OBJS-$(CONFIG_APPLEHTTP_PROTOCOL)+= hlsproto.o OBJS-$(CONFIG_BLURAY_PROTOCOL) += bluray.o OBJS-$(CONFIG_CACHE_PROTOCOL)+= cache.o diff --git a/libavformat/allformats.c b/libavformat/allformats.c index 2caa6b1..181cb9e 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -351,6 +351,7 @@ void av_register_all(void) /* protocols */ +REGISTER_PROTOCOL(ASYNC,async); REGISTER_PROTOCOL(BLURAY, bluray); REGISTER_PROTOCOL(CACHE,cache); REGISTER_PROTOCOL(CONCAT, concat); diff --git a/libavformat/async.c b/libavformat/async.c new file mode 100644 index 000..0748309 --- /dev/null +++ b/libavformat/async.c @@ -0,0 +1,387 @@ +/* + * Input async protocol. + * Copyright (c) 2015 Zhang Rui + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Based on libavformat/cache.c by Michael Niedermayer + */ + + /** + * @TODO + * support timeout + * support backward short seek + * support work with concatdec, hls + */ + +#include "libavutil/avassert.h" +#include "libavutil/avstring.h" +#include "libavutil/error.h" +#include "libavutil/fifo.h" +#include "libavutil/log.h" +#include "libavutil/opt.h" +#include "url.h" +#include +#include + +#if HAVE_UNISTD_H +#include +#endif + +#define BUFFER_CAPACITY (4 * 1024 * 1024) +#define SHORT_SEEK_THRESHOLD(256 * 1024) + +typedef struct Context { +AVClass*class; +URLContext *inner; + +int seek_request; +size_t seek_pos; +int seek_whence; +int seek_completed; +int64_t seek_ret; + +int io_error; +int io_eof_reached; + +size_t logical_pos; +size_t logical_size; +AVFifoBuffer *fifo; + +pthread_cond_t cond_wakeup_main; +pthread_cond_t cond_wakeup_background; +pthread_mutex_t mutex; +pthread_t async_buffer_thread; + +int abort_request; +AVIOInterruptCB interrupt_callback; +} Context; + +static int async_interrupt_callback(void *arg) +{ +URLContext *h = arg; +Context*c = h->priv_data; +int ret = 0; + +if (c->interrupt_callback.callback) { +
[FFmpeg-cvslog] avutil/fifo: Fix the case where func() returns less bytes than requested in av_fifo_generic_write()
ffmpeg | branch: release/2.7 | Zhang Rui | Tue Jul 14 14:47:26 2015 +0800| [a330aca126eb67d7374f821cbf4765eb6640d00c] | committer: Michael Niedermayer avutil/fifo: Fix the case where func() returns less bytes than requested in av_fifo_generic_write() Signed-off-by: Michael Niedermayer (cherry picked from commit fcbea93cf8777bbef2a393d26942b5d3c70a448d) Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a330aca126eb67d7374f821cbf4765eb6640d00c --- libavutil/fifo.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavutil/fifo.c b/libavutil/fifo.c index 4ff3194..f2fe93d 100644 --- a/libavutil/fifo.c +++ b/libavutil/fifo.c @@ -129,7 +129,8 @@ int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, do { int len = FFMIN(f->end - wptr, size); if (func) { -if (func(src, wptr, len) <= 0) +len = func(src, wptr, len); +if (len <= 0) break; } else { memcpy(wptr, src, len); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avformat/concatdec: avoid NULL dereference when failed to open file.
ffmpeg | branch: master | Zhang Rui | Thu Jan 29 17:55:32 2015 +0800| [038f3a173f59c9fc3396aa38e7972661da7ca504] | committer: Michael Niedermayer avformat/concatdec: avoid NULL dereference when failed to open file. Reviewed-by: Nicolas George Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=038f3a173f59c9fc3396aa38e7972661da7ca504 --- libavformat/concatdec.c |3 +++ 1 file changed, 3 insertions(+) diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c index e109524..f07cfd7 100644 --- a/libavformat/concatdec.c +++ b/libavformat/concatdec.c @@ -482,6 +482,9 @@ static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt) ConcatStream *cs; AVStream *st; +if (!cat->avf) +return AVERROR(EIO); + while (1) { ret = av_read_frame(cat->avf, pkt); if (ret == AVERROR_EOF) { ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avformat/cache: pass options to the underlying protocol via the url_open2
ffmpeg | branch: master | Zhang Rui | Sat Jan 31 13:35:04 2015 +0800| [ca2e3e47fc6f755e5614e33dc0e654b8137fc16f] | committer: Michael Niedermayer avformat/cache: pass options to the underlying protocol via the url_open2 Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=ca2e3e47fc6f755e5614e33dc0e654b8137fc16f --- libavformat/cache.c |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavformat/cache.c b/libavformat/cache.c index 02b02bb..26e68c5 100644 --- a/libavformat/cache.c +++ b/libavformat/cache.c @@ -70,7 +70,7 @@ static int cmp(void *key, const void *node) return (*(int64_t *) key) - ((const CacheEntry *) node)->logical_pos; } -static int cache_open(URLContext *h, const char *arg, int flags) +static int cache_open(URLContext *h, const char *arg, int flags, AVDictionary **options) { char *buffername; Context *c= h->priv_data; @@ -86,7 +86,7 @@ static int cache_open(URLContext *h, const char *arg, int flags) unlink(buffername); av_freep(&buffername); -return ffurl_open(&c->inner, arg, flags, &h->interrupt_callback, NULL); +return ffurl_open(&c->inner, arg, flags, &h->interrupt_callback, options); } static int add_entry(URLContext *h, const unsigned char *buf, int size) @@ -313,7 +313,7 @@ static const AVClass cache_context_class = { URLProtocol ff_cache_protocol = { .name= "cache", -.url_open= cache_open, +.url_open2 = cache_open, .url_read= cache_read, .url_seek= cache_seek, .url_close = cache_close, ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avformat/http: support auto reconnect
ffmpeg | branch: master | Zhang Rui | Thu Mar 12 11:39:55 2015 +0800| [3f375950f3c9a9c5cf7cece6c26d3e0e7ce278cf] | committer: Michael Niedermayer avformat/http: support auto reconnect Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=3f375950f3c9a9c5cf7cece6c26d3e0e7ce278cf --- libavformat/http.c | 32 +++- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/libavformat/http.c b/libavformat/http.c index 55dcb6e..86380b2 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -93,6 +93,7 @@ typedef struct HTTPContext { AVDictionary *chained_options; int send_expect_100; char *method; +int reconnect; } HTTPContext; #define OFFSET(x) offsetof(HTTPContext, x) @@ -123,6 +124,7 @@ static const AVOption options[] = { { "offset", "initial byte offset", OFFSET(off), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, D }, { "end_offset", "try to limit the request to bytes preceding this offset", OFFSET(end_off), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, D }, { "method", "Override the HTTP method", OFFSET(method), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E }, +{ "reconnect", "auto reconnect after disconnect before EOF", OFFSET(reconnect), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, D }, { NULL } }; @@ -908,10 +910,12 @@ static int http_buf_read_compressed(URLContext *h, uint8_t *buf, int size) } #endif /* CONFIG_ZLIB */ +static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int force_reconnect); + static int http_read_stream(URLContext *h, uint8_t *buf, int size) { HTTPContext *s = h->priv_data; -int err, new_location; +int err, new_location, read_ret, seek_ret; if (!s->hd) return AVERROR_EOF; @@ -945,7 +949,19 @@ static int http_read_stream(URLContext *h, uint8_t *buf, int size) if (s->compressed) return http_buf_read_compressed(h, buf, size); #endif /* CONFIG_ZLIB */ -return http_buf_read(h, buf, size); +read_ret = http_buf_read(h, buf, size); +if (read_ret < 0 && s->reconnect && !h->is_streamed && s->filesize > 0 && s->off < s->filesize) { +av_log(h, AV_LOG_INFO, "Will reconnect at %"PRId64".\n", s->off); +seek_ret = http_seek_internal(h, s->off, SEEK_SET, 1); +if (seek_ret != s->off) { +av_log(h, AV_LOG_ERROR, "Failed to reconnect at %"PRId64".\n", s->off); +return read_ret; +} + +read_ret = http_buf_read(h, buf, size); +} + +return read_ret; } // Like http_read_stream(), but no short reads. @@ -1104,7 +1120,7 @@ static int http_close(URLContext *h) return ret; } -static int64_t http_seek(URLContext *h, int64_t off, int whence) +static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int force_reconnect) { HTTPContext *s = h->priv_data; URLContext *old_hd = s->hd; @@ -1115,8 +1131,9 @@ static int64_t http_seek(URLContext *h, int64_t off, int whence) if (whence == AVSEEK_SIZE) return s->filesize; -else if ((whence == SEEK_CUR && off == 0) || - (whence == SEEK_SET && off == s->off)) +else if (!force_reconnect && + ((whence == SEEK_CUR && off == 0) || + (whence == SEEK_SET && off == s->off))) return s->off; else if ((s->filesize == -1 && whence == SEEK_END) || h->is_streamed) return AVERROR(ENOSYS); @@ -1151,6 +1168,11 @@ static int64_t http_seek(URLContext *h, int64_t off, int whence) return off; } +static int64_t http_seek(URLContext *h, int64_t off, int whence) +{ +return http_seek_internal(h, off, whence, 0); +} + static int http_get_file_handle(URLContext *h) { HTTPContext *s = h->priv_data; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avutil/fifo: Fix the case where func() returns less bytes than requested in av_fifo_generic_write()
ffmpeg | branch: release/2.6 | Zhang Rui | Tue Jul 14 14:47:26 2015 +0800| [5db095793a28b1fa9b5547394c51edcf273ddb31] | committer: Michael Niedermayer avutil/fifo: Fix the case where func() returns less bytes than requested in av_fifo_generic_write() Signed-off-by: Michael Niedermayer (cherry picked from commit fcbea93cf8777bbef2a393d26942b5d3c70a448d) Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=5db095793a28b1fa9b5547394c51edcf273ddb31 --- libavutil/fifo.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavutil/fifo.c b/libavutil/fifo.c index 4ff3194..f2fe93d 100644 --- a/libavutil/fifo.c +++ b/libavutil/fifo.c @@ -129,7 +129,8 @@ int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, do { int len = FFMIN(f->end - wptr, size); if (func) { -if (func(src, wptr, len) <= 0) +len = func(src, wptr, len); +if (len <= 0) break; } else { memcpy(wptr, src, len); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] MAINTAINERS: add myself as a maintainer for async protocol
ffmpeg | branch: master | Zhang Rui | Tue Jul 21 15:46:02 2015 +0800| [cee7acfcfc1bc806044ff35ff7ec7b64528f99b1] | committer: Michael Niedermayer MAINTAINERS: add myself as a maintainer for async protocol Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=cee7acfcfc1bc806044ff35ff7ec7b64528f99b1 --- MAINTAINERS |1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 886ecae..6eff022 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -504,6 +504,7 @@ Muxers/Demuxers: wvenc.c Paul B Mahol Protocols: + async.c Zhang Rui bluray.c Petri Hintukainen ftp.c Lukasz Marek http.cRonald S. Bultje ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] fate: add test for async protocol
ffmpeg | branch: master | Zhang Rui | Tue Jul 21 21:04:03 2015 +0800| [aee909acfb34bf8c03e3c4a93430df95ba8fae08] | committer: Michael Niedermayer fate: add test for async protocol Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=aee909acfb34bf8c03e3c4a93430df95ba8fae08 --- libavformat/Makefile |3 +- libavformat/async.c| 171 tests/fate/libavformat.mak |4 ++ tests/ref/fate/async |7 ++ 4 files changed, 184 insertions(+), 1 deletion(-) diff --git a/libavformat/Makefile b/libavformat/Makefile index 108b6a6..cc73fd8 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -546,7 +546,8 @@ SLIBOBJS-$(HAVE_GNU_WINDRES) += avformatres.o SKIPHEADERS-$(CONFIG_FFRTMPCRYPT_PROTOCOL) += rtmpdh.h SKIPHEADERS-$(CONFIG_NETWORK)+= network.h rtsp.h -TESTPROGS = seek\ +TESTPROGS = async \ +seek\ srtp\ url \ diff --git a/libavformat/async.c b/libavformat/async.c index 0748309..be02308 100644 --- a/libavformat/async.c +++ b/libavformat/async.c @@ -385,3 +385,174 @@ URLProtocol ff_async_protocol = { .priv_data_size = sizeof(Context), .priv_data_class = &async_context_class, }; + +#ifdef TEST + +#define TEST_SEEK_POS(1536) +#define TEST_STREAM_SIZE (2048) + +typedef struct TestContext { +AVClass*class; +size_t logical_pos; +size_t logical_size; +} TestContext; + +static int async_test_open(URLContext *h, const char *arg, int flags, AVDictionary **options) +{ +TestContext *c = h->priv_data; +c->logical_pos = 0; +c->logical_size = TEST_STREAM_SIZE; +return 0; +} + +static int async_test_close(URLContext *h) +{ +return 0; +} + +static int async_test_read(URLContext *h, unsigned char *buf, int size) +{ +TestContext *c = h->priv_data; +int i; +int read_len = 0; + +if (c->logical_pos >= c->logical_size) +return AVERROR_EOF; + +for (i = 0; i < size; ++i) { +buf[i] = c->logical_pos & 0xFF; + +c->logical_pos++; +read_len++; + +if (c->logical_pos >= c->logical_size) +break; +} + +return read_len; +} + +static int64_t async_test_seek(URLContext *h, int64_t pos, int whence) +{ +TestContext *c = h->priv_data; +int64_t new_logical_pos; + +if (whence == AVSEEK_SIZE) { +return c->logical_size; +} if (whence == SEEK_CUR) { +new_logical_pos = pos + c->logical_pos; +} else if (whence == SEEK_SET){ +new_logical_pos = pos; +} else { +return AVERROR(EINVAL); +} +if (new_logical_pos < 0) +return AVERROR(EINVAL); + +c->logical_pos = new_logical_pos; +return new_logical_pos; +} + +static const AVClass async_test_context_class = { +.class_name = "Async-Test", +.item_name = av_default_item_name, +.version= LIBAVUTIL_VERSION_INT, +}; + +URLProtocol ff_async_test_protocol = { +.name= "async-test", +.url_open2 = async_test_open, +.url_read= async_test_read, +.url_seek= async_test_seek, +.url_close = async_test_close, +.priv_data_size = sizeof(TestContext), +.priv_data_class = &async_test_context_class, +}; + +int main(void) +{ +URLContext *h = NULL; +int i; +int ret; +int64_t size; +int64_t pos; +int64_t read_len; +unsigned char buf[4096]; + +ffurl_register_protocol(&ff_async_protocol); +ffurl_register_protocol(&ff_async_test_protocol); + +ret = ffurl_open(&h, "async:async-test:", AVIO_FLAG_READ, NULL, NULL); +printf("open: %d\n", ret); + +size = ffurl_size(h); +printf("size: %"PRId64"\n", size); + +pos = ffurl_seek(h, 0, SEEK_CUR); +read_len = 0; +while (1) { +ret = ffurl_read(h, buf, sizeof(buf)); +if (ret == AVERROR_EOF) { +printf("read-error: AVERROR_EOF at %"PRId64"\n", ffurl_seek(h, 0, SEEK_CUR)); +break; +} +else if (ret == 0) +break; +else if (ret < 0) { +printf("read-error: %d at %"PRId64"\n", ret, ffurl_seek(h, 0, SEEK_CUR)); +goto fail; +} else { +for (i = 0; i < ret; ++i) { +if (buf[i] != (pos & 0xFF)) { +printf(&
[FFmpeg-cvslog] avformat/async: rename async_interrupt_callback to async_check_interrupt
ffmpeg | branch: master | Zhang Rui | Wed Jul 22 02:47:24 2015 +0800| [830d3a0ebe24600ebd1f27767204db5f7d059ea1] | committer: Michael Niedermayer avformat/async: rename async_interrupt_callback to async_check_interrupt Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=830d3a0ebe24600ebd1f27767204db5f7d059ea1 --- libavformat/async.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavformat/async.c b/libavformat/async.c index 54021e7..c523b3d 100644 --- a/libavformat/async.c +++ b/libavformat/async.c @@ -71,7 +71,7 @@ typedef struct Context { AVIOInterruptCB interrupt_callback; } Context; -static int async_interrupt_callback(void *arg) +static int async_check_interrupt(void *arg) { URLContext *h = arg; Context*c = h->priv_data; @@ -95,7 +95,7 @@ static void *async_buffer_task(void *arg) while (1) { int fifo_space, to_copy; -if (async_interrupt_callback(h)) { +if (async_check_interrupt(h)) { c->io_eof_reached = 1; c->io_error = AVERROR_EXIT; break; @@ -154,7 +154,7 @@ static int async_open(URLContext *h, const char *arg, int flags, AVDictionary ** { Context *c = h->priv_data; int ret; -AVIOInterruptCB interrupt_callback = {.callback = async_interrupt_callback, .opaque = h}; +AVIOInterruptCB interrupt_callback = {.callback = async_check_interrupt, .opaque = h}; av_strstart(arg, "async:", &arg); @@ -250,7 +250,7 @@ static int async_read_internal(URLContext *h, void *dest, int size, int read_com while (to_read > 0) { int fifo_size, to_copy; -if (async_interrupt_callback(h)) { +if (async_check_interrupt(h)) { ret = AVERROR_EXIT; break; } @@ -342,7 +342,7 @@ static int64_t async_seek(URLContext *h, int64_t pos, int whence) c->seek_ret = 0; while (1) { -if (async_interrupt_callback(h)) { +if (async_check_interrupt(h)) { ret = AVERROR_EXIT; break; } ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avformat/async: fix interrupt_callback usage and return code
ffmpeg | branch: master | Zhang Rui | Wed Jul 22 02:47:23 2015 +0800| [5e2098d9064e130e603018c8185f591fbcfd5873] | committer: Michael Niedermayer avformat/async: fix interrupt_callback usage and return code Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=5e2098d9064e130e603018c8185f591fbcfd5873 --- libavformat/async.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/libavformat/async.c b/libavformat/async.c index c2df274..54021e7 100644 --- a/libavformat/async.c +++ b/libavformat/async.c @@ -75,13 +75,12 @@ static int async_interrupt_callback(void *arg) { URLContext *h = arg; Context*c = h->priv_data; -int ret = 0; -if (c->interrupt_callback.callback) { -ret = c->interrupt_callback.callback(c->interrupt_callback.opaque); -if (!ret) -return ret; -} +if (c->abort_request) +return 1; + +if (ff_check_interrupt(&c->interrupt_callback)) +c->abort_request = 1; return c->abort_request; } ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avformat/async: wake up main thread before exit background thread
ffmpeg | branch: master | Zhang Rui | Wed Jul 22 02:47:26 2015 +0800| [8a173351895e29e842e3a299b0366faac80aff9a] | committer: Michael Niedermayer avformat/async: wake up main thread before exit background thread Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=8a173351895e29e842e3a299b0366faac80aff9a --- libavformat/async.c |1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/async.c b/libavformat/async.c index 0bcc3ae..60ea14c 100644 --- a/libavformat/async.c +++ b/libavformat/async.c @@ -99,6 +99,7 @@ static void *async_buffer_task(void *arg) if (async_check_interrupt(h)) { c->io_eof_reached = 1; c->io_error = AVERROR_EXIT; +pthread_cond_signal(&c->cond_wakeup_main); pthread_mutex_unlock(&c->mutex); break; } ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avformat/async: move more code into locked area in background thread
ffmpeg | branch: master | Zhang Rui | Wed Jul 22 02:47:25 2015 +0800| [c0a4af408ee56e38aed32dc75749014e21261b13] | committer: Michael Niedermayer avformat/async: move more code into locked area in background thread Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=c0a4af408ee56e38aed32dc75749014e21261b13 --- libavformat/async.c |9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libavformat/async.c b/libavformat/async.c index c523b3d..0bcc3ae 100644 --- a/libavformat/async.c +++ b/libavformat/async.c @@ -95,15 +95,15 @@ static void *async_buffer_task(void *arg) while (1) { int fifo_space, to_copy; +pthread_mutex_lock(&c->mutex); if (async_check_interrupt(h)) { c->io_eof_reached = 1; c->io_error = AVERROR_EXIT; +pthread_mutex_unlock(&c->mutex); break; } if (c->seek_request) { -pthread_mutex_lock(&c->mutex); - ret = ffurl_seek(c->inner, c->seek_pos, c->seek_whence); if (ret < 0) { c->io_eof_reached = 1; @@ -126,15 +126,17 @@ static void *async_buffer_task(void *arg) fifo_space = av_fifo_space(fifo); if (c->io_eof_reached || fifo_space <= 0) { -pthread_mutex_lock(&c->mutex); pthread_cond_signal(&c->cond_wakeup_main); pthread_cond_wait(&c->cond_wakeup_background, &c->mutex); pthread_mutex_unlock(&c->mutex); continue; } +pthread_mutex_unlock(&c->mutex); to_copy = FFMIN(4096, fifo_space); ret = av_fifo_generic_write(fifo, c->inner, to_copy, (void *)ffurl_read); + +pthread_mutex_lock(&c->mutex); if (ret <= 0) { c->io_eof_reached = 1; if (ret < 0) { @@ -142,7 +144,6 @@ static void *async_buffer_task(void *arg) } } -pthread_mutex_lock(&c->mutex); pthread_cond_signal(&c->cond_wakeup_main); pthread_mutex_unlock(&c->mutex); } ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avutil/fifo: Fix the case where func() returns less bytes than requested in av_fifo_generic_write()
ffmpeg | branch: release/2.5 | Zhang Rui | Tue Jul 14 14:47:26 2015 +0800| [d819a2c9869cacfc58ab7ef55bf74532bd6dad20] | committer: Michael Niedermayer avutil/fifo: Fix the case where func() returns less bytes than requested in av_fifo_generic_write() Signed-off-by: Michael Niedermayer (cherry picked from commit fcbea93cf8777bbef2a393d26942b5d3c70a448d) Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=d819a2c9869cacfc58ab7ef55bf74532bd6dad20 --- libavutil/fifo.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavutil/fifo.c b/libavutil/fifo.c index 4ff3194..f2fe93d 100644 --- a/libavutil/fifo.c +++ b/libavutil/fifo.c @@ -129,7 +129,8 @@ int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, do { int len = FFMIN(f->end - wptr, size); if (func) { -if (func(src, wptr, len) <= 0) +len = func(src, wptr, len); +if (len <= 0) break; } else { memcpy(wptr, src, len); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avutil/fifo: Fix the case where func() returns less bytes than requested in av_fifo_generic_write()
ffmpeg | branch: release/2.4 | Zhang Rui | Tue Jul 14 14:47:26 2015 +0800| [7a7ec3ccd9b63e898bb9bafe31ff2475c47cd210] | committer: Michael Niedermayer avutil/fifo: Fix the case where func() returns less bytes than requested in av_fifo_generic_write() Signed-off-by: Michael Niedermayer (cherry picked from commit fcbea93cf8777bbef2a393d26942b5d3c70a448d) Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=7a7ec3ccd9b63e898bb9bafe31ff2475c47cd210 --- libavutil/fifo.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavutil/fifo.c b/libavutil/fifo.c index 77391ee..7cb212e 100644 --- a/libavutil/fifo.c +++ b/libavutil/fifo.c @@ -129,7 +129,8 @@ int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, do { int len = FFMIN(f->end - wptr, size); if (func) { -if (func(src, wptr, len) <= 0) +len = func(src, wptr, len); +if (len <= 0) break; } else { memcpy(wptr, src, len); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] ffplay: remove unused include libavutil/colorspace.h
ffmpeg | branch: master | Zhang Rui | Thu Aug 27 14:00:30 2015 +0800| [92d378067ee3ed47fb9076e37d5fb7613c6aac5f] | committer: Michael Niedermayer ffplay: remove unused include libavutil/colorspace.h Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=92d378067ee3ed47fb9076e37d5fb7613c6aac5f --- ffplay.c |1 - 1 file changed, 1 deletion(-) diff --git a/ffplay.c b/ffplay.c index cde88db..d0e1822 100644 --- a/ffplay.c +++ b/ffplay.c @@ -31,7 +31,6 @@ #include #include "libavutil/avstring.h" -#include "libavutil/colorspace.h" #include "libavutil/eval.h" #include "libavutil/mathematics.h" #include "libavutil/pixdesc.h" ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avformat/async: replace strerror with av_err2str
ffmpeg | branch: master | Zhang Rui | Sun Sep 6 12:51:54 2015 +0800| [929451c5cba5f05fa3511bc4cec2a8ebd4a41f5d] | committer: Michael Niedermayer avformat/async: replace strerror with av_err2str Fixes CID1322337 Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=929451c5cba5f05fa3511bc4cec2a8ebd4a41f5d --- libavformat/async.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libavformat/async.c b/libavformat/async.c index 60ea14c..15355fb 100644 --- a/libavformat/async.c +++ b/libavformat/async.c @@ -170,7 +170,7 @@ static int async_open(URLContext *h, const char *arg, int flags, AVDictionary ** c->interrupt_callback = h->interrupt_callback; ret = ffurl_open(&c->inner, arg, flags, &interrupt_callback, options); if (ret != 0) { -av_log(h, AV_LOG_ERROR, "ffurl_open failed : %s, %s\n", strerror(ret), arg); +av_log(h, AV_LOG_ERROR, "ffurl_open failed : %s, %s\n", av_err2str(ret), arg); goto url_fail; } @@ -179,25 +179,25 @@ static int async_open(URLContext *h, const char *arg, int flags, AVDictionary ** ret = pthread_mutex_init(&c->mutex, NULL); if (ret != 0) { -av_log(h, AV_LOG_ERROR, "pthread_mutex_init failed : %s\n", strerror(ret)); +av_log(h, AV_LOG_ERROR, "pthread_mutex_init failed : %s\n", av_err2str(ret)); goto mutex_fail; } ret = pthread_cond_init(&c->cond_wakeup_main, NULL); if (ret != 0) { -av_log(h, AV_LOG_ERROR, "pthread_cond_init failed : %s\n", strerror(ret)); +av_log(h, AV_LOG_ERROR, "pthread_cond_init failed : %s\n", av_err2str(ret)); goto cond_wakeup_main_fail; } ret = pthread_cond_init(&c->cond_wakeup_background, NULL); if (ret != 0) { -av_log(h, AV_LOG_ERROR, "pthread_cond_init failed : %s\n", strerror(ret)); +av_log(h, AV_LOG_ERROR, "pthread_cond_init failed : %s\n", av_err2str(ret)); goto cond_wakeup_background_fail; } ret = pthread_create(&c->async_buffer_thread, NULL, async_buffer_task, h); if (ret) { -av_log(h, AV_LOG_ERROR, "pthread_create failed : %s\n", strerror(ret)); +av_log(h, AV_LOG_ERROR, "pthread_create failed : %s\n", av_err2str(ret)); goto thread_fail; } @@ -229,7 +229,7 @@ static int async_close(URLContext *h) ret = pthread_join(c->async_buffer_thread, NULL); if (ret != 0) -av_log(h, AV_LOG_ERROR, "pthread_join(): %s\n", strerror(ret)); +av_log(h, AV_LOG_ERROR, "pthread_join(): %s\n", av_err2str(ret)); pthread_cond_destroy(&c->cond_wakeup_background); pthread_cond_destroy(&c->cond_wakeup_main); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avformat/async: replace strerror with av_err2str
ffmpeg | branch: release/2.8 | Zhang Rui | Sun Sep 6 12:51:54 2015 +0800| [8cd24f8fe7b834b1b9197544100fe6cdda7d18d8] | committer: Michael Niedermayer avformat/async: replace strerror with av_err2str Fixes CID1322337 Signed-off-by: Michael Niedermayer (cherry picked from commit 929451c5cba5f05fa3511bc4cec2a8ebd4a41f5d) Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=8cd24f8fe7b834b1b9197544100fe6cdda7d18d8 --- libavformat/async.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libavformat/async.c b/libavformat/async.c index 60ea14c..15355fb 100644 --- a/libavformat/async.c +++ b/libavformat/async.c @@ -170,7 +170,7 @@ static int async_open(URLContext *h, const char *arg, int flags, AVDictionary ** c->interrupt_callback = h->interrupt_callback; ret = ffurl_open(&c->inner, arg, flags, &interrupt_callback, options); if (ret != 0) { -av_log(h, AV_LOG_ERROR, "ffurl_open failed : %s, %s\n", strerror(ret), arg); +av_log(h, AV_LOG_ERROR, "ffurl_open failed : %s, %s\n", av_err2str(ret), arg); goto url_fail; } @@ -179,25 +179,25 @@ static int async_open(URLContext *h, const char *arg, int flags, AVDictionary ** ret = pthread_mutex_init(&c->mutex, NULL); if (ret != 0) { -av_log(h, AV_LOG_ERROR, "pthread_mutex_init failed : %s\n", strerror(ret)); +av_log(h, AV_LOG_ERROR, "pthread_mutex_init failed : %s\n", av_err2str(ret)); goto mutex_fail; } ret = pthread_cond_init(&c->cond_wakeup_main, NULL); if (ret != 0) { -av_log(h, AV_LOG_ERROR, "pthread_cond_init failed : %s\n", strerror(ret)); +av_log(h, AV_LOG_ERROR, "pthread_cond_init failed : %s\n", av_err2str(ret)); goto cond_wakeup_main_fail; } ret = pthread_cond_init(&c->cond_wakeup_background, NULL); if (ret != 0) { -av_log(h, AV_LOG_ERROR, "pthread_cond_init failed : %s\n", strerror(ret)); +av_log(h, AV_LOG_ERROR, "pthread_cond_init failed : %s\n", av_err2str(ret)); goto cond_wakeup_background_fail; } ret = pthread_create(&c->async_buffer_thread, NULL, async_buffer_task, h); if (ret) { -av_log(h, AV_LOG_ERROR, "pthread_create failed : %s\n", strerror(ret)); +av_log(h, AV_LOG_ERROR, "pthread_create failed : %s\n", av_err2str(ret)); goto thread_fail; } @@ -229,7 +229,7 @@ static int async_close(URLContext *h) ret = pthread_join(c->async_buffer_thread, NULL); if (ret != 0) -av_log(h, AV_LOG_ERROR, "pthread_join(): %s\n", strerror(ret)); +av_log(h, AV_LOG_ERROR, "pthread_join(): %s\n", av_err2str(ret)); pthread_cond_destroy(&c->cond_wakeup_background); pthread_cond_destroy(&c->cond_wakeup_main); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avformat/async: fix integer conversion warning
ffmpeg | branch: master | Zhang Rui | Mon Sep 7 14:54:49 2015 +0800| [b821aed706292047290d8a739629fa8486328878] | committer: Michael Niedermayer avformat/async: fix integer conversion warning Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=b821aed706292047290d8a739629fa8486328878 --- libavformat/async.c | 21 +++-- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/libavformat/async.c b/libavformat/async.c index 15355fb..003212d 100644 --- a/libavformat/async.c +++ b/libavformat/async.c @@ -50,7 +50,7 @@ typedef struct Context { URLContext *inner; int seek_request; -size_t seek_pos; +int64_t seek_pos; int seek_whence; int seek_completed; int64_t seek_ret; @@ -58,8 +58,8 @@ typedef struct Context { int io_error; int io_eof_reached; -size_t logical_pos; -size_t logical_size; +int64_t logical_pos; +int64_t logical_size; AVFifoBuffer *fifo; pthread_cond_t cond_wakeup_main; @@ -91,6 +91,7 @@ static void *async_buffer_task(void *arg) Context *c= h->priv_data; AVFifoBuffer *fifo = c->fifo; int ret = 0; +int64_t seek_ret; while (1) { int fifo_space, to_copy; @@ -105,17 +106,17 @@ static void *async_buffer_task(void *arg) } if (c->seek_request) { -ret = ffurl_seek(c->inner, c->seek_pos, c->seek_whence); -if (ret < 0) { +seek_ret = ffurl_seek(c->inner, c->seek_pos, c->seek_whence); +if (seek_ret < 0) { c->io_eof_reached = 1; -c->io_error = ret; +c->io_error = (int)seek_ret; } else { c->io_eof_reached = 0; c->io_error = 0; } c->seek_completed = 1; -c->seek_ret = ret; +c->seek_ret = seek_ret; c->seek_request = 0; av_fifo_reset(fifo); @@ -325,7 +326,7 @@ static int64_t async_seek(URLContext *h, int64_t pos, int whence) av_log(h, AV_LOG_TRACE, "async_seek: fask_seek %"PRId64" from %d dist:%d/%d\n", new_logical_pos, (int)c->logical_pos, (int)(new_logical_pos - c->logical_pos), fifo_size); -async_read_internal(h, NULL, new_logical_pos - c->logical_pos, 1, fifo_do_not_copy_func); +async_read_internal(h, NULL, (int)(new_logical_pos - c->logical_pos), 1, fifo_do_not_copy_func); return c->logical_pos; } else if (c->logical_size <= 0) { /* can not seek */ @@ -394,8 +395,8 @@ URLProtocol ff_async_protocol = { typedef struct TestContext { AVClass*class; -size_t logical_pos; -size_t logical_size; +int64_t logical_pos; +int64_t logical_size; } TestContext; static int async_test_open(URLContext *h, const char *arg, int flags, AVDictionary **options) ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avformat/async: pass internal I/O error
ffmpeg | branch: master | Zhang Rui | Sat Oct 10 17:51:08 2015 +0800| [7dc42c9e657196d5b30cd27edbf8c7f8c6bbc678] | committer: Michael Niedermayer avformat/async: pass internal I/O error av_fifo_generic_write() does not return any error code. Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=7dc42c9e657196d5b30cd27edbf8c7f8c6bbc678 --- libavformat/async.c | 28 ++-- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/libavformat/async.c b/libavformat/async.c index a01673d..9172f5d 100644 --- a/libavformat/async.c +++ b/libavformat/async.c @@ -55,6 +55,7 @@ typedef struct Context { int seek_completed; int64_t seek_ret; +int inner_io_error; int io_error; int io_eof_reached; @@ -85,6 +86,18 @@ static int async_check_interrupt(void *arg) return c->abort_request; } +static int wrapped_url_read(void *src, void *dst, int size) +{ +URLContext *h = src; +Context*c = h->priv_data; +int ret; + +ret = ffurl_read(c->inner, dst, size); +c->inner_io_error = ret < 0 ? ret : 0; + +return ret; +} + static void *async_buffer_task(void *arg) { URLContext *h= arg; @@ -136,14 +149,13 @@ static void *async_buffer_task(void *arg) pthread_mutex_unlock(&c->mutex); to_copy = FFMIN(4096, fifo_space); -ret = av_fifo_generic_write(fifo, c->inner, to_copy, (void *)ffurl_read); +ret = av_fifo_generic_write(fifo, (void *)h, to_copy, (void *)wrapped_url_read); pthread_mutex_lock(&c->mutex); if (ret <= 0) { c->io_eof_reached = 1; -if (ret < 0) { -c->io_error = ret; -} +if (c->inner_io_error < 0) +c->io_error = c->inner_io_error; } pthread_cond_signal(&c->cond_wakeup_main); @@ -270,8 +282,12 @@ static int async_read_internal(URLContext *h, void *dest, int size, int read_com if (to_read <= 0 || !read_complete) break; } else if (c->io_eof_reached) { -if (ret <= 0) -ret = AVERROR_EOF; +if (ret <= 0) { +if (c->io_error) +ret = c->io_error; +else +ret = AVERROR_EOF; +} break; } pthread_cond_signal(&c->cond_wakeup_background); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] fate/async: test error code from underlying protocol
ffmpeg | branch: master | Zhang Rui | Sat Oct 10 17:51:09 2015 +0800| [810fbd8933031d58764190f58dff3fc6986cf866] | committer: Michael Niedermayer fate/async: test error code from underlying protocol Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=810fbd8933031d58764190f58dff3fc6986cf866 --- libavformat/async.c | 41 + tests/ref/fate/async |2 ++ 2 files changed, 43 insertions(+) diff --git a/libavformat/async.c b/libavformat/async.c index 9172f5d..a8c8f54 100644 --- a/libavformat/async.c +++ b/libavformat/async.c @@ -387,6 +387,9 @@ static const AVOption options[] = { {NULL}, }; +#undef D +#undef OFFSET + static const AVClass async_context_class = { .class_name = "Async", .item_name = av_default_item_name, @@ -413,6 +416,9 @@ typedef struct TestContext { AVClass*class; int64_t logical_pos; int64_t logical_size; + +/* options */ +int opt_read_error; } TestContext; static int async_test_open(URLContext *h, const char *arg, int flags, AVDictionary **options) @@ -434,6 +440,9 @@ static int async_test_read(URLContext *h, unsigned char *buf, int size) int i; int read_len = 0; +if (c->opt_read_error) +return c->opt_read_error; + if (c->logical_pos >= c->logical_size) return AVERROR_EOF; @@ -471,9 +480,22 @@ static int64_t async_test_seek(URLContext *h, int64_t pos, int whence) return new_logical_pos; } +#define OFFSET(x) offsetof(TestContext, x) +#define D AV_OPT_FLAG_DECODING_PARAM + +static const AVOption async_test_options[] = { +{ "async-test-read-error", "cause read fail", +OFFSET(opt_read_error), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, .flags = D }, +{NULL}, +}; + +#undef D +#undef OFFSET + static const AVClass async_test_context_class = { .class_name = "Async-Test", .item_name = av_default_item_name, +.option = async_test_options, .version= LIBAVUTIL_VERSION_INT, }; @@ -496,10 +518,14 @@ int main(void) int64_t pos; int64_t read_len; unsigned char buf[4096]; +AVDictionary *opts = NULL; ffurl_register_protocol(&ff_async_protocol); ffurl_register_protocol(&ff_async_test_protocol); +/* + * test normal read + */ ret = ffurl_open(&h, "async:async-test:", AVIO_FLAG_READ, NULL, NULL); printf("open: %d\n", ret); @@ -534,6 +560,9 @@ int main(void) } printf("read: %"PRId64"\n", read_len); +/* + * test normal seek + */ ret = ffurl_read(h, buf, 1); printf("read: %d\n", ret); @@ -568,7 +597,19 @@ int main(void) ret = ffurl_read(h, buf, 1); printf("read: %d\n", ret); +/* + * test read error + */ +ffurl_close(h); +av_dict_set_int(&opts, "async-test-read-error", -1, 0); +ret = ffurl_open(&h, "async:async-test:", AVIO_FLAG_READ, NULL, &opts); +printf("open: %d\n", ret); + +ret = ffurl_read(h, buf, 1); +printf("read: %d\n", ret); + fail: +av_dict_free(&opts); ffurl_close(h); return 0; } diff --git a/tests/ref/fate/async b/tests/ref/fate/async index 3ab5e8c..c4c0b0b 100644 --- a/tests/ref/fate/async +++ b/tests/ref/fate/async @@ -5,3 +5,5 @@ read: 0 seek: 1536 read: 512 read: 0 +open: 0 +read: -1 ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avutil/fifo: add function av_fifo_generic_peek_at()
ffmpeg | branch: master | Zhang Rui | Wed Oct 14 14:20:07 2015 +0800| [87ff61b9abde99d8cdc2a4332b41f69a80eb3d56] | committer: Michael Niedermayer avutil/fifo: add function av_fifo_generic_peek_at() Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=87ff61b9abde99d8cdc2a4332b41f69a80eb3d56 --- libavutil/fifo.c| 61 +++ libavutil/fifo.h| 11 ++ tests/ref/fate/fifo | 27 +++ 3 files changed, 99 insertions(+) diff --git a/libavutil/fifo.c b/libavutil/fifo.c index 1a22708..7bd48a2 100644 --- a/libavutil/fifo.c +++ b/libavutil/fifo.c @@ -148,6 +148,44 @@ int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, return total - size; } +int av_fifo_generic_peek_at(AVFifoBuffer *f, void *dest, int offset, int buf_size, void (*func)(void*, void*, int)) +{ +uint8_t *rptr = f->rptr; + +av_assert2(offset >= 0); + +/* + * *ndx are indexes modulo 2^32, they are intended to overflow, + * to handle *ndx greater than 4gb. + */ +av_assert2(buf_size + (unsigned)offset <= f->wndx - f->rndx); + +if (offset >= f->end - rptr) +rptr += offset - (f->end - f->buffer); +else +rptr += offset; + +while (buf_size > 0) { +int len; + +if (rptr >= f->end) +rptr -= f->end - f->buffer; + +len = FFMIN(f->end - rptr, buf_size); +if (func) +func(dest, rptr, len); +else { +memcpy(dest, rptr, len); +dest = (uint8_t *)dest + len; +} + +buf_size -= len; +rptr += len; +} + +return 0; +} + int av_fifo_generic_peek(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void *, void *, int)) { @@ -221,6 +259,14 @@ int main(void) } printf("\n"); +/* peek_at at FIFO */ +n = av_fifo_size(fifo) / sizeof(int); +for (i = 0; i < n; i++) { +av_fifo_generic_peek_at(fifo, &j, i * sizeof(int), sizeof(j), NULL); +printf("%d: %d\n", i, j); +} +printf("\n"); + /* read data */ for (i = 0; av_fifo_size(fifo) >= sizeof(int); i++) { av_fifo_generic_read(fifo, &j, sizeof(int), NULL); @@ -228,6 +274,21 @@ int main(void) } printf("\n"); +/* test *ndx overflow */ +av_fifo_reset(fifo); +fifo->rndx = fifo->wndx = ~(uint32_t)0 - 5; + +/* fill data */ +for (i = 0; av_fifo_space(fifo) >= sizeof(int); i++) +av_fifo_generic_write(fifo, &i, sizeof(int), NULL); + +/* peek_at at FIFO */ +n = av_fifo_size(fifo) / sizeof(int); +for (i = 0; i < n; i++) { +av_fifo_generic_peek_at(fifo, &j, i * sizeof(int), sizeof(j), NULL); +printf("%d: %d\n", i, j); +} + av_fifo_free(fifo); return 0; diff --git a/libavutil/fifo.h b/libavutil/fifo.h index 0e4070b..dc7bc6f 100644 --- a/libavutil/fifo.h +++ b/libavutil/fifo.h @@ -84,6 +84,17 @@ int av_fifo_size(const AVFifoBuffer *f); int av_fifo_space(const AVFifoBuffer *f); /** + * Feed data at specific position from an AVFifoBuffer to a user-supplied callback. + * Similar as av_fifo_gereric_read but without discarding data. + * @param f AVFifoBuffer to read from + * @param offset offset from current read position + * @param buf_size number of bytes to read + * @param func generic read function + * @param dest data destination + */ +int av_fifo_generic_peek_at(AVFifoBuffer *f, void *dest, int offset, int buf_size, void (*func)(void*, void*, int)); + +/** * Feed data from an AVFifoBuffer to a user-supplied callback. * Similar as av_fifo_gereric_read but without discarding data. * @param f AVFifoBuffer to read from diff --git a/tests/ref/fate/fifo b/tests/ref/fate/fifo index 18a5691..162d754 100644 --- a/tests/ref/fate/fifo +++ b/tests/ref/fate/fifo @@ -24,4 +24,31 @@ 11: 11 12: 12 +0: 0 +1: 1 +2: 2 +3: 3 +4: 4 +5: 5 +6: 6 +7: 7 +8: 8 +9: 9 +10: 10 +11: 11 +12: 12 + 0 1 2 3 4 5 6 7 8 9 10 11 12 +0: 0 +1: 1 +2: 2 +3: 3 +4: 4 +5: 5 +6: 6 +7: 7 +8: 8 +9: 9 +10: 10 +11: 11 +12: 12 ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avformat/async: cache some data for fast seek backward
ffmpeg | branch: master | Zhang Rui | Tue Oct 13 18:30:47 2015 +0800| [6c7f289fab3429706cb47b81ea02963585f0dd05] | committer: Michael Niedermayer avformat/async: cache some data for fast seek backward Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=6c7f289fab3429706cb47b81ea02963585f0dd05 --- libavformat/async.c | 123 +++ 1 file changed, 104 insertions(+), 19 deletions(-) diff --git a/libavformat/async.c b/libavformat/async.c index a8c8f54..9fac84a 100644 --- a/libavformat/async.c +++ b/libavformat/async.c @@ -24,7 +24,6 @@ /** * @TODO * support timeout - * support backward short seek * support work with concatdec, hls */ @@ -43,8 +42,17 @@ #endif #define BUFFER_CAPACITY (4 * 1024 * 1024) +#define READ_BACK_CAPACITY (4 * 1024 * 1024) #define SHORT_SEEK_THRESHOLD(256 * 1024) +typedef struct RingBuffer +{ +AVFifoBuffer *fifo; +int read_back_capacity; + +int read_pos; +} RingBuffer; + typedef struct Context { AVClass*class; URLContext *inner; @@ -61,7 +69,7 @@ typedef struct Context { int64_t logical_pos; int64_t logical_size; -AVFifoBuffer *fifo; +RingBuffer ring; pthread_cond_t cond_wakeup_main; pthread_cond_t cond_wakeup_background; @@ -72,6 +80,73 @@ typedef struct Context { AVIOInterruptCB interrupt_callback; } Context; +static int ring_init(RingBuffer *ring, unsigned int capacity, int read_back_capacity) +{ +memset(ring, 0, sizeof(RingBuffer)); +ring->fifo = av_fifo_alloc(capacity + read_back_capacity); +if (!ring->fifo) +return AVERROR(ENOMEM); + +ring->read_back_capacity = read_back_capacity; +return 0; +} + +static void ring_destroy(RingBuffer *ring) +{ +av_fifo_freep(&ring->fifo); +} + +static void ring_reset(RingBuffer *ring) +{ +av_fifo_reset(ring->fifo); +ring->read_pos = 0; +} + +static int ring_size(RingBuffer *ring) +{ +return av_fifo_size(ring->fifo) - ring->read_pos; +} + +static int ring_space(RingBuffer *ring) +{ +return av_fifo_space(ring->fifo); +} + +static int ring_generic_read(RingBuffer *ring, void *dest, int buf_size, void (*func)(void*, void*, int)) +{ +int ret; + +av_assert2(buf_size <= ring_size(ring)); +ret = av_fifo_generic_peek_at(ring->fifo, dest, ring->read_pos, buf_size, func); +ring->read_pos += buf_size; + +if (ring->read_pos > ring->read_back_capacity) { +av_fifo_drain(ring->fifo, ring->read_pos - ring->read_back_capacity); +ring->read_pos = ring->read_back_capacity; +} + +return ret; +} + +static int ring_generic_write(RingBuffer *ring, void *src, int size, int (*func)(void*, void*, int)) +{ +av_assert2(size <= ring_space(ring)); +return av_fifo_generic_write(ring->fifo, src, size, func); +} + +static int ring_size_of_read_back(RingBuffer *ring) +{ +return ring->read_pos; +} + +static int ring_drain(RingBuffer *ring, int offset) +{ +av_assert2(offset >= -ring_size_of_read_back(ring)); +av_assert2(offset <= -ring_size(ring)); +ring->read_pos += offset; +return 0; +} + static int async_check_interrupt(void *arg) { URLContext *h = arg; @@ -102,7 +177,7 @@ static void *async_buffer_task(void *arg) { URLContext *h= arg; Context *c= h->priv_data; -AVFifoBuffer *fifo = c->fifo; +RingBuffer *ring = &c->ring; int ret = 0; int64_t seek_ret; @@ -132,14 +207,14 @@ static void *async_buffer_task(void *arg) c->seek_ret = seek_ret; c->seek_request = 0; -av_fifo_reset(fifo); +ring_reset(ring); pthread_cond_signal(&c->cond_wakeup_main); pthread_mutex_unlock(&c->mutex); continue; } -fifo_space = av_fifo_space(fifo); +fifo_space = ring_space(ring); if (c->io_eof_reached || fifo_space <= 0) { pthread_cond_signal(&c->cond_wakeup_main); pthread_cond_wait(&c->cond_wakeup_background, &c->mutex); @@ -149,7 +224,7 @@ static void *async_buffer_task(void *arg) pthread_mutex_unlock(&c->mutex); to_copy = FFMIN(4096, fifo_space); -ret = av_fifo_generic_write(fifo, (void *)h, to_copy, (void *)wrapped_url_read); +ret = ring_generic_write(ring, (void *)h, to_copy, (void *)wrapped_url_read); pthread_mutex_lock(&c->mutex); if (ret <= 0) { @@ -173,11 +248,9 @@ static int async_open(URLContext *h, const char *arg, int flags, AVDictionary ** av_strstart(arg, "async:", &arg); -c->fifo = av_fifo_alloc(BUFFER_CAPACITY); -if (!c-&g