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