FFmpeg
Loading...
Searching...
No Matches
async.c
Go to the documentation of this file.
1/*
2 * Input async protocol.
3 * Copyright (c) 2015 Zhang Rui <bbcallen@gmail.com>
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 * Based on libavformat/cache.c by Michael Niedermayer
22 */
23
24 /**
25 * @TODO
26 * support timeout
27 * support work with concatdec, hls
28 */
29
30#include <inttypes.h>
31#include <stdatomic.h>
32#include <string.h>
33
34#include "libavutil/avassert.h"
35#include "libavutil/avstring.h"
36#include "libavutil/error.h"
37#include "libavutil/fifo.h"
38#include "libavutil/log.h"
39#include "libavutil/opt.h"
40#include "libavutil/thread.h"
41#include "url.h"
42
43#if HAVE_UNISTD_H
44#include <unistd.h>
45#endif
46
47#define BUFFER_CAPACITY (4 * 1024 * 1024)
48#define READ_BACK_CAPACITY (4 * 1024 * 1024)
49#define SHORT_SEEK_THRESHOLD (256 * 1024)
50
58
85
86static int ring_init(RingBuffer *ring, unsigned int capacity, int read_back_capacity)
87{
88 memset(ring, 0, sizeof(RingBuffer));
89 ring->fifo = av_fifo_alloc2(capacity + read_back_capacity, 1, 0);
90 if (!ring->fifo)
91 return AVERROR(ENOMEM);
92
93 ring->read_back_capacity = read_back_capacity;
94 return 0;
95}
96
97static void ring_destroy(RingBuffer *ring)
98{
99 av_fifo_freep2(&ring->fifo);
100}
101
102static void ring_reset(RingBuffer *ring)
103{
104 av_fifo_reset2(ring->fifo);
105 ring->read_pos = 0;
106}
107
108static int ring_size(RingBuffer *ring)
109{
110 return av_fifo_can_read(ring->fifo) - ring->read_pos;
111}
112
113static int ring_space(RingBuffer *ring)
114{
115 return av_fifo_can_write(ring->fifo);
116}
117
118static int ring_read(RingBuffer *ring, void *dest, int buf_size)
119{
120 int ret = 0;
121
122 av_assert2(buf_size <= ring_size(ring));
123 if (dest)
124 ret = av_fifo_peek(ring->fifo, dest, buf_size, ring->read_pos);
125 ring->read_pos += buf_size;
126
127 if (ring->read_pos > ring->read_back_capacity) {
128 av_fifo_drain2(ring->fifo, ring->read_pos - ring->read_back_capacity);
129 ring->read_pos = ring->read_back_capacity;
130 }
131
132 return ret;
133}
134
135static int wrapped_url_read(void *src, void *dst, size_t *size)
136{
137 URLContext *h = src;
138 AsyncContext *c = h->priv_data;
139 int ret;
140
141 ret = ffurl_read(c->inner, dst, *size);
142 *size = ret > 0 ? ret : 0;
143 c->inner_io_error = ret < 0 ? ret : 0;
144
145 return c->inner_io_error;
146}
147
148static int ring_write(RingBuffer *ring, URLContext *h, size_t size)
149{
150 int ret;
151
152 av_assert2(size <= ring_space(ring));
154 if (ret < 0)
155 return ret;
156
157 return size;
158}
159
161{
162 return ring->read_pos;
163}
164
165static int ring_drain(RingBuffer *ring, int offset)
166{
168 av_assert2(offset <= ring_size(ring));
169 ring->read_pos += offset;
170 return 0;
171}
172
173static int async_check_interrupt(void *arg)
174{
175 URLContext *h = arg;
176 AsyncContext *c = h->priv_data;
177
178 if (atomic_load(&c->abort_request))
179 return 1;
180
181 if (ff_check_interrupt(&c->interrupt_callback))
182 atomic_store(&c->abort_request, 1);
183
184 return atomic_load(&c->abort_request);
185}
186
187static void *async_buffer_task(void *arg)
188{
189 URLContext *h = arg;
190 AsyncContext *c = h->priv_data;
191 RingBuffer *ring = &c->ring;
192 int ret = 0;
193 int64_t seek_ret;
194
195 ff_thread_setname("async");
196
197 while (1) {
198 int fifo_space, to_copy;
199
200 pthread_mutex_lock(&c->mutex);
202 c->io_eof_reached = 1;
203 c->io_error = AVERROR_EXIT;
204 pthread_cond_signal(&c->cond_wakeup_main);
205 pthread_mutex_unlock(&c->mutex);
206 break;
207 }
208
209 if (c->seek_request) {
210 seek_ret = ffurl_seek(c->inner, c->seek_pos, c->seek_whence);
211 if (seek_ret >= 0) {
212 c->io_eof_reached = 0;
213 c->io_error = 0;
214 ring_reset(ring);
215 }
216
217 c->seek_completed = 1;
218 c->seek_ret = seek_ret;
219 c->seek_request = 0;
220
221
222 pthread_cond_signal(&c->cond_wakeup_main);
223 pthread_mutex_unlock(&c->mutex);
224 continue;
225 }
226
227 fifo_space = ring_space(ring);
228 if (c->io_eof_reached || fifo_space <= 0) {
229 pthread_cond_signal(&c->cond_wakeup_main);
230 pthread_cond_wait(&c->cond_wakeup_background, &c->mutex);
231 pthread_mutex_unlock(&c->mutex);
232 continue;
233 }
234 pthread_mutex_unlock(&c->mutex);
235
236 to_copy = FFMIN(4096, fifo_space);
237 ret = ring_write(ring, h, to_copy);
238
239 pthread_mutex_lock(&c->mutex);
240 if (ret <= 0) {
241 c->io_eof_reached = 1;
242 if (c->inner_io_error < 0)
243 c->io_error = c->inner_io_error;
244 }
245
246 pthread_cond_signal(&c->cond_wakeup_main);
247 pthread_mutex_unlock(&c->mutex);
248 }
249
250 return NULL;
251}
252
253static int async_open(URLContext *h, const char *arg, int flags, AVDictionary **options)
254{
255 AsyncContext *c = h->priv_data;
256 int ret;
257 AVIOInterruptCB interrupt_callback = {.callback = async_check_interrupt, .opaque = h};
258
259 av_strstart(arg, "async:", &arg);
260 atomic_init(&c->abort_request, 0);
261
263 if (ret < 0)
264 goto fifo_fail;
265
266 /* wrap interrupt callback */
267 c->interrupt_callback = h->interrupt_callback;
268 ret = ffurl_open_whitelist(&c->inner, arg, flags, &interrupt_callback, options, h->protocol_whitelist, h->protocol_blacklist, h);
269 if (ret != 0) {
270 av_log(h, AV_LOG_ERROR, "ffurl_open failed : %s, %s\n", av_err2str(ret), arg);
271 goto url_fail;
272 }
273
274 c->logical_size = ffurl_size(c->inner);
275 h->is_streamed = c->inner->is_streamed;
276
277 ret = pthread_mutex_init(&c->mutex, NULL);
278 if (ret != 0) {
279 ret = AVERROR(ret);
280 av_log(h, AV_LOG_ERROR, "pthread_mutex_init failed : %s\n", av_err2str(ret));
281 goto mutex_fail;
282 }
283
284 ret = pthread_cond_init(&c->cond_wakeup_main, NULL);
285 if (ret != 0) {
286 ret = AVERROR(ret);
287 av_log(h, AV_LOG_ERROR, "pthread_cond_init failed : %s\n", av_err2str(ret));
288 goto cond_wakeup_main_fail;
289 }
290
291 ret = pthread_cond_init(&c->cond_wakeup_background, NULL);
292 if (ret != 0) {
293 ret = AVERROR(ret);
294 av_log(h, AV_LOG_ERROR, "pthread_cond_init failed : %s\n", av_err2str(ret));
295 goto cond_wakeup_background_fail;
296 }
297
298 ret = pthread_create(&c->async_buffer_thread, NULL, async_buffer_task, h);
299 if (ret) {
300 ret = AVERROR(ret);
301 av_log(h, AV_LOG_ERROR, "pthread_create failed : %s\n", av_err2str(ret));
302 goto thread_fail;
303 }
304
305 return 0;
306
307thread_fail:
308 pthread_cond_destroy(&c->cond_wakeup_background);
309cond_wakeup_background_fail:
310 pthread_cond_destroy(&c->cond_wakeup_main);
311cond_wakeup_main_fail:
312 pthread_mutex_destroy(&c->mutex);
313mutex_fail:
314 ffurl_closep(&c->inner);
315url_fail:
316 ring_destroy(&c->ring);
317fifo_fail:
318 return ret;
319}
320
322{
323 AsyncContext *c = h->priv_data;
324 int ret;
325
326 pthread_mutex_lock(&c->mutex);
327 atomic_store(&c->abort_request, 1);
328 pthread_cond_signal(&c->cond_wakeup_background);
329 pthread_mutex_unlock(&c->mutex);
330
331 ret = pthread_join(c->async_buffer_thread, NULL);
332 if (ret != 0)
333 av_log(h, AV_LOG_ERROR, "pthread_join(): %s\n", av_err2str(ret));
334
335 pthread_cond_destroy(&c->cond_wakeup_background);
336 pthread_cond_destroy(&c->cond_wakeup_main);
337 pthread_mutex_destroy(&c->mutex);
338 ffurl_closep(&c->inner);
339 ring_destroy(&c->ring);
340
341 return 0;
342}
343
344static int async_read_internal(URLContext *h, void *dest, int size)
345{
346 AsyncContext *c = h->priv_data;
347 RingBuffer *ring = &c->ring;
348 int read_complete = !dest;
349 int to_read = size;
350 int ret = 0;
351
352 pthread_mutex_lock(&c->mutex);
353
354 while (to_read > 0) {
355 int fifo_size, to_copy;
358 break;
359 }
360 fifo_size = ring_size(ring);
361 to_copy = FFMIN(to_read, fifo_size);
362 if (to_copy > 0) {
363 ring_read(ring, dest, to_copy);
364 if (dest)
365 dest = (uint8_t *)dest + to_copy;
366 c->logical_pos += to_copy;
367 to_read -= to_copy;
368 ret = size - to_read;
369
370 if (to_read <= 0 || !read_complete)
371 break;
372 } else if (c->io_eof_reached) {
373 if (ret <= 0) {
374 if (c->io_error)
375 ret = c->io_error;
376 else
378 }
379 break;
380 }
381 pthread_cond_signal(&c->cond_wakeup_background);
382 pthread_cond_wait(&c->cond_wakeup_main, &c->mutex);
383 }
384
385 pthread_cond_signal(&c->cond_wakeup_background);
386 pthread_mutex_unlock(&c->mutex);
387
388 return ret;
389}
390
391static int async_read(URLContext *h, unsigned char *buf, int size)
392{
393 return async_read_internal(h, buf, size);
394}
395
397{
398 AsyncContext *c = h->priv_data;
399 RingBuffer *ring = &c->ring;
400 int64_t ret;
401 int64_t new_logical_pos;
402 int fifo_size;
403 int fifo_size_of_read_back;
404
405 if (whence == AVSEEK_SIZE) {
406 av_log(h, AV_LOG_TRACE, "async_seek: AVSEEK_SIZE: %"PRId64"\n", (int64_t)c->logical_size);
407 return c->logical_size;
408 } else if (whence == SEEK_CUR) {
409 av_log(h, AV_LOG_TRACE, "async_seek: %"PRId64"\n", pos);
410 new_logical_pos = pos + c->logical_pos;
411 } else if (whence == SEEK_SET){
412 av_log(h, AV_LOG_TRACE, "async_seek: %"PRId64"\n", pos);
413 new_logical_pos = pos;
414 } else {
415 return AVERROR(EINVAL);
416 }
417 if (new_logical_pos < 0)
418 return AVERROR(EINVAL);
419
420 fifo_size = ring_size(ring);
421 fifo_size_of_read_back = ring_size_of_read_back(ring);
422 if (new_logical_pos == c->logical_pos) {
423 /* current position */
424 return c->logical_pos;
425 } else if ((new_logical_pos >= (c->logical_pos - fifo_size_of_read_back)) &&
426 (new_logical_pos < (c->logical_pos + fifo_size + SHORT_SEEK_THRESHOLD))) {
427 int pos_delta = (int)(new_logical_pos - c->logical_pos);
428 /* fast seek */
429 av_log(h, AV_LOG_TRACE, "async_seek: fask_seek %"PRId64" from %d dist:%d/%d\n",
430 new_logical_pos, (int)c->logical_pos,
431 (int)(new_logical_pos - c->logical_pos), fifo_size);
432
433 if (pos_delta > 0) {
434 // fast seek forwards
435 async_read_internal(h, NULL, pos_delta);
436 } else {
437 // fast seek backwards
438 ring_drain(ring, pos_delta);
439 c->logical_pos = new_logical_pos;
440 }
441
442 return c->logical_pos;
443 } else if (c->logical_size <= 0) {
444 /* can not seek */
445 return AVERROR(EINVAL);
446 } else if (new_logical_pos > c->logical_size) {
447 /* beyond end */
448 return AVERROR(EINVAL);
449 }
450
451 pthread_mutex_lock(&c->mutex);
452
453 c->seek_request = 1;
454 c->seek_pos = new_logical_pos;
455 c->seek_whence = SEEK_SET;
456 c->seek_completed = 0;
457 c->seek_ret = 0;
458
459 while (1) {
462 break;
463 }
464 if (c->seek_completed) {
465 if (c->seek_ret >= 0)
466 c->logical_pos = c->seek_ret;
467 ret = c->seek_ret;
468 break;
469 }
470 pthread_cond_signal(&c->cond_wakeup_background);
471 pthread_cond_wait(&c->cond_wakeup_main, &c->mutex);
472 }
473
474 pthread_mutex_unlock(&c->mutex);
475
476 return ret;
477}
478
479#define OFFSET(x) offsetof(AsyncContext, x)
480#define D AV_OPT_FLAG_DECODING_PARAM
481
482static const AVOption options[] = {
483 {NULL},
484};
485
486#undef D
487#undef OFFSET
488
490 .class_name = "Async",
491 .item_name = av_default_item_name,
492 .option = options,
493 .version = LIBAVUTIL_VERSION_INT,
494};
495
497 .name = "async",
498 .url_open2 = async_open,
499 .url_read = async_read,
500 .url_seek = async_seek,
501 .url_close = async_close,
502 .priv_data_size = sizeof(AsyncContext),
503 .priv_data_class = &async_context_class,
504};
505
506#if 0
507
508#define TEST_SEEK_POS (1536)
509#define TEST_STREAM_SIZE (2048)
510
511typedef struct TestContext {
512 AVClass *class;
513 int64_t logical_pos;
514 int64_t logical_size;
515
516 /* options */
517 int opt_read_error;
519
520static int async_test_open(URLContext *h, const char *arg, int flags, AVDictionary **options)
521{
522 TestContext *c = h->priv_data;
523 c->logical_pos = 0;
524 c->logical_size = TEST_STREAM_SIZE;
525 return 0;
526}
527
528static int async_test_close(URLContext *h)
529{
530 return 0;
531}
532
533static int async_test_read(URLContext *h, unsigned char *buf, int size)
534{
535 TestContext *c = h->priv_data;
536 int i;
537 int read_len = 0;
538
539 if (c->opt_read_error)
540 return c->opt_read_error;
541
542 if (c->logical_pos >= c->logical_size)
543 return AVERROR_EOF;
544
545 for (i = 0; i < size; ++i) {
546 buf[i] = c->logical_pos & 0xFF;
547
548 c->logical_pos++;
549 read_len++;
550
551 if (c->logical_pos >= c->logical_size)
552 break;
553 }
554
555 return read_len;
556}
557
558static int64_t async_test_seek(URLContext *h, int64_t pos, int whence)
559{
560 TestContext *c = h->priv_data;
561 int64_t new_logical_pos;
562
563 if (whence == AVSEEK_SIZE) {
564 return c->logical_size;
565 } else if (whence == SEEK_CUR) {
566 new_logical_pos = pos + c->logical_pos;
567 } else if (whence == SEEK_SET){
568 new_logical_pos = pos;
569 } else {
570 return AVERROR(EINVAL);
571 }
572 if (new_logical_pos < 0)
573 return AVERROR(EINVAL);
574
575 c->logical_pos = new_logical_pos;
576 return new_logical_pos;
577}
578
579#define OFFSET(x) offsetof(TestContext, x)
580#define D AV_OPT_FLAG_DECODING_PARAM
581
582static const AVOption async_test_options[] = {
583 { "async-test-read-error", "cause read fail",
584 OFFSET(opt_read_error), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, .flags = D },
585 {NULL},
586};
587
588#undef D
589#undef OFFSET
590
591static const AVClass async_test_context_class = {
592 .class_name = "Async-Test",
593 .item_name = av_default_item_name,
594 .option = async_test_options,
595 .version = LIBAVUTIL_VERSION_INT,
596};
597
598const URLProtocol ff_async_test_protocol = {
599 .name = "async-test",
600 .url_open2 = async_test_open,
601 .url_read = async_test_read,
602 .url_seek = async_test_seek,
603 .url_close = async_test_close,
604 .priv_data_size = sizeof(TestContext),
605 .priv_data_class = &async_test_context_class,
606};
607
608int main(void)
609{
610 URLContext *h = NULL;
611 int i;
612 int ret;
614 int64_t pos;
615 int64_t read_len;
616 unsigned char buf[4096];
618
619 ffurl_register_protocol(&ff_async_protocol);
620 ffurl_register_protocol(&ff_async_test_protocol);
621
622 /*
623 * test normal read
624 */
625 ret = ffurl_open_whitelist(&h, "async:async-test:", AVIO_FLAG_READ,
626 NULL, NULL, NULL, NULL, NULL);
627 printf("open: %d\n", ret);
628
629 size = ffurl_size(h);
630 printf("size: %"PRId64"\n", size);
631
632 pos = ffurl_seek(h, 0, SEEK_CUR);
633 read_len = 0;
634 while (1) {
635 ret = ffurl_read(h, buf, sizeof(buf));
636 if (ret == AVERROR_EOF) {
637 printf("read-error: AVERROR_EOF at %"PRId64"\n", ffurl_seek(h, 0, SEEK_CUR));
638 break;
639 }
640 else if (ret == 0)
641 break;
642 else if (ret < 0) {
643 printf("read-error: %d at %"PRId64"\n", ret, ffurl_seek(h, 0, SEEK_CUR));
644 goto fail;
645 } else {
646 for (i = 0; i < ret; ++i) {
647 if (buf[i] != (pos & 0xFF)) {
648 printf("read-mismatch: actual %d, expecting %d, at %"PRId64"\n",
649 (int)buf[i], (int)(pos & 0xFF), pos);
650 break;
651 }
652 pos++;
653 }
654 }
655
656 read_len += ret;
657 }
658 printf("read: %"PRId64"\n", read_len);
659
660 /*
661 * test normal seek
662 */
663 ret = ffurl_read(h, buf, 1);
664 printf("read: %d\n", ret);
665
666 pos = ffurl_seek(h, TEST_SEEK_POS, SEEK_SET);
667 printf("seek: %"PRId64"\n", pos);
668
669 read_len = 0;
670 while (1) {
671 ret = ffurl_read(h, buf, sizeof(buf));
672 if (ret == AVERROR_EOF)
673 break;
674 else if (ret == 0)
675 break;
676 else if (ret < 0) {
677 printf("read-error: %d at %"PRId64"\n", ret, ffurl_seek(h, 0, SEEK_CUR));
678 goto fail;
679 } else {
680 for (i = 0; i < ret; ++i) {
681 if (buf[i] != (pos & 0xFF)) {
682 printf("read-mismatch: actual %d, expecting %d, at %"PRId64"\n",
683 (int)buf[i], (int)(pos & 0xFF), pos);
684 break;
685 }
686 pos++;
687 }
688 }
689
690 read_len += ret;
691 }
692 printf("read: %"PRId64"\n", read_len);
693
694 ret = ffurl_read(h, buf, 1);
695 printf("read: %d\n", ret);
696
697 /*
698 * test read error
699 */
700 ffurl_close(h);
701 av_dict_set_int(&opts, "async-test-read-error", -10000, 0);
702 ret = ffurl_open_whitelist(&h, "async:async-test:", AVIO_FLAG_READ,
703 NULL, &opts, NULL, NULL, NULL);
704 printf("open: %d\n", ret);
705
706 ret = ffurl_read(h, buf, 1);
707 printf("read: %d\n", ret);
708
709fail:
711 ffurl_close(h);
712 return 0;
713}
714
715#endif
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:97
static AVDictionary * opts
static int async_check_interrupt(void *arg)
Definition async.c:173
static const AVClass async_context_class
Definition async.c:489
static int ring_drain(RingBuffer *ring, int offset)
Definition async.c:165
static void * async_buffer_task(void *arg)
Definition async.c:187
static int async_read(URLContext *h, unsigned char *buf, int size)
Definition async.c:391
static int ring_space(RingBuffer *ring)
Definition async.c:113
const URLProtocol ff_async_protocol
Definition async.c:496
#define READ_BACK_CAPACITY
Definition async.c:48
#define BUFFER_CAPACITY
@TODO support timeout support work with concatdec, hls
Definition async.c:47
static void ring_reset(RingBuffer *ring)
Definition async.c:102
static int async_open(URLContext *h, const char *arg, int flags, AVDictionary **options)
Definition async.c:253
static int async_close(URLContext *h)
Definition async.c:321
static void ring_destroy(RingBuffer *ring)
Definition async.c:97
#define SHORT_SEEK_THRESHOLD
Definition async.c:49
static int wrapped_url_read(void *src, void *dst, size_t *size)
Definition async.c:135
static int ring_read(RingBuffer *ring, void *dest, int buf_size)
Definition async.c:118
static int ring_init(RingBuffer *ring, unsigned int capacity, int read_back_capacity)
Definition async.c:86
static int ring_size_of_read_back(RingBuffer *ring)
Definition async.c:160
static int ring_write(RingBuffer *ring, URLContext *h, size_t size)
Definition async.c:148
static int ring_size(RingBuffer *ring)
Definition async.c:108
#define OFFSET(x)
Definition async.c:479
static int64_t async_seek(URLContext *h, int64_t pos, int whence)
Definition async.c:396
static int async_read_internal(URLContext *h, void *dest, int size)
Definition async.c:344
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.
Definition avassert.h:68
#define D
Definition avdct.c:35
int ff_check_interrupt(AVIOInterruptCB *cb)
Check if the user has requested to interrupt a blocking function associated with cb.
Definition avio.c:934
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.
Definition avio.c:466
int64_t ffurl_size(URLContext *h)
Return the filesize of the resource accessed by h, AVERROR(ENOSYS) if the operation is not supported ...
Definition avio.c:879
int ffurl_closep(URLContext **hh)
Close the resource accessed by the URLContext h, and free the memory used by it.
Definition avio.c:663
int ffurl_close(URLContext *h)
Definition avio.c:686
#define AVIO_FLAG_READ
read-only
Definition avio.h:630
#define AVSEEK_SIZE
Passing this as the "whence" parameter to a seek function causes it to return the filesize without se...
Definition avio.h:481
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
__device__ int printf(const char *,...)
int main
Definition dovi_rpuenc.c:38
size_t fifo_size
Definition dts2pts.c:616
error code definitions
int ret
Definition ffplay.c:391
A generic FIFO API.
#define fail
Definition test.h:479
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition dict.c:236
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.
Definition dict.c:180
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition error.h:58
#define AVERROR_EOF
End of file.
Definition error.h:57
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition error.h:122
#define AVERROR(e)
Definition error.h:45
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.
Definition fifo.c:47
void av_fifo_freep2(AVFifo **f)
Free an AVFifo and reset pointer to NULL.
Definition fifo.c:286
void av_fifo_reset2(AVFifo *f)
Definition fifo.c:280
size_t av_fifo_can_write(const AVFifo *f)
Definition fifo.c:94
size_t av_fifo_can_read(const AVFifo *f)
Definition fifo.c:87
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.
Definition fifo.c:255
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.
Definition fifo.c:193
void av_fifo_drain2(AVFifo *f, size_t size)
Discard the specified amount of data from an AVFifo.
Definition fifo.c:266
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition log.h:236
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:247
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition avstring.c:36
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
unsigned offset
Definition libaomenc.c:763
const char * arg
Definition jacosubdec.c:66
static int ff_thread_setname(const char *name)
Definition thread.h:216
#define FFMIN(a, b)
Definition macros.h:49
AVOptions.
static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
Definition os2threads.h:158
static av_always_inline int pthread_mutex_lock(pthread_mutex_t *mutex)
Definition os2threads.h:119
static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
Definition os2threads.h:150
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Definition os2threads.h:104
static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
Definition os2threads.h:94
static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
Definition os2threads.h:139
static av_always_inline int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
Definition os2threads.h:80
_fmutex pthread_mutex_t
Definition os2threads.h:53
static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
Definition os2threads.h:132
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
Definition os2threads.h:198
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Definition os2threads.h:112
unsigned int pos
Definition spdifenc.c:431
#define atomic_store(object, desired)
Definition stdatomic.h:256
int atomic_int
Definition stdatomic.h:63
#define atomic_load(object)
Definition stdatomic.h:250
#define atomic_init(obj, value)
Definition stdatomic.h:119
Describe the class of an AVClass context structure.
Definition log.h:76
Definition fifo.c:35
Callback for checking whether to abort blocking functions.
Definition avio.h:59
AVOption.
Definition opt.h:428
pthread_cond_t cond_wakeup_background
Definition async.c:78
pthread_cond_t cond_wakeup_main
Definition async.c:77
int64_t seek_ret
Definition async.c:67
int64_t seek_pos
Definition async.c:64
int io_eof_reached
Definition async.c:71
RingBuffer ring
Definition async.c:75
atomic_int abort_request
Definition async.c:82
URLContext * inner
Definition async.c:61
int seek_completed
Definition async.c:66
int64_t logical_size
Definition async.c:74
pthread_t async_buffer_thread
Definition async.c:80
int io_error
Definition async.c:70
pthread_mutex_t mutex
Definition async.c:79
int inner_io_error
Definition async.c:69
AVIOInterruptCB interrupt_callback
Definition async.c:83
int seek_whence
Definition async.c:65
int64_t logical_pos
Definition async.c:73
int seek_request
Definition async.c:63
int read_pos
Definition async.c:56
int read_back_capacity
Definition async.c:54
AVFifo * fifo
Definition async.c:53
#define av_log(a,...)
#define src
Definition vp8dsp.c:248
int size
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.
Definition url.h:225
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.
Definition url.h:184
static double c[64]