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