FFmpeg  4.0
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  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:679
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:1922
#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:1618
AVOption.
Definition: opt.h:246
void av_thread_message_queue_set_err_recv(AVThreadMessageQueue *mq, int err)
Set the receiving error code.
int av_write_frame(AVFormatContext *s, AVPacket *pkt)
Write a packet to an output media file.
Definition: mux.c:878
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:478
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:1342
int64_t cur_dts
Definition: avformat.h:1076
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:5599
static int fifo_mux_init(AVFormatContext *avf, AVOutputFormat *oformat, const char *filename)
Definition: fifo.c:445
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4441
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1410
int64_t last_recovery_ts
Definition: fifo.c:89
const char data[16]
Definition: mxf.c:90
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:1473
int ff_format_output_open(AVFormatContext *s, const char *url, AVDictionary **options)
Utility function to open IO stream of output format.
Definition: utils.c:5589
static int flags
Definition: log.c:55
int ff_stream_encode_params_copy(AVStream *dst, const AVStream *src)
Copy encoding parameters from source to destination stream.
Definition: utils.c:4254
#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:601
int recovery_wait_streamtime
Definition: fifo.c:63
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1462
static int fifo_thread_flush_output(FifoThreadContext *ctx)
Definition: fifo.c:154
static int fifo_thread_write_trailer(FifoThreadContext *ctx)
Definition: fifo.c:193
int avformat_alloc_output_context2(AVFormatContext **ctx, AVOutputFormat *oformat, const char *format_name, const char *filename)
Allocate an AVFormatContext for an output format.
Definition: mux.c:148
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 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:1580
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:694
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
#define AVERROR(e)
Definition: error.h:43
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:1438
#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
#define FFMAX(a, b)
Definition: common.h:94
#define fail()
Definition: checkasm.h:116
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1436
void * opaque
User data.
Definition: avformat.h:1846
AVPacket pkt
Definition: fifo.c:112
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1398
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:508
#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:507
#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
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
#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:873
#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:1384
static int fifo_write_trailer(AVFormatContext *avf)
Definition: fifo.c:585
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:592
void(* io_close)(struct AVFormatContext *s, AVIOContext *pb)
A callback for closing the streams opened with AVFormatContext.io_open().
Definition: avformat.h:1928
Perform non-blocking operation.
Definition: threadmessage.h:31
Describe the class of an AVClass context structure.
Definition: log.h:67
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:4375
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
Definition: time.c:56
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:465
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:1370
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:337
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:1247
#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:1432
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avformat.h:902
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:484
This structure stores compressed data.
Definition: avcodec.h:1407
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1423
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