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