OpenShot Library | libopenshot  0.4.0
FFmpegWriter.cpp
Go to the documentation of this file.
1 
12 // Copyright (c) 2008-2025 OpenShot Studios, LLC, Fabrice Bellard
13 //
14 // SPDX-License-Identifier: LGPL-3.0-or-later
15 
16 #include <algorithm>
17 #include <iostream>
18 #include <cmath>
19 #include <ctime>
20 #include <unistd.h>
21 
22 #include "FFmpegUtilities.h"
23 
24 #include "FFmpegWriter.h"
25 #include "Exceptions.h"
26 #include "Frame.h"
27 #include "OpenMPUtilities.h"
28 #include "Settings.h"
29 #include "ZmqLogger.h"
30 
31 using namespace openshot;
32 
33 // Multiplexer parameters temporary storage
34 AVDictionary *mux_dict = NULL;
35 
36 #if USE_HW_ACCEL
37 int hw_en_on = 1; // Is set in UI
38 int hw_en_supported = 0; // Is set by FFmpegWriter
39 AVPixelFormat hw_en_av_pix_fmt = AV_PIX_FMT_NONE;
40 AVHWDeviceType hw_en_av_device_type = AV_HWDEVICE_TYPE_VAAPI;
41 static AVBufferRef *hw_device_ctx = NULL;
42 AVFrame *hw_frame = NULL;
43 
44 static int set_hwframe_ctx(AVCodecContext *ctx, AVBufferRef *hw_device_ctx, int64_t width, int64_t height)
45 {
46  AVBufferRef *hw_frames_ref;
47  AVHWFramesContext *frames_ctx = NULL;
48  int err = 0;
49 
50  if (!(hw_frames_ref = av_hwframe_ctx_alloc(hw_device_ctx))) {
51  std::clog << "Failed to create HW frame context.\n";
52  return -1;
53  }
54  frames_ctx = (AVHWFramesContext *)(hw_frames_ref->data);
55  frames_ctx->format = hw_en_av_pix_fmt;
56  frames_ctx->sw_format = AV_PIX_FMT_NV12;
57  frames_ctx->width = width;
58  frames_ctx->height = height;
59  frames_ctx->initial_pool_size = 20;
60  if ((err = av_hwframe_ctx_init(hw_frames_ref)) < 0) {
61  std::clog << "Failed to initialize HW frame context. " <<
62  "Error code: " << av_err2string(err) << "\n";
63  av_buffer_unref(&hw_frames_ref);
64  return err;
65  }
66  ctx->hw_frames_ctx = av_buffer_ref(hw_frames_ref);
67  if (!ctx->hw_frames_ctx)
68  err = AVERROR(ENOMEM);
69 
70  av_buffer_unref(&hw_frames_ref);
71  return err;
72 }
73 #endif // USE_HW_ACCEL
74 
75 FFmpegWriter::FFmpegWriter(const std::string& path) :
76  path(path), oc(NULL), audio_st(NULL), video_st(NULL), samples(NULL),
77  audio_outbuf(NULL), audio_outbuf_size(0), audio_input_frame_size(0), audio_input_position(0),
78  initial_audio_input_frame_size(0), img_convert_ctx(NULL),
79  video_codec_ctx(NULL), audio_codec_ctx(NULL), is_writing(false), video_timestamp(0), audio_timestamp(0),
80  original_sample_rate(0), original_channels(0), avr(NULL), avr_planar(NULL), is_open(false), prepare_streams(false),
81  write_header(false), write_trailer(false), audio_encoder_buffer_size(0), audio_encoder_buffer(NULL) {
82 
83  // Disable audio & video (so they can be independently enabled)
84  info.has_audio = false;
85  info.has_video = false;
86 
87  // Initialize FFMpeg, and register all formats and codecs
89 
90  // auto detect format
91  auto_detect_format();
92 }
93 
94 // Open the writer
96  if (!is_open) {
97  // Open the writer
98  is_open = true;
99 
100  // Prepare streams (if needed)
101  if (!prepare_streams)
102  PrepareStreams();
103 
104  // Now that all the parameters are set, we can open the audio and video codecs and allocate the necessary encode buffers
105  if (info.has_video && video_st)
106  open_video(oc, video_st);
107  if (info.has_audio && audio_st)
108  open_audio(oc, audio_st);
109 
110  // Write header (if needed)
111  if (!write_header)
112  WriteHeader();
113  }
114 }
115 
116 // auto detect format (from path)
117 void FFmpegWriter::auto_detect_format() {
118 
119  // Allocate the output media context
120  AV_OUTPUT_CONTEXT(&oc, path.c_str());
121  if (!oc) {
122  throw OutOfMemory(
123  "Could not allocate memory for AVFormatContext.", path);
124  }
125 
126  // Determine what format to use when encoding this output filename
127  oc->oformat = av_guess_format(NULL, path.c_str(), NULL);
128  if (oc->oformat == nullptr) {
129  throw InvalidFormat(
130  "Could not deduce output format from file extension.", path);
131  }
132 
133  // Update video codec name
134  if (oc->oformat->video_codec != AV_CODEC_ID_NONE && info.has_video)
135  info.vcodec = avcodec_find_encoder(oc->oformat->video_codec)->name;
136 
137  // Update audio codec name
138  if (oc->oformat->audio_codec != AV_CODEC_ID_NONE && info.has_audio)
139  info.acodec = avcodec_find_encoder(oc->oformat->audio_codec)->name;
140 }
141 
142 // initialize streams
143 void FFmpegWriter::initialize_streams() {
145  "FFmpegWriter::initialize_streams",
146  "oc->oformat->video_codec", oc->oformat->video_codec,
147  "oc->oformat->audio_codec", oc->oformat->audio_codec,
148  "AV_CODEC_ID_NONE", AV_CODEC_ID_NONE);
149 
150  // Add the audio and video streams using the default format codecs and initialize the codecs
151  video_st = NULL;
152  audio_st = NULL;
153  if (oc->oformat->video_codec != AV_CODEC_ID_NONE && info.has_video)
154  // Add video stream
155  video_st = add_video_stream();
156 
157  if (oc->oformat->audio_codec != AV_CODEC_ID_NONE && info.has_audio)
158  // Add audio stream
159  audio_st = add_audio_stream();
160 }
161 
162 // Set video export options
163 void FFmpegWriter::SetVideoOptions(bool has_video, std::string codec, Fraction fps, int width, int height, Fraction pixel_ratio, bool interlaced, bool top_field_first, int bit_rate) {
164  // Set the video options
165  if (codec.length() > 0) {
166  const AVCodec *new_codec;
167  // Check if the codec selected is a hardware accelerated codec
168 #if USE_HW_ACCEL
169 #if defined(__linux__)
170  if (strstr(codec.c_str(), "_vaapi") != NULL) {
171  new_codec = avcodec_find_encoder_by_name(codec.c_str());
172  hw_en_on = 1;
173  hw_en_supported = 1;
174  hw_en_av_pix_fmt = AV_PIX_FMT_VAAPI;
175  hw_en_av_device_type = AV_HWDEVICE_TYPE_VAAPI;
176  } else if (strstr(codec.c_str(), "_nvenc") != NULL) {
177  new_codec = avcodec_find_encoder_by_name(codec.c_str());
178  hw_en_on = 1;
179  hw_en_supported = 1;
180  hw_en_av_pix_fmt = AV_PIX_FMT_CUDA;
181  hw_en_av_device_type = AV_HWDEVICE_TYPE_CUDA;
182  } else {
183  new_codec = avcodec_find_encoder_by_name(codec.c_str());
184  hw_en_on = 0;
185  hw_en_supported = 0;
186  }
187 #elif defined(_WIN32)
188  if (strstr(codec.c_str(), "_dxva2") != NULL) {
189  new_codec = avcodec_find_encoder_by_name(codec.c_str());
190  hw_en_on = 1;
191  hw_en_supported = 1;
192  hw_en_av_pix_fmt = AV_PIX_FMT_DXVA2_VLD;
193  hw_en_av_device_type = AV_HWDEVICE_TYPE_DXVA2;
194  } else if (strstr(codec.c_str(), "_nvenc") != NULL) {
195  new_codec = avcodec_find_encoder_by_name(codec.c_str());
196  hw_en_on = 1;
197  hw_en_supported = 1;
198  hw_en_av_pix_fmt = AV_PIX_FMT_CUDA;
199  hw_en_av_device_type = AV_HWDEVICE_TYPE_CUDA;
200  } else {
201  new_codec = avcodec_find_encoder_by_name(codec.c_str());
202  hw_en_on = 0;
203  hw_en_supported = 0;
204  }
205 #elif defined(__APPLE__)
206  if (strstr(codec.c_str(), "_videotoolbox") != NULL) {
207  new_codec = avcodec_find_encoder_by_name(codec.c_str());
208  hw_en_on = 1;
209  hw_en_supported = 1;
210  hw_en_av_pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX;
211  hw_en_av_device_type = AV_HWDEVICE_TYPE_VIDEOTOOLBOX;
212  } else {
213  new_codec = avcodec_find_encoder_by_name(codec.c_str());
214  hw_en_on = 0;
215  hw_en_supported = 0;
216  }
217 #else // unknown OS
218  new_codec = avcodec_find_encoder_by_name(codec.c_str());
219 #endif //__linux__/_WIN32/__APPLE__
220 #else // USE_HW_ACCEL
221  new_codec = avcodec_find_encoder_by_name(codec.c_str());
222 #endif // USE_HW_ACCEL
223  if (new_codec == NULL)
224  throw InvalidCodec("A valid video codec could not be found for this file.", path);
225  else {
226  // Set video codec
227  info.vcodec = new_codec->name;
228  }
229  }
230  if (fps.num > 0) {
231  // Set frames per second (if provided)
232  info.fps.num = fps.num;
233  info.fps.den = fps.den;
234 
235  // Set the timebase (inverse of fps)
238  }
239  if (width >= 1)
240  info.width = width;
241  if (height >= 1)
242  info.height = height;
243  if (pixel_ratio.num > 0) {
244  info.pixel_ratio.num = pixel_ratio.num;
245  info.pixel_ratio.den = pixel_ratio.den;
246  }
247  if (bit_rate >= 1000) // bit_rate is the bitrate in b/s
248  info.video_bit_rate = bit_rate;
249  if ((bit_rate >= 0) && (bit_rate < 256)) // bit_rate is the bitrate in crf
250  info.video_bit_rate = bit_rate;
251 
252  info.interlaced_frame = interlaced;
253  info.top_field_first = top_field_first;
254 
255  // Calculate the DAR (display aspect ratio)
257 
258  // Reduce size fraction
259  size.Reduce();
260 
261  // Set the ratio based on the reduced fraction
262  info.display_ratio.num = size.num;
263  info.display_ratio.den = size.den;
264 
266  "FFmpegWriter::SetVideoOptions (" + codec + ")",
267  "width", width, "height", height,
268  "size.num", size.num, "size.den", size.den,
269  "fps.num", fps.num, "fps.den", fps.den);
270 
271  // Enable / Disable video
272  info.has_video = has_video;
273 }
274 
275 // Set video export options (overloaded function)
276 void FFmpegWriter::SetVideoOptions(std::string codec, int width, int height, Fraction fps, int bit_rate) {
277  // Call full signature with some default parameters
279  true, codec, fps, width, height,
280  openshot::Fraction(1, 1), false, true, bit_rate
281  );
282 }
283 
284 
285 // Set audio export options
286 void FFmpegWriter::SetAudioOptions(bool has_audio, std::string codec, int sample_rate, int channels, ChannelLayout channel_layout, int bit_rate) {
287  // Set audio options
288  if (codec.length() > 0) {
289  const AVCodec *new_codec = avcodec_find_encoder_by_name(codec.c_str());
290  if (new_codec == NULL)
291  throw InvalidCodec("A valid audio codec could not be found for this file.", path);
292  else {
293  // Set audio codec
294  info.acodec = new_codec->name;
295  }
296  }
297  if (sample_rate > 7999)
298  info.sample_rate = sample_rate;
299  if (channels > 0)
300  info.channels = channels;
301  if (bit_rate > 999)
302  info.audio_bit_rate = bit_rate;
303  info.channel_layout = channel_layout;
304 
305  // init resample options (if zero)
306  if (original_sample_rate == 0)
307  original_sample_rate = info.sample_rate;
308  if (original_channels == 0)
309  original_channels = info.channels;
310 
312  "FFmpegWriter::SetAudioOptions (" + codec + ")",
313  "sample_rate", sample_rate,
314  "channels", channels,
315  "bit_rate", bit_rate);
316 
317  // Enable / Disable audio
318  info.has_audio = has_audio;
319 }
320 
321 
322 // Set audio export options (overloaded function)
323 void FFmpegWriter::SetAudioOptions(std::string codec, int sample_rate, int bit_rate) {
324  // Call full signature with some default parameters
326  true, codec, sample_rate, 2,
327  openshot::LAYOUT_STEREO, bit_rate
328  );
329 }
330 
331 
332 // Set custom options (some codecs accept additional params)
333 void FFmpegWriter::SetOption(StreamType stream, std::string name, std::string value) {
334  // Declare codec context
335  AVCodecContext *c = NULL;
336  AVStream *st = NULL;
337  std::stringstream convert(value);
338 
339  if (info.has_video && stream == VIDEO_STREAM && video_st) {
340  st = video_st;
341  // Get codec context
342  c = AV_GET_CODEC_PAR_CONTEXT(st, video_codec_ctx);
343  // Was a codec / stream found?
344  if (c) {
345  if (info.interlaced_frame) {
346  c->field_order = info.top_field_first ? AV_FIELD_TT : AV_FIELD_BB;
347  // We only use these two version and ignore AV_FIELD_TB and AV_FIELD_BT
348  // Otherwise we would need to change the whole export window
349  }
350  }
351  } else if (info.has_audio && stream == AUDIO_STREAM && audio_st) {
352  st = audio_st;
353  // Get codec context
354  c = AV_GET_CODEC_PAR_CONTEXT(st, audio_codec_ctx);
355  } else
356  throw NoStreamsFound("The stream was not found. Be sure to call PrepareStreams() first.", path);
357 
358  // Init AVOption
359  const AVOption *option = NULL;
360 
361  // Was a codec / stream found?
362  if (c)
363  // Find AVOption (if it exists)
364  option = AV_OPTION_FIND(c->priv_data, name.c_str());
365 
366  // Was option found?
367  if (option || (name == "g" || name == "qmin" || name == "qmax" || name == "max_b_frames" || name == "mb_decision" ||
368  name == "level" || name == "profile" || name == "slices" || name == "rc_min_rate" || name == "rc_max_rate" ||
369  name == "rc_buffer_size" || name == "crf" || name == "cqp" || name == "qp")) {
370  // Check for specific named options
371  if (name == "g")
372  // Set gop_size
373  convert >> c->gop_size;
374 
375  else if (name == "qmin")
376  // Minimum quantizer
377  convert >> c->qmin;
378 
379  else if (name == "qmax")
380  // Maximum quantizer
381  convert >> c->qmax;
382 
383  else if (name == "max_b_frames")
384  // Maximum number of B-frames between non-B-frames
385  convert >> c->max_b_frames;
386 
387  else if (name == "mb_decision")
388  // Macroblock decision mode
389  convert >> c->mb_decision;
390 
391  else if (name == "level")
392  // Set codec level
393  convert >> c->level;
394 
395  else if (name == "profile")
396  // Set codec profile
397  convert >> c->profile;
398 
399  else if (name == "slices")
400  // Indicates number of picture subdivisions
401  convert >> c->slices;
402 
403  else if (name == "rc_min_rate")
404  // Minimum bitrate
405  convert >> c->rc_min_rate;
406 
407  else if (name == "rc_max_rate")
408  // Maximum bitrate
409  convert >> c->rc_max_rate;
410 
411  else if (name == "rc_buffer_size")
412  // Buffer size
413  convert >> c->rc_buffer_size;
414 
415  else if (name == "cqp") {
416  // encode quality and special settings like lossless
417 #if USE_HW_ACCEL
418  if (hw_en_on) {
419  av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),63), 0); // 0-63
420  } else
421 #endif // USE_HW_ACCEL
422  {
423  switch (c->codec_id) {
424 #if (LIBAVCODEC_VERSION_MAJOR >= 58)
425  // FFmpeg 4.0+
426  case AV_CODEC_ID_AV1 :
427  c->bit_rate = 0;
428  av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),63), 0); // 0-63
429  break;
430 #endif
431  case AV_CODEC_ID_VP8 :
432  c->bit_rate = 10000000;
433  av_opt_set_int(c->priv_data, "qp", std::max(std::min(std::stoi(value), 63), 4), 0); // 4-63
434  break;
435  case AV_CODEC_ID_VP9 :
436  c->bit_rate = 0; // Must be zero!
437  av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value), 63), 0); // 0-63
438  if (std::stoi(value) == 0) {
439  av_opt_set(c->priv_data, "preset", "veryslow", 0);
440  av_opt_set_int(c->priv_data, "lossless", 1, 0);
441  }
442  break;
443  case AV_CODEC_ID_H264 :
444  av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value), 51), 0); // 0-51
445  if (std::stoi(value) == 0) {
446  av_opt_set(c->priv_data, "preset", "veryslow", 0);
447  c->pix_fmt = PIX_FMT_YUV444P; // no chroma subsampling
448  }
449  break;
450  case AV_CODEC_ID_HEVC :
451  av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value), 51), 0); // 0-51
452  if (std::stoi(value) == 0) {
453  av_opt_set(c->priv_data, "preset", "veryslow", 0);
454  av_opt_set_int(c->priv_data, "lossless", 1, 0);
455  }
456  break;
457  default:
458  // For all other codecs assume a range of 0-63
459  av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value), 63), 0); // 0-63
460  c->bit_rate = 0;
461  }
462  }
463  } else if (name == "crf") {
464  // encode quality and special settings like lossless
465 #if USE_HW_ACCEL
466  if (hw_en_on) {
467  double mbs = 15000000.0;
468  if (info.video_bit_rate > 0) {
469  if (info.video_bit_rate > 42) {
470  mbs = 380000.0;
471  }
472  else {
473  mbs *= std::pow(0.912,info.video_bit_rate);
474  }
475  }
476  c->bit_rate = (int)(mbs);
477  } else
478 #endif // USE_HW_ACCEL
479  {
480  switch (c->codec_id) {
481 #if (LIBAVCODEC_VERSION_MAJOR >= 58)
482  // FFmpeg 4.0+
483  case AV_CODEC_ID_AV1 :
484  c->bit_rate = 0;
485  // AV1 only supports "crf" quality values
486  av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0);
487  break;
488 #endif
489  case AV_CODEC_ID_VP8 :
490  c->bit_rate = 10000000;
491  av_opt_set_int(c->priv_data, "crf", std::max(std::min(std::stoi(value), 63), 4), 0); // 4-63
492  break;
493  case AV_CODEC_ID_VP9 :
494  c->bit_rate = 0; // Must be zero!
495  av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value), 63), 0); // 0-63
496  if (std::stoi(value) == 0) {
497  av_opt_set(c->priv_data, "preset", "veryslow", 0);
498  av_opt_set_int(c->priv_data, "lossless", 1, 0);
499  }
500  break;
501  case AV_CODEC_ID_H264 :
502  av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value), 51), 0); // 0-51
503  if (std::stoi(value) == 0) {
504  av_opt_set(c->priv_data, "preset", "veryslow", 0);
505  c->pix_fmt = PIX_FMT_YUV444P; // no chroma subsampling
506  }
507  break;
508  case AV_CODEC_ID_HEVC :
509  if (strstr(info.vcodec.c_str(), "svt_hevc") != NULL) {
510  av_opt_set_int(c->priv_data, "preset", 7, 0);
511  av_opt_set_int(c->priv_data, "forced-idr",1,0);
512  av_opt_set_int(c->priv_data, "qp",std::min(std::stoi(value), 51),0);
513  }
514  else {
515  av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value), 51), 0); // 0-51
516  }
517  if (std::stoi(value) == 0) {
518  av_opt_set(c->priv_data, "preset", "veryslow", 0);
519  av_opt_set_int(c->priv_data, "lossless", 1, 0);
520  }
521  break;
522  default:
523  // If this codec doesn't support crf calculate a bitrate
524  // TODO: find better formula
525  double mbs = 15000000.0;
526  if (info.video_bit_rate > 0) {
527  if (info.video_bit_rate > 42) {
528  mbs = 380000.0;
529  } else {
530  mbs *= std::pow(0.912, info.video_bit_rate);
531  }
532  }
533  c->bit_rate = (int) (mbs);
534  }
535  }
536  } else if (name == "qp") {
537  // encode quality and special settings like lossless
538 #if (LIBAVCODEC_VERSION_MAJOR >= 58)
539  // FFmpeg 4.0+
540  switch (c->codec_id) {
541  case AV_CODEC_ID_AV1 :
542  c->bit_rate = 0;
543  if (strstr(info.vcodec.c_str(), "svtav1") != NULL) {
544  av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),63), 0);
545  }
546  else if (strstr(info.vcodec.c_str(), "rav1e") != NULL) {
547  // Set number of tiles to a fixed value
548  // TODO Let user choose number of tiles
549  av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),255), 0);
550  }
551  else if (strstr(info.vcodec.c_str(), "aom") != NULL) {
552  // Set number of tiles to a fixed value
553  // TODO Let user choose number of tiles
554  // libaom doesn't have qp only crf
555  av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0);
556  }
557  else {
558  av_opt_set_int(c->priv_data, "crf", std::min(std::stoi(value),63), 0);
559  }
560  case AV_CODEC_ID_HEVC :
561  c->bit_rate = 0;
562  if (strstr(info.vcodec.c_str(), "svt_hevc") != NULL) {
563  av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),51), 0);
564  av_opt_set_int(c->priv_data, "preset", 7, 0);
565  av_opt_set_int(c->priv_data, "forced-idr",1,0);
566  }
567  break;
568  }
569 #endif // FFmpeg 4.0+
570  } else {
571  // Set AVOption
572  AV_OPTION_SET(st, c->priv_data, name.c_str(), value.c_str(), c);
573  }
574 
576  "FFmpegWriter::SetOption (" + (std::string)name + ")",
577  "stream == VIDEO_STREAM", stream == VIDEO_STREAM);
578 
579  // Muxing dictionary is not part of the codec context.
580  // Just reusing SetOption function to set popular multiplexing presets.
581  } else if (name == "muxing_preset") {
582  if (value == "mp4_faststart") {
583  // 'moov' box to the beginning; only for MOV, MP4
584  av_dict_set(&mux_dict, "movflags", "faststart", 0);
585  } else if (value == "mp4_fragmented") {
586  // write selfcontained fragmented file, minimum length of the fragment 8 sec; only for MOV, MP4
587  av_dict_set(&mux_dict, "movflags", "frag_keyframe", 0);
588  av_dict_set(&mux_dict, "min_frag_duration", "8000000", 0);
589  }
590  } else {
591  throw InvalidOptions("The option is not valid for this codec.", path);
592  }
593 
594 }
595 
597 bool FFmpegWriter::IsValidCodec(std::string codec_name) {
598  // Initialize FFMpeg, and register all formats and codecs
600 
601  // Find the codec (if any)
602  return avcodec_find_encoder_by_name(codec_name.c_str()) != NULL;
603 }
604 
605 // Prepare & initialize streams and open codecs
607  if (!info.has_audio && !info.has_video)
608  throw InvalidOptions("No video or audio options have been set. You must set has_video or has_audio (or both).", path);
609 
611  "FFmpegWriter::PrepareStreams [" + path + "]",
612  "info.has_audio", info.has_audio,
613  "info.has_video", info.has_video);
614 
615  // Initialize the streams (i.e. add the streams)
616  initialize_streams();
617 
618  // Mark as 'prepared'
619  prepare_streams = true;
620 }
621 
622 // Write the file header (after the options are set)
624  if (!info.has_audio && !info.has_video)
625  throw InvalidOptions("No video or audio options have been set. You must set has_video or has_audio (or both).", path);
626 
627  // Open the output file, if needed
628  if (!(oc->oformat->flags & AVFMT_NOFILE)) {
629  if (avio_open(&oc->pb, path.c_str(), AVIO_FLAG_WRITE) < 0)
630  throw InvalidFile("Could not open or write file.", path);
631  }
632 
633  // Force the output filename (which doesn't always happen for some reason)
634  AV_SET_FILENAME(oc, path.c_str());
635 
636  // Add general metadata (if any)
637  for (auto iter = info.metadata.begin(); iter != info.metadata.end(); ++iter) {
638  av_dict_set(&oc->metadata, iter->first.c_str(), iter->second.c_str(), 0);
639  }
640 
641  // Set multiplexing parameters (only for MP4/MOV containers)
642  AVDictionary *dict = NULL;
643  if (mux_dict) {
644  av_dict_copy(&dict, mux_dict, 0);
645  }
646 
647  // Write the stream header
648  if (avformat_write_header(oc, &dict) != 0) {
650  "FFmpegWriter::WriteHeader (avformat_write_header)");
651  throw InvalidFile("Could not write header to file.", path);
652  };
653 
654  // Free multiplexing dictionaries sets
655  if (dict) av_dict_free(&dict);
656  if (mux_dict) av_dict_free(&mux_dict);
657 
658  // Mark as 'written'
659  write_header = true;
660 
661  ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::WriteHeader");
662 }
663 
664 // Add a frame to the queue waiting to be encoded.
665 void FFmpegWriter::WriteFrame(std::shared_ptr<openshot::Frame> frame) {
666  // Check for open reader (or throw exception)
667  if (!is_open)
668  throw WriterClosed("The FFmpegWriter is closed. Call Open() before calling this method.", path);
669 
671  "FFmpegWriter::WriteFrame",
672  "frame->number", frame->number,
673  "is_writing", is_writing);
674 
675  // Write frames to video file
676  write_frame(frame);
677 
678  // Keep track of the last frame added
679  last_frame = frame;
680 }
681 
682 // Write all frames in the queue to the video file.
683 void FFmpegWriter::write_frame(std::shared_ptr<Frame> frame) {
684  // Flip writing flag
685  is_writing = true;
686 
687  // Create blank exception
688  bool has_error_encoding_video = false;
689 
690  // Process audio frame
691  if (info.has_audio && audio_st)
692  write_audio_packets(false, frame);
693 
694  // Process video frame
695  if (info.has_video && video_st)
696  process_video_packet(frame);
697 
698  if (info.has_video && video_st) {
699  // Does this frame's AVFrame still exist
700  if (av_frames.count(frame)) {
701  // Get AVFrame
702  AVFrame *frame_final = av_frames[frame];
703 
704  // Write frame to video file
705  if (!write_video_packet(frame, frame_final)) {
706  has_error_encoding_video = true;
707  }
708 
709  // Deallocate buffer and AVFrame
710  av_freep(&(frame_final->data[0]));
711  AV_FREE_FRAME(&frame_final);
712  av_frames.erase(frame);
713  }
714  }
715 
716  // Done writing
717  is_writing = false;
718 
719  // Raise exception from main thread
720  if (has_error_encoding_video)
721  throw ErrorEncodingVideo("Error while writing raw video frame", -1);
722 }
723 
724 // Write a block of frames from a reader
725 void FFmpegWriter::WriteFrame(ReaderBase *reader, int64_t start, int64_t length) {
727  "FFmpegWriter::WriteFrame (from Reader)",
728  "start", start,
729  "length", length);
730 
731  // Loop through each frame (and encoded it)
732  for (int64_t number = start; number <= length; number++) {
733  // Get the frame
734  std::shared_ptr<Frame> f = reader->GetFrame(number);
735 
736  // Encode frame
737  WriteFrame(f);
738  }
739 }
740 
741 // Write the file trailer (after all frames are written)
743  // Process final audio frame (if any)
744  if (info.has_audio && audio_st)
745  write_audio_packets(true, NULL);
746 
747  // Flush encoders (who sometimes hold on to frames)
748  flush_encoders();
749 
750  /* write the trailer, if any. The trailer must be written
751  * before you close the CodecContexts open when you wrote the
752  * header; otherwise write_trailer may try to use memory that
753  * was freed on av_codec_close() */
754  av_write_trailer(oc);
755 
756  // Mark as 'written'
757  write_trailer = true;
758 
759  ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::WriteTrailer");
760 }
761 
762 // Flush encoders
763 void FFmpegWriter::flush_encoders() {
764  if (info.has_audio && audio_codec_ctx && AV_GET_CODEC_TYPE(audio_st) == AVMEDIA_TYPE_AUDIO && AV_GET_CODEC_ATTRIBUTES(audio_st, audio_codec_ctx)->frame_size <= 1)
765  return;
766 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
767  // FFmpeg < 4.0
768  if (info.has_video && video_codec_ctx && AV_GET_CODEC_TYPE(video_st) == AVMEDIA_TYPE_VIDEO && (oc->oformat->flags & AVFMT_RAWPICTURE) && AV_FIND_DECODER_CODEC_ID(video_st) == AV_CODEC_ID_RAWVIDEO)
769  return;
770 #else
771  if (info.has_video && video_codec_ctx && AV_GET_CODEC_TYPE(video_st) == AVMEDIA_TYPE_VIDEO && AV_FIND_DECODER_CODEC_ID(video_st) == AV_CODEC_ID_RAWVIDEO)
772  return;
773 #endif
774 
775  // FLUSH VIDEO ENCODER
776  if (info.has_video) {
777  for (;;) {
778 
779  // Increment PTS (in frames and scaled to the codec's timebase)
780  video_timestamp += av_rescale_q(1, av_make_q(info.fps.den, info.fps.num), video_codec_ctx->time_base);
781 
782 #if IS_FFMPEG_3_2
783  AVPacket* pkt = av_packet_alloc();
784 #else
785  AVPacket* pkt;
786  av_init_packet(pkt);
787 #endif
788  pkt->data = NULL;
789  pkt->size = 0;
790 
791  /* encode the image */
792  int got_packet = 0;
793  int error_code = 0;
794 
795 #if IS_FFMPEG_3_2
796  // Encode video packet (latest version of FFmpeg)
797  error_code = avcodec_send_frame(video_codec_ctx, NULL);
798  got_packet = 0;
799  while (error_code >= 0) {
800  error_code = avcodec_receive_packet(video_codec_ctx, pkt);
801  if (error_code == AVERROR(EAGAIN)|| error_code == AVERROR_EOF) {
802  got_packet = 0;
803  // Write packet
804  avcodec_flush_buffers(video_codec_ctx);
805  break;
806  }
807  av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
808  pkt->stream_index = video_st->index;
809  error_code = av_interleaved_write_frame(oc, pkt);
810  }
811 #else // IS_FFMPEG_3_2
812 
813  // Encode video packet (older than FFmpeg 3.2)
814  error_code = avcodec_encode_video2(video_codec_ctx, pkt, NULL, &got_packet);
815 
816 #endif // IS_FFMPEG_3_2
817 
818  if (error_code < 0) {
820  "FFmpegWriter::flush_encoders ERROR ["
821  + av_err2string(error_code) + "]",
822  "error_code", error_code);
823  }
824  if (!got_packet) {
825  break;
826  }
827 
828  // set the timestamp
829  av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
830  pkt->stream_index = video_st->index;
831 
832  // Write packet
833  error_code = av_interleaved_write_frame(oc, pkt);
834  if (error_code < 0) {
836  "FFmpegWriter::flush_encoders ERROR ["
837  + av_err2string(error_code) + "]",
838  "error_code", error_code);
839  }
840  }
841  }
842 
843  // FLUSH AUDIO ENCODER
844  if (info.has_audio) {
845  for (;;) {
846 #if IS_FFMPEG_3_2
847  AVPacket* pkt = av_packet_alloc();
848 #else
849  AVPacket* pkt;
850  av_init_packet(pkt);
851 #endif
852  pkt->data = NULL;
853  pkt->size = 0;
854  pkt->pts = pkt->dts = audio_timestamp;
855 
856  /* encode the image */
857  int error_code = 0;
858  int got_packet = 0;
859 #if IS_FFMPEG_3_2
860  error_code = avcodec_send_frame(audio_codec_ctx, NULL);
861 #else
862  error_code = avcodec_encode_audio2(audio_codec_ctx, pkt, NULL, &got_packet);
863 #endif
864  if (error_code < 0) {
866  "FFmpegWriter::flush_encoders ERROR ["
867  + av_err2string(error_code) + "]",
868  "error_code", error_code);
869  }
870  if (!got_packet) {
871  break;
872  }
873 
874  // Since the PTS can change during encoding, set the value again. This seems like a huge hack,
875  // but it fixes lots of PTS related issues when I do this.
876  pkt->pts = pkt->dts = audio_timestamp;
877 
878  // Scale the PTS to the audio stream timebase (which is sometimes different than the codec's timebase)
879  av_packet_rescale_ts(pkt, audio_codec_ctx->time_base, audio_st->time_base);
880 
881  // set stream
882  pkt->stream_index = audio_st->index;
883  pkt->flags |= AV_PKT_FLAG_KEY;
884 
885  // Write packet
886  error_code = av_interleaved_write_frame(oc, pkt);
887  if (error_code < 0) {
889  "FFmpegWriter::flush_encoders ERROR ["
890  + av_err2string(error_code) + "]",
891  "error_code", error_code);
892  }
893 
894  // Increment PTS by duration of packet
895  audio_timestamp += pkt->duration;
896 
897  // deallocate memory for packet
898  AV_FREE_PACKET(pkt);
899  }
900  }
901 
902 }
903 
904 // Close the video codec
905 void FFmpegWriter::close_video(AVFormatContext *oc, AVStream *st)
906 {
907 #if USE_HW_ACCEL
908  if (hw_en_on && hw_en_supported) {
909  if (hw_device_ctx) {
910  av_buffer_unref(&hw_device_ctx);
911  hw_device_ctx = NULL;
912  }
913  }
914 #endif // USE_HW_ACCEL
915 
916  // Free any previous memory allocations
917  if (video_codec_ctx != nullptr) {
918  AV_FREE_CONTEXT(video_codec_ctx);
919  av_free(video_codec_ctx);
920  }
921 }
922 
923 // Close the audio codec
924 void FFmpegWriter::close_audio(AVFormatContext *oc, AVStream *st)
925 {
926  // Clear buffers
927  delete[] samples;
928  delete[] audio_outbuf;
929  delete[] audio_encoder_buffer;
930  samples = NULL;
931  audio_outbuf = NULL;
932  audio_encoder_buffer = NULL;
933 
934  // Deallocate resample buffer
935  if (avr) {
936  SWR_CLOSE(avr);
937  SWR_FREE(&avr);
938  avr = NULL;
939  }
940 
941  if (avr_planar) {
942  SWR_CLOSE(avr_planar);
943  SWR_FREE(&avr_planar);
944  avr_planar = NULL;
945  }
946 
947  // Free any previous memory allocations
948  if (audio_codec_ctx != nullptr) {
949  AV_FREE_CONTEXT(audio_codec_ctx);
950  av_free(audio_codec_ctx);
951  }
952 }
953 
954 // Close the writer
956  // Write trailer (if needed)
957  if (!write_trailer)
958  WriteTrailer();
959 
960  // Close each codec
961  if (video_st)
962  close_video(oc, video_st);
963  if (audio_st)
964  close_audio(oc, audio_st);
965 
966  // Remove single software scaler
967  if (img_convert_ctx)
968  sws_freeContext(img_convert_ctx);
969 
970  if (!(oc->oformat->flags & AVFMT_NOFILE)) {
971  /* close the output file */
972  avio_close(oc->pb);
973  }
974 
975  // Reset frame counters
976  video_timestamp = 0;
977  audio_timestamp = 0;
978 
979  // Free the context which frees the streams too
980  avformat_free_context(oc);
981  oc = NULL;
982 
983  // Close writer
984  is_open = false;
985  prepare_streams = false;
986  write_header = false;
987  write_trailer = false;
988 
989  ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::Close");
990 }
991 
992 // Add an AVFrame to the cache
993 void FFmpegWriter::add_avframe(std::shared_ptr<Frame> frame, AVFrame *av_frame) {
994  // Add AVFrame to map (if it does not already exist)
995  if (!av_frames.count(frame)) {
996  // Add av_frame
997  av_frames[frame] = av_frame;
998  } else {
999  // Do not add, and deallocate this AVFrame
1000  AV_FREE_FRAME(&av_frame);
1001  }
1002 }
1003 
1004 // Add an audio output stream
1005 AVStream *FFmpegWriter::add_audio_stream() {
1006  // Find the audio codec
1007  const AVCodec *codec = avcodec_find_encoder_by_name(info.acodec.c_str());
1008  if (codec == NULL)
1009  throw InvalidCodec("A valid audio codec could not be found for this file.", path);
1010 
1011  // Free any previous memory allocations
1012  if (audio_codec_ctx != nullptr) {
1013  AV_FREE_CONTEXT(audio_codec_ctx);
1014  }
1015 
1016  // Create a new audio stream
1017  AVStream* st = avformat_new_stream(oc, codec);
1018  if (!st)
1019  throw OutOfMemory("Could not allocate memory for the audio stream.", path);
1020 
1021  // Allocate a new codec context for the stream
1022  ALLOC_CODEC_CTX(audio_codec_ctx, codec, st)
1023 #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
1024  st->codecpar->codec_id = codec->id;
1025 #endif
1026  AVCodecContext* c = audio_codec_ctx;
1027 
1028  c->codec_id = codec->id;
1029  c->codec_type = AVMEDIA_TYPE_AUDIO;
1030 
1031  // Set the sample parameters
1032  c->bit_rate = info.audio_bit_rate;
1033 #if !HAVE_CH_LAYOUT
1034  c->channels = info.channels;
1035 #endif
1036 
1037  // Set valid sample rate (or throw error)
1038  if (codec->supported_samplerates) {
1039  int i;
1040  for (i = 0; codec->supported_samplerates[i] != 0; i++)
1041  if (info.sample_rate == codec->supported_samplerates[i]) {
1042  // Set the valid sample rate
1043  c->sample_rate = info.sample_rate;
1044  break;
1045  }
1046  if (codec->supported_samplerates[i] == 0)
1047  throw InvalidSampleRate("An invalid sample rate was detected for this codec.", path);
1048  } else
1049  // Set sample rate
1050  c->sample_rate = info.sample_rate;
1051 
1052  uint64_t channel_layout = info.channel_layout;
1053 #if HAVE_CH_LAYOUT
1054  // Set a valid number of channels (or throw error)
1055  AVChannelLayout ch_layout;
1056  av_channel_layout_from_mask(&ch_layout, info.channel_layout);
1057  if (codec->ch_layouts) {
1058  int i;
1059  for (i = 0; av_channel_layout_check(&codec->ch_layouts[i]); i++)
1060  if (av_channel_layout_compare(&ch_layout, &codec->ch_layouts[i])) {
1061  // Set valid channel layout
1062  av_channel_layout_copy(&c->ch_layout, &ch_layout);
1063  break;
1064  }
1065  if (!av_channel_layout_check(&codec->ch_layouts[i]))
1066  throw InvalidChannels("An invalid channel layout was detected (i.e. MONO / STEREO).", path);
1067  } else
1068  // Set valid channel layout
1069  av_channel_layout_copy(&c->ch_layout, &ch_layout);
1070 #else
1071  // Set a valid number of channels (or throw error)
1072  if (codec->channel_layouts) {
1073  int i;
1074  for (i = 0; codec->channel_layouts[i] != 0; i++)
1075  if (channel_layout == codec->channel_layouts[i]) {
1076  // Set valid channel layout
1077  c->channel_layout = channel_layout;
1078  break;
1079  }
1080  if (codec->channel_layouts[i] == 0)
1081  throw InvalidChannels("An invalid channel layout was detected (i.e. MONO / STEREO).", path);
1082  } else
1083  // Set valid channel layout
1084  c->channel_layout = channel_layout;
1085 #endif
1086 
1087  // Choose a valid sample_fmt
1088  if (codec->sample_fmts) {
1089  for (int i = 0; codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) {
1090  // Set sample format to 1st valid format (and then exit loop)
1091  c->sample_fmt = codec->sample_fmts[i];
1092  break;
1093  }
1094  }
1095  if (c->sample_fmt == AV_SAMPLE_FMT_NONE) {
1096  // Default if no sample formats found
1097  c->sample_fmt = AV_SAMPLE_FMT_S16;
1098  }
1099 
1100  // some formats want stream headers to be separate
1101  if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1102 #if (LIBAVCODEC_VERSION_MAJOR >= 57)
1103  // FFmpeg 3.0+
1104  c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1105 #else
1106  c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1107 #endif
1108 
1110 
1111  int nb_channels;
1112  const char* nb_channels_label;
1113  const char* channel_layout_label;
1114 
1115 #if HAVE_CH_LAYOUT
1116  nb_channels = c->ch_layout.nb_channels;
1117  channel_layout = c->ch_layout.u.mask;
1118  nb_channels_label = "c->ch_layout.nb_channels";
1119  channel_layout_label = "c->ch_layout.u.mask";
1120 #else
1121  nb_channels = c->channels;
1122  nb_channels_label = "c->channels";
1123  channel_layout_label = "c->channel_layout";
1124 #endif
1125 
1127  "FFmpegWriter::add_audio_stream",
1128  "c->codec_id", c->codec_id,
1129  "c->bit_rate", c->bit_rate,
1130  nb_channels_label, nb_channels,
1131  "c->sample_fmt", c->sample_fmt,
1132  channel_layout_label, channel_layout,
1133  "c->sample_rate", c->sample_rate);
1134 
1135  return st;
1136 }
1137 
1138 // Add a video output stream
1139 AVStream *FFmpegWriter::add_video_stream() {
1140  // Find the video codec
1141  const AVCodec *codec = avcodec_find_encoder_by_name(info.vcodec.c_str());
1142  if (codec == NULL)
1143  throw InvalidCodec("A valid video codec could not be found for this file.", path);
1144 
1145  // Free any previous memory allocations
1146  if (video_codec_ctx != nullptr) {
1147  AV_FREE_CONTEXT(video_codec_ctx);
1148  }
1149 
1150  // Create a new video stream
1151  AVStream* st = avformat_new_stream(oc, codec);
1152  if (!st)
1153  throw OutOfMemory("Could not allocate memory for the video stream.", path);
1154 
1155  // Allocate a new codec context for the stream
1156  ALLOC_CODEC_CTX(video_codec_ctx, codec, st)
1157 #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
1158  st->codecpar->codec_id = codec->id;
1159 #endif
1160 
1161  AVCodecContext* c = video_codec_ctx;
1162 
1163  c->codec_id = codec->id;
1164  c->codec_type = AVMEDIA_TYPE_VIDEO;
1165 
1166  // Set sample aspect ratio
1167  c->sample_aspect_ratio.num = info.pixel_ratio.num;
1168  c->sample_aspect_ratio.den = info.pixel_ratio.den;
1169 
1170  /* Init video encoder options */
1171  if (info.video_bit_rate >= 1000
1172 #if (LIBAVCODEC_VERSION_MAJOR >= 58)
1173  && c->codec_id != AV_CODEC_ID_AV1
1174 #endif
1175  ) {
1176  c->bit_rate = info.video_bit_rate;
1177  if (info.video_bit_rate >= 1500000) {
1178  if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
1179  c->qmin = 2;
1180  c->qmax = 30;
1181  }
1182  }
1183  // Here should be the setting for low fixed bitrate
1184  // Defaults are used because mpeg2 otherwise had problems
1185  } else {
1186  // Check if codec supports crf or qp
1187  switch (c->codec_id) {
1188 #if (LIBAVCODEC_VERSION_MAJOR >= 58)
1189  // FFmpeg 4.0+
1190  case AV_CODEC_ID_AV1 :
1191  // TODO: Set `crf` or `qp` according to bitrate, as bitrate is not supported by these encoders yet.
1192  if (info.video_bit_rate >= 1000) {
1193  c->bit_rate = 0;
1194  if (strstr(info.vcodec.c_str(), "aom") != NULL) {
1195  int calculated_quality = 35;
1196  if (info.video_bit_rate < 500000) calculated_quality = 50;
1197  if (info.video_bit_rate > 5000000) calculated_quality = 10;
1198  av_opt_set_int(c->priv_data, "crf", calculated_quality, 0);
1199  info.video_bit_rate = calculated_quality;
1200  } else {
1201  int calculated_quality = 50;
1202  if (info.video_bit_rate < 500000) calculated_quality = 60;
1203  if (info.video_bit_rate > 5000000) calculated_quality = 15;
1204  av_opt_set_int(c->priv_data, "qp", calculated_quality, 0);
1205  info.video_bit_rate = calculated_quality;
1206  } // medium
1207  }
1208  if (strstr(info.vcodec.c_str(), "svtav1") != NULL) {
1209  av_opt_set_int(c->priv_data, "preset", 6, 0);
1210  av_opt_set_int(c->priv_data, "forced-idr",1,0);
1211  }
1212  else if (strstr(info.vcodec.c_str(), "rav1e") != NULL) {
1213  av_opt_set_int(c->priv_data, "speed", 7, 0);
1214  av_opt_set_int(c->priv_data, "tile-rows", 2, 0);
1215  av_opt_set_int(c->priv_data, "tile-columns", 4, 0);
1216  }
1217  else if (strstr(info.vcodec.c_str(), "aom") != NULL) {
1218  // Set number of tiles to a fixed value
1219  // TODO: Allow user to chose their own number of tiles
1220  av_opt_set_int(c->priv_data, "tile-rows", 1, 0); // log2 of number of rows
1221  av_opt_set_int(c->priv_data, "tile-columns", 2, 0); // log2 of number of columns
1222  av_opt_set_int(c->priv_data, "row-mt", 1, 0); // use multiple cores
1223  av_opt_set_int(c->priv_data, "cpu-used", 3, 0); // default is 1, usable is 4
1224  }
1225  //break;
1226 #endif
1227  case AV_CODEC_ID_VP9 :
1228  case AV_CODEC_ID_HEVC :
1229  case AV_CODEC_ID_VP8 :
1230  case AV_CODEC_ID_H264 :
1231  if (info.video_bit_rate < 40) {
1232  c->qmin = 0;
1233  c->qmax = 63;
1234  } else {
1235  c->qmin = info.video_bit_rate - 5;
1236  c->qmax = 63;
1237  }
1238  break;
1239  default:
1240  // Here should be the setting for codecs that don't support crf
1241  // For now defaults are used
1242  break;
1243  }
1244  }
1245 
1246  //TODO: Implement variable bitrate feature (which actually works). This implementation throws
1247  //invalid bitrate errors and rc buffer underflow errors, etc...
1248  //c->rc_min_rate = info.video_bit_rate;
1249  //c->rc_max_rate = info.video_bit_rate;
1250  //c->rc_buffer_size = FFMAX(c->rc_max_rate, 15000000) * 112L / 15000000 * 16384;
1251  //if ( !c->rc_initial_buffer_occupancy )
1252  // c->rc_initial_buffer_occupancy = c->rc_buffer_size * 3/4;
1253 
1254  /* resolution must be a multiple of two */
1255  // TODO: require /2 height and width
1256  c->width = info.width;
1257  c->height = info.height;
1258 
1259  /* time base: this is the fundamental unit of time (in seconds) in terms
1260  of which frame timestamps are represented. for fixed-fps content,
1261  timebase should be 1/framerate and timestamp increments should be
1262  identically 1. */
1263  c->time_base.num = info.video_timebase.num;
1264  c->time_base.den = info.video_timebase.den;
1265 // AVCodecContext->framerate was added in FFmpeg 2.6
1266 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 26, 0)
1267  c->framerate = av_inv_q(c->time_base);
1268 #endif
1269  st->avg_frame_rate = av_inv_q(c->time_base);
1270  st->time_base.num = info.video_timebase.num;
1271  st->time_base.den = info.video_timebase.den;
1272 
1273  c->gop_size = 12; /* TODO: add this to "info"... emit one intra frame every twelve frames at most */
1274  c->max_b_frames = 10;
1275  if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO)
1276  /* just for testing, we also add B frames */
1277  c->max_b_frames = 2;
1278  if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO)
1279  /* Needed to avoid using macroblocks in which some coeffs overflow.
1280  This does not happen with normal video, it just happens here as
1281  the motion of the chroma plane does not match the luma plane. */
1282  c->mb_decision = 2;
1283  // some formats want stream headers to be separate
1284  if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1285 #if (LIBAVCODEC_VERSION_MAJOR >= 57)
1286  // FFmpeg 3.0+
1287  c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1288 #else
1289  c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1290 #endif
1291 
1292  // Find all supported pixel formats for this codec
1293  const PixelFormat *supported_pixel_formats = codec->pix_fmts;
1294  while (supported_pixel_formats != NULL && *supported_pixel_formats != PIX_FMT_NONE) {
1295  // Assign the 1st valid pixel format (if one is missing)
1296  if (c->pix_fmt == PIX_FMT_NONE)
1297  c->pix_fmt = *supported_pixel_formats;
1298  ++supported_pixel_formats;
1299  }
1300 
1301  // Codec doesn't have any pix formats?
1302  if (c->pix_fmt == PIX_FMT_NONE) {
1303  if (oc->oformat->video_codec == AV_CODEC_ID_RAWVIDEO) {
1304  // Raw video should use RGB24
1305  c->pix_fmt = PIX_FMT_RGB24;
1306 
1307 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
1308  // FFmpeg < 4.0
1309  if (strcmp(oc->oformat->name, "gif") != 0)
1310  // If not GIF format, skip the encoding process
1311  // Set raw picture flag (so we don't encode this video)
1312  oc->oformat->flags |= AVFMT_RAWPICTURE;
1313 #endif
1314  } else {
1315  // Set the default codec
1316  c->pix_fmt = PIX_FMT_YUV420P;
1317  }
1318  }
1319 
1322  "FFmpegWriter::add_video_stream ("
1323  + (std::string)oc->oformat->name + " : "
1324  + (std::string)av_get_pix_fmt_name(c->pix_fmt) + ")",
1325  "c->codec_id", c->codec_id,
1326  "c->bit_rate", c->bit_rate,
1327  "c->pix_fmt", c->pix_fmt,
1328  "oc->oformat->flags", oc->oformat->flags);
1329  return st;
1330 }
1331 
1332 // open audio codec
1333 void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st) {
1334  const AVCodec *codec;
1335  AV_GET_CODEC_FROM_STREAM(st, audio_codec_ctx)
1336 
1337  // Audio encoding does not typically use more than 2 threads (most codecs use 1 thread)
1338  audio_codec_ctx->thread_count = std::min(FF_AUDIO_NUM_PROCESSORS, 2);
1339 
1340  // Find the audio encoder
1341  codec = avcodec_find_encoder_by_name(info.acodec.c_str());
1342  if (!codec)
1343  codec = avcodec_find_encoder(audio_codec_ctx->codec_id);
1344  if (!codec)
1345  throw InvalidCodec("Could not find codec", path);
1346 
1347  // Init options
1348  AVDictionary *opts = NULL;
1349  av_dict_set(&opts, "strict", "experimental", 0);
1350 
1351  // Open the codec
1352  if (avcodec_open2(audio_codec_ctx, codec, &opts) < 0)
1353  throw InvalidCodec("Could not open audio codec", path);
1354  AV_COPY_PARAMS_FROM_CONTEXT(st, audio_codec_ctx);
1355 
1356  // Free options
1357  av_dict_free(&opts);
1358 
1359  // Calculate the size of the input frame (i..e how many samples per packet), and the output buffer
1360  // TODO: Ugly hack for PCM codecs (will be removed ASAP with new PCM support to compute the input frame size in samples
1361  if (audio_codec_ctx->frame_size <= 1) {
1362  // No frame size found... so calculate
1363  audio_input_frame_size = 50000 / info.channels;
1364 
1365  int s = AV_FIND_DECODER_CODEC_ID(st);
1366  switch (s) {
1367  case AV_CODEC_ID_PCM_S16LE:
1368  case AV_CODEC_ID_PCM_S16BE:
1369  case AV_CODEC_ID_PCM_U16LE:
1370  case AV_CODEC_ID_PCM_U16BE:
1371  audio_input_frame_size >>= 1;
1372  break;
1373  default:
1374  break;
1375  }
1376  } else {
1377  // Set frame size based on the codec
1378  audio_input_frame_size = audio_codec_ctx->frame_size;
1379  }
1380 
1381  // Set the initial frame size (since it might change during resampling)
1382  initial_audio_input_frame_size = audio_input_frame_size;
1383 
1384  // Allocate array for samples
1385  samples = new int16_t[AVCODEC_MAX_AUDIO_FRAME_SIZE];
1386 
1387  // Set audio output buffer (used to store the encoded audio)
1388  audio_outbuf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
1389  audio_outbuf = new uint8_t[audio_outbuf_size];
1390 
1391  // Set audio packet encoding buffer
1392  audio_encoder_buffer_size = AUDIO_PACKET_ENCODING_SIZE;
1393  audio_encoder_buffer = new uint8_t[audio_encoder_buffer_size];
1394 
1395  // Add audio metadata (if any)
1396  for (std::map<std::string, std::string>::iterator iter = info.metadata.begin(); iter != info.metadata.end(); ++iter) {
1397  av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1398  }
1399 
1401  "FFmpegWriter::open_audio",
1402  "audio_codec_ctx->thread_count", audio_codec_ctx->thread_count,
1403  "audio_input_frame_size", audio_input_frame_size,
1405 }
1406 
1407 // open video codec
1408 void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) {
1409  const AVCodec *codec;
1410  AV_GET_CODEC_FROM_STREAM(st, video_codec_ctx)
1411 
1412  // Set number of threads equal to number of processors (not to exceed 16, FFmpeg doesn't recommend more than 16)
1413  video_codec_ctx->thread_count = std::min(FF_VIDEO_NUM_PROCESSORS, 16);
1414 
1415 #if USE_HW_ACCEL
1416  if (hw_en_on && hw_en_supported) {
1417  //char *dev_hw = NULL;
1418  char adapter[256];
1419  char *adapter_ptr = NULL;
1420  int adapter_num;
1421  // Use the hw device given in the environment variable HW_EN_DEVICE_SET or the default if not set
1423  std::clog << "Encoding Device Nr: " << adapter_num << "\n";
1424  if (adapter_num < 3 && adapter_num >=0) {
1425 #if defined(__linux__)
1426  snprintf(adapter,sizeof(adapter),"/dev/dri/renderD%d", adapter_num+128);
1427  // Maybe 127 is better because the first card would be 1?!
1428  adapter_ptr = adapter;
1429 #elif defined(_WIN32) || defined(__APPLE__)
1430  adapter_ptr = NULL;
1431 #endif
1432  }
1433  else {
1434  adapter_ptr = NULL; // Just to be sure
1435  }
1436 // Check if it is there and writable
1437 #if defined(__linux__)
1438  if( adapter_ptr != NULL && access( adapter_ptr, W_OK ) == 0 ) {
1439 #elif defined(_WIN32) || defined(__APPLE__)
1440  if( adapter_ptr != NULL ) {
1441 #endif
1443  "Encode Device present using device",
1444  "adapter", adapter_num);
1445  }
1446  else {
1447  adapter_ptr = NULL; // use default
1449  "Encode Device not present, using default");
1450  }
1451  if (av_hwdevice_ctx_create(&hw_device_ctx,
1452  hw_en_av_device_type, adapter_ptr, NULL, 0) < 0)
1453  {
1455  "FFmpegWriter::open_video ERROR creating hwdevice, Codec name:",
1456  info.vcodec.c_str(), -1);
1457  throw InvalidCodec("Could not create hwdevice", path);
1458  }
1459  }
1460 #endif // USE_HW_ACCEL
1461 
1462  /* find the video encoder */
1463  codec = avcodec_find_encoder_by_name(info.vcodec.c_str());
1464  if (!codec)
1465  codec = avcodec_find_encoder(AV_FIND_DECODER_CODEC_ID(st));
1466  if (!codec)
1467  throw InvalidCodec("Could not find codec", path);
1468 
1469  /* Force max_b_frames to 0 in some cases (i.e. for mjpeg image sequences */
1470  if (video_codec_ctx->max_b_frames && video_codec_ctx->codec_id != AV_CODEC_ID_MPEG4 && video_codec_ctx->codec_id != AV_CODEC_ID_MPEG1VIDEO && video_codec_ctx->codec_id != AV_CODEC_ID_MPEG2VIDEO)
1471  video_codec_ctx->max_b_frames = 0;
1472 
1473  // Init options
1474  AVDictionary *opts = NULL;
1475  av_dict_set(&opts, "strict", "experimental", 0);
1476 
1477 #if USE_HW_ACCEL
1479  video_codec_ctx->pix_fmt = hw_en_av_pix_fmt;
1480 
1481  // for the list of possible options, see the list of codec-specific options:
1482  // e.g. ffmpeg -h encoder=h264_vaapi or ffmpeg -h encoder=hevc_vaapi
1483  // and "man ffmpeg-codecs"
1484 
1485  // For VAAPI, it is safer to explicitly set rc_mode instead of relying on auto-selection
1486  // which is ffmpeg version-specific.
1487  if (hw_en_av_pix_fmt == AV_PIX_FMT_VAAPI) {
1488  int64_t qp;
1489  if (av_opt_get_int(video_codec_ctx->priv_data, "qp", 0, &qp) != 0 || qp == 0) {
1490  // unless "qp" was set for CQP, switch to VBR RC mode
1491  av_opt_set(video_codec_ctx->priv_data, "rc_mode", "VBR", 0);
1492 
1493  // In the current state (ffmpeg-4.2-4 libva-mesa-driver-19.1.5-1) to use VBR,
1494  // one has to specify both bit_rate and maxrate, otherwise a small low quality file is generated on Intel iGPU).
1495  video_codec_ctx->rc_max_rate = video_codec_ctx->bit_rate;
1496  }
1497  }
1498 
1499  switch (video_codec_ctx->codec_id) {
1500  case AV_CODEC_ID_H264:
1501  video_codec_ctx->max_b_frames = 0; // At least this GPU doesn't support b-frames
1502  video_codec_ctx->profile = FF_PROFILE_H264_BASELINE | FF_PROFILE_H264_CONSTRAINED;
1503  av_opt_set(video_codec_ctx->priv_data, "preset", "slow", 0);
1504  av_opt_set(video_codec_ctx->priv_data, "tune", "zerolatency", 0);
1505  av_opt_set(video_codec_ctx->priv_data, "vprofile", "baseline", AV_OPT_SEARCH_CHILDREN);
1506  break;
1507  case AV_CODEC_ID_HEVC:
1508  // tested to work with defaults
1509  break;
1510  case AV_CODEC_ID_VP9:
1511  // tested to work with defaults
1512  break;
1513  default:
1515  "No codec-specific options defined for this codec. HW encoding may fail",
1516  "codec_id", video_codec_ctx->codec_id);
1517  break;
1518  }
1519 
1520  // set hw_frames_ctx for encoder's AVCodecContext
1521  int err;
1522  if ((err = set_hwframe_ctx(video_codec_ctx, hw_device_ctx, info.width, info.height)) < 0)
1523  {
1525  "FFmpegWriter::open_video (set_hwframe_ctx) ERROR faled to set hwframe context",
1526  "width", info.width,
1527  "height", info.height,
1528  av_err2string(err), -1);
1529  }
1530  }
1531 #endif // USE_HW_ACCEL
1532 
1533 // Set libx265 hvc1 tag (for Apple playback compatibility).
1534 #if USE_HW_ACCEL
1535  if (!(hw_en_on && hw_en_supported) && video_codec_ctx->codec_id == AV_CODEC_ID_HEVC) {
1536  video_codec_ctx->codec_tag = MKTAG('h', 'v', 'c', '1');
1537  }
1538 #else
1539  if (video_codec_ctx->codec_id == AV_CODEC_ID_HEVC) {
1540  video_codec_ctx->codec_tag = MKTAG('h', 'v', 'c', '1');
1541  }
1542 #endif
1543 
1544  /* open the codec */
1545  if (avcodec_open2(video_codec_ctx, codec, &opts) < 0)
1546  throw InvalidCodec("Could not open video codec", path);
1547  AV_COPY_PARAMS_FROM_CONTEXT(st, video_codec_ctx);
1548 
1549  // Free options
1550  av_dict_free(&opts);
1551 
1552  // Add video metadata (if any)
1553  for (auto iter = info.metadata.begin(); iter != info.metadata.end(); ++iter) {
1554  av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1555  }
1556 
1558  "FFmpegWriter::open_video",
1559  "video_codec_ctx->thread_count", video_codec_ctx->thread_count);
1560 
1561 }
1562 
1563 // write all queued frames' audio to the video file
1564 void FFmpegWriter::write_audio_packets(bool is_final, std::shared_ptr<openshot::Frame> frame) {
1565  if (!frame && !is_final)
1566  return;
1567 
1568  // Init audio buffers / variables
1569  int total_frame_samples = 0;
1570  int frame_position = 0;
1571  int channels_in_frame = 0;
1572  int sample_rate_in_frame = 0;
1573  int samples_in_frame = 0;
1574  ChannelLayout channel_layout_in_frame = LAYOUT_MONO; // default channel layout
1575 
1576  // Create a new array (to hold all S16 audio samples, for the current queued frames
1577  unsigned int all_queued_samples_size = sizeof(int16_t) * AVCODEC_MAX_AUDIO_FRAME_SIZE;
1578  int16_t *all_queued_samples = (int16_t *) av_malloc(all_queued_samples_size);
1579  int16_t *all_resampled_samples = NULL;
1580  int16_t *final_samples_planar = NULL;
1581  int16_t *final_samples = NULL;
1582 
1583  // Get audio sample array
1584  float *frame_samples_float = NULL;
1585 
1586  // Get the audio details from this frame
1587  if (frame) {
1588  sample_rate_in_frame = frame->SampleRate();
1589  samples_in_frame = frame->GetAudioSamplesCount();
1590  channels_in_frame = frame->GetAudioChannelsCount();
1591  channel_layout_in_frame = frame->ChannelsLayout();
1592 
1593  // Get samples interleaved together (c1 c2 c1 c2 c1 c2)
1594  frame_samples_float = frame->GetInterleavedAudioSamples(&samples_in_frame);
1595  }
1596 
1597  // Calculate total samples
1598  total_frame_samples = samples_in_frame * channels_in_frame;
1599 
1600  // Translate audio sample values back to 16 bit integers with saturation
1601  const int16_t max16 = 32767;
1602  const int16_t min16 = -32768;
1603  for (int s = 0; s < total_frame_samples; s++, frame_position++) {
1604  float valF = frame_samples_float[s] * (1 << 15);
1605  int16_t conv;
1606  if (valF > max16) {
1607  conv = max16;
1608  } else if (valF < min16) {
1609  conv = min16;
1610  } else {
1611  conv = int(valF + 32768.5) - 32768; // +0.5 is for rounding
1612  }
1613 
1614  // Copy into buffer
1615  all_queued_samples[frame_position] = conv;
1616  }
1617 
1618  // Deallocate float array
1619  delete[] frame_samples_float;
1620 
1621 
1622  // Update total samples (since we've combined all queued frames)
1623  total_frame_samples = frame_position;
1624  int remaining_frame_samples = total_frame_samples;
1625  int samples_position = 0;
1626 
1627 
1629  "FFmpegWriter::write_audio_packets",
1630  "is_final", is_final,
1631  "total_frame_samples", total_frame_samples,
1632  "channel_layout_in_frame", channel_layout_in_frame,
1633  "channels_in_frame", channels_in_frame,
1634  "samples_in_frame", samples_in_frame,
1635  "LAYOUT_MONO", LAYOUT_MONO);
1636 
1637  // Keep track of the original sample format
1638  AVSampleFormat output_sample_fmt = audio_codec_ctx->sample_fmt;
1639 
1640  AVFrame *audio_frame = NULL;
1641  if (!is_final) {
1642  // Create input frame (and allocate arrays)
1643  audio_frame = AV_ALLOCATE_FRAME();
1644  AV_RESET_FRAME(audio_frame);
1645  audio_frame->nb_samples = total_frame_samples / channels_in_frame;
1646 
1647  // Fill input frame with sample data
1648  int error_code = avcodec_fill_audio_frame(audio_frame, channels_in_frame, AV_SAMPLE_FMT_S16, (uint8_t *) all_queued_samples, all_queued_samples_size, 0);
1649  if (error_code < 0) {
1651  "FFmpegWriter::write_audio_packets ERROR ["
1652  + av_err2string(error_code) + "]",
1653  "error_code", error_code);
1654  }
1655 
1656  // Do not convert audio to planar format (yet). We need to keep everything interleaved at this point.
1657  switch (audio_codec_ctx->sample_fmt) {
1658  case AV_SAMPLE_FMT_FLTP: {
1659  output_sample_fmt = AV_SAMPLE_FMT_FLT;
1660  break;
1661  }
1662  case AV_SAMPLE_FMT_S32P: {
1663  output_sample_fmt = AV_SAMPLE_FMT_S32;
1664  break;
1665  }
1666  case AV_SAMPLE_FMT_S16P: {
1667  output_sample_fmt = AV_SAMPLE_FMT_S16;
1668  break;
1669  }
1670  case AV_SAMPLE_FMT_U8P: {
1671  output_sample_fmt = AV_SAMPLE_FMT_U8;
1672  break;
1673  }
1674  default: {
1675  // This is only here to silence unused-enum warnings
1676  break;
1677  }
1678  }
1679 
1680  // Update total samples & input frame size (due to bigger or smaller data types)
1681  total_frame_samples *= (float(info.sample_rate) / sample_rate_in_frame); // adjust for different byte sizes
1682  total_frame_samples *= (float(info.channels) / channels_in_frame); // adjust for different # of channels
1683 
1684  // Create output frame (and allocate arrays)
1685  AVFrame *audio_converted = AV_ALLOCATE_FRAME();
1686  AV_RESET_FRAME(audio_converted);
1687  audio_converted->nb_samples = total_frame_samples / channels_in_frame;
1688  av_samples_alloc(audio_converted->data, audio_converted->linesize, info.channels, audio_converted->nb_samples, output_sample_fmt, 0);
1689 
1691  "FFmpegWriter::write_audio_packets (1st resampling)",
1692  "in_sample_fmt", AV_SAMPLE_FMT_S16,
1693  "out_sample_fmt", output_sample_fmt,
1694  "in_sample_rate", sample_rate_in_frame,
1695  "out_sample_rate", info.sample_rate,
1696  "in_channels", channels_in_frame,
1697  "out_channels", info.channels);
1698 
1699  // setup resample context
1700  if (!avr) {
1701  avr = SWR_ALLOC();
1702 #if HAVE_CH_LAYOUT
1703  AVChannelLayout in_chlayout;
1704  AVChannelLayout out_chlayout;
1705  av_channel_layout_from_mask(&in_chlayout, channel_layout_in_frame);
1706  av_channel_layout_from_mask(&out_chlayout, info.channel_layout);
1707  av_opt_set_chlayout(avr, "in_chlayout", &in_chlayout, 0);
1708  av_opt_set_chlayout(avr, "out_chlayout", &out_chlayout, 0);
1709 #else
1710  av_opt_set_int(avr, "in_channel_layout", channel_layout_in_frame, 0);
1711  av_opt_set_int(avr, "out_channel_layout", info.channel_layout, 0);
1712  av_opt_set_int(avr, "in_channels", channels_in_frame, 0);
1713  av_opt_set_int(avr, "out_channels", info.channels, 0);
1714 #endif
1715  av_opt_set_int(avr, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
1716  av_opt_set_int(avr, "out_sample_fmt", output_sample_fmt, 0); // planar not allowed here
1717  av_opt_set_int(avr, "in_sample_rate", sample_rate_in_frame, 0);
1718  av_opt_set_int(avr, "out_sample_rate", info.sample_rate, 0);
1719  SWR_INIT(avr);
1720  }
1721  // Convert audio samples
1722  int nb_samples = SWR_CONVERT(
1723  avr, // audio resample context
1724  audio_converted->data, // output data pointers
1725  audio_converted->linesize[0], // output plane size, in bytes. (0 if unknown)
1726  audio_converted->nb_samples, // maximum number of samples that the output buffer can hold
1727  audio_frame->data, // input data pointers
1728  audio_frame->linesize[0], // input plane size, in bytes (0 if unknown)
1729  audio_frame->nb_samples // number of input samples to convert
1730  );
1731 
1732  // Set remaining samples
1733  remaining_frame_samples = total_frame_samples;
1734 
1735  // Create a new array (to hold all resampled S16 audio samples)
1736  all_resampled_samples = (int16_t *) av_malloc(
1737  sizeof(int16_t) * nb_samples * info.channels
1738  * (av_get_bytes_per_sample(output_sample_fmt) /
1739  av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1740  );
1741 
1742  // Copy audio samples over original samples
1743  memcpy(all_resampled_samples, audio_converted->data[0],
1744  static_cast<size_t>(nb_samples)
1745  * info.channels
1746  * av_get_bytes_per_sample(output_sample_fmt));
1747 
1748  // Remove converted audio
1749  av_freep(&(audio_frame->data[0]));
1750  AV_FREE_FRAME(&audio_frame);
1751  av_freep(&audio_converted->data[0]);
1752  AV_FREE_FRAME(&audio_converted);
1753  all_queued_samples = NULL; // this array cleared with above call
1754 
1756  "FFmpegWriter::write_audio_packets (Successfully completed 1st resampling)",
1757  "nb_samples", nb_samples,
1758  "remaining_frame_samples", remaining_frame_samples);
1759  }
1760 
1761  // Loop until no more samples
1762  while (remaining_frame_samples > 0 || is_final) {
1763  // Get remaining samples needed for this packet
1764  int remaining_packet_samples = (audio_input_frame_size * info.channels) - audio_input_position;
1765 
1766  // Determine how many samples we need
1767  int diff = 0;
1768  if (remaining_frame_samples >= remaining_packet_samples) {
1769  diff = remaining_packet_samples;
1770  } else {
1771  diff = remaining_frame_samples;
1772  }
1773 
1774  // Copy frame samples into the packet samples array
1775  if (!is_final)
1776  //TODO: Make this more sane
1777  memcpy(
1778  samples + (audio_input_position
1779  * (av_get_bytes_per_sample(output_sample_fmt) /
1780  av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1781  ),
1782  all_resampled_samples + samples_position,
1783  static_cast<size_t>(diff)
1784  * av_get_bytes_per_sample(output_sample_fmt)
1785  );
1786 
1787  // Increment counters
1788  audio_input_position += diff;
1789  samples_position += diff * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16));
1790  remaining_frame_samples -= diff;
1791 
1792  // Do we have enough samples to proceed?
1793  if (audio_input_position < (audio_input_frame_size * info.channels) && !is_final)
1794  // Not enough samples to encode... so wait until the next frame
1795  break;
1796 
1797  // Convert to planar (if needed by audio codec)
1798  AVFrame *frame_final = AV_ALLOCATE_FRAME();
1799  AV_RESET_FRAME(frame_final);
1800  if (av_sample_fmt_is_planar(audio_codec_ctx->sample_fmt)) {
1802  "FFmpegWriter::write_audio_packets (2nd resampling for Planar formats)",
1803  "in_sample_fmt", output_sample_fmt,
1804  "out_sample_fmt", audio_codec_ctx->sample_fmt,
1805  "in_sample_rate", info.sample_rate,
1806  "out_sample_rate", info.sample_rate,
1807  "in_channels", info.channels,
1808  "out_channels", info.channels
1809  );
1810 
1811  // setup resample context
1812  if (!avr_planar) {
1813  avr_planar = SWR_ALLOC();
1814 #if HAVE_CH_LAYOUT
1815  AVChannelLayout layout;
1816  av_channel_layout_from_mask(&layout, info.channel_layout);
1817  av_opt_set_chlayout(avr_planar, "in_chlayout", &layout, 0);
1818  av_opt_set_chlayout(avr_planar, "out_chlayout", &layout, 0);
1819 #else
1820  av_opt_set_int(avr_planar, "in_channel_layout", info.channel_layout, 0);
1821  av_opt_set_int(avr_planar, "out_channel_layout", info.channel_layout, 0);
1822  av_opt_set_int(avr_planar, "in_channels", info.channels, 0);
1823  av_opt_set_int(avr_planar, "out_channels", info.channels, 0);
1824 #endif
1825  av_opt_set_int(avr_planar, "in_sample_fmt", output_sample_fmt, 0);
1826  av_opt_set_int(avr_planar, "out_sample_fmt", audio_codec_ctx->sample_fmt, 0); // planar not allowed here
1827  av_opt_set_int(avr_planar, "in_sample_rate", info.sample_rate, 0);
1828  av_opt_set_int(avr_planar, "out_sample_rate", info.sample_rate, 0);
1829  SWR_INIT(avr_planar);
1830  }
1831 
1832  // Create input frame (and allocate arrays)
1833  audio_frame = AV_ALLOCATE_FRAME();
1834  AV_RESET_FRAME(audio_frame);
1835  audio_frame->nb_samples = audio_input_position / info.channels;
1836 
1837  // Create a new array
1838  final_samples_planar = (int16_t *) av_malloc(
1839  sizeof(int16_t) * audio_frame->nb_samples * info.channels
1840  * (av_get_bytes_per_sample(output_sample_fmt) /
1841  av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1842  );
1843 
1844  // Copy audio into buffer for frame
1845  memcpy(final_samples_planar, samples,
1846  static_cast<size_t>(audio_frame->nb_samples)
1847  * info.channels
1848  * av_get_bytes_per_sample(output_sample_fmt));
1849 
1850  // Fill input frame with sample data
1851  avcodec_fill_audio_frame(audio_frame, info.channels, output_sample_fmt,
1852  (uint8_t *) final_samples_planar, audio_encoder_buffer_size, 0);
1853 
1854  // Create output frame (and allocate arrays)
1855  frame_final->nb_samples = audio_input_frame_size;
1856 #if HAVE_CH_LAYOUT
1857  av_channel_layout_from_mask(&frame_final->ch_layout, info.channel_layout);
1858 #else
1859  frame_final->channels = info.channels;
1860  frame_final->channel_layout = info.channel_layout;
1861 #endif
1862  frame_final->format = audio_codec_ctx->sample_fmt;
1863  av_samples_alloc(frame_final->data, frame_final->linesize, info.channels,
1864  frame_final->nb_samples, audio_codec_ctx->sample_fmt, 0);
1865 
1866  // Convert audio samples
1867  int nb_samples = SWR_CONVERT(
1868  avr_planar, // audio resample context
1869  frame_final->data, // output data pointers
1870  frame_final->linesize[0], // output plane size, in bytes. (0 if unknown)
1871  frame_final->nb_samples, // maximum number of samples that the output buffer can hold
1872  audio_frame->data, // input data pointers
1873  audio_frame->linesize[0], // input plane size, in bytes (0 if unknown)
1874  audio_frame->nb_samples // number of input samples to convert
1875  );
1876 
1877  // Copy audio samples over original samples
1878  const auto copy_length = static_cast<size_t>(nb_samples)
1879  * av_get_bytes_per_sample(audio_codec_ctx->sample_fmt)
1880  * info.channels;
1881 
1882  if (nb_samples > 0)
1883  memcpy(samples, frame_final->data[0], copy_length);
1884 
1885  // deallocate AVFrame
1886  av_freep(&(audio_frame->data[0]));
1887  AV_FREE_FRAME(&audio_frame);
1888  all_queued_samples = NULL; // this array cleared with above call
1889 
1891  "FFmpegWriter::write_audio_packets (Successfully completed 2nd resampling for Planar formats)",
1892  "nb_samples", nb_samples);
1893 
1894  } else {
1895  // Create a new array
1896  const auto buf_size = static_cast<size_t>(audio_input_position)
1897  * (av_get_bytes_per_sample(audio_codec_ctx->sample_fmt) /
1898  av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)
1899  );
1900  final_samples = reinterpret_cast<int16_t*>(
1901  av_malloc(sizeof(int16_t) * buf_size));
1902 
1903  // Copy audio into buffer for frame
1904  memcpy(final_samples, samples,
1905  audio_input_position * av_get_bytes_per_sample(audio_codec_ctx->sample_fmt));
1906 
1907  // Init the nb_samples property
1908  frame_final->nb_samples = audio_input_frame_size;
1909 
1910  // Fill the final_frame AVFrame with audio (non planar)
1911 #if HAVE_CH_LAYOUT
1912  int nb_channels = audio_codec_ctx->ch_layout.nb_channels;
1913 #else
1914  int nb_channels = audio_codec_ctx->channels;
1915 #endif
1916  avcodec_fill_audio_frame(frame_final, nb_channels,
1917  audio_codec_ctx->sample_fmt, (uint8_t *) final_samples,
1918  audio_encoder_buffer_size, 0);
1919  }
1920 
1921  // Set the AVFrame's PTS
1922  frame_final->pts = audio_timestamp;
1923 
1924  // Init the packet
1925 #if IS_FFMPEG_3_2
1926  AVPacket* pkt = av_packet_alloc();
1927 #else
1928  AVPacket* pkt;
1929  av_init_packet(pkt);
1930 #endif
1931  pkt->data = audio_encoder_buffer;
1932  pkt->size = audio_encoder_buffer_size;
1933 
1934  // Set the packet's PTS prior to encoding
1935  pkt->pts = pkt->dts = audio_timestamp;
1936 
1937  /* encode the audio samples */
1938  int got_packet_ptr = 0;
1939 
1940 #if IS_FFMPEG_3_2
1941  // Encode audio (latest version of FFmpeg)
1942  int error_code;
1943  int ret = 0;
1944  int frame_finished = 0;
1945  error_code = ret = avcodec_send_frame(audio_codec_ctx, frame_final);
1946  if (ret < 0 && ret != AVERROR(EINVAL) && ret != AVERROR_EOF) {
1947  avcodec_send_frame(audio_codec_ctx, NULL);
1948  }
1949  else {
1950  if (ret >= 0)
1951  pkt->size = 0;
1952  ret = avcodec_receive_packet(audio_codec_ctx, pkt);
1953  if (ret >= 0)
1954  frame_finished = 1;
1955  if(ret == AVERROR(EINVAL) || ret == AVERROR_EOF) {
1956  avcodec_flush_buffers(audio_codec_ctx);
1957  ret = 0;
1958  }
1959  if (ret >= 0) {
1960  ret = frame_finished;
1961  }
1962  }
1963  if (!pkt->data && !frame_finished)
1964  {
1965  ret = -1;
1966  }
1967  got_packet_ptr = ret;
1968 #else
1969  // Encode audio (older versions of FFmpeg)
1970  int error_code = avcodec_encode_audio2(audio_codec_ctx, pkt, frame_final, &got_packet_ptr);
1971 #endif
1972  /* if zero size, it means the image was buffered */
1973  if (error_code == 0 && got_packet_ptr) {
1974 
1975  // Since the PTS can change during encoding, set the value again. This seems like a huge hack,
1976  // but it fixes lots of PTS related issues when I do this.
1977  pkt->pts = pkt->dts = audio_timestamp;
1978 
1979  // Scale the PTS to the audio stream timebase (which is sometimes different than the codec's timebase)
1980  av_packet_rescale_ts(pkt, audio_codec_ctx->time_base, audio_st->time_base);
1981 
1982  // set stream
1983  pkt->stream_index = audio_st->index;
1984  pkt->flags |= AV_PKT_FLAG_KEY;
1985 
1986  /* write the compressed frame in the media file */
1987  error_code = av_interleaved_write_frame(oc, pkt);
1988  }
1989 
1990  if (error_code < 0) {
1992  "FFmpegWriter::write_audio_packets ERROR ["
1993  + av_err2string(error_code) + "]",
1994  "error_code", error_code);
1995  }
1996 
1997  // Increment PTS (no pkt.duration, so calculate with maths)
1998  audio_timestamp += FFMIN(audio_input_frame_size, audio_input_position);
1999 
2000  // deallocate AVFrame
2001  av_freep(&(frame_final->data[0]));
2002  AV_FREE_FRAME(&frame_final);
2003 
2004  // deallocate memory for packet
2005  AV_FREE_PACKET(pkt);
2006 
2007  // Reset position
2008  audio_input_position = 0;
2009  is_final = false;
2010  }
2011 
2012  // Delete arrays (if needed)
2013  if (all_resampled_samples) {
2014  av_freep(&all_resampled_samples);
2015  all_resampled_samples = NULL;
2016  }
2017  if (all_queued_samples) {
2018  av_freep(&all_queued_samples);
2019  all_queued_samples = NULL;
2020  }
2021 }
2022 
2023 // Allocate an AVFrame object
2024 AVFrame *FFmpegWriter::allocate_avframe(PixelFormat pix_fmt, int width, int height, int *buffer_size, uint8_t *new_buffer) {
2025  // Create an RGB AVFrame
2026  AVFrame *new_av_frame = NULL;
2027 
2028  // Allocate an AVFrame structure
2029  new_av_frame = AV_ALLOCATE_FRAME();
2030  if (new_av_frame == NULL)
2031  throw OutOfMemory("Could not allocate AVFrame", path);
2032 
2033  // Determine required buffer size and allocate buffer
2034  *buffer_size = AV_GET_IMAGE_SIZE(pix_fmt, width, height);
2035 
2036  // Create buffer (if not provided)
2037  if (!new_buffer) {
2038  // New Buffer
2039  new_buffer = (uint8_t *) av_malloc(*buffer_size * sizeof(uint8_t));
2040  // Attach buffer to AVFrame
2041  AV_COPY_PICTURE_DATA(new_av_frame, new_buffer, pix_fmt, width, height);
2042  new_av_frame->width = width;
2043  new_av_frame->height = height;
2044  new_av_frame->format = pix_fmt;
2045  }
2046 
2047  // return AVFrame
2048  return new_av_frame;
2049 }
2050 
2051 // process video frame
2052 void FFmpegWriter::process_video_packet(std::shared_ptr<Frame> frame) {
2053  // Source dimensions (RGBA)
2054  int src_w = frame->GetWidth();
2055  int src_h = frame->GetHeight();
2056 
2057  // Skip empty frames (1×1)
2058  if (src_w == 1 && src_h == 1)
2059  return;
2060 
2061  // Point persistent_src_frame->data to RGBA pixels
2062  const uchar* pixels = frame->GetPixels();
2063  if (!persistent_src_frame) {
2064  persistent_src_frame = av_frame_alloc();
2065  if (!persistent_src_frame)
2066  throw OutOfMemory("Could not allocate persistent_src_frame", path);
2067  persistent_src_frame->format = AV_PIX_FMT_RGBA;
2068  persistent_src_frame->width = src_w;
2069  persistent_src_frame->height = src_h;
2070  persistent_src_frame->linesize[0] = src_w * 4;
2071  }
2072  persistent_src_frame->data[0] = const_cast<uint8_t*>(
2073  reinterpret_cast<const uint8_t*>(pixels)
2074  );
2075 
2076  // Prepare persistent_dst_frame + buffer on first use
2077  if (!persistent_dst_frame) {
2078  persistent_dst_frame = av_frame_alloc();
2079  if (!persistent_dst_frame)
2080  throw OutOfMemory("Could not allocate persistent_dst_frame", path);
2081 
2082  // Decide destination pixel format: NV12 if HW accel is on, else encoder’s pix_fmt
2083  AVPixelFormat dst_fmt = video_codec_ctx->pix_fmt;
2084 #if USE_HW_ACCEL
2085  if (hw_en_on && hw_en_supported) {
2086  dst_fmt = AV_PIX_FMT_NV12;
2087  }
2088 #endif
2089  persistent_dst_frame->format = dst_fmt;
2090  persistent_dst_frame->width = info.width;
2091  persistent_dst_frame->height = info.height;
2092 
2093  persistent_dst_size = av_image_get_buffer_size(
2094  dst_fmt, info.width, info.height, 1
2095  );
2096  if (persistent_dst_size < 0)
2097  throw ErrorEncodingVideo("Invalid destination image size", -1);
2098 
2099  persistent_dst_buffer = static_cast<uint8_t*>(
2100  av_malloc(persistent_dst_size)
2101  );
2102  if (!persistent_dst_buffer)
2103  throw OutOfMemory("Could not allocate persistent_dst_buffer", path);
2104 
2105  av_image_fill_arrays(
2106  persistent_dst_frame->data,
2107  persistent_dst_frame->linesize,
2108  persistent_dst_buffer,
2109  dst_fmt,
2110  info.width,
2111  info.height,
2112  1
2113  );
2114  }
2115 
2116  // Initialize SwsContext (RGBA → dst_fmt) on first use
2117  if (!img_convert_ctx) {
2118  int flags = SWS_FAST_BILINEAR;
2119  if (openshot::Settings::Instance()->HIGH_QUALITY_SCALING) {
2120  flags = SWS_BICUBIC;
2121  }
2122  AVPixelFormat dst_fmt = video_codec_ctx->pix_fmt;
2123 #if USE_HW_ACCEL
2124  if (hw_en_on && hw_en_supported) {
2125  dst_fmt = AV_PIX_FMT_NV12;
2126  }
2127 #endif
2128  img_convert_ctx = sws_getContext(
2129  src_w, src_h, AV_PIX_FMT_RGBA,
2130  info.width, info.height, dst_fmt,
2131  flags, NULL, NULL, NULL
2132  );
2133  if (!img_convert_ctx)
2134  throw ErrorEncodingVideo("Could not initialize sws context", -1);
2135  }
2136 
2137  // Scale RGBA → dst_fmt into persistent_dst_buffer
2138  sws_scale(
2139  img_convert_ctx,
2140  persistent_src_frame->data,
2141  persistent_src_frame->linesize,
2142  0, src_h,
2143  persistent_dst_frame->data,
2144  persistent_dst_frame->linesize
2145  );
2146 
2147  // Allocate a new AVFrame + buffer, then copy scaled data into it
2148  int bytes_final = 0;
2149  AVPixelFormat dst_fmt = video_codec_ctx->pix_fmt;
2150 #if USE_HW_ACCEL
2151  if (hw_en_on && hw_en_supported) {
2152  dst_fmt = AV_PIX_FMT_NV12;
2153  }
2154 #endif
2155 
2156  AVFrame* new_frame = allocate_avframe(
2157  dst_fmt,
2158  info.width,
2159  info.height,
2160  &bytes_final,
2161  nullptr
2162  );
2163  if (!new_frame)
2164  throw OutOfMemory("Could not allocate new_frame via allocate_avframe", path);
2165 
2166  // Copy persistent_dst_buffer → new_frame buffer
2167  memcpy(
2168  new_frame->data[0],
2169  persistent_dst_buffer,
2170  static_cast<size_t>(bytes_final)
2171  );
2172 
2173  // Queue the deep‐copied frame for encoding
2174  add_avframe(frame, new_frame);
2175 }
2176 
2177 // write video frame
2178 bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *frame_final) {
2179 #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
2180  // FFmpeg 4.0+
2182  "FFmpegWriter::write_video_packet",
2183  "frame->number", frame->number,
2184  "oc->oformat->flags", oc->oformat->flags);
2185 
2186  if (AV_GET_CODEC_TYPE(video_st) == AVMEDIA_TYPE_VIDEO && AV_FIND_DECODER_CODEC_ID(video_st) == AV_CODEC_ID_RAWVIDEO) {
2187 #else
2188  // TODO: Should we have moved away from oc->oformat->flags / AVFMT_RAWPICTURE
2189  // on ffmpeg < 4.0 as well?
2190  // Does AV_CODEC_ID_RAWVIDEO not work in ffmpeg 3.x?
2192  "FFmpegWriter::write_video_packet",
2193  "frame->number", frame->number,
2194  "oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE);
2195 
2196  if (oc->oformat->flags & AVFMT_RAWPICTURE) {
2197 #endif
2198  // Raw video case.
2199 #if IS_FFMPEG_3_2
2200  AVPacket* pkt = av_packet_alloc();
2201 #else
2202  AVPacket* pkt;
2203  av_init_packet(pkt);
2204 #endif
2205 
2206  av_packet_from_data(
2207  pkt, frame_final->data[0],
2208  frame_final->linesize[0] * frame_final->height);
2209 
2210  pkt->flags |= AV_PKT_FLAG_KEY;
2211  pkt->stream_index = video_st->index;
2212 
2213  // Set PTS (in frames and scaled to the codec's timebase)
2214  pkt->pts = video_timestamp;
2215 
2216  /* write the compressed frame in the media file */
2217  int error_code = av_interleaved_write_frame(oc, pkt);
2218  if (error_code < 0) {
2220  "FFmpegWriter::write_video_packet ERROR ["
2221  + av_err2string(error_code) + "]",
2222  "error_code", error_code);
2223  return false;
2224  }
2225 
2226  // Deallocate packet
2227  AV_FREE_PACKET(pkt);
2228 
2229  } else
2230  {
2231 
2232 #if IS_FFMPEG_3_2
2233  AVPacket* pkt = av_packet_alloc();
2234 #else
2235  AVPacket* pkt;
2236  av_init_packet(pkt);
2237 #endif
2238  pkt->data = NULL;
2239  pkt->size = 0;
2240  pkt->pts = pkt->dts = AV_NOPTS_VALUE;
2241 
2242  // Assign the initial AVFrame PTS from the frame counter
2243  frame_final->pts = video_timestamp;
2244 #if USE_HW_ACCEL
2245  if (hw_en_on && hw_en_supported) {
2246  if (!(hw_frame = av_frame_alloc())) {
2247  std::clog << "Error code: av_hwframe_alloc\n";
2248  }
2249  if (av_hwframe_get_buffer(video_codec_ctx->hw_frames_ctx, hw_frame, 0) < 0) {
2250  std::clog << "Error code: av_hwframe_get_buffer\n";
2251  }
2252  if (!hw_frame->hw_frames_ctx) {
2253  std::clog << "Error hw_frames_ctx.\n";
2254  }
2255  hw_frame->format = AV_PIX_FMT_NV12;
2256  if ( av_hwframe_transfer_data(hw_frame, frame_final, 0) < 0) {
2257  std::clog << "Error while transferring frame data to surface.\n";
2258  }
2259  av_frame_copy_props(hw_frame, frame_final);
2260  }
2261 #endif // USE_HW_ACCEL
2262  /* encode the image */
2263  int got_packet_ptr = 0;
2264  int error_code = 0;
2265 #if IS_FFMPEG_3_2
2266  // Write video packet
2267  int ret;
2268 
2269  #if USE_HW_ACCEL
2270  if (hw_en_on && hw_en_supported) {
2271  ret = avcodec_send_frame(video_codec_ctx, hw_frame); //hw_frame!!!
2272  } else
2273  #endif // USE_HW_ACCEL
2274  {
2275  ret = avcodec_send_frame(video_codec_ctx, frame_final);
2276  }
2277  error_code = ret;
2278  if (ret < 0 ) {
2280  "FFmpegWriter::write_video_packet (Frame not sent)");
2281  if (ret == AVERROR(EAGAIN) ) {
2282  std::clog << "Frame EAGAIN\n";
2283  }
2284  if (ret == AVERROR_EOF ) {
2285  std::clog << "Frame AVERROR_EOF\n";
2286  }
2287  avcodec_send_frame(video_codec_ctx, NULL);
2288  }
2289  else {
2290  while (ret >= 0) {
2291  ret = avcodec_receive_packet(video_codec_ctx, pkt);
2292 
2293  if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
2294  got_packet_ptr = 0;
2295  break;
2296  }
2297  if (ret == 0) {
2298  got_packet_ptr = 1;
2299  break;
2300  }
2301  }
2302  }
2303 #else
2304  // Write video packet (older than FFmpeg 3.2)
2305  error_code = avcodec_encode_video2(video_codec_ctx, pkt, frame_final, &got_packet_ptr);
2306  if (error_code != 0) {
2308  "FFmpegWriter::write_video_packet ERROR ["
2309  + av_err2string(error_code) + "]",
2310  "error_code", error_code);
2311  }
2312  if (got_packet_ptr == 0) {
2314  "FFmpegWriter::write_video_packet (Frame gotpacket error)");
2315  }
2316 #endif // IS_FFMPEG_3_2
2317 
2318  /* if zero size, it means the image was buffered */
2319  if (error_code == 0 && got_packet_ptr) {
2320  // set the timestamp
2321  av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
2322  pkt->stream_index = video_st->index;
2323 
2324  /* write the compressed frame in the media file */
2325  int result = av_interleaved_write_frame(oc, pkt);
2326  if (result < 0) {
2328  "FFmpegWriter::write_video_packet ERROR ["
2329  + av_err2string(result) + "]",
2330  "result", result);
2331  return false;
2332  }
2333  }
2334 
2335  // Deallocate packet
2336  AV_FREE_PACKET(pkt);
2337 #if USE_HW_ACCEL
2338  if (hw_en_on && hw_en_supported) {
2339  if (hw_frame) {
2340  av_frame_free(&hw_frame);
2341  hw_frame = NULL;
2342  }
2343  }
2344 #endif // USE_HW_ACCEL
2345  }
2346 
2347  // Increment PTS (in frames and scaled to the codec's timebase)
2348  video_timestamp += av_rescale_q(1, av_make_q(info.fps.den, info.fps.num), video_codec_ctx->time_base);
2349 
2350  // Success
2351  return true;
2352 }
2353 
2354 // Output the ffmpeg info about this format, streams, and codecs (i.e. dump format)
2356  // output debug info
2357  av_dump_format(oc, 0, path.c_str(), 1);
2358 }
2359 
2360 // Set audio resample options
2361 void FFmpegWriter::ResampleAudio(int sample_rate, int channels) {
2362  original_sample_rate = sample_rate;
2363  original_channels = channels;
2364 }
2365 
2366 // In FFmpegWriter.cpp
2367 void FFmpegWriter::AddSphericalMetadata(const std::string& projection, float yaw_deg, float pitch_deg, float roll_deg) {
2368  if (!oc) return;
2369  if (!info.has_video || !video_st) return;
2370 
2371  // Allow movenc.c to write out the sv3d atom
2372  oc->strict_std_compliance = FF_COMPLIANCE_UNOFFICIAL;
2373 
2374 #if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 0, 0)
2375  // Map the projection name to the enum (defaults to equirectangular)
2376  int proj = av_spherical_from_name(projection.c_str());
2377  if (proj < 0)
2378  proj = AV_SPHERICAL_EQUIRECTANGULAR;
2379 
2380  // Allocate the side‐data structure
2381  size_t sd_size = 0;
2382  AVSphericalMapping* map = av_spherical_alloc(&sd_size);
2383  if (!map) return;
2384 
2385  // Populate it
2386  map->projection = static_cast<AVSphericalProjection>(proj);
2387  // yaw/pitch/roll are 16.16 fixed point
2388  map->yaw = static_cast<int32_t>(yaw_deg * (1 << 16));
2389  map->pitch = static_cast<int32_t>(pitch_deg * (1 << 16));
2390  map->roll = static_cast<int32_t>(roll_deg * (1 << 16));
2391 
2392  av_stream_add_side_data(video_st, AV_PKT_DATA_SPHERICAL, reinterpret_cast<uint8_t*>(map), sd_size);
2393 #endif
2394 }
AUDIO_PACKET_ENCODING_SIZE
#define AUDIO_PACKET_ENCODING_SIZE
Definition: FFmpegUtilities.h:90
Settings.h
Header file for global Settings class.
openshot::AUDIO_STREAM
@ AUDIO_STREAM
An audio stream (used to determine which type of stream)
Definition: FFmpegWriter.h:30
hw_frame
AVFrame * hw_frame
Definition: FFmpegWriter.cpp:42
openshot::InvalidFormat
Exception when no valid format is found for a file.
Definition: Exceptions.h:202
PIX_FMT_RGB24
#define PIX_FMT_RGB24
Definition: FFmpegUtilities.h:116
AV_FIND_DECODER_CODEC_ID
#define AV_FIND_DECODER_CODEC_ID(av_stream)
Definition: FFmpegUtilities.h:211
openshot::InvalidSampleRate
Exception when invalid sample rate is detected during encoding.
Definition: Exceptions.h:247
FFmpegUtilities.h
Header file for FFmpegUtilities.
openshot::WriterInfo::video_bit_rate
int video_bit_rate
The bit rate of the video stream (in bytes)
Definition: WriterBase.h:43
FFmpegWriter.h
Header file for FFmpegWriter class.
openshot::InvalidCodec
Exception when no valid codec is found for a file.
Definition: Exceptions.h:172
openshot::FFmpegWriter::ResampleAudio
void ResampleAudio(int sample_rate, int channels)
Set audio resample options.
Definition: FFmpegWriter.cpp:2361
openshot::WriterInfo::display_ratio
openshot::Fraction display_ratio
The ratio of width to height of the video stream (i.e. 640x480 has a ratio of 4/3)
Definition: WriterBase.h:45
openshot::WriterClosed
Exception when a writer is closed, and a frame is requested.
Definition: Exceptions.h:415
AV_COPY_PICTURE_DATA
#define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height)
Definition: FFmpegUtilities.h:223
openshot::FFmpegWriter::OutputStreamInfo
void OutputStreamInfo()
Output the ffmpeg info about this format, streams, and codecs (i.e. dump format)
Definition: FFmpegWriter.cpp:2355
PixelFormat
#define PixelFormat
Definition: FFmpegUtilities.h:107
openshot::ReaderBase::GetFrame
virtual std::shared_ptr< openshot::Frame > GetFrame(int64_t number)=0
AV_ALLOCATE_FRAME
#define AV_ALLOCATE_FRAME()
Definition: FFmpegUtilities.h:203
SWR_CONVERT
#define SWR_CONVERT(ctx, out, linesize, out_count, in, linesize2, in_count)
Definition: FFmpegUtilities.h:149
openshot::WriterInfo::fps
openshot::Fraction fps
Frames per second, as a fraction (i.e. 24/1 = 24 fps)
Definition: WriterBase.h:42
openshot
This namespace is the default namespace for all code in the openshot library.
Definition: Compressor.h:28
AV_OPTION_SET
#define AV_OPTION_SET(av_stream, priv_data, name, value, avcodec)
Definition: FFmpegUtilities.h:228
openshot::WriterInfo::audio_bit_rate
int audio_bit_rate
The bit rate of the audio stream (in bytes)
Definition: WriterBase.h:53
openshot::WriterInfo::channels
int channels
The number of audio channels used in the audio stream.
Definition: WriterBase.h:55
AV_COPY_PARAMS_FROM_CONTEXT
AV_COPY_PARAMS_FROM_CONTEXT(st, video_codec_ctx)
openshot::Fraction
This class represents a fraction.
Definition: Fraction.h:30
AV_GET_CODEC_FROM_STREAM
#define AV_GET_CODEC_FROM_STREAM(av_stream, codec_in)
Definition: FFmpegUtilities.h:217
openshot::FFmpegWriter::FFmpegWriter
FFmpegWriter(const std::string &path)
Constructor for FFmpegWriter. Throws an exception on failure to open path.
Definition: FFmpegWriter.cpp:75
AV_FREE_FRAME
#define AV_FREE_FRAME(av_frame)
Definition: FFmpegUtilities.h:207
AV_FREE_PACKET
#define AV_FREE_PACKET(av_packet)
Definition: FFmpegUtilities.h:208
openshot::FFmpegWriter::Open
void Open()
Open writer.
Definition: FFmpegWriter.cpp:95
openshot::FFmpegWriter::SetVideoOptions
void SetVideoOptions(bool has_video, std::string codec, openshot::Fraction fps, int width, int height, openshot::Fraction pixel_ratio, bool interlaced, bool top_field_first, int bit_rate)
Set video export options.
Definition: FFmpegWriter.cpp:163
openshot::LAYOUT_STEREO
@ LAYOUT_STEREO
Definition: ChannelLayouts.h:31
AV_GET_CODEC_PAR_CONTEXT
#define AV_GET_CODEC_PAR_CONTEXT(av_stream, av_codec)
Definition: FFmpegUtilities.h:216
openshot::WriterInfo::width
int width
The width of the video (in pixels)
Definition: WriterBase.h:40
hw_en_on
int hw_en_on
Definition: FFmpegWriter.cpp:37
openshot::WriterInfo::acodec
std::string acodec
The name of the audio codec used to encode / decode the video stream.
Definition: WriterBase.h:52
openshot::WriterInfo::video_timebase
openshot::Fraction video_timebase
The video timebase determines how long each frame stays on the screen.
Definition: WriterBase.h:49
openshot::LAYOUT_MONO
@ LAYOUT_MONO
Definition: ChannelLayouts.h:30
AV_GET_CODEC_ATTRIBUTES
#define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context)
Definition: FFmpegUtilities.h:218
openshot::Settings::HW_EN_DEVICE_SET
int HW_EN_DEVICE_SET
Which GPU to use to encode (0 is the first)
Definition: Settings.h:83
openshot::WriterInfo::pixel_ratio
openshot::Fraction pixel_ratio
The pixel ratio of the video stream as a fraction (i.e. some pixels are not square)
Definition: WriterBase.h:44
openshot::Fraction::num
int num
Numerator for the fraction.
Definition: Fraction.h:32
openshot::WriterInfo::top_field_first
bool top_field_first
Which interlaced field should be displayed first.
Definition: WriterBase.h:51
if
if(!codec) codec
AV_SET_FILENAME
#define AV_SET_FILENAME(oc, f)
Definition: FFmpegUtilities.h:201
AV_GET_IMAGE_SIZE
#define AV_GET_IMAGE_SIZE(pix_fmt, width, height)
Definition: FFmpegUtilities.h:222
ZmqLogger.h
Header file for ZeroMQ-based Logger class.
mux_dict
AVDictionary * mux_dict
Definition: FFmpegWriter.cpp:34
openshot::ErrorEncodingVideo
Exception when encoding audio packet.
Definition: Exceptions.h:142
openshot::Fraction::den
int den
Denominator for the fraction.
Definition: Fraction.h:33
openshot::FFmpegWriter::AddSphericalMetadata
void AddSphericalMetadata(const std::string &projection="equirectangular", float yaw_deg=0.0f, float pitch_deg=0.0f, float roll_deg=0.0f)
Add spherical (360°) video metadata to the video stream.
Definition: FFmpegWriter.cpp:2367
openshot::FFmpegWriter::SetOption
void SetOption(openshot::StreamType stream, std::string name, std::string value)
Set custom options (some codecs accept additional params). This must be called after the PrepareStrea...
Definition: FFmpegWriter.cpp:333
openshot::Fraction::Reduce
void Reduce()
Reduce this fraction (i.e. 640/480 = 4/3)
Definition: Fraction.cpp:65
AV_RESET_FRAME
#define AV_RESET_FRAME(av_frame)
Definition: FFmpegUtilities.h:206
SWR_CLOSE
#define SWR_CLOSE(ctx)
Definition: FFmpegUtilities.h:152
openshot::WriterInfo::channel_layout
openshot::ChannelLayout channel_layout
The channel layout (mono, stereo, 5 point surround, etc...)
Definition: WriterBase.h:56
openshot::OutOfMemory
Exception when memory could not be allocated.
Definition: Exceptions.h:348
SWR_INIT
#define SWR_INIT(ctx)
Definition: FFmpegUtilities.h:154
hw_en_av_pix_fmt
AVPixelFormat hw_en_av_pix_fmt
Definition: FFmpegWriter.cpp:39
openshot::Settings::Instance
static Settings * Instance()
Create or get an instance of this logger singleton (invoke the class with this method)
Definition: Settings.cpp:23
openshot::VIDEO_STREAM
@ VIDEO_STREAM
A video stream (used to determine which type of stream)
Definition: FFmpegWriter.h:29
openshot::WriterInfo::metadata
std::map< std::string, std::string > metadata
An optional map/dictionary of video & audio metadata.
Definition: WriterBase.h:59
path
path
Definition: FFmpegWriter.cpp:1467
Frame.h
Header file for Frame class.
ALLOC_CODEC_CTX
#define ALLOC_CODEC_CTX(ctx, codec, stream)
Definition: FFmpegUtilities.h:231
openshot::InvalidFile
Exception for files that can not be found or opened.
Definition: Exceptions.h:187
openshot::ZmqLogger::Instance
static ZmqLogger * Instance()
Create or get an instance of this logger singleton (invoke the class with this method)
Definition: ZmqLogger.cpp:35
openshot::FFmpegWriter::WriteFrame
void WriteFrame(std::shared_ptr< openshot::Frame > frame)
Add a frame to the stack waiting to be encoded.
Definition: FFmpegWriter.cpp:665
openshot::ZmqLogger::AppendDebugMethod
void AppendDebugMethod(std::string method_name, std::string arg1_name="", float arg1_value=-1.0, std::string arg2_name="", float arg2_value=-1.0, std::string arg3_name="", float arg3_value=-1.0, std::string arg4_name="", float arg4_value=-1.0, std::string arg5_name="", float arg5_value=-1.0, std::string arg6_name="", float arg6_value=-1.0)
Append debug information.
Definition: ZmqLogger.cpp:178
openshot::WriterInfo::has_video
bool has_video
Determines if this file has a video stream.
Definition: WriterBase.h:34
openshot::WriterInfo::has_audio
bool has_audio
Determines if this file has an audio stream.
Definition: WriterBase.h:35
PIX_FMT_YUV420P
#define PIX_FMT_YUV420P
Definition: FFmpegUtilities.h:119
PIX_FMT_YUV444P
#define PIX_FMT_YUV444P
Definition: FFmpegUtilities.h:122
AV_GET_CODEC_TYPE
#define AV_GET_CODEC_TYPE(av_stream)
Definition: FFmpegUtilities.h:210
openshot::FFmpegWriter::Close
void Close()
Close the writer.
Definition: FFmpegWriter.cpp:955
openshot::FFmpegWriter::IsValidCodec
static bool IsValidCodec(std::string codec_name)
Determine if codec name is valid.
Definition: FFmpegWriter.cpp:597
openshot::WriterInfo::height
int height
The height of the video (in pixels)
Definition: WriterBase.h:39
AV_FREE_CONTEXT
#define AV_FREE_CONTEXT(av_context)
Definition: FFmpegUtilities.h:209
OpenMPUtilities.h
Header file for OpenMPUtilities (set some common macros)
SWR_FREE
#define SWR_FREE(ctx)
Definition: FFmpegUtilities.h:153
openshot::FFmpegWriter::WriteTrailer
void WriteTrailer()
Write the file trailer (after all frames are written). This is called automatically by the Close() me...
Definition: FFmpegWriter.cpp:742
PIX_FMT_NONE
#define PIX_FMT_NONE
Definition: FFmpegUtilities.h:113
FF_AUDIO_NUM_PROCESSORS
#define FF_AUDIO_NUM_PROCESSORS
Definition: OpenMPUtilities.h:25
openshot::ReaderBase
This abstract class is the base class, used by all readers in libopenshot.
Definition: ReaderBase.h:75
openshot::WriterInfo::interlaced_frame
bool interlaced_frame
Are the contents of this frame interlaced.
Definition: WriterBase.h:50
FF_VIDEO_NUM_PROCESSORS
#define FF_VIDEO_NUM_PROCESSORS
Definition: OpenMPUtilities.h:24
openshot::WriterInfo::vcodec
std::string vcodec
The name of the video codec used to encode / decode the video stream.
Definition: WriterBase.h:46
openshot::WriterInfo::sample_rate
int sample_rate
The number of audio samples per second (44100 is a common sample rate)
Definition: WriterBase.h:54
openshot::InvalidChannels
Exception when an invalid # of audio channels are detected.
Definition: Exceptions.h:157
AV_OPTION_FIND
#define AV_OPTION_FIND(priv_data, name)
Definition: FFmpegUtilities.h:227
codec
codec
Definition: FFmpegWriter.cpp:1463
openshot::ChannelLayout
ChannelLayout
This enumeration determines the audio channel layout (such as stereo, mono, 5 point surround,...
Definition: ChannelLayouts.h:28
hw_en_av_device_type
AVHWDeviceType hw_en_av_device_type
Definition: FFmpegWriter.cpp:40
SWR_ALLOC
#define SWR_ALLOC()
Definition: FFmpegUtilities.h:151
openshot::FFmpegWriter::SetAudioOptions
void SetAudioOptions(bool has_audio, std::string codec, int sample_rate, int channels, openshot::ChannelLayout channel_layout, int bit_rate)
Set audio export options.
Definition: FFmpegWriter.cpp:286
AV_REGISTER_ALL
#define AV_REGISTER_ALL
Definition: FFmpegUtilities.h:198
AV_OUTPUT_CONTEXT
#define AV_OUTPUT_CONTEXT(output_context, path)
Definition: FFmpegUtilities.h:225
hw_en_supported
int hw_en_supported
Definition: FFmpegWriter.cpp:38
openshot::StreamType
StreamType
This enumeration designates the type of stream when encoding (video or audio)
Definition: FFmpegWriter.h:28
openshot::FFmpegWriter::PrepareStreams
void PrepareStreams()
Prepare & initialize streams and open codecs. This method is called automatically by the Open() metho...
Definition: FFmpegWriter.cpp:606
openshot::InvalidOptions
Exception when invalid encoding options are used.
Definition: Exceptions.h:232
openshot::WriterBase::info
WriterInfo info
Information about the current media file.
Definition: WriterBase.h:76
openshot::NoStreamsFound
Exception when no streams are found in the file.
Definition: Exceptions.h:285
MY_INPUT_BUFFER_PADDING_SIZE
#define MY_INPUT_BUFFER_PADDING_SIZE
Definition: FFmpegUtilities.h:202
AVCODEC_MAX_AUDIO_FRAME_SIZE
#define AVCODEC_MAX_AUDIO_FRAME_SIZE
Definition: FFmpegUtilities.h:83
opts
AVDictionary * opts
Definition: FFmpegWriter.cpp:1474
Exceptions.h
Header file for all Exception classes.
openshot::FFmpegWriter::WriteHeader
void WriteHeader()
Write the file header (after the options are set). This method is called automatically by the Open() ...
Definition: FFmpegWriter.cpp:623