45 #define BUFFER_CAPACITY (4 * 1024 * 1024)
46 #define SHORT_SEEK_THRESHOLD (256 * 1024)
96 int fifo_space, to_copy;
137 to_copy =
FFMIN(4096, fifo_space);
189 goto cond_wakeup_main_fail;
195 goto cond_wakeup_background_fail;
208 cond_wakeup_background_fail:
210 cond_wakeup_main_fail:
244 void (*
func)(
void*,
void*,
int))
253 while (to_read > 0) {
254 int fifo_size, to_copy;
260 to_copy =
FFMIN(to_read, fifo_size);
264 dest = (
uint8_t *)dest + to_copy;
267 ret = size - to_read;
269 if (to_read <= 0 || !read_complete)
300 int64_t new_logical_pos;
306 }
else if (whence == SEEK_CUR) {
309 }
else if (whence == SEEK_SET){
311 new_logical_pos = pos;
315 if (new_logical_pos < 0)
327 (
int)(new_logical_pos - c->
logical_pos), fifo_size);
366 #define OFFSET(x) offsetof(Context, x)
367 #define D AV_OPT_FLAG_DECODING_PARAM
386 .priv_data_size =
sizeof(
Context),
387 .priv_data_class = &async_context_class,
392 #define TEST_SEEK_POS (1536)
393 #define TEST_STREAM_SIZE (2048)
395 typedef struct TestContext {
405 c->logical_size = TEST_STREAM_SIZE;
414 static int async_test_read(
URLContext *h,
unsigned char *
buf,
int size)
420 if (c->logical_pos >= c->logical_size)
423 for (i = 0; i <
size; ++i) {
424 buf[i] = c->logical_pos & 0xFF;
429 if (c->logical_pos >= c->logical_size)
436 static int64_t async_test_seek(
URLContext *h, int64_t pos,
int whence)
439 int64_t new_logical_pos;
442 return c->logical_size;
443 }
else if (whence == SEEK_CUR) {
444 new_logical_pos = pos + c->logical_pos;
445 }
else if (whence == SEEK_SET){
446 new_logical_pos = pos;
450 if (new_logical_pos < 0)
453 c->logical_pos = new_logical_pos;
454 return new_logical_pos;
457 static const AVClass async_test_context_class = {
464 .
name =
"async-test",
465 .url_open2 = async_test_open,
466 .url_read = async_test_read,
467 .url_seek = async_test_seek,
468 .url_close = async_test_close,
469 .priv_data_size =
sizeof(TestContext),
470 .priv_data_class = &async_test_context_class,
481 unsigned char buf[4096];
487 printf(
"open: %d\n", ret);
490 printf(
"size: %"PRId64
"\n", size);
497 printf(
"read-error: AVERROR_EOF at %"PRId64
"\n",
ffurl_seek(h, 0, SEEK_CUR));
503 printf(
"read-error: %d at %"PRId64
"\n", ret,
ffurl_seek(h, 0, SEEK_CUR));
506 for (i = 0; i < ret; ++i) {
507 if (buf[i] != (pos & 0xFF)) {
508 printf(
"read-mismatch: actual %d, expecting %d, at %"PRId64
"\n",
509 (
int)buf[i], (
int)(pos & 0xFF), pos);
518 printf(
"read: %"PRId64
"\n", read_len);
521 printf(
"read: %d\n", ret);
524 printf(
"seek: %"PRId64
"\n", pos);
534 printf(
"read-error: %d at %"PRId64
"\n", ret,
ffurl_seek(h, 0, SEEK_CUR));
537 for (i = 0; i < ret; ++i) {
538 if (buf[i] != (pos & 0xFF)) {
539 printf(
"read-mismatch: actual %d, expecting %d, at %"PRId64
"\n",
540 (
int)buf[i], (
int)(pos & 0xFF), pos);
549 printf(
"read: %"PRId64
"\n", read_len);
552 printf(
"read: %d\n", ret);
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 av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
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...
#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
#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.
int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void(*func)(void *, void *, int))
Feed data from an AVFifoBuffer to a user-supplied callback.
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)
#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 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 ...
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)
int ffurl_close(URLContext *h)
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)
Create an URLContext for accessing to the resource indicated by url, and open 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 backward short seek 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...
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