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;
41 
44 
46 
47  /* Return value of last write_trailer_call */
49 
50  /* Time to wait before next recovery attempt
51  * This can refer to the time in processed stream,
52  * or real time. */
54 
55  /* Maximal number of unsuccessful successive recovery attempts */
57 
58  /* Whether to attempt recovery from failure */
60 
61  /* If >0 stream time will be used when waiting
62  * for the recovery attempt instead of real time */
64 
65  /* If >0 recovery will be attempted regardless of error code
66  * (except AVERROR_EXIT, so exit request is never ignored) */
68 
69  /* Whether to drop packets in case the queue is full. */
71 
72  /* Whether to wait for keyframe when recovering
73  * from failure or queue overflow */
75 
78  /* Value > 0 signals queue overflow */
80 
81 } FifoContext;
82 
83 typedef struct FifoThreadContext {
85 
86  /* Timestamp of last failure.
87  * This is either pts in case stream time is used,
88  * or microseconds as returned by av_getttime_relative() */
90 
91  /* Number of current recovery process
92  * Value > 0 means we are in recovery process */
94 
95  /* If > 0 all frames will be dropped until keyframe is received */
97 
98  /* Value > 0 means that the previous write_header call was successful
99  * so finalization by calling write_trailer and ff_io_close must be done
100  * before exiting / reinitialization of underlying muxer */
103 
104 typedef enum FifoMessageType {
109 
110 typedef struct FifoMessage {
113 } FifoMessage;
114 
116 {
117  AVFormatContext *avf = ctx->avf;
118  FifoContext *fifo = avf->priv_data;
119  AVFormatContext *avf2 = fifo->avf;
121  int ret, i;
122 
123  ret = av_dict_copy(&format_options, fifo->format_options, 0);
124  if (ret < 0)
125  return ret;
126 
127  ret = ff_format_output_open(avf2, avf->url, &format_options);
128  if (ret < 0) {
129  av_log(avf, AV_LOG_ERROR, "Error opening %s: %s\n", avf->url,
130  av_err2str(ret));
131  goto end;
132  }
133 
134  for (i = 0;i < avf2->nb_streams; i++)
135  avf2->streams[i]->cur_dts = 0;
136 
137  ret = avformat_write_header(avf2, &format_options);
138  if (!ret)
139  ctx->header_written = 1;
140 
141  // Check for options unrecognized by underlying muxer
142  if (format_options) {
143  AVDictionaryEntry *entry = NULL;
144  while ((entry = av_dict_get(format_options, "", entry, AV_DICT_IGNORE_SUFFIX)))
145  av_log(avf2, AV_LOG_ERROR, "Unknown option '%s'\n", entry->key);
146  ret = AVERROR(EINVAL);
147  }
148 
149 end:
150  av_dict_free(&format_options);
151  return ret;
152 }
153 
155 {
156  AVFormatContext *avf = ctx->avf;
157  FifoContext *fifo = avf->priv_data;
158  AVFormatContext *avf2 = fifo->avf;
159 
160  return av_write_frame(avf2, NULL);
161 }
162 
164 {
165  AVFormatContext *avf = ctx->avf;
166  FifoContext *fifo = avf->priv_data;
167  AVFormatContext *avf2 = fifo->avf;
168  AVRational src_tb, dst_tb;
169  int ret, s_idx;
170 
171  if (ctx->drop_until_keyframe) {
172  if (pkt->flags & AV_PKT_FLAG_KEY) {
173  ctx->drop_until_keyframe = 0;
174  av_log(avf, AV_LOG_VERBOSE, "Keyframe received, recovering...\n");
175  } else {
176  av_log(avf, AV_LOG_VERBOSE, "Dropping non-keyframe packet\n");
177  av_packet_unref(pkt);
178  return 0;
179  }
180  }
181 
182  s_idx = pkt->stream_index;
183  src_tb = avf->streams[s_idx]->time_base;
184  dst_tb = avf2->streams[s_idx]->time_base;
185  av_packet_rescale_ts(pkt, src_tb, dst_tb);
186 
187  ret = av_write_frame(avf2, pkt);
188  if (ret >= 0)
189  av_packet_unref(pkt);
190  return ret;
191 }
192 
194 {
195  AVFormatContext *avf = ctx->avf;
196  FifoContext *fifo = avf->priv_data;
197  AVFormatContext *avf2 = fifo->avf;
198  int ret;
199 
200  if (!ctx->header_written)
201  return 0;
202 
203  ret = av_write_trailer(avf2);
204  ff_format_io_close(avf2, &avf2->pb);
205 
206  return ret;
207 }
208 
210 {
211  int ret = AVERROR(EINVAL);
212 
213  if (!ctx->header_written) {
214  ret = fifo_thread_write_header(ctx);
215  if (ret < 0)
216  return ret;
217  }
218 
219  switch(msg->type) {
220  case FIFO_WRITE_HEADER:
221  av_assert0(ret >= 0);
222  return ret;
223  case FIFO_WRITE_PACKET:
224  return fifo_thread_write_packet(ctx, &msg->pkt);
225  case FIFO_FLUSH_OUTPUT:
226  return fifo_thread_flush_output(ctx);
227  }
228 
229  av_assert0(0);
230  return AVERROR(EINVAL);
231 }
232 
233 static int is_recoverable(const FifoContext *fifo, int err_no) {
234  if (!fifo->attempt_recovery)
235  return 0;
236 
237  if (fifo->recover_any_error)
238  return err_no != AVERROR_EXIT;
239 
240  switch (err_no) {
241  case AVERROR(EINVAL):
242  case AVERROR(ENOSYS):
243  case AVERROR_EOF:
244  case AVERROR_EXIT:
246  return 0;
247  default:
248  return 1;
249  }
250 }
251 
252 static void free_message(void *msg)
253 {
254  FifoMessage *fifo_msg = msg;
255 
256  if (fifo_msg->type == FIFO_WRITE_PACKET)
257  av_packet_unref(&fifo_msg->pkt);
258 }
259 
261  int err_no)
262 {
263  AVFormatContext *avf = ctx->avf;
264  FifoContext *fifo = avf->priv_data;
265  int ret;
266 
267  av_log(avf, AV_LOG_INFO, "Recovery failed: %s\n",
268  av_err2str(err_no));
269 
270  if (fifo->recovery_wait_streamtime) {
271  if (pkt->pts == AV_NOPTS_VALUE)
272  av_log(avf, AV_LOG_WARNING, "Packet does not contain presentation"
273  " timestamp, recovery will be attempted immediately");
274  ctx->last_recovery_ts = pkt->pts;
275  } else {
277  }
278 
279  if (fifo->max_recovery_attempts &&
280  ctx->recovery_nr >= fifo->max_recovery_attempts) {
281  av_log(avf, AV_LOG_ERROR,
282  "Maximal number of %d recovery attempts reached.\n",
283  fifo->max_recovery_attempts);
284  ret = err_no;
285  } else {
286  ret = AVERROR(EAGAIN);
287  }
288 
289  return ret;
290 }
291 
293 {
294  AVFormatContext *avf = ctx->avf;
295  FifoContext *fifo = avf->priv_data;
296  AVPacket *pkt = &msg->pkt;
297  int64_t time_since_recovery;
298  int ret;
299 
300  if (!is_recoverable(fifo, err_no)) {
301  ret = err_no;
302  goto fail;
303  }
304 
305  if (ctx->header_written) {
307  ctx->header_written = 0;
308  }
309 
310  if (!ctx->recovery_nr) {
312  AV_NOPTS_VALUE : 0;
313  } else {
314  if (fifo->recovery_wait_streamtime) {
315  if (ctx->last_recovery_ts == AV_NOPTS_VALUE) {
317  time_since_recovery = av_rescale_q(pkt->pts - ctx->last_recovery_ts,
318  tb, AV_TIME_BASE_Q);
319  } else {
320  /* Enforce recovery immediately */
321  time_since_recovery = fifo->recovery_wait_time;
322  }
323  } else {
324  time_since_recovery = av_gettime_relative() - ctx->last_recovery_ts;
325  }
326 
327  if (time_since_recovery < fifo->recovery_wait_time)
328  return AVERROR(EAGAIN);
329  }
330 
331  ctx->recovery_nr++;
332 
333  if (fifo->max_recovery_attempts) {
334  av_log(avf, AV_LOG_VERBOSE, "Recovery attempt #%d/%d\n",
335  ctx->recovery_nr, fifo->max_recovery_attempts);
336  } else {
337  av_log(avf, AV_LOG_VERBOSE, "Recovery attempt #%d\n",
338  ctx->recovery_nr);
339  }
340 
341  if (fifo->restart_with_keyframe && fifo->drop_pkts_on_overflow)
342  ctx->drop_until_keyframe = 1;
343 
344  ret = fifo_thread_dispatch_message(ctx, msg);
345  if (ret < 0) {
346  if (is_recoverable(fifo, ret)) {
347  return fifo_thread_process_recovery_failure(ctx, pkt, ret);
348  } else {
349  goto fail;
350  }
351  } else {
352  av_log(avf, AV_LOG_INFO, "Recovery successful\n");
353  ctx->recovery_nr = 0;
354  }
355 
356  return 0;
357 
358 fail:
359  free_message(msg);
360  return ret;
361 }
362 
363 static int fifo_thread_recover(FifoThreadContext *ctx, FifoMessage *msg, int err_no)
364 {
365  AVFormatContext *avf = ctx->avf;
366  FifoContext *fifo = avf->priv_data;
367  int ret;
368 
369  do {
370  if (!fifo->recovery_wait_streamtime && ctx->recovery_nr > 0) {
371  int64_t time_since_recovery = av_gettime_relative() - ctx->last_recovery_ts;
372  int64_t time_to_wait = FFMAX(0, fifo->recovery_wait_time - time_since_recovery);
373  if (time_to_wait)
374  av_usleep(FFMIN(10000, time_to_wait));
375  }
376 
377  ret = fifo_thread_attempt_recovery(ctx, msg, err_no);
378  } while (ret == AVERROR(EAGAIN) && !fifo->drop_pkts_on_overflow);
379 
380  if (ret == AVERROR(EAGAIN) && fifo->drop_pkts_on_overflow) {
381  if (msg->type == FIFO_WRITE_PACKET)
382  av_packet_unref(&msg->pkt);
383  ret = 0;
384  }
385 
386  return ret;
387 }
388 
389 static void *fifo_consumer_thread(void *data)
390 {
392  FifoContext *fifo = avf->priv_data;
394  FifoMessage msg = {FIFO_WRITE_HEADER, {0}};
395  int ret;
396 
397  FifoThreadContext fifo_thread_ctx;
398  memset(&fifo_thread_ctx, 0, sizeof(FifoThreadContext));
399  fifo_thread_ctx.avf = avf;
400 
401  while (1) {
402  uint8_t just_flushed = 0;
403 
404  if (!fifo_thread_ctx.recovery_nr)
405  ret = fifo_thread_dispatch_message(&fifo_thread_ctx, &msg);
406 
407  if (ret < 0 || fifo_thread_ctx.recovery_nr > 0) {
408  int rec_ret = fifo_thread_recover(&fifo_thread_ctx, &msg, ret);
409  if (rec_ret < 0) {
410  av_thread_message_queue_set_err_send(queue, rec_ret);
411  break;
412  }
413  }
414 
415  /* If the queue is full at the moment when fifo_write_packet
416  * attempts to insert new message (packet) to the queue,
417  * it sets the fifo->overflow_flag to 1 and drops packet.
418  * Here in consumer thread, the flag is checked and if it is
419  * set, the queue is flushed and flag cleared. */
421  if (fifo->overflow_flag) {
423  if (fifo->restart_with_keyframe)
424  fifo_thread_ctx.drop_until_keyframe = 1;
425  fifo->overflow_flag = 0;
426  just_flushed = 1;
427  }
429 
430  if (just_flushed)
431  av_log(avf, AV_LOG_INFO, "FIFO queue flushed\n");
432 
433  ret = av_thread_message_queue_recv(queue, &msg, 0);
434  if (ret < 0) {
436  break;
437  }
438  }
439 
440  fifo->write_trailer_ret = fifo_thread_write_trailer(&fifo_thread_ctx);
441 
442  return NULL;
443 }
444 
446  const char *filename)
447 {
448  FifoContext *fifo = avf->priv_data;
449  AVFormatContext *avf2;
450  int ret = 0, i;
451 
452  ret = avformat_alloc_output_context2(&avf2, oformat, NULL, filename);
453  if (ret < 0)
454  return ret;
455 
456  fifo->avf = avf2;
457 
459  avf2->max_delay = avf->max_delay;
460  ret = av_dict_copy(&avf2->metadata, avf->metadata, 0);
461  if (ret < 0)
462  return ret;
463  avf2->opaque = avf->opaque;
464  avf2->io_close = avf->io_close;
465  avf2->io_open = avf->io_open;
466  avf2->flags = avf->flags;
467 
468  for (i = 0; i < avf->nb_streams; ++i) {
469  AVStream *st = avformat_new_stream(avf2, NULL);
470  if (!st)
471  return AVERROR(ENOMEM);
472 
473  ret = ff_stream_encode_params_copy(st, avf->streams[i]);
474  if (ret < 0)
475  return ret;
476  }
477 
478  return 0;
479 }
480 
482 {
483  FifoContext *fifo = avf->priv_data;
484  ff_const59 AVOutputFormat *oformat;
485  int ret = 0;
486 
487  if (fifo->recovery_wait_streamtime && !fifo->drop_pkts_on_overflow) {
488  av_log(avf, AV_LOG_ERROR, "recovery_wait_streamtime can be turned on"
489  " only when drop_pkts_on_overflow is also turned on\n");
490  return AVERROR(EINVAL);
491  }
492 
493  if (fifo->format_options_str) {
495  "=", ":", 0);
496  if (ret < 0) {
497  av_log(avf, AV_LOG_ERROR, "Could not parse format options list '%s'\n",
498  fifo->format_options_str);
499  return ret;
500  }
501  }
502 
503  oformat = av_guess_format(fifo->format, avf->url, NULL);
504  if (!oformat) {
506  return ret;
507  }
508 
509  ret = fifo_mux_init(avf, oformat, avf->url);
510  if (ret < 0)
511  return ret;
512 
513  ret = av_thread_message_queue_alloc(&fifo->queue, (unsigned) fifo->queue_size,
514  sizeof(FifoMessage));
515  if (ret < 0)
516  return ret;
517 
519 
521  if (ret < 0)
522  return AVERROR(ret);
524 
525  return 0;
526 }
527 
529 {
530  FifoContext * fifo = avf->priv_data;
531  int ret;
532 
534  if (ret) {
535  av_log(avf, AV_LOG_ERROR, "Failed to start thread: %s\n",
536  av_err2str(AVERROR(ret)));
537  ret = AVERROR(ret);
538  }
539 
540  return ret;
541 }
542 
544 {
545  FifoContext *fifo = avf->priv_data;
547  int ret;
548 
549  if (pkt) {
550  av_init_packet(&msg.pkt);
551  ret = av_packet_ref(&msg.pkt,pkt);
552  if (ret < 0)
553  return ret;
554  }
555 
556  ret = av_thread_message_queue_send(fifo->queue, &msg,
557  fifo->drop_pkts_on_overflow ?
559  if (ret == AVERROR(EAGAIN)) {
560  uint8_t overflow_set = 0;
561 
562  /* Queue is full, set fifo->overflow_flag to 1
563  * to let consumer thread know the queue should
564  * be flushed. */
566  if (!fifo->overflow_flag)
567  fifo->overflow_flag = overflow_set = 1;
569 
570  if (overflow_set)
571  av_log(avf, AV_LOG_WARNING, "FIFO queue full\n");
572  ret = 0;
573  goto fail;
574  } else if (ret < 0) {
575  goto fail;
576  }
577 
578  return ret;
579 fail:
580  if (pkt)
581  av_packet_unref(&msg.pkt);
582  return ret;
583 }
584 
586 {
587  FifoContext *fifo= avf->priv_data;
588  int ret;
589 
591 
592  ret = pthread_join(fifo->writer_thread, NULL);
593  if (ret < 0) {
594  av_log(avf, AV_LOG_ERROR, "pthread join error: %s\n",
595  av_err2str(AVERROR(ret)));
596  return AVERROR(ret);
597  }
598 
599  ret = fifo->write_trailer_ret;
600  return ret;
601 }
602 
604 {
605  FifoContext *fifo = avf->priv_data;
606 
608  avformat_free_context(fifo->avf);
612 }
613 
614 #define OFFSET(x) offsetof(FifoContext, x)
615 static const AVOption options[] = {
616  {"fifo_format", "Target muxer", OFFSET(format),
618 
619  {"queue_size", "Size of fifo queue", OFFSET(queue_size),
620  AV_OPT_TYPE_INT, {.i64 = FIFO_DEFAULT_QUEUE_SIZE}, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
621 
622  {"format_opts", "Options to be passed to underlying muxer", OFFSET(format_options_str),
623  AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM},
624 
625  {"drop_pkts_on_overflow", "Drop packets on fifo queue overflow not to block encoder", OFFSET(drop_pkts_on_overflow),
626  AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
627 
628  {"restart_with_keyframe", "Wait for keyframe when restarting output", OFFSET(restart_with_keyframe),
629  AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
630 
631  {"attempt_recovery", "Attempt recovery in case of failure", OFFSET(attempt_recovery),
632  AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
633 
634  {"max_recovery_attempts", "Maximal number of recovery attempts", OFFSET(max_recovery_attempts),
635  AV_OPT_TYPE_INT, {.i64 = FIFO_DEFAULT_MAX_RECOVERY_ATTEMPTS}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
636 
637  {"recovery_wait_time", "Waiting time between recovery attempts", OFFSET(recovery_wait_time),
638  AV_OPT_TYPE_DURATION, {.i64 = FIFO_DEFAULT_RECOVERY_WAIT_TIME_USEC}, 0, INT64_MAX, AV_OPT_FLAG_ENCODING_PARAM},
639 
640  {"recovery_wait_streamtime", "Use stream time instead of real time while waiting for recovery",
641  OFFSET(recovery_wait_streamtime), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
642 
643  {"recover_any_error", "Attempt recovery regardless of type of the error", OFFSET(recover_any_error),
644  AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
645 
646  {NULL},
647 };
648 
649 static const AVClass fifo_muxer_class = {
650  .class_name = "Fifo muxer",
651  .item_name = av_default_item_name,
652  .option = options,
653  .version = LIBAVUTIL_VERSION_INT,
654 };
655 
657  .name = "fifo",
658  .long_name = NULL_IF_CONFIG_SMALL("FIFO queue pseudo-muxer"),
659  .priv_data_size = sizeof(FifoContext),
660  .init = fifo_init,
664  .deinit = fifo_deinit,
665  .priv_class = &fifo_muxer_class,
667 };
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:1940
#define NULL
Definition: coverity.c:32
AVFormatContext * avf
Definition: fifo.c:84
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Definition: os2threads.h:108
#define pthread_mutex_lock(a)
Definition: ffprobe.c:61
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition: avformat.h:1636
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:615
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:96
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:252
static const AVClass fifo_muxer_class
Definition: fifo.c:649
#define AVFMT_ALLOW_FLUSH
Format allows flushing.
Definition: avformat.h:476
pthread_mutex_t overflow_flag_lock
Definition: fifo.c:76
char * format
Definition: fifo.c:38
uint8_t header_written
Definition: fifo.c:101
Format I/O context.
Definition: avformat.h:1358
int64_t cur_dts
Definition: avformat.h:1084
AVDictionary * format_options
Definition: fifo.c:40
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:656
uint8_t
static void fifo_deinit(AVFormatContext *avf)
Definition: fifo.c:603
int max_recovery_attempts
Definition: fifo.c:56
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:70
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:5684
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4502
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1426
int64_t last_recovery_ts
Definition: fifo.c:89
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:1489
int ff_format_output_open(AVFormatContext *s, const char *url, AVDictionary **options)
Utility function to open IO stream of output format.
Definition: utils.c:5674
int ff_stream_encode_params_copy(AVStream *dst, const AVStream *src)
Copy encoding parameters from source to destination stream.
Definition: utils.c:4312
#define AVERROR_EOF
End of file.
Definition: error.h:55
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
FifoMessageType
Definition: fifo.c:104
#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:63
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1512
static int fifo_thread_flush_output(FifoThreadContext *ctx)
Definition: fifo.c:154
static int fifo_thread_write_trailer(FifoThreadContext *ctx)
Definition: fifo.c:193
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:481
#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:1598
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:115
void av_thread_message_flush(AVThreadMessageQueue *mq)
Flush the message queue.
static int fifo_write_header(AVFormatContext *avf)
Definition: fifo.c:528
FifoMessageType type
Definition: fifo.c:111
int64_t recovery_wait_time
Definition: fifo.c:53
pthread_t writer_thread
Definition: fifo.c:45
#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:79
char * url
input or output URL.
Definition: avformat.h:1454
#define OFFSET(x)
Definition: fifo.c:614
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:1486
void * opaque
User data.
Definition: avformat.h:1864
AVPacket pkt
Definition: fifo.c:112
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1414
int queue_size
Definition: fifo.c:42
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:93
static int fifo_thread_write_packet(FifoThreadContext *ctx, AVPacket *pkt)
Definition: fifo.c:163
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:90
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Definition: os2threads.h:100
#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:74
Stream structure.
Definition: avformat.h:881
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
int av_dict_parse_string(AVDictionary **pm, const char *str, const char *key_val_sep, const char *pairs_sep, int flags)
Parse the key/value pairs list and add the parsed entries to a dictionary.
Definition: dict.c:180
static av_always_inline int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
Definition: os2threads.h:76
static int fifo_write_packet(AVFormatContext *avf, AVPacket *pkt)
Definition: fifo.c:543
#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:1400
static int fifo_write_trailer(AVFormatContext *avf)
Definition: fifo.c:585
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:1946
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:260
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:43
int write_trailer_ret
Definition: fifo.c:48
static int fifo_thread_attempt_recovery(FifoThreadContext *ctx, FifoMessage *msg, int err_no)
Definition: fifo.c:292
static int fifo_thread_dispatch_message(FifoThreadContext *ctx, FifoMessage *msg)
Definition: fifo.c:209
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: utils.c:4433
static int fifo_mux_init(AVFormatContext *avf, ff_const59 AVOutputFormat *oformat, const char *filename)
Definition: fifo.c:445
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:561
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:49
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:463
char * format_options_str
Definition: fifo.c:39
int attempt_recovery
Definition: fifo.c:59
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:77
void * priv_data
Format private data.
Definition: avformat.h:1386
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:349
static void * fifo_consumer_thread(void *data)
Definition: fifo.c:389
int av_write_trailer(AVFormatContext *s)
Write the stream trailer to an output media file and free the file private data.
Definition: mux.c:1261
#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:363
#define AVERROR_MUXER_NOT_FOUND
Muxer not found.
Definition: error.h:60
int stream_index
Definition: avcodec.h:1482
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avformat.h:910
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:233
#define AVFMT_TS_NEGATIVE
Format allows muxing negative timestamps.
Definition: avformat.h:482
This structure stores compressed data.
Definition: avcodec.h:1457
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1473
int recover_any_error
Definition: fifo.c:67
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
#define tb
Definition: regdef.h:68