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);
274 goto cond_wakeup_main_fail;
281 goto cond_wakeup_background_fail;
295 cond_wakeup_background_fail:
297 cond_wakeup_main_fail:
331 void (*
func)(
void*,
void*,
int))
340 while (to_read > 0) {
341 int fifo_size, to_copy;
347 to_copy =
FFMIN(to_read, fifo_size);
351 dest = (
uint8_t *)dest + to_copy;
354 ret = size - to_read;
356 if (to_read <= 0 || !read_complete)
391 int64_t new_logical_pos;
393 int fifo_size_of_read_back;
398 }
else if (whence == SEEK_CUR) {
401 }
else if (whence == SEEK_SET){
403 new_logical_pos =
pos;
407 if (new_logical_pos < 0)
415 }
else if ((new_logical_pos >= (c->
logical_pos - fifo_size_of_read_back)) &&
421 (
int)(new_logical_pos - c->
logical_pos), fifo_size);
469 #define OFFSET(x) offsetof(Context, x) 470 #define D AV_OPT_FLAG_DECODING_PARAM 492 .priv_data_size =
sizeof(
Context),
493 .priv_data_class = &async_context_class,
498 #define TEST_SEEK_POS (1536) 499 #define TEST_STREAM_SIZE (2048) 504 int64_t logical_size;
514 c->logical_size = TEST_STREAM_SIZE;
523 static int async_test_read(
URLContext *h,
unsigned char *buf,
int size)
529 if (c->opt_read_error)
530 return c->opt_read_error;
532 if (c->logical_pos >= c->logical_size)
535 for (i = 0; i <
size; ++
i) {
536 buf[
i] = c->logical_pos & 0xFF;
541 if (c->logical_pos >= c->logical_size)
548 static int64_t async_test_seek(
URLContext *h, int64_t
pos,
int whence)
551 int64_t new_logical_pos;
554 return c->logical_size;
555 }
else if (whence == SEEK_CUR) {
556 new_logical_pos = pos + c->logical_pos;
557 }
else if (whence == SEEK_SET){
558 new_logical_pos =
pos;
562 if (new_logical_pos < 0)
565 c->logical_pos = new_logical_pos;
566 return new_logical_pos;
569 #define OFFSET(x) offsetof(TestContext, x) 570 #define D AV_OPT_FLAG_DECODING_PARAM 572 static const AVOption async_test_options[] = {
573 {
"async-test-read-error",
"cause read fail",
581 static const AVClass async_test_context_class = {
584 .option = async_test_options,
589 .
name =
"async-test",
590 .url_open2 = async_test_open,
591 .url_read = async_test_read,
592 .url_seek = async_test_seek,
593 .url_close = async_test_close,
595 .priv_data_class = &async_test_context_class,
606 unsigned char buf[4096];
609 ffurl_register_protocol(&ff_async_protocol);
610 ffurl_register_protocol(&ff_async_test_protocol);
617 printf(
"open: %d\n", ret);
620 printf(
"size: %"PRId64
"\n", size);
627 printf(
"read-error: AVERROR_EOF at %"PRId64
"\n",
ffurl_seek(h, 0, SEEK_CUR));
636 for (i = 0; i <
ret; ++
i) {
637 if (buf[i] != (pos & 0xFF)) {
638 printf(
"read-mismatch: actual %d, expecting %d, at %"PRId64
"\n",
639 (
int)buf[i], (
int)(pos & 0xFF), pos);
648 printf(
"read: %"PRId64
"\n", read_len);
654 printf(
"read: %d\n", ret);
657 printf(
"seek: %"PRId64
"\n", pos);
670 for (i = 0; i <
ret; ++
i) {
671 if (buf[i] != (pos & 0xFF)) {
672 printf(
"read-mismatch: actual %d, expecting %d, at %"PRId64
"\n",
673 (
int)buf[i], (
int)(pos & 0xFF), pos);
682 printf(
"read: %"PRId64
"\n", read_len);
685 printf(
"read: %d\n", ret);
694 printf(
"open: %d\n", ret);
697 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. ...
#define pthread_mutex_lock(a)
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
const char * av_default_item_name(void *ptr)
Return the context name.
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.
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
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
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 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)
int main(int argc, char *argv[])
#define pthread_mutex_unlock(a)
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
int ffurl_closep(URLContext **hh)
Close the resource accessed by the URLContext h, and free the memory used by it.
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
int(* func)(AVBPrint *dst, const char *in, const char *arg)
Describe the class of an AVClass context structure.
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)
#define flags(name, subs,...)
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 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)
printf("static const uint8_t my_array[100] = {\n")
#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.
void av_fifo_reset(AVFifoBuffer *f)
Reset the AVFifoBuffer to the state right after av_fifo_alloc, in particular it is emptied...
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
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