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