FFmpeg
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 "libavutil/avassert.h"
23 #include "libavutil/opt.h"
24 #include "libavutil/time.h"
25 #include "libavutil/thread.h"
27 #include "avformat.h"
28 #include "internal.h"
29 
30 #define FIFO_DEFAULT_QUEUE_SIZE 60
31 #define FIFO_DEFAULT_MAX_RECOVERY_ATTEMPTS 0
32 #define FIFO_DEFAULT_RECOVERY_WAIT_TIME_USEC 5000000 // 5 seconds
33 
34 typedef struct FifoContext {
35  const AVClass *class;
37 
38  char *format;
40 
43 
45 
46  /* Return value of last write_trailer_call */
48 
49  /* Time to wait before next recovery attempt
50  * This can refer to the time in processed stream,
51  * or real time. */
53 
54  /* Maximal number of unsuccessful successive recovery attempts */
56 
57  /* Whether to attempt recovery from failure */
59 
60  /* If >0 stream time will be used when waiting
61  * for the recovery attempt instead of real time */
63 
64  /* If >0 recovery will be attempted regardless of error code
65  * (except AVERROR_EXIT, so exit request is never ignored) */
67 
68  /* Whether to drop packets in case the queue is full. */
70 
71  /* Whether to wait for keyframe when recovering
72  * from failure or queue overflow */
74 
77  /* Value > 0 signals queue overflow */
79 
80 } FifoContext;
81 
82 typedef struct FifoThreadContext {
84 
85  /* Timestamp of last failure.
86  * This is either pts in case stream time is used,
87  * or microseconds as returned by av_getttime_relative() */
89 
90  /* Number of current recovery process
91  * Value > 0 means we are in recovery process */
93 
94  /* If > 0 all frames will be dropped until keyframe is received */
96 
97  /* Value > 0 means that the previous write_header call was successful
98  * so finalization by calling write_trailer and ff_io_close must be done
99  * before exiting / reinitialization of underlying muxer */
102 
103 typedef enum FifoMessageType {
108 
109 typedef struct FifoMessage {
112 } FifoMessage;
113 
115 {
116  AVFormatContext *avf = ctx->avf;
117  FifoContext *fifo = avf->priv_data;
118  AVFormatContext *avf2 = fifo->avf;
119  AVDictionary *format_options = NULL;
120  int ret, i;
121 
122  ret = av_dict_copy(&format_options, fifo->format_options, 0);
123  if (ret < 0)
124  return ret;
125 
126  ret = ff_format_output_open(avf2, avf->url, &format_options);
127  if (ret < 0) {
128  av_log(avf, AV_LOG_ERROR, "Error opening %s: %s\n", avf->url,
129  av_err2str(ret));
130  goto end;
131  }
132 
133  for (i = 0;i < avf2->nb_streams; i++)
134  avf2->streams[i]->cur_dts = 0;
135 
136  ret = avformat_write_header(avf2, &format_options);
137  if (!ret)
138  ctx->header_written = 1;
139 
140  // Check for options unrecognized by underlying muxer
141  if (format_options) {
142  AVDictionaryEntry *entry = NULL;
143  while ((entry = av_dict_get(format_options, "", entry, AV_DICT_IGNORE_SUFFIX)))
144  av_log(avf2, AV_LOG_ERROR, "Unknown option '%s'\n", entry->key);
145  ret = AVERROR(EINVAL);
146  }
147 
148 end:
149  av_dict_free(&format_options);
150  return ret;
151 }
152 
154 {
155  AVFormatContext *avf = ctx->avf;
156  FifoContext *fifo = avf->priv_data;
157  AVFormatContext *avf2 = fifo->avf;
158 
159  return av_write_frame(avf2, NULL);
160 }
161 
163 {
164  AVFormatContext *avf = ctx->avf;
165  FifoContext *fifo = avf->priv_data;
166  AVFormatContext *avf2 = fifo->avf;
167  AVRational src_tb, dst_tb;
168  int ret, s_idx;
169 
170  if (ctx->drop_until_keyframe) {
171  if (pkt->flags & AV_PKT_FLAG_KEY) {
172  ctx->drop_until_keyframe = 0;
173  av_log(avf, AV_LOG_VERBOSE, "Keyframe received, recovering...\n");
174  } else {
175  av_log(avf, AV_LOG_VERBOSE, "Dropping non-keyframe packet\n");
177  return 0;
178  }
179  }
180 
181  s_idx = pkt->stream_index;
182  src_tb = avf->streams[s_idx]->time_base;
183  dst_tb = avf2->streams[s_idx]->time_base;
184  av_packet_rescale_ts(pkt, src_tb, dst_tb);
185 
186  ret = av_write_frame(avf2, pkt);
187  if (ret >= 0)
189  return ret;
190 }
191 
193 {
194  AVFormatContext *avf = ctx->avf;
195  FifoContext *fifo = avf->priv_data;
196  AVFormatContext *avf2 = fifo->avf;
197  int ret;
198 
199  if (!ctx->header_written)
200  return 0;
201 
202  ret = av_write_trailer(avf2);
203  ff_format_io_close(avf2, &avf2->pb);
204 
205  return ret;
206 }
207 
209 {
210  int ret = AVERROR(EINVAL);
211 
212  if (!ctx->header_written) {
214  if (ret < 0)
215  return ret;
216  }
217 
218  switch(msg->type) {
219  case FIFO_WRITE_HEADER:
220  av_assert0(ret >= 0);
221  return ret;
222  case FIFO_WRITE_PACKET:
223  return fifo_thread_write_packet(ctx, &msg->pkt);
224  case FIFO_FLUSH_OUTPUT:
226  }
227 
228  av_assert0(0);
229  return AVERROR(EINVAL);
230 }
231 
232 static int is_recoverable(const FifoContext *fifo, int err_no) {
233  if (!fifo->attempt_recovery)
234  return 0;
235 
236  if (fifo->recover_any_error)
237  return err_no != AVERROR_EXIT;
238 
239  switch (err_no) {
240  case AVERROR(EINVAL):
241  case AVERROR(ENOSYS):
242  case AVERROR_EOF:
243  case AVERROR_EXIT:
245  return 0;
246  default:
247  return 1;
248  }
249 }
250 
251 static void free_message(void *msg)
252 {
253  FifoMessage *fifo_msg = msg;
254 
255  if (fifo_msg->type == FIFO_WRITE_PACKET)
256  av_packet_unref(&fifo_msg->pkt);
257 }
258 
260  int err_no)
261 {
262  AVFormatContext *avf = ctx->avf;
263  FifoContext *fifo = avf->priv_data;
264  int ret;
265 
266  av_log(avf, AV_LOG_INFO, "Recovery failed: %s\n",
267  av_err2str(err_no));
268 
269  if (fifo->recovery_wait_streamtime) {
270  if (pkt->pts == AV_NOPTS_VALUE)
271  av_log(avf, AV_LOG_WARNING, "Packet does not contain presentation"
272  " timestamp, recovery will be attempted immediately");
273  ctx->last_recovery_ts = pkt->pts;
274  } else {
275  ctx->last_recovery_ts = av_gettime_relative();
276  }
277 
278  if (fifo->max_recovery_attempts &&
279  ctx->recovery_nr >= fifo->max_recovery_attempts) {
280  av_log(avf, AV_LOG_ERROR,
281  "Maximal number of %d recovery attempts reached.\n",
282  fifo->max_recovery_attempts);
283  ret = err_no;
284  } else {
285  ret = AVERROR(EAGAIN);
286  }
287 
288  return ret;
289 }
290 
292 {
293  AVFormatContext *avf = ctx->avf;
294  FifoContext *fifo = avf->priv_data;
295  AVPacket *pkt = &msg->pkt;
296  int64_t time_since_recovery;
297  int ret;
298 
299  if (!is_recoverable(fifo, err_no)) {
300  ret = err_no;
301  goto fail;
302  }
303 
304  if (ctx->header_written) {
306  ctx->header_written = 0;
307  }
308 
309  if (!ctx->recovery_nr) {
310  ctx->last_recovery_ts = fifo->recovery_wait_streamtime ?
311  AV_NOPTS_VALUE : 0;
312  } else {
313  if (fifo->recovery_wait_streamtime) {
314  if (ctx->last_recovery_ts == AV_NOPTS_VALUE) {
316  time_since_recovery = av_rescale_q(pkt->pts - ctx->last_recovery_ts,
317  tb, AV_TIME_BASE_Q);
318  } else {
319  /* Enforce recovery immediately */
320  time_since_recovery = fifo->recovery_wait_time;
321  }
322  } else {
323  time_since_recovery = av_gettime_relative() - ctx->last_recovery_ts;
324  }
325 
326  if (time_since_recovery < fifo->recovery_wait_time)
327  return AVERROR(EAGAIN);
328  }
329 
330  ctx->recovery_nr++;
331 
332  if (fifo->max_recovery_attempts) {
333  av_log(avf, AV_LOG_VERBOSE, "Recovery attempt #%d/%d\n",
334  ctx->recovery_nr, fifo->max_recovery_attempts);
335  } else {
336  av_log(avf, AV_LOG_VERBOSE, "Recovery attempt #%d\n",
337  ctx->recovery_nr);
338  }
339 
340  if (fifo->restart_with_keyframe && fifo->drop_pkts_on_overflow)
341  ctx->drop_until_keyframe = 1;
342 
344  if (ret < 0) {
345  if (is_recoverable(fifo, ret)) {
347  } else {
348  goto fail;
349  }
350  } else {
351  av_log(avf, AV_LOG_INFO, "Recovery successful\n");
352  ctx->recovery_nr = 0;
353  }
354 
355  return 0;
356 
357 fail:
358  free_message(msg);
359  return ret;
360 }
361 
362 static int fifo_thread_recover(FifoThreadContext *ctx, FifoMessage *msg, int err_no)
363 {
364  AVFormatContext *avf = ctx->avf;
365  FifoContext *fifo = avf->priv_data;
366  int ret;
367 
368  do {
369  if (!fifo->recovery_wait_streamtime && ctx->recovery_nr > 0) {
370  int64_t time_since_recovery = av_gettime_relative() - ctx->last_recovery_ts;
371  int64_t time_to_wait = FFMAX(0, fifo->recovery_wait_time - time_since_recovery);
372  if (time_to_wait)
373  av_usleep(FFMIN(10000, time_to_wait));
374  }
375 
376  ret = fifo_thread_attempt_recovery(ctx, msg, err_no);
377  } while (ret == AVERROR(EAGAIN) && !fifo->drop_pkts_on_overflow);
378 
379  if (ret == AVERROR(EAGAIN) && fifo->drop_pkts_on_overflow) {
380  if (msg->type == FIFO_WRITE_PACKET)
381  av_packet_unref(&msg->pkt);
382  ret = 0;
383  }
384 
385  return ret;
386 }
387 
388 static void *fifo_consumer_thread(void *data)
389 {
390  AVFormatContext *avf = data;
391  FifoContext *fifo = avf->priv_data;
392  AVThreadMessageQueue *queue = fifo->queue;
393  FifoMessage msg = {FIFO_WRITE_HEADER, {0}};
394  int ret;
395 
396  FifoThreadContext fifo_thread_ctx;
397  memset(&fifo_thread_ctx, 0, sizeof(FifoThreadContext));
398  fifo_thread_ctx.avf = avf;
399 
400  while (1) {
401  uint8_t just_flushed = 0;
402 
403  if (!fifo_thread_ctx.recovery_nr)
404  ret = fifo_thread_dispatch_message(&fifo_thread_ctx, &msg);
405 
406  if (ret < 0 || fifo_thread_ctx.recovery_nr > 0) {
407  int rec_ret = fifo_thread_recover(&fifo_thread_ctx, &msg, ret);
408  if (rec_ret < 0) {
409  av_thread_message_queue_set_err_send(queue, rec_ret);
410  break;
411  }
412  }
413 
414  /* If the queue is full at the moment when fifo_write_packet
415  * attempts to insert new message (packet) to the queue,
416  * it sets the fifo->overflow_flag to 1 and drops packet.
417  * Here in consumer thread, the flag is checked and if it is
418  * set, the queue is flushed and flag cleared. */
420  if (fifo->overflow_flag) {
422  if (fifo->restart_with_keyframe)
423  fifo_thread_ctx.drop_until_keyframe = 1;
424  fifo->overflow_flag = 0;
425  just_flushed = 1;
426  }
428 
429  if (just_flushed)
430  av_log(avf, AV_LOG_INFO, "FIFO queue flushed\n");
431 
432  ret = av_thread_message_queue_recv(queue, &msg, 0);
433  if (ret < 0) {
435  break;
436  }
437  }
438 
439  fifo->write_trailer_ret = fifo_thread_write_trailer(&fifo_thread_ctx);
440 
441  return NULL;
442 }
443 
445  const char *filename)
446 {
447  FifoContext *fifo = avf->priv_data;
448  AVFormatContext *avf2;
449  int ret = 0, i;
450 
451  ret = avformat_alloc_output_context2(&avf2, oformat, NULL, filename);
452  if (ret < 0)
453  return ret;
454 
455  fifo->avf = avf2;
456 
458  avf2->max_delay = avf->max_delay;
459  ret = av_dict_copy(&avf2->metadata, avf->metadata, 0);
460  if (ret < 0)
461  return ret;
462  avf2->opaque = avf->opaque;
463  avf2->io_close = avf->io_close;
464  avf2->io_open = avf->io_open;
465  avf2->flags = avf->flags;
466 
467  for (i = 0; i < avf->nb_streams; ++i) {
468  AVStream *st = avformat_new_stream(avf2, NULL);
469  if (!st)
470  return AVERROR(ENOMEM);
471 
473  if (ret < 0)
474  return ret;
475  }
476 
477  return 0;
478 }
479 
480 static int fifo_init(AVFormatContext *avf)
481 {
482  FifoContext *fifo = avf->priv_data;
483  ff_const59 AVOutputFormat *oformat;
484  int ret = 0;
485 
486  if (fifo->recovery_wait_streamtime && !fifo->drop_pkts_on_overflow) {
487  av_log(avf, AV_LOG_ERROR, "recovery_wait_streamtime can be turned on"
488  " only when drop_pkts_on_overflow is also turned on\n");
489  return AVERROR(EINVAL);
490  }
491 
492  oformat = av_guess_format(fifo->format, avf->url, NULL);
493  if (!oformat) {
495  return ret;
496  }
497 
498  ret = fifo_mux_init(avf, oformat, avf->url);
499  if (ret < 0)
500  return ret;
501 
502  ret = av_thread_message_queue_alloc(&fifo->queue, (unsigned) fifo->queue_size,
503  sizeof(FifoMessage));
504  if (ret < 0)
505  return ret;
506 
508 
510  if (ret < 0)
511  return AVERROR(ret);
513 
514  return 0;
515 }
516 
518 {
519  FifoContext * fifo = avf->priv_data;
520  int ret;
521 
523  if (ret) {
524  av_log(avf, AV_LOG_ERROR, "Failed to start thread: %s\n",
526  ret = AVERROR(ret);
527  }
528 
529  return ret;
530 }
531 
533 {
534  FifoContext *fifo = avf->priv_data;
536  int ret;
537 
538  if (pkt) {
539  ret = av_packet_ref(&msg.pkt,pkt);
540  if (ret < 0)
541  return ret;
542  }
543 
544  ret = av_thread_message_queue_send(fifo->queue, &msg,
545  fifo->drop_pkts_on_overflow ?
547  if (ret == AVERROR(EAGAIN)) {
548  uint8_t overflow_set = 0;
549 
550  /* Queue is full, set fifo->overflow_flag to 1
551  * to let consumer thread know the queue should
552  * be flushed. */
554  if (!fifo->overflow_flag)
555  fifo->overflow_flag = overflow_set = 1;
557 
558  if (overflow_set)
559  av_log(avf, AV_LOG_WARNING, "FIFO queue full\n");
560  ret = 0;
561  goto fail;
562  } else if (ret < 0) {
563  goto fail;
564  }
565 
566  return ret;
567 fail:
568  if (pkt)
569  av_packet_unref(&msg.pkt);
570  return ret;
571 }
572 
574 {
575  FifoContext *fifo= avf->priv_data;
576  int ret;
577 
579 
581  if (ret < 0) {
582  av_log(avf, AV_LOG_ERROR, "pthread join error: %s\n",
584  return AVERROR(ret);
585  }
586 
587  ret = fifo->write_trailer_ret;
588  return ret;
589 }
590 
591 static void fifo_deinit(AVFormatContext *avf)
592 {
593  FifoContext *fifo = avf->priv_data;
594 
595  avformat_free_context(fifo->avf);
599 }
600 
601 #define OFFSET(x) offsetof(FifoContext, x)
602 static const AVOption options[] = {
603  {"fifo_format", "Target muxer", OFFSET(format),
605 
606  {"queue_size", "Size of fifo queue", OFFSET(queue_size),
608 
609  {"format_opts", "Options to be passed to underlying muxer", OFFSET(format_options),
611 
612  {"drop_pkts_on_overflow", "Drop packets on fifo queue overflow not to block encoder", OFFSET(drop_pkts_on_overflow),
613  AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
614 
615  {"restart_with_keyframe", "Wait for keyframe when restarting output", OFFSET(restart_with_keyframe),
616  AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
617 
618  {"attempt_recovery", "Attempt recovery in case of failure", OFFSET(attempt_recovery),
619  AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
620 
621  {"max_recovery_attempts", "Maximal number of recovery attempts", OFFSET(max_recovery_attempts),
623 
624  {"recovery_wait_time", "Waiting time between recovery attempts", OFFSET(recovery_wait_time),
626 
627  {"recovery_wait_streamtime", "Use stream time instead of real time while waiting for recovery",
628  OFFSET(recovery_wait_streamtime), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
629 
630  {"recover_any_error", "Attempt recovery regardless of type of the error", OFFSET(recover_any_error),
631  AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
632 
633  {NULL},
634 };
635 
636 static const AVClass fifo_muxer_class = {
637  .class_name = "Fifo muxer",
638  .item_name = av_default_item_name,
639  .option = options,
640  .version = LIBAVUTIL_VERSION_INT,
641 };
642 
644  .name = "fifo",
645  .long_name = NULL_IF_CONFIG_SMALL("FIFO queue pseudo-muxer"),
646  .priv_data_size = sizeof(FifoContext),
647  .init = fifo_init,
651  .deinit = fifo_deinit,
652  .priv_class = &fifo_muxer_class,
654 };
pthread_mutex_t
_fmutex pthread_mutex_t
Definition: os2threads.h:53
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:605
pthread_join
static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
Definition: os2threads.h:94
av_gettime_relative
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
Definition: time.c:56
fifo_init
static int fifo_init(AVFormatContext *avf)
Definition: fifo.c:480
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
fifo_thread_flush_output
static int fifo_thread_flush_output(FifoThreadContext *ctx)
Definition: fifo.c:153
AVOutputFormat::name
const char * name
Definition: avformat.h:491
AVERROR
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
FifoContext::write_trailer_ret
int write_trailer_ret
Definition: fifo.c:47
opt.h
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4526
FifoContext::queue
AVThreadMessageQueue * queue
Definition: fifo.c:42
FIFO_WRITE_PACKET
@ FIFO_WRITE_PACKET
Definition: fifo.c:105
FifoContext::avf
AVFormatContext * avf
Definition: fifo.c:36
thread.h
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:55
pthread_mutex_init
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Definition: os2threads.h:104
ff_format_output_open
int ff_format_output_open(AVFormatContext *s, const char *url, AVDictionary **options)
Utility function to open IO stream of output format.
Definition: utils.c:5685
fifo_deinit
static void fifo_deinit(AVFormatContext *avf)
Definition: fifo.c:591
FifoContext
Definition: fifo.c:42
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:260
fifo_write_packet
static int fifo_write_packet(AVFormatContext *avf, AVPacket *pkt)
Definition: fifo.c:532
end
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:92
AV_THREAD_MESSAGE_NONBLOCK
@ AV_THREAD_MESSAGE_NONBLOCK
Perform non-blocking operation.
Definition: threadmessage.h:31
AVFormatContext::streams
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1403
free_message
static void free_message(void *msg)
Definition: fifo.c:251
FifoContext::format_options
AVDictionary * format_options
Definition: fifo.c:39
AVOption
AVOption.
Definition: opt.h:246
data
const char data[16]
Definition: mxf.c:91
AV_OPT_TYPE_DURATION
@ AV_OPT_TYPE_DURATION
Definition: opt.h:237
AVStream::cur_dts
int64_t cur_dts
Definition: avformat.h:1068
AV_DICT_IGNORE_SUFFIX
#define AV_DICT_IGNORE_SUFFIX
Return first entry in a dictionary whose first part corresponds to the search key,...
Definition: dict.h:70
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
FifoThreadContext::drop_until_keyframe
uint8_t drop_until_keyframe
Definition: fifo.c:95
AVDictionary
Definition: dict.c:30
FIFO_WRITE_HEADER
@ FIFO_WRITE_HEADER
Definition: fifo.c:104
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:388
FifoContext::overflow_flag
volatile uint8_t overflow_flag
Definition: fifo.c:78
ff_const59
#define ff_const59
The ff_const59 define is not part of the public API and will be removed without further warning.
Definition: avformat.h:535
av_guess_format
ff_const59 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:51
AVFormatContext::interrupt_callback
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition: avformat.h:1613
FifoMessage::type
FifoMessageType type
Definition: fifo.c:110
fail
#define fail()
Definition: checkasm.h:123
FifoMessage
Definition: fifo.c:109
FifoContext::queue_size
int queue_size
Definition: fifo.c:41
av_thread_message_queue_recv
int av_thread_message_queue_recv(AVThreadMessageQueue *mq, void *msg, unsigned flags)
Receive a message from the queue.
Definition: threadmessage.c:172
is_recoverable
static int is_recoverable(const FifoContext *fifo, int err_no)
Definition: fifo.c:232
avassert.h
fifo_thread_process_recovery_failure
static int fifo_thread_process_recovery_failure(FifoThreadContext *ctx, AVPacket *pkt, int err_no)
Definition: fifo.c:259
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
AVFormatContext::metadata
AVDictionary * metadata
Metadata that applies to the whole file.
Definition: avformat.h:1575
av_thread_message_queue_send
int av_thread_message_queue_send(AVThreadMessageQueue *mq, void *msg, unsigned flags)
Send a message on the queue.
Definition: threadmessage.c:156
av_thread_message_flush
void av_thread_message_flush(AVThreadMessageQueue *mq)
Flush the message queue.
Definition: threadmessage.c:218
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:40
FifoContext::overflow_flag_lock
pthread_mutex_t overflow_flag_lock
Definition: fifo.c:75
AV_OPT_FLAG_ENCODING_PARAM
#define AV_OPT_FLAG_ENCODING_PARAM
a generic parameter which can be set by the user for muxing or encoding
Definition: opt.h:276
FifoContext::max_recovery_attempts
int max_recovery_attempts
Definition: fifo.c:55
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1466
format
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
AVDictionaryEntry::key
char * key
Definition: dict.h:82
fifo_thread_write_packet
static int fifo_thread_write_packet(FifoThreadContext *ctx, AVPacket *pkt)
Definition: fifo.c:162
options
static const AVOption options[]
Definition: fifo.c:602
OFFSET
#define OFFSET(x)
Definition: fifo.c:601
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
ctx
AVFormatContext * ctx
Definition: movenc.c:48
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
FIFO_DEFAULT_QUEUE_SIZE
#define FIFO_DEFAULT_QUEUE_SIZE
Definition: fifo.c:30
AVFormatContext::opaque
void * opaque
User data.
Definition: avformat.h:1841
AVThreadMessageQueue
Definition: threadmessage.c:25
fifo_thread_write_trailer
static int fifo_thread_write_trailer(FifoThreadContext *ctx)
Definition: fifo.c:192
av_usleep
int av_usleep(unsigned usec)
Sleep for a period of time.
Definition: time.c:84
avformat_write_header
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:505
pthread_create
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
AVFormatContext
Format I/O context.
Definition: avformat.h:1335
internal.h
FifoThreadContext
Definition: fifo.c:82
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:894
NULL
#define NULL
Definition: coverity.c:32
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
write_trailer
static int write_trailer(AVFormatContext *s1)
Definition: v4l2enc.c:98
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AV_OPT_TYPE_DICT
@ AV_OPT_TYPE_DICT
Definition: opt.h:230
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
AVFormatContext::pb
AVIOContext * pb
I/O context.
Definition: avformat.h:1377
fifo_write_header
static int fifo_write_header(AVFormatContext *avf)
Definition: fifo.c:517
fifo_thread_dispatch_message
static int fifo_thread_dispatch_message(FifoThreadContext *ctx, FifoMessage *msg)
Definition: fifo.c:208
time.h
av_write_frame
int av_write_frame(AVFormatContext *s, AVPacket *pkt)
Write a packet to an output media file.
Definition: mux.c:1190
av_packet_ref
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
Definition: avpacket.c:614
fifo_mux_init
static int fifo_mux_init(AVFormatContext *avf, ff_const59 AVOutputFormat *oformat, const char *filename)
Definition: fifo.c:444
FifoContext::writer_thread
pthread_t writer_thread
Definition: fifo.c:44
pthread_mutex_unlock
#define pthread_mutex_unlock(a)
Definition: ffprobe.c:66
AVFormatContext::nb_streams
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1391
FifoContext::recover_any_error
int recover_any_error
Definition: fifo.c:66
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:188
fifo_consumer_thread
static void * fifo_consumer_thread(void *data)
Definition: fifo.c:388
threadmessage.h
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:119
FifoContext::drop_pkts_on_overflow
int drop_pkts_on_overflow
Definition: fifo.c:69
FFMAX
#define FFMAX(a, b)
Definition: common.h:94
FifoThreadContext::last_recovery_ts
int64_t last_recovery_ts
Definition: fifo.c:88
AVFormatContext::url
char * url
input or output URL.
Definition: avformat.h:1431
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
AVFMT_ALLOW_FLUSH
#define AVFMT_ALLOW_FLUSH
Format allows flushing.
Definition: avformat.h:471
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:458
FifoMessageType
FifoMessageType
Definition: fifo.c:103
FFMIN
#define FFMIN(a, b)
Definition: common.h:96
FifoContext::recovery_wait_streamtime
int recovery_wait_streamtime
Definition: fifo.c:62
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:361
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:203
avformat_alloc_output_context2
int avformat_alloc_output_context2(AVFormatContext **ctx, ff_const59 AVOutputFormat *oformat, const char *format_name, const char *filename)
Allocate an AVFormatContext for an output format.
Definition: mux.c:135
av_packet_rescale_ts
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: avpacket.c:712
pthread_t
Definition: os2threads.h:44
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:187
av_thread_message_queue_alloc
int av_thread_message_queue_alloc(AVThreadMessageQueue **mq, unsigned nelem, unsigned elsize)
Allocate a new message queue.
Definition: threadmessage.c:40
pthread_mutex_destroy
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Definition: os2threads.h:112
write_packet
static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int unqueue)
Definition: ffmpeg.c:702
av_write_trailer
int av_write_trailer(AVFormatContext *s)
Write the stream trailer to an output media file and free the file private data.
Definition: mux.c:1251
FIFO_DEFAULT_MAX_RECOVERY_ATTEMPTS
#define FIFO_DEFAULT_MAX_RECOVERY_ATTEMPTS
Definition: fifo.c:31
FifoMessage::pkt
AVPacket pkt
Definition: fifo.c:111
AVOutputFormat
Definition: avformat.h:490
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:348
AVERROR_MUXER_NOT_FOUND
#define AVERROR_MUXER_NOT_FOUND
Muxer not found.
Definition: error.h:60
av_thread_message_queue_set_err_send
void av_thread_message_queue_set_err_send(AVThreadMessageQueue *mq, int err)
Set the sending error code.
Definition: threadmessage.c:188
uint8_t
uint8_t
Definition: audio_convert.c:194
AVFormatContext::max_delay
int max_delay
Definition: avformat.h:1460
tb
#define tb
Definition: regdef.h:68
FifoThreadContext::recovery_nr
int recovery_nr
Definition: fifo.c:92
AVFMT_TS_NEGATIVE
#define AVFMT_TS_NEGATIVE
Format allows muxing negative timestamps.
Definition: avformat.h:475
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:865
ff_fifo_muxer
AVOutputFormat ff_fifo_muxer
Definition: fifo.c:643
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
FifoContext::restart_with_keyframe
int restart_with_keyframe
Definition: fifo.c:73
avformat.h
ff_stream_encode_params_copy
int ff_stream_encode_params_copy(AVStream *dst, const AVStream *src)
Copy encoding parameters from source to destination stream.
Definition: utils.c:4337
fifo_thread_write_header
static int fifo_thread_write_header(FifoThreadContext *ctx)
Definition: fifo.c:114
pkt
static AVPacket pkt
Definition: demuxing_decoding.c:54
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:223
FifoThreadContext::avf
AVFormatContext * avf
Definition: fifo.c:83
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: utils.c:4455
fifo_muxer_class
static const AVClass fifo_muxer_class
Definition: fifo.c:636
AVFormatContext::io_close
void(* io_close)(struct AVFormatContext *s, AVIOContext *pb)
A callback for closing the streams opened with AVFormatContext.io_open().
Definition: avformat.h:1923
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.
Definition: avformat.h:1917
AVPacket::stream_index
int stream_index
Definition: packet.h:357
ff_format_io_close
void ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: utils.c:5695
FifoContext::attempt_recovery
int attempt_recovery
Definition: fifo.c:58
FIFO_DEFAULT_RECOVERY_WAIT_TIME_USEC
#define FIFO_DEFAULT_RECOVERY_WAIT_TIME_USEC
Definition: fifo.c:32
fifo_thread_recover
static int fifo_thread_recover(FifoThreadContext *ctx, FifoMessage *msg, int err_no)
Definition: fifo.c:362
AVDictionaryEntry
Definition: dict.h:81
fifo_write_trailer
static int fifo_write_trailer(AVFormatContext *avf)
Definition: fifo.c:573
AVPacket
This structure stores compressed data.
Definition: packet.h:332
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:240
av_thread_message_queue_free
void av_thread_message_queue_free(AVThreadMessageQueue **mq)
Free a message queue.
Definition: threadmessage.c:91
av_dict_copy
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition: dict.c:217
fifo_thread_attempt_recovery
static int fifo_thread_attempt_recovery(FifoThreadContext *ctx, FifoMessage *msg, int err_no)
Definition: fifo.c:291
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:565
av_thread_message_queue_set_err_recv
void av_thread_message_queue_set_err_recv(AVThreadMessageQueue *mq, int err)
Set the receiving error code.
Definition: threadmessage.c:199
av_thread_message_queue_set_free_func
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...
Definition: threadmessage.c:83
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVERROR_EXIT
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:56
FifoContext::recovery_wait_time
int64_t recovery_wait_time
Definition: fifo.c:52
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:227
write_header
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:346
init
static av_cold int init(AVFilterContext *ctx)
Definition: fifo.c:54
FIFO_FLUSH_OUTPUT
@ FIFO_FLUSH_OUTPUT
Definition: fifo.c:106
FifoContext::overflow_flag_lock_initialized
int overflow_flag_lock_initialized
Definition: fifo.c:76
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1363
FifoThreadContext::header_written
uint8_t header_written
Definition: fifo.c:100
FifoContext::format
char * format
Definition: fifo.c:38
pthread_mutex_lock
#define pthread_mutex_lock(a)
Definition: ffprobe.c:62