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  int64_t fs;
66  uint64_t frame_num;
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 (ost->type == AVMEDIA_TYPE_VIDEO && ost->vsync_method == VSYNC_DROP)
78 
79  // rescale timestamps to the stream timebase
80  if (ost->type == AVMEDIA_TYPE_AUDIO && !ost->enc) {
81  // use av_rescale_delta() for streamcopying audio, to preserve
82  // accuracy with coarse input timebases
84 
85  if (!duration)
87 
89  (AVRational){1, ost->st->codecpar->sample_rate}, duration,
91  pkt->pts = pkt->dts;
92 
94  } else
96  pkt->time_base = ost->st->time_base;
97 
98  if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) {
99  if (pkt->dts != AV_NOPTS_VALUE &&
100  pkt->pts != AV_NOPTS_VALUE &&
101  pkt->dts > pkt->pts) {
102  av_log(s, AV_LOG_WARNING, "Invalid DTS: %"PRId64" PTS: %"PRId64" in output stream %d:%d, replacing by guess\n",
103  pkt->dts, pkt->pts,
104  ost->file_index, ost->st->index);
105  pkt->pts =
106  pkt->dts = pkt->pts + pkt->dts + ms->last_mux_dts + 1
107  - FFMIN3(pkt->pts, pkt->dts, ms->last_mux_dts + 1)
108  - FFMAX3(pkt->pts, pkt->dts, ms->last_mux_dts + 1);
109  }
110  if ((ost->type == AVMEDIA_TYPE_AUDIO || ost->type == AVMEDIA_TYPE_VIDEO || ost->type == AVMEDIA_TYPE_SUBTITLE) &&
111  pkt->dts != AV_NOPTS_VALUE &&
112  ms->last_mux_dts != AV_NOPTS_VALUE) {
113  int64_t max = ms->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT);
114  if (pkt->dts < max) {
115  int loglevel = max - pkt->dts > 2 || ost->type == AVMEDIA_TYPE_VIDEO ? AV_LOG_WARNING : AV_LOG_DEBUG;
116  if (exit_on_error)
117  loglevel = AV_LOG_ERROR;
118  av_log(s, loglevel, "Non-monotonic DTS in output stream "
119  "%d:%d; previous: %"PRId64", current: %"PRId64"; ",
120  ost->file_index, ost->st->index, ms->last_mux_dts, pkt->dts);
121  if (exit_on_error) {
122  ret = AVERROR(EINVAL);
123  goto fail;
124  }
125 
126  av_log(s, loglevel, "changing to %"PRId64". This may result "
127  "in incorrect timestamps in the output file.\n",
128  max);
129  if (pkt->pts >= pkt->dts)
130  pkt->pts = FFMAX(pkt->pts, max);
131  pkt->dts = max;
132  }
133  }
134  }
135  ms->last_mux_dts = pkt->dts;
136 
137  ms->data_size_mux += pkt->size;
138  frame_num = atomic_fetch_add(&ost->packets_written, 1);
139 
141 
142  if (debug_ts) {
143  av_log(ost, AV_LOG_INFO, "muxer <- type:%s "
144  "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s duration:%s duration_time:%s size:%d\n",
149  pkt->size
150  );
151  }
152 
153  if (ms->stats.io)
154  enc_stats_write(ost, &ms->stats, NULL, pkt, frame_num);
155 
157  if (ret < 0) {
159  "Error submitting a packet to the muxer: %s\n",
160  av_err2str(ret));
161  goto fail;
162  }
163 
164  return 0;
165 fail:
167  return ret;
168 }
169 
170 static int sync_queue_process(Muxer *mux, OutputStream *ost, AVPacket *pkt, int *stream_eof)
171 {
172  OutputFile *of = &mux->of;
173 
174  if (ost->sq_idx_mux >= 0) {
175  int ret = sq_send(mux->sq_mux, ost->sq_idx_mux, SQPKT(pkt));
176  if (ret < 0) {
177  if (ret == AVERROR_EOF)
178  *stream_eof = 1;
179 
180  return ret;
181  }
182 
183  while (1) {
184  ret = sq_receive(mux->sq_mux, -1, SQPKT(mux->sq_pkt));
185  if (ret < 0) {
186  /* n.b.: We forward EOF from the sync queue, terminating muxing.
187  * This assumes that if a muxing sync queue is present, then all
188  * the streams use it. That is true currently, but may change in
189  * the future, then this code needs to be revisited.
190  */
191  return ret == AVERROR(EAGAIN) ? 0 : ret;
192  }
193 
194  ret = write_packet(mux, of->streams[ret],
195  mux->sq_pkt);
196  if (ret < 0)
197  return ret;
198  }
199  } else if (pkt)
200  return write_packet(mux, ost, pkt);
201 
202  return 0;
203 }
204 
205 static void thread_set_name(OutputFile *of)
206 {
207  char name[16];
208  snprintf(name, sizeof(name), "mux%d:%s", of->index, of->format->name);
210 }
211 
212 static void *muxer_thread(void *arg)
213 {
214  Muxer *mux = arg;
215  OutputFile *of = &mux->of;
216  AVPacket *pkt = NULL;
217  int ret = 0;
218 
219  pkt = av_packet_alloc();
220  if (!pkt) {
221  ret = AVERROR(ENOMEM);
222  goto finish;
223  }
224 
225  thread_set_name(of);
226 
227  while (1) {
228  OutputStream *ost;
229  int stream_idx, stream_eof = 0;
230 
231  ret = tq_receive(mux->tq, &stream_idx, pkt);
232  if (stream_idx < 0) {
233  av_log(mux, AV_LOG_VERBOSE, "All streams finished\n");
234  ret = 0;
235  break;
236  }
237 
238  ost = of->streams[stream_idx];
239  ret = sync_queue_process(mux, ost, ret < 0 ? NULL : pkt, &stream_eof);
241  if (ret == AVERROR_EOF) {
242  if (stream_eof) {
243  tq_receive_finish(mux->tq, stream_idx);
244  } else {
245  av_log(mux, AV_LOG_VERBOSE, "Muxer returned EOF\n");
246  ret = 0;
247  break;
248  }
249  } else if (ret < 0) {
250  av_log(mux, AV_LOG_ERROR, "Error muxing a packet\n");
251  break;
252  }
253  }
254 
255 finish:
257 
258  for (unsigned int i = 0; i < mux->fc->nb_streams; i++)
259  tq_receive_finish(mux->tq, i);
260 
261  av_log(mux, AV_LOG_VERBOSE, "Terminating muxer thread\n");
262 
263  return (void*)(intptr_t)ret;
264 }
265 
267 {
268  int ret = 0;
269 
270  if (!pkt || ost->finished & MUXER_FINISHED)
271  goto finish;
272 
273  ret = tq_send(mux->tq, ost->index, pkt);
274  if (ret < 0)
275  goto finish;
276 
277  return 0;
278 
279 finish:
280  if (pkt)
282 
283  ost->finished |= MUXER_FINISHED;
284  tq_send_finish(mux->tq, ost->index);
285  return ret == AVERROR_EOF ? 0 : ret;
286 }
287 
289 {
290  MuxStream *ms = ms_from_ost(ost);
291  AVPacket *tmp_pkt = NULL;
292  int ret;
293 
294  if (!av_fifo_can_write(ms->muxing_queue)) {
295  size_t cur_size = av_fifo_can_read(ms->muxing_queue);
296  size_t pkt_size = pkt ? pkt->size : 0;
297  unsigned int are_we_over_size =
299  size_t limit = are_we_over_size ? ms->max_muxing_queue_size : SIZE_MAX;
300  size_t new_size = FFMIN(2 * cur_size, limit);
301 
302  if (new_size <= cur_size) {
304  "Too many packets buffered for output stream %d:%d.\n",
305  ost->file_index, ost->st->index);
306  return AVERROR(ENOSPC);
307  }
308  ret = av_fifo_grow2(ms->muxing_queue, new_size - cur_size);
309  if (ret < 0)
310  return ret;
311  }
312 
313  if (pkt) {
315  if (ret < 0)
316  return ret;
317 
318  tmp_pkt = av_packet_alloc();
319  if (!tmp_pkt)
320  return AVERROR(ENOMEM);
321 
322  av_packet_move_ref(tmp_pkt, pkt);
323  ms->muxing_queue_data_size += tmp_pkt->size;
324  }
325  av_fifo_write(ms->muxing_queue, &tmp_pkt, 1);
326 
327  return 0;
328 }
329 
331 {
332  int ret;
333 
334  if (mux->tq) {
335  return thread_submit_packet(mux, ost, pkt);
336  } else {
337  /* the muxer is not initialized yet, buffer the packet */
338  ret = queue_packet(ost, pkt);
339  if (ret < 0) {
340  if (pkt)
342  return ret;
343  }
344  }
345 
346  return 0;
347 }
348 
350 {
351  Muxer *mux = mux_from_of(of);
352  MuxStream *ms = ms_from_ost(ost);
353  const char *err_msg;
354  int ret = 0;
355 
356  if (pkt && pkt->dts != AV_NOPTS_VALUE)
357  ost->last_mux_dts = av_rescale_q(pkt->dts, pkt->time_base, AV_TIME_BASE_Q);
358 
359  /* apply the output bitstream filters */
360  if (ms->bsf_ctx) {
361  int bsf_eof = 0;
362 
363  if (pkt)
365 
367  if (ret < 0) {
368  err_msg = "submitting a packet for bitstream filtering";
369  goto fail;
370  }
371 
372  while (!bsf_eof) {
374  if (ret == AVERROR(EAGAIN))
375  return 0;
376  else if (ret == AVERROR_EOF)
377  bsf_eof = 1;
378  else if (ret < 0) {
379  err_msg = "applying bitstream filters to a packet";
380  goto fail;
381  }
382 
383  if (!bsf_eof)
385 
386  ret = submit_packet(mux, bsf_eof ? NULL : ms->bsf_pkt, ost);
387  if (ret < 0)
388  goto mux_fail;
389  }
390  } else {
391  ret = submit_packet(mux, pkt, ost);
392  if (ret < 0)
393  goto mux_fail;
394  }
395 
396  return 0;
397 
398 mux_fail:
399  err_msg = "submitting a packet to the muxer";
400 
401 fail:
402  av_log(ost, AV_LOG_ERROR, "Error %s\n", err_msg);
403  return exit_on_error ? ret : 0;
404 }
405 
406 int of_streamcopy(OutputStream *ost, const AVPacket *pkt, int64_t dts)
407 {
408  OutputFile *of = output_files[ost->file_index];
409  MuxStream *ms = ms_from_ost(ost);
410  int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time;
411  int64_t ts_offset;
412  AVPacket *opkt = ms->pkt;
413  int ret;
414 
415  av_packet_unref(opkt);
416 
417  if (of->recording_time != INT64_MAX &&
418  dts >= of->recording_time + start_time)
419  pkt = NULL;
420 
421  // EOF: flush output bitstream filters.
422  if (!pkt)
423  return of_output_packet(of, ost, NULL);
424 
425  if (!ms->streamcopy_started && !(pkt->flags & AV_PKT_FLAG_KEY) &&
427  return 0;
428 
429  if (!ms->streamcopy_started) {
430  if (!ms->copy_prior_start &&
431  (pkt->pts == AV_NOPTS_VALUE ?
432  dts < ms->ts_copy_start :
434  return 0;
435 
436  if (of->start_time != AV_NOPTS_VALUE && dts < of->start_time)
437  return 0;
438  }
439 
440  ret = av_packet_ref(opkt, pkt);
441  if (ret < 0)
442  return ret;
443 
444  ts_offset = av_rescale_q(start_time, AV_TIME_BASE_Q, opkt->time_base);
445 
446  if (pkt->pts != AV_NOPTS_VALUE)
447  opkt->pts -= ts_offset;
448 
449  if (pkt->dts == AV_NOPTS_VALUE) {
450  opkt->dts = av_rescale_q(dts, AV_TIME_BASE_Q, opkt->time_base);
451  } else if (ost->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
452  opkt->pts = opkt->dts - ts_offset;
453  }
454  opkt->dts -= ts_offset;
455 
456  {
458  if (ret < 0) {
460  "Subtitle heartbeat logic failed in %s! (%s)\n",
461  __func__, av_err2str(ret));
462  return ret;
463  }
464  }
465 
466  ret = of_output_packet(of, ost, opkt);
467  if (ret < 0)
468  return ret;
469 
470  ms->streamcopy_started = 1;
471 
472  return 0;
473 }
474 
475 static int thread_stop(Muxer *mux)
476 {
477  void *ret;
478 
479  if (!mux || !mux->tq)
480  return 0;
481 
482  for (unsigned int i = 0; i < mux->fc->nb_streams; i++)
483  tq_send_finish(mux->tq, i);
484 
485  pthread_join(mux->thread, &ret);
486 
487  tq_free(&mux->tq);
488 
489  return (int)(intptr_t)ret;
490 }
491 
492 static int thread_start(Muxer *mux)
493 {
494  AVFormatContext *fc = mux->fc;
495  ObjPool *op;
496  int ret;
497 
499  if (!op)
500  return AVERROR(ENOMEM);
501 
502  mux->tq = tq_alloc(fc->nb_streams, mux->thread_queue_size, op, pkt_move);
503  if (!mux->tq) {
504  objpool_free(&op);
505  return AVERROR(ENOMEM);
506  }
507 
508  ret = pthread_create(&mux->thread, NULL, muxer_thread, (void*)mux);
509  if (ret) {
510  tq_free(&mux->tq);
511  return AVERROR(ret);
512  }
513 
514  /* flush the muxing queues */
515  for (int i = 0; i < fc->nb_streams; i++) {
516  OutputStream *ost = mux->of.streams[i];
517  MuxStream *ms = ms_from_ost(ost);
518  AVPacket *pkt;
519 
520  while (av_fifo_read(ms->muxing_queue, &pkt, 1) >= 0) {
521  ret = thread_submit_packet(mux, ost, pkt);
522  if (pkt) {
525  }
526  if (ret < 0)
527  return ret;
528  }
529  }
530 
531  return 0;
532 }
533 
534 static int print_sdp(void)
535 {
536  char sdp[16384];
537  int i;
538  int j, ret;
539  AVIOContext *sdp_pb;
540  AVFormatContext **avc;
541 
542  for (i = 0; i < nb_output_files; i++) {
543  if (!mux_from_of(output_files[i])->header_written)
544  return 0;
545  }
546 
547  avc = av_malloc_array(nb_output_files, sizeof(*avc));
548  if (!avc)
549  return AVERROR(ENOMEM);
550  for (i = 0, j = 0; i < nb_output_files; i++) {
551  if (!strcmp(output_files[i]->format->name, "rtp")) {
552  avc[j] = mux_from_of(output_files[i])->fc;
553  j++;
554  }
555  }
556 
557  if (!j) {
558  av_log(NULL, AV_LOG_ERROR, "No output streams in the SDP.\n");
559  ret = AVERROR(EINVAL);
560  goto fail;
561  }
562 
563  ret = av_sdp_create(avc, j, sdp, sizeof(sdp));
564  if (ret < 0)
565  goto fail;
566 
567  if (!sdp_filename) {
568  printf("SDP:\n%s\n", sdp);
569  fflush(stdout);
570  } else {
572  if (ret < 0) {
573  av_log(NULL, AV_LOG_ERROR, "Failed to open sdp file '%s'\n", sdp_filename);
574  goto fail;
575  }
576 
577  avio_print(sdp_pb, sdp);
578  avio_closep(&sdp_pb);
580  }
581 
582  // SDP successfully written, allow muxer threads to start
583  ret = 1;
584 
585 fail:
586  av_freep(&avc);
587  return ret;
588 }
589 
591 {
592  OutputFile *of = &mux->of;
593  AVFormatContext *fc = mux->fc;
594  int ret, i;
595 
596  for (i = 0; i < fc->nb_streams; i++) {
597  OutputStream *ost = of->streams[i];
598  if (!ost->initialized)
599  return 0;
600  }
601 
602  ret = avformat_write_header(fc, &mux->opts);
603  if (ret < 0) {
604  av_log(mux, AV_LOG_ERROR, "Could not write header (incorrect codec "
605  "parameters ?): %s\n", av_err2str(ret));
606  return ret;
607  }
608  //assert_avoptions(of->opts);
609  mux->header_written = 1;
610 
611  av_dump_format(fc, of->index, fc->url, 1);
613 
614  if (sdp_filename || want_sdp) {
615  ret = print_sdp();
616  if (ret < 0) {
617  av_log(NULL, AV_LOG_ERROR, "Error writing the SDP.\n");
618  return ret;
619  } else if (ret == 1) {
620  /* SDP is written only after all the muxers are ready, so now we
621  * start ALL the threads */
622  for (i = 0; i < nb_output_files; i++) {
624  if (ret < 0)
625  return ret;
626  }
627  }
628  } else {
630  if (ret < 0)
631  return ret;
632  }
633 
634  return 0;
635 }
636 
637 static int bsf_init(MuxStream *ms)
638 {
639  OutputStream *ost = &ms->ost;
640  AVBSFContext *ctx = ms->bsf_ctx;
641  int ret;
642 
643  if (!ctx)
644  return avcodec_parameters_copy(ost->st->codecpar, ost->par_in);
645 
646  ret = avcodec_parameters_copy(ctx->par_in, ost->par_in);
647  if (ret < 0)
648  return ret;
649 
650  ctx->time_base_in = ost->st->time_base;
651 
652  ret = av_bsf_init(ctx);
653  if (ret < 0) {
654  av_log(ms, AV_LOG_ERROR, "Error initializing bitstream filter: %s\n",
655  ctx->filter->name);
656  return ret;
657  }
658 
659  ret = avcodec_parameters_copy(ost->st->codecpar, ctx->par_out);
660  if (ret < 0)
661  return ret;
662  ost->st->time_base = ctx->time_base_out;
663 
664  ms->bsf_pkt = av_packet_alloc();
665  if (!ms->bsf_pkt)
666  return AVERROR(ENOMEM);
667 
668  return 0;
669 }
670 
672 {
673  Muxer *mux = mux_from_of(of);
674  MuxStream *ms = ms_from_ost(ost);
675  int ret;
676 
677  /* initialize bitstream filters for the output stream
678  * needs to be done here, because the codec id for streamcopy is not
679  * known until now */
680  ret = bsf_init(ms);
681  if (ret < 0)
682  return ret;
683 
684  if (ms->stream_duration) {
686  ost->st->time_base);
687  }
688 
689  ost->initialized = 1;
690 
691  return mux_check_init(mux);
692 }
693 
694 static int check_written(OutputFile *of)
695 {
696  int64_t total_packets_written = 0;
697  int pass1_used = 1;
698  int ret = 0;
699 
700  for (int i = 0; i < of->nb_streams; i++) {
701  OutputStream *ost = of->streams[i];
702  uint64_t packets_written = atomic_load(&ost->packets_written);
703 
704  total_packets_written += packets_written;
705 
706  if (ost->enc_ctx &&
707  (ost->enc_ctx->flags & (AV_CODEC_FLAG_PASS1 | AV_CODEC_FLAG_PASS2))
709  pass1_used = 0;
710 
711  if (!packets_written &&
713  av_log(ost, AV_LOG_FATAL, "Empty output stream\n");
714  ret = err_merge(ret, AVERROR(EINVAL));
715  }
716  }
717 
718  if (!total_packets_written) {
719  int level = AV_LOG_WARNING;
720 
722  ret = err_merge(ret, AVERROR(EINVAL));
724  }
725 
726  av_log(of, level, "Output file is empty, nothing was encoded%s\n",
727  pass1_used ? "" : "(check -ss / -t / -frames parameters if used)");
728  }
729 
730  return ret;
731 }
732 
733 static void mux_final_stats(Muxer *mux)
734 {
735  OutputFile *of = &mux->of;
736  uint64_t total_packets = 0, total_size = 0;
737  uint64_t video_size = 0, audio_size = 0, subtitle_size = 0,
738  extra_size = 0, other_size = 0;
739 
740  uint8_t overhead[16] = "unknown";
741  int64_t file_size = of_filesize(of);
742 
743  av_log(of, AV_LOG_VERBOSE, "Output file #%d (%s):\n",
744  of->index, of->url);
745 
746  for (int j = 0; j < of->nb_streams; j++) {
747  OutputStream *ost = of->streams[j];
748  MuxStream *ms = ms_from_ost(ost);
749  const AVCodecParameters *par = ost->st->codecpar;
750  const enum AVMediaType type = par->codec_type;
751  const uint64_t s = ms->data_size_mux;
752 
753  switch (type) {
754  case AVMEDIA_TYPE_VIDEO: video_size += s; break;
755  case AVMEDIA_TYPE_AUDIO: audio_size += s; break;
756  case AVMEDIA_TYPE_SUBTITLE: subtitle_size += s; break;
757  default: other_size += s; break;
758  }
759 
760  extra_size += par->extradata_size;
761  total_size += s;
762  total_packets += atomic_load(&ost->packets_written);
763 
764  av_log(of, AV_LOG_VERBOSE, " Output stream #%d:%d (%s): ",
766  if (ost->enc) {
767  av_log(of, AV_LOG_VERBOSE, "%"PRIu64" frames encoded",
768  ost->frames_encoded);
769  if (type == AVMEDIA_TYPE_AUDIO)
770  av_log(of, AV_LOG_VERBOSE, " (%"PRIu64" samples)", ost->samples_encoded);
771  av_log(of, AV_LOG_VERBOSE, "; ");
772  }
773 
774  av_log(of, AV_LOG_VERBOSE, "%"PRIu64" packets muxed (%"PRIu64" bytes); ",
775  atomic_load(&ost->packets_written), s);
776 
777  av_log(of, AV_LOG_VERBOSE, "\n");
778  }
779 
780  av_log(of, AV_LOG_VERBOSE, " Total: %"PRIu64" packets (%"PRIu64" bytes) muxed\n",
781  total_packets, total_size);
782 
783  if (total_size && file_size > 0 && file_size >= total_size) {
784  snprintf(overhead, sizeof(overhead), "%f%%",
785  100.0 * (file_size - total_size) / total_size);
786  }
787 
788  av_log(of, AV_LOG_INFO,
789  "video:%1.0fkB audio:%1.0fkB subtitle:%1.0fkB other streams:%1.0fkB "
790  "global headers:%1.0fkB muxing overhead: %s\n",
791  video_size / 1024.0,
792  audio_size / 1024.0,
793  subtitle_size / 1024.0,
794  other_size / 1024.0,
795  extra_size / 1024.0,
796  overhead);
797 }
798 
800 {
801  Muxer *mux = mux_from_of(of);
802  AVFormatContext *fc = mux->fc;
803  int ret, mux_result = 0;
804 
805  if (!mux->tq) {
806  av_log(mux, AV_LOG_ERROR,
807  "Nothing was written into output file, because "
808  "at least one of its streams received no packets.\n");
809  return AVERROR(EINVAL);
810  }
811 
812  mux_result = thread_stop(mux);
813 
815  if (ret < 0) {
816  av_log(mux, AV_LOG_ERROR, "Error writing trailer: %s\n", av_err2str(ret));
817  mux_result = err_merge(mux_result, ret);
818  }
819 
820  mux->last_filesize = filesize(fc->pb);
821 
822  if (!(of->format->flags & AVFMT_NOFILE)) {
823  ret = avio_closep(&fc->pb);
824  if (ret < 0) {
825  av_log(mux, AV_LOG_ERROR, "Error closing file: %s\n", av_err2str(ret));
826  mux_result = err_merge(mux_result, ret);
827  }
828  }
829 
830  mux_final_stats(mux);
831 
832  // check whether anything was actually written
833  ret = check_written(of);
834  mux_result = err_merge(mux_result, ret);
835 
836  return mux_result;
837 }
838 
839 static void ost_free(OutputStream **post)
840 {
841  OutputStream *ost = *post;
842  MuxStream *ms;
843 
844  if (!ost)
845  return;
846  ms = ms_from_ost(ost);
847 
848  enc_free(&ost->enc);
849 
850  if (ost->logfile) {
851  if (fclose(ost->logfile))
852  av_log(ms, AV_LOG_ERROR,
853  "Error closing logfile, loss of information possible: %s\n",
854  av_err2str(AVERROR(errno)));
855  ost->logfile = NULL;
856  }
857 
858  if (ms->muxing_queue) {
859  AVPacket *pkt;
860  while (av_fifo_read(ms->muxing_queue, &pkt, 1) >= 0)
863  }
864 
865  avcodec_parameters_free(&ost->par_in);
866 
867  av_bsf_free(&ms->bsf_ctx);
868  av_packet_free(&ms->bsf_pkt);
869 
870  av_packet_free(&ms->pkt);
871  av_dict_free(&ost->encoder_opts);
872 
873  av_freep(&ost->kf.pts);
874  av_expr_free(ost->kf.pexpr);
875 
876  av_freep(&ost->logfile_prefix);
877  av_freep(&ost->apad);
878 
879 #if FFMPEG_OPT_MAP_CHANNEL
880  av_freep(&ost->audio_channels_map);
881  ost->audio_channels_mapped = 0;
882 #endif
883 
884  av_dict_free(&ost->sws_dict);
885  av_dict_free(&ost->swr_opts);
886 
887  if (ost->enc_ctx)
888  av_freep(&ost->enc_ctx->stats_in);
889  avcodec_free_context(&ost->enc_ctx);
890 
891  for (int i = 0; i < ost->enc_stats_pre.nb_components; i++)
892  av_freep(&ost->enc_stats_pre.components[i].str);
893  av_freep(&ost->enc_stats_pre.components);
894 
895  for (int i = 0; i < ost->enc_stats_post.nb_components; i++)
896  av_freep(&ost->enc_stats_post.components[i].str);
897  av_freep(&ost->enc_stats_post.components);
898 
899  for (int i = 0; i < ms->stats.nb_components; i++)
900  av_freep(&ms->stats.components[i].str);
901  av_freep(&ms->stats.components);
902 
903  av_freep(post);
904 }
905 
906 static void fc_close(AVFormatContext **pfc)
907 {
908  AVFormatContext *fc = *pfc;
909 
910  if (!fc)
911  return;
912 
913  if (!(fc->oformat->flags & AVFMT_NOFILE))
914  avio_closep(&fc->pb);
916 
917  *pfc = NULL;
918 }
919 
920 void of_free(OutputFile **pof)
921 {
922  OutputFile *of = *pof;
923  Muxer *mux;
924 
925  if (!of)
926  return;
927  mux = mux_from_of(of);
928 
929  thread_stop(mux);
930 
931  sq_free(&of->sq_encode);
932  sq_free(&mux->sq_mux);
933 
934  for (int i = 0; i < of->nb_streams; i++)
935  ost_free(&of->streams[i]);
936  av_freep(&of->streams);
937 
938  av_dict_free(&mux->opts);
939 
940  av_packet_free(&mux->sq_pkt);
941 
942  fc_close(&mux->fc);
943 
944  av_freep(pof);
945 }
946 
948 {
949  Muxer *mux = mux_from_of(of);
950  return atomic_load(&mux->last_filesize);
951 }
MuxStream::ost
OutputStream ost
Definition: ffmpeg_mux.h:38
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:423
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
MuxStream::copy_initial_nonkeyframes
int copy_initial_nonkeyframes
Definition: ffmpeg_mux.h:84
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:95
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
of_output_packet
int of_output_packet(OutputFile *of, OutputStream *ost, AVPacket *pkt)
Definition: ffmpeg_mux.c:349
level
uint8_t level
Definition: svq3.c:204
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:118
AVOutputFormat::name
const char * name
Definition: avformat.h:511
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:51
mux_from_of
static Muxer * mux_from_of(OutputFile *of)
Definition: ffmpeg_mux.c:43
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:47
Muxer::thread
pthread_t thread
Definition: ffmpeg_mux.h:97
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:480
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:264
print_sdp
static int print_sdp(void)
Definition: ffmpeg_mux.c:534
MuxStream::max_muxing_queue_size
int max_muxing_queue_size
Definition: ffmpeg_mux.h:61
OutputFile::start_time
int64_t start_time
start time in microseconds == AV_TIME_BASE units
Definition: ffmpeg.h:629
Muxer::thread_queue_size
int thread_queue_size
Definition: ffmpeg_mux.h:102
MuxStream::muxing_queue_data_threshold
size_t muxing_queue_data_threshold
Definition: ffmpeg_mux.h:64
sync_queue.h
fc_close
static void fc_close(AVFormatContext **pfc)
Definition: ffmpeg_mux.c:906
nb_output_dumped
unsigned nb_output_dumped
Definition: ffmpeg.c:118
Muxer::of
OutputFile of
Definition: ffmpeg_mux.h:90
MuxStream::ts_rescale_delta_last
int64_t ts_rescale_delta_last
Definition: ffmpeg_mux.h:79
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:464
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:509
max
#define max(a, b)
Definition: cuda_runtime.h:33
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
enc_stats_write
void enc_stats_write(OutputStream *ost, EncStats *es, const AVFrame *frame, const AVPacket *pkt, uint64_t frame_num)
Definition: ffmpeg_enc.c:481
MuxStream::copy_prior_start
int copy_prior_start
Definition: ffmpeg_mux.h:85
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:52
avio_size
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:370
ost
static AVStream * ost
Definition: vaapi_transcode.c:42
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:546
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:74
AVBSFContext
The bitstream filter state.
Definition: bsf.h:68
MuxStream::ts_copy_start
int64_t ts_copy_start
Definition: ffmpeg_mux.h:69
MuxStream::stream_duration_tb
AVRational stream_duration_tb
Definition: ffmpeg_mux.h:76
OutputFile::nb_streams
int nb_streams
Definition: ffmpeg.h:624
Muxer
Definition: ffmpeg_mux.h:89
debug_ts
int debug_ts
Definition: ffmpeg_opt.c:81
thread_stop
static int thread_stop(Muxer *mux)
Definition: ffmpeg_mux.c:475
objpool.h
of_filesize
int64_t of_filesize(OutputFile *of)
Definition: ffmpeg_mux.c:947
fifo.h
mux_final_stats
static void mux_final_stats(Muxer *mux)
Definition: ffmpeg_mux.c:733
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:1265
finish
static void finish(void)
Definition: movenc.c:342
Muxer::tq
ThreadQueue * tq
Definition: ffmpeg_mux.h:98
fail
#define fail()
Definition: checkasm.h:138
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:513
sq_receive
int sq_receive(SyncQueue *sq, int stream_idx, SyncQueueFrame frame)
Read a frame from the queue.
Definition: sync_queue.c:608
type
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 type
Definition: writing_filters.txt:86
want_sdp
int want_sdp
Definition: ffmpeg_mux.c:41
thread_start
static int thread_start(Muxer *mux)
Definition: ffmpeg_mux.c:492
Muxer::sq_pkt
AVPacket * sq_pkt
Definition: ffmpeg_mux.h:110
AVStream::duration
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:900
trigger_fix_sub_duration_heartbeat
int trigger_fix_sub_duration_heartbeat(OutputStream *ost, const AVPacket *pkt)
Definition: ffmpeg.c:771
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
ABORT_ON_FLAG_EMPTY_OUTPUT_STREAM
#define ABORT_ON_FLAG_EMPTY_OUTPUT_STREAM
Definition: ffmpeg.h:445
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
duration
int64_t duration
Definition: movenc.c:64
AVCodecParameters::frame_size
int frame_size
Audio only.
Definition: codec_par.h:182
EncStats::components
EncStatsComponent * components
Definition: ffmpeg.h:476
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
MuxStream::pkt
AVPacket * pkt
Definition: ffmpeg_mux.h:49
mux_check_init
int mux_check_init(Muxer *mux)
Definition: ffmpeg_mux.c:590
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:637
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:486
ctx
AVFormatContext * ctx
Definition: movenc.c:48
AVBSFContext::time_base_in
AVRational time_base_in
The timebase used for the timestamps of the input packets.
Definition: bsf.h:102
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
av_rescale_delta
int64_t av_rescale_delta(AVRational in_tb, int64_t in_ts, AVRational fs_tb, int duration, int64_t *last, AVRational out_tb)
Rescale a timestamp while preserving known durations.
Definition: mathematics.c:168
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:477
Muxer::limit_filesize
int64_t limit_filesize
Definition: ffmpeg_mux.h:105
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:1115
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:864
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:149
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:880
NULL
#define NULL
Definition: coverity.c:32
of_free
void of_free(OutputFile **pof)
Definition: ffmpeg_mux.c:920
avcodec_parameters_free
void avcodec_parameters_free(AVCodecParameters **ppar)
Free an AVCodecParameters instance and everything associated with it and write NULL to the supplied p...
Definition: codec_par.c:66
fs
#define fs(width, name, subs,...)
Definition: cbs_vp9.c:200
av_bsf_receive_packet
int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt)
Retrieve a filtered packet.
Definition: bsf.c:230
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:556
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
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
av_fifo_can_read
size_t av_fifo_can_read(const AVFifo *f)
Definition: fifo.c:87
MuxStream::bsf_ctx
AVBSFContext * bsf_ctx
Definition: ffmpeg_mux.h:46
MuxStream::streamcopy_started
int streamcopy_started
Definition: ffmpeg_mux.h:86
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:431
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:480
OutputFile::index
int index
Definition: ffmpeg.h:618
Muxer::last_filesize
atomic_int_least64_t last_filesize
Definition: ffmpeg_mux.h:106
OutputFile::streams
OutputStream ** streams
Definition: ffmpeg.h:623
MuxStream::data_size_mux
uint64_t data_size_mux
Definition: ffmpeg_mux.h:82
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:73
AVFormatContext::nb_streams
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1171
AVOutputFormat::flags
int flags
can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_GLOBALHEADER, AVFMT_NOTIMESTAMPS,...
Definition: avformat.h:530
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:799
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
AVMediaType
AVMediaType
Definition: avutil.h:199
Muxer::sq_mux
SyncQueue * sq_mux
Definition: ffmpeg_mux.h:109
AVPacket::size
int size
Definition: packet.h:492
output_files
OutputFile ** output_files
Definition: ffmpeg.c:126
av_bsf_send_packet
int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt)
Submit a packet for filtering.
Definition: bsf.c:202
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
start_time
static int64_t start_time
Definition: ffplay.c:328
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:343
sq_free
void sq_free(SyncQueue **psq)
Definition: sync_queue.c:699
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:170
av_get_audio_frame_duration2
int av_get_audio_frame_duration2(AVCodecParameters *par, int frame_bytes)
This function is the same as av_get_audio_frame_duration(), except it works with AVCodecParameters in...
Definition: utils.c:812
OutputFile::url
const char * url
Definition: ffmpeg.h:621
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:469
printf
printf("static const uint8_t my_array[100] = {\n")
Muxer::opts
AVDictionary * opts
Definition: ffmpeg_mux.h:100
MuxStream::bsf_pkt
AVPacket * bsf_pkt
Definition: ffmpeg_mux.h:47
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:490
MuxStream
Definition: ffmpeg_mux.h:37
AV_CODEC_FLAG_PASS2
#define AV_CODEC_FLAG_PASS2
Use internal 2pass ratecontrol in second pass mode.
Definition: avcodec.h:310
ObjPool
Definition: objpool.c:30
pkt_move
static void pkt_move(void *dst, void *src)
Definition: ffmpeg.h:945
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
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:497
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:486
av_packet_alloc
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition: avpacket.c:63
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:225
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:626
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:527
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:1304
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:1291
MuxStream::muxing_queue_data_size
size_t muxing_queue_data_size
Definition: ffmpeg_mux.h:59
submit_packet
static int submit_packet(Muxer *mux, AVPacket *pkt, OutputStream *ost)
Definition: ffmpeg_mux.c:330
log.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:484
packet.h
MuxStream::stats
EncStats stats
Definition: ffmpeg_mux.h:51
FFMIN3
#define FFMIN3(a, b, c)
Definition: macros.h:50
check_written
static int check_written(OutputFile *of)
Definition: ffmpeg_mux.c:694
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:82
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
int_cb
const AVIOInterruptCB int_cb
Definition: ffmpeg.c:346
AVBSFContext::time_base_out
AVRational time_base_out
The timebase used for the timestamps of the output packets.
Definition: bsf.h:108
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:127
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:142
AVFMT_TS_NONSTRICT
#define AVFMT_TS_NONSTRICT
Format does not require strictly increasing timestamps, but they must still be monotonic.
Definition: avformat.h:492
muxer_thread
static void * muxer_thread(void *arg)
Definition: ffmpeg_mux.c:212
Muxer::header_written
int header_written
Definition: ffmpeg_mux.h:107
ret
ret
Definition: filter_design.txt:187
AV_LOG_FATAL
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition: log.h:174
enc_free
void enc_free(Encoder **penc)
Definition: ffmpeg_enc.c:56
abort_on_flags
int abort_on_flags
Definition: ffmpeg_opt.c:83
VSYNC_DROP
@ VSYNC_DROP
Definition: ffmpeg.h:69
sdp_filename
char * sdp_filename
Definition: ffmpeg_opt.c:66
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:847
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:102
thread_queue.h
AVPacket::stream_index
int stream_index
Definition: packet.h:493
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
mem.h
queue_packet
static int queue_packet(OutputStream *ost, AVPacket *pkt)
Definition: ffmpeg_mux.c:288
ffmpeg_mux.h
ost_free
static void ost_free(OutputStream **post)
Definition: ffmpeg_mux.c:839
AVPacket
This structure stores compressed data.
Definition: packet.h:468
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:1276
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
EncStats::nb_components
int nb_components
Definition: ffmpeg.h:477
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:671
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:471
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
err_merge
static int err_merge(int err0, int err1)
Merge two return codes - return one of the error codes if at least one of them was negative,...
Definition: ffmpeg.h:889
OutputFile::format
const AVOutputFormat * format
Definition: ffmpeg.h:620
OutputFile::recording_time
int64_t recording_time
desired length of the resulting file in microseconds == AV_TIME_BASE units
Definition: ffmpeg.h:628
snprintf
#define snprintf
Definition: snprintf.h:34
EncStats::io
AVIOContext * io
Definition: ffmpeg.h:479
ABORT_ON_FLAG_EMPTY_OUTPUT
#define ABORT_ON_FLAG_EMPTY_OUTPUT
Definition: ffmpeg.h:444
thread_set_name
static void thread_set_name(OutputFile *of)
Definition: ffmpeg_mux.c:205
of_streamcopy
int of_streamcopy(OutputStream *ost, const AVPacket *pkt, int64_t dts)
Definition: ffmpeg_mux.c:406
MuxStream::last_mux_dts
int64_t last_mux_dts
Definition: ffmpeg_mux.h:73
avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:106
AVPacket::time_base
AVRational time_base
Time base of the packet's timestamps.
Definition: packet.h:535
MuxStream::stream_duration
int64_t stream_duration
Definition: ffmpeg_mux.h:75
AV_CODEC_FLAG_PASS1
#define AV_CODEC_FLAG_PASS1
Use internal 2pass ratecontrol in first pass mode.
Definition: avcodec.h:306
OutputFile
Definition: ffmpeg.h:615
thread_submit_packet
static int thread_submit_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
Definition: ffmpeg_mux.c:266
bsf_init
static int bsf_init(MuxStream *ms)
Definition: ffmpeg_mux.c:637
ff_thread_setname
static int ff_thread_setname(const char *name)
Definition: thread.h:214
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