FFmpeg: libavformat/fifo.c Source File
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
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
40
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 */
82
87
90
91 /* Timestamp of last failure.
92 * This is either pts in case stream time is used,
93 * or microseconds as returned by av_getttime_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
110
117
122
124 {
130
133 goto end;
134
139 goto end;
140 }
141
144
147 ctx->header_written = 1;
148
149 // Check for options unrecognized by underlying muxer
150 if (format_options) {
155 }
156
157 end:
160 }
161
163 {
167
169 }
170
172 {
176 *last_dts = dts;
178 }
179
181 {
187 int64_t orig_pts, orig_dts, orig_duration;
188
191
192 if (
ctx->drop_until_keyframe) {
194 ctx->drop_until_keyframe = 0;
196 } else {
199 return 0;
200 }
201 }
202
210
214 } else {
215 // avoid scaling twice
219 }
221 }
222
224 {
229
230 if (!
ctx->header_written)
231 return 0;
232
235
237 }
238
240 {
242
244 return 0;
245
246 if (!
ctx->header_written) {
250 }
251
260 }
261
264 }
265
268 return 0;
269
272
273 switch (err_no) {
279 return 0;
280 default:
281 return 1;
282 }
283 }
284
286 {
288
291 }
292
294 int err_no)
295 {
299
302
306 " timestamp, recovery will be attempted immediately");
308 } else {
310 }
311
315 "Maximal number of %d recovery attempts reached.\n",
318 } else {
320 }
321
323 }
324
326 {
330 int64_t time_since_recovery;
332
336 }
337
338 if (
ctx->header_written) {
340 ctx->header_written = 0;
341 }
342
343 if (!
ctx->recovery_nr) {
346 } else {
352 } else {
353 /* Enforce recovery immediately */
355 }
356 } else {
358 }
359
360 if (time_since_recovery < fifo->recovery_wait_time)
362 }
363
365
369 } else {
372 }
373
375 ctx->drop_until_keyframe = 1;
376
381 } else {
383 }
384 } else {
386 ctx->recovery_nr = 0;
387 }
388
389 return 0;
390
394 }
395
397 {
401
402 do {
406 if (time_to_wait)
408 }
409
412
417 }
418
420 }
421
423 {
429
432 fifo_thread_ctx.
avf = avf;
434
435 while (1) {
436 uint8_t just_flushed = 0;
437
440
441 if (ret < 0 || fifo_thread_ctx.recovery_nr > 0) {
443 if (rec_ret < 0) {
445 break;
446 }
447 }
448
449 /* If the queue is full at the moment when fifo_write_packet
450 * attempts to insert new message (packet) to the queue,
451 * it sets the fifo->overflow_flag to 1 and drops packet.
452 * Here in consumer thread, the flag is checked and if it is
453 * set, the queue is flushed and flag cleared. */
460 just_flushed = 1;
461 }
463
464 if (just_flushed)
466
470
474 break;
475 }
476 }
477
479
481 }
482
484 const char *filename)
485 {
489
493
495
506
509 if (!st)
511
515 }
516
517 return 0;
518 }
519
521 {
525
528 " only when drop_pkts_on_overflow is also turned on\n");
530 }
533
535 if (!oformat) {
538 }
539
543
548
550
555
556 return 0;
557 }
558
560 {
563
569 }
570
572 }
573
575 {
579
584 }
585
590 uint8_t overflow_set = 0;
591
592 /* Queue is full, set fifo->overflow_flag to 1
593 * to let consumer thread know the queue should
594 * be flushed. */
599
600 if (overflow_set)
604 }
else if (
ret < 0) {
606 }
607
610
616 }
617
619 {
622
626 int64_t elapsed = 0;
628 do {
630 if (delay < 0) { // Discontinuity?
631 delay = 10000;
633 } else {
634 now += delay;
635 }
637 elapsed += delay;
639 break;
644 }
645
651 }
652
655 }
656
658 {
660
665 }
666
667 #define OFFSET(x) offsetof(FifoContext, x)
671
672 {
"queue_size",
"Size of fifo queue",
OFFSET(queue_size),
674
675 {
"format_opts",
"Options to be passed to underlying muxer",
OFFSET(format_options),
677
678 {
"drop_pkts_on_overflow",
"Drop packets on fifo queue overflow not to block encoder",
OFFSET(drop_pkts_on_overflow),
680
681 {
"restart_with_keyframe",
"Wait for keyframe when restarting output",
OFFSET(restart_with_keyframe),
683
684 {
"attempt_recovery",
"Attempt recovery in case of failure",
OFFSET(attempt_recovery),
686
687 {
"max_recovery_attempts",
"Maximal number of recovery attempts",
OFFSET(max_recovery_attempts),
689
690 {
"recovery_wait_time",
"Waiting time between recovery attempts",
OFFSET(recovery_wait_time),
692
693 {"recovery_wait_streamtime", "Use stream time instead of real time while waiting for recovery",
695
696 {
"recover_any_error",
"Attempt recovery regardless of type of the error",
OFFSET(recover_any_error),
698
699 {
"timeshift",
"Delay fifo output",
OFFSET(timeshift),
701
703 };
704
710 };
711
723 };
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define atomic_store(object, desired)
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
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
AVThreadMessageQueue * queue
#define AVERROR_EOF
End of file.
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
@ AV_THREAD_MESSAGE_NONBLOCK
Perform non-blocking operation.
int ff_stream_encode_params_copy(AVStream *dst, const AVStream *src)
Copy encoding parameters from source to destination stream.
AVStream ** streams
A list of all streams in the file.
static void deinit(AVFormatContext *s)
AVDictionary * format_options
#define AV_DICT_IGNORE_SUFFIX
Return first entry in a dictionary whose first part corresponds to the search key,...
#define AV_LOG_VERBOSE
Detailed information.
uint8_t drop_until_keyframe
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
volatile uint8_t overflow_flag
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
int av_thread_message_queue_recv(AVThreadMessageQueue *mq, void *msg, unsigned flags)
Receive a message from the queue.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
AVDictionary * metadata
Metadata that applies to the whole file.
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.
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
pthread_mutex_t overflow_flag_lock
#define AV_OPT_FLAG_ENCODING_PARAM
a generic parameter which can be set by the user for muxing or encoding
int max_recovery_attempts
int flags
Flags modifying the (de)muxer behaviour.
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 format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
#define av_assert0(cond)
assert() equivalent, that is always enabled.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
int av_usleep(unsigned usec)
Sleep for a period of time.
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.
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
Describe the class of an AVClass context structure.
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
static int write_trailer(AVFormatContext *s1)
Rational number (pair of numerator and denominator).
const char * av_default_item_name(void *ptr)
Return the context name.
AVIOContext * pb
I/O context.
int av_write_frame(AVFormatContext *s, AVPacket *pkt)
Write a packet to an output media file.
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
#define atomic_fetch_sub_explicit(object, operand, order)
#define atomic_load_explicit(object, order)
#define pthread_mutex_unlock(a)
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
int64_t last_received_dts
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
int drop_pkts_on_overflow
char * url
input or output URL.
#define atomic_fetch_add_explicit(object, operand, order)
#define AV_NOPTS_VALUE
Undefined timestamp value.
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
int recovery_wait_streamtime
int flags
A combination of AV_PKT_FLAG values.
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
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.
atomic_int_least64_t queue_duration
#define AV_LOG_INFO
Standard information.
int av_thread_message_queue_alloc(AVThreadMessageQueue **mq, unsigned nelem, unsigned elsize)
Allocate a new message queue.
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
int av_write_trailer(AVFormatContext *s)
Write the stream trailer to an output media file and free the file private data.
#define i(width, name, range_min, range_max)
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
#define AVERROR_MUXER_NOT_FOUND
Muxer not found.
void av_thread_message_queue_set_err_send(AVThreadMessageQueue *mq, int err)
Set the sending error code.
intptr_t atomic_int_least64_t
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
int restart_with_keyframe
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
void(* io_close)(struct AVFormatContext *s, AVIOContext *pb)
A callback for closing the streams opened with AVFormatContext.io_open().
int(* io_open)(struct AVFormatContext *s, AVIOContext **pb, const char *url, int flags, AVDictionary **options)
A callback for opening new IO streams.
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...
This structure stores compressed data.
void av_thread_message_queue_free(AVThreadMessageQueue **mq)
Free a message queue.
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
int(* io_close2)(struct AVFormatContext *s, AVIOContext *pb)
A callback for closing the streams opened with AVFormatContext.io_open().
#define flags(name, subs,...)
int ff_format_output_open(AVFormatContext *s, const char *url, AVDictionary **options)
Utility function to open IO stream of output format.
void av_thread_message_queue_set_err_recv(AVThreadMessageQueue *mq, int err)
Set the receiving error code.
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...
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
int64_t recovery_wait_time
static int write_packet(AVFormatContext *s1, AVPacket *pkt)
#define atomic_init(obj, value)
static void write_header(FFV1Context *f)
static av_cold int init(AVFilterContext *ctx)
int overflow_flag_lock_initialized
void * priv_data
Format private data.
#define pthread_mutex_lock(a)
Generated on Wed Aug 24 2022 21:42:02 for FFmpeg by
doxygen
1.8.17