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;
169 if (
c->abort_request)
173 c->abort_request = 1;
175 return c->abort_request;
187 int fifo_space, to_copy;
191 c->io_eof_reached = 1;
198 if (
c->seek_request) {
199 seek_ret =
ffurl_seek(
c->inner,
c->seek_pos,
c->seek_whence);
201 c->io_eof_reached = 0;
206 c->seek_completed = 1;
207 c->seek_ret = seek_ret;
217 if (
c->io_eof_reached || fifo_space <= 0) {
225 to_copy =
FFMIN(4096, fifo_space);
230 c->io_eof_reached = 1;
231 if (
c->inner_io_error < 0)
232 c->io_error =
c->inner_io_error;
255 c->interrupt_callback =
h->interrupt_callback;
263 h->is_streamed =
c->inner->is_streamed;
276 goto cond_wakeup_main_fail;
283 goto cond_wakeup_background_fail;
297 cond_wakeup_background_fail:
299 cond_wakeup_main_fail:
315 c->abort_request = 1;
336 int read_complete = !dest;
342 while (to_read > 0) {
343 int fifo_size, to_copy;
349 to_copy =
FFMIN(to_read, fifo_size);
353 dest = (uint8_t *)dest + to_copy;
354 c->logical_pos += to_copy;
358 if (to_read <= 0 || !read_complete)
360 }
else if (
c->io_eof_reached) {
389 int64_t new_logical_pos;
391 int fifo_size_of_read_back;
395 return c->logical_size;
396 }
else if (whence == SEEK_CUR) {
398 new_logical_pos =
pos +
c->logical_pos;
399 }
else if (whence == SEEK_SET){
401 new_logical_pos =
pos;
405 if (new_logical_pos < 0)
410 if (new_logical_pos ==
c->logical_pos) {
412 return c->logical_pos;
413 }
else if ((new_logical_pos >= (
c->logical_pos - fifo_size_of_read_back)) &&
415 int pos_delta = (
int)(new_logical_pos -
c->logical_pos);
418 new_logical_pos, (
int)
c->logical_pos,
419 (
int)(new_logical_pos -
c->logical_pos), fifo_size);
427 c->logical_pos = new_logical_pos;
430 return c->logical_pos;
431 }
else if (
c->logical_size <= 0) {
434 }
else if (new_logical_pos >
c->logical_size) {
442 c->seek_pos = new_logical_pos;
443 c->seek_whence = SEEK_SET;
444 c->seek_completed = 0;
452 if (
c->seek_completed) {
453 if (
c->seek_ret >= 0)
454 c->logical_pos =
c->seek_ret;
467 #define OFFSET(x) offsetof(Context, x)
468 #define D AV_OPT_FLAG_DECODING_PARAM
490 .priv_data_size =
sizeof(
Context),
496 #define TEST_SEEK_POS (1536)
497 #define TEST_STREAM_SIZE (2048)
502 int64_t logical_size;
512 c->logical_size = TEST_STREAM_SIZE;
521 static int async_test_read(
URLContext *
h,
unsigned char *buf,
int size)
527 if (
c->opt_read_error)
528 return c->opt_read_error;
530 if (
c->logical_pos >=
c->logical_size)
534 buf[
i] =
c->logical_pos & 0xFF;
539 if (
c->logical_pos >=
c->logical_size)
546 static int64_t async_test_seek(
URLContext *
h, int64_t
pos,
int whence)
549 int64_t new_logical_pos;
552 return c->logical_size;
553 }
else if (whence == SEEK_CUR) {
554 new_logical_pos =
pos +
c->logical_pos;
555 }
else if (whence == SEEK_SET){
556 new_logical_pos =
pos;
560 if (new_logical_pos < 0)
563 c->logical_pos = new_logical_pos;
564 return new_logical_pos;
567 #define OFFSET(x) offsetof(TestContext, x)
568 #define D AV_OPT_FLAG_DECODING_PARAM
570 static const AVOption async_test_options[] = {
571 {
"async-test-read-error",
"cause read fail",
579 static const AVClass async_test_context_class = {
582 .option = async_test_options,
587 .
name =
"async-test",
588 .url_open2 = async_test_open,
589 .url_read = async_test_read,
590 .url_seek = async_test_seek,
591 .url_close = async_test_close,
593 .priv_data_class = &async_test_context_class,
604 unsigned char buf[4096];
608 ffurl_register_protocol(&ff_async_test_protocol);
634 for (
i = 0;
i <
ret; ++
i) {
635 if (buf[
i] != (
pos & 0xFF)) {
636 printf(
"read-mismatch: actual %d, expecting %d, at %"PRId64
"\n",
637 (
int)buf[
i], (
int)(
pos & 0xFF),
pos);
646 printf(
"read: %"PRId64
"\n", read_len);
668 for (
i = 0;
i <
ret; ++
i) {
669 if (buf[
i] != (
pos & 0xFF)) {
670 printf(
"read-mismatch: actual %d, expecting %d, at %"PRId64
"\n",
671 (
int)buf[
i], (
int)(
pos & 0xFF),
pos);
680 printf(
"read: %"PRId64
"\n", read_len);
static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
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)
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.
#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)
size_t av_fifo_can_read(const AVFifo *f)
#define AVSEEK_SIZE
ORing this as the "whence" parameter to a seek function causes it to return the filesize without seek...
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.
int ffurl_close(URLContext *h)
void av_fifo_reset2(AVFifo *f)
static int ring_size(RingBuffer *ring)
pthread_t async_buffer_thread
Callback for checking whether to abort blocking functions.
pthread_cond_t cond_wakeup_background
pthread_cond_t cond_wakeup_main
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.
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)
#define SHORT_SEEK_THRESHOLD
size_t av_fifo_can_write(const AVFifo *f)
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
int main(int argc, char *argv[])
Describe the class of an AVClass context structure.
AVIOInterruptCB interrupt_callback
const char * av_default_item_name(void *ptr)
Return the context name.
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)
int av_fifo_peek(AVFifo *f, void *buf, size_t nb_elems, size_t offset)
Read data from a FIFO without modifying FIFO state.
#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)
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.
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...
static int async_read_internal(URLContext *h, void *dest, int size)
const URLProtocol ff_async_protocol
static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
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.
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 ...
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)
void av_fifo_drain2(AVFifo *f, size_t size)
Discard the specified amount of data from an AVFifo.
#define pthread_mutex_lock(a)