OpenShot Library | libopenshot  0.5.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 // Write all frames in the queue to the video file.
690 void FFmpegWriter::write_frame(std::shared_ptr<Frame> frame) {
691  // Flip writing flag
692  is_writing = true;
693 
694  // Create blank exception
695  bool has_error_encoding_video = false;
696 
697  // Process audio frame
698  if (info.has_audio && audio_st)
699  write_audio_packets(false, frame);
700 
701  // Process video frame
702  if (info.has_video && video_st)
703  process_video_packet(frame);
704 
705  if (info.has_video && video_st) {
706  // Does this frame's AVFrame still exist
707  if (av_frames.count(frame)) {
708  // Get AVFrame
709  AVFrame *frame_final = av_frames[frame];
710 
711  // Write frame to video file
712  if (!write_video_packet(frame, frame_final)) {
713  has_error_encoding_video = true;
714  }
715 
716  // Deallocate buffer and AVFrame
717  av_freep(&(frame_final->data[0]));
718  AV_FREE_FRAME(&frame_final);
719  av_frames.erase(frame);
720  }
721  }
722 
723  // Done writing
724  is_writing = false;
725 
726  // Raise exception from main thread
727  if (has_error_encoding_video)
728  throw ErrorEncodingVideo("Error while writing raw video frame", -1);
729 }
730 
731 // Write a block of frames from a reader
732 void FFmpegWriter::WriteFrame(ReaderBase *reader, int64_t start, int64_t length) {
734  "FFmpegWriter::WriteFrame (from Reader)",
735  "start", start,
736  "length", length);
737 
738  // Loop through each frame (and encoded it)
739  for (int64_t number = start; number <= length; number++) {
740  // Get the frame
741  std::shared_ptr<Frame> f = reader->GetFrame(number);
742 
743  // Encode frame
744  WriteFrame(f);
745  }
746 }
747 
748 // Write the file trailer (after all frames are written)
750  // Process final audio frame (if any)
751  if (info.has_audio && audio_st)
752  write_audio_packets(true, NULL);
753 
754  // Flush encoders (who sometimes hold on to frames)
755  flush_encoders();
756 
757  /* write the trailer, if any. The trailer must be written
758  * before you close the CodecContexts open when you wrote the
759  * header; otherwise write_trailer may try to use memory that
760  * was freed on av_codec_close() */
761  av_write_trailer(oc);
762 
763  // Mark as 'written'
764  write_trailer = true;
765 
766  ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::WriteTrailer");
767 }
768 
769 // Flush encoders
770 void FFmpegWriter::flush_encoders() {
771  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)
772  return;
773 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
774  // FFmpeg < 4.0
775  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)
776  return;
777 #else
778  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)
779  return;
780 #endif
781 
782  // FLUSH VIDEO ENCODER
783  if (info.has_video) {
784  for (;;) {
785 
786  // Increment PTS (in frames and scaled to the codec's timebase)
787  video_timestamp += av_rescale_q(1, av_make_q(info.fps.den, info.fps.num), video_codec_ctx->time_base);
788 
789 #if IS_FFMPEG_3_2
790  AVPacket* pkt = av_packet_alloc();
791 #else
792  AVPacket* pkt;
793  av_init_packet(pkt);
794 #endif
795  pkt->data = NULL;
796  pkt->size = 0;
797 
798  /* encode the image */
799  int got_packet = 0;
800  int error_code = 0;
801 
802 #if IS_FFMPEG_3_2
803  // Encode video packet (latest version of FFmpeg)
804  error_code = avcodec_send_frame(video_codec_ctx, NULL);
805  got_packet = 0;
806  while (error_code >= 0) {
807  error_code = avcodec_receive_packet(video_codec_ctx, pkt);
808  if (error_code == AVERROR(EAGAIN)|| error_code == AVERROR_EOF) {
809  got_packet = 0;
810  // Write packet
811  avcodec_flush_buffers(video_codec_ctx);
812  break;
813  }
814  av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
815  pkt->stream_index = video_st->index;
816  error_code = av_interleaved_write_frame(oc, pkt);
817  }
818 #else // IS_FFMPEG_3_2
819 
820  // Encode video packet (older than FFmpeg 3.2)
821  error_code = avcodec_encode_video2(video_codec_ctx, pkt, NULL, &got_packet);
822 
823 #endif // IS_FFMPEG_3_2
824 
825  if (error_code < 0) {
827  "FFmpegWriter::flush_encoders ERROR ["
828  + av_err2string(error_code) + "]",
829  "error_code", error_code);
830  }
831  if (!got_packet) {
832  break;
833  }
834 
835  // set the timestamp
836  av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
837  pkt->stream_index = video_st->index;
838 
839  // Write packet
840  error_code = av_interleaved_write_frame(oc, pkt);
841  if (error_code < 0) {
843  "FFmpegWriter::flush_encoders ERROR ["
844  + av_err2string(error_code) + "]",
845  "error_code", error_code);
846  }
847  }
848  }
849 
850  // FLUSH AUDIO ENCODER
851  if (info.has_audio) {
852  for (;;) {
853 #if IS_FFMPEG_3_2
854  AVPacket* pkt = av_packet_alloc();
855 #else
856  AVPacket* pkt;
857  av_init_packet(pkt);
858 #endif
859  pkt->data = NULL;
860  pkt->size = 0;
861  pkt->pts = pkt->dts = audio_timestamp;
862 
863  /* encode the image */
864  int error_code = 0;
865  int got_packet = 0;
866 #if IS_FFMPEG_3_2
867  error_code = avcodec_send_frame(audio_codec_ctx, NULL);
868 #else
869  error_code = avcodec_encode_audio2(audio_codec_ctx, pkt, NULL, &got_packet);
870 #endif
871  if (error_code < 0) {
873  "FFmpegWriter::flush_encoders ERROR ["
874  + av_err2string(error_code) + "]",
875  "error_code", error_code);
876  }
877  if (!got_packet) {
878  break;
879  }
880 
881  // Since the PTS can change during encoding, set the value again. This seems like a huge hack,
882  // but it fixes lots of PTS related issues when I do this.
883  pkt->pts = pkt->dts = audio_timestamp;
884 
885  // Scale the PTS to the audio stream timebase (which is sometimes different than the codec's timebase)
886  av_packet_rescale_ts(pkt, audio_codec_ctx->time_base, audio_st->time_base);
887 
888  // set stream
889  pkt->stream_index = audio_st->index;
890  pkt->flags |= AV_PKT_FLAG_KEY;
891 
892  // Write packet
893  error_code = av_interleaved_write_frame(oc, pkt);
894  if (error_code < 0) {
896  "FFmpegWriter::flush_encoders ERROR ["
897  + av_err2string(error_code) + "]",
898  "error_code", error_code);
899  }
900 
901  // Increment PTS by duration of packet
902  audio_timestamp += pkt->duration;
903 
904  // deallocate memory for packet
905  AV_FREE_PACKET(pkt);
906  }
907  }
908 
909 }
910 
911 // Close the video codec
912 void FFmpegWriter::close_video(AVFormatContext *oc, AVStream *st)
913 {
914 #if USE_HW_ACCEL
915  if (hw_en_on && hw_en_supported) {
916  if (hw_device_ctx) {
917  av_buffer_unref(&hw_device_ctx);
918  hw_device_ctx = NULL;
919  }
920  }
921 #endif // USE_HW_ACCEL
922 
923  // Free any previous memory allocations
924  if (video_codec_ctx != nullptr) {
925  AV_FREE_CONTEXT(video_codec_ctx);
926  av_free(video_codec_ctx);
927  }
928 }
929 
930 // Close the audio codec
931 void FFmpegWriter::close_audio(AVFormatContext *oc, AVStream *st)
932 {
933  // Clear buffers
934  delete[] samples;
935  delete[] audio_outbuf;
936  delete[] audio_encoder_buffer;
937  samples = NULL;
938  audio_outbuf = NULL;
939  audio_encoder_buffer = NULL;
940 
941  // Deallocate resample buffer
942  if (avr) {
943  SWR_CLOSE(avr);
944  SWR_FREE(&avr);
945  avr = NULL;
946  }
947 
948  if (avr_planar) {
949  SWR_CLOSE(avr_planar);
950  SWR_FREE(&avr_planar);
951  avr_planar = NULL;
952  }
953 
954  // Free any previous memory allocations
955  if (audio_codec_ctx != nullptr) {
956  AV_FREE_CONTEXT(audio_codec_ctx);
957  av_free(audio_codec_ctx);
958  }
959 }
960 
961 // Close the writer
963  // Write trailer (if needed)
964  if (!write_trailer)
965  WriteTrailer();
966 
967  // Close each codec
968  if (video_st)
969  close_video(oc, video_st);
970  if (audio_st)
971  close_audio(oc, audio_st);
972 
973  // Remove single software scaler
974  if (img_convert_ctx)
975  sws_freeContext(img_convert_ctx);
976 
977  if (!(oc->oformat->flags & AVFMT_NOFILE)) {
978  /* close the output file */
979  avio_close(oc->pb);
980  }
981 
982  // Reset frame counters
983  video_timestamp = 0;
984  audio_timestamp = 0;
985 
986  // Free the context which frees the streams too
987  avformat_free_context(oc);
988  oc = NULL;
989 
990  // Close writer
991  is_open = false;
992  prepare_streams = false;
993  write_header = false;
994  write_trailer = false;
995 
996  ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::Close");
997 }
998 
999 // Add an AVFrame to the cache
1000 void FFmpegWriter::add_avframe(std::shared_ptr<Frame> frame, AVFrame *av_frame) {
1001  // Add AVFrame to map (if it does not already exist)
1002  if (!av_frames.count(frame)) {
1003  // Add av_frame
1004  av_frames[frame] = av_frame;
1005  } else {
1006  // Do not add, and deallocate this AVFrame
1007  AV_FREE_FRAME(&av_frame);
1008  }
1009 }
1010 
1011 // Add an audio output stream
1012 AVStream *FFmpegWriter::add_audio_stream() {
1013  // Find the audio codec
1014  const AVCodec *codec = avcodec_find_encoder_by_name(info.acodec.c_str());
1015  if (codec == NULL)
1016  throw InvalidCodec("A valid audio codec could not be found for this file.", path);
1017 
1018  // Free any previous memory allocations
1019  if (audio_codec_ctx != nullptr) {
1020  AV_FREE_CONTEXT(audio_codec_ctx);
1021  }
1022 
1023  // Create a new audio stream
1024  AVStream* st = avformat_new_stream(oc, codec);
1025  if (!st)
1026  throw OutOfMemory("Could not allocate memory for the audio stream.", path);
1027 
1028  // Allocate a new codec context for the stream
1029  ALLOC_CODEC_CTX(audio_codec_ctx, codec, st)
1030 #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
1031  st->codecpar->codec_id = codec->id;
1032 #endif
1033  AVCodecContext* c = audio_codec_ctx;
1034 
1035  c->codec_id = codec->id;
1036  c->codec_type = AVMEDIA_TYPE_AUDIO;
1037 
1038  // Set the sample parameters
1039  c->bit_rate = info.audio_bit_rate;
1040 #if !HAVE_CH_LAYOUT
1041  c->channels = info.channels;
1042 #endif
1043 
1044  // Set valid sample rate (or throw error)
1045  if (codec->supported_samplerates) {
1046  int i;
1047  for (i = 0; codec->supported_samplerates[i] != 0; i++)
1048  if (info.sample_rate == codec->supported_samplerates[i]) {
1049  // Set the valid sample rate
1050  c->sample_rate = info.sample_rate;
1051  break;
1052  }
1053  if (codec->supported_samplerates[i] == 0)
1054  throw InvalidSampleRate("An invalid sample rate was detected for this codec.", path);
1055  } else
1056  // Set sample rate
1057  c->sample_rate = info.sample_rate;
1058 
1059  uint64_t channel_layout = info.channel_layout;
1060 #if HAVE_CH_LAYOUT
1061  // Set a valid number of channels (or throw error)
1062  AVChannelLayout ch_layout;
1063  av_channel_layout_from_mask(&ch_layout, info.channel_layout);
1064  if (codec->ch_layouts) {
1065  int i;
1066  for (i = 0; av_channel_layout_check(&codec->ch_layouts[i]); i++)
1067  if (av_channel_layout_compare(&ch_layout, &codec->ch_layouts[i])) {
1068  // Set valid channel layout
1069  av_channel_layout_copy(&c->ch_layout, &ch_layout);
1070  break;
1071  }
1072  if (!av_channel_layout_check(&codec->ch_layouts[i]))
1073  throw InvalidChannels("An invalid channel layout was detected (i.e. MONO / STEREO).", path);
1074  } else
1075  // Set valid channel layout
1076  av_channel_layout_copy(&c->ch_layout, &ch_layout);
1077 #else
1078  // Set a valid number of channels (or throw error)
1079  if (codec->channel_layouts) {
1080  int i;
1081  for (i = 0; codec->channel_layouts[i] != 0; i++)
1082  if (channel_layout == codec->channel_layouts[i]) {
1083  // Set valid channel layout
1084  c->channel_layout = channel_layout;
1085  break;
1086  }
1087  if (codec->channel_layouts[i] == 0)
1088  throw InvalidChannels("An invalid channel layout was detected (i.e. MONO / STEREO).", path);
1089  } else
1090  // Set valid channel layout
1091  c->channel_layout = channel_layout;
1092 #endif
1093 
1094  // Choose a valid sample_fmt
1095  if (codec->sample_fmts) {
1096  for (int i = 0; codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) {
1097  // Set sample format to 1st valid format (and then exit loop)
1098  c->sample_fmt = codec->sample_fmts[i];
1099  break;
1100  }
1101  }
1102  if (c->sample_fmt == AV_SAMPLE_FMT_NONE) {
1103  // Default if no sample formats found
1104  c->sample_fmt = AV_SAMPLE_FMT_S16;
1105  }
1106 
1107  // some formats want stream headers to be separate
1108  if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1109 #if (LIBAVCODEC_VERSION_MAJOR >= 57)
1110  // FFmpeg 3.0+
1111  c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1112 #else
1113  c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1114 #endif
1115 
1117 
1118  int nb_channels;
1119  const char* nb_channels_label;
1120  const char* channel_layout_label;
1121 
1122 #if HAVE_CH_LAYOUT
1123  nb_channels = c->ch_layout.nb_channels;
1124  channel_layout = c->ch_layout.u.mask;
1125  nb_channels_label = "c->ch_layout.nb_channels";
1126  channel_layout_label = "c->ch_layout.u.mask";
1127 #else
1128  nb_channels = c->channels;
1129  nb_channels_label = "c->channels";
1130  channel_layout_label = "c->channel_layout";
1131 #endif
1132 
1134  "FFmpegWriter::add_audio_stream",
1135  "c->codec_id", c->codec_id,
1136  "c->bit_rate", c->bit_rate,
1137  nb_channels_label, nb_channels,
1138  "c->sample_fmt", c->sample_fmt,
1139  channel_layout_label, channel_layout,
1140  "c->sample_rate", c->sample_rate);
1141 
1142  return st;
1143 }
1144 
1145 // Add a video output stream
1146 AVStream *FFmpegWriter::add_video_stream() {
1147  // Find the video codec
1148  const AVCodec *codec = avcodec_find_encoder_by_name(info.vcodec.c_str());
1149  if (codec == NULL)
1150  throw InvalidCodec("A valid video codec could not be found for this file.", path);
1151 
1152  // Free any previous memory allocations
1153  if (video_codec_ctx != nullptr) {
1154  AV_FREE_CONTEXT(video_codec_ctx);
1155  }
1156 
1157  // Create a new video stream
1158  AVStream* st = avformat_new_stream(oc, codec);
1159  if (!st)
1160  throw OutOfMemory("Could not allocate memory for the video stream.", path);
1161 
1162  // Allocate a new codec context for the stream
1163  ALLOC_CODEC_CTX(video_codec_ctx, codec, st)
1164 #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
1165  st->codecpar->codec_id = codec->id;
1166 #endif
1167 
1168  AVCodecContext* c = video_codec_ctx;
1169 
1170  c->codec_id = codec->id;
1171  c->codec_type = AVMEDIA_TYPE_VIDEO;
1172 
1173  // Set sample aspect ratio
1174  c->sample_aspect_ratio.num = info.pixel_ratio.num;
1175  c->sample_aspect_ratio.den = info.pixel_ratio.den;
1176 
1177  /* Init video encoder options */
1178  if (info.video_bit_rate >= 1000
1179 #if (LIBAVCODEC_VERSION_MAJOR >= 58)
1180  && c->codec_id != AV_CODEC_ID_AV1
1181 #endif
1182  ) {
1183  c->bit_rate = info.video_bit_rate;
1184  if (info.video_bit_rate >= 1500000) {
1185  if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
1186  c->qmin = 2;
1187  c->qmax = 30;
1188  }
1189  }
1190  // Here should be the setting for low fixed bitrate
1191  // Defaults are used because mpeg2 otherwise had problems
1192  } else {
1193  // Check if codec supports crf or qp
1194  switch (c->codec_id) {
1195 #if (LIBAVCODEC_VERSION_MAJOR >= 58)
1196  // FFmpeg 4.0+
1197  case AV_CODEC_ID_AV1 :
1198  // TODO: Set `crf` or `qp` according to bitrate, as bitrate is not supported by these encoders yet.
1199  if (info.video_bit_rate >= 1000) {
1200  c->bit_rate = 0;
1201  if (strstr(info.vcodec.c_str(), "aom") != NULL) {
1202  int calculated_quality = 35;
1203  if (info.video_bit_rate < 500000) calculated_quality = 50;
1204  if (info.video_bit_rate > 5000000) calculated_quality = 10;
1205  av_opt_set_int(c->priv_data, "crf", calculated_quality, 0);
1206  info.video_bit_rate = calculated_quality;
1207  } else {
1208  int calculated_quality = 50;
1209  if (info.video_bit_rate < 500000) calculated_quality = 60;
1210  if (info.video_bit_rate > 5000000) calculated_quality = 15;
1211  av_opt_set_int(c->priv_data, "qp", calculated_quality, 0);
1212  info.video_bit_rate = calculated_quality;
1213  } // medium
1214  }
1215  if (strstr(info.vcodec.c_str(), "svtav1") != NULL) {
1216  av_opt_set_int(c->priv_data, "preset", 6, 0);
1217  av_opt_set_int(c->priv_data, "forced-idr",1,0);
1218  }
1219  else if (strstr(info.vcodec.c_str(), "rav1e") != NULL) {
1220  av_opt_set_int(c->priv_data, "speed", 7, 0);
1221  av_opt_set_int(c->priv_data, "tile-rows", 2, 0);
1222  av_opt_set_int(c->priv_data, "tile-columns", 4, 0);
1223  }
1224  else if (strstr(info.vcodec.c_str(), "aom") != NULL) {
1225  // Set number of tiles to a fixed value
1226  // TODO: Allow user to chose their own number of tiles
1227  av_opt_set_int(c->priv_data, "tile-rows", 1, 0); // log2 of number of rows
1228  av_opt_set_int(c->priv_data, "tile-columns", 2, 0); // log2 of number of columns
1229  av_opt_set_int(c->priv_data, "row-mt", 1, 0); // use multiple cores
1230  av_opt_set_int(c->priv_data, "cpu-used", 3, 0); // default is 1, usable is 4
1231  }
1232  //break;
1233 #endif
1234  case AV_CODEC_ID_VP9 :
1235  case AV_CODEC_ID_HEVC :
1236  case AV_CODEC_ID_VP8 :
1237  case AV_CODEC_ID_H264 :
1238  if (info.video_bit_rate < 40) {
1239  c->qmin = 0;
1240  c->qmax = 63;
1241  } else {
1242  c->qmin = info.video_bit_rate - 5;
1243  c->qmax = 63;
1244  }
1245  break;
1246  default:
1247  // Here should be the setting for codecs that don't support crf
1248  // For now defaults are used
1249  break;
1250  }
1251  }
1252 
1253  //TODO: Implement variable bitrate feature (which actually works). This implementation throws
1254  //invalid bitrate errors and rc buffer underflow errors, etc...
1255  //c->rc_min_rate = info.video_bit_rate;
1256  //c->rc_max_rate = info.video_bit_rate;
1257  //c->rc_buffer_size = FFMAX(c->rc_max_rate, 15000000) * 112L / 15000000 * 16384;
1258  //if ( !c->rc_initial_buffer_occupancy )
1259  // c->rc_initial_buffer_occupancy = c->rc_buffer_size * 3/4;
1260 
1261  /* resolution must be a multiple of two */
1262  // TODO: require /2 height and width
1263  c->width = info.width;
1264  c->height = info.height;
1265 
1266  /* time base: this is the fundamental unit of time (in seconds) in terms
1267  of which frame timestamps are represented. for fixed-fps content,
1268  timebase should be 1/framerate and timestamp increments should be
1269  identically 1. */
1270  c->time_base.num = info.video_timebase.num;
1271  c->time_base.den = info.video_timebase.den;
1272 // AVCodecContext->framerate was added in FFmpeg 2.6
1273 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 26, 0)
1274  c->framerate = av_inv_q(c->time_base);
1275 #endif
1276  st->avg_frame_rate = av_inv_q(c->time_base);
1277  st->time_base.num = info.video_timebase.num;
1278  st->time_base.den = info.video_timebase.den;
1279 
1280  c->gop_size = 12; /* TODO: add this to "info"... emit one intra frame every twelve frames at most */
1281  c->max_b_frames = 10;
1282  if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO)
1283  /* just for testing, we also add B frames */
1284  c->max_b_frames = 2;
1285  if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO)
1286  /* Needed to avoid using macroblocks in which some coeffs overflow.
1287  This does not happen with normal video, it just happens here as
1288  the motion of the chroma plane does not match the luma plane. */
1289  c->mb_decision = 2;
1290  // some formats want stream headers to be separate
1291  if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1292 #if (LIBAVCODEC_VERSION_MAJOR >= 57)
1293  // FFmpeg 3.0+
1294  c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1295 #else
1296  c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1297 #endif
1298 
1299  // Find all supported pixel formats for this codec
1300  const PixelFormat *supported_pixel_formats = codec->pix_fmts;
1301  while (supported_pixel_formats != NULL && *supported_pixel_formats != PIX_FMT_NONE) {
1302  // Assign the 1st valid pixel format (if one is missing)
1303  if (c->pix_fmt == PIX_FMT_NONE)
1304  c->pix_fmt = *supported_pixel_formats;
1305  ++supported_pixel_formats;
1306  }
1307 
1308  // Codec doesn't have any pix formats?
1309  if (c->pix_fmt == PIX_FMT_NONE) {
1310  if (oc->oformat->video_codec == AV_CODEC_ID_RAWVIDEO) {
1311  // Raw video should use RGB24
1312  c->pix_fmt = PIX_FMT_RGB24;
1313 
1314 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
1315  // FFmpeg < 4.0
1316  if (strcmp(oc->oformat->name, "gif") != 0)
1317  // If not GIF format, skip the encoding process
1318  // Set raw picture flag (so we don't encode this video)
1319  oc->oformat->flags |= AVFMT_RAWPICTURE;
1320 #endif
1321  } else {
1322  // Set the default codec
1323  c->pix_fmt = PIX_FMT_YUV420P;
1324  }
1325  }
1326 
1329  "FFmpegWriter::add_video_stream ("
1330  + (std::string)oc->oformat->name + " : "
1331  + (std::string)av_get_pix_fmt_name(c->pix_fmt) + ")",
1332  "c->codec_id", c->codec_id,
1333  "c->bit_rate", c->bit_rate,
1334  "c->pix_fmt", c->pix_fmt,
1335  "oc->oformat->flags", oc->oformat->flags);
1336  return st;
1337 }
1338 
1339 // open audio codec
1340 void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st) {
1341  const AVCodec *codec;
1342  AV_GET_CODEC_FROM_STREAM(st, audio_codec_ctx)
1343 
1344  // Audio encoding does not typically use more than 2 threads (most codecs use 1 thread)
1345  audio_codec_ctx->thread_count = std::min(FF_AUDIO_NUM_PROCESSORS, 2);
1346 
1347  // Find the audio encoder
1348  codec = avcodec_find_encoder_by_name(info.acodec.c_str());
1349  if (!codec)
1350  codec = avcodec_find_encoder(audio_codec_ctx->codec_id);
1351  if (!codec)
1352  throw InvalidCodec("Could not find codec", path);
1353 
1354  // Init options
1355  AVDictionary *opts = NULL;
1356  av_dict_set(&opts, "strict", "experimental", 0);
1357 
1358  // Open the codec
1359  if (avcodec_open2(audio_codec_ctx, codec, &opts) < 0)
1360  throw InvalidCodec("Could not open audio codec", path);
1361  AV_COPY_PARAMS_FROM_CONTEXT(st, audio_codec_ctx);
1362 
1363  // Free options
1364  av_dict_free(&opts);
1365 
1366  // Calculate the size of the input frame (i..e how many samples per packet), and the output buffer
1367  // TODO: Ugly hack for PCM codecs (will be removed ASAP with new PCM support to compute the input frame size in samples
1368  if (audio_codec_ctx->frame_size <= 1) {
1369  // No frame size found... so calculate
1370  audio_input_frame_size = 50000 / info.channels;
1371 
1372  int s = AV_FIND_DECODER_CODEC_ID(st);
1373  switch (s) {
1374  case AV_CODEC_ID_PCM_S16LE:
1375  case AV_CODEC_ID_PCM_S16BE:
1376  case AV_CODEC_ID_PCM_U16LE:
1377  case AV_CODEC_ID_PCM_U16BE:
1378  audio_input_frame_size >>= 1;
1379  break;
1380  default:
1381  break;
1382  }
1383  } else {
1384  // Set frame size based on the codec
1385  audio_input_frame_size = audio_codec_ctx->frame_size;
1386  }
1387 
1388  // Set the initial frame size (since it might change during resampling)
1389  initial_audio_input_frame_size = audio_input_frame_size;
1390 
1391  // Allocate array for samples
1392  samples = new int16_t[AVCODEC_MAX_AUDIO_FRAME_SIZE];
1393 
1394  // Set audio output buffer (used to store the encoded audio)
1395  audio_outbuf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
1396  audio_outbuf = new uint8_t[audio_outbuf_size];
1397 
1398  // Set audio packet encoding buffer
1399  audio_encoder_buffer_size = AUDIO_PACKET_ENCODING_SIZE;
1400  audio_encoder_buffer = new uint8_t[audio_encoder_buffer_size];
1401 
1402  // Add audio metadata (if any)
1403  for (std::map<std::string, std::string>::iterator iter = info.metadata.begin(); iter != info.metadata.end(); ++iter) {
1404  av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1405  }
1406 
1408  "FFmpegWriter::open_audio",
1409  "audio_codec_ctx->thread_count", audio_codec_ctx->thread_count,
1410  "audio_input_frame_size", audio_input_frame_size,
1412 }
1413 
1414 // open video codec
1415 void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) {
1416  const AVCodec *codec;
1417  AV_GET_CODEC_FROM_STREAM(st, video_codec_ctx)
1418 
1419  // Set number of threads equal to number of processors (not to exceed 16, FFmpeg doesn't recommend more than 16)
1420  video_codec_ctx->thread_count = std::min(FF_VIDEO_NUM_PROCESSORS, 16);
1421 
1422 #if USE_HW_ACCEL
1423  if (hw_en_on && hw_en_supported) {
1424  //char *dev_hw = NULL;
1425  char adapter[256];
1426  char *adapter_ptr = NULL;
1427  int adapter_num;
1428  // Use the hw device given in the environment variable HW_EN_DEVICE_SET or the default if not set
1430  std::clog << "Encoding Device Nr: " << adapter_num << "\n";
1431  if (adapter_num < 3 && adapter_num >=0) {
1432 #if defined(__linux__)
1433  snprintf(adapter,sizeof(adapter),"/dev/dri/renderD%d", adapter_num+128);
1434  // Maybe 127 is better because the first card would be 1?!
1435  adapter_ptr = adapter;
1436 #elif defined(_WIN32) || defined(__APPLE__)
1437  adapter_ptr = NULL;
1438 #endif
1439  }
1440  else {
1441  adapter_ptr = NULL; // Just to be sure
1442  }
1443 // Check if it is there and writable
1444 #if defined(__linux__)
1445  if( adapter_ptr != NULL && access( adapter_ptr, W_OK ) == 0 ) {
1446 #elif defined(_WIN32) || defined(__APPLE__)
1447  if( adapter_ptr != NULL ) {
1448 #endif
1450  "Encode Device present using device",
1451  "adapter", adapter_num);
1452  }
1453  else {
1454  adapter_ptr = NULL; // use default
1456  "Encode Device not present, using default");
1457  }
1458  if (av_hwdevice_ctx_create(&hw_device_ctx,
1459  hw_en_av_device_type, adapter_ptr, NULL, 0) < 0)
1460  {
1462  "FFmpegWriter::open_video ERROR creating hwdevice, Codec name:",
1463  info.vcodec.c_str(), -1);
1464  throw InvalidCodec("Could not create hwdevice", path);
1465  }
1466  }
1467 #endif // USE_HW_ACCEL
1468 
1469  /* find the video encoder */
1470  codec = avcodec_find_encoder_by_name(info.vcodec.c_str());
1471  if (!codec)
1472  codec = avcodec_find_encoder(AV_FIND_DECODER_CODEC_ID(st));
1473  if (!codec)
1474  throw InvalidCodec("Could not find codec", path);
1475 
1476  /* Legacy behavior: force max_b_frames to 0 for many codecs.
1477  * This can be disabled via SetOption(VIDEO_STREAM, "allow_b_frames", "1"). */
1478  if (!allow_b_frames && video_codec_ctx->max_b_frames &&
1479  video_codec_ctx->codec_id != AV_CODEC_ID_MPEG4 &&
1480  video_codec_ctx->codec_id != AV_CODEC_ID_MPEG1VIDEO &&
1481  video_codec_ctx->codec_id != AV_CODEC_ID_MPEG2VIDEO)
1482  video_codec_ctx->max_b_frames = 0;
1483 
1484  // Init options
1485  AVDictionary *opts = NULL;
1486  av_dict_set(&opts, "strict", "experimental", 0);
1487 
1488 #if USE_HW_ACCEL
1490  video_codec_ctx->pix_fmt = hw_en_av_pix_fmt;
1491 
1492  // for the list of possible options, see the list of codec-specific options:
1493  // e.g. ffmpeg -h encoder=h264_vaapi or ffmpeg -h encoder=hevc_vaapi
1494  // and "man ffmpeg-codecs"
1495 
1496  // For VAAPI, it is safer to explicitly set rc_mode instead of relying on auto-selection
1497  // which is ffmpeg version-specific.
1498  if (hw_en_av_pix_fmt == AV_PIX_FMT_VAAPI) {
1499  int64_t qp;
1500  if (av_opt_get_int(video_codec_ctx->priv_data, "qp", 0, &qp) != 0 || qp == 0) {
1501  // unless "qp" was set for CQP, switch to VBR RC mode
1502  av_opt_set(video_codec_ctx->priv_data, "rc_mode", "VBR", 0);
1503 
1504  // In the current state (ffmpeg-4.2-4 libva-mesa-driver-19.1.5-1) to use VBR,
1505  // one has to specify both bit_rate and maxrate, otherwise a small low quality file is generated on Intel iGPU).
1506  video_codec_ctx->rc_max_rate = video_codec_ctx->bit_rate;
1507  }
1508  }
1509 
1510  switch (video_codec_ctx->codec_id) {
1511  case AV_CODEC_ID_H264:
1512  video_codec_ctx->max_b_frames = 0; // At least this GPU doesn't support b-frames
1513  video_codec_ctx->profile = FF_PROFILE_H264_BASELINE | FF_PROFILE_H264_CONSTRAINED;
1514  av_opt_set(video_codec_ctx->priv_data, "preset", "slow", 0);
1515  av_opt_set(video_codec_ctx->priv_data, "tune", "zerolatency", 0);
1516  av_opt_set(video_codec_ctx->priv_data, "vprofile", "baseline", AV_OPT_SEARCH_CHILDREN);
1517  break;
1518  case AV_CODEC_ID_HEVC:
1519  // tested to work with defaults
1520  break;
1521  case AV_CODEC_ID_VP9:
1522  // tested to work with defaults
1523  break;
1524  default:
1526  "No codec-specific options defined for this codec. HW encoding may fail",
1527  "codec_id", video_codec_ctx->codec_id);
1528  break;
1529  }
1530 
1531  // set hw_frames_ctx for encoder's AVCodecContext
1532  int err;
1533  if ((err = set_hwframe_ctx(video_codec_ctx, hw_device_ctx, info.width, info.height)) < 0)
1534  {
1536  "FFmpegWriter::open_video (set_hwframe_ctx) ERROR faled to set hwframe context",
1537  "width", info.width,
1538  "height", info.height,
1539  av_err2string(err), -1);
1540  }
1541  }
1542 #endif // USE_HW_ACCEL
1543 
1544 // Set libx265 hvc1 tag (for Apple playback compatibility).
1545 #if USE_HW_ACCEL
1546  if (!(hw_en_on && hw_en_supported) && video_codec_ctx->codec_id == AV_CODEC_ID_HEVC) {
1547  video_codec_ctx->codec_tag = MKTAG('h', 'v', 'c', '1');
1548  }
1549 #else
1550  if (video_codec_ctx->codec_id == AV_CODEC_ID_HEVC) {
1551  video_codec_ctx->codec_tag = MKTAG('h', 'v', 'c', '1');
1552  }
1553 #endif
1554 
1555  /* open the codec */
1556  if (avcodec_open2(video_codec_ctx, codec, &opts) < 0)
1557  throw InvalidCodec("Could not open video codec", path);
1558  AV_COPY_PARAMS_FROM_CONTEXT(st, video_codec_ctx);
1559 
1560  // Free options
1561  av_dict_free(&opts);
1562 
1563  // Add video metadata (if any)
1564  for (auto iter = info.metadata.begin(); iter != info.metadata.end(); ++iter) {
1565  av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1566  }
1567 
1569  "FFmpegWriter::open_video",
1570  "video_codec_ctx->thread_count", video_codec_ctx->thread_count);
1571 
1572 }
1573 
1574 // write all queued frames' audio to the video file
1575 void FFmpegWriter::write_audio_packets(bool is_final, std::shared_ptr<openshot::Frame> frame) {
1576  if (!frame && !is_final)
1577  return;
1578 
1579  // Init audio buffers / variables
1580  int total_frame_samples = 0;
1581  int frame_position = 0;
1582  int channels_in_frame = 0;
1583  int sample_rate_in_frame = 0;
1584  int samples_in_frame = 0;
1585  ChannelLayout channel_layout_in_frame = LAYOUT_MONO; // default channel layout
1586 
1587  // Create a new array (to hold all S16 audio samples, for the current queued frames
1588  unsigned int all_queued_samples_size = sizeof(int16_t) * AVCODEC_MAX_AUDIO_FRAME_SIZE;
1589  int16_t *all_queued_samples = (int16_t *) av_malloc(all_queued_samples_size);
1590  int16_t *all_resampled_samples = NULL;
1591  int16_t *final_samples_planar = NULL;
1592  int16_t *final_samples = NULL;
1593 
1594  // Get audio sample array
1595  float *frame_samples_float = NULL;
1596 
1597  // Get the audio details from this frame
1598  if (frame) {
1599  sample_rate_in_frame = frame->SampleRate();
1600  samples_in_frame = frame->GetAudioSamplesCount();
1601  channels_in_frame = frame->GetAudioChannelsCount();
1602  channel_layout_in_frame = frame->ChannelsLayout();
1603 
1604  // Get samples interleaved together (c1 c2 c1 c2 c1 c2)
1605  frame_samples_float = frame->GetInterleavedAudioSamples(&samples_in_frame);
1606  }
1607 
1608  // Calculate total samples
1609  total_frame_samples = samples_in_frame * channels_in_frame;
1610 
1611  // Translate audio sample values back to 16 bit integers with saturation
1612  const int16_t max16 = 32767;
1613  const int16_t min16 = -32768;
1614  for (int s = 0; s < total_frame_samples; s++, frame_position++) {
1615  float valF = frame_samples_float[s] * (1 << 15);
1616  int16_t conv;
1617  if (valF > max16) {
1618  conv = max16;
1619  } else if (valF < min16) {
1620  conv = min16;
1621  } else {
1622  conv = int(valF + 32768.5) - 32768; // +0.5 is for rounding
1623  }
1624 
1625  // Copy into buffer
1626  all_queued_samples[frame_position] = conv;
1627  }
1628 
1629  // Deallocate float array
1630  delete[] frame_samples_float;
1631 
1632 
1633  // Update total samples (since we've combined all queued frames)
1634  total_frame_samples = frame_position;
1635  int remaining_frame_samples = total_frame_samples;
1636  int samples_position = 0;
1637 
1638 
1640  "FFmpegWriter::write_audio_packets",
1641  "is_final", is_final,
1642  "total_frame_samples", total_frame_samples,
1643  "channel_layout_in_frame", channel_layout_in_frame,
1644  "channels_in_frame", channels_in_frame,
1645  "samples_in_frame", samples_in_frame,
1646  "LAYOUT_MONO", LAYOUT_MONO);
1647 
1648  // Keep track of the original sample format
1649  AVSampleFormat output_sample_fmt = audio_codec_ctx->sample_fmt;
1650 
1651  AVFrame *audio_frame = NULL;
1652  if (!is_final) {
1653  // Create input frame (and allocate arrays)
1654  audio_frame = AV_ALLOCATE_FRAME();
1655  AV_RESET_FRAME(audio_frame);
1656  audio_frame->nb_samples = total_frame_samples / channels_in_frame;
1657 
1658  // Fill input frame with sample data
1659  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);
1660  if (error_code < 0) {
1662  "FFmpegWriter::write_audio_packets ERROR ["
1663  + av_err2string(error_code) + "]",
1664  "error_code", error_code);
1665  }
1666 
1667  // Do not convert audio to planar format (yet). We need to keep everything interleaved at this point.
1668  switch (audio_codec_ctx->sample_fmt) {
1669  case AV_SAMPLE_FMT_FLTP: {
1670  output_sample_fmt = AV_SAMPLE_FMT_FLT;
1671  break;
1672  }
1673  case AV_SAMPLE_FMT_S32P: {
1674  output_sample_fmt = AV_SAMPLE_FMT_S32;
1675  break;
1676  }
1677  case AV_SAMPLE_FMT_S16P: {
1678  output_sample_fmt = AV_SAMPLE_FMT_S16;
1679  break;
1680  }
1681  case AV_SAMPLE_FMT_U8P: {
1682  output_sample_fmt = AV_SAMPLE_FMT_U8;
1683  break;
1684  }
1685  default: {
1686  // This is only here to silence unused-enum warnings
1687  break;
1688  }
1689  }
1690 
1691  // Update total samples & input frame size (due to bigger or smaller data types)
1692  total_frame_samples *= (float(info.sample_rate) / sample_rate_in_frame); // adjust for different byte sizes
1693  total_frame_samples *= (float(info.channels) / channels_in_frame); // adjust for different # of channels
1694 
1695  // Create output frame (and allocate arrays)
1696  AVFrame *audio_converted = AV_ALLOCATE_FRAME();
1697  AV_RESET_FRAME(audio_converted);
1698  audio_converted->nb_samples = total_frame_samples / channels_in_frame;
1699  av_samples_alloc(audio_converted->data, audio_converted->linesize, info.channels, audio_converted->nb_samples, output_sample_fmt, 0);
1700 
1702  "FFmpegWriter::write_audio_packets (1st resampling)",
1703  "in_sample_fmt", AV_SAMPLE_FMT_S16,
1704  "out_sample_fmt", output_sample_fmt,
1705  "in_sample_rate", sample_rate_in_frame,
1706  "out_sample_rate", info.sample_rate,
1707  "in_channels", channels_in_frame,
1708  "out_channels", info.channels);
1709 
1710  // setup resample context
1711  if (!avr) {
1712  avr = SWR_ALLOC();
1713 #if HAVE_CH_LAYOUT
1714  AVChannelLayout in_chlayout;
1715  AVChannelLayout out_chlayout;
1716  av_channel_layout_from_mask(&in_chlayout, channel_layout_in_frame);
1717  av_channel_layout_from_mask(&out_chlayout, info.channel_layout);
1718  av_opt_set_chlayout(avr, "in_chlayout", &in_chlayout, 0);
1719  av_opt_set_chlayout(avr, "out_chlayout", &out_chlayout, 0);
1720 #else
1721  av_opt_set_int(avr, "in_channel_layout", channel_layout_in_frame, 0);
1722  av_opt_set_int(avr, "out_channel_layout", info.channel_layout, 0);
1723  av_opt_set_int(avr, "in_channels", channels_in_frame, 0);
1724  av_opt_set_int(avr, "out_channels", info.channels, 0);
1725 #endif
1726  av_opt_set_int(avr, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
1727  av_opt_set_int(avr, "out_sample_fmt", output_sample_fmt, 0); // planar not allowed here
1728  av_opt_set_int(avr, "in_sample_rate", sample_rate_in_frame, 0);
1729  av_opt_set_int(avr, "out_sample_rate", info.sample_rate, 0);
1730  SWR_INIT(avr);
1731  }
1732  // Convert audio samples
1733  int nb_samples = SWR_CONVERT(
1734  avr, // audio resample context
1735  audio_converted->data, // output data pointers
1736  audio_converted->linesize[0], // output plane size, in bytes. (0 if unknown)
1737  audio_converted->nb_samples, // maximum number of samples that the output buffer can hold
1738  audio_frame->data, // input data pointers
1739  audio_frame->linesize[0], // input plane size, in bytes (0 if unknown)
1740  audio_frame->nb_samples // number of input samples to convert
1741  );
1742 
1743  // Set remaining samples
1744  remaining_frame_samples = total_frame_samples;
1745 
1746  // Create a new array (to hold all resampled S16 audio samples)
1747  all_resampled_samples = (int16_t *) av_malloc(
1748  sizeof(int16_t) * nb_samples * info.channels
1749  * (av_get_bytes_per_sample(output_sample_fmt) /
1750  av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1751  );
1752 
1753  // Copy audio samples over original samples
1754  memcpy(all_resampled_samples, audio_converted->data[0],
1755  static_cast<size_t>(nb_samples)
1756  * info.channels
1757  * av_get_bytes_per_sample(output_sample_fmt));
1758 
1759  // Remove converted audio
1760  av_freep(&(audio_frame->data[0]));
1761  AV_FREE_FRAME(&audio_frame);
1762  av_freep(&audio_converted->data[0]);
1763  AV_FREE_FRAME(&audio_converted);
1764  all_queued_samples = NULL; // this array cleared with above call
1765 
1767  "FFmpegWriter::write_audio_packets (Successfully completed 1st resampling)",
1768  "nb_samples", nb_samples,
1769  "remaining_frame_samples", remaining_frame_samples);
1770  }
1771 
1772  // Loop until no more samples
1773  while (remaining_frame_samples > 0 || is_final) {
1774  // Get remaining samples needed for this packet
1775  int remaining_packet_samples = (audio_input_frame_size * info.channels) - audio_input_position;
1776 
1777  // Determine how many samples we need
1778  int diff = 0;
1779  if (remaining_frame_samples >= remaining_packet_samples) {
1780  diff = remaining_packet_samples;
1781  } else {
1782  diff = remaining_frame_samples;
1783  }
1784 
1785  // Copy frame samples into the packet samples array
1786  if (!is_final)
1787  //TODO: Make this more sane
1788  memcpy(
1789  samples + (audio_input_position
1790  * (av_get_bytes_per_sample(output_sample_fmt) /
1791  av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1792  ),
1793  all_resampled_samples + samples_position,
1794  static_cast<size_t>(diff)
1795  * av_get_bytes_per_sample(output_sample_fmt)
1796  );
1797 
1798  // Increment counters
1799  audio_input_position += diff;
1800  samples_position += diff * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16));
1801  remaining_frame_samples -= diff;
1802 
1803  // Do we have enough samples to proceed?
1804  if (audio_input_position < (audio_input_frame_size * info.channels) && !is_final)
1805  // Not enough samples to encode... so wait until the next frame
1806  break;
1807 
1808  // Convert to planar (if needed by audio codec)
1809  AVFrame *frame_final = AV_ALLOCATE_FRAME();
1810  AV_RESET_FRAME(frame_final);
1811  if (av_sample_fmt_is_planar(audio_codec_ctx->sample_fmt)) {
1813  "FFmpegWriter::write_audio_packets (2nd resampling for Planar formats)",
1814  "in_sample_fmt", output_sample_fmt,
1815  "out_sample_fmt", audio_codec_ctx->sample_fmt,
1816  "in_sample_rate", info.sample_rate,
1817  "out_sample_rate", info.sample_rate,
1818  "in_channels", info.channels,
1819  "out_channels", info.channels
1820  );
1821 
1822  // setup resample context
1823  if (!avr_planar) {
1824  avr_planar = SWR_ALLOC();
1825 #if HAVE_CH_LAYOUT
1826  AVChannelLayout layout;
1827  av_channel_layout_from_mask(&layout, info.channel_layout);
1828  av_opt_set_chlayout(avr_planar, "in_chlayout", &layout, 0);
1829  av_opt_set_chlayout(avr_planar, "out_chlayout", &layout, 0);
1830 #else
1831  av_opt_set_int(avr_planar, "in_channel_layout", info.channel_layout, 0);
1832  av_opt_set_int(avr_planar, "out_channel_layout", info.channel_layout, 0);
1833  av_opt_set_int(avr_planar, "in_channels", info.channels, 0);
1834  av_opt_set_int(avr_planar, "out_channels", info.channels, 0);
1835 #endif
1836  av_opt_set_int(avr_planar, "in_sample_fmt", output_sample_fmt, 0);
1837  av_opt_set_int(avr_planar, "out_sample_fmt", audio_codec_ctx->sample_fmt, 0); // planar not allowed here
1838  av_opt_set_int(avr_planar, "in_sample_rate", info.sample_rate, 0);
1839  av_opt_set_int(avr_planar, "out_sample_rate", info.sample_rate, 0);
1840  SWR_INIT(avr_planar);
1841  }
1842 
1843  // Create input frame (and allocate arrays)
1844  audio_frame = AV_ALLOCATE_FRAME();
1845  AV_RESET_FRAME(audio_frame);
1846  audio_frame->nb_samples = audio_input_position / info.channels;
1847 
1848  // Create a new array
1849  final_samples_planar = (int16_t *) av_malloc(
1850  sizeof(int16_t) * audio_frame->nb_samples * info.channels
1851  * (av_get_bytes_per_sample(output_sample_fmt) /
1852  av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1853  );
1854 
1855  // Copy audio into buffer for frame
1856  memcpy(final_samples_planar, samples,
1857  static_cast<size_t>(audio_frame->nb_samples)
1858  * info.channels
1859  * av_get_bytes_per_sample(output_sample_fmt));
1860 
1861  // Fill input frame with sample data
1862  avcodec_fill_audio_frame(audio_frame, info.channels, output_sample_fmt,
1863  (uint8_t *) final_samples_planar, audio_encoder_buffer_size, 0);
1864 
1865  // Create output frame (and allocate arrays)
1866  frame_final->nb_samples = audio_input_frame_size;
1867 #if HAVE_CH_LAYOUT
1868  av_channel_layout_from_mask(&frame_final->ch_layout, info.channel_layout);
1869 #else
1870  frame_final->channels = info.channels;
1871  frame_final->channel_layout = info.channel_layout;
1872 #endif
1873  frame_final->format = audio_codec_ctx->sample_fmt;
1874  av_samples_alloc(frame_final->data, frame_final->linesize, info.channels,
1875  frame_final->nb_samples, audio_codec_ctx->sample_fmt, 0);
1876 
1877  // Convert audio samples
1878  int nb_samples = SWR_CONVERT(
1879  avr_planar, // audio resample context
1880  frame_final->data, // output data pointers
1881  frame_final->linesize[0], // output plane size, in bytes. (0 if unknown)
1882  frame_final->nb_samples, // maximum number of samples that the output buffer can hold
1883  audio_frame->data, // input data pointers
1884  audio_frame->linesize[0], // input plane size, in bytes (0 if unknown)
1885  audio_frame->nb_samples // number of input samples to convert
1886  );
1887 
1888  // Copy audio samples over original samples
1889  const auto copy_length = static_cast<size_t>(nb_samples)
1890  * av_get_bytes_per_sample(audio_codec_ctx->sample_fmt)
1891  * info.channels;
1892 
1893  if (nb_samples > 0)
1894  memcpy(samples, frame_final->data[0], copy_length);
1895 
1896  // deallocate AVFrame
1897  av_freep(&(audio_frame->data[0]));
1898  AV_FREE_FRAME(&audio_frame);
1899  all_queued_samples = NULL; // this array cleared with above call
1900 
1902  "FFmpegWriter::write_audio_packets (Successfully completed 2nd resampling for Planar formats)",
1903  "nb_samples", nb_samples);
1904 
1905  } else {
1906  // Create a new array
1907  const auto buf_size = static_cast<size_t>(audio_input_position)
1908  * (av_get_bytes_per_sample(audio_codec_ctx->sample_fmt) /
1909  av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)
1910  );
1911  final_samples = reinterpret_cast<int16_t*>(
1912  av_malloc(sizeof(int16_t) * buf_size));
1913 
1914  // Copy audio into buffer for frame
1915  memcpy(final_samples, samples,
1916  audio_input_position * av_get_bytes_per_sample(audio_codec_ctx->sample_fmt));
1917 
1918  // Init the nb_samples property
1919  frame_final->nb_samples = audio_input_frame_size;
1920 
1921  // Fill the final_frame AVFrame with audio (non planar)
1922 #if HAVE_CH_LAYOUT
1923  int nb_channels = audio_codec_ctx->ch_layout.nb_channels;
1924 #else
1925  int nb_channels = audio_codec_ctx->channels;
1926 #endif
1927  avcodec_fill_audio_frame(frame_final, nb_channels,
1928  audio_codec_ctx->sample_fmt, (uint8_t *) final_samples,
1929  audio_encoder_buffer_size, 0);
1930  }
1931 
1932  // Set the AVFrame's PTS
1933  frame_final->pts = audio_timestamp;
1934 
1935  // Init the packet
1936 #if IS_FFMPEG_3_2
1937  AVPacket* pkt = av_packet_alloc();
1938 #else
1939  AVPacket* pkt;
1940  av_init_packet(pkt);
1941 #endif
1942  pkt->data = audio_encoder_buffer;
1943  pkt->size = audio_encoder_buffer_size;
1944 
1945  // Set the packet's PTS prior to encoding
1946  pkt->pts = pkt->dts = audio_timestamp;
1947 
1948  /* encode the audio samples */
1949  int got_packet_ptr = 0;
1950 
1951 #if IS_FFMPEG_3_2
1952  // Encode audio (latest version of FFmpeg)
1953  int error_code;
1954  int ret = 0;
1955  int frame_finished = 0;
1956  error_code = ret = avcodec_send_frame(audio_codec_ctx, frame_final);
1957  if (ret < 0 && ret != AVERROR(EINVAL) && ret != AVERROR_EOF) {
1958  avcodec_send_frame(audio_codec_ctx, NULL);
1959  }
1960  else {
1961  if (ret >= 0)
1962  pkt->size = 0;
1963  ret = avcodec_receive_packet(audio_codec_ctx, pkt);
1964  if (ret >= 0)
1965  frame_finished = 1;
1966  if(ret == AVERROR(EINVAL) || ret == AVERROR_EOF) {
1967  avcodec_flush_buffers(audio_codec_ctx);
1968  ret = 0;
1969  }
1970  if (ret >= 0) {
1971  ret = frame_finished;
1972  }
1973  }
1974  if (!pkt->data && !frame_finished)
1975  {
1976  ret = -1;
1977  }
1978  got_packet_ptr = ret;
1979 #else
1980  // Encode audio (older versions of FFmpeg)
1981  int error_code = avcodec_encode_audio2(audio_codec_ctx, pkt, frame_final, &got_packet_ptr);
1982 #endif
1983  /* if zero size, it means the image was buffered */
1984  if (error_code == 0 && got_packet_ptr) {
1985 
1986  // Since the PTS can change during encoding, set the value again. This seems like a huge hack,
1987  // but it fixes lots of PTS related issues when I do this.
1988  pkt->pts = pkt->dts = audio_timestamp;
1989 
1990  // Scale the PTS to the audio stream timebase (which is sometimes different than the codec's timebase)
1991  av_packet_rescale_ts(pkt, audio_codec_ctx->time_base, audio_st->time_base);
1992 
1993  // set stream
1994  pkt->stream_index = audio_st->index;
1995  pkt->flags |= AV_PKT_FLAG_KEY;
1996 
1997  /* write the compressed frame in the media file */
1998  error_code = av_interleaved_write_frame(oc, pkt);
1999  }
2000 
2001  if (error_code < 0) {
2003  "FFmpegWriter::write_audio_packets ERROR ["
2004  + av_err2string(error_code) + "]",
2005  "error_code", error_code);
2006  }
2007 
2008  // Increment PTS (no pkt.duration, so calculate with maths)
2009  audio_timestamp += FFMIN(audio_input_frame_size, audio_input_position);
2010 
2011  // deallocate AVFrame
2012  av_freep(&(frame_final->data[0]));
2013  AV_FREE_FRAME(&frame_final);
2014 
2015  // deallocate memory for packet
2016  AV_FREE_PACKET(pkt);
2017 
2018  // Reset position
2019  audio_input_position = 0;
2020  is_final = false;
2021  }
2022 
2023  // Delete arrays (if needed)
2024  if (all_resampled_samples) {
2025  av_freep(&all_resampled_samples);
2026  all_resampled_samples = NULL;
2027  }
2028  if (all_queued_samples) {
2029  av_freep(&all_queued_samples);
2030  all_queued_samples = NULL;
2031  }
2032 }
2033 
2034 // Allocate an AVFrame object
2035 AVFrame *FFmpegWriter::allocate_avframe(PixelFormat pix_fmt, int width, int height, int *buffer_size, uint8_t *new_buffer) {
2036  // Create an RGB AVFrame
2037  AVFrame *new_av_frame = NULL;
2038 
2039  // Allocate an AVFrame structure
2040  new_av_frame = AV_ALLOCATE_FRAME();
2041  if (new_av_frame == NULL)
2042  throw OutOfMemory("Could not allocate AVFrame", path);
2043 
2044  // Determine required buffer size and allocate buffer
2045  *buffer_size = AV_GET_IMAGE_SIZE(pix_fmt, width, height);
2046 
2047  // Create buffer (if not provided)
2048  if (!new_buffer) {
2049  // New Buffer
2050  new_buffer = (uint8_t *) av_malloc(*buffer_size * sizeof(uint8_t));
2051  // Attach buffer to AVFrame
2052  AV_COPY_PICTURE_DATA(new_av_frame, new_buffer, pix_fmt, width, height);
2053  new_av_frame->width = width;
2054  new_av_frame->height = height;
2055  new_av_frame->format = pix_fmt;
2056  }
2057 
2058  // return AVFrame
2059  return new_av_frame;
2060 }
2061 
2062 // process video frame
2063 void FFmpegWriter::process_video_packet(std::shared_ptr<Frame> frame) {
2064  // Source dimensions (RGBA)
2065  int src_w = frame->GetWidth();
2066  int src_h = frame->GetHeight();
2067 
2068  // Skip empty frames (1×1)
2069  if (src_w == 1 && src_h == 1)
2070  return;
2071 
2072  // Point persistent_src_frame->data to RGBA pixels
2073  const uchar* pixels = frame->GetPixels();
2074  if (!persistent_src_frame) {
2075  persistent_src_frame = av_frame_alloc();
2076  if (!persistent_src_frame)
2077  throw OutOfMemory("Could not allocate persistent_src_frame", path);
2078  persistent_src_frame->format = AV_PIX_FMT_RGBA;
2079  persistent_src_frame->width = src_w;
2080  persistent_src_frame->height = src_h;
2081  persistent_src_frame->linesize[0] = src_w * 4;
2082  }
2083  persistent_src_frame->data[0] = const_cast<uint8_t*>(
2084  reinterpret_cast<const uint8_t*>(pixels)
2085  );
2086 
2087  // Prepare persistent_dst_frame + buffer on first use
2088  if (!persistent_dst_frame) {
2089  persistent_dst_frame = av_frame_alloc();
2090  if (!persistent_dst_frame)
2091  throw OutOfMemory("Could not allocate persistent_dst_frame", path);
2092 
2093  // Decide destination pixel format: NV12 if HW accel is on, else encoder’s pix_fmt
2094  AVPixelFormat dst_fmt = video_codec_ctx->pix_fmt;
2095 #if USE_HW_ACCEL
2096  if (hw_en_on && hw_en_supported) {
2097  dst_fmt = AV_PIX_FMT_NV12;
2098  }
2099 #endif
2100  persistent_dst_frame->format = dst_fmt;
2101  persistent_dst_frame->width = info.width;
2102  persistent_dst_frame->height = info.height;
2103 
2104  persistent_dst_size = av_image_get_buffer_size(
2105  dst_fmt, info.width, info.height, 1
2106  );
2107  if (persistent_dst_size < 0)
2108  throw ErrorEncodingVideo("Invalid destination image size", -1);
2109 
2110  persistent_dst_buffer = static_cast<uint8_t*>(
2111  av_malloc(persistent_dst_size)
2112  );
2113  if (!persistent_dst_buffer)
2114  throw OutOfMemory("Could not allocate persistent_dst_buffer", path);
2115 
2116  av_image_fill_arrays(
2117  persistent_dst_frame->data,
2118  persistent_dst_frame->linesize,
2119  persistent_dst_buffer,
2120  dst_fmt,
2121  info.width,
2122  info.height,
2123  1
2124  );
2125  }
2126 
2127  // Initialize SwsContext (RGBA → dst_fmt) on first use
2128  if (!img_convert_ctx) {
2129  int flags = SWS_FAST_BILINEAR;
2130  if (openshot::Settings::Instance()->HIGH_QUALITY_SCALING) {
2131  flags = SWS_BICUBIC;
2132  }
2133  AVPixelFormat dst_fmt = video_codec_ctx->pix_fmt;
2134 #if USE_HW_ACCEL
2135  if (hw_en_on && hw_en_supported) {
2136  dst_fmt = AV_PIX_FMT_NV12;
2137  }
2138 #endif
2139  img_convert_ctx = sws_getContext(
2140  src_w, src_h, AV_PIX_FMT_RGBA,
2141  info.width, info.height, dst_fmt,
2142  flags, NULL, NULL, NULL
2143  );
2144  if (!img_convert_ctx)
2145  throw ErrorEncodingVideo("Could not initialize sws context", -1);
2146  }
2147 
2148  // Scale RGBA → dst_fmt into persistent_dst_buffer
2149  sws_scale(
2150  img_convert_ctx,
2151  persistent_src_frame->data,
2152  persistent_src_frame->linesize,
2153  0, src_h,
2154  persistent_dst_frame->data,
2155  persistent_dst_frame->linesize
2156  );
2157 
2158  // Allocate a new AVFrame + buffer, then copy scaled data into it
2159  int bytes_final = 0;
2160  AVPixelFormat dst_fmt = video_codec_ctx->pix_fmt;
2161 #if USE_HW_ACCEL
2162  if (hw_en_on && hw_en_supported) {
2163  dst_fmt = AV_PIX_FMT_NV12;
2164  }
2165 #endif
2166 
2167  AVFrame* new_frame = allocate_avframe(
2168  dst_fmt,
2169  info.width,
2170  info.height,
2171  &bytes_final,
2172  nullptr
2173  );
2174  if (!new_frame)
2175  throw OutOfMemory("Could not allocate new_frame via allocate_avframe", path);
2176 
2177  // Copy persistent_dst_buffer → new_frame buffer
2178  memcpy(
2179  new_frame->data[0],
2180  persistent_dst_buffer,
2181  static_cast<size_t>(bytes_final)
2182  );
2183 
2184  // Queue the deep‐copied frame for encoding
2185  add_avframe(frame, new_frame);
2186 }
2187 
2188 // write video frame
2189 bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *frame_final) {
2190 #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
2191  // FFmpeg 4.0+
2193  "FFmpegWriter::write_video_packet",
2194  "frame->number", frame->number,
2195  "oc->oformat->flags", oc->oformat->flags);
2196 
2197  if (AV_GET_CODEC_TYPE(video_st) == AVMEDIA_TYPE_VIDEO && AV_FIND_DECODER_CODEC_ID(video_st) == AV_CODEC_ID_RAWVIDEO) {
2198 #else
2199  // TODO: Should we have moved away from oc->oformat->flags / AVFMT_RAWPICTURE
2200  // on ffmpeg < 4.0 as well?
2201  // Does AV_CODEC_ID_RAWVIDEO not work in ffmpeg 3.x?
2203  "FFmpegWriter::write_video_packet",
2204  "frame->number", frame->number,
2205  "oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE);
2206 
2207  if (oc->oformat->flags & AVFMT_RAWPICTURE) {
2208 #endif
2209  // Raw video case.
2210 #if IS_FFMPEG_3_2
2211  AVPacket* pkt = av_packet_alloc();
2212 #else
2213  AVPacket* pkt;
2214  av_init_packet(pkt);
2215 #endif
2216 
2217  av_packet_from_data(
2218  pkt, frame_final->data[0],
2219  frame_final->linesize[0] * frame_final->height);
2220 
2221  pkt->flags |= AV_PKT_FLAG_KEY;
2222  pkt->stream_index = video_st->index;
2223 
2224  // Set PTS (in frames and scaled to the codec's timebase)
2225  pkt->pts = video_timestamp;
2226 
2227  /* write the compressed frame in the media file */
2228  int error_code = av_interleaved_write_frame(oc, pkt);
2229  if (error_code < 0) {
2231  "FFmpegWriter::write_video_packet ERROR ["
2232  + av_err2string(error_code) + "]",
2233  "error_code", error_code);
2234  return false;
2235  }
2236 
2237  // Deallocate packet
2238  AV_FREE_PACKET(pkt);
2239 
2240  } else
2241  {
2242 
2243 #if IS_FFMPEG_3_2
2244  AVPacket* pkt = av_packet_alloc();
2245 #else
2246  AVPacket* pkt;
2247  av_init_packet(pkt);
2248 #endif
2249  pkt->data = NULL;
2250  pkt->size = 0;
2251  pkt->pts = pkt->dts = AV_NOPTS_VALUE;
2252 
2253  // Assign the initial AVFrame PTS from the frame counter
2254  frame_final->pts = video_timestamp;
2255 #if USE_HW_ACCEL
2256  if (hw_en_on && hw_en_supported) {
2257  if (!(hw_frame = av_frame_alloc())) {
2258  std::clog << "Error code: av_hwframe_alloc\n";
2259  }
2260  if (av_hwframe_get_buffer(video_codec_ctx->hw_frames_ctx, hw_frame, 0) < 0) {
2261  std::clog << "Error code: av_hwframe_get_buffer\n";
2262  }
2263  if (!hw_frame->hw_frames_ctx) {
2264  std::clog << "Error hw_frames_ctx.\n";
2265  }
2266  hw_frame->format = AV_PIX_FMT_NV12;
2267  if ( av_hwframe_transfer_data(hw_frame, frame_final, 0) < 0) {
2268  std::clog << "Error while transferring frame data to surface.\n";
2269  }
2270  av_frame_copy_props(hw_frame, frame_final);
2271  }
2272 #endif // USE_HW_ACCEL
2273  /* encode the image */
2274  int got_packet_ptr = 0;
2275  int error_code = 0;
2276 #if IS_FFMPEG_3_2
2277  // Write video packet
2278  int ret;
2279 
2280  #if USE_HW_ACCEL
2281  if (hw_en_on && hw_en_supported) {
2282  ret = avcodec_send_frame(video_codec_ctx, hw_frame); //hw_frame!!!
2283  } else
2284  #endif // USE_HW_ACCEL
2285  {
2286  ret = avcodec_send_frame(video_codec_ctx, frame_final);
2287  }
2288  error_code = ret;
2289  if (ret < 0 ) {
2291  "FFmpegWriter::write_video_packet (Frame not sent)");
2292  if (ret == AVERROR(EAGAIN) ) {
2293  std::clog << "Frame EAGAIN\n";
2294  }
2295  if (ret == AVERROR_EOF ) {
2296  std::clog << "Frame AVERROR_EOF\n";
2297  }
2298  avcodec_send_frame(video_codec_ctx, NULL);
2299  }
2300  else {
2301  while (ret >= 0) {
2302  ret = avcodec_receive_packet(video_codec_ctx, pkt);
2303 
2304  if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
2305  got_packet_ptr = 0;
2306  break;
2307  }
2308  if (ret == 0) {
2309  got_packet_ptr = 1;
2310  break;
2311  }
2312  }
2313  }
2314 #else
2315  // Write video packet (older than FFmpeg 3.2)
2316  error_code = avcodec_encode_video2(video_codec_ctx, pkt, frame_final, &got_packet_ptr);
2317  if (error_code != 0) {
2319  "FFmpegWriter::write_video_packet ERROR ["
2320  + av_err2string(error_code) + "]",
2321  "error_code", error_code);
2322  }
2323  if (got_packet_ptr == 0) {
2325  "FFmpegWriter::write_video_packet (Frame gotpacket error)");
2326  }
2327 #endif // IS_FFMPEG_3_2
2328 
2329  /* if zero size, it means the image was buffered */
2330  if (error_code == 0 && got_packet_ptr) {
2331  // set the timestamp
2332  av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
2333  pkt->stream_index = video_st->index;
2334 
2335  /* write the compressed frame in the media file */
2336  int result = av_interleaved_write_frame(oc, pkt);
2337  if (result < 0) {
2339  "FFmpegWriter::write_video_packet ERROR ["
2340  + av_err2string(result) + "]",
2341  "result", result);
2342  return false;
2343  }
2344  }
2345 
2346  // Deallocate packet
2347  AV_FREE_PACKET(pkt);
2348 #if USE_HW_ACCEL
2349  if (hw_en_on && hw_en_supported) {
2350  if (hw_frame) {
2351  av_frame_free(&hw_frame);
2352  hw_frame = NULL;
2353  }
2354  }
2355 #endif // USE_HW_ACCEL
2356  }
2357 
2358  // Increment PTS (in frames and scaled to the codec's timebase)
2359  video_timestamp += av_rescale_q(1, av_make_q(info.fps.den, info.fps.num), video_codec_ctx->time_base);
2360 
2361  // Success
2362  return true;
2363 }
2364 
2365 // Output the ffmpeg info about this format, streams, and codecs (i.e. dump format)
2367  // output debug info
2368  av_dump_format(oc, 0, path.c_str(), 1);
2369 }
2370 
2371 // Set audio resample options
2372 void FFmpegWriter::ResampleAudio(int sample_rate, int channels) {
2373  original_sample_rate = sample_rate;
2374  original_channels = channels;
2375 }
2376 
2377 // In FFmpegWriter.cpp
2378 void FFmpegWriter::AddSphericalMetadata(const std::string& projection, float yaw_deg, float pitch_deg, float roll_deg) {
2379  if (!oc) return;
2380  if (!info.has_video || !video_st) return;
2381 
2382  // Allow movenc.c to write out the sv3d atom
2383  oc->strict_std_compliance = FF_COMPLIANCE_UNOFFICIAL;
2384 
2385 #if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 0, 0)
2386  // Map the projection name to the enum (defaults to equirectangular)
2387  int proj = av_spherical_from_name(projection.c_str());
2388  if (proj < 0)
2389  proj = AV_SPHERICAL_EQUIRECTANGULAR;
2390 
2391  // Allocate the side‐data structure
2392  size_t sd_size = 0;
2393  AVSphericalMapping* map = av_spherical_alloc(&sd_size);
2394  if (!map) return;
2395 
2396  // Populate it
2397  map->projection = static_cast<AVSphericalProjection>(proj);
2398  // yaw/pitch/roll are 16.16 fixed point
2399  map->yaw = static_cast<int32_t>(yaw_deg * (1 << 16));
2400  map->pitch = static_cast<int32_t>(pitch_deg * (1 << 16));
2401  map->roll = static_cast<int32_t>(roll_deg * (1 << 16));
2402 
2403  av_stream_add_side_data(video_st, AV_PKT_DATA_SPHERICAL, reinterpret_cast<uint8_t*>(map), sd_size);
2404 #endif
2405 }
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:211
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:2372
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:223
openshot::FFmpegWriter::OutputStreamInfo
void OutputStreamInfo()
Output the ffmpeg info about this format, streams, and codecs (i.e. dump format)
Definition: FFmpegWriter.cpp:2366
PixelFormat
#define PixelFormat
Definition: FFmpegUtilities.h:107
openshot::ReaderBase::GetFrame
virtual std::shared_ptr< openshot::Frame > GetFrame(int64_t number)=0
AV_ALLOCATE_FRAME
#define AV_ALLOCATE_FRAME()
Definition: FFmpegUtilities.h:203
SWR_CONVERT
#define SWR_CONVERT(ctx, out, linesize, out_count, in, linesize2, in_count)
Definition: FFmpegUtilities.h:149
openshot::WriterInfo::fps
openshot::Fraction fps
Frames per second, as a fraction (i.e. 24/1 = 24 fps)
Definition: WriterBase.h:42
openshot
This namespace is the default namespace for all code in the openshot library.
Definition: Compressor.h:28
AV_OPTION_SET
#define AV_OPTION_SET(av_stream, priv_data, name, value, avcodec)
Definition: FFmpegUtilities.h:228
openshot::WriterInfo::audio_bit_rate
int audio_bit_rate
The bit rate of the audio stream (in bytes)
Definition: WriterBase.h:53
openshot::WriterInfo::channels
int channels
The number of audio channels used in the audio stream.
Definition: WriterBase.h:55
AV_COPY_PARAMS_FROM_CONTEXT
AV_COPY_PARAMS_FROM_CONTEXT(st, video_codec_ctx)
openshot::Fraction
This class represents a fraction.
Definition: Fraction.h:30
AV_GET_CODEC_FROM_STREAM
#define AV_GET_CODEC_FROM_STREAM(av_stream, codec_in)
Definition: FFmpegUtilities.h:217
openshot::FFmpegWriter::FFmpegWriter
FFmpegWriter(const std::string &path)
Constructor for FFmpegWriter. Throws an exception on failure to open path.
Definition: FFmpegWriter.cpp:76
AV_FREE_FRAME
#define AV_FREE_FRAME(av_frame)
Definition: FFmpegUtilities.h:207
AV_FREE_PACKET
#define AV_FREE_PACKET(av_packet)
Definition: FFmpegUtilities.h:208
openshot::FFmpegWriter::Open
void Open()
Open writer.
Definition: FFmpegWriter.cpp: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:216
openshot::WriterInfo::width
int width
The width of the video (in pixels)
Definition: WriterBase.h:40
hw_en_on
int hw_en_on
Definition: FFmpegWriter.cpp: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:218
openshot::Settings::HW_EN_DEVICE_SET
int HW_EN_DEVICE_SET
Which GPU to use to encode (0 is the first)
Definition: Settings.h:86
openshot::WriterInfo::pixel_ratio
openshot::Fraction pixel_ratio
The pixel ratio of the video stream as a fraction (i.e. some pixels are not square)
Definition: WriterBase.h:44
openshot::Fraction::num
int num
Numerator for the fraction.
Definition: Fraction.h:32
openshot::WriterInfo::top_field_first
bool top_field_first
Which interlaced field should be displayed first.
Definition: WriterBase.h:51
if
if(!codec) codec
AV_SET_FILENAME
#define AV_SET_FILENAME(oc, f)
Definition: FFmpegUtilities.h:201
AV_GET_IMAGE_SIZE
#define AV_GET_IMAGE_SIZE(pix_fmt, width, height)
Definition: FFmpegUtilities.h:222
ZmqLogger.h
Header file for ZeroMQ-based Logger class.
mux_dict
AVDictionary * mux_dict
Definition: FFmpegWriter.cpp: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:2378
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:206
SWR_CLOSE
#define SWR_CLOSE(ctx)
Definition: FFmpegUtilities.h:152
openshot::WriterInfo::channel_layout
openshot::ChannelLayout channel_layout
The channel layout (mono, stereo, 5 point surround, etc...)
Definition: WriterBase.h:56
openshot::OutOfMemory
Exception when memory could not be allocated.
Definition: Exceptions.h:354
SWR_INIT
#define SWR_INIT(ctx)
Definition: FFmpegUtilities.h:154
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:23
openshot::VIDEO_STREAM
@ VIDEO_STREAM
A video stream (used to determine which type of stream)
Definition: FFmpegWriter.h:29
openshot::WriterInfo::metadata
std::map< std::string, std::string > metadata
An optional map/dictionary of video & audio metadata.
Definition: WriterBase.h:59
path
path
Definition: FFmpegWriter.cpp:1474
Frame.h
Header file for Frame class.
ALLOC_CODEC_CTX
#define ALLOC_CODEC_CTX(ctx, codec, stream)
Definition: FFmpegUtilities.h:231
openshot::InvalidFile
Exception for files that can not be found or opened.
Definition: Exceptions.h: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:210
openshot::FFmpegWriter::Close
void Close()
Close the writer.
Definition: FFmpegWriter.cpp:962
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:209
OpenMPUtilities.h
Header file for OpenMPUtilities (set some common macros)
SWR_FREE
#define SWR_FREE(ctx)
Definition: FFmpegUtilities.h:153
openshot::FFmpegWriter::WriteTrailer
void WriteTrailer()
Write the file trailer (after all frames are written). This is called automatically by the Close() me...
Definition: FFmpegWriter.cpp:749
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:227
codec
codec
Definition: FFmpegWriter.cpp:1470
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:151
openshot::FFmpegWriter::SetAudioOptions
void SetAudioOptions(bool has_audio, std::string codec, int sample_rate, int channels, openshot::ChannelLayout channel_layout, int bit_rate)
Set audio export options.
Definition: FFmpegWriter.cpp:288
AV_REGISTER_ALL
#define AV_REGISTER_ALL
Definition: FFmpegUtilities.h:198
AV_OUTPUT_CONTEXT
#define AV_OUTPUT_CONTEXT(output_context, path)
Definition: FFmpegUtilities.h:225
hw_en_supported
int hw_en_supported
Definition: FFmpegWriter.cpp: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:202
AVCODEC_MAX_AUDIO_FRAME_SIZE
#define AVCODEC_MAX_AUDIO_FRAME_SIZE
Definition: FFmpegUtilities.h:83
opts
AVDictionary * opts
Definition: FFmpegWriter.cpp:1485
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