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