FFmpeg
Loading...
Searching...
No Matches
fifo.c
Go to the documentation of this file.
1/*
2 * FIFO pseudo-muxer
3 * Copyright (c) 2016 Jan Sebechlebsky
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 License
9 * 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
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with FFmpeg; if not, write to the Free Software * Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#include <stdatomic.h>
23
24#include "libavutil/avassert.h"
25#include "libavutil/opt.h"
26#include "libavutil/time.h"
27#include "libavutil/thread.h"
29#include "avformat.h"
30#include "internal.h"
31#include "mux.h"
32
33#define FIFO_DEFAULT_QUEUE_SIZE 60
34#define FIFO_DEFAULT_MAX_RECOVERY_ATTEMPTS 0
35#define FIFO_DEFAULT_RECOVERY_WAIT_TIME_USEC 5000000 // 5 seconds
36
37typedef struct FifoContext {
38 const AVClass *class;
40
41 char *format;
43
46
48
49 /* Return value of last write_trailer_call */
51
52 /* Time to wait before next recovery attempt
53 * This can refer to the time in processed stream,
54 * or real time. */
56
57 /* Maximal number of unsuccessful successive recovery attempts */
59
60 /* Whether to attempt recovery from failure */
62
63 /* If >0 stream time will be used when waiting
64 * for the recovery attempt instead of real time */
66
67 /* If >0 recovery will be attempted regardless of error code
68 * (except AVERROR_EXIT, so exit request is never ignored) */
70
71 /* Whether to drop packets in case the queue is full. */
73
74 /* Whether to wait for keyframe when recovering
75 * from failure or queue overflow */
77
80 /* Value > 0 signals queue overflow */
81 volatile uint8_t overflow_flag;
82
87
88typedef struct FifoThreadContext {
90
91 /* Timestamp of last failure.
92 * This is either pts in case stream time is used,
93 * or microseconds as returned by av_gettime_relative() */
95
96 /* Number of current recovery process
97 * Value > 0 means we are in recovery process */
99
100 /* If > 0 all frames will be dropped until keyframe is received */
102
103 /* Value > 0 means that the previous write_header call was successful
104 * so finalization by calling write_trailer and ff_io_close must be done
105 * before exiting / reinitialization of underlying muxer */
107
109
110 /* If > 0 at least one of the streams is a video stream */
113
120
125
127{
128 AVFormatContext *avf = ctx->avf;
129 FifoContext *fifo = avf->priv_data;
130 AVFormatContext *avf2 = fifo->avf;
131 AVDictionary *format_options = NULL;
132 int ret, i;
133
134 ret = av_dict_copy(&format_options, fifo->format_options, 0);
135 if (ret < 0)
136 goto end;
137
138 ret = ff_format_output_open(avf2, avf->url, &format_options);
139 if (ret < 0) {
140 av_log(avf, AV_LOG_ERROR, "Error opening %s: %s\n", avf->url,
141 av_err2str(ret));
142 goto end;
143 }
144
145 for (i = 0;i < avf2->nb_streams; i++)
146 ffstream(avf2->streams[i])->cur_dts = 0;
147
148 ret = avformat_write_header(avf2, &format_options);
149 if (!ret) {
150 ctx->header_written = 1;
151 } else {
152 ff_format_io_close(avf2, &avf2->pb);
153 }
154
155 // Check for options unrecognized by underlying muxer
156 if (format_options) {
158 while ((entry = av_dict_iterate(format_options, entry)))
159 av_log(avf2, AV_LOG_ERROR, "Unknown option '%s'\n", entry->key);
160 ret = AVERROR(EINVAL);
161 }
162
163end:
164 av_dict_free(&format_options);
165 return ret;
166}
167
169{
170 AVFormatContext *avf = ctx->avf;
171 FifoContext *fifo = avf->priv_data;
172 AVFormatContext *avf2 = fifo->avf;
173
174 return av_write_frame(avf2, NULL);
175}
176
178{
179 AVStream *st = avf->streams[pkt->stream_index];
181 int64_t duration = (*last_dts == AV_NOPTS_VALUE ? 0 : dts - *last_dts);
182 *last_dts = dts;
183 return duration;
184}
185
187{
188 AVFormatContext *avf = ctx->avf;
189 FifoContext *fifo = avf->priv_data;
190 AVFormatContext *avf2 = fifo->avf;
191 AVRational src_tb, dst_tb;
192 int ret, s_idx;
193 int64_t orig_pts, orig_dts, orig_duration;
194 enum AVMediaType stream_codec_type = avf->streams[pkt->stream_index]->codecpar->codec_type;
195
196 if (fifo->timeshift && pkt->dts != AV_NOPTS_VALUE)
198
199 if (ctx->drop_until_keyframe) {
200 if (pkt->flags & AV_PKT_FLAG_KEY) {
201 if (!ctx->has_video_stream) {
202 ctx->drop_until_keyframe = 0;
203 av_log(avf, AV_LOG_VERBOSE, "Keyframe received, recovering...\n");
204 } else {
205 if (stream_codec_type == AVMEDIA_TYPE_VIDEO) {
206 ctx->drop_until_keyframe = 0;
207 av_log(avf, AV_LOG_VERBOSE, "Video keyframe received, recovering...\n");
208 } else {
209 av_log(avf, AV_LOG_VERBOSE, "Dropping non-video keyframe\n");
211 return 0;
212 }
213 }
214 } else {
215 av_log(avf, AV_LOG_VERBOSE, "Dropping non-keyframe packet\n");
217 return 0;
218 }
219 }
220
221 orig_pts = pkt->pts;
222 orig_dts = pkt->dts;
223 orig_duration = pkt->duration;
224 s_idx = pkt->stream_index;
225 src_tb = avf->streams[s_idx]->time_base;
226 dst_tb = avf2->streams[s_idx]->time_base;
227 av_packet_rescale_ts(pkt, src_tb, dst_tb);
228
229 ret = av_write_frame(avf2, pkt);
230 if (ret >= 0) {
232 } else {
233 // avoid scaling twice
234 pkt->pts = orig_pts;
235 pkt->dts = orig_dts;
236 pkt->duration = orig_duration;
237 }
238 return ret;
239}
240
242{
243 AVFormatContext *avf = ctx->avf;
244 FifoContext *fifo = avf->priv_data;
245 AVFormatContext *avf2 = fifo->avf;
246 int ret;
247
248 if (!ctx->header_written)
249 return 0;
250
251 ret = av_write_trailer(avf2);
252 ff_format_io_close(avf2, &avf2->pb);
253
254 return ret;
255}
256
258{
259 int ret = AVERROR(EINVAL);
260
261 if (msg->type == FIFO_NOOP)
262 return 0;
263
264 if (!ctx->header_written) {
266 if (ret < 0)
267 return ret;
268 }
269
270 switch(msg->type) {
272 av_assert0(ret >= 0);
273 return ret;
275 return fifo_thread_write_packet(ctx, &msg->pkt);
278 }
279
280 av_assert0(0);
281 return AVERROR(EINVAL);
282}
283
284static int is_recoverable(const FifoContext *fifo, int err_no) {
285 if (!fifo->attempt_recovery)
286 return 0;
287
288 if (fifo->recover_any_error)
289 return err_no != AVERROR_EXIT;
290
291 switch (err_no) {
292 case AVERROR(EINVAL):
293 case AVERROR(ENOSYS):
294 case AVERROR_EOF:
295 case AVERROR_EXIT:
297 return 0;
298 default:
299 return 1;
300 }
301}
302
303static void free_message(void *msg)
304{
305 FifoMessage *fifo_msg = msg;
306
307 if (fifo_msg->type == FIFO_WRITE_PACKET)
308 av_packet_unref(&fifo_msg->pkt);
309}
310
312 int err_no)
313{
314 AVFormatContext *avf = ctx->avf;
315 FifoContext *fifo = avf->priv_data;
316 int ret;
317
318 av_log(avf, AV_LOG_INFO, "Recovery failed: %s\n",
319 av_err2str(err_no));
320
321 if (fifo->recovery_wait_streamtime) {
322 if (pkt->pts == AV_NOPTS_VALUE)
323 av_log(avf, AV_LOG_WARNING, "Packet does not contain presentation"
324 " timestamp, recovery will be attempted immediately");
325 ctx->last_recovery_ts = pkt->pts;
326 } else {
327 ctx->last_recovery_ts = av_gettime_relative();
328 }
329
330 if (fifo->max_recovery_attempts &&
331 ctx->recovery_nr >= fifo->max_recovery_attempts) {
332 av_log(avf, AV_LOG_ERROR,
333 "Maximal number of %d recovery attempts reached.\n",
335 ret = err_no;
336 } else {
337 ret = AVERROR(EAGAIN);
338 }
339
340 return ret;
341}
342
344{
345 AVFormatContext *avf = ctx->avf;
346 FifoContext *fifo = avf->priv_data;
347 AVPacket *pkt = &msg->pkt;
348 int64_t time_since_recovery;
349 int ret;
350
351 if (!is_recoverable(fifo, err_no)) {
352 ret = err_no;
353 goto fail;
354 }
355
356 if (ctx->header_written) {
358 ctx->header_written = 0;
359 }
360
361 if (!ctx->recovery_nr) {
362 ctx->last_recovery_ts = fifo->recovery_wait_streamtime ?
363 AV_NOPTS_VALUE : 0;
364 } else {
365 if (fifo->recovery_wait_streamtime) {
366 if (ctx->last_recovery_ts == AV_NOPTS_VALUE) {
367 AVRational tb = avf->streams[pkt->stream_index]->time_base;
368 time_since_recovery = av_rescale_q(pkt->pts - ctx->last_recovery_ts,
369 tb, AV_TIME_BASE_Q);
370 } else {
371 /* Enforce recovery immediately */
372 time_since_recovery = fifo->recovery_wait_time;
373 }
374 } else {
375 time_since_recovery = av_gettime_relative() - ctx->last_recovery_ts;
376 }
377
378 if (time_since_recovery < fifo->recovery_wait_time)
379 return AVERROR(EAGAIN);
380 }
381
382 ctx->recovery_nr++;
383
384 if (fifo->max_recovery_attempts) {
385 av_log(avf, AV_LOG_VERBOSE, "Recovery attempt #%d/%d\n",
386 ctx->recovery_nr, fifo->max_recovery_attempts);
387 } else {
388 av_log(avf, AV_LOG_VERBOSE, "Recovery attempt #%d\n",
389 ctx->recovery_nr);
390 }
391
393 ctx->drop_until_keyframe = 1;
394
396 if (ret < 0) {
397 if (is_recoverable(fifo, ret)) {
399 } else {
400 goto fail;
401 }
402 } else {
403 av_log(avf, AV_LOG_INFO, "Recovery successful\n");
404 ctx->recovery_nr = 0;
405 }
406
407 return 0;
408
409fail:
410 free_message(msg);
411 return ret;
412}
413
415{
416 AVFormatContext *avf = ctx->avf;
417 FifoContext *fifo = avf->priv_data;
418 int ret;
419
420 do {
421 if (!fifo->recovery_wait_streamtime && ctx->recovery_nr > 0) {
422 int64_t time_since_recovery = av_gettime_relative() - ctx->last_recovery_ts;
423 int64_t time_to_wait = FFMAX(0, fifo->recovery_wait_time - time_since_recovery);
424 if (time_to_wait)
425 av_usleep(FFMIN(10000, time_to_wait));
426 }
427
428 ret = fifo_thread_attempt_recovery(ctx, msg, err_no);
429 } while (ret == AVERROR(EAGAIN) && !fifo->drop_pkts_on_overflow);
430
431 if (ret == AVERROR(EAGAIN) && fifo->drop_pkts_on_overflow) {
432 if (msg->type == FIFO_WRITE_PACKET)
433 av_packet_unref(&msg->pkt);
434 ret = 0;
435 }
436
437 return ret;
438}
439
440static void *fifo_consumer_thread(void *data)
441{
442 AVFormatContext *avf = data;
443 FifoContext *fifo = avf->priv_data;
444 AVThreadMessageQueue *queue = fifo->queue;
445 FifoMessage msg = {fifo->timeshift ? FIFO_NOOP : FIFO_WRITE_HEADER, {0}};
446 int ret, i;
447
448 FifoThreadContext fifo_thread_ctx;
449 memset(&fifo_thread_ctx, 0, sizeof(FifoThreadContext));
450 fifo_thread_ctx.avf = avf;
451 fifo_thread_ctx.last_received_dts = AV_NOPTS_VALUE;
452
453 ff_thread_setname("fifo-consumer");
454
455 for (i = 0; i < avf->nb_streams; i++) {
457 fifo_thread_ctx.has_video_stream = 1;
458 break;
459 }
460 }
461
462 while (1) {
463 uint8_t just_flushed = 0;
464
465 if (!fifo_thread_ctx.recovery_nr)
466 ret = fifo_thread_dispatch_message(&fifo_thread_ctx, &msg);
467
468 if (ret < 0 || fifo_thread_ctx.recovery_nr > 0) {
469 int rec_ret = fifo_thread_recover(&fifo_thread_ctx, &msg, ret);
470 if (rec_ret < 0) {
472 break;
473 }
474 }
475
476 /* If the queue is full at the moment when fifo_write_packet
477 * attempts to insert new message (packet) to the queue,
478 * it sets the fifo->overflow_flag to 1 and drops packet.
479 * Here in consumer thread, the flag is checked and if it is
480 * set, the queue is flushed and flag cleared. */
482 if (fifo->overflow_flag) {
484 if (fifo->restart_with_keyframe)
485 fifo_thread_ctx.drop_until_keyframe = 1;
486 fifo->overflow_flag = 0;
487 just_flushed = 1;
488 }
490
491 if (just_flushed)
492 av_log(avf, AV_LOG_INFO, "FIFO queue flushed\n");
493
494 if (fifo->timeshift)
496 av_usleep(10000);
497
498 ret = av_thread_message_queue_recv(queue, &msg, 0);
499 if (ret < 0) {
501 break;
502 }
503 }
504
505 fifo->write_trailer_ret = fifo_thread_write_trailer(&fifo_thread_ctx);
506
507 return NULL;
508}
509
510static int fifo_mux_init(AVFormatContext *avf, const AVOutputFormat *oformat,
511 const char *filename)
512{
513 FifoContext *fifo = avf->priv_data;
514 AVFormatContext *avf2;
515 int ret = 0, i;
516
517 ret = avformat_alloc_output_context2(&avf2, oformat, NULL, filename);
518 if (ret < 0)
519 return ret;
520
521 fifo->avf = avf2;
522
524 avf2->max_delay = avf->max_delay;
525 ret = av_dict_copy(&avf2->metadata, avf->metadata, 0);
526 if (ret < 0)
527 return ret;
528 avf2->opaque = avf->opaque;
529 avf2->io_close2 = avf->io_close2;
530 avf2->io_open = avf->io_open;
531 avf2->flags = avf->flags;
532
533 for (i = 0; i < avf->nb_streams; ++i) {
534 AVStream *st = ff_stream_clone(avf2, avf->streams[i]);
535 if (!st)
536 return AVERROR(ENOMEM);
537 }
538
539 return 0;
540}
541
543{
544 FifoContext *fifo = avf->priv_data;
545 const AVOutputFormat *oformat;
546 int ret = 0;
547
549 av_log(avf, AV_LOG_ERROR, "recovery_wait_streamtime can be turned on"
550 " only when drop_pkts_on_overflow is also turned on\n");
551 return AVERROR(EINVAL);
552 }
553 atomic_init(&fifo->queue_duration, 0);
555
556#ifdef FIFO_TEST
557 /* This exists for the fifo_muxer test tool. */
558 if (fifo->format && !strcmp(fifo->format, "fifo_test")) {
560 oformat = &ff_fifo_test_muxer.p;
561 } else
562#endif
563 oformat = av_guess_format(fifo->format, avf->url, NULL);
564 if (!oformat) {
566 return ret;
567 }
568
569 ret = fifo_mux_init(avf, oformat, avf->url);
570 if (ret < 0)
571 return ret;
572
573 ret = av_thread_message_queue_alloc(&fifo->queue, (unsigned) fifo->queue_size,
574 sizeof(FifoMessage));
575 if (ret < 0)
576 return ret;
577
579
581 if (ret < 0)
582 return AVERROR(ret);
584
585 return 0;
586}
587
589{
590 FifoContext * fifo = avf->priv_data;
591 int ret;
592
594 if (ret) {
595 av_log(avf, AV_LOG_ERROR, "Failed to start thread: %s\n",
596 av_err2str(AVERROR(ret)));
597 ret = AVERROR(ret);
598 }
599
600 return ret;
601}
602
604{
605 FifoContext *fifo = avf->priv_data;
607 int ret;
608
609 if (pkt) {
610 ret = av_packet_ref(&msg.pkt,pkt);
611 if (ret < 0)
612 return ret;
613 }
614
615 ret = av_thread_message_queue_send(fifo->queue, &msg,
618 if (ret == AVERROR(EAGAIN)) {
619 uint8_t overflow_set = 0;
620
621 /* Queue is full, set fifo->overflow_flag to 1
622 * to let consumer thread know the queue should
623 * be flushed. */
625 if (!fifo->overflow_flag)
626 fifo->overflow_flag = overflow_set = 1;
628
629 if (overflow_set)
630 av_log(avf, AV_LOG_WARNING, "FIFO queue full\n");
631 ret = 0;
632 goto fail;
633 } else if (ret < 0) {
634 goto fail;
635 }
636
637 if (fifo->timeshift && pkt && pkt->dts != AV_NOPTS_VALUE)
639
640 return ret;
641fail:
642 if (pkt)
643 av_packet_unref(&msg.pkt);
644 return ret;
645}
646
648{
649 FifoContext *fifo= avf->priv_data;
650 int ret;
651
653 if (fifo->timeshift) {
655 int64_t elapsed = 0;
656 FifoMessage msg = {FIFO_NOOP};
657 do {
658 int64_t delay = av_gettime_relative() - now;
659 if (delay < 0) { // Discontinuity?
660 delay = 10000;
661 now = av_gettime_relative();
662 } else {
663 now += delay;
664 }
666 elapsed += delay;
667 if (elapsed > fifo->timeshift)
668 break;
669 av_usleep(10000);
671 } while (ret >= 0 || ret == AVERROR(EAGAIN));
672 atomic_store(&fifo->queue_duration, INT64_MAX);
673 }
674
675 ret = pthread_join(fifo->writer_thread, NULL);
676 if (ret < 0) {
677 av_log(avf, AV_LOG_ERROR, "pthread join error: %s\n",
678 av_err2str(AVERROR(ret)));
679 return AVERROR(ret);
680 }
681
682 ret = fifo->write_trailer_ret;
683 return ret;
684}
685
695
696#define OFFSET(x) offsetof(FifoContext, x)
697static const AVOption options[] = {
698 {"attempt_recovery", "Attempt recovery in case of failure", OFFSET(attempt_recovery),
700
701 {"drop_pkts_on_overflow", "Drop packets on fifo queue overflow not to block encoder", OFFSET(drop_pkts_on_overflow),
703
704 {"fifo_format", "Target muxer", OFFSET(format),
706
707 {"format_opts", "Options to be passed to underlying muxer", OFFSET(format_options),
709
710 {"max_recovery_attempts", "Maximal number of recovery attempts", OFFSET(max_recovery_attempts),
712
713 {"queue_size", "Size of fifo queue", OFFSET(queue_size),
715
716 {"recovery_wait_streamtime", "Use stream time instead of real time while waiting for recovery",
717 OFFSET(recovery_wait_streamtime), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
718
719 {"recovery_wait_time", "Waiting time between recovery attempts", OFFSET(recovery_wait_time),
721
722 {"recover_any_error", "Attempt recovery regardless of type of the error", OFFSET(recover_any_error),
724
725 {"restart_with_keyframe", "Wait for keyframe when restarting output", OFFSET(restart_with_keyframe),
727
728 {"timeshift", "Delay fifo output", OFFSET(timeshift),
729 AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX, AV_OPT_FLAG_ENCODING_PARAM},
730
731 {NULL},
732};
733
734static const AVClass fifo_muxer_class = {
735 .class_name = "Fifo muxer",
736 .item_name = av_default_item_name,
737 .option = options,
738 .version = LIBAVUTIL_VERSION_INT,
739};
740
742 .p.name = "fifo",
743 .p.long_name = NULL_IF_CONFIG_SMALL("FIFO queue pseudo-muxer"),
744 .p.priv_class = &fifo_muxer_class,
745 .p.flags = AVFMT_NOFILE | AVFMT_TS_NEGATIVE,
746 .priv_data_size = sizeof(FifoContext),
747 .init = fifo_init,
752 .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
753};
static const char *const format[]
Definition af_aiir.c:445
const FFOutputFormat ff_fifo_muxer
Definition fifo.c:741
#define entry
static AVFormatContext * ctx
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition avformat.c:966
AVStream * ff_stream_clone(AVFormatContext *dst_ctx, const AVStream *src)
Create a new stream and copy to it all parameters from a source stream, with the exception of the ind...
Definition avformat.c:252
Main libavformat public API header.
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition avformat.h:490
#define AVFMT_TS_NEGATIVE
Format allows muxing negative timestamps.
Definition avformat.h:512
int avformat_alloc_output_context2(AVFormatContext **ctx, const AVOutputFormat *oformat, const char *format_name, const char *filename)
Allocate an AVFormatContext for an output format.
Definition mux.c:95
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
static void deinit(AVFormatContext *s)
Definition chromaprint.c:53
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
static AVPacket * pkt
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
Definition ffmpeg_mux.c:205
static int64_t duration
Definition ffplay.c:399
static void write_header(FFV1Context *f)
Definition ffv1enc.c:384
const FFOutputFormat ff_fifo_test_muxer
Definition fifo_muxer.c:148
#define fail
Definition test.h:479
#define AV_OPT_FLAG_ENCODING_PARAM
A generic parameter which can be set by the user for muxing or encoding.
Definition opt.h:351
@ AV_OPT_TYPE_DURATION
Underlying C type is int64_t.
Definition opt.h:318
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_DICT
Underlying C type is AVDictionary*.
Definition opt.h:289
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition opt.h:326
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition opt.h:275
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition packet.c:434
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition packet.h:650
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
Definition packet.c:442
void av_packet_rescale_ts(AVPacket *pkt, AVRational src_tb, AVRational dst_tb)
Convert valid timing fields (timestamps / durations) in a packet from one timebase to another.
Definition packet.c:538
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition avformat.c:151
av_warn_unused_result int avformat_write_header(AVFormatContext *s, AVDictionary **options)
Allocate the stream private data and write the stream header to an output media file.
Definition mux.c:467
int av_write_trailer(AVFormatContext *s)
Write the stream trailer to an output media file and free the file private data.
Definition mux.c:1238
const AVOutputFormat * av_guess_format(const char *short_name, const char *filename, const char *mime_type)
Return the output format in the list of registered output formats which best matches the provided par...
Definition format.c:79
int av_write_frame(AVFormatContext *s, AVPacket *pkt)
Write a packet to an output media file.
Definition mux.c:1176
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition dict.c:233
const AVDictionaryEntry * av_dict_iterate(const AVDictionary *m, const AVDictionaryEntry *prev)
Iterate over a dictionary.
Definition dict.c:42
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition dict.c:247
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition error.h:58
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition error.h:64
#define AVERROR_MUXER_NOT_FOUND
Muxer not found.
Definition error.h:62
#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
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_INFO
Standard information.
Definition log.h:221
#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:241
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
AVMediaType
Definition avutil.h:198
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition avutil.h:263
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
static void * fifo_consumer_thread(void *data)
Definition fifo.c:440
static int fifo_thread_write_header(FifoThreadContext *ctx)
Definition fifo.c:126
static const AVClass fifo_muxer_class
Definition fifo.c:734
FifoMessageType
Definition fifo.c:114
@ FIFO_WRITE_HEADER
Definition fifo.c:116
@ FIFO_NOOP
Definition fifo.c:115
@ FIFO_FLUSH_OUTPUT
Definition fifo.c:118
@ FIFO_WRITE_PACKET
Definition fifo.c:117
static int fifo_init(AVFormatContext *avf)
Definition fifo.c:542
static int fifo_write_header(AVFormatContext *avf)
Definition fifo.c:588
static int fifo_thread_process_recovery_failure(FifoThreadContext *ctx, AVPacket *pkt, int err_no)
Definition fifo.c:311
static int fifo_thread_flush_output(FifoThreadContext *ctx)
Definition fifo.c:168
#define FIFO_DEFAULT_MAX_RECOVERY_ATTEMPTS
Definition fifo.c:34
static int fifo_mux_init(AVFormatContext *avf, const AVOutputFormat *oformat, const char *filename)
Definition fifo.c:510
static int fifo_thread_recover(FifoThreadContext *ctx, FifoMessage *msg, int err_no)
Definition fifo.c:414
static int fifo_write_packet(AVFormatContext *avf, AVPacket *pkt)
Definition fifo.c:603
static int fifo_thread_attempt_recovery(FifoThreadContext *ctx, FifoMessage *msg, int err_no)
Definition fifo.c:343
#define FIFO_DEFAULT_QUEUE_SIZE
Definition fifo.c:33
static int fifo_thread_write_packet(FifoThreadContext *ctx, AVPacket *pkt)
Definition fifo.c:186
static int is_recoverable(const FifoContext *fifo, int err_no)
Definition fifo.c:284
#define OFFSET(x)
Definition fifo.c:696
static void fifo_deinit(AVFormatContext *avf)
Definition fifo.c:686
static int fifo_write_trailer(AVFormatContext *avf)
Definition fifo.c:647
static void free_message(void *msg)
Definition fifo.c:303
static int64_t next_duration(AVFormatContext *avf, AVPacket *pkt, int64_t *last_dts)
Definition fifo.c:177
static int fifo_thread_write_trailer(FifoThreadContext *ctx)
Definition fifo.c:241
static int fifo_thread_dispatch_message(FifoThreadContext *ctx, FifoMessage *msg)
Definition fifo.c:257
#define FIFO_DEFAULT_RECOVERY_WAIT_TIME_USEC
Definition fifo.c:35
static av_always_inline FFStream * ffstream(AVStream *st)
Definition internal.h:365
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:97
static int ff_thread_setname(const char *name)
Definition thread.h:216
#define FFMIN(a, b)
Definition macros.h:49
#define FFMAX(a, b)
Definition macros.h:47
int ff_format_output_open(AVFormatContext *s, const char *url, AVDictionary **options)
Utility function to open IO stream of output format.
Definition mux_utils.c:127
#define FF_OFMT_FLAG_ALLOW_FLUSH
This flag indicates that the muxer stores data internally and supports flushing it.
Definition mux.h:38
const char data[16]
Definition mxf.c:149
AVOptions.
static av_always_inline int pthread_mutex_lock(pthread_mutex_t *mutex)
Definition os2threads.h:119
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_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_mutex_destroy(pthread_mutex_t *mutex)
Definition os2threads.h:112
FF_ATOMIC_ALIGN64 int_least64_t atomic_int_least64_t
Definition stdatomic.h:79
#define atomic_store(object, desired)
Definition stdatomic.h:256
@ memory_order_relaxed
Definition stdatomic.h:29
#define atomic_fetch_add_explicit(object, operand, order)
Definition stdatomic.h:297
#define atomic_load_explicit(object, order)
Definition stdatomic.h:247
#define atomic_init(obj, value)
Definition stdatomic.h:119
#define atomic_fetch_sub_explicit(object, operand, order)
Definition stdatomic.h:300
Describe the class of an AVClass context structure.
Definition log.h:76
enum AVMediaType codec_type
General type of the encoded data.
Definition codec_par.h:53
Format I/O context.
Definition avformat.h:1337
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition avformat.h:1393
int(* io_close2)(struct AVFormatContext *s, AVIOContext *pb)
A callback for closing the streams opened with AVFormatContext.io_open().
Definition avformat.h:1967
AVIOContext * pb
I/O context.
Definition avformat.h:1379
AVDictionary * metadata
Metadata that applies to the whole file.
Definition avformat.h:1584
int flags
Flags modifying the (de)muxer behaviour.
Definition avformat.h:1488
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition avformat.h:1622
char * url
input or output URL.
Definition avformat.h:1453
void * opaque
User data.
Definition avformat.h:1916
void * priv_data
Format private data.
Definition avformat.h:1365
AVStream ** streams
A list of all streams in the file.
Definition avformat.h:1405
int(* io_open)(struct AVFormatContext *s, AVIOContext **pb, const char *url, int flags, AVDictionary **options)
A callback for opening new IO streams.
Definition avformat.h:1957
AVOption.
Definition opt.h:428
This structure stores compressed data.
Definition packet.h:580
Rational number (pair of numerator and denominator).
Definition rational.h:58
Stream structure.
Definition avformat.h:768
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:791
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition avformat.h:807
int64_t cur_dts
Definition internal.h:360
volatile uint8_t overflow_flag
Definition fifo.c:81
int64_t timeshift
Definition fifo.c:85
int overflow_flag_lock_initialized
Definition fifo.c:79
atomic_int_least64_t queue_duration
Definition fifo.c:83
int64_t last_sent_dts
Definition fifo.c:84
int recover_any_error
Definition fifo.c:69
int recovery_wait_streamtime
Definition fifo.c:65
int write_trailer_ret
Definition fifo.c:50
pthread_mutex_t overflow_flag_lock
Definition fifo.c:78
AVFormatContext * avf
Definition fifo.c:39
int drop_pkts_on_overflow
Definition fifo.c:72
int queue_size
Definition fifo.c:44
pthread_t writer_thread
Definition fifo.c:47
int attempt_recovery
Definition fifo.c:61
char * format
Definition fifo.c:41
int max_recovery_attempts
Definition fifo.c:58
int restart_with_keyframe
Definition fifo.c:76
int64_t recovery_wait_time
Definition fifo.c:55
AVThreadMessageQueue * queue
Definition fifo.c:45
AVDictionary * format_options
Definition fifo.c:42
FifoMessageType type
Definition fifo.c:122
AVPacket pkt
Definition fifo.c:123
int64_t last_received_dts
Definition fifo.c:108
uint8_t has_video_stream
Definition fifo.c:111
uint8_t header_written
Definition fifo.c:106
uint8_t drop_until_keyframe
Definition fifo.c:101
int recovery_nr
Definition fifo.c:98
int64_t last_recovery_ts
Definition fifo.c:94
AVFormatContext * avf
Definition fifo.c:89
#define av_log(a,...)
void av_thread_message_queue_set_err_send(AVThreadMessageQueue *mq, int err)
Set the sending error code.
int av_thread_message_queue_recv(AVThreadMessageQueue *mq, void *msg, unsigned flags)
Receive a message from the queue.
int av_thread_message_queue_alloc(AVThreadMessageQueue **mq, unsigned nelem, unsigned elsize)
Allocate a new message queue.
void av_thread_message_queue_set_free_func(AVThreadMessageQueue *mq, void(*free_func)(void *msg))
Set the optional free message callback function which will be called if an operation is removing mess...
void av_thread_message_queue_set_err_recv(AVThreadMessageQueue *mq, int err)
Set the receiving error code.
int av_thread_message_queue_send(AVThreadMessageQueue *mq, void *msg, unsigned flags)
Send a message on the queue.
void av_thread_message_flush(AVThreadMessageQueue *mq)
Flush the message queue.
void av_thread_message_queue_free(AVThreadMessageQueue **mq)
Free a message queue.
@ AV_THREAD_MESSAGE_NONBLOCK
Perform non-blocking operation.
int av_usleep(unsigned usec)
Sleep for a period of time.
Definition time.c:93
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
Definition time.c:57
static int write_trailer(AVFormatContext *s1)
Definition v4l2enc.c:101