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 <stdatomic.h>
23 
24 #include "libavutil/avassert.h"
25 #include "libavutil/opt.h"
26 #include "libavutil/time.h"
27 #include "libavutil/thread.h"
29 #include "avformat.h"
30 #include "internal.h"
31 #include "mux.h"
32 
33 #define FIFO_DEFAULT_QUEUE_SIZE 60
34 #define FIFO_DEFAULT_MAX_RECOVERY_ATTEMPTS 0
35 #define FIFO_DEFAULT_RECOVERY_WAIT_TIME_USEC 5000000 // 5 seconds
36 
37 typedef struct FifoContext {
38  const AVClass *class;
40 
41  char *format;
43 
46 
48 
49  /* Return value of last write_trailer_call */
51 
52  /* Time to wait before next recovery attempt
53  * This can refer to the time in processed stream,
54  * or real time. */
56 
57  /* Maximal number of unsuccessful successive recovery attempts */
59 
60  /* Whether to attempt recovery from failure */
62 
63  /* If >0 stream time will be used when waiting
64  * for the recovery attempt instead of real time */
66 
67  /* If >0 recovery will be attempted regardless of error code
68  * (except AVERROR_EXIT, so exit request is never ignored) */
70 
71  /* Whether to drop packets in case the queue is full. */
73 
74  /* Whether to wait for keyframe when recovering
75  * from failure or queue overflow */
77 
80  /* Value > 0 signals queue overflow */
81  volatile uint8_t overflow_flag;
82 
86 } FifoContext;
87 
88 typedef struct FifoThreadContext {
90 
91  /* Timestamp of last failure.
92  * This is either pts in case stream time is used,
93  * or microseconds as returned by av_gettime_relative() */
95 
96  /* Number of current recovery process
97  * Value > 0 means we are in recovery process */
99 
100  /* If > 0 all frames will be dropped until keyframe is received */
102 
103  /* Value > 0 means that the previous write_header call was successful
104  * so finalization by calling write_trailer and ff_io_close must be done
105  * before exiting / reinitialization of underlying muxer */
106  uint8_t header_written;
107 
109 
110  /* If > 0 at least one of the streams is a video stream */
113 
114 typedef enum FifoMessageType {
120 
121 typedef struct FifoMessage {
124 } FifoMessage;
125 
127 {
128  AVFormatContext *avf = ctx->avf;
129  FifoContext *fifo = avf->priv_data;
130  AVFormatContext *avf2 = fifo->avf;
131  AVDictionary *format_options = NULL;
132  int ret, i;
133 
134  ret = av_dict_copy(&format_options, fifo->format_options, 0);
135  if (ret < 0)
136  goto end;
137 
138  ret = ff_format_output_open(avf2, avf->url, &format_options);
139  if (ret < 0) {
140  av_log(avf, AV_LOG_ERROR, "Error opening %s: %s\n", avf->url,
141  av_err2str(ret));
142  goto end;
143  }
144 
145  for (i = 0;i < avf2->nb_streams; i++)
146  ffstream(avf2->streams[i])->cur_dts = 0;
147 
148  ret = avformat_write_header(avf2, &format_options);
149  if (!ret)
150  ctx->header_written = 1;
151 
152  // Check for options unrecognized by underlying muxer
153  if (format_options) {
154  const AVDictionaryEntry *entry = NULL;
155  while ((entry = av_dict_iterate(format_options, entry)))
156  av_log(avf2, AV_LOG_ERROR, "Unknown option '%s'\n", entry->key);
157  ret = AVERROR(EINVAL);
158  }
159 
160 end:
161  av_dict_free(&format_options);
162  return ret;
163 }
164 
166 {
167  AVFormatContext *avf = ctx->avf;
168  FifoContext *fifo = avf->priv_data;
169  AVFormatContext *avf2 = fifo->avf;
170 
171  return av_write_frame(avf2, NULL);
172 }
173 
175 {
176  AVStream *st = avf->streams[pkt->stream_index];
178  int64_t duration = (*last_dts == AV_NOPTS_VALUE ? 0 : dts - *last_dts);
179  *last_dts = dts;
180  return duration;
181 }
182 
184 {
185  AVFormatContext *avf = ctx->avf;
186  FifoContext *fifo = avf->priv_data;
187  AVFormatContext *avf2 = fifo->avf;
188  AVRational src_tb, dst_tb;
189  int ret, s_idx;
190  int64_t orig_pts, orig_dts, orig_duration;
191  enum AVMediaType stream_codec_type = avf->streams[pkt->stream_index]->codecpar->codec_type;
192 
193  if (fifo->timeshift && pkt->dts != AV_NOPTS_VALUE)
194  atomic_fetch_sub_explicit(&fifo->queue_duration, next_duration(avf, pkt, &ctx->last_received_dts), memory_order_relaxed);
195 
196  if (ctx->drop_until_keyframe) {
197  if (pkt->flags & AV_PKT_FLAG_KEY) {
198  if (!ctx->has_video_stream) {
199  ctx->drop_until_keyframe = 0;
200  av_log(avf, AV_LOG_VERBOSE, "Keyframe received, recovering...\n");
201  } else {
202  if (stream_codec_type == AVMEDIA_TYPE_VIDEO) {
203  ctx->drop_until_keyframe = 0;
204  av_log(avf, AV_LOG_VERBOSE, "Video keyframe received, recovering...\n");
205  } else {
206  av_log(avf, AV_LOG_VERBOSE, "Dropping non-video keyframe\n");
208  return 0;
209  }
210  }
211  } else {
212  av_log(avf, AV_LOG_VERBOSE, "Dropping non-keyframe packet\n");
214  return 0;
215  }
216  }
217 
218  orig_pts = pkt->pts;
219  orig_dts = pkt->dts;
220  orig_duration = pkt->duration;
221  s_idx = pkt->stream_index;
222  src_tb = avf->streams[s_idx]->time_base;
223  dst_tb = avf2->streams[s_idx]->time_base;
224  av_packet_rescale_ts(pkt, src_tb, dst_tb);
225 
226  ret = av_write_frame(avf2, pkt);
227  if (ret >= 0) {
229  } else {
230  // avoid scaling twice
231  pkt->pts = orig_pts;
232  pkt->dts = orig_dts;
233  pkt->duration = orig_duration;
234  }
235  return ret;
236 }
237 
239 {
240  AVFormatContext *avf = ctx->avf;
241  FifoContext *fifo = avf->priv_data;
242  AVFormatContext *avf2 = fifo->avf;
243  int ret;
244 
245  if (!ctx->header_written)
246  return 0;
247 
248  ret = av_write_trailer(avf2);
249  ff_format_io_close(avf2, &avf2->pb);
250 
251  return ret;
252 }
253 
255 {
256  int ret = AVERROR(EINVAL);
257 
258  if (msg->type == FIFO_NOOP)
259  return 0;
260 
261  if (!ctx->header_written) {
263  if (ret < 0)
264  return ret;
265  }
266 
267  switch(msg->type) {
268  case FIFO_WRITE_HEADER:
269  av_assert0(ret >= 0);
270  return ret;
271  case FIFO_WRITE_PACKET:
272  return fifo_thread_write_packet(ctx, &msg->pkt);
273  case FIFO_FLUSH_OUTPUT:
275  }
276 
277  av_assert0(0);
278  return AVERROR(EINVAL);
279 }
280 
281 static int is_recoverable(const FifoContext *fifo, int err_no) {
282  if (!fifo->attempt_recovery)
283  return 0;
284 
285  if (fifo->recover_any_error)
286  return err_no != AVERROR_EXIT;
287 
288  switch (err_no) {
289  case AVERROR(EINVAL):
290  case AVERROR(ENOSYS):
291  case AVERROR_EOF:
292  case AVERROR_EXIT:
294  return 0;
295  default:
296  return 1;
297  }
298 }
299 
300 static void free_message(void *msg)
301 {
302  FifoMessage *fifo_msg = msg;
303 
304  if (fifo_msg->type == FIFO_WRITE_PACKET)
305  av_packet_unref(&fifo_msg->pkt);
306 }
307 
309  int err_no)
310 {
311  AVFormatContext *avf = ctx->avf;
312  FifoContext *fifo = avf->priv_data;
313  int ret;
314 
315  av_log(avf, AV_LOG_INFO, "Recovery failed: %s\n",
316  av_err2str(err_no));
317 
318  if (fifo->recovery_wait_streamtime) {
319  if (pkt->pts == AV_NOPTS_VALUE)
320  av_log(avf, AV_LOG_WARNING, "Packet does not contain presentation"
321  " timestamp, recovery will be attempted immediately");
322  ctx->last_recovery_ts = pkt->pts;
323  } else {
324  ctx->last_recovery_ts = av_gettime_relative();
325  }
326 
327  if (fifo->max_recovery_attempts &&
328  ctx->recovery_nr >= fifo->max_recovery_attempts) {
329  av_log(avf, AV_LOG_ERROR,
330  "Maximal number of %d recovery attempts reached.\n",
331  fifo->max_recovery_attempts);
332  ret = err_no;
333  } else {
334  ret = AVERROR(EAGAIN);
335  }
336 
337  return ret;
338 }
339 
341 {
342  AVFormatContext *avf = ctx->avf;
343  FifoContext *fifo = avf->priv_data;
344  AVPacket *pkt = &msg->pkt;
345  int64_t time_since_recovery;
346  int ret;
347 
348  if (!is_recoverable(fifo, err_no)) {
349  ret = err_no;
350  goto fail;
351  }
352 
353  if (ctx->header_written) {
355  ctx->header_written = 0;
356  }
357 
358  if (!ctx->recovery_nr) {
359  ctx->last_recovery_ts = fifo->recovery_wait_streamtime ?
360  AV_NOPTS_VALUE : 0;
361  } else {
362  if (fifo->recovery_wait_streamtime) {
363  if (ctx->last_recovery_ts == AV_NOPTS_VALUE) {
365  time_since_recovery = av_rescale_q(pkt->pts - ctx->last_recovery_ts,
366  tb, AV_TIME_BASE_Q);
367  } else {
368  /* Enforce recovery immediately */
369  time_since_recovery = fifo->recovery_wait_time;
370  }
371  } else {
372  time_since_recovery = av_gettime_relative() - ctx->last_recovery_ts;
373  }
374 
375  if (time_since_recovery < fifo->recovery_wait_time)
376  return AVERROR(EAGAIN);
377  }
378 
379  ctx->recovery_nr++;
380 
381  if (fifo->max_recovery_attempts) {
382  av_log(avf, AV_LOG_VERBOSE, "Recovery attempt #%d/%d\n",
383  ctx->recovery_nr, fifo->max_recovery_attempts);
384  } else {
385  av_log(avf, AV_LOG_VERBOSE, "Recovery attempt #%d\n",
386  ctx->recovery_nr);
387  }
388 
389  if (fifo->restart_with_keyframe && fifo->drop_pkts_on_overflow)
390  ctx->drop_until_keyframe = 1;
391 
393  if (ret < 0) {
394  if (is_recoverable(fifo, ret)) {
396  } else {
397  goto fail;
398  }
399  } else {
400  av_log(avf, AV_LOG_INFO, "Recovery successful\n");
401  ctx->recovery_nr = 0;
402  }
403 
404  return 0;
405 
406 fail:
407  free_message(msg);
408  return ret;
409 }
410 
411 static int fifo_thread_recover(FifoThreadContext *ctx, FifoMessage *msg, int err_no)
412 {
413  AVFormatContext *avf = ctx->avf;
414  FifoContext *fifo = avf->priv_data;
415  int ret;
416 
417  do {
418  if (!fifo->recovery_wait_streamtime && ctx->recovery_nr > 0) {
419  int64_t time_since_recovery = av_gettime_relative() - ctx->last_recovery_ts;
420  int64_t time_to_wait = FFMAX(0, fifo->recovery_wait_time - time_since_recovery);
421  if (time_to_wait)
422  av_usleep(FFMIN(10000, time_to_wait));
423  }
424 
425  ret = fifo_thread_attempt_recovery(ctx, msg, err_no);
426  } while (ret == AVERROR(EAGAIN) && !fifo->drop_pkts_on_overflow);
427 
428  if (ret == AVERROR(EAGAIN) && fifo->drop_pkts_on_overflow) {
429  if (msg->type == FIFO_WRITE_PACKET)
430  av_packet_unref(&msg->pkt);
431  ret = 0;
432  }
433 
434  return ret;
435 }
436 
437 static void *fifo_consumer_thread(void *data)
438 {
439  AVFormatContext *avf = data;
440  FifoContext *fifo = avf->priv_data;
441  AVThreadMessageQueue *queue = fifo->queue;
442  FifoMessage msg = {fifo->timeshift ? FIFO_NOOP : FIFO_WRITE_HEADER, {0}};
443  int ret, i;
444 
445  FifoThreadContext fifo_thread_ctx;
446  memset(&fifo_thread_ctx, 0, sizeof(FifoThreadContext));
447  fifo_thread_ctx.avf = avf;
448  fifo_thread_ctx.last_received_dts = AV_NOPTS_VALUE;
449 
450  ff_thread_setname("fifo-consumer");
451 
452  for (i = 0; i < avf->nb_streams; i++) {
454  fifo_thread_ctx.has_video_stream = 1;
455  break;
456  }
457  }
458 
459  while (1) {
460  uint8_t just_flushed = 0;
461 
462  if (!fifo_thread_ctx.recovery_nr)
463  ret = fifo_thread_dispatch_message(&fifo_thread_ctx, &msg);
464 
465  if (ret < 0 || fifo_thread_ctx.recovery_nr > 0) {
466  int rec_ret = fifo_thread_recover(&fifo_thread_ctx, &msg, ret);
467  if (rec_ret < 0) {
468  av_thread_message_queue_set_err_send(queue, rec_ret);
469  break;
470  }
471  }
472 
473  /* If the queue is full at the moment when fifo_write_packet
474  * attempts to insert new message (packet) to the queue,
475  * it sets the fifo->overflow_flag to 1 and drops packet.
476  * Here in consumer thread, the flag is checked and if it is
477  * set, the queue is flushed and flag cleared. */
479  if (fifo->overflow_flag) {
481  if (fifo->restart_with_keyframe)
482  fifo_thread_ctx.drop_until_keyframe = 1;
483  fifo->overflow_flag = 0;
484  just_flushed = 1;
485  }
487 
488  if (just_flushed)
489  av_log(avf, AV_LOG_INFO, "FIFO queue flushed\n");
490 
491  if (fifo->timeshift)
492  while (atomic_load_explicit(&fifo->queue_duration, memory_order_relaxed) < fifo->timeshift)
493  av_usleep(10000);
494 
495  ret = av_thread_message_queue_recv(queue, &msg, 0);
496  if (ret < 0) {
498  break;
499  }
500  }
501 
502  fifo->write_trailer_ret = fifo_thread_write_trailer(&fifo_thread_ctx);
503 
504  return NULL;
505 }
506 
507 static int fifo_mux_init(AVFormatContext *avf, const AVOutputFormat *oformat,
508  const char *filename)
509 {
510  FifoContext *fifo = avf->priv_data;
511  AVFormatContext *avf2;
512  int ret = 0, i;
513 
514  ret = avformat_alloc_output_context2(&avf2, oformat, NULL, filename);
515  if (ret < 0)
516  return ret;
517 
518  fifo->avf = avf2;
519 
521  avf2->max_delay = avf->max_delay;
522  ret = av_dict_copy(&avf2->metadata, avf->metadata, 0);
523  if (ret < 0)
524  return ret;
525  avf2->opaque = avf->opaque;
526  avf2->io_close2 = avf->io_close2;
527  avf2->io_open = avf->io_open;
528  avf2->flags = avf->flags;
529 
530  for (i = 0; i < avf->nb_streams; ++i) {
531  AVStream *st = ff_stream_clone(avf2, avf->streams[i]);
532  if (!st)
533  return AVERROR(ENOMEM);
534  }
535 
536  return 0;
537 }
538 
539 static int fifo_init(AVFormatContext *avf)
540 {
541  FifoContext *fifo = avf->priv_data;
542  const AVOutputFormat *oformat;
543  int ret = 0;
544 
545  if (fifo->recovery_wait_streamtime && !fifo->drop_pkts_on_overflow) {
546  av_log(avf, AV_LOG_ERROR, "recovery_wait_streamtime can be turned on"
547  " only when drop_pkts_on_overflow is also turned on\n");
548  return AVERROR(EINVAL);
549  }
550  atomic_init(&fifo->queue_duration, 0);
552 
553 #ifdef FIFO_TEST
554  /* This exists for the fifo_muxer test tool. */
555  if (fifo->format && !strcmp(fifo->format, "fifo_test")) {
556  extern const FFOutputFormat ff_fifo_test_muxer;
557  oformat = &ff_fifo_test_muxer.p;
558  } else
559 #endif
560  oformat = av_guess_format(fifo->format, avf->url, NULL);
561  if (!oformat) {
563  return ret;
564  }
565 
566  ret = fifo_mux_init(avf, oformat, avf->url);
567  if (ret < 0)
568  return ret;
569 
570  ret = av_thread_message_queue_alloc(&fifo->queue, (unsigned) fifo->queue_size,
571  sizeof(FifoMessage));
572  if (ret < 0)
573  return ret;
574 
576 
578  if (ret < 0)
579  return AVERROR(ret);
581 
582  return 0;
583 }
584 
586 {
587  FifoContext * fifo = avf->priv_data;
588  int ret;
589 
591  if (ret) {
592  av_log(avf, AV_LOG_ERROR, "Failed to start thread: %s\n",
594  ret = AVERROR(ret);
595  }
596 
597  return ret;
598 }
599 
601 {
602  FifoContext *fifo = avf->priv_data;
604  int ret;
605 
606  if (pkt) {
607  ret = av_packet_ref(&msg.pkt,pkt);
608  if (ret < 0)
609  return ret;
610  }
611 
612  ret = av_thread_message_queue_send(fifo->queue, &msg,
613  fifo->drop_pkts_on_overflow ?
615  if (ret == AVERROR(EAGAIN)) {
616  uint8_t overflow_set = 0;
617 
618  /* Queue is full, set fifo->overflow_flag to 1
619  * to let consumer thread know the queue should
620  * be flushed. */
622  if (!fifo->overflow_flag)
623  fifo->overflow_flag = overflow_set = 1;
625 
626  if (overflow_set)
627  av_log(avf, AV_LOG_WARNING, "FIFO queue full\n");
628  ret = 0;
629  goto fail;
630  } else if (ret < 0) {
631  goto fail;
632  }
633 
634  if (fifo->timeshift && pkt && pkt->dts != AV_NOPTS_VALUE)
635  atomic_fetch_add_explicit(&fifo->queue_duration, next_duration(avf, pkt, &fifo->last_sent_dts), memory_order_relaxed);
636 
637  return ret;
638 fail:
639  if (pkt)
640  av_packet_unref(&msg.pkt);
641  return ret;
642 }
643 
645 {
646  FifoContext *fifo= avf->priv_data;
647  int ret;
648 
650  if (fifo->timeshift) {
652  int64_t elapsed = 0;
653  FifoMessage msg = {FIFO_NOOP};
654  do {
655  int64_t delay = av_gettime_relative() - now;
656  if (delay < 0) { // Discontinuity?
657  delay = 10000;
658  now = av_gettime_relative();
659  } else {
660  now += delay;
661  }
662  atomic_fetch_add_explicit(&fifo->queue_duration, delay, memory_order_relaxed);
663  elapsed += delay;
664  if (elapsed > fifo->timeshift)
665  break;
666  av_usleep(10000);
668  } while (ret >= 0 || ret == AVERROR(EAGAIN));
669  atomic_store(&fifo->queue_duration, INT64_MAX);
670  }
671 
673  if (ret < 0) {
674  av_log(avf, AV_LOG_ERROR, "pthread join error: %s\n",
676  return AVERROR(ret);
677  }
678 
679  ret = fifo->write_trailer_ret;
680  return ret;
681 }
682 
683 static void fifo_deinit(AVFormatContext *avf)
684 {
685  FifoContext *fifo = avf->priv_data;
686 
687  avformat_free_context(fifo->avf);
691 }
692 
693 #define OFFSET(x) offsetof(FifoContext, x)
694 static const AVOption options[] = {
695  {"attempt_recovery", "Attempt recovery in case of failure", OFFSET(attempt_recovery),
696  AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
697 
698  {"drop_pkts_on_overflow", "Drop packets on fifo queue overflow not to block encoder", OFFSET(drop_pkts_on_overflow),
699  AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
700 
701  {"fifo_format", "Target muxer", OFFSET(format),
703 
704  {"format_opts", "Options to be passed to underlying muxer", OFFSET(format_options),
706 
707  {"max_recovery_attempts", "Maximal number of recovery attempts", OFFSET(max_recovery_attempts),
709 
710  {"queue_size", "Size of fifo queue", OFFSET(queue_size),
712 
713  {"recovery_wait_streamtime", "Use stream time instead of real time while waiting for recovery",
714  OFFSET(recovery_wait_streamtime), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
715 
716  {"recovery_wait_time", "Waiting time between recovery attempts", OFFSET(recovery_wait_time),
718 
719  {"recover_any_error", "Attempt recovery regardless of type of the error", OFFSET(recover_any_error),
720  AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
721 
722  {"restart_with_keyframe", "Wait for keyframe when restarting output", OFFSET(restart_with_keyframe),
723  AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
724 
725  {"timeshift", "Delay fifo output", OFFSET(timeshift),
726  AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX, AV_OPT_FLAG_ENCODING_PARAM},
727 
728  {NULL},
729 };
730 
731 static const AVClass fifo_muxer_class = {
732  .class_name = "Fifo muxer",
733  .item_name = av_default_item_name,
734  .option = options,
735  .version = LIBAVUTIL_VERSION_INT,
736 };
737 
739  .p.name = "fifo",
740  .p.long_name = NULL_IF_CONFIG_SMALL("FIFO queue pseudo-muxer"),
741  .p.priv_class = &fifo_muxer_class,
742  .p.flags = AVFMT_NOFILE | AVFMT_TS_NEGATIVE,
743  .priv_data_size = sizeof(FifoContext),
744  .init = fifo_init,
748  .deinit = fifo_deinit,
749  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
750 };
pthread_mutex_t
_fmutex pthread_mutex_t
Definition: os2threads.h:53
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:430
FifoThreadContext::has_video_stream
uint8_t has_video_stream
Definition: fifo.c:111
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:539
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
fifo_thread_flush_output
static int fifo_thread_flush_output(FifoThreadContext *ctx)
Definition: fifo.c:165
entry
#define entry
Definition: aom_film_grain_template.c:66
atomic_store
#define atomic_store(object, desired)
Definition: stdatomic.h:85
AVOutputFormat::name
const char * name
Definition: avformat.h:507
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:50
opt.h
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:51
FifoContext::queue
AVThreadMessageQueue * queue
Definition: fifo.c:45
FIFO_WRITE_PACKET
@ FIFO_WRITE_PACKET
Definition: fifo.c:117
FifoContext::avf
AVFormatContext * avf
Definition: fifo.c:39
thread.h
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
pthread_mutex_init
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Definition: os2threads.h:104
fifo_deinit
static void fifo_deinit(AVFormatContext *avf)
Definition: fifo.c:683
FifoContext
Definition: fifo.c:37
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:264
int64_t
long long int64_t
Definition: coverity.c:34
fifo_write_packet
static int fifo_write_packet(AVFormatContext *avf, AVPacket *pkt)
Definition: fifo.c:600
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:1333
deinit
static void deinit(AVFormatContext *s)
Definition: chromaprint.c:52
free_message
static void free_message(void *msg)
Definition: fifo.c:300
FifoContext::format_options
AVDictionary * format_options
Definition: fifo.c:42
pthread_mutex_lock
static av_always_inline int pthread_mutex_lock(pthread_mutex_t *mutex)
Definition: os2threads.h:119
AVOption
AVOption.
Definition: opt.h:429
FIFO_NOOP
@ FIFO_NOOP
Definition: fifo.c:115
data
const char data[16]
Definition: mxf.c:149
AV_OPT_TYPE_DURATION
@ AV_OPT_TYPE_DURATION
Underlying C type is int64_t.
Definition: opt.h:319
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
FifoThreadContext::drop_until_keyframe
uint8_t drop_until_keyframe
Definition: fifo.c:101
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:553
AVDictionary
Definition: dict.c:32
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
FIFO_WRITE_HEADER
@ FIFO_WRITE_HEADER
Definition: fifo.c:116
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:590
FifoContext::overflow_flag
volatile uint8_t overflow_flag
Definition: fifo.c:81
FFOutputFormat::p
AVOutputFormat p
The public AVOutputFormat.
Definition: mux.h:65
ff_fifo_muxer
const FFOutputFormat ff_fifo_muxer
Definition: fifo.c:738
AVFormatContext::interrupt_callback
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition: avformat.h:1535
FifoContext::last_sent_dts
int64_t last_sent_dts
Definition: fifo.c:84
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:347
FifoMessage::type
FifoMessageType type
Definition: fifo.c:122
fail
#define fail()
Definition: checkasm.h:194
FifoMessage
Definition: fifo.c:121
FifoContext::queue_size
int queue_size
Definition: fifo.c:44
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:177
is_recoverable
static int is_recoverable(const FifoContext *fifo, int err_no)
Definition: fifo.c:281
avassert.h
fifo_thread_process_recovery_failure
static int fifo_thread_process_recovery_failure(FifoThreadContext *ctx, AVPacket *pkt, int err_no)
Definition: fifo.c:308
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
AVFormatContext::metadata
AVDictionary * metadata
Metadata that applies to the whole file.
Definition: avformat.h:1497
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:161
av_thread_message_flush
void av_thread_message_flush(AVThreadMessageQueue *mq)
Flush the message queue.
Definition: threadmessage.c:226
duration
int64_t duration
Definition: movenc.c:65
FifoContext::overflow_flag_lock
pthread_mutex_t overflow_flag_lock
Definition: fifo.c:78
pthread_mutex_unlock
static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
Definition: os2threads.h:126
FifoContext::max_recovery_attempts
int max_recovery_attempts
Definition: fifo.c:58
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1416
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
fifo_thread_write_packet
static int fifo_thread_write_packet(FifoThreadContext *ctx, AVPacket *pkt)
Definition: fifo.c:183
options
static const AVOption options[]
Definition: fifo.c:694
OFFSET
#define OFFSET(x)
Definition: fifo.c:693
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
ctx
AVFormatContext * ctx
Definition: movenc.c:49
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:33
AVFormatContext::opaque
void * opaque
User data.
Definition: avformat.h:1824
AVThreadMessageQueue
Definition: threadmessage.c:30
fifo_thread_write_trailer
static int fifo_thread_write_trailer(FifoThreadContext *ctx)
Definition: fifo.c:238
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:467
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:1265
internal.h
FifoThreadContext
Definition: fifo.c:88
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:768
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
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:784
NULL
#define NULL
Definition: coverity.c:32
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
write_trailer
static int write_trailer(AVFormatContext *s1)
Definition: v4l2enc.c:101
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AV_OPT_TYPE_DICT
@ AV_OPT_TYPE_DICT
Underlying C type is AVDictionary*.
Definition: opt.h:290
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:240
AVFormatContext::pb
AVIOContext * pb
I/O context.
Definition: avformat.h:1307
fifo_write_header
static int fifo_write_header(AVFormatContext *avf)
Definition: fifo.c:585
options
Definition: swscale.c:43
FFOutputFormat
Definition: mux.h:61
fifo_thread_dispatch_message
static int fifo_thread_dispatch_message(FifoThreadContext *ctx, FifoMessage *msg)
Definition: fifo.c:254
time.h
av_write_frame
int av_write_frame(AVFormatContext *s, AVPacket *pkt)
Write a packet to an output media file.
Definition: mux.c:1176
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: packet.c:438
atomic_fetch_sub_explicit
#define atomic_fetch_sub_explicit(object, operand, order)
Definition: stdatomic.h:152
atomic_load_explicit
#define atomic_load_explicit(object, order)
Definition: stdatomic.h:96
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:352
FifoContext::writer_thread
pthread_t writer_thread
Definition: fifo.c:47
AVFormatContext::nb_streams
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1321
FifoContext::recover_any_error
int recover_any_error
Definition: fifo.c:69
FifoThreadContext::last_received_dts
int64_t last_received_dts
Definition: fifo.c:108
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:368
AVMediaType
AVMediaType
Definition: avutil.h:199
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:94
FF_OFMT_FLAG_ALLOW_FLUSH
#define FF_OFMT_FLAG_ALLOW_FLUSH
This flag indicates that the muxer stores data internally and supports flushing it.
Definition: mux.h:38
fifo_consumer_thread
static void * fifo_consumer_thread(void *data)
Definition: fifo.c:437
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:122
FifoContext::drop_pkts_on_overflow
int drop_pkts_on_overflow
Definition: fifo.c:72
FifoThreadContext::last_recovery_ts
int64_t last_recovery_ts
Definition: fifo.c:94
AVFormatContext::url
char * url
input or output URL.
Definition: avformat.h:1381
atomic_fetch_add_explicit
#define atomic_fetch_add_explicit(object, operand, order)
Definition: stdatomic.h:149
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:468
ff_format_io_close
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: avformat.c:868
FifoContext::timeshift
int64_t timeshift
Definition: fifo.c:85
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:534
FifoMessageType
FifoMessageType
Definition: fifo.c:114
FifoContext::recovery_wait_streamtime
int recovery_wait_streamtime
Definition: fifo.c:65
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:541
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:233
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: packet.c:534
pthread_t
Definition: os2threads.h:44
FifoContext::queue_duration
atomic_int_least64_t queue_duration
Definition: fifo.c:83
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
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:45
pthread_mutex_destroy
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Definition: os2threads.h:112
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:1238
FIFO_DEFAULT_MAX_RECOVERY_ATTEMPTS
#define FIFO_DEFAULT_MAX_RECOVERY_ATTEMPTS
Definition: fifo.c:34
FifoMessage::pkt
AVPacket pkt
Definition: fifo.c:123
AVOutputFormat
Definition: avformat.h:506
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:528
AVERROR_MUXER_NOT_FOUND
#define AVERROR_MUXER_NOT_FOUND
Muxer not found.
Definition: error.h:62
ff_fifo_test_muxer
const FFOutputFormat ff_fifo_test_muxer
Definition: fifo_muxer.c:148
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:193
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AVFormatContext::max_delay
int max_delay
Definition: avformat.h:1410
write_packet
static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
Definition: ffmpeg_mux.c:209
FifoThreadContext::recovery_nr
int recovery_nr
Definition: fifo.c:98
AVFMT_TS_NEGATIVE
#define AVFMT_TS_NEGATIVE
Format allows muxing negative timestamps.
Definition: avformat.h:491
atomic_int_least64_t
intptr_t atomic_int_least64_t
Definition: stdatomic.h:68
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:745
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:81
FifoContext::restart_with_keyframe
int restart_with_keyframe
Definition: fifo.c:76
avformat.h
fifo_thread_write_header
static int fifo_thread_write_header(FifoThreadContext *ctx)
Definition: fifo.c:126
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
FifoThreadContext::avf
AVFormatContext * avf
Definition: fifo.c:89
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:141
fifo_muxer_class
static const AVClass fifo_muxer_class
Definition: fifo.c:731
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:1865
AVPacket::stream_index
int stream_index
Definition: packet.h:537
next_duration
static int64_t next_duration(AVFormatContext *avf, AVPacket *pkt, int64_t *last_dts)
Definition: fifo.c:174
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
av_guess_format
const AVOutputFormat * av_guess_format(const char *short_name, const char *filename, const char *mime_type)
Return the output format in the list of registered output formats which best matches the provided par...
Definition: format.c:79
FifoContext::attempt_recovery
int attempt_recovery
Definition: fifo.c:61
FIFO_DEFAULT_RECOVERY_WAIT_TIME_USEC
#define FIFO_DEFAULT_RECOVERY_WAIT_TIME_USEC
Definition: fifo.c:35
fifo_thread_recover
static int fifo_thread_recover(FifoThreadContext *ctx, FifoMessage *msg, int err_no)
Definition: fifo.c:411
AVDictionaryEntry
Definition: dict.h:90
fifo_write_trailer
static int fifo_write_trailer(AVFormatContext *avf)
Definition: fifo.c:644
ff_stream_clone
AVStream * ff_stream_clone(AVFormatContext *dst_ctx, const AVStream *src)
Create a new stream and copy to it all parameters from a source stream, with the exception of the ind...
Definition: avformat.c:238
AVPacket
This structure stores compressed data.
Definition: packet.h:512
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
av_thread_message_queue_free
void av_thread_message_queue_free(AVThreadMessageQueue **mq)
Free a message queue.
Definition: threadmessage.c:96
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:247
fifo_thread_attempt_recovery
static int fifo_thread_attempt_recovery(FifoThreadContext *ctx, FifoMessage *msg, int err_no)
Definition: fifo.c:340
FFStream::cur_dts
int64_t cur_dts
Definition: internal.h:338
AVFormatContext::io_close2
int(* io_close2)(struct AVFormatContext *s, AVIOContext *pb)
A callback for closing the streams opened with AVFormatContext.io_open().
Definition: avformat.h:1879
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: mux_utils.c:127
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:204
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:88
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_EXIT
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:58
FifoContext::recovery_wait_time
int64_t recovery_wait_time
Definition: fifo.c:55
atomic_init
#define atomic_init(obj, value)
Definition: stdatomic.h:33
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition: opt.h:276
write_header
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:382
FIFO_FLUSH_OUTPUT
@ FIFO_FLUSH_OUTPUT
Definition: fifo.c:118
fifo_mux_init
static int fifo_mux_init(AVFormatContext *avf, const AVOutputFormat *oformat, const char *filename)
Definition: fifo.c:507
avformat_alloc_output_context2
int avformat_alloc_output_context2(AVFormatContext **ctx, const AVOutputFormat *oformat, const char *format_name, const char *filename)
Allocate an AVFormatContext for an output format.
Definition: mux.c:95
FifoContext::overflow_flag_lock_initialized
int overflow_flag_lock_initialized
Definition: fifo.c:79
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1293
FifoThreadContext::header_written
uint8_t header_written
Definition: fifo.c:106
av_dict_iterate
const AVDictionaryEntry * av_dict_iterate(const AVDictionary *m, const AVDictionaryEntry *prev)
Iterate over a dictionary.
Definition: dict.c:42
FifoContext::format
char * format
Definition: fifo.c:41
ff_thread_setname
static int ff_thread_setname(const char *name)
Definition: thread.h:216
mux.h