Go to the documentation of this file.
44 #define BUFFER_CAPACITY (4 * 1024 * 1024)
45 #define READ_BACK_CAPACITY (4 * 1024 * 1024)
46 #define SHORT_SEEK_THRESHOLD (256 * 1024)
140 c->inner_io_error =
ret < 0 ?
ret : 0;
142 return c->inner_io_error;
175 if (
c->abort_request)
179 c->abort_request = 1;
181 return c->abort_request;
195 int fifo_space, to_copy;
199 c->io_eof_reached = 1;
206 if (
c->seek_request) {
207 seek_ret =
ffurl_seek(
c->inner,
c->seek_pos,
c->seek_whence);
209 c->io_eof_reached = 0;
214 c->seek_completed = 1;
215 c->seek_ret = seek_ret;
225 if (
c->io_eof_reached || fifo_space <= 0) {
233 to_copy =
FFMIN(4096, fifo_space);
238 c->io_eof_reached = 1;
239 if (
c->inner_io_error < 0)
240 c->io_error =
c->inner_io_error;
263 c->interrupt_callback =
h->interrupt_callback;
271 h->is_streamed =
c->inner->is_streamed;
284 goto cond_wakeup_main_fail;
291 goto cond_wakeup_background_fail;
305 cond_wakeup_background_fail:
307 cond_wakeup_main_fail:
323 c->abort_request = 1;
344 int read_complete = !dest;
350 while (to_read > 0) {
361 dest = (uint8_t *)dest + to_copy;
362 c->logical_pos += to_copy;
366 if (to_read <= 0 || !read_complete)
368 }
else if (
c->io_eof_reached) {
399 int fifo_size_of_read_back;
403 return c->logical_size;
404 }
else if (whence == SEEK_CUR) {
406 new_logical_pos =
pos +
c->logical_pos;
407 }
else if (whence == SEEK_SET){
409 new_logical_pos =
pos;
413 if (new_logical_pos < 0)
418 if (new_logical_pos ==
c->logical_pos) {
420 return c->logical_pos;
421 }
else if ((new_logical_pos >= (
c->logical_pos - fifo_size_of_read_back)) &&
423 int pos_delta = (int)(new_logical_pos -
c->logical_pos);
426 new_logical_pos, (
int)
c->logical_pos,
427 (
int)(new_logical_pos -
c->logical_pos),
fifo_size);
435 c->logical_pos = new_logical_pos;
438 return c->logical_pos;
439 }
else if (
c->logical_size <= 0) {
442 }
else if (new_logical_pos >
c->logical_size) {
450 c->seek_pos = new_logical_pos;
451 c->seek_whence = SEEK_SET;
452 c->seek_completed = 0;
460 if (
c->seek_completed) {
461 if (
c->seek_ret >= 0)
462 c->logical_pos =
c->seek_ret;
475 #define OFFSET(x) offsetof(AsyncContext, x)
476 #define D AV_OPT_FLAG_DECODING_PARAM
504 #define TEST_SEEK_POS (1536)
505 #define TEST_STREAM_SIZE (2048)
520 c->logical_size = TEST_STREAM_SIZE;
529 static int async_test_read(
URLContext *
h,
unsigned char *buf,
int size)
535 if (
c->opt_read_error)
536 return c->opt_read_error;
538 if (
c->logical_pos >=
c->logical_size)
542 buf[
i] =
c->logical_pos & 0xFF;
547 if (
c->logical_pos >=
c->logical_size)
560 return c->logical_size;
561 }
else if (whence == SEEK_CUR) {
562 new_logical_pos =
pos +
c->logical_pos;
563 }
else if (whence == SEEK_SET){
564 new_logical_pos =
pos;
568 if (new_logical_pos < 0)
571 c->logical_pos = new_logical_pos;
572 return new_logical_pos;
575 #define OFFSET(x) offsetof(TestContext, x)
576 #define D AV_OPT_FLAG_DECODING_PARAM
578 static const AVOption async_test_options[] = {
579 {
"async-test-read-error",
"cause read fail",
587 static const AVClass async_test_context_class = {
590 .option = async_test_options,
595 .
name =
"async-test",
596 .url_open2 = async_test_open,
597 .url_read = async_test_read,
598 .url_seek = async_test_seek,
599 .url_close = async_test_close,
601 .priv_data_class = &async_test_context_class,
612 unsigned char buf[4096];
616 ffurl_register_protocol(&ff_async_test_protocol);
642 for (
i = 0;
i <
ret; ++
i) {
643 if (buf[
i] != (
pos & 0xFF)) {
644 printf(
"read-mismatch: actual %d, expecting %d, at %"PRId64
"\n",
645 (
int)buf[
i], (
int)(
pos & 0xFF),
pos);
654 printf(
"read: %"PRId64
"\n", read_len);
676 for (
i = 0;
i <
ret; ++
i) {
677 if (buf[
i] != (
pos & 0xFF)) {
678 printf(
"read-mismatch: actual %d, expecting %d, at %"PRId64
"\n",
679 (
int)buf[
i], (
int)(
pos & 0xFF),
pos);
688 printf(
"read: %"PRId64
"\n", read_len);
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.
void av_fifo_drain2(AVFifo *f, size_t size)
Discard the specified amount of data from an AVFifo.
static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
size_t av_fifo_can_write(const AVFifo *f)
static int async_close(URLContext *h)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
static int ring_space(RingBuffer *ring)
#define AVERROR_EOF
End of file.
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
static void * async_buffer_task(void *arg)
static const AVOption options[]
static int ring_write(RingBuffer *ring, URLContext *h, size_t size)
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.
#define AVSEEK_SIZE
ORing this as the "whence" parameter to a seek function causes it to return the filesize without seek...
int ffurl_close(URLContext *h)
static int ring_size(RingBuffer *ring)
Callback for checking whether to abort blocking functions.
int ff_check_interrupt(AVIOInterruptCB *cb)
Check if the user has requested to interrupt a blocking function associated with cb.
#define BUFFER_CAPACITY
@TODO support timeout support work with concatdec, hls
static const AVClass async_context_class
#define READ_BACK_CAPACITY
static int async_check_interrupt(void *arg)
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
pthread_t async_buffer_thread
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 void ring_destroy(RingBuffer *ring)
static int wrapped_url_read(void *src, void *dst, size_t *size)
static int ring_init(RingBuffer *ring, unsigned int capacity, int read_back_capacity)
pthread_cond_t cond_wakeup_main
#define SHORT_SEEK_THRESHOLD
static int ring_read(RingBuffer *ring, void *dest, int buf_size)
static av_always_inline int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
#define LIBAVUTIL_VERSION_INT
Describe the class of an AVClass context structure.
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.
const char * av_default_item_name(void *ptr)
Return the context name.
size_t av_fifo_can_read(const AVFifo *f)
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
#define pthread_mutex_unlock(a)
void av_fifo_reset2(AVFifo *f)
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
static int async_open(URLContext *h, const char *arg, int flags, AVDictionary **options)
printf("static const uint8_t my_array[100] = {\n")
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
static int async_read(URLContext *h, unsigned char *buf, int size)
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
#define i(width, name, range_min, range_max)
AVIOInterruptCB interrupt_callback
int ffurl_closep(URLContext **hh)
Close the resource accessed by the URLContext h, and free the memory used by it.
static int64_t async_seek(URLContext *h, int64_t pos, int whence)
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
pthread_cond_t cond_wakeup_background
static int async_read_internal(URLContext *h, void *dest, int size)
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.
const URLProtocol ff_async_protocol
static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
@ AV_OPT_TYPE_INT
Underlying C type is int.
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
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 AVIO_FLAG_READ
read-only
static void ring_reset(RingBuffer *ring)
static int ring_size_of_read_back(RingBuffer *ring)
#define flags(name, subs,...)
int64_t ffurl_size(URLContext *h)
Return the filesize of the resource accessed by h, AVERROR(ENOSYS) if the operation is not supported ...
void av_fifo_freep2(AVFifo **f)
Free an AVFifo and reset pointer to NULL.
static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
static int ring_drain(RingBuffer *ring, int offset)
#define pthread_mutex_lock(a)
static int ff_thread_setname(const char *name)
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.