44 #define BUFFER_CAPACITY (4 * 1024 * 1024)
45 #define READ_BACK_CAPACITY (4 * 1024 * 1024)
46 #define SHORT_SEEK_THRESHOLD (256 * 1024)
185 int fifo_space, to_copy;
223 to_copy =
FFMIN(4096, fifo_space);
272 goto cond_wakeup_main_fail;
278 goto cond_wakeup_background_fail;
291 cond_wakeup_background_fail:
293 cond_wakeup_main_fail:
327 void (*
func)(
void*,
void*,
int))
336 while (to_read > 0) {
337 int fifo_size, to_copy;
343 to_copy =
FFMIN(to_read, fifo_size);
347 dest = (
uint8_t *)dest + to_copy;
350 ret = size - to_read;
352 if (to_read <= 0 || !read_complete)
387 int64_t new_logical_pos;
389 int fifo_size_of_read_back;
394 }
else if (whence == SEEK_CUR) {
397 }
else if (whence == SEEK_SET){
399 new_logical_pos = pos;
403 if (new_logical_pos < 0)
411 }
else if ((new_logical_pos >= (c->
logical_pos - fifo_size_of_read_back)) &&
413 int pos_delta = (int)(new_logical_pos - c->
logical_pos);
417 (
int)(new_logical_pos - c->
logical_pos), fifo_size);
465 #define OFFSET(x) offsetof(Context, x)
466 #define D AV_OPT_FLAG_DECODING_PARAM
488 .priv_data_size =
sizeof(
Context),
489 .priv_data_class = &async_context_class,
494 #define TEST_SEEK_POS (1536)
495 #define TEST_STREAM_SIZE (2048)
500 int64_t logical_size;
510 c->logical_size = TEST_STREAM_SIZE;
519 static int async_test_read(
URLContext *h,
unsigned char *
buf,
int size)
525 if (c->opt_read_error)
526 return c->opt_read_error;
528 if (c->logical_pos >= c->logical_size)
531 for (i = 0; i <
size; ++i) {
532 buf[i] = c->logical_pos & 0xFF;
537 if (c->logical_pos >= c->logical_size)
544 static int64_t async_test_seek(
URLContext *h, int64_t pos,
int whence)
547 int64_t new_logical_pos;
550 return c->logical_size;
551 }
else if (whence == SEEK_CUR) {
552 new_logical_pos = pos + c->logical_pos;
553 }
else if (whence == SEEK_SET){
554 new_logical_pos = pos;
558 if (new_logical_pos < 0)
561 c->logical_pos = new_logical_pos;
562 return new_logical_pos;
565 #define OFFSET(x) offsetof(TestContext, x)
566 #define D AV_OPT_FLAG_DECODING_PARAM
568 static const AVOption async_test_options[] = {
569 {
"async-test-read-error",
"cause read fail",
577 static const AVClass async_test_context_class = {
580 .option = async_test_options,
585 .
name =
"async-test",
586 .url_open2 = async_test_open,
587 .url_read = async_test_read,
588 .url_seek = async_test_seek,
589 .url_close = async_test_close,
591 .priv_data_class = &async_test_context_class,
602 unsigned char buf[4096];
605 ffurl_register_protocol(&ff_async_protocol);
606 ffurl_register_protocol(&ff_async_test_protocol);
612 printf(
"open: %d\n", ret);
615 printf(
"size: %"PRId64
"\n", size);
622 printf(
"read-error: AVERROR_EOF at %"PRId64
"\n",
ffurl_seek(h, 0, SEEK_CUR));
628 printf(
"read-error: %d at %"PRId64
"\n", ret,
ffurl_seek(h, 0, SEEK_CUR));
631 for (i = 0; i < ret; ++i) {
632 if (buf[i] != (pos & 0xFF)) {
633 printf(
"read-mismatch: actual %d, expecting %d, at %"PRId64
"\n",
634 (
int)buf[i], (
int)(pos & 0xFF), pos);
643 printf(
"read: %"PRId64
"\n", read_len);
649 printf(
"read: %d\n", ret);
652 printf(
"seek: %"PRId64
"\n", pos);
662 printf(
"read-error: %d at %"PRId64
"\n", ret,
ffurl_seek(h, 0, SEEK_CUR));
665 for (i = 0; i < ret; ++i) {
666 if (buf[i] != (pos & 0xFF)) {
667 printf(
"read-mismatch: actual %d, expecting %d, at %"PRId64
"\n",
668 (
int)buf[i], (
int)(pos & 0xFF), pos);
677 printf(
"read: %"PRId64
"\n", read_len);
680 printf(
"read: %d\n", ret);
688 printf(
"open: %d\n", ret);
691 printf(
"read: %d\n", ret);
static int wrapped_url_read(void *src, void *dst, int size)
#define READ_BACK_CAPACITY
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options, const char *whitelist, const char *blacklist, URLContext *parent)
Create an URLContext for accessing to the resource indicated by url, and open it. ...
static int async_check_interrupt(void *arg)
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
#define LIBAVUTIL_VERSION_INT
static int async_read_internal(URLContext *h, void *dest, int size, int read_complete, void(*func)(void *, void *, int))
int is_streamed
true if streamed (no seek possible), default = false
AVIOInterruptCB interrupt_callback
#define AVIO_FLAG_READ
read-only
static const AVClass async_context_class
static int ring_size(RingBuffer *ring)
static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
static int ring_space(RingBuffer *ring)
static const AVOption options[]
int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int(*func)(void *, void *, int))
Feed data from a user-supplied callback to an AVFifoBuffer.
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
static int ring_drain(RingBuffer *ring, int offset)
static int ring_generic_write(RingBuffer *ring, void *src, int size, int(*func)(void *, void *, int))
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
const URLProtocol ff_async_protocol
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
int av_fifo_space(const AVFifoBuffer *f)
Return the amount of space in bytes in the AVFifoBuffer, that is the amount of data you can write int...
#define SHORT_SEEK_THRESHOLD
static int ring_generic_read(RingBuffer *ring, void *dest, int buf_size, void(*func)(void *, void *, int))
#define AVERROR_EOF
End of file.
static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
static void * async_buffer_task(void *arg)
Callback for checking whether to abort blocking functions.
static int64_t async_seek(URLContext *h, int64_t pos, int whence)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
const char * protocol_whitelist
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values. ...
simple assert() macros that are a bit more flexible than ISO C assert().
static void fifo_do_not_copy_func(void *dest, void *src, int size)
static const uint8_t offset[127][2]
static int async_open(URLContext *h, const char *arg, int flags, AVDictionary **options)
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
AVIOInterruptCB interrupt_callback
static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
static av_always_inline int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
const char * protocol_blacklist
int ff_check_interrupt(AVIOInterruptCB *cb)
Check if the user has requested to interrupt a blocking function associated with cb.
int av_fifo_size(const AVFifoBuffer *f)
Return the amount of data in bytes in the AVFifoBuffer, that is the amount of data you can read from ...
int av_fifo_generic_peek_at(AVFifoBuffer *f, void *dest, int offset, int buf_size, void(*func)(void *, void *, int))
Feed data at specific position from an AVFifoBuffer to a user-supplied callback.
pthread_t async_buffer_thread
int64_t ffurl_size(URLContext *h)
Return the filesize of the resource accessed by h, AVERROR(ENOSYS) if the operation is not supported ...
a very simple circular buffer FIFO implementation
Describe the class of an AVClass context structure.
int(* func)(AVBPrint *dst, const char *in, const char *arg)
static void ring_destroy(RingBuffer *ring)
static int ring_size_of_read_back(RingBuffer *ring)
static int ring_init(RingBuffer *ring, unsigned int capacity, int read_back_capacity)
int ffurl_close(URLContext *h)
static void ring_reset(RingBuffer *ring)
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
int64_t ffurl_seek(URLContext *h, int64_t pos, int whence)
Change the position that will be used by the next read/write operation on the resource accessed by h...
int ffurl_open(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options)
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set that converts the value to a string and stores it...
static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
#define AVSEEK_SIZE
ORing this as the "whence" parameter to a seek function causes it to return the filesize without seek...
pthread_cond_t cond_wakeup_main
AVFifoBuffer * av_fifo_alloc(unsigned int size)
Initialize an AVFifoBuffer.
static int async_close(URLContext *h)
static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
#define BUFFER_CAPACITY
support timeout support work with concatdec, hls
unbuffered private I/O API
void av_fifo_freep(AVFifoBuffer **f)
Free an AVFifoBuffer and reset pointer to NULL.
static av_always_inline int pthread_mutex_lock(pthread_mutex_t *mutex)
int main(int argc, char **argv)
void av_fifo_reset(AVFifoBuffer *f)
Reset the AVFifoBuffer to the state right after av_fifo_alloc, in particular it is emptied...
void av_fifo_drain(AVFifoBuffer *f, int size)
Discard data from the FIFO.
static int async_read(URLContext *h, unsigned char *buf, int size)
int ffurl_read(URLContext *h, unsigned char *buf, int size)
Read up to size bytes from the resource accessed by h, and store the read bytes in buf...
pthread_cond_t cond_wakeup_background