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