--- libavformat/Makefile | 3 +- libavformat/async.c | 171 +++++++++++++++++++++++++++++++++++++++++++++ tests/fate/libavformat.mak | 4 ++ tests/ref/fate/async | 7 ++ 4 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 tests/ref/fate/async
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("read-mismatch: actual %d, expecting %d, at %"PRId64"\n", + (int)buf[i], (int)(pos & 0xFF), pos); + break; + } + pos++; + } + } + + read_len += ret; + } + printf("read: %"PRId64"\n", read_len); + + ret = ffurl_read(h, buf, 1); + printf("read: %d\n", ret); + + pos = ffurl_seek(h, TEST_SEEK_POS, SEEK_SET); + printf("seek: %"PRId64"\n", pos); + + read_len = 0; + while (1) { + ret = ffurl_read(h, buf, sizeof(buf)); + if (ret == AVERROR_EOF) + 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("read-mismatch: actual %d, expecting %d, at %"PRId64"\n", + (int)buf[i], (int)(pos & 0xFF), pos); + break; + } + pos++; + } + } + + read_len += ret; + } + printf("read: %"PRId64"\n", read_len); + + ret = ffurl_read(h, buf, 1); + printf("read: %d\n", ret); + +fail: + ffurl_close(h); + return 0; +} + +#endif diff --git a/tests/fate/libavformat.mak b/tests/fate/libavformat.mak index a9c02bc..4102ce8 100644 --- a/tests/fate/libavformat.mak +++ b/tests/fate/libavformat.mak @@ -1,3 +1,7 @@ +FATE_LIBAVFORMAT-$(HAVE_PTHREADS) += fate-async +fate-async: libavformat/async-test$(EXESUF) +fate-async: CMD = run libavformat/async-test + FATE_LIBAVFORMAT-$(CONFIG_NETWORK) += fate-noproxy fate-noproxy: libavformat/noproxy-test$(EXESUF) fate-noproxy: CMD = run libavformat/noproxy-test diff --git a/tests/ref/fate/async b/tests/ref/fate/async new file mode 100644 index 0000000..3ab5e8c --- /dev/null +++ b/tests/ref/fate/async @@ -0,0 +1,7 @@ +open: 0 +size: 2048 +read: 2048 +read: 0 +seek: 1536 +read: 512 +read: 0 -- 2.0.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel