From: Jan Sebechlebsky <sebechlebsky...@gmail.com> Signed-off-by: Jan Sebechlebsky <sebechlebsky...@gmail.com> --- Changes from last version: - av_abort_output was renamed to avformat_write_abort
libavformat/tests/fifo_muxer.c | 139 +++++++++++++++++++++++++++++++++++++++++ tests/ref/fate/fifo-muxer-tst | 5 ++ 2 files changed, 144 insertions(+) diff --git a/libavformat/tests/fifo_muxer.c b/libavformat/tests/fifo_muxer.c index 0b5a95e..9801810 100644 --- a/libavformat/tests/fifo_muxer.c +++ b/libavformat/tests/fifo_muxer.c @@ -336,6 +336,137 @@ fail: return ret; } +static int retry_write_frame(AVFormatContext *oc, AVPacket *pkt, int max_retries) +{ + int ret = 0, retry_count = 0; + do { + ret = av_write_frame(oc, pkt); + if (ret == AVERROR(EAGAIN)) { + av_usleep(SLEEPTIME_10_MS); + retry_count++; + } + } while ( ret == AVERROR(EAGAIN) && retry_count < max_retries); + return ret; +} + +static int retry_write_trailer(AVFormatContext *oc, int max_retries) +{ + int ret = 0, retry_count = 0; + do { + ret = av_write_trailer(oc); + if (ret == AVERROR(EAGAIN)) { + av_usleep(SLEEPTIME_10_MS); + retry_count++; + } + } while (ret == AVERROR(EAGAIN) && retry_count < max_retries); + return ret; +} + +static int fifo_nonblock_test(AVFormatContext *oc, AVDictionary **opts, + const FailingMuxerPacketData *pkt_data) +{ + int ret = 0, i; + AVPacket pkt; + + av_init_packet(&pkt); + + oc->flags |= AVFMT_FLAG_NONBLOCK; + + ret = avformat_write_header(oc, opts); + if (ret) { + fprintf(stderr, "Unexpected write_header failure: %s\n", + av_err2str(ret)); + return ret; + } + + for (i = 0; i < 16; i++ ) { + ret = prepare_packet(&pkt, pkt_data, i); + if (ret < 0) { + fprintf(stderr, "Failed to prepare test packet: %s\n", + av_err2str(ret)); + goto fail; + } + ret = retry_write_frame(oc, &pkt, 100); + av_packet_unref(&pkt); + if (ret < 0) + break; + } + + if (ret) { + fprintf(stderr, "Unexpected write_packet error: %s\n", av_err2str(ret)); + goto fail; + } + + ret = retry_write_trailer(oc, 100); + if (ret == AVERROR(EAGAIN)) { + fprintf(stderr, "write_trailer() operation timeout\n"); + goto fail; + } else if (ret < 0) + fprintf(stderr, "Unexpected write_trailer error: %s\n", av_err2str(ret)); + + return ret; +fail: + avformat_write_abort(oc); + return ret; +} + +static int fifo_nonblock_abort_test(AVFormatContext *oc, AVDictionary **opts, + const FailingMuxerPacketData *pkt_data) +{ + int ret = 0, i; + AVPacket pkt; + int64_t start_time, end_time, duration; + + av_init_packet(&pkt); + + oc->flags |= AVFMT_FLAG_NONBLOCK; + + ret = avformat_write_header(oc, opts); + if (ret) { + fprintf(stderr, "Unexpected write header failure: %s\n", + av_err2str(ret)); + goto fail; + } + + av_assert0(pkt_data->sleep_time > 0); + + start_time = av_gettime_relative(); + for (i = 0; i < 16; i++ ) { + ret = prepare_packet(&pkt, pkt_data, i); + if (ret < 0) { + fprintf(stderr, "Failed to prepare test packet: %s\n", + av_err2str(ret)); + goto fail; + } + ret = retry_write_frame(oc, &pkt, 100); + av_packet_unref(&pkt); + if (ret < 0) + break; + } + + if (ret) { + fprintf(stderr, "Unexpected write_packet error: %s\n", av_err2str(ret)); + goto fail; + } + + avformat_write_abort(oc); + + end_time = av_gettime_relative(); + duration = end_time - start_time; + + if (duration > (16*pkt_data->sleep_time)/2 ) { + fprintf(stderr, "Aborting output took too much time: %u us," + " expected time if not aborted %u us\n", + (unsigned) duration, 16*pkt_data->sleep_time); + ret = AVERROR(ETIMEDOUT); + } + + return ret; +fail: + avformat_write_abort(oc); + return ret; +} + typedef struct TestCase { int (*test_func)(AVFormatContext *, AVDictionary **,const FailingMuxerPacketData *pkt_data); const char *test_name; @@ -423,6 +554,14 @@ const TestCase tests[] = { {fifo_overflow_drop_test, "overflow with packet dropping", "queue_size=3:drop_pkts_on_overflow=1", 0, 0, 0, {0, 0, SLEEPTIME_50_MS}}, + /* Simple test of nonblocking mode, the consumer should receive all the packets. */ + {fifo_nonblock_test, "nonblocking mode test", "queue_size=3", + 1, 0, 0, {0, 0, SLEEPTIME_10_MS}}, + + /* Test of terminating fifo muxer with av_abort_format() */ + {fifo_nonblock_abort_test, "abort in nonblocking mode", "queue_size=16", + 0, 0, 0, {0, 0, SLEEPTIME_50_MS}}, + {NULL} }; diff --git a/tests/ref/fate/fifo-muxer-tst b/tests/ref/fate/fifo-muxer-tst index ca7e294..1c18887 100644 --- a/tests/ref/fate/fifo-muxer-tst +++ b/tests/ref/fate/fifo-muxer-tst @@ -9,3 +9,8 @@ pts seen nr: 15 pts seen: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 overflow without packet dropping: ok overflow with packet dropping: ok +flush count: 0 +pts seen nr: 16 +pts seen: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 +nonblocking mode test: ok +abort in nonblocking mode: ok -- 1.9.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel