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  int ret;
68 
69  fs = filesize(s->pb);
71  if (fs >= mux->limit_filesize) {
72  ret = AVERROR_EOF;
73  goto fail;
74  }
75 
76  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->vsync_method == VSYNC_DROP)
78 
80  if (ost->frame_rate.num && ost->is_cfr) {
81  if (pkt->duration > 0)
82  av_log(NULL, AV_LOG_WARNING, "Overriding packet duration by frame rate, this should not happen\n");
83  pkt->duration = av_rescale_q(1, av_inv_q(ost->frame_rate),
84  ost->mux_timebase);
85  }
86  }
87 
88  av_packet_rescale_ts(pkt, ost->mux_timebase, ost->st->time_base);
89 
90  if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) {
91  if (pkt->dts != AV_NOPTS_VALUE &&
92  pkt->pts != AV_NOPTS_VALUE &&
93  pkt->dts > pkt->pts) {
94  av_log(s, AV_LOG_WARNING, "Invalid DTS: %"PRId64" PTS: %"PRId64" in output stream %d:%d, replacing by guess\n",
95  pkt->dts, pkt->pts,
96  ost->file_index, ost->st->index);
97  pkt->pts =
98  pkt->dts = pkt->pts + pkt->dts + ms->last_mux_dts + 1
99  - FFMIN3(pkt->pts, pkt->dts, ms->last_mux_dts + 1)
100  - FFMAX3(pkt->pts, pkt->dts, ms->last_mux_dts + 1);
101  }
103  pkt->dts != AV_NOPTS_VALUE &&
104  ms->last_mux_dts != AV_NOPTS_VALUE) {
105  int64_t max = ms->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT);
106  if (pkt->dts < max) {
107  int loglevel = max - pkt->dts > 2 || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ? AV_LOG_WARNING : AV_LOG_DEBUG;
108  if (exit_on_error)
109  loglevel = AV_LOG_ERROR;
110  av_log(s, loglevel, "Non-monotonous DTS in output stream "
111  "%d:%d; previous: %"PRId64", current: %"PRId64"; ",
112  ost->file_index, ost->st->index, ms->last_mux_dts, pkt->dts);
113  if (exit_on_error) {
114  ret = AVERROR(EINVAL);
115  goto fail;
116  }
117 
118  av_log(s, loglevel, "changing to %"PRId64". This may result "
119  "in incorrect timestamps in the output file.\n",
120  max);
121  if (pkt->pts >= pkt->dts)
122  pkt->pts = FFMAX(pkt->pts, max);
123  pkt->dts = max;
124  }
125  }
126  }
127  ms->last_mux_dts = pkt->dts;
128 
129  ost->data_size_mux += pkt->size;
130  atomic_fetch_add(&ost->packets_written, 1);
131 
133 
134  if (debug_ts) {
135  av_log(NULL, AV_LOG_INFO, "muxer <- type:%s "
136  "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s duration:%s duration_time:%s size:%d\n",
141  pkt->size
142  );
143  }
144 
146  if (ret < 0) {
147  print_error("av_interleaved_write_frame()", ret);
148  goto fail;
149  }
150 
151  return 0;
152 fail:
154  return ret;
155 }
156 
158 {
159  OutputFile *of = &mux->of;
160 
161  if (ost->sq_idx_mux >= 0) {
162  int ret = sq_send(mux->sq_mux, ost->sq_idx_mux, SQPKT(pkt));
163  if (ret < 0)
164  return ret;
165 
166  while (1) {
167  ret = sq_receive(mux->sq_mux, -1, SQPKT(mux->sq_pkt));
168  if (ret < 0)
169  return (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) ? 0 : ret;
170 
171  ret = write_packet(mux, of->streams[ret],
172  mux->sq_pkt);
173  if (ret < 0)
174  return ret;
175  }
176  } else if (pkt)
177  return write_packet(mux, ost, pkt);
178 
179  return 0;
180 }
181 
182 static void thread_set_name(OutputFile *of)
183 {
184  char name[16];
185  snprintf(name, sizeof(name), "mux%d:%s", of->index, of->format->name);
187 }
188 
189 static void *muxer_thread(void *arg)
190 {
191  Muxer *mux = arg;
192  OutputFile *of = &mux->of;
193  AVPacket *pkt = NULL;
194  int ret = 0;
195 
196  pkt = av_packet_alloc();
197  if (!pkt) {
198  ret = AVERROR(ENOMEM);
199  goto finish;
200  }
201 
202  thread_set_name(of);
203 
204  while (1) {
205  OutputStream *ost;
206  int stream_idx;
207 
208  ret = tq_receive(mux->tq, &stream_idx, pkt);
209  if (stream_idx < 0) {
211  "All streams finished for output file #%d\n", of->index);
212  ret = 0;
213  break;
214  }
215 
216  ost = of->streams[stream_idx];
217  ret = sync_queue_process(mux, ost, ret < 0 ? NULL : pkt);
219  if (ret == AVERROR_EOF)
220  tq_receive_finish(mux->tq, stream_idx);
221  else if (ret < 0) {
223  "Error muxing a packet for output file #%d\n", of->index);
224  break;
225  }
226  }
227 
228 finish:
230 
231  for (unsigned int i = 0; i < mux->fc->nb_streams; i++)
232  tq_receive_finish(mux->tq, i);
233 
234  av_log(NULL, AV_LOG_VERBOSE, "Terminating muxer thread %d\n", of->index);
235 
236  return (void*)(intptr_t)ret;
237 }
238 
240 {
241  int ret = 0;
242 
243  if (!pkt || ost->finished & MUXER_FINISHED)
244  goto finish;
245 
246  ret = tq_send(mux->tq, ost->index, pkt);
247  if (ret < 0)
248  goto finish;
249 
250  return 0;
251 
252 finish:
253  if (pkt)
255 
256  ost->finished |= MUXER_FINISHED;
257  tq_send_finish(mux->tq, ost->index);
258  return ret == AVERROR_EOF ? 0 : ret;
259 }
260 
262 {
263  MuxStream *ms = ms_from_ost(ost);
264  AVPacket *tmp_pkt = NULL;
265  int ret;
266 
267  if (!av_fifo_can_write(ms->muxing_queue)) {
268  size_t cur_size = av_fifo_can_read(ms->muxing_queue);
269  size_t pkt_size = pkt ? pkt->size : 0;
270  unsigned int are_we_over_size =
272  size_t limit = are_we_over_size ? ms->max_muxing_queue_size : SIZE_MAX;
273  size_t new_size = FFMIN(2 * cur_size, limit);
274 
275  if (new_size <= cur_size) {
277  "Too many packets buffered for output stream %d:%d.\n",
278  ost->file_index, ost->st->index);
279  return AVERROR(ENOSPC);
280  }
281  ret = av_fifo_grow2(ms->muxing_queue, new_size - cur_size);
282  if (ret < 0)
283  return ret;
284  }
285 
286  if (pkt) {
288  if (ret < 0)
289  return ret;
290 
291  tmp_pkt = av_packet_alloc();
292  if (!tmp_pkt)
293  return AVERROR(ENOMEM);
294 
295  av_packet_move_ref(tmp_pkt, pkt);
296  ms->muxing_queue_data_size += tmp_pkt->size;
297  }
298  av_fifo_write(ms->muxing_queue, &tmp_pkt, 1);
299 
300  return 0;
301 }
302 
304 {
305  int ret;
306 
307  if (mux->tq) {
308  return thread_submit_packet(mux, ost, pkt);
309  } else {
310  /* the muxer is not initialized yet, buffer the packet */
311  ret = queue_packet(mux, ost, pkt);
312  if (ret < 0) {
313  if (pkt)
315  return ret;
316  }
317  }
318 
319  return 0;
320 }
321 
323 {
324  Muxer *mux = mux_from_of(of);
325  MuxStream *ms = ms_from_ost(ost);
326  const char *err_msg;
327  int ret = 0;
328 
329  if (!eof && pkt->dts != AV_NOPTS_VALUE)
330  ost->last_mux_dts = av_rescale_q(pkt->dts, ost->mux_timebase, AV_TIME_BASE_Q);
331 
332  /* apply the output bitstream filters */
333  if (ms->bsf_ctx) {
334  int bsf_eof = 0;
335 
336  ret = av_bsf_send_packet(ms->bsf_ctx, eof ? NULL : pkt);
337  if (ret < 0) {
338  err_msg = "submitting a packet for bitstream filtering";
339  goto fail;
340  }
341 
342  while (!bsf_eof) {
344  if (ret == AVERROR(EAGAIN))
345  return;
346  else if (ret == AVERROR_EOF)
347  bsf_eof = 1;
348  else if (ret < 0) {
349  err_msg = "applying bitstream filters to a packet";
350  goto fail;
351  }
352 
353  ret = submit_packet(mux, bsf_eof ? NULL : pkt, ost);
354  if (ret < 0)
355  goto mux_fail;
356  }
357  } else {
358  ret = submit_packet(mux, eof ? NULL : pkt, ost);
359  if (ret < 0)
360  goto mux_fail;
361  }
362 
363  return;
364 
365 mux_fail:
366  err_msg = "submitting a packet to the muxer";
367 
368 fail:
369  av_log(NULL, AV_LOG_ERROR, "Error %s for output stream #%d:%d.\n",
370  err_msg, ost->file_index, ost->index);
371  if (exit_on_error)
372  exit_program(1);
373 
374 }
375 
376 static int thread_stop(Muxer *mux)
377 {
378  void *ret;
379 
380  if (!mux || !mux->tq)
381  return 0;
382 
383  for (unsigned int i = 0; i < mux->fc->nb_streams; i++)
384  tq_send_finish(mux->tq, i);
385 
386  pthread_join(mux->thread, &ret);
387 
388  tq_free(&mux->tq);
389 
390  return (int)(intptr_t)ret;
391 }
392 
393 static void pkt_move(void *dst, void *src)
394 {
395  av_packet_move_ref(dst, src);
396 }
397 
398 static int thread_start(Muxer *mux)
399 {
400  AVFormatContext *fc = mux->fc;
401  ObjPool *op;
402  int ret;
403 
405  if (!op)
406  return AVERROR(ENOMEM);
407 
408  mux->tq = tq_alloc(fc->nb_streams, mux->thread_queue_size, op, pkt_move);
409  if (!mux->tq) {
410  objpool_free(&op);
411  return AVERROR(ENOMEM);
412  }
413 
414  ret = pthread_create(&mux->thread, NULL, muxer_thread, (void*)mux);
415  if (ret) {
416  tq_free(&mux->tq);
417  return AVERROR(ret);
418  }
419 
420  /* flush the muxing queues */
421  for (int i = 0; i < fc->nb_streams; i++) {
422  OutputStream *ost = mux->of.streams[i];
423  MuxStream *ms = ms_from_ost(ost);
424  AVPacket *pkt;
425 
426  /* try to improve muxing time_base (only possible if nothing has been written yet) */
427  if (!av_fifo_can_read(ms->muxing_queue))
428  ost->mux_timebase = ost->st->time_base;
429 
430  while (av_fifo_read(ms->muxing_queue, &pkt, 1) >= 0) {
431  ret = thread_submit_packet(mux, ost, pkt);
432  if (pkt) {
435  }
436  if (ret < 0)
437  return ret;
438  }
439  }
440 
441  return 0;
442 }
443 
444 static int print_sdp(void)
445 {
446  char sdp[16384];
447  int i;
448  int j, ret;
449  AVIOContext *sdp_pb;
450  AVFormatContext **avc;
451 
452  for (i = 0; i < nb_output_files; i++) {
453  if (!mux_from_of(output_files[i])->header_written)
454  return 0;
455  }
456 
457  avc = av_malloc_array(nb_output_files, sizeof(*avc));
458  if (!avc)
459  return AVERROR(ENOMEM);
460  for (i = 0, j = 0; i < nb_output_files; i++) {
461  if (!strcmp(output_files[i]->format->name, "rtp")) {
462  avc[j] = mux_from_of(output_files[i])->fc;
463  j++;
464  }
465  }
466 
467  if (!j) {
468  av_log(NULL, AV_LOG_ERROR, "No output streams in the SDP.\n");
469  ret = AVERROR(EINVAL);
470  goto fail;
471  }
472 
473  ret = av_sdp_create(avc, j, sdp, sizeof(sdp));
474  if (ret < 0)
475  goto fail;
476 
477  if (!sdp_filename) {
478  printf("SDP:\n%s\n", sdp);
479  fflush(stdout);
480  } else {
482  if (ret < 0) {
483  av_log(NULL, AV_LOG_ERROR, "Failed to open sdp file '%s'\n", sdp_filename);
484  goto fail;
485  }
486 
487  avio_print(sdp_pb, sdp);
488  avio_closep(&sdp_pb);
490  }
491 
492  // SDP successfully written, allow muxer threads to start
493  ret = 1;
494 
495 fail:
496  av_freep(&avc);
497  return ret;
498 }
499 
501 {
502  OutputFile *of = &mux->of;
503  AVFormatContext *fc = mux->fc;
504  int ret, i;
505 
506  for (i = 0; i < fc->nb_streams; i++) {
507  OutputStream *ost = of->streams[i];
508  if (!ost->initialized)
509  return 0;
510  }
511 
512  ret = avformat_write_header(fc, &mux->opts);
513  if (ret < 0) {
515  "Could not write header for output file #%d "
516  "(incorrect codec parameters ?): %s\n",
517  of->index, av_err2str(ret));
518  return ret;
519  }
520  //assert_avoptions(of->opts);
521  mux->header_written = 1;
522 
523  av_dump_format(fc, of->index, fc->url, 1);
525 
526  if (sdp_filename || want_sdp) {
527  ret = print_sdp();
528  if (ret < 0) {
529  av_log(NULL, AV_LOG_ERROR, "Error writing the SDP.\n");
530  return ret;
531  } else if (ret == 1) {
532  /* SDP is written only after all the muxers are ready, so now we
533  * start ALL the threads */
534  for (i = 0; i < nb_output_files; i++) {
536  if (ret < 0)
537  return ret;
538  }
539  }
540  } else {
542  if (ret < 0)
543  return ret;
544  }
545 
546  return 0;
547 }
548 
549 static int bsf_init(MuxStream *ms)
550 {
551  OutputStream *ost = &ms->ost;
552  AVBSFContext *ctx = ms->bsf_ctx;
553  int ret;
554 
555  if (!ctx)
556  return 0;
557 
558  ret = avcodec_parameters_copy(ctx->par_in, ost->st->codecpar);
559  if (ret < 0)
560  return ret;
561 
562  ctx->time_base_in = ost->st->time_base;
563 
564  ret = av_bsf_init(ctx);
565  if (ret < 0) {
566  av_log(NULL, AV_LOG_ERROR, "Error initializing bitstream filter: %s\n",
567  ctx->filter->name);
568  return ret;
569  }
570 
571  ret = avcodec_parameters_copy(ost->st->codecpar, ctx->par_out);
572  if (ret < 0)
573  return ret;
574  ost->st->time_base = ctx->time_base_out;
575 
576  return 0;
577 }
578 
580 {
581  Muxer *mux = mux_from_of(of);
582  MuxStream *ms = ms_from_ost(ost);
583  int ret;
584 
585  if (ost->sq_idx_mux >= 0)
586  sq_set_tb(mux->sq_mux, ost->sq_idx_mux, ost->mux_timebase);
587 
588  /* initialize bitstream filters for the output stream
589  * needs to be done here, because the codec id for streamcopy is not
590  * known until now */
591  ret = bsf_init(ms);
592  if (ret < 0)
593  return ret;
594 
595  ost->initialized = 1;
596 
597  return mux_check_init(mux);
598 }
599 
601 {
602  Muxer *mux = mux_from_of(of);
603  AVFormatContext *fc = mux->fc;
604  int ret;
605 
606  if (!mux->tq) {
608  "Nothing was written into output file %d (%s), because "
609  "at least one of its streams received no packets.\n",
610  of->index, fc->url);
611  return AVERROR(EINVAL);
612  }
613 
614  ret = thread_stop(mux);
615  if (ret < 0)
617 
619  if (ret < 0) {
620  av_log(NULL, AV_LOG_ERROR, "Error writing trailer of %s: %s\n", fc->url, av_err2str(ret));
621  return ret;
622  }
623 
624  mux->last_filesize = filesize(fc->pb);
625 
626  if (!(of->format->flags & AVFMT_NOFILE)) {
627  ret = avio_closep(&fc->pb);
628  if (ret < 0) {
629  av_log(NULL, AV_LOG_ERROR, "Error closing file %s: %s\n",
630  fc->url, av_err2str(ret));
631  return ret;
632  }
633  }
634 
635  return 0;
636 }
637 
638 static void ost_free(OutputStream **post)
639 {
640  OutputStream *ost = *post;
641  MuxStream *ms;
642 
643  if (!ost)
644  return;
645  ms = ms_from_ost(ost);
646 
647  if (ost->logfile) {
648  if (fclose(ost->logfile))
650  "Error closing logfile, loss of information possible: %s\n",
651  av_err2str(AVERROR(errno)));
652  ost->logfile = NULL;
653  }
654 
655  if (ms->muxing_queue) {
656  AVPacket *pkt;
657  while (av_fifo_read(ms->muxing_queue, &pkt, 1) >= 0)
660  }
661 
662  av_bsf_free(&ms->bsf_ctx);
663 
664  av_frame_free(&ost->filtered_frame);
665  av_frame_free(&ost->sq_frame);
666  av_frame_free(&ost->last_frame);
667  av_packet_free(&ost->pkt);
668  av_dict_free(&ost->encoder_opts);
669 
670  av_freep(&ost->kf.pts);
671  av_expr_free(ost->kf.pexpr);
672 
673  av_freep(&ost->avfilter);
674  av_freep(&ost->logfile_prefix);
675  av_freep(&ost->apad);
676 
677 #if FFMPEG_OPT_MAP_CHANNEL
678  av_freep(&ost->audio_channels_map);
679  ost->audio_channels_mapped = 0;
680 #endif
681 
682  av_dict_free(&ost->sws_dict);
683  av_dict_free(&ost->swr_opts);
684 
685  if (ost->enc_ctx)
686  av_freep(&ost->enc_ctx->stats_in);
687  avcodec_free_context(&ost->enc_ctx);
688 
689  av_freep(post);
690 }
691 
692 static void fc_close(AVFormatContext **pfc)
693 {
694  AVFormatContext *fc = *pfc;
695 
696  if (!fc)
697  return;
698 
699  if (!(fc->oformat->flags & AVFMT_NOFILE))
700  avio_closep(&fc->pb);
702 
703  *pfc = NULL;
704 }
705 
706 void of_close(OutputFile **pof)
707 {
708  OutputFile *of = *pof;
709  Muxer *mux;
710 
711  if (!of)
712  return;
713  mux = mux_from_of(of);
714 
715  thread_stop(mux);
716 
717  sq_free(&of->sq_encode);
718  sq_free(&mux->sq_mux);
719 
720  for (int i = 0; i < of->nb_streams; i++)
721  ost_free(&of->streams[i]);
722  av_freep(&of->streams);
723 
724  av_dict_free(&mux->opts);
725 
726  av_packet_free(&mux->sq_pkt);
727 
728  fc_close(&mux->fc);
729 
730  av_freep(pof);
731 }
732 
734 {
735  Muxer *mux = mux_from_of(of);
736  return atomic_load(&mux->last_filesize);
737 }
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:66
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:89
AVOutputFormat::name
const char * name
Definition: avformat.h:510
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:68
thread.h
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
MuxStream::muxing_queue
AVFifo * muxing_queue
Definition: ffmpeg_mux.h:41
AVFMT_NOTIMESTAMPS
#define AVFMT_NOTIMESTAMPS
Format does not need / have any timestamps.
Definition: avformat.h:481
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:444
MuxStream::max_muxing_queue_size
int max_muxing_queue_size
Definition: ffmpeg_mux.h:53
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:116
Muxer::thread_queue_size
int thread_queue_size
Definition: ffmpeg_mux.h:73
MuxStream::muxing_queue_data_threshold
size_t muxing_queue_data_threshold
Definition: ffmpeg_mux.h:56
sync_queue.h
fc_close
static void fc_close(AVFormatContext **pfc)
Definition: ffmpeg_mux.c:692
nb_output_dumped
unsigned nb_output_dumped
Definition: ffmpeg.c:130
Muxer::of
OutputFile of
Definition: ffmpeg_mux.h:64
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:354
ost
static AVStream * ost
Definition: vaapi_transcode.c:45
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:261
OutputFile::nb_streams
int nb_streams
Definition: ffmpeg.h:637
exit_program
void exit_program(int ret)
Wraps exit with a program-specific cleanup routine.
Definition: cmdutils.c:99
Muxer
Definition: ffmpeg_mux.h:63
debug_ts
int debug_ts
Definition: ffmpeg_opt.c:79
thread_stop
static int thread_stop(Muxer *mux)
Definition: ffmpeg_mux.c:376
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:733
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:1251
finish
static void finish(void)
Definition: movenc.c:342
Muxer::tq
ThreadQueue * tq
Definition: ffmpeg_mux.h:69
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:510
sq_receive
int sq_receive(SyncQueue *sq, int stream_idx, SyncQueueFrame frame)
Read a frame from the queue.
Definition: sync_queue.c:339
sync_queue_process
static int sync_queue_process(Muxer *mux, OutputStream *ost, AVPacket *pkt)
Definition: ffmpeg_mux.c:157
want_sdp
int want_sdp
Definition: ffmpeg_mux.c:41
of_close
void of_close(OutputFile **pof)
Definition: ffmpeg_mux.c:706
thread_start
static int thread_start(Muxer *mux)
Definition: ffmpeg_mux.c:398
Muxer::sq_pkt
AVPacket * sq_pkt
Definition: ffmpeg_mux.h:81
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
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:500
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:634
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:487
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
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:450
Muxer::limit_filesize
int64_t limit_filesize
Definition: ffmpeg_mux.h:76
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:1216
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1108
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:978
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:553
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:164
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:326
MuxStream::bsf_ctx
AVBSFContext * bsf_ctx
Definition: ffmpeg_mux.h:43
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:631
Muxer::last_filesize
atomic_int_least64_t last_filesize
Definition: ffmpeg_mux.h:77
OutputFile::streams
OutputStream ** streams
Definition: ffmpeg.h:636
AVFormatContext::nb_streams
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1272
AVOutputFormat::flags
int flags
can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_GLOBALHEADER, AVFMT_NOTIMESTAMPS,...
Definition: avformat.h:529
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:600
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:80
AVPacket::size
int size
Definition: packet.h:375
output_files
OutputFile ** output_files
Definition: ffmpeg.c:138
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
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:470
printf
printf("static const uint8_t my_array[100] = {\n")
Muxer::opts
AVDictionary * opts
Definition: ffmpeg_mux.h:71
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:393
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:639
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:1290
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
MuxStream::muxing_queue_data_size
size_t muxing_queue_data_size
Definition: ffmpeg_mux.h:51
submit_packet
static int submit_packet(Muxer *mux, AVPacket *pkt, OutputStream *ost)
Definition: ffmpeg_mux.c:303
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
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:492
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:139
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:491
muxer_thread
static void * muxer_thread(void *arg)
Definition: ffmpeg_mux.c:189
Muxer::header_written
int header_written
Definition: ffmpeg_mux.h:78
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:948
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:956
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:95
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:322
ost_free
static void ost_free(OutputStream **post)
Definition: ffmpeg_mux.c:638
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:1239
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
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:579
timestamp.h
OutputStream
Definition: muxing.c:54
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
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:633
snprintf
#define snprintf
Definition: snprintf.h:34
thread_set_name
static void thread_set_name(OutputFile *of)
Definition: ffmpeg_mux.c:182
MuxStream::last_mux_dts
int64_t last_mux_dts
Definition: ffmpeg_mux.h:60
avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:74
OutputFile
Definition: ffmpeg.h:630
thread_submit_packet
static int thread_submit_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
Definition: ffmpeg_mux.c:239
bsf_init
static int bsf_init(MuxStream *ms)
Definition: ffmpeg_mux.c:549
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