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