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