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;
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");
176  av_packet_unref(pkt);
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)
188  av_packet_unref(pkt);
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) {
213  ret = fifo_thread_write_header(ctx);
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:
225  return fifo_thread_flush_output(ctx);
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 {
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) {
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 
343  ret = fifo_thread_dispatch_message(ctx, msg);
344  if (ret < 0) {
345  if (is_recoverable(fifo, ret)) {
346  return fifo_thread_process_recovery_failure(ctx, pkt, 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 {
391  FifoContext *fifo = avf->priv_data;
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 
472  ret = ff_stream_encode_params_copy(st, avf->streams[i]);
473  if (ret < 0)
474  return ret;
475  }
476 
477  return 0;
478 }
479 
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",
525  av_err2str(AVERROR(ret)));
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  av_init_packet(&msg.pkt);
540  ret = av_packet_ref(&msg.pkt,pkt);
541  if (ret < 0)
542  return ret;
543  }
544 
545  ret = av_thread_message_queue_send(fifo->queue, &msg,
546  fifo->drop_pkts_on_overflow ?
548  if (ret == AVERROR(EAGAIN)) {
549  uint8_t overflow_set = 0;
550 
551  /* Queue is full, set fifo->overflow_flag to 1
552  * to let consumer thread know the queue should
553  * be flushed. */
555  if (!fifo->overflow_flag)
556  fifo->overflow_flag = overflow_set = 1;
558 
559  if (overflow_set)
560  av_log(avf, AV_LOG_WARNING, "FIFO queue full\n");
561  ret = 0;
562  goto fail;
563  } else if (ret < 0) {
564  goto fail;
565  }
566 
567  return ret;
568 fail:
569  if (pkt)
570  av_packet_unref(&msg.pkt);
571  return ret;
572 }
573 
575 {
576  FifoContext *fifo= avf->priv_data;
577  int ret;
578 
580 
581  ret = pthread_join(fifo->writer_thread, NULL);
582  if (ret < 0) {
583  av_log(avf, AV_LOG_ERROR, "pthread join error: %s\n",
584  av_err2str(AVERROR(ret)));
585  return AVERROR(ret);
586  }
587 
588  ret = fifo->write_trailer_ret;
589  return ret;
590 }
591 
593 {
594  FifoContext *fifo = avf->priv_data;
595 
596  avformat_free_context(fifo->avf);
600 }
601 
602 #define OFFSET(x) offsetof(FifoContext, x)
603 static const AVOption options[] = {
604  {"fifo_format", "Target muxer", OFFSET(format),
606 
607  {"queue_size", "Size of fifo queue", OFFSET(queue_size),
608  AV_OPT_TYPE_INT, {.i64 = FIFO_DEFAULT_QUEUE_SIZE}, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
609 
610  {"format_opts", "Options to be passed to underlying muxer", OFFSET(format_options),
611  AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM},
612 
613  {"drop_pkts_on_overflow", "Drop packets on fifo queue overflow not to block encoder", OFFSET(drop_pkts_on_overflow),
614  AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
615 
616  {"restart_with_keyframe", "Wait for keyframe when restarting output", OFFSET(restart_with_keyframe),
617  AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
618 
619  {"attempt_recovery", "Attempt recovery in case of failure", OFFSET(attempt_recovery),
620  AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
621 
622  {"max_recovery_attempts", "Maximal number of recovery attempts", OFFSET(max_recovery_attempts),
623  AV_OPT_TYPE_INT, {.i64 = FIFO_DEFAULT_MAX_RECOVERY_ATTEMPTS}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
624 
625  {"recovery_wait_time", "Waiting time between recovery attempts", OFFSET(recovery_wait_time),
626  AV_OPT_TYPE_DURATION, {.i64 = FIFO_DEFAULT_RECOVERY_WAIT_TIME_USEC}, 0, INT64_MAX, AV_OPT_FLAG_ENCODING_PARAM},
627 
628  {"recovery_wait_streamtime", "Use stream time instead of real time while waiting for recovery",
629  OFFSET(recovery_wait_streamtime), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
630 
631  {"recover_any_error", "Attempt recovery regardless of type of the error", OFFSET(recover_any_error),
632  AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
633 
634  {NULL},
635 };
636 
637 static const AVClass fifo_muxer_class = {
638  .class_name = "Fifo muxer",
639  .item_name = av_default_item_name,
640  .option = options,
641  .version = LIBAVUTIL_VERSION_INT,
642 };
643 
645  .name = "fifo",
646  .long_name = NULL_IF_CONFIG_SMALL("FIFO queue pseudo-muxer"),
647  .priv_data_size = sizeof(FifoContext),
648  .init = fifo_init,
652  .deinit = fifo_deinit,
653  .priv_class = &fifo_muxer_class,
655 };
static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int unqueue)
Definition: ffmpeg.c:690
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:1939
#define NULL
Definition: coverity.c:32
AVFormatContext * avf
Definition: fifo.c:83
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Definition: os2threads.h:111
#define pthread_mutex_lock(a)
Definition: ffprobe.c:61
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition: avformat.h:1635
AVOption.
Definition: opt.h:246
void av_thread_message_queue_set_err_recv(AVThreadMessageQueue *mq, int err)
Set the receiving error code.
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
int av_write_frame(AVFormatContext *s, AVPacket *pkt)
Write a packet to an output media file.
Definition: mux.c:885
static av_cold int init(AVFilterContext *ctx)
Definition: fifo.c:54
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
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
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
static const AVOption options[]
Definition: fifo.c:603
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition: dict.c:217
uint8_t drop_until_keyframe
Definition: fifo.c:95
int av_usleep(unsigned usec)
Sleep for a period of time.
Definition: time.c:84
static AVPacket pkt
static void free_message(void *msg)
Definition: fifo.c:251
static const AVClass fifo_muxer_class
Definition: fifo.c:637
#define AVFMT_ALLOW_FLUSH
Format allows flushing.
Definition: avformat.h:476
pthread_mutex_t overflow_flag_lock
Definition: fifo.c:75
char * format
Definition: fifo.c:38
uint8_t header_written
Definition: fifo.c:100
Format I/O context.
Definition: avformat.h:1357
int64_t cur_dts
Definition: avformat.h:1083
AVDictionary * format_options
Definition: fifo.c:39
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
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
AVOutputFormat ff_fifo_muxer
Definition: fifo.c:644
uint8_t
static void fifo_deinit(AVFormatContext *avf)
Definition: fifo.c:592
int max_recovery_attempts
Definition: fifo.c:55
int av_thread_message_queue_recv(AVThreadMessageQueue *mq, void *msg, unsigned flags)
Receive a message from the queue.
AVFormatContext * avf
Definition: fifo.c:36
AVOptions.
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
int drop_pkts_on_overflow
Definition: fifo.c:69
int av_thread_message_queue_send(AVThreadMessageQueue *mq, void *msg, unsigned flags)
Send a message on the queue.
void ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: utils.c:5685
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4504
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1425
int64_t last_recovery_ts
Definition: fifo.c:88
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
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1488
int ff_format_output_open(AVFormatContext *s, const char *url, AVDictionary **options)
Utility function to open IO stream of output format.
Definition: utils.c:5675
int ff_stream_encode_params_copy(AVStream *dst, const AVStream *src)
Copy encoding parameters from source to destination stream.
Definition: utils.c:4314
#define AVERROR_EOF
End of file.
Definition: error.h:55
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
FifoMessageType
Definition: fifo.c:103
#define av_log(a,...)
#define AV_OPT_FLAG_ENCODING_PARAM
a generic parameter which can be set by the user for muxing or encoding
Definition: opt.h:276
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
Definition: avpacket.c:608
int recovery_wait_streamtime
Definition: fifo.c:62
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1526
static int fifo_thread_flush_output(FifoThreadContext *ctx)
Definition: fifo.c:153
static int fifo_thread_write_trailer(FifoThreadContext *ctx)
Definition: fifo.c:192
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
static int fifo_init(AVFormatContext *avf)
Definition: fifo.c:480
#define ff_const59
The ff_const59 define is not part of the public API and will be removed without further warning...
Definition: avformat.h:549
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
AVDictionary * metadata
Metadata that applies to the whole file.
Definition: avformat.h:1597
void av_packet_rescale_ts(AVPacket *pkt, AVRational tb_src, AVRational tb_dst)
Convert valid timing fields (timestamps / durations) in a packet from one timebase to another...
Definition: avpacket.c:704
static int fifo_thread_write_header(FifoThreadContext *ctx)
Definition: fifo.c:114
void av_thread_message_flush(AVThreadMessageQueue *mq)
Flush the message queue.
static int fifo_write_header(AVFormatContext *avf)
Definition: fifo.c:517
FifoMessageType type
Definition: fifo.c:110
int64_t recovery_wait_time
Definition: fifo.c:52
pthread_t writer_thread
Definition: fifo.c:44
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
volatile uint8_t overflow_flag
Definition: fifo.c:78
char * url
input or output URL.
Definition: avformat.h:1453
#define OFFSET(x)
Definition: fifo.c:602
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values. ...
Definition: dict.c:203
simple assert() macros that are a bit more flexible than ISO C assert().
#define FIFO_DEFAULT_MAX_RECOVERY_ATTEMPTS
Definition: fifo.c:31
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:148
#define FFMAX(a, b)
Definition: common.h:94
#define fail()
Definition: checkasm.h:122
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1500
void * opaque
User data.
Definition: avformat.h:1863
AVPacket pkt
Definition: fifo.c:111
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1413
int queue_size
Definition: fifo.c:41
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:516
#define FFMIN(a, b)
Definition: common.h:96
int recovery_nr
Definition: fifo.c:92
static int fifo_thread_write_packet(FifoThreadContext *ctx, AVPacket *pkt)
Definition: fifo.c:162
static int write_trailer(AVFormatContext *s1)
Definition: v4l2enc.c:94
const char * name
Definition: avformat.h:505
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:119
AVFormatContext * ctx
Definition: movenc.c:48
static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
Definition: os2threads.h:93
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Definition: os2threads.h:103
#define pthread_mutex_unlock(a)
Definition: ffprobe.c:65
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:56
#define FIFO_DEFAULT_QUEUE_SIZE
Definition: fifo.c:30
int restart_with_keyframe
Definition: fifo.c:73
Stream structure.
Definition: avformat.h:880
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
static av_always_inline int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
Definition: os2threads.h:79
static int fifo_write_packet(AVFormatContext *avf, AVPacket *pkt)
Definition: fifo.c:532
#define AV_LOG_INFO
Standard information.
Definition: log.h:187
void av_thread_message_queue_set_err_send(AVThreadMessageQueue *mq, int err)
Set the sending error code.
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:260
AVIOContext * pb
I/O context.
Definition: avformat.h:1399
static int fifo_write_trailer(AVFormatContext *avf)
Definition: fifo.c:574
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:599
void(* io_close)(struct AVFormatContext *s, AVIOContext *pb)
A callback for closing the streams opened with AVFormatContext.io_open().
Definition: avformat.h:1945
Perform non-blocking operation.
Definition: threadmessage.h:31
Describe the class of an AVClass context structure.
Definition: log.h:67
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
static int fifo_thread_process_recovery_failure(FifoThreadContext *ctx, AVPacket *pkt, int err_no)
Definition: fifo.c:259
Rational number (pair of numerator and denominator).
Definition: rational.h:58
int av_thread_message_queue_alloc(AVThreadMessageQueue **mq, unsigned nelem, unsigned elsize)
Allocate a new message queue.
Definition: threadmessage.c:40
AVThreadMessageQueue * queue
Definition: fifo.c:42
int write_trailer_ret
Definition: fifo.c:47
static int fifo_thread_attempt_recovery(FifoThreadContext *ctx, FifoMessage *msg, int err_no)
Definition: fifo.c:291
static int fifo_thread_dispatch_message(FifoThreadContext *ctx, FifoMessage *msg)
Definition: fifo.c:208
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: utils.c:4435
static int fifo_mux_init(AVFormatContext *avf, ff_const59 AVOutputFormat *oformat, const char *filename)
Definition: fifo.c:444
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
Definition: time.c:56
#define flags(name, subs,...)
Definition: cbs_av1.c:564
void av_thread_message_queue_free(AVThreadMessageQueue **mq)
Free a message queue.
Definition: threadmessage.c:91
#define FIFO_DEFAULT_RECOVERY_WAIT_TIME_USEC
Definition: fifo.c:32
Main libavformat public API header.
_fmutex pthread_mutex_t
Definition: os2threads.h:52
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:463
int attempt_recovery
Definition: fifo.c:58
void av_init_packet(AVPacket *pkt)
Initialize optional fields of a packet with default values.
Definition: avpacket.c:33
char * key
Definition: dict.h:86
int overflow_flag_lock_initialized
Definition: fifo.c:76
void * priv_data
Format private data.
Definition: avformat.h:1385
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:349
static void * fifo_consumer_thread(void *data)
Definition: fifo.c:388
int av_write_trailer(AVFormatContext *s)
Write the stream trailer to an output media file and free the file private data.
Definition: mux.c:1258
#define AV_DICT_IGNORE_SUFFIX
Return first entry in a dictionary whose first part corresponds to the search key, ignoring the suffix of the found key string.
Definition: dict.h:70
static int fifo_thread_recover(FifoThreadContext *ctx, FifoMessage *msg, int err_no)
Definition: fifo.c:362
#define AVERROR_MUXER_NOT_FOUND
Muxer not found.
Definition: error.h:60
int stream_index
Definition: avcodec.h:1496
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avformat.h:909
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
static int is_recoverable(const FifoContext *fifo, int err_no)
Definition: fifo.c:232
#define AVFMT_TS_NEGATIVE
Format allows muxing negative timestamps.
Definition: avformat.h:482
This structure stores compressed data.
Definition: avcodec.h:1471
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1487
int recover_any_error
Definition: fifo.c:66
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
#define tb
Definition: regdef.h:68