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