46#define BUFFER_CAPACITY (4 * 1024 * 1024)
47#define READ_BACK_CAPACITY (4 * 1024 * 1024)
48#define SHORT_SEEK_THRESHOLD (256 * 1024)
141 *
size = ret > 0 ? ret : 0;
142 c->inner_io_error = ret < 0 ? ret : 0;
144 return c->inner_io_error;
177 if (
c->abort_request)
181 c->abort_request = 1;
183 return c->abort_request;
197 int fifo_space, to_copy;
201 c->io_eof_reached = 1;
208 if (
c->seek_request) {
209 seek_ret =
ffurl_seek(
c->inner,
c->seek_pos,
c->seek_whence);
211 c->io_eof_reached = 0;
216 c->seek_completed = 1;
217 c->seek_ret = seek_ret;
227 if (
c->io_eof_reached || fifo_space <= 0) {
235 to_copy =
FFMIN(4096, fifo_space);
240 c->io_eof_reached = 1;
241 if (
c->inner_io_error < 0)
242 c->io_error =
c->inner_io_error;
265 c->interrupt_callback =
h->interrupt_callback;
273 h->is_streamed =
c->inner->is_streamed;
286 goto cond_wakeup_main_fail;
293 goto cond_wakeup_background_fail;
307cond_wakeup_background_fail:
309cond_wakeup_main_fail:
325 c->abort_request = 1;
346 int read_complete = !dest;
352 while (to_read > 0) {
363 dest = (uint8_t *)dest + to_copy;
364 c->logical_pos += to_copy;
366 ret =
size - to_read;
368 if (to_read <= 0 || !read_complete)
370 }
else if (
c->io_eof_reached) {
401 int fifo_size_of_read_back;
405 return c->logical_size;
406 }
else if (whence == SEEK_CUR) {
408 new_logical_pos =
pos +
c->logical_pos;
409 }
else if (whence == SEEK_SET){
411 new_logical_pos =
pos;
415 if (new_logical_pos < 0)
420 if (new_logical_pos ==
c->logical_pos) {
422 return c->logical_pos;
423 }
else if ((new_logical_pos >= (
c->logical_pos - fifo_size_of_read_back)) &&
425 int pos_delta = (int)(new_logical_pos -
c->logical_pos);
428 new_logical_pos, (
int)
c->logical_pos,
429 (
int)(new_logical_pos -
c->logical_pos),
fifo_size);
437 c->logical_pos = new_logical_pos;
440 return c->logical_pos;
441 }
else if (
c->logical_size <= 0) {
444 }
else if (new_logical_pos >
c->logical_size) {
452 c->seek_pos = new_logical_pos;
453 c->seek_whence = SEEK_SET;
454 c->seek_completed = 0;
462 if (
c->seek_completed) {
463 if (
c->seek_ret >= 0)
464 c->logical_pos =
c->seek_ret;
477#define OFFSET(x) offsetof(AsyncContext, x)
478#define D AV_OPT_FLAG_DECODING_PARAM
488 .class_name =
"Async",
506#define TEST_SEEK_POS (1536)
507#define TEST_STREAM_SIZE (2048)
522 c->logical_size = TEST_STREAM_SIZE;
537 if (
c->opt_read_error)
538 return c->opt_read_error;
540 if (
c->logical_pos >=
c->logical_size)
544 buf[
i] =
c->logical_pos & 0xFF;
549 if (
c->logical_pos >=
c->logical_size)
562 return c->logical_size;
563 }
else if (whence == SEEK_CUR) {
564 new_logical_pos =
pos +
c->logical_pos;
565 }
else if (whence == SEEK_SET){
566 new_logical_pos =
pos;
570 if (new_logical_pos < 0)
573 c->logical_pos = new_logical_pos;
574 return new_logical_pos;
577#define OFFSET(x) offsetof(TestContext, x)
578#define D AV_OPT_FLAG_DECODING_PARAM
580static const AVOption async_test_options[] = {
581 {
"async-test-read-error",
"cause read fail",
589static const AVClass async_test_context_class = {
590 .class_name =
"Async-Test",
592 .option = async_test_options,
597 .name =
"async-test",
598 .url_open2 = async_test_open,
599 .url_read = async_test_read,
600 .url_seek = async_test_seek,
601 .url_close = async_test_close,
603 .priv_data_class = &async_test_context_class,
614 unsigned char buf[4096];
618 ffurl_register_protocol(&ff_async_test_protocol);
625 printf(
"open: %d\n", ret);
644 for (
i = 0;
i < ret; ++
i) {
645 if (buf[
i] != (
pos & 0xFF)) {
646 printf(
"read-mismatch: actual %d, expecting %d, at %"PRId64
"\n",
647 (
int)buf[
i], (
int)(
pos & 0xFF),
pos);
656 printf(
"read: %"PRId64
"\n", read_len);
662 printf(
"read: %d\n", ret);
678 for (
i = 0;
i < ret; ++
i) {
679 if (buf[
i] != (
pos & 0xFF)) {
680 printf(
"read-mismatch: actual %d, expecting %d, at %"PRId64
"\n",
681 (
int)buf[
i], (
int)(
pos & 0xFF),
pos);
690 printf(
"read: %"PRId64
"\n", read_len);
693 printf(
"read: %d\n", ret);
702 printf(
"open: %d\n", ret);
705 printf(
"read: %d\n", ret);
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
static AVDictionary * opts
static int async_check_interrupt(void *arg)
static const AVClass async_context_class
static int ring_drain(RingBuffer *ring, int offset)
static void * async_buffer_task(void *arg)
static int async_read(URLContext *h, unsigned char *buf, int size)
static int ring_space(RingBuffer *ring)
const URLProtocol ff_async_protocol
#define READ_BACK_CAPACITY
#define BUFFER_CAPACITY
@TODO support timeout support work with concatdec, hls
static void ring_reset(RingBuffer *ring)
static int async_open(URLContext *h, const char *arg, int flags, AVDictionary **options)
static int async_close(URLContext *h)
static void ring_destroy(RingBuffer *ring)
#define SHORT_SEEK_THRESHOLD
static int wrapped_url_read(void *src, void *dst, size_t *size)
static int ring_read(RingBuffer *ring, void *dest, int buf_size)
static int ring_init(RingBuffer *ring, unsigned int capacity, int read_back_capacity)
static int ring_size_of_read_back(RingBuffer *ring)
static int ring_write(RingBuffer *ring, URLContext *h, size_t size)
static int ring_size(RingBuffer *ring)
static int64_t async_seek(URLContext *h, int64_t pos, int whence)
static int async_read_internal(URLContext *h, void *dest, int size)
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
int ff_check_interrupt(AVIOInterruptCB *cb)
Check if the user has requested to interrupt a blocking function associated with cb.
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.
int64_t ffurl_size(URLContext *h)
Return the filesize of the resource accessed by h, AVERROR(ENOSYS) if the operation is not supported ...
int ffurl_closep(URLContext **hh)
Close the resource accessed by the URLContext h, and free the memory used by it.
int ffurl_close(URLContext *h)
#define AVIO_FLAG_READ
read-only
#define AVSEEK_SIZE
Passing this as the "whence" parameter to a seek function causes it to return the filesize without se...
#define flags(name, subs,...)
#define i(width, name, range_min, range_max)
__device__ int printf(const char *,...)
@ AV_OPT_TYPE_INT
Underlying C type is int.
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
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.
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
#define AVERROR_EOF
End of file.
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
AVFifo * av_fifo_alloc2(size_t nb_elems, size_t elem_size, unsigned int flags)
Allocate and initialize an AVFifo with a given element size.
void av_fifo_freep2(AVFifo **f)
Free an AVFifo and reset pointer to NULL.
void av_fifo_reset2(AVFifo *f)
size_t av_fifo_can_write(const AVFifo *f)
size_t av_fifo_can_read(const AVFifo *f)
int av_fifo_peek(const AVFifo *f, void *buf, size_t nb_elems, size_t offset)
Read data from a FIFO without modifying FIFO state.
int av_fifo_write_from_cb(AVFifo *f, AVFifoCB read_cb, void *opaque, size_t *nb_elems)
Write data from a user-provided callback into a FIFO.
void av_fifo_drain2(AVFifo *f, size_t size)
Discard the specified amount of data from an AVFifo.
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
const char * av_default_item_name(void *ptr)
Return the context name.
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
#define LIBAVUTIL_VERSION_INT
static int ff_thread_setname(const char *name)
static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
static av_always_inline int pthread_mutex_lock(pthread_mutex_t *mutex)
static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
static av_always_inline int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Describe the class of an AVClass context structure.
Callback for checking whether to abort blocking functions.
pthread_cond_t cond_wakeup_background
pthread_cond_t cond_wakeup_main
pthread_t async_buffer_thread
AVIOInterruptCB interrupt_callback
unbuffered private I/O API
static 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.
static int ffurl_read(URLContext *h, uint8_t *buf, int size)
Read up to size bytes from the resource accessed by h, and store the read bytes in buf.