FFmpeg
ffmpeg_mux.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include <stdatomic.h>
20 #include <stdio.h>
21 #include <string.h>
22 
23 #include "ffmpeg.h"
24 #include "ffmpeg_mux.h"
25 #include "objpool.h"
26 #include "sync_queue.h"
27 #include "thread_queue.h"
28 
29 #include "libavutil/fifo.h"
30 #include "libavutil/intreadwrite.h"
31 #include "libavutil/log.h"
32 #include "libavutil/mem.h"
33 #include "libavutil/timestamp.h"
34 #include "libavutil/thread.h"
35 
36 #include "libavcodec/packet.h"
37 
38 #include "libavformat/avformat.h"
39 #include "libavformat/avio.h"
40 
41 int want_sdp = 1;
42 
44 {
45  return (Muxer*)of;
46 }
47 
48 static int64_t filesize(AVIOContext *pb)
49 {
50  int64_t ret = -1;
51 
52  if (pb) {
53  ret = avio_size(pb);
54  if (ret <= 0) // FIXME improve avio_size() so it works with non seekable output too
55  ret = avio_tell(pb);
56  }
57 
58  return ret;
59 }
60 
62 {
63  MuxStream *ms = ms_from_ost(ost);
64  AVFormatContext *s = mux->fc;
65  AVStream *st = ost->st;
66  int64_t fs;
67  uint64_t frame_num;
68  int ret;
69 
70  fs = filesize(s->pb);
72  if (fs >= mux->limit_filesize) {
73  ret = AVERROR_EOF;
74  goto fail;
75  }
76 
77  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->vsync_method == VSYNC_DROP)
79 
81  if (ost->frame_rate.num && ost->is_cfr) {
82  if (pkt->duration > 0)
83  av_log(ost, AV_LOG_WARNING, "Overriding packet duration by frame rate, this should not happen\n");
84  pkt->duration = av_rescale_q(1, av_inv_q(ost->frame_rate),
85  pkt->time_base);
86  }
87  }
88 
90  pkt->time_base = ost->st->time_base;
91 
92  if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) {
93  if (pkt->dts != AV_NOPTS_VALUE &&
94  pkt->pts != AV_NOPTS_VALUE &&
95  pkt->dts > pkt->pts) {
96  av_log(s, AV_LOG_WARNING, "Invalid DTS: %"PRId64" PTS: %"PRId64" in output stream %d:%d, replacing by guess\n",
97  pkt->dts, pkt->pts,
98  ost->file_index, ost->st->index);
99  pkt->pts =
100  pkt->dts = pkt->pts + pkt->dts + ms->last_mux_dts + 1
101  - FFMIN3(pkt->pts, pkt->dts, ms->last_mux_dts + 1)
102  - FFMAX3(pkt->pts, pkt->dts, ms->last_mux_dts + 1);
103  }
105  pkt->dts != AV_NOPTS_VALUE &&
106  ms->last_mux_dts != AV_NOPTS_VALUE) {
107  int64_t max = ms->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT);
108  if (pkt->dts < max) {
109  int loglevel = max - pkt->dts > 2 || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ? AV_LOG_WARNING : AV_LOG_DEBUG;
110  if (exit_on_error)
111  loglevel = AV_LOG_ERROR;
112  av_log(s, loglevel, "Non-monotonous DTS in output stream "
113  "%d:%d; previous: %"PRId64", current: %"PRId64"; ",
114  ost->file_index, ost->st->index, ms->last_mux_dts, pkt->dts);
115  if (exit_on_error) {
116  ret = AVERROR(EINVAL);
117  goto fail;
118  }
119 
120  av_log(s, loglevel, "changing to %"PRId64". This may result "
121  "in incorrect timestamps in the output file.\n",
122  max);
123  if (pkt->pts >= pkt->dts)
124  pkt->pts = FFMAX(pkt->pts, max);
125  pkt->dts = max;
126  }
127  }
128  }
129  ms->last_mux_dts = pkt->dts;
130 
131  ost->data_size_mux += pkt->size;
132  frame_num = atomic_fetch_add(&ost->packets_written, 1);
133 
135 
136  if (debug_ts) {
137  av_log(ost, AV_LOG_INFO, "muxer <- type:%s "
138  "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s duration:%s duration_time:%s size:%d\n",
143  pkt->size
144  );
145  }
146 
147  if (ms->stats.io)
148  enc_stats_write(ost, &ms->stats, NULL, pkt, frame_num);
149 
151  if (ret < 0) {
152  print_error("av_interleaved_write_frame()", ret);
153  goto fail;
154  }
155 
156  return 0;
157 fail:
159  return ret;
160 }
161 
162 static int sync_queue_process(Muxer *mux, OutputStream *ost, AVPacket *pkt, int *stream_eof)
163 {
164  OutputFile *of = &mux->of;
165 
166  if (ost->sq_idx_mux >= 0) {
167  int ret = sq_send(mux->sq_mux, ost->sq_idx_mux, SQPKT(pkt));
168  if (ret < 0) {
169  if (ret == AVERROR_EOF)
170  *stream_eof = 1;
171 
172  return ret;
173  }
174 
175  while (1) {
176  ret = sq_receive(mux->sq_mux, -1, SQPKT(mux->sq_pkt));
177  if (ret < 0)
178  return (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) ? 0 : ret;
179 
180  ret = write_packet(mux, of->streams[ret],
181  mux->sq_pkt);
182  if (ret < 0)
183  return ret;
184  }
185  } else if (pkt)
186  return write_packet(mux, ost, pkt);
187 
188  return 0;
189 }
190 
191 static void thread_set_name(OutputFile *of)
192 {
193  char name[16];
194  snprintf(name, sizeof(name), "mux%d:%s", of->index, of->format->name);
196 }
197 
198 static void *muxer_thread(void *arg)
199 {
200  Muxer *mux = arg;
201  OutputFile *of = &mux->of;
202  AVPacket *pkt = NULL;
203  int ret = 0;
204 
205  pkt = av_packet_alloc();
206  if (!pkt) {
207  ret = AVERROR(ENOMEM);
208  goto finish;
209  }
210 
211  thread_set_name(of);
212 
213  while (1) {
214  OutputStream *ost;
215  int stream_idx, stream_eof = 0;
216 
217  ret = tq_receive(mux->tq, &stream_idx, pkt);
218  if (stream_idx < 0) {
219  av_log(mux, AV_LOG_VERBOSE, "All streams finished\n");
220  ret = 0;
221  break;
222  }
223 
224  ost = of->streams[stream_idx];
225  ret = sync_queue_process(mux, ost, ret < 0 ? NULL : pkt, &stream_eof);
227  if (ret == AVERROR_EOF && stream_eof)
228  tq_receive_finish(mux->tq, stream_idx);
229  else if (ret < 0) {
230  av_log(mux, AV_LOG_ERROR, "Error muxing a packet\n");
231  break;
232  }
233  }
234 
235 finish:
237 
238  for (unsigned int i = 0; i < mux->fc->nb_streams; i++)
239  tq_receive_finish(mux->tq, i);
240 
241  av_log(mux, AV_LOG_VERBOSE, "Terminating muxer thread\n");
242 
243  return (void*)(intptr_t)ret;
244 }
245 
247 {
248  int ret = 0;
249 
250  if (!pkt || ost->finished & MUXER_FINISHED)
251  goto finish;
252 
253  ret = tq_send(mux->tq, ost->index, pkt);
254  if (ret < 0)
255  goto finish;
256 
257  return 0;
258 
259 finish:
260  if (pkt)
262 
263  ost->finished |= MUXER_FINISHED;
264  tq_send_finish(mux->tq, ost->index);
265  return ret == AVERROR_EOF ? 0 : ret;
266 }
267 
269 {
270  MuxStream *ms = ms_from_ost(ost);
271  AVPacket *tmp_pkt = NULL;
272  int ret;
273 
274  if (!av_fifo_can_write(ms->muxing_queue)) {
275  size_t cur_size = av_fifo_can_read(ms->muxing_queue);
276  size_t pkt_size = pkt ? pkt->size : 0;
277  unsigned int are_we_over_size =
279  size_t limit = are_we_over_size ? ms->max_muxing_queue_size : SIZE_MAX;
280  size_t new_size = FFMIN(2 * cur_size, limit);
281 
282  if (new_size <= cur_size) {
284  "Too many packets buffered for output stream %d:%d.\n",
285  ost->file_index, ost->st->index);
286  return AVERROR(ENOSPC);
287  }
288  ret = av_fifo_grow2(ms->muxing_queue, new_size - cur_size);
289  if (ret < 0)
290  return ret;
291  }
292 
293  if (pkt) {
295  if (ret < 0)
296  return ret;
297 
298  tmp_pkt = av_packet_alloc();
299  if (!tmp_pkt)
300  return AVERROR(ENOMEM);
301 
302  av_packet_move_ref(tmp_pkt, pkt);
303  ms->muxing_queue_data_size += tmp_pkt->size;
304  }
305  av_fifo_write(ms->muxing_queue, &tmp_pkt, 1);
306 
307  return 0;
308 }
309 
311 {
312  int ret;
313 
314  if (mux->tq) {
315  return thread_submit_packet(mux, ost, pkt);
316  } else {
317  /* the muxer is not initialized yet, buffer the packet */
318  ret = queue_packet(mux, ost, pkt);
319  if (ret < 0) {
320  if (pkt)
322  return ret;
323  }
324  }
325 
326  return 0;
327 }
328 
330 {
331  Muxer *mux = mux_from_of(of);
332  MuxStream *ms = ms_from_ost(ost);
333  const char *err_msg;
334  int ret = 0;
335 
336  if (!eof && pkt->dts != AV_NOPTS_VALUE)
337  ost->last_mux_dts = av_rescale_q(pkt->dts, pkt->time_base, AV_TIME_BASE_Q);
338 
339  /* apply the output bitstream filters */
340  if (ms->bsf_ctx) {
341  int bsf_eof = 0;
342 
343  ret = av_bsf_send_packet(ms->bsf_ctx, eof ? NULL : pkt);
344  if (ret < 0) {
345  err_msg = "submitting a packet for bitstream filtering";
346  goto fail;
347  }
348 
349  while (!bsf_eof) {
351  if (ret == AVERROR(EAGAIN))
352  return;
353  else if (ret == AVERROR_EOF)
354  bsf_eof = 1;
355  else if (ret < 0) {
356  err_msg = "applying bitstream filters to a packet";
357  goto fail;
358  }
359 
360  ret = submit_packet(mux, bsf_eof ? NULL : pkt, ost);
361  if (ret < 0)
362  goto mux_fail;
363  }
364  } else {
365  ret = submit_packet(mux, eof ? NULL : pkt, ost);
366  if (ret < 0)
367  goto mux_fail;
368  }
369 
370  return;
371 
372 mux_fail:
373  err_msg = "submitting a packet to the muxer";
374 
375 fail:
376  av_log(ost, AV_LOG_ERROR, "Error %s\n", err_msg);
377  if (exit_on_error)
378  exit_program(1);
379 
380 }
381 
382 static int thread_stop(Muxer *mux)
383 {
384  void *ret;
385 
386  if (!mux || !mux->tq)
387  return 0;
388 
389  for (unsigned int i = 0; i < mux->fc->nb_streams; i++)
390  tq_send_finish(mux->tq, i);
391 
392  pthread_join(mux->thread, &ret);
393 
394  tq_free(&mux->tq);
395 
396  return (int)(intptr_t)ret;
397 }
398 
399 static void pkt_move(void *dst, void *src)
400 {
401  av_packet_move_ref(dst, src);
402 }
403 
404 static int thread_start(Muxer *mux)
405 {
406  AVFormatContext *fc = mux->fc;
407  ObjPool *op;
408  int ret;
409 
411  if (!op)
412  return AVERROR(ENOMEM);
413 
414  mux->tq = tq_alloc(fc->nb_streams, mux->thread_queue_size, op, pkt_move);
415  if (!mux->tq) {
416  objpool_free(&op);
417  return AVERROR(ENOMEM);
418  }
419 
420  ret = pthread_create(&mux->thread, NULL, muxer_thread, (void*)mux);
421  if (ret) {
422  tq_free(&mux->tq);
423  return AVERROR(ret);
424  }
425 
426  /* flush the muxing queues */
427  for (int i = 0; i < fc->nb_streams; i++) {
428  OutputStream *ost = mux->of.streams[i];
429  MuxStream *ms = ms_from_ost(ost);
430  AVPacket *pkt;
431 
432  /* try to improve muxing time_base (only possible if nothing has been written yet) */
433  if (!av_fifo_can_read(ms->muxing_queue))
434  ost->mux_timebase = ost->st->time_base;
435 
436  while (av_fifo_read(ms->muxing_queue, &pkt, 1) >= 0) {
437  ret = thread_submit_packet(mux, ost, pkt);
438  if (pkt) {
441  }
442  if (ret < 0)
443  return ret;
444  }
445  }
446 
447  return 0;
448 }
449 
450 static int print_sdp(void)
451 {
452  char sdp[16384];
453  int i;
454  int j, ret;
455  AVIOContext *sdp_pb;
456  AVFormatContext **avc;
457 
458  for (i = 0; i < nb_output_files; i++) {
459  if (!mux_from_of(output_files[i])->header_written)
460  return 0;
461  }
462 
463  avc = av_malloc_array(nb_output_files, sizeof(*avc));
464  if (!avc)
465  return AVERROR(ENOMEM);
466  for (i = 0, j = 0; i < nb_output_files; i++) {
467  if (!strcmp(output_files[i]->format->name, "rtp")) {
468  avc[j] = mux_from_of(output_files[i])->fc;
469  j++;
470  }
471  }
472 
473  if (!j) {
474  av_log(NULL, AV_LOG_ERROR, "No output streams in the SDP.\n");
475  ret = AVERROR(EINVAL);
476  goto fail;
477  }
478 
479  ret = av_sdp_create(avc, j, sdp, sizeof(sdp));
480  if (ret < 0)
481  goto fail;
482 
483  if (!sdp_filename) {
484  printf("SDP:\n%s\n", sdp);
485  fflush(stdout);
486  } else {
488  if (ret < 0) {
489  av_log(NULL, AV_LOG_ERROR, "Failed to open sdp file '%s'\n", sdp_filename);
490  goto fail;
491  }
492 
493  avio_print(sdp_pb, sdp);
494  avio_closep(&sdp_pb);
496  }
497 
498  // SDP successfully written, allow muxer threads to start
499  ret = 1;
500 
501 fail:
502  av_freep(&avc);
503  return ret;
504 }
505 
507 {
508  OutputFile *of = &mux->of;
509  AVFormatContext *fc = mux->fc;
510  int ret, i;
511 
512  for (i = 0; i < fc->nb_streams; i++) {
513  OutputStream *ost = of->streams[i];
514  if (!ost->initialized)
515  return 0;
516  }
517 
518  ret = avformat_write_header(fc, &mux->opts);
519  if (ret < 0) {
520  av_log(mux, AV_LOG_ERROR, "Could not write header (incorrect codec "
521  "parameters ?): %s\n", av_err2str(ret));
522  return ret;
523  }
524  //assert_avoptions(of->opts);
525  mux->header_written = 1;
526 
527  av_dump_format(fc, of->index, fc->url, 1);
529 
530  if (sdp_filename || want_sdp) {
531  ret = print_sdp();
532  if (ret < 0) {
533  av_log(NULL, AV_LOG_ERROR, "Error writing the SDP.\n");
534  return ret;
535  } else if (ret == 1) {
536  /* SDP is written only after all the muxers are ready, so now we
537  * start ALL the threads */
538  for (i = 0; i < nb_output_files; i++) {
540  if (ret < 0)
541  return ret;
542  }
543  }
544  } else {
546  if (ret < 0)
547  return ret;
548  }
549 
550  return 0;
551 }
552 
553 static int bsf_init(MuxStream *ms)
554 {
555  OutputStream *ost = &ms->ost;
556  AVBSFContext *ctx = ms->bsf_ctx;
557  int ret;
558 
559  if (!ctx)
560  return 0;
561 
562  ret = avcodec_parameters_copy(ctx->par_in, ost->st->codecpar);
563  if (ret < 0)
564  return ret;
565 
566  ctx->time_base_in = ost->st->time_base;
567 
568  ret = av_bsf_init(ctx);
569  if (ret < 0) {
570  av_log(ms, AV_LOG_ERROR, "Error initializing bitstream filter: %s\n",
571  ctx->filter->name);
572  return ret;
573  }
574 
575  ret = avcodec_parameters_copy(ost->st->codecpar, ctx->par_out);
576  if (ret < 0)
577  return ret;
578  ost->st->time_base = ctx->time_base_out;
579 
580  return 0;
581 }
582 
584 {
585  Muxer *mux = mux_from_of(of);
586  MuxStream *ms = ms_from_ost(ost);
587  int ret;
588 
589  if (ost->sq_idx_mux >= 0)
590  sq_set_tb(mux->sq_mux, ost->sq_idx_mux, ost->mux_timebase);
591 
592  /* initialize bitstream filters for the output stream
593  * needs to be done here, because the codec id for streamcopy is not
594  * known until now */
595  ret = bsf_init(ms);
596  if (ret < 0)
597  return ret;
598 
599  ost->initialized = 1;
600 
601  return mux_check_init(mux);
602 }
603 
605 {
606  Muxer *mux = mux_from_of(of);
607  AVFormatContext *fc = mux->fc;
608  int ret;
609 
610  if (!mux->tq) {
611  av_log(mux, AV_LOG_ERROR,
612  "Nothing was written into output file, because "
613  "at least one of its streams received no packets.\n");
614  return AVERROR(EINVAL);
615  }
616 
617  ret = thread_stop(mux);
618  if (ret < 0)
620 
622  if (ret < 0) {
623  av_log(mux, AV_LOG_ERROR, "Error writing trailer: %s\n", av_err2str(ret));
624  return ret;
625  }
626 
627  mux->last_filesize = filesize(fc->pb);
628 
629  if (!(of->format->flags & AVFMT_NOFILE)) {
630  ret = avio_closep(&fc->pb);
631  if (ret < 0) {
632  av_log(mux, AV_LOG_ERROR, "Error closing file: %s\n", av_err2str(ret));
633  return ret;
634  }
635  }
636 
637  return 0;
638 }
639 
640 static void ost_free(OutputStream **post)
641 {
642  OutputStream *ost = *post;
643  MuxStream *ms;
644 
645  if (!ost)
646  return;
647  ms = ms_from_ost(ost);
648 
649  if (ost->logfile) {
650  if (fclose(ost->logfile))
651  av_log(ms, AV_LOG_ERROR,
652  "Error closing logfile, loss of information possible: %s\n",
653  av_err2str(AVERROR(errno)));
654  ost->logfile = NULL;
655  }
656 
657  if (ms->muxing_queue) {
658  AVPacket *pkt;
659  while (av_fifo_read(ms->muxing_queue, &pkt, 1) >= 0)
662  }
663 
664  av_bsf_free(&ms->bsf_ctx);
665 
666  av_frame_free(&ost->filtered_frame);
667  av_frame_free(&ost->sq_frame);
668  av_frame_free(&ost->last_frame);
669  av_packet_free(&ost->pkt);
670  av_dict_free(&ost->encoder_opts);
671 
672  av_freep(&ost->kf.pts);
673  av_expr_free(ost->kf.pexpr);
674 
675  av_freep(&ost->avfilter);
676  av_freep(&ost->logfile_prefix);
677  av_freep(&ost->apad);
678 
679 #if FFMPEG_OPT_MAP_CHANNEL
680  av_freep(&ost->audio_channels_map);
681  ost->audio_channels_mapped = 0;
682 #endif
683 
684  av_dict_free(&ost->sws_dict);
685  av_dict_free(&ost->swr_opts);
686 
687  if (ost->enc_ctx)
688  av_freep(&ost->enc_ctx->stats_in);
689  avcodec_free_context(&ost->enc_ctx);
690 
691  for (int i = 0; i < ost->enc_stats_pre.nb_components; i++)
692  av_freep(&ost->enc_stats_pre.components[i].str);
693  av_freep(&ost->enc_stats_pre.components);
694 
695  for (int i = 0; i < ost->enc_stats_post.nb_components; i++)
696  av_freep(&ost->enc_stats_post.components[i].str);
697  av_freep(&ost->enc_stats_post.components);
698 
699  for (int i = 0; i < ms->stats.nb_components; i++)
700  av_freep(&ms->stats.components[i].str);
701  av_freep(&ms->stats.components);
702 
703  av_freep(post);
704 }
705 
706 static void fc_close(AVFormatContext **pfc)
707 {
708  AVFormatContext *fc = *pfc;
709 
710  if (!fc)
711  return;
712 
713  if (!(fc->oformat->flags & AVFMT_NOFILE))
714  avio_closep(&fc->pb);
716 
717  *pfc = NULL;
718 }
719 
720 void of_close(OutputFile **pof)
721 {
722  OutputFile *of = *pof;
723  Muxer *mux;
724 
725  if (!of)
726  return;
727  mux = mux_from_of(of);
728 
729  thread_stop(mux);
730 
731  sq_free(&of->sq_encode);
732  sq_free(&mux->sq_mux);
733 
734  for (int i = 0; i < of->nb_streams; i++)
735  ost_free(&of->streams[i]);
736  av_freep(&of->streams);
737 
738  av_dict_free(&mux->opts);
739 
740  av_packet_free(&mux->sq_pkt);
741 
742  fc_close(&mux->fc);
743 
744  av_freep(pof);
745 }
746 
748 {
749  Muxer *mux = mux_from_of(of);
750  return atomic_load(&mux->last_filesize);
751 }
MuxStream::ost
OutputStream ost
Definition: ffmpeg_mux.h:38
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:422
pthread_join
static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
Definition: os2threads.h:94
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:204
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
Muxer::fc
AVFormatContext * fc
Definition: ffmpeg_mux.h:74
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
av_fifo_can_write
size_t av_fifo_can_write(const AVFifo *f)
Definition: fifo.c:94
atomic_store
#define atomic_store(object, desired)
Definition: stdatomic.h:85
ms_from_ost
static MuxStream * ms_from_ost(OutputStream *ost)
Definition: ffmpeg_mux.h:97
AVOutputFormat::name
const char * name
Definition: avformat.h:508
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
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:58
mux_from_of
static Muxer * mux_from_of(OutputFile *of)
Definition: ffmpeg_mux.c:43
Muxer::thread
pthread_t thread
Definition: ffmpeg_mux.h:76
thread.h
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
MuxStream::muxing_queue
AVFifo * muxing_queue
Definition: ffmpeg_mux.h:44
AVFMT_NOTIMESTAMPS
#define AVFMT_NOTIMESTAMPS
Format does not need / have any timestamps.
Definition: avformat.h:479
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:260
print_sdp
static int print_sdp(void)
Definition: ffmpeg_mux.c:450
MuxStream::max_muxing_queue_size
int max_muxing_queue_size
Definition: ffmpeg_mux.h:58
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:99
Muxer::thread_queue_size
int thread_queue_size
Definition: ffmpeg_mux.h:81
MuxStream::muxing_queue_data_threshold
size_t muxing_queue_data_threshold
Definition: ffmpeg_mux.h:61
sync_queue.h
fc_close
static void fc_close(AVFormatContext **pfc)
Definition: ffmpeg_mux.c:706
nb_output_dumped
unsigned nb_output_dumped
Definition: ffmpeg.c:138
Muxer::of
OutputFile of
Definition: ffmpeg_mux.h:69
objpool_free
void objpool_free(ObjPool **pop)
Definition: objpool.c:54
ffmpeg.h
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:551
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:392
max
#define max(a, b)
Definition: cuda_runtime.h:33
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
objpool_alloc_packets
ObjPool * objpool_alloc_packets(void)
Definition: objpool.c:124
av_bsf_free
void av_bsf_free(AVBSFContext **pctx)
Free a bitstream filter context and everything associated with it; write NULL into the supplied point...
Definition: bsf.c:53
avio_size
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:344
ost
static AVStream * ost
Definition: vaapi_transcode.c:42
av_packet_free
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition: avpacket.c:73
AVBSFContext
The bitstream filter state.
Definition: bsf.h:68
queue_packet
static int queue_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
Definition: ffmpeg_mux.c:268
OutputFile::nb_streams
int nb_streams
Definition: ffmpeg.h:701
exit_program
void exit_program(int ret)
Wraps exit with a program-specific cleanup routine.
Definition: cmdutils.c:99
Muxer
Definition: ffmpeg_mux.h:68
debug_ts
int debug_ts
Definition: ffmpeg_opt.c:79
thread_stop
static int thread_stop(Muxer *mux)
Definition: ffmpeg_mux.c:382
objpool.h
print_error
void print_error(const char *filename, int err)
Print an error message to stderr, indicating filename and a human readable description of the error c...
Definition: cmdutils.c:799
of_filesize
int64_t of_filesize(OutputFile *of)
Definition: ffmpeg_mux.c:747
fifo.h
avio_open2
int avio_open2(AVIOContext **s, const char *url, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options)
Create and initialize a AVIOContext for accessing the resource indicated by url.
Definition: aviobuf.c:1241
finish
static void finish(void)
Definition: movenc.c:342
Muxer::tq
ThreadQueue * tq
Definition: ffmpeg_mux.h:77
fail
#define fail()
Definition: checkasm.h:134
av_fifo_write
int av_fifo_write(AVFifo *f, const void *buf, size_t nb_elems)
Write data into a FIFO.
Definition: fifo.c:188
av_fifo_grow2
int av_fifo_grow2(AVFifo *f, size_t inc)
Enlarge an AVFifo.
Definition: fifo.c:99
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:500
sq_receive
int sq_receive(SyncQueue *sq, int stream_idx, SyncQueueFrame frame)
Read a frame from the queue.
Definition: sync_queue.c:339
want_sdp
int want_sdp
Definition: ffmpeg_mux.c:41
of_close
void of_close(OutputFile **pof)
Definition: ffmpeg_mux.c:720
thread_start
static int thread_start(Muxer *mux)
Definition: ffmpeg_mux.c:404
Muxer::sq_pkt
AVPacket * sq_pkt
Definition: ffmpeg_mux.h:89
av_expr_free
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:336
SQPKT
#define SQPKT(pkt)
Definition: sync_queue.h:39
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_dump_format
void av_dump_format(AVFormatContext *ic, int index, const char *url, int is_output)
Print detailed information about the input or output format, such as duration, bitrate,...
Definition: dump.c:629
av_fifo_read
int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems)
Read data from a FIFO.
Definition: fifo.c:240
EncStats::components
EncStatsComponent * components
Definition: ffmpeg.h:528
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:256
mux_check_init
int mux_check_init(Muxer *mux)
Definition: ffmpeg_mux.c:506
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
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
op
static int op(uint8_t **dst, const uint8_t *dst_end, GetByteContext *gb, int pixel, int count, int *x, int width, int linesize)
Perform decode operation.
Definition: anm.c:76
AVIO_FLAG_WRITE
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:624
sq_set_tb
void sq_set_tb(SyncQueue *sq, unsigned int stream_idx, AVRational tb)
Set the timebase for the stream with index stream_idx.
Definition: sync_queue.c:378
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
MUXER_FINISHED
@ MUXER_FINISHED
Definition: ffmpeg.h:538
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
enc_stats_write
void enc_stats_write(OutputStream *ost, EncStats *es, const AVFrame *frame, const AVPacket *pkt, uint64_t frame_num)
Definition: ffmpeg.c:811
atomic_load
#define atomic_load(object)
Definition: stdatomic.h:93
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:451
Muxer::limit_filesize
int64_t limit_filesize
Definition: ffmpeg_mux.h:84
arg
const char * arg
Definition: jacosubdec.c:67
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:1104
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:861
tq_free
void tq_free(ThreadQueue **ptq)
Definition: thread_queue.c:55
av_bsf_init
int av_bsf_init(AVBSFContext *ctx)
Prepare the filter for use, after all the parameters and options have been set.
Definition: bsf.c:150
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:877
NULL
#define NULL
Definition: coverity.c:32
fs
#define fs(width, name, subs,...)
Definition: cbs_vp9.c:258
av_bsf_receive_packet
int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt)
Retrieve a filtered packet.
Definition: bsf.c:231
tq_receive_finish
void tq_receive_finish(ThreadQueue *tq, unsigned int stream_idx)
Mark the given stream finished from the receiving side.
Definition: thread_queue.c:232
avio_print
#define avio_print(s,...)
Write strings (const char *) to the context.
Definition: avio.h:543
avcodec_free_context
void avcodec_free_context(AVCodecContext **avctx)
Free the codec context and everything associated with it and write NULL to the provided pointer.
Definition: options.c:168
av_fifo_can_read
size_t av_fifo_can_read(const AVFifo *f)
Definition: fifo.c:87
main_return_code
int main_return_code
Definition: ffmpeg.c:334
MuxStream::bsf_ctx
AVBSFContext * bsf_ctx
Definition: ffmpeg_mux.h:46
av_packet_move_ref
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
Move every field in src to dst and reset src.
Definition: avpacket.c:479
OutputFile::index
int index
Definition: ffmpeg.h:695
Muxer::last_filesize
atomic_int_least64_t last_filesize
Definition: ffmpeg_mux.h:85
OutputFile::streams
OutputStream ** streams
Definition: ffmpeg.h:700
AVFormatContext::nb_streams
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1160
AVOutputFormat::flags
int flags
can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_GLOBALHEADER, AVFMT_NOTIMESTAMPS,...
Definition: avformat.h:527
tq_send
int tq_send(ThreadQueue *tq, unsigned int stream_idx, void *data)
Send an item for the given stream to the queue.
Definition: thread_queue.c:120
AVIOContext
Bytestream IO Context.
Definition: avio.h:166
of_write_trailer
int of_write_trailer(OutputFile *of)
Definition: ffmpeg_mux.c:604
av_ts2timestr
#define av_ts2timestr(ts, tb)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: timestamp.h:76
Muxer::sq_mux
SyncQueue * sq_mux
Definition: ffmpeg_mux.h:88
AVPacket::size
int size
Definition: packet.h:375
output_files
OutputFile ** output_files
Definition: ffmpeg.c:146
av_bsf_send_packet
int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt)
Submit a packet for filtering.
Definition: bsf.c:203
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:121
sq_send
int sq_send(SyncQueue *sq, unsigned int stream_idx, SyncQueueFrame frame)
Submit a frame for the stream with index stream_idx.
Definition: sync_queue.c:234
sq_free
void sq_free(SyncQueue **psq)
Definition: sync_queue.c:428
avio.h
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
sync_queue_process
static int sync_queue_process(Muxer *mux, OutputStream *ost, AVPacket *pkt, int *stream_eof)
Definition: ffmpeg_mux.c:162
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:468
printf
printf("static const uint8_t my_array[100] = {\n")
Muxer::opts
AVDictionary * opts
Definition: ffmpeg_mux.h:79
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:373
MuxStream
Definition: ffmpeg_mux.h:37
ObjPool
Definition: objpool.c:30
pkt_move
static void pkt_move(void *dst, void *src)
Definition: ffmpeg_mux.c:399
av_sdp_create
int av_sdp_create(AVFormatContext *ac[], int n_files, char *buf, int size)
Generate an SDP for an RTP session.
Definition: sdp.c:911
av_packet_make_refcounted
int av_packet_make_refcounted(AVPacket *pkt)
Ensure the data described by a given packet is reference counted.
Definition: avpacket.c:485
av_packet_alloc
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition: avpacket.c:62
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:223
tq_alloc
ThreadQueue * tq_alloc(unsigned int nb_streams, size_t queue_size, ObjPool *obj_pool, void(*obj_move)(void *dst, void *src))
Allocate a queue for sending data between threads.
Definition: thread_queue.c:79
OutputFile::sq_encode
SyncQueue * sq_encode
Definition: ffmpeg.h:703
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: avpacket.c:526
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
filesize
static int64_t filesize(AVIOContext *pb)
Definition: ffmpeg_mux.c:48
avio_closep
int avio_closep(AVIOContext **s)
Close the resource accessed by the AVIOContext *s, free it and set the pointer pointing to it to NULL...
Definition: aviobuf.c:1280
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:1256
MuxStream::muxing_queue_data_size
size_t muxing_queue_data_size
Definition: ffmpeg_mux.h:56
submit_packet
static int submit_packet(Muxer *mux, AVPacket *pkt, OutputStream *ost)
Definition: ffmpeg_mux.c:310
log.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:367
packet.h
MuxStream::stats
EncStats stats
Definition: ffmpeg_mux.h:48
FFMIN3
#define FFMIN3(a, b, c)
Definition: macros.h:50
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
exit_on_error
int exit_on_error
Definition: ffmpeg_opt.c:80
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_inv_q
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
int_cb
const AVIOInterruptCB int_cb
Definition: ffmpeg.c:500
tq_receive
int tq_receive(ThreadQueue *tq, int *stream_idx, void *data)
Read the next item from the queue.
Definition: thread_queue.c:191
nb_output_files
int nb_output_files
Definition: ffmpeg.c:147
write_packet
static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
Definition: ffmpeg_mux.c:61
limit
static double limit(double x)
Definition: vf_pseudocolor.c:130
AVFMT_TS_NONSTRICT
#define AVFMT_TS_NONSTRICT
Format does not require strictly increasing timestamps, but they must still be monotonic.
Definition: avformat.h:489
muxer_thread
static void * muxer_thread(void *arg)
Definition: ffmpeg_mux.c:198
Muxer::header_written
int header_written
Definition: ffmpeg_mux.h:86
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:838
VSYNC_DROP
@ VSYNC_DROP
Definition: ffmpeg.h:64
sdp_filename
char * sdp_filename
Definition: ffmpeg_opt.c:64
avformat.h
av_get_media_type_string
const char * av_get_media_type_string(enum AVMediaType media_type)
Return a string describing the media_type enum, NULL if media_type is unknown.
Definition: utils.c:28
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:844
atomic_fetch_add
#define atomic_fetch_add(object, operand)
Definition: stdatomic.h:131
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:96
thread_queue.h
AVPacket::stream_index
int stream_index
Definition: packet.h:376
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
mem.h
ffmpeg_mux.h
of_output_packet
void of_output_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int eof)
Definition: ffmpeg_mux.c:329
ost_free
static void ost_free(OutputStream **post)
Definition: ffmpeg_mux.c:640
AVPacket
This structure stores compressed data.
Definition: packet.h:351
av_interleaved_write_frame
int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt)
Write a packet to an output media file ensuring correct interleaving.
Definition: mux.c:1241
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
EncStats::nb_components
int nb_components
Definition: ffmpeg.h:529
FFMAX3
#define FFMAX3(a, b, c)
Definition: macros.h:48
of_stream_init
int of_stream_init(OutputFile *of, OutputStream *ost)
Definition: ffmpeg_mux.c:583
timestamp.h
OutputStream
Definition: mux.c:53
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
EncStatsComponent::str
uint8_t * str
Definition: ffmpeg.h:523
av_fifo_freep2
void av_fifo_freep2(AVFifo **f)
Free an AVFifo and reset pointer to NULL.
Definition: fifo.c:286
av_ts2str
#define av_ts2str(ts)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: timestamp.h:54
OutputFile::format
const AVOutputFormat * format
Definition: ffmpeg.h:697
snprintf
#define snprintf
Definition: snprintf.h:34
EncStats::io
AVIOContext * io
Definition: ffmpeg.h:531
thread_set_name
static void thread_set_name(OutputFile *of)
Definition: ffmpeg_mux.c:191
MuxStream::last_mux_dts
int64_t last_mux_dts
Definition: ffmpeg_mux.h:65
avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:74
AVPacket::time_base
AVRational time_base
Time base of the packet's timestamps.
Definition: packet.h:418
OutputFile
Definition: ffmpeg.h:692
thread_submit_packet
static int thread_submit_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
Definition: ffmpeg_mux.c:246
bsf_init
static int bsf_init(MuxStream *ms)
Definition: ffmpeg_mux.c:553
ff_thread_setname
static int ff_thread_setname(const char *name)
Definition: thread.h:195
tq_send_finish
void tq_send_finish(ThreadQueue *tq, unsigned int stream_idx)
Mark the given stream finished from the sending side.
Definition: thread_queue.c:217