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) 
  497 typedef struct TestContext {
 
  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,
 
  590     .priv_data_size      = 
sizeof(TestContext),
 
  591     .priv_data_class     = &async_test_context_class,
 
  602     unsigned char buf[4096];
 
  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)
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. 
URLProtocol ff_async_protocol
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. 
#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)
int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options, const char *whitelist)
Create an URLContext for accessing to the resource indicated by url, and open it. ...
int ff_check_interrupt(AVIOInterruptCB *cb)
Check if the user has requested to interrup 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. 
int ffurl_register_protocol(URLProtocol *protocol)
Register the URLProtocol protocol. 
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
Passing this as the "whence" parameter to a seek function causes it to return the filesize without se...
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