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;
120  AVDictionary *format_options = NULL;
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");
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)
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) {
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:
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 {
276  ctx->last_recovery_ts = av_gettime_relative();
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) {
311  ctx->last_recovery_ts = fifo->recovery_wait_streamtime ?
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 
345  if (ret < 0) {
346  if (is_recoverable(fifo, 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 {
391  AVFormatContext *avf = data;
392  FifoContext *fifo = avf->priv_data;
393  AVThreadMessageQueue *queue = fifo->queue;
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 
474  if (ret < 0)
475  return ret;
476  }
477 
478  return 0;
479 }
480 
481 static int fifo_init(AVFormatContext *avf)
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",
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 
593  if (ret < 0) {
594  av_log(avf, AV_LOG_ERROR, "pthread join error: %s\n",
596  return AVERROR(ret);
597  }
598 
599  ret = fifo->write_trailer_ret;
600  return ret;
601 }
602 
603 static void fifo_deinit(AVFormatContext *avf)
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),
621 
622  {"format_opts", "Options to be passed to underlying muxer", OFFSET(format_options_str),
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),
636 
637  {"recovery_wait_time", "Waiting time between recovery attempts", OFFSET(recovery_wait_time),
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 };
pthread_mutex_t
_fmutex pthread_mutex_t
Definition: os2threads.h:49
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:599
pthread_join
static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
Definition: os2threads.h:90
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:481
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
fifo_thread_flush_output
static int fifo_thread_flush_output(FifoThreadContext *ctx)
Definition: fifo.c:154
AVOutputFormat::name
const char * name
Definition: avformat.h:496
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:48
opt.h
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4480
FifoContext::queue
AVThreadMessageQueue * queue
Definition: fifo.c:43
FIFO_WRITE_PACKET
@ FIFO_WRITE_PACKET
Definition: fifo.c:106
FifoContext::avf
AVFormatContext * avf
Definition: fifo.c:36
thread.h
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:55
pthread_mutex_init
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Definition: os2threads.h:100
ff_format_output_open
int ff_format_output_open(AVFormatContext *s, const char *url, AVDictionary **options)
Utility function to open IO stream of output format.
Definition: utils.c:5655
fifo_deinit
static void fifo_deinit(AVFormatContext *avf)
Definition: fifo.c:603
FifoContext
Definition: fifo.c:42
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:260
fifo_write_packet
static int fifo_write_packet(AVFormatContext *avf, AVPacket *pkt)
Definition: fifo.c:543
end
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
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:1410
free_message
static void free_message(void *msg)
Definition: fifo.c:252
FifoContext::format_options
AVDictionary * format_options
Definition: fifo.c:40
AVOption
AVOption.
Definition: opt.h:246
data
const char data[16]
Definition: mxf.c:91
AV_OPT_TYPE_DURATION
@ AV_OPT_TYPE_DURATION
Definition: opt.h:237
AVStream::cur_dts
int64_t cur_dts
Definition: avformat.h:1073
AV_DICT_IGNORE_SUFFIX
#define AV_DICT_IGNORE_SUFFIX
Return first entry in a dictionary whose first part corresponds to the search key,...
Definition: dict.h:70
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
FifoThreadContext::drop_until_keyframe
uint8_t drop_until_keyframe
Definition: fifo.c:96
AVDictionary
Definition: dict.c:30
FIFO_WRITE_HEADER
@ FIFO_WRITE_HEADER
Definition: fifo.c:105
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1509
FifoContext::overflow_flag
volatile uint8_t overflow_flag
Definition: fifo.c:79
ff_const59
#define ff_const59
The ff_const59 define is not part of the public API and will be removed without further warning.
Definition: avformat.h:540
av_guess_format
ff_const59 AVOutputFormat * av_guess_format(const char *short_name, const char *filename, const char *mime_type)
Return the output format in the list of registered output formats which best matches the provided par...
Definition: format.c:51
AVFormatContext::interrupt_callback
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition: avformat.h:1620
FifoMessage::type
FifoMessageType type
Definition: fifo.c:111
fail
#define fail()
Definition: checkasm.h:120
FifoMessage
Definition: fifo.c:110
FifoContext::queue_size
int queue_size
Definition: fifo.c:42
av_thread_message_queue_recv
int av_thread_message_queue_recv(AVThreadMessageQueue *mq, void *msg, unsigned flags)
Receive a message from the queue.
Definition: threadmessage.c:172
is_recoverable
static int is_recoverable(const FifoContext *fifo, int err_no)
Definition: fifo.c:233
avassert.h
fifo_thread_process_recovery_failure
static int fifo_thread_process_recovery_failure(FifoThreadContext *ctx, AVPacket *pkt, int err_no)
Definition: fifo.c:260
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
AVFormatContext::metadata
AVDictionary * metadata
Metadata that applies to the whole file.
Definition: avformat.h:1582
av_thread_message_queue_send
int av_thread_message_queue_send(AVThreadMessageQueue *mq, void *msg, unsigned flags)
Send a message on the queue.
Definition: threadmessage.c:156
av_thread_message_flush
void av_thread_message_flush(AVThreadMessageQueue *mq)
Flush the message queue.
Definition: threadmessage.c:218
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:40
FifoContext::overflow_flag_lock
pthread_mutex_t overflow_flag_lock
Definition: fifo.c:76
AV_OPT_FLAG_ENCODING_PARAM
#define AV_OPT_FLAG_ENCODING_PARAM
a generic parameter which can be set by the user for muxing or encoding
Definition: opt.h:276
FifoContext::max_recovery_attempts
int max_recovery_attempts
Definition: fifo.c:56
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1473
format
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
AVDictionaryEntry::key
char * key
Definition: dict.h:82
fifo_thread_write_packet
static int fifo_thread_write_packet(FifoThreadContext *ctx, AVPacket *pkt)
Definition: fifo.c:163
options
static const AVOption options[]
Definition: fifo.c:615
OFFSET
#define OFFSET(x)
Definition: fifo.c:614
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
ctx
AVFormatContext * ctx
Definition: movenc.c:48
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
FIFO_DEFAULT_QUEUE_SIZE
#define FIFO_DEFAULT_QUEUE_SIZE
Definition: fifo.c:30
AVFormatContext::opaque
void * opaque
User data.
Definition: avformat.h:1848
AVThreadMessageQueue
Definition: threadmessage.c:25
fifo_thread_write_trailer
static int fifo_thread_write_trailer(FifoThreadContext *ctx)
Definition: fifo.c:193
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:508
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:76
AVFormatContext
Format I/O context.
Definition: avformat.h:1342
internal.h
FifoThreadContext
Definition: fifo.c:83
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:899
NULL
#define NULL
Definition: coverity.c:32
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
write_trailer
static int write_trailer(AVFormatContext *s1)
Definition: v4l2enc.c:94
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
AVFormatContext::pb
AVIOContext * pb
I/O context.
Definition: avformat.h:1384
fifo_write_header
static int fifo_write_header(AVFormatContext *avf)
Definition: fifo.c:528
fifo_thread_dispatch_message
static int fifo_thread_dispatch_message(FifoThreadContext *ctx, FifoMessage *msg)
Definition: fifo.c:209
time.h
av_write_frame
int av_write_frame(AVFormatContext *s, AVPacket *pkt)
Write a packet to an output media file.
Definition: mux.c:878
av_packet_ref
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
Definition: avpacket.c:608
fifo_mux_init
static int fifo_mux_init(AVFormatContext *avf, ff_const59 AVOutputFormat *oformat, const char *filename)
Definition: fifo.c:445
FifoContext::writer_thread
pthread_t writer_thread
Definition: fifo.c:45
pthread_mutex_unlock
#define pthread_mutex_unlock(a)
Definition: ffprobe.c:65
AVFormatContext::nb_streams
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1398
FifoContext::recover_any_error
int recover_any_error
Definition: fifo.c:67
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:188
fifo_consumer_thread
static void * fifo_consumer_thread(void *data)
Definition: fifo.c:389
threadmessage.h
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:119
FifoContext::drop_pkts_on_overflow
int drop_pkts_on_overflow
Definition: fifo.c:70
FFMAX
#define FFMAX(a, b)
Definition: common.h:94
FifoThreadContext::last_recovery_ts
int64_t last_recovery_ts
Definition: fifo.c:89
AVFormatContext::url
char * url
input or output URL.
Definition: avformat.h:1438
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
AVFMT_ALLOW_FLUSH
#define AVFMT_ALLOW_FLUSH
Format allows flushing.
Definition: avformat.h:476
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:463
FifoMessageType
FifoMessageType
Definition: fifo.c:104
FFMIN
#define FFMIN(a, b)
Definition: common.h:96
FifoContext::recovery_wait_streamtime
int recovery_wait_streamtime
Definition: fifo.c:63
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1483
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:203
avformat_alloc_output_context2
int avformat_alloc_output_context2(AVFormatContext **ctx, ff_const59 AVOutputFormat *oformat, const char *format_name, const char *filename)
Allocate an AVFormatContext for an output format.
Definition: mux.c:148
av_packet_rescale_ts
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
pthread_t
Definition: os2threads.h:40
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:187
av_thread_message_queue_alloc
int av_thread_message_queue_alloc(AVThreadMessageQueue **mq, unsigned nelem, unsigned elsize)
Allocate a new message queue.
Definition: threadmessage.c:40
pthread_mutex_destroy
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Definition: os2threads.h:108
write_packet
static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int unqueue)
Definition: ffmpeg.c:690
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:1254
FIFO_DEFAULT_MAX_RECOVERY_ATTEMPTS
#define FIFO_DEFAULT_MAX_RECOVERY_ATTEMPTS
Definition: fifo.c:31
FifoMessage::pkt
AVPacket pkt
Definition: fifo.c:112
AVOutputFormat
Definition: avformat.h:495
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1470
AVERROR_MUXER_NOT_FOUND
#define AVERROR_MUXER_NOT_FOUND
Muxer not found.
Definition: error.h:60
av_thread_message_queue_set_err_send
void av_thread_message_queue_set_err_send(AVThreadMessageQueue *mq, int err)
Set the sending error code.
Definition: threadmessage.c:188
uint8_t
uint8_t
Definition: audio_convert.c:194
AVFormatContext::max_delay
int max_delay
Definition: avformat.h:1467
tb
#define tb
Definition: regdef.h:68
FifoThreadContext::recovery_nr
int recovery_nr
Definition: fifo.c:93
AVFMT_TS_NEGATIVE
#define AVFMT_TS_NEGATIVE
Format allows muxing negative timestamps.
Definition: avformat.h:480
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:870
ff_fifo_muxer
AVOutputFormat ff_fifo_muxer
Definition: fifo.c:656
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
FifoContext::restart_with_keyframe
int restart_with_keyframe
Definition: fifo.c:74
avformat.h
ff_stream_encode_params_copy
int ff_stream_encode_params_copy(AVStream *dst, const AVStream *src)
Copy encoding parameters from source to destination stream.
Definition: utils.c:4293
fifo_thread_write_header
static int fifo_thread_write_header(FifoThreadContext *ctx)
Definition: fifo.c:115
pkt
static AVPacket pkt
Definition: demuxing_decoding.c:54
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:223
FifoThreadContext::avf
AVFormatContext * avf
Definition: fifo.c:84
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: utils.c:4414
av_dict_parse_string
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
fifo_muxer_class
static const AVClass fifo_muxer_class
Definition: fifo.c:649
AVFormatContext::io_close
void(* io_close)(struct AVFormatContext *s, AVIOContext *pb)
A callback for closing the streams opened with AVFormatContext.io_open().
Definition: avformat.h:1930
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:1924
AVPacket::stream_index
int stream_index
Definition: avcodec.h:1479
ff_format_io_close
void ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: utils.c:5665
FifoContext::attempt_recovery
int attempt_recovery
Definition: fifo.c:59
FIFO_DEFAULT_RECOVERY_WAIT_TIME_USEC
#define FIFO_DEFAULT_RECOVERY_WAIT_TIME_USEC
Definition: fifo.c:32
fifo_thread_recover
static int fifo_thread_recover(FifoThreadContext *ctx, FifoMessage *msg, int err_no)
Definition: fifo.c:363
AVDictionaryEntry
Definition: dict.h:81
fifo_write_trailer
static int fifo_write_trailer(AVFormatContext *avf)
Definition: fifo.c:585
AVPacket
This structure stores compressed data.
Definition: avcodec.h:1454
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:240
av_thread_message_queue_free
void av_thread_message_queue_free(AVThreadMessageQueue **mq)
Free a message queue.
Definition: threadmessage.c:91
av_dict_copy
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition: dict.c:217
fifo_thread_attempt_recovery
static int fifo_thread_attempt_recovery(FifoThreadContext *ctx, FifoMessage *msg, int err_no)
Definition: fifo.c:292
FifoContext::format_options_str
char * format_options_str
Definition: fifo.c:39
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:565
av_thread_message_queue_set_err_recv
void av_thread_message_queue_set_err_recv(AVThreadMessageQueue *mq, int err)
Set the receiving error code.
Definition: threadmessage.c:199
av_thread_message_queue_set_free_func
void av_thread_message_queue_set_free_func(AVThreadMessageQueue *mq, void(*free_func)(void *msg))
Set the optional free message callback function which will be called if an operation is removing mess...
Definition: threadmessage.c:83
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVERROR_EXIT
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:56
FifoContext::recovery_wait_time
int64_t recovery_wait_time
Definition: fifo.c:53
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:227
write_header
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:337
init
static av_cold int init(AVFilterContext *ctx)
Definition: fifo.c:54
FIFO_FLUSH_OUTPUT
@ FIFO_FLUSH_OUTPUT
Definition: fifo.c:107
FifoContext::overflow_flag_lock_initialized
int overflow_flag_lock_initialized
Definition: fifo.c:77
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1370
FifoThreadContext::header_written
uint8_t header_written
Definition: fifo.c:101
FifoContext::format
char * format
Definition: fifo.c:38
av_init_packet
void av_init_packet(AVPacket *pkt)
Initialize optional fields of a packet with default values.
Definition: avpacket.c:33
pthread_mutex_lock
#define pthread_mutex_lock(a)
Definition: ffprobe.c:61