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 "objpool.h"
25 #include "sync_queue.h"
26 #include "thread_queue.h"
27 
28 #include "libavutil/fifo.h"
29 #include "libavutil/intreadwrite.h"
30 #include "libavutil/log.h"
31 #include "libavutil/mem.h"
32 #include "libavutil/timestamp.h"
33 #include "libavutil/thread.h"
34 
35 #include "libavcodec/packet.h"
36 
37 #include "libavformat/avformat.h"
38 #include "libavformat/avio.h"
39 
40 typedef struct MuxStream {
41  /* the packets are buffered here until the muxer is ready to be initialized */
43 
44  /*
45  * The size of the AVPackets' buffers in queue.
46  * Updated when a packet is either pushed or pulled from the queue.
47  */
49 
50  /* dts of the last packet sent to the muxer, in the stream timebase
51  * used for making up missing dts values */
52  int64_t last_mux_dts;
53 } MuxStream;
54 
55 struct Muxer {
57 
60 
62 
64 
66 
67  /* filesize limit expressed in bytes */
68  int64_t limit_filesize;
71 
73 };
74 
75 static int want_sdp = 1;
76 
77 static int64_t filesize(AVIOContext *pb)
78 {
79  int64_t ret = -1;
80 
81  if (pb) {
82  ret = avio_size(pb);
83  if (ret <= 0) // FIXME improve avio_size() so it works with non seekable output too
84  ret = avio_tell(pb);
85  }
86 
87  return ret;
88 }
89 
91 {
92  MuxStream *ms = &of->mux->streams[ost->index];
93  AVFormatContext *s = of->mux->fc;
94  AVStream *st = ost->st;
95  int64_t fs;
96  int ret;
97 
98  fs = filesize(s->pb);
100  if (fs >= of->mux->limit_filesize) {
101  ret = AVERROR_EOF;
102  goto fail;
103  }
104 
105  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->vsync_method == VSYNC_DROP)
106  pkt->pts = pkt->dts = AV_NOPTS_VALUE;
107 
108  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
109  if (ost->frame_rate.num && ost->is_cfr) {
110  if (pkt->duration > 0)
111  av_log(NULL, AV_LOG_WARNING, "Overriding packet duration by frame rate, this should not happen\n");
112  pkt->duration = av_rescale_q(1, av_inv_q(ost->frame_rate),
113  ost->mux_timebase);
114  }
115  }
116 
117  av_packet_rescale_ts(pkt, ost->mux_timebase, ost->st->time_base);
118 
119  if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) {
120  if (pkt->dts != AV_NOPTS_VALUE &&
121  pkt->pts != AV_NOPTS_VALUE &&
122  pkt->dts > pkt->pts) {
123  av_log(s, AV_LOG_WARNING, "Invalid DTS: %"PRId64" PTS: %"PRId64" in output stream %d:%d, replacing by guess\n",
124  pkt->dts, pkt->pts,
125  ost->file_index, ost->st->index);
126  pkt->pts =
127  pkt->dts = pkt->pts + pkt->dts + ms->last_mux_dts + 1
128  - FFMIN3(pkt->pts, pkt->dts, ms->last_mux_dts + 1)
129  - FFMAX3(pkt->pts, pkt->dts, ms->last_mux_dts + 1);
130  }
132  pkt->dts != AV_NOPTS_VALUE &&
133  ms->last_mux_dts != AV_NOPTS_VALUE) {
134  int64_t max = ms->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT);
135  if (pkt->dts < max) {
136  int loglevel = max - pkt->dts > 2 || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ? AV_LOG_WARNING : AV_LOG_DEBUG;
137  if (exit_on_error)
138  loglevel = AV_LOG_ERROR;
139  av_log(s, loglevel, "Non-monotonous DTS in output stream "
140  "%d:%d; previous: %"PRId64", current: %"PRId64"; ",
141  ost->file_index, ost->st->index, ms->last_mux_dts, pkt->dts);
142  if (exit_on_error) {
143  ret = AVERROR(EINVAL);
144  goto fail;
145  }
146 
147  av_log(s, loglevel, "changing to %"PRId64". This may result "
148  "in incorrect timestamps in the output file.\n",
149  max);
150  if (pkt->pts >= pkt->dts)
151  pkt->pts = FFMAX(pkt->pts, max);
152  pkt->dts = max;
153  }
154  }
155  }
156  ms->last_mux_dts = pkt->dts;
157 
158  ost->data_size_mux += pkt->size;
159  atomic_fetch_add(&ost->packets_written, 1);
160 
162 
163  if (debug_ts) {
164  av_log(NULL, AV_LOG_INFO, "muxer <- type:%s "
165  "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s duration:%s duration_time:%s size:%d\n",
170  pkt->size
171  );
172  }
173 
175  if (ret < 0) {
176  print_error("av_interleaved_write_frame()", ret);
177  goto fail;
178  }
179 
180  return 0;
181 fail:
183  return ret;
184 }
185 
187 {
188  if (ost->sq_idx_mux >= 0) {
189  int ret = sq_send(of->sq_mux, ost->sq_idx_mux, SQPKT(pkt));
190  if (ret < 0)
191  return ret;
192 
193  while (1) {
194  ret = sq_receive(of->sq_mux, -1, SQPKT(of->mux->sq_pkt));
195  if (ret < 0)
196  return (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) ? 0 : ret;
197 
199  of->mux->sq_pkt);
200  if (ret < 0)
201  return ret;
202  }
203  } else if (pkt)
204  return write_packet(of, ost, pkt);
205 
206  return 0;
207 }
208 
209 static void *muxer_thread(void *arg)
210 {
211  OutputFile *of = arg;
212  Muxer *mux = of->mux;
213  AVPacket *pkt = NULL;
214  int ret = 0;
215 
216  pkt = av_packet_alloc();
217  if (!pkt) {
218  ret = AVERROR(ENOMEM);
219  goto finish;
220  }
221 
222  while (1) {
223  OutputStream *ost;
224  int stream_idx;
225 
226  ret = tq_receive(mux->tq, &stream_idx, pkt);
227  if (stream_idx < 0) {
229  "All streams finished for output file #%d\n", of->index);
230  ret = 0;
231  break;
232  }
233 
234  ost = output_streams[of->ost_index + stream_idx];
235  ret = sync_queue_process(of, ost, ret < 0 ? NULL : pkt);
237  if (ret == AVERROR_EOF)
238  tq_receive_finish(mux->tq, stream_idx);
239  else if (ret < 0) {
241  "Error muxing a packet for output file #%d\n", of->index);
242  break;
243  }
244  }
245 
246 finish:
248 
249  for (unsigned int i = 0; i < mux->fc->nb_streams; i++)
250  tq_receive_finish(mux->tq, i);
251 
252  av_log(NULL, AV_LOG_VERBOSE, "Terminating muxer thread %d\n", of->index);
253 
254  return (void*)(intptr_t)ret;
255 }
256 
258 {
259  Muxer *mux = of->mux;
260  int ret = 0;
261 
262  if (!pkt || ost->finished & MUXER_FINISHED)
263  goto finish;
264 
265  ret = tq_send(mux->tq, ost->index, pkt);
266  if (ret < 0)
267  goto finish;
268 
269  return 0;
270 
271 finish:
272  if (pkt)
274 
275  ost->finished |= MUXER_FINISHED;
276  tq_send_finish(mux->tq, ost->index);
277  return ret == AVERROR_EOF ? 0 : ret;
278 }
279 
281 {
282  MuxStream *ms = &of->mux->streams[ost->index];
283  AVPacket *tmp_pkt = NULL;
284  int ret;
285 
286  if (!av_fifo_can_write(ms->muxing_queue)) {
287  size_t cur_size = av_fifo_can_read(ms->muxing_queue);
288  size_t pkt_size = pkt ? pkt->size : 0;
289  unsigned int are_we_over_size =
290  (ms->muxing_queue_data_size + pkt_size) > ost->muxing_queue_data_threshold;
291  size_t limit = are_we_over_size ? ost->max_muxing_queue_size : SIZE_MAX;
292  size_t new_size = FFMIN(2 * cur_size, limit);
293 
294  if (new_size <= cur_size) {
296  "Too many packets buffered for output stream %d:%d.\n",
297  ost->file_index, ost->st->index);
298  return AVERROR(ENOSPC);
299  }
300  ret = av_fifo_grow2(ms->muxing_queue, new_size - cur_size);
301  if (ret < 0)
302  return ret;
303  }
304 
305  if (pkt) {
307  if (ret < 0)
308  return ret;
309 
310  tmp_pkt = av_packet_alloc();
311  if (!tmp_pkt)
312  return AVERROR(ENOMEM);
313 
314  av_packet_move_ref(tmp_pkt, pkt);
315  ms->muxing_queue_data_size += tmp_pkt->size;
316  }
317  av_fifo_write(ms->muxing_queue, &tmp_pkt, 1);
318 
319  return 0;
320 }
321 
323 {
324  int ret;
325 
326  if (of->mux->tq) {
327  return submit_packet(of, ost, pkt);
328  } else {
329  /* the muxer is not initialized yet, buffer the packet */
330  ret = queue_packet(of, ost, pkt);
331  if (ret < 0) {
333  return ret;
334  }
335  }
336 
337  return 0;
338 }
339 
340 static int thread_stop(OutputFile *of)
341 {
342  Muxer *mux = of->mux;
343  void *ret;
344 
345  if (!mux || !mux->tq)
346  return 0;
347 
348  for (unsigned int i = 0; i < mux->fc->nb_streams; i++)
349  tq_send_finish(mux->tq, i);
350 
351  pthread_join(mux->thread, &ret);
352 
353  tq_free(&mux->tq);
354 
355  return (int)(intptr_t)ret;
356 }
357 
358 static void pkt_move(void *dst, void *src)
359 {
360  av_packet_move_ref(dst, src);
361 }
362 
363 static int thread_start(OutputFile *of)
364 {
365  Muxer *mux = of->mux;
366  AVFormatContext *fc = mux->fc;
367  ObjPool *op;
368  int ret;
369 
371  if (!op)
372  return AVERROR(ENOMEM);
373 
374  mux->tq = tq_alloc(fc->nb_streams, mux->thread_queue_size, op, pkt_move);
375  if (!mux->tq) {
376  objpool_free(&op);
377  return AVERROR(ENOMEM);
378  }
379 
380  ret = pthread_create(&mux->thread, NULL, muxer_thread, (void*)of);
381  if (ret) {
382  tq_free(&mux->tq);
383  return AVERROR(ret);
384  }
385 
386  /* flush the muxing queues */
387  for (int i = 0; i < fc->nb_streams; i++) {
388  MuxStream *ms = &of->mux->streams[i];
389  OutputStream *ost = output_streams[of->ost_index + i];
390  AVPacket *pkt;
391 
392  /* try to improve muxing time_base (only possible if nothing has been written yet) */
393  if (!av_fifo_can_read(ms->muxing_queue))
394  ost->mux_timebase = ost->st->time_base;
395 
396  while (av_fifo_read(ms->muxing_queue, &pkt, 1) >= 0) {
397  ret = submit_packet(of, ost, pkt);
398  if (pkt) {
401  }
402  if (ret < 0)
403  return ret;
404  }
405  }
406 
407  return 0;
408 }
409 
410 static int print_sdp(void)
411 {
412  char sdp[16384];
413  int i;
414  int j, ret;
415  AVIOContext *sdp_pb;
416  AVFormatContext **avc;
417 
418  for (i = 0; i < nb_output_files; i++) {
419  if (!output_files[i]->mux->header_written)
420  return 0;
421  }
422 
423  avc = av_malloc_array(nb_output_files, sizeof(*avc));
424  if (!avc)
425  return AVERROR(ENOMEM);
426  for (i = 0, j = 0; i < nb_output_files; i++) {
427  if (!strcmp(output_files[i]->format->name, "rtp")) {
428  avc[j] = output_files[i]->mux->fc;
429  j++;
430  }
431  }
432 
433  if (!j) {
434  av_log(NULL, AV_LOG_ERROR, "No output streams in the SDP.\n");
435  ret = AVERROR(EINVAL);
436  goto fail;
437  }
438 
439  ret = av_sdp_create(avc, j, sdp, sizeof(sdp));
440  if (ret < 0)
441  goto fail;
442 
443  if (!sdp_filename) {
444  printf("SDP:\n%s\n", sdp);
445  fflush(stdout);
446  } else {
448  if (ret < 0) {
449  av_log(NULL, AV_LOG_ERROR, "Failed to open sdp file '%s'\n", sdp_filename);
450  goto fail;
451  }
452 
453  avio_print(sdp_pb, sdp);
454  avio_closep(&sdp_pb);
456  }
457 
458  // SDP successfully written, allow muxer threads to start
459  ret = 1;
460 
461 fail:
462  av_freep(&avc);
463  return ret;
464 }
465 
466 /* open the muxer when all the streams are initialized */
468 {
469  AVFormatContext *fc = of->mux->fc;
470  int ret, i;
471 
472  for (i = 0; i < fc->nb_streams; i++) {
474  if (!ost->initialized)
475  return 0;
476  }
477 
478  ret = avformat_write_header(fc, &of->mux->opts);
479  if (ret < 0) {
481  "Could not write header for output file #%d "
482  "(incorrect codec parameters ?): %s\n",
483  of->index, av_err2str(ret));
484  return ret;
485  }
486  //assert_avoptions(of->opts);
487  of->mux->header_written = 1;
488 
489  av_dump_format(fc, of->index, fc->url, 1);
491 
492  if (sdp_filename || want_sdp) {
493  ret = print_sdp();
494  if (ret < 0) {
495  av_log(NULL, AV_LOG_ERROR, "Error writing the SDP.\n");
496  return ret;
497  } else if (ret == 1) {
498  /* SDP is written only after all the muxers are ready, so now we
499  * start ALL the threads */
500  for (i = 0; i < nb_output_files; i++) {
502  if (ret < 0)
503  return ret;
504  }
505  }
506  } else {
507  ret = thread_start(of);
508  if (ret < 0)
509  return ret;
510  }
511 
512  return 0;
513 }
514 
516 {
517  AVFormatContext *fc = of->mux->fc;
518  int ret;
519 
520  if (!of->mux->tq) {
522  "Nothing was written into output file %d (%s), because "
523  "at least one of its streams received no packets.\n",
524  of->index, fc->url);
525  return AVERROR(EINVAL);
526  }
527 
528  ret = thread_stop(of);
529  if (ret < 0)
531 
533  if (ret < 0) {
534  av_log(NULL, AV_LOG_ERROR, "Error writing trailer of %s: %s\n", fc->url, av_err2str(ret));
535  return ret;
536  }
537 
538  of->mux->last_filesize = filesize(fc->pb);
539 
540  if (!(of->format->flags & AVFMT_NOFILE)) {
541  ret = avio_closep(&fc->pb);
542  if (ret < 0) {
543  av_log(NULL, AV_LOG_ERROR, "Error closing file %s: %s\n",
544  fc->url, av_err2str(ret));
545  return ret;
546  }
547  }
548 
549  return 0;
550 }
551 
552 static void fc_close(AVFormatContext **pfc)
553 {
554  AVFormatContext *fc = *pfc;
555 
556  if (!fc)
557  return;
558 
559  if (!(fc->oformat->flags & AVFMT_NOFILE))
560  avio_closep(&fc->pb);
562 
563  *pfc = NULL;
564 }
565 
566 static void mux_free(Muxer **pmux)
567 {
568  Muxer *mux = *pmux;
569 
570  if (!mux)
571  return;
572 
573  for (int i = 0; i < mux->fc->nb_streams; i++) {
574  MuxStream *ms = &mux->streams[i];
575  AVPacket *pkt;
576 
577  if (!ms->muxing_queue)
578  continue;
579 
580  while (av_fifo_read(ms->muxing_queue, &pkt, 1) >= 0)
583  }
584  av_freep(&mux->streams);
585  av_dict_free(&mux->opts);
586 
587  av_packet_free(&mux->sq_pkt);
588 
589  fc_close(&mux->fc);
590 
591  av_freep(pmux);
592 }
593 
594 void of_close(OutputFile **pof)
595 {
596  OutputFile *of = *pof;
597 
598  if (!of)
599  return;
600 
601  thread_stop(of);
602 
603  sq_free(&of->sq_encode);
604  sq_free(&of->sq_mux);
605 
606  mux_free(&of->mux);
607 
608  av_freep(pof);
609 }
610 
612  AVDictionary *opts, int64_t limit_filesize,
613  int thread_queue_size)
614 {
615  Muxer *mux = av_mallocz(sizeof(*mux));
616  int ret = 0;
617 
618  if (!mux) {
619  fc_close(&fc);
620  return AVERROR(ENOMEM);
621  }
622 
623  mux->streams = av_calloc(fc->nb_streams, sizeof(*mux->streams));
624  if (!mux->streams) {
625  fc_close(&fc);
626  av_freep(&mux);
627  return AVERROR(ENOMEM);
628  }
629 
630  of->mux = mux;
631  mux->fc = fc;
632 
633  for (int i = 0; i < fc->nb_streams; i++) {
634  MuxStream *ms = &mux->streams[i];
635  ms->muxing_queue = av_fifo_alloc2(8, sizeof(AVPacket*), 0);
636  if (!ms->muxing_queue) {
637  ret = AVERROR(ENOMEM);
638  goto fail;
639  }
641  }
642 
643  mux->thread_queue_size = thread_queue_size > 0 ? thread_queue_size : 8;
644  mux->limit_filesize = limit_filesize;
645  mux->opts = opts;
646 
647  if (strcmp(of->format->name, "rtp"))
648  want_sdp = 0;
649 
650  if (of->sq_mux) {
651  mux->sq_pkt = av_packet_alloc();
652  if (!mux->sq_pkt) {
653  ret = AVERROR(ENOMEM);
654  goto fail;
655  }
656  }
657 
658  /* write the header for files with no streams */
659  if (of->format->flags & AVFMT_NOSTREAMS && fc->nb_streams == 0) {
660  ret = of_check_init(of);
661  if (ret < 0)
662  goto fail;
663  }
664 
665 fail:
666  if (ret < 0)
667  mux_free(&of->mux);
668 
669  return ret;
670 }
671 
673 {
674  return atomic_load(&of->mux->last_filesize);
675 }
676 
677 AVChapter * const *
678 of_get_chapters(OutputFile *of, unsigned int *nb_chapters)
679 {
680  *nb_chapters = of->mux->fc->nb_chapters;
681  return of->mux->fc->chapters;
682 }
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:422
pthread_join
static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
Definition: os2threads.h:94
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:204
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
Muxer::fc
AVFormatContext * fc
Definition: ffmpeg_mux.c:56
av_fifo_can_write
size_t av_fifo_can_write(const AVFifo *f)
Definition: fifo.c:94
atomic_store
#define atomic_store(object, desired)
Definition: stdatomic.h:85
AVOutputFormat::name
const char * name
Definition: avformat.h:510
of_muxer_init
int of_muxer_init(OutputFile *of, AVFormatContext *fc, AVDictionary *opts, int64_t limit_filesize, int thread_queue_size)
Definition: ffmpeg_mux.c:611
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:57
AVFormatContext::nb_chapters
unsigned int nb_chapters
Number of chapters in AVChapter array.
Definition: avformat.h:1434
Muxer::thread
pthread_t thread
Definition: ffmpeg_mux.c:58
thread.h
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
MuxStream::muxing_queue
AVFifo * muxing_queue
Definition: ffmpeg_mux.c:42
AVFMT_NOTIMESTAMPS
#define AVFMT_NOTIMESTAMPS
Format does not need / have any timestamps.
Definition: avformat.h:481
print_sdp
static int print_sdp(void)
Definition: ffmpeg_mux.c:410
Muxer::thread_queue_size
int thread_queue_size
Definition: ffmpeg_mux.c:65
sync_queue.h
fc_close
static void fc_close(AVFormatContext **pfc)
Definition: ffmpeg_mux.c:552
nb_output_dumped
unsigned nb_output_dumped
Definition: ffmpeg.c:139
objpool_free
void objpool_free(ObjPool **pop)
Definition: objpool.c:54
ffmpeg.h
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:551
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:392
max
#define max(a, b)
Definition: cuda_runtime.h:33
AVDictionary
Definition: dict.c:31
of_get_chapters
AVChapter *const * of_get_chapters(OutputFile *of, unsigned int *nb_chapters)
Definition: ffmpeg_mux.c:678
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
objpool_alloc_packets
ObjPool * objpool_alloc_packets(void)
Definition: objpool.c:124
avio_size
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:354
ost
static AVStream * ost
Definition: vaapi_transcode.c:45
av_packet_free
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition: avpacket.c:73
Muxer
Definition: ffmpeg_mux.c:55
debug_ts
int debug_ts
Definition: ffmpeg_opt.c:169
objpool.h
print_error
void print_error(const char *filename, int err)
Print an error message to stderr, indicating filename and a human readable description of the error c...
Definition: cmdutils.c:799
of_filesize
int64_t of_filesize(OutputFile *of)
Definition: ffmpeg_mux.c:672
fifo.h
avio_open2
int avio_open2(AVIOContext **s, const char *url, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options)
Create and initialize a AVIOContext for accessing the resource indicated by url.
Definition: aviobuf.c:1251
finish
static void finish(void)
Definition: movenc.c:342
Muxer::tq
ThreadQueue * tq
Definition: ffmpeg_mux.c:59
fail
#define fail()
Definition: checkasm.h:133
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:509
AVChapter
Definition: avformat.h:1175
sq_receive
int sq_receive(SyncQueue *sq, int stream_idx, SyncQueueFrame frame)
Read a frame from the queue.
Definition: sync_queue.c:339
want_sdp
static int want_sdp
Definition: ffmpeg_mux.c:75
of_close
void of_close(OutputFile **pof)
Definition: ffmpeg_mux.c:594
Muxer::sq_pkt
AVPacket * sq_pkt
Definition: ffmpeg_mux.c:72
thread_stop
static int thread_stop(OutputFile *of)
Definition: ffmpeg_mux.c:340
SQPKT
#define SQPKT(pkt)
Definition: sync_queue.h:39
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_dump_format
void av_dump_format(AVFormatContext *ic, int index, const char *url, int is_output)
Print detailed information about the input or output format, such as duration, bitrate,...
Definition: dump.c:629
av_fifo_read
int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems)
Read data from a FIFO.
Definition: fifo.c:240
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:256
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
AVFormatContext::chapters
AVChapter ** chapters
Definition: avformat.h:1435
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:633
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:485
OutputFile::sq_mux
SyncQueue * sq_mux
Definition: ffmpeg.h:625
OutputFile::mux
Muxer * mux
Definition: ffmpeg.h:620
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
atomic_load
#define atomic_load(object)
Definition: stdatomic.h:93
avformat_write_header
av_warn_unused_result int avformat_write_header(AVFormatContext *s, AVDictionary **options)
Allocate the stream private data and write the stream header to an output media file.
Definition: mux.c:449
Muxer::limit_filesize
int64_t limit_filesize
Definition: ffmpeg_mux.c:68
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
mux_free
static void mux_free(Muxer **pmux)
Definition: ffmpeg_mux.c:566
output_streams
OutputStream ** output_streams
Definition: ffmpeg.c:149
AVFormatContext
Format I/O context.
Definition: avformat.h:1216
opts
AVDictionary * opts
Definition: movenc.c:50
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1108
tq_free
void tq_free(ThreadQueue **ptq)
Definition: thread_queue.c:55
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:978
NULL
#define NULL
Definition: coverity.c:32
fs
#define fs(width, name, subs,...)
Definition: cbs_vp9.c:258
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:552
av_fifo_can_read
size_t av_fifo_can_read(const AVFifo *f)
Definition: fifo.c:87
main_return_code
int main_return_code
Definition: ffmpeg.c:339
av_packet_move_ref
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
Move every field in src to dst and reset src.
Definition: avpacket.c:479
OutputFile::index
int index
Definition: ffmpeg.h:618
of_submit_packet
int of_submit_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost)
Definition: ffmpeg_mux.c:322
Muxer::last_filesize
atomic_int_least64_t last_filesize
Definition: ffmpeg_mux.c:69
AVFormatContext::nb_streams
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1272
AVOutputFormat::flags
int flags
can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_GLOBALHEADER, AVFMT_NOTIMESTAMPS,...
Definition: avformat.h:529
tq_send
int tq_send(ThreadQueue *tq, unsigned int stream_idx, void *data)
Send an item for the given stream to the queue.
Definition: thread_queue.c:120
AVIOContext
Bytestream IO Context.
Definition: avio.h:166
of_write_trailer
int of_write_trailer(OutputFile *of)
Definition: ffmpeg_mux.c:515
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
AVPacket::size
int size
Definition: packet.h:375
AVFifo
Definition: fifo.c:35
output_files
OutputFile ** output_files
Definition: ffmpeg.c:151
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:121
sq_send
int sq_send(SyncQueue *sq, unsigned int stream_idx, SyncQueueFrame frame)
Submit a frame for the stream with index stream_idx.
Definition: sync_queue.c:234
sq_free
void sq_free(SyncQueue **psq)
Definition: sync_queue.c:428
avio.h
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:470
printf
printf("static const uint8_t my_array[100] = {\n")
Muxer::opts
AVDictionary * opts
Definition: ffmpeg_mux.c:63
AVFMT_NOSTREAMS
#define AVFMT_NOSTREAMS
Format does not require any streams.
Definition: avformat.h:486
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:373
MuxStream
Definition: ffmpeg_mux.c:40
ObjPool
Definition: objpool.c:30
pkt_move
static void pkt_move(void *dst, void *src)
Definition: ffmpeg_mux.c:358
av_sdp_create
int av_sdp_create(AVFormatContext *ac[], int n_files, char *buf, int size)
Generate an SDP for an RTP session.
Definition: sdp.c:911
av_packet_make_refcounted
int av_packet_make_refcounted(AVPacket *pkt)
Ensure the data described by a given packet is reference counted.
Definition: avpacket.c:485
av_packet_alloc
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition: avpacket.c:62
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:208
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:624
av_packet_rescale_ts
void av_packet_rescale_ts(AVPacket *pkt, AVRational src_tb, AVRational dst_tb)
Convert valid timing fields (timestamps / durations) in a packet from one timebase to another.
Definition: avpacket.c:526
pthread_t
Definition: os2threads.h:44
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
filesize
static int64_t filesize(AVIOContext *pb)
Definition: ffmpeg_mux.c:77
of_check_init
int of_check_init(OutputFile *of)
Definition: ffmpeg_mux.c:467
avio_closep
int avio_closep(AVIOContext **s)
Close the resource accessed by the AVIOContext *s, free it and set the pointer pointing to it to NULL...
Definition: aviobuf.c:1290
av_write_trailer
int av_write_trailer(AVFormatContext *s)
Write the stream trailer to an output media file and free the file private data.
Definition: mux.c:1253
MuxStream::muxing_queue_data_size
size_t muxing_queue_data_size
Definition: ffmpeg_mux.c:48
log.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:367
packet.h
FFMIN3
#define FFMIN3(a, b, c)
Definition: macros.h:50
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
sync_queue_process
static int sync_queue_process(OutputFile *of, OutputStream *ost, AVPacket *pkt)
Definition: ffmpeg_mux.c:186
exit_on_error
int exit_on_error
Definition: ffmpeg_opt.c:170
OutputFile::ost_index
int ost_index
Definition: ffmpeg.h:628
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:264
av_inv_q
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
Muxer::streams
MuxStream * streams
Definition: ffmpeg_mux.c:61
int_cb
const AVIOInterruptCB int_cb
Definition: ffmpeg.c:505
tq_receive
int tq_receive(ThreadQueue *tq, int *stream_idx, void *data)
Read the next item from the queue.
Definition: thread_queue.c:191
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:272
nb_output_files
int nb_output_files
Definition: ffmpeg.c:152
limit
static double limit(double x)
Definition: vf_pseudocolor.c:128
AVFMT_TS_NONSTRICT
#define AVFMT_TS_NONSTRICT
Format does not require strictly increasing timestamps, but they must still be monotonic.
Definition: avformat.h:491
atomic_int_least64_t
intptr_t atomic_int_least64_t
Definition: stdatomic.h:68
queue_packet
static int queue_packet(OutputFile *of, OutputStream *ost, AVPacket *pkt)
Definition: ffmpeg_mux.c:280
muxer_thread
static void * muxer_thread(void *arg)
Definition: ffmpeg_mux.c:209
Muxer::header_written
int header_written
Definition: ffmpeg_mux.c:70
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:948
VSYNC_DROP
@ VSYNC_DROP
Definition: ffmpeg.h:63
sdp_filename
char * sdp_filename
Definition: ffmpeg_opt.c:154
ThreadQueue
Definition: thread_queue.c:42
avformat.h
av_fifo_alloc2
AVFifo * av_fifo_alloc2(size_t nb_elems, size_t elem_size, unsigned int flags)
Allocate and initialize an AVFifo with a given element size.
Definition: fifo.c:47
submit_packet
static int submit_packet(OutputFile *of, OutputStream *ost, AVPacket *pkt)
Definition: ffmpeg_mux.c:257
av_get_media_type_string
const char * av_get_media_type_string(enum AVMediaType media_type)
Return a string describing the media_type enum, NULL if media_type is unknown.
Definition: utils.c:28
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:956
atomic_fetch_add
#define atomic_fetch_add(object, operand)
Definition: stdatomic.h:131
thread_start
static int thread_start(OutputFile *of)
Definition: ffmpeg_mux.c:363
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:95
thread_queue.h
AVPacket::stream_index
int stream_index
Definition: packet.h:376
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
mem.h
AVPacket
This structure stores compressed data.
Definition: packet.h:351
av_interleaved_write_frame
int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt)
Write a packet to an output media file ensuring correct interleaving.
Definition: mux.c:1238
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
FFMAX3
#define FFMAX3(a, b, c)
Definition: macros.h:48
timestamp.h
OutputStream
Definition: muxing.c:54
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
av_fifo_freep2
void av_fifo_freep2(AVFifo **f)
Free an AVFifo and reset pointer to NULL.
Definition: fifo.c:286
av_ts2str
#define av_ts2str(ts)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: timestamp.h:54
OutputFile::format
const AVOutputFormat * format
Definition: ffmpeg.h:621
write_packet
static int write_packet(OutputFile *of, OutputStream *ost, AVPacket *pkt)
Definition: ffmpeg_mux.c:90
MuxStream::last_mux_dts
int64_t last_mux_dts
Definition: ffmpeg_mux.c:52
OutputFile
Definition: ffmpeg.h:617
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