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 
86 FFmpegWriter::FFmpegWriter(std::string path) :
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
1421  if (hw_en_on && hw_en_supported) {
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  frame_final->channels = info.channels;
1715  frame_final->format = audio_codec->sample_fmt;
1716  frame_final->channel_layout = info.channel_layout;
1717  av_samples_alloc(frame_final->data, frame_final->linesize, info.channels, frame_final->nb_samples, audio_codec->sample_fmt, 0);
1718 
1719  // Convert audio samples
1720  int nb_samples = SWR_CONVERT(avr_planar, // audio resample context
1721  frame_final->data, // output data pointers
1722  frame_final->linesize[0], // output plane size, in bytes. (0 if unknown)
1723  frame_final->nb_samples, // maximum number of samples that the output buffer can hold
1724  audio_frame->data, // input data pointers
1725  audio_frame->linesize[0], // input plane size, in bytes (0 if unknown)
1726  audio_frame->nb_samples); // number of input samples to convert
1727 
1728  // Copy audio samples over original samples
1729  if (nb_samples > 0)
1730  memcpy(samples, frame_final->data[0], nb_samples * av_get_bytes_per_sample(audio_codec->sample_fmt) * info.channels);
1731 
1732  // deallocate AVFrame
1733  av_freep(&(audio_frame->data[0]));
1734  AV_FREE_FRAME(&audio_frame);
1735  all_queued_samples = NULL; // this array cleared with above call
1736 
1737  ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_audio_packets (Successfully completed 2nd resampling for Planar formats)", "nb_samples", nb_samples);
1738 
1739  } else {
1740  // Create a new array
1741  final_samples = (int16_t *) av_malloc(
1742  sizeof(int16_t) * audio_input_position * (av_get_bytes_per_sample(audio_codec->sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)));
1743 
1744  // Copy audio into buffer for frame
1745  memcpy(final_samples, samples, audio_input_position * av_get_bytes_per_sample(audio_codec->sample_fmt));
1746 
1747  // Init the nb_samples property
1748  frame_final->nb_samples = audio_input_frame_size;
1749 
1750  // Fill the final_frame AVFrame with audio (non planar)
1751  avcodec_fill_audio_frame(frame_final, audio_codec->channels, audio_codec->sample_fmt, (uint8_t *) final_samples,
1752  audio_encoder_buffer_size, 0);
1753  }
1754 
1755  // Increment PTS (in samples)
1756  write_audio_count += FFMIN(audio_input_frame_size, audio_input_position);
1757  frame_final->pts = write_audio_count; // Set the AVFrame's PTS
1758 
1759  // Init the packet
1760  AVPacket pkt;
1761  av_init_packet(&pkt);
1762  pkt.data = audio_encoder_buffer;
1763  pkt.size = audio_encoder_buffer_size;
1764 
1765  // Set the packet's PTS prior to encoding
1766  pkt.pts = pkt.dts = write_audio_count;
1767 
1768  /* encode the audio samples */
1769  int got_packet_ptr = 0;
1770 
1771 #if IS_FFMPEG_3_2
1772  // Encode audio (latest version of FFmpeg)
1773  int error_code;
1774  int ret = 0;
1775  int frame_finished = 0;
1776  error_code = ret = avcodec_send_frame(audio_codec, frame_final);
1777  if (ret < 0 && ret != AVERROR(EINVAL) && ret != AVERROR_EOF) {
1778  avcodec_send_frame(audio_codec, NULL);
1779  }
1780  else {
1781  if (ret >= 0)
1782  pkt.size = 0;
1783  ret = avcodec_receive_packet(audio_codec, &pkt);
1784  if (ret >= 0)
1785  frame_finished = 1;
1786  if(ret == AVERROR(EINVAL) || ret == AVERROR_EOF) {
1787  avcodec_flush_buffers(audio_codec);
1788  ret = 0;
1789  }
1790  if (ret >= 0) {
1791  ret = frame_finished;
1792  }
1793  }
1794  if (!pkt.data && !frame_finished)
1795  {
1796  ret = -1;
1797  }
1798  got_packet_ptr = ret;
1799 #else
1800  // Encode audio (older versions of FFmpeg)
1801  int error_code = avcodec_encode_audio2(audio_codec, &pkt, frame_final, &got_packet_ptr);
1802 #endif
1803  /* if zero size, it means the image was buffered */
1804  if (error_code == 0 && got_packet_ptr) {
1805 
1806  // Since the PTS can change during encoding, set the value again. This seems like a huge hack,
1807  // but it fixes lots of PTS related issues when I do this.
1808  pkt.pts = pkt.dts = write_audio_count;
1809 
1810  // Scale the PTS to the audio stream timebase (which is sometimes different than the codec's timebase)
1811  if (pkt.pts != AV_NOPTS_VALUE)
1812  pkt.pts = av_rescale_q(pkt.pts, audio_codec->time_base, audio_st->time_base);
1813  if (pkt.dts != AV_NOPTS_VALUE)
1814  pkt.dts = av_rescale_q(pkt.dts, audio_codec->time_base, audio_st->time_base);
1815  if (pkt.duration > 0)
1816  pkt.duration = av_rescale_q(pkt.duration, audio_codec->time_base, audio_st->time_base);
1817 
1818  // set stream
1819  pkt.stream_index = audio_st->index;
1820  pkt.flags |= AV_PKT_FLAG_KEY;
1821 
1822  /* write the compressed frame in the media file */
1823  int error_code = av_interleaved_write_frame(oc, &pkt);
1824  if (error_code < 0) {
1825  ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_audio_packets ERROR [" + (std::string) av_err2str(error_code) + "]", "error_code", error_code);
1826  }
1827  }
1828 
1829  if (error_code < 0) {
1830  ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_audio_packets ERROR [" + (std::string) av_err2str(error_code) + "]", "error_code", error_code);
1831  }
1832 
1833  // deallocate AVFrame
1834  av_freep(&(frame_final->data[0]));
1835  AV_FREE_FRAME(&frame_final);
1836 
1837  // deallocate memory for packet
1838  AV_FREE_PACKET(&pkt);
1839 
1840  // Reset position
1841  audio_input_position = 0;
1842  is_final = false;
1843  }
1844 
1845  // Delete arrays (if needed)
1846  if (all_resampled_samples) {
1847  av_freep(&all_resampled_samples);
1848  all_resampled_samples = NULL;
1849  }
1850  if (all_queued_samples) {
1851  av_freep(&all_queued_samples);
1852  all_queued_samples = NULL;
1853  }
1854 
1855  } // end task
1856 }
1857 
1858 // Allocate an AVFrame object
1859 AVFrame *FFmpegWriter::allocate_avframe(PixelFormat pix_fmt, int width, int height, int *buffer_size, uint8_t *new_buffer) {
1860  // Create an RGB AVFrame
1861  AVFrame *new_av_frame = NULL;
1862 
1863  // Allocate an AVFrame structure
1864  new_av_frame = AV_ALLOCATE_FRAME();
1865  if (new_av_frame == NULL)
1866  throw OutOfMemory("Could not allocate AVFrame", path);
1867 
1868  // Determine required buffer size and allocate buffer
1869  *buffer_size = AV_GET_IMAGE_SIZE(pix_fmt, width, height);
1870 
1871  // Create buffer (if not provided)
1872  if (!new_buffer) {
1873  // New Buffer
1874  new_buffer = (uint8_t *) av_malloc(*buffer_size * sizeof(uint8_t));
1875  // Attach buffer to AVFrame
1876  AV_COPY_PICTURE_DATA(new_av_frame, new_buffer, pix_fmt, width, height);
1877  new_av_frame->width = width;
1878  new_av_frame->height = height;
1879  new_av_frame->format = pix_fmt;
1880  }
1881 
1882  // return AVFrame
1883  return new_av_frame;
1884 }
1885 
1886 // process video frame
1887 void FFmpegWriter::process_video_packet(std::shared_ptr<Frame> frame) {
1888  // Determine the height & width of the source image
1889  int source_image_width = frame->GetWidth();
1890  int source_image_height = frame->GetHeight();
1891 
1892  // Do nothing if size is 1x1 (i.e. no image in this frame)
1893  if (source_image_height == 1 && source_image_width == 1)
1894  return;
1895 
1896  // Init rescalers (if not initialized yet)
1897  if (image_rescalers.size() == 0)
1898  InitScalers(source_image_width, source_image_height);
1899 
1900  // Get a unique rescaler (for this thread)
1901  SwsContext *scaler = image_rescalers[rescaler_position];
1902  rescaler_position++;
1903  if (rescaler_position == num_of_rescalers)
1904  rescaler_position = 0;
1905 
1906 #pragma omp task firstprivate(frame, scaler, source_image_width, source_image_height)
1907  {
1908  // Allocate an RGB frame & final output frame
1909  int bytes_source = 0;
1910  int bytes_final = 0;
1911  AVFrame *frame_source = NULL;
1912  const uchar *pixels = NULL;
1913 
1914  // Get a list of pixels from source image
1915  pixels = frame->GetPixels();
1916 
1917  // Init AVFrame for source image & final (converted image)
1918  frame_source = allocate_avframe(PIX_FMT_RGBA, source_image_width, source_image_height, &bytes_source, (uint8_t *) pixels);
1919 #if IS_FFMPEG_3_2
1920  AVFrame *frame_final;
1921  #if HAVE_HW_ACCEL
1922  if (hw_en_on && hw_en_supported) {
1923  frame_final = allocate_avframe(AV_PIX_FMT_NV12, info.width, info.height, &bytes_final, NULL);
1924  } else
1925  #endif // HAVE_HW_ACCEL
1926  {
1927  frame_final = allocate_avframe((AVPixelFormat)(video_st->codecpar->format), info.width, info.height, &bytes_final, NULL);
1928  }
1929 #else
1930  AVFrame *frame_final = allocate_avframe(video_codec->pix_fmt, info.width, info.height, &bytes_final, NULL);
1931 #endif // IS_FFMPEG_3_2
1932 
1933  // Fill with data
1934  AV_COPY_PICTURE_DATA(frame_source, (uint8_t *) pixels, PIX_FMT_RGBA, source_image_width, source_image_height);
1935  ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::process_video_packet", "frame->number", frame->number, "bytes_source", bytes_source, "bytes_final", bytes_final);
1936 
1937  // Resize & convert pixel format
1938  sws_scale(scaler, frame_source->data, frame_source->linesize, 0,
1939  source_image_height, frame_final->data, frame_final->linesize);
1940 
1941  // Add resized AVFrame to av_frames map
1942 #pragma omp critical (av_frames_section)
1943  add_avframe(frame, frame_final);
1944 
1945  // Deallocate memory
1946  AV_FREE_FRAME(&frame_source);
1947 
1948  } // end task
1949 
1950 }
1951 
1952 // write video frame
1953 bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *frame_final) {
1954 #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
1955  ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet", "frame->number", frame->number, "oc->oformat->flags", oc->oformat->flags);
1956 #else
1957  ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet", "frame->number", frame->number, "oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE);
1958 
1959  if (oc->oformat->flags & AVFMT_RAWPICTURE) {
1960  // Raw video case.
1961  AVPacket pkt;
1962  av_init_packet(&pkt);
1963 
1964  pkt.flags |= AV_PKT_FLAG_KEY;
1965  pkt.stream_index = video_st->index;
1966  pkt.data = (uint8_t *) frame_final->data;
1967  pkt.size = sizeof(AVPicture);
1968 
1969  // Increment PTS (in frames and scaled to the codec's timebase)
1970  write_video_count += av_rescale_q(1, (AVRational) {info.fps.den, info.fps.num}, video_codec->time_base);
1971  pkt.pts = write_video_count;
1972 
1973  /* write the compressed frame in the media file */
1974  int error_code = av_interleaved_write_frame(oc, &pkt);
1975  if (error_code < 0) {
1976  ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet ERROR [" + (std::string) av_err2str(error_code) + "]", "error_code", error_code);
1977  return false;
1978  }
1979 
1980  // Deallocate packet
1981  AV_FREE_PACKET(&pkt);
1982 
1983  } else
1984 #endif
1985  {
1986 
1987  AVPacket pkt;
1988  av_init_packet(&pkt);
1989  pkt.data = NULL;
1990  pkt.size = 0;
1991  pkt.pts = pkt.dts = AV_NOPTS_VALUE;
1992 
1993  // Pointer for video buffer (if using old FFmpeg version)
1994  uint8_t *video_outbuf = NULL;
1995 
1996  // Increment PTS (in frames and scaled to the codec's timebase)
1997  write_video_count += av_rescale_q(1, (AVRational) {info.fps.den, info.fps.num}, video_codec->time_base);
1998 
1999  // Assign the initial AVFrame PTS from the frame counter
2000  frame_final->pts = write_video_count;
2001 #if HAVE_HW_ACCEL
2002  if (hw_en_on && hw_en_supported) {
2003  if (!(hw_frame = av_frame_alloc())) {
2004  fprintf(stderr, "Error code: av_hwframe_alloc\n");
2005  }
2006  if (av_hwframe_get_buffer(video_codec->hw_frames_ctx, hw_frame, 0) < 0) {
2007  fprintf(stderr, "Error code: av_hwframe_get_buffer\n");
2008  }
2009  if (!hw_frame->hw_frames_ctx) {
2010  fprintf(stderr, "Error hw_frames_ctx.\n");
2011  }
2012  hw_frame->format = AV_PIX_FMT_NV12;
2013  if ( av_hwframe_transfer_data(hw_frame, frame_final, 0) < 0) {
2014  fprintf(stderr, "Error while transferring frame data to surface.\n");
2015  }
2016  av_frame_copy_props(hw_frame, frame_final);
2017  }
2018 #endif // HAVE_HW_ACCEL
2019  /* encode the image */
2020  int got_packet_ptr = 0;
2021  int error_code = 0;
2022 #if IS_FFMPEG_3_2
2023  // Write video packet (latest version of FFmpeg)
2024  int frameFinished = 0;
2025  int ret;
2026 
2027  #if HAVE_HW_ACCEL
2028  if (hw_en_on && hw_en_supported) {
2029  ret = avcodec_send_frame(video_codec, hw_frame); //hw_frame!!!
2030  } else
2031  #endif // HAVE_HW_ACCEL
2032  {
2033  ret = avcodec_send_frame(video_codec, frame_final);
2034  }
2035  error_code = ret;
2036  if (ret < 0 ) {
2037  ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet (Frame not sent)");
2038  if (ret == AVERROR(EAGAIN) ) {
2039  std::cerr << "Frame EAGAIN" << "\n";
2040  }
2041  if (ret == AVERROR_EOF ) {
2042  std::cerr << "Frame AVERROR_EOF" << "\n";
2043  }
2044  avcodec_send_frame(video_codec, NULL);
2045  }
2046  else {
2047  while (ret >= 0) {
2048  ret = avcodec_receive_packet(video_codec, &pkt);
2049 
2050  if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
2051  avcodec_flush_buffers(video_codec);
2052  got_packet_ptr = 0;
2053  break;
2054  }
2055  if (ret == 0) {
2056  got_packet_ptr = 1;
2057  break;
2058  }
2059  }
2060  }
2061 #else
2062 #if LIBAVFORMAT_VERSION_MAJOR >= 54
2063  // Write video packet (older than FFmpeg 3.2)
2064  error_code = avcodec_encode_video2(video_codec, &pkt, frame_final, &got_packet_ptr);
2065  if (error_code != 0) {
2066  std::cerr << "Frame AVERROR_EOF" << "\n";
2067  }
2068  if (got_packet_ptr == 0) {
2069  std::cerr << "Frame gotpacket error" << "\n";
2070  }
2071 #else
2072  // Write video packet (even older versions of FFmpeg)
2073  int video_outbuf_size = 200000;
2074  video_outbuf = (uint8_t*) av_malloc(200000);
2075 
2076  /* encode the image */
2077  int out_size = avcodec_encode_video(video_codec, video_outbuf, video_outbuf_size, frame_final);
2078 
2079  /* if zero size, it means the image was buffered */
2080  if (out_size > 0) {
2081  if(video_codec->coded_frame->key_frame)
2082  pkt.flags |= AV_PKT_FLAG_KEY;
2083  pkt.data= video_outbuf;
2084  pkt.size= out_size;
2085 
2086  // got data back (so encode this frame)
2087  got_packet_ptr = 1;
2088  }
2089 #endif // LIBAVFORMAT_VERSION_MAJOR >= 54
2090 #endif // IS_FFMPEG_3_2
2091 
2092  /* if zero size, it means the image was buffered */
2093  if (error_code == 0 && got_packet_ptr) {
2094 
2095  // Since the PTS can change during encoding, set the value again. This seems like a huge hack,
2096  // but it fixes lots of PTS related issues when I do this.
2097  //pkt.pts = pkt.dts = write_video_count;
2098 
2099  // set the timestamp
2100  if (pkt.pts != AV_NOPTS_VALUE)
2101  pkt.pts = av_rescale_q(pkt.pts, video_codec->time_base, video_st->time_base);
2102  if (pkt.dts != AV_NOPTS_VALUE)
2103  pkt.dts = av_rescale_q(pkt.dts, video_codec->time_base, video_st->time_base);
2104  if (pkt.duration > 0)
2105  pkt.duration = av_rescale_q(pkt.duration, video_codec->time_base, video_st->time_base);
2106  pkt.stream_index = video_st->index;
2107 
2108  /* write the compressed frame in the media file */
2109  int error_code = av_interleaved_write_frame(oc, &pkt);
2110  if (error_code < 0) {
2111  ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet ERROR [" + (std::string) av_err2str(error_code) + "]", "error_code", error_code);
2112  return false;
2113  }
2114  }
2115 
2116  // Deallocate memory (if needed)
2117  if (video_outbuf)
2118  delete[] video_outbuf;
2119 
2120  // Deallocate packet
2121  AV_FREE_PACKET(&pkt);
2122 #if HAVE_HW_ACCEL
2123  if (hw_en_on && hw_en_supported) {
2124  if (hw_frame) {
2125  av_frame_free(&hw_frame);
2126  hw_frame = NULL;
2127  }
2128  }
2129 #endif // HAVE_HW_ACCEL
2130  }
2131 
2132  // Success
2133  return true;
2134 }
2135 
2136 // Output the ffmpeg info about this format, streams, and codecs (i.e. dump format)
2138  // output debug info
2139  av_dump_format(oc, 0, path.c_str(), 1);
2140 }
2141 
2142 // Init a collection of software rescalers (thread safe)
2143 void FFmpegWriter::InitScalers(int source_width, int source_height) {
2144  int scale_mode = SWS_FAST_BILINEAR;
2145  if (openshot::Settings::Instance()->HIGH_QUALITY_SCALING) {
2146  scale_mode = SWS_BICUBIC;
2147  }
2148 
2149  // Init software rescalers vector (many of them, one for each thread)
2150  for (int x = 0; x < num_of_rescalers; x++) {
2151  // Init the software scaler from FFMpeg
2152 #if HAVE_HW_ACCEL
2153  if (hw_en_on && hw_en_supported) {
2154  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);
2155  } else
2156 #endif // HAVE_HW_ACCEL
2157  {
2158  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,
2159  NULL, NULL, NULL);
2160  }
2161 
2162  // Add rescaler to vector
2163  image_rescalers.push_back(img_convert_ctx);
2164  }
2165 }
2166 
2167 // Set audio resample options
2168 void FFmpegWriter::ResampleAudio(int sample_rate, int channels) {
2169  original_sample_rate = sample_rate;
2170  original_channels = channels;
2171 }
2172 
2173 // Remove & deallocate all software scalers
2175  // Close all rescalers
2176  for (int x = 0; x < num_of_rescalers; x++)
2177  sws_freeContext(image_rescalers[x]);
2178 
2179  // Clear vector
2180  image_rescalers.clear();
2181 }
#define SWR_INIT(ctx)
#define AUDIO_PACKET_ENCODING_SIZE
#define AV_GET_CODEC_FROM_STREAM(av_stream, codec_in)
#define AV_SET_FILENAME(oc, f)
#define PIX_FMT_YUV420P
#define AV_FREE_FRAME(av_frame)
#define SWR_CONVERT(ctx, out, linesize, out_count, in, linesize2, in_count)
#define AV_GET_IMAGE_SIZE(pix_fmt, width, height)
#define AV_OPTION_FIND(priv_data, name)
#define AV_OUTPUT_CONTEXT(output_context, path)
#define SWR_ALLOC()
#define SWR_CLOSE(ctx)
#define AV_GET_CODEC_TYPE(av_stream)
#define PixelFormat
#define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context)
#define AV_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec)
#define AV_FIND_DECODER_CODEC_ID(av_stream)
#define AV_FORMAT_NEW_STREAM(oc, st_codec, av_codec, av_st)
#define AV_ALLOCATE_FRAME()
#define PIX_FMT_RGB24
#define AV_GET_CODEC_PAR_CONTEXT(av_stream, av_codec)
#define AV_REGISTER_ALL
#define PIX_FMT_NONE
#define PIX_FMT_RGBA
#define SWR_FREE(ctx)
#define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height)
#define AV_OPTION_SET(av_stream, priv_data, name, value, avcodec)
#define AV_FREE_PACKET(av_packet)
#define av_err2str(errnum)
#define AVCODEC_MAX_AUDIO_FRAME_SIZE
#define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context)
#define MY_INPUT_BUFFER_PADDING_SIZE
#define AV_RESET_FRAME(av_frame)
AVDictionary * mux_dict
#define FF_NUM_PROCESSORS
#define OPEN_MP_NUM_PROCESSORS
Exception when encoding audio packet.
Definition: Exceptions.h:126
void Close()
Close the writer.
void SetAudioOptions(bool has_audio, std::string codec, int sample_rate, int channels, openshot::ChannelLayout channel_layout, int bit_rate)
Set audio export options.
void SetOption(openshot::StreamType stream, std::string name, std::string value)
Set custom options (some codecs accept additional params). This must be called after the PrepareStrea...
void PrepareStreams()
Prepare & initialize streams and open codecs. This method is called automatically by the Open() metho...
void SetVideoOptions(bool has_video, std::string codec, openshot::Fraction fps, int width, int height, openshot::Fraction pixel_ratio, bool interlaced, bool top_field_first, int bit_rate)
Set video export options.
void ResampleAudio(int sample_rate, int channels)
Set audio resample options.
FFmpegWriter(std::string path)
Constructor for FFmpegWriter. Throws one of the following exceptions.
void Open()
Open writer.
void WriteHeader()
Write the file header (after the options are set). This method is called automatically by the Open() ...
static bool IsValidCodec(std::string codec_name)
Determine if codec name is valid.
void OutputStreamInfo()
Output the ffmpeg info about this format, streams, and codecs (i.e. dump format)
void WriteFrame(std::shared_ptr< openshot::Frame > frame)
Add a frame to the stack waiting to be encoded.
void WriteTrailer()
Write the file trailer (after all frames are written). This is called automatically by the Close() me...
void RemoveScalers()
Remove & deallocate all software scalers.
This class represents a fraction.
Definition: Fraction.h:45
int num
Numerator for the fraction.
Definition: Fraction.h:47
void Reduce()
Reduce this fraction (i.e. 640/480 = 4/3)
Definition: Fraction.cpp:74
int den
Denominator for the fraction.
Definition: Fraction.h:48
Exception when an invalid # of audio channels are detected.
Definition: Exceptions.h:142
Exception when no valid codec is found for a file.
Definition: Exceptions.h:158
Exception for files that can not be found or opened.
Definition: Exceptions.h:174
Exception when no valid format is found for a file.
Definition: Exceptions.h:190
Exception when invalid encoding options are used.
Definition: Exceptions.h:222
Exception when invalid sample rate is detected during encoding.
Definition: Exceptions.h:238
Exception when no streams are found in the file.
Definition: Exceptions.h:270
Exception when memory could not be allocated.
Definition: Exceptions.h:322
This abstract class is the base class, used by all readers in libopenshot.
Definition: ReaderBase.h:98
virtual std::shared_ptr< openshot::Frame > GetFrame(int64_t number)=0
static Settings * Instance()
Create or get an instance of this logger singleton (invoke the class with this method)
Definition: Settings.cpp:41
int HW_EN_DEVICE_SET
Which GPU to use to encode (0 is the first)
Definition: Settings.h:122
WriterInfo info
Information about the current media file.
Definition: WriterBase.h:94
Exception when a writer is closed, and a frame is requested.
Definition: Exceptions.h:386
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
static ZmqLogger * Instance()
Create or get an instance of this logger singleton (invoke the class with this method)
Definition: ZmqLogger.cpp:45
This namespace is the default namespace for all code in the openshot library.
ChannelLayout
This enumeration determines the audio channel layout (such as stereo, mono, 5 point surround,...
StreamType
This enumeration designates the type of stream when encoding (video or audio)
Definition: FFmpegWriter.h:63
@ AUDIO_STREAM
An audio stream (used to determine which type of stream)
Definition: FFmpegWriter.h:65
@ VIDEO_STREAM
A video stream (used to determine which type of stream)
Definition: FFmpegWriter.h:64
int height
The height of the video (in pixels)
Definition: WriterBase.h:57
int audio_bit_rate
The bit rate of the audio stream (in bytes)
Definition: WriterBase.h:71
int video_bit_rate
The bit rate of the video stream (in bytes)
Definition: WriterBase.h:61
bool has_audio
Determines if this file has an audio stream.
Definition: WriterBase.h:53
bool top_field_first
Which interlaced field should be displayed first.
Definition: WriterBase.h:69
int channels
The number of audio channels used in the audio stream.
Definition: WriterBase.h:73
std::string vcodec
The name of the video codec used to encode / decode the video stream.
Definition: WriterBase.h:64
bool has_video
Determines if this file has a video stream.
Definition: WriterBase.h:52
std::map< std::string, std::string > metadata
An optional map/dictionary of video & audio metadata.
Definition: WriterBase.h:77
openshot::Fraction fps
Frames per second, as a fraction (i.e. 24/1 = 24 fps)
Definition: WriterBase.h:60
std::string acodec
The name of the audio codec used to encode / decode the video stream.
Definition: WriterBase.h:70
openshot::Fraction video_timebase
The video timebase determines how long each frame stays on the screen.
Definition: WriterBase.h:67
openshot::ChannelLayout channel_layout
The channel layout (mono, stereo, 5 point surround, etc...)
Definition: WriterBase.h:74
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
int width
The width of the video (in pixels)
Definition: WriterBase.h:58
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
int sample_rate
The number of audio samples per second (44100 is a common sample rate)
Definition: WriterBase.h:72
bool interlaced_frame
Are the contents of this frame interlaced.
Definition: WriterBase.h:68