OpenShot Library | libopenshot 0.3.2
Loading...
Searching...
No Matches
FFmpegWriter.cpp
Go to the documentation of this file.
1
12// Copyright (c) 2008-2024 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(__linux__)
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 //__linux__/_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 case AV_CODEC_ID_HEVC :
567 c->bit_rate = 0;
568 if (strstr(info.vcodec.c_str(), "svt_hevc") != NULL) {
569 av_opt_set_int(c->priv_data, "qp", std::min(std::stoi(value),51), 0);
570 av_opt_set_int(c->priv_data, "preset", 7, 0);
571 av_opt_set_int(c->priv_data, "forced-idr",1,0);
572 }
573 break;
574 }
575#endif // FFmpeg 4.0+
576 } else {
577 // Set AVOption
578 AV_OPTION_SET(st, c->priv_data, name.c_str(), value.c_str(), c);
579 }
580
582 "FFmpegWriter::SetOption (" + (std::string)name + ")",
583 "stream == VIDEO_STREAM", stream == VIDEO_STREAM);
584
585 // Muxing dictionary is not part of the codec context.
586 // Just reusing SetOption function to set popular multiplexing presets.
587 } else if (name == "muxing_preset") {
588 if (value == "mp4_faststart") {
589 // 'moov' box to the beginning; only for MOV, MP4
590 av_dict_set(&mux_dict, "movflags", "faststart", 0);
591 } else if (value == "mp4_fragmented") {
592 // write selfcontained fragmented file, minimum length of the fragment 8 sec; only for MOV, MP4
593 av_dict_set(&mux_dict, "movflags", "frag_keyframe", 0);
594 av_dict_set(&mux_dict, "min_frag_duration", "8000000", 0);
595 }
596 } else {
597 throw InvalidOptions("The option is not valid for this codec.", path);
598 }
599
600}
601
603bool FFmpegWriter::IsValidCodec(std::string codec_name) {
604 // Initialize FFMpeg, and register all formats and codecs
606
607 // Find the codec (if any)
608 if (avcodec_find_encoder_by_name(codec_name.c_str()) == NULL)
609 return false;
610 else
611 return true;
612}
613
614// Prepare & initialize streams and open codecs
616 if (!info.has_audio && !info.has_video)
617 throw InvalidOptions("No video or audio options have been set. You must set has_video or has_audio (or both).", path);
618
620 "FFmpegWriter::PrepareStreams [" + path + "]",
621 "info.has_audio", info.has_audio,
622 "info.has_video", info.has_video);
623
624 // Initialize the streams (i.e. add the streams)
625 initialize_streams();
626
627 // Mark as 'prepared'
628 prepare_streams = true;
629}
630
631// Write the file header (after the options are set)
633 if (!info.has_audio && !info.has_video)
634 throw InvalidOptions("No video or audio options have been set. You must set has_video or has_audio (or both).", path);
635
636 // Open the output file, if needed
637 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
638 if (avio_open(&oc->pb, path.c_str(), AVIO_FLAG_WRITE) < 0)
639 throw InvalidFile("Could not open or write file.", path);
640 }
641
642 // Force the output filename (which doesn't always happen for some reason)
643 AV_SET_FILENAME(oc, path.c_str());
644
645 // Add general metadata (if any)
646 for (std::map<std::string, std::string>::iterator iter = info.metadata.begin(); iter != info.metadata.end(); ++iter) {
647 av_dict_set(&oc->metadata, iter->first.c_str(), iter->second.c_str(), 0);
648 }
649
650 // Set multiplexing parameters
651 AVDictionary *dict = NULL;
652
653 bool is_mp4 = strcmp(oc->oformat->name, "mp4");
654 bool is_mov = strcmp(oc->oformat->name, "mov");
655 // Set dictionary preset only for MP4 and MOV files
656 if (is_mp4 || is_mov)
657 av_dict_copy(&dict, mux_dict, 0);
658
659 // Write the stream header
660 if (avformat_write_header(oc, &dict) != 0) {
662 "FFmpegWriter::WriteHeader (avformat_write_header)");
663 throw InvalidFile("Could not write header to file.", path);
664 };
665
666 // Free multiplexing dictionaries sets
667 if (dict) av_dict_free(&dict);
668 if (mux_dict) av_dict_free(&mux_dict);
669
670 // Mark as 'written'
671 write_header = true;
672
673 ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::WriteHeader");
674}
675
676// Add a frame to the queue waiting to be encoded.
677void FFmpegWriter::WriteFrame(std::shared_ptr<openshot::Frame> frame) {
678 // Check for open reader (or throw exception)
679 if (!is_open)
680 throw WriterClosed("The FFmpegWriter is closed. Call Open() before calling this method.", path);
681
682 // Add frame pointer to "queue", waiting to be processed the next
683 // time the WriteFrames() method is called.
684 if (info.has_video && video_st)
685 spooled_video_frames.push_back(frame);
686
687 if (info.has_audio && audio_st)
688 spooled_audio_frames.push_back(frame);
689
691 "FFmpegWriter::WriteFrame",
692 "frame->number", frame->number,
693 "spooled_video_frames.size()", spooled_video_frames.size(),
694 "spooled_audio_frames.size()", spooled_audio_frames.size(),
695 "cache_size", cache_size,
696 "is_writing", is_writing);
697
698 // Write the frames once it reaches the correct cache size
699 if ((int)spooled_video_frames.size() == cache_size || (int)spooled_audio_frames.size() == cache_size) {
700 // Write frames to video file
701 write_queued_frames();
702 }
703
704 // Keep track of the last frame added
705 last_frame = frame;
706}
707
708// Write all frames in the queue to the video file.
709void FFmpegWriter::write_queued_frames() {
711 "FFmpegWriter::write_queued_frames",
712 "spooled_video_frames.size()", spooled_video_frames.size(),
713 "spooled_audio_frames.size()", spooled_audio_frames.size());
714
715 // Flip writing flag
716 is_writing = true;
717
718 // Transfer spool to queue
719 queued_video_frames = spooled_video_frames;
720 queued_audio_frames = spooled_audio_frames;
721
722 // Empty spool
723 spooled_video_frames.clear();
724 spooled_audio_frames.clear();
725
726 // Create blank exception
727 bool has_error_encoding_video = false;
728
729 // Process all audio frames (in a separate thread)
730 if (info.has_audio && audio_st && !queued_audio_frames.empty())
731 write_audio_packets(false);
732
733 // Loop through each queued image frame
734 while (!queued_video_frames.empty()) {
735 // Get front frame (from the queue)
736 std::shared_ptr<Frame> frame = queued_video_frames.front();
737
738 // Add to processed queue
739 processed_frames.push_back(frame);
740
741 // Encode and add the frame to the output file
742 if (info.has_video && video_st)
743 process_video_packet(frame);
744
745 // Remove front item
746 queued_video_frames.pop_front();
747
748 } // end while
749
750
751 // Loop back through the frames (in order), and write them to the video file
752 while (!processed_frames.empty()) {
753 // Get front frame (from the queue)
754 std::shared_ptr<Frame> frame = processed_frames.front();
755
756 if (info.has_video && video_st) {
757 // Add to deallocate queue (so we can remove the AVFrames when we are done)
758 deallocate_frames.push_back(frame);
759
760 // Does this frame's AVFrame still exist
761 if (av_frames.count(frame)) {
762 // Get AVFrame
763 AVFrame *frame_final = av_frames[frame];
764
765 // Write frame to video file
766 bool success = write_video_packet(frame, frame_final);
767 if (!success)
768 has_error_encoding_video = true;
769 }
770 }
771
772 // Remove front item
773 processed_frames.pop_front();
774 }
775
776 // Loop through, and deallocate AVFrames
777 while (!deallocate_frames.empty()) {
778 // Get front frame (from the queue)
779 std::shared_ptr<Frame> frame = deallocate_frames.front();
780
781 // Does this frame's AVFrame still exist
782 if (av_frames.count(frame)) {
783 // Get AVFrame
784 AVFrame *av_frame = av_frames[frame];
785
786 // Deallocate buffer and AVFrame
787 av_freep(&(av_frame->data[0]));
788 AV_FREE_FRAME(&av_frame);
789 av_frames.erase(frame);
790 }
791
792 // Remove front item
793 deallocate_frames.pop_front();
794 }
795
796 // Done writing
797 is_writing = false;
798
799 // Raise exception from main thread
800 if (has_error_encoding_video)
801 throw ErrorEncodingVideo("Error while writing raw video frame", -1);
802}
803
804// Write a block of frames from a reader
805void FFmpegWriter::WriteFrame(ReaderBase *reader, int64_t start, int64_t length) {
807 "FFmpegWriter::WriteFrame (from Reader)",
808 "start", start,
809 "length", length);
810
811 // Loop through each frame (and encoded it)
812 for (int64_t number = start; number <= length; number++) {
813 // Get the frame
814 std::shared_ptr<Frame> f = reader->GetFrame(number);
815
816 // Encode frame
817 WriteFrame(f);
818 }
819}
820
821// Write the file trailer (after all frames are written)
823 // Write any remaining queued frames to video file
824 write_queued_frames();
825
826 // Process final audio frame (if any)
827 if (info.has_audio && audio_st)
828 write_audio_packets(true);
829
830 // Flush encoders (who sometimes hold on to frames)
831 flush_encoders();
832
833 /* write the trailer, if any. The trailer must be written
834 * before you close the CodecContexts open when you wrote the
835 * header; otherwise write_trailer may try to use memory that
836 * was freed on av_codec_close() */
837 av_write_trailer(oc);
838
839 // Mark as 'written'
840 write_trailer = true;
841
842 ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::WriteTrailer");
843}
844
845// Flush encoders
846void FFmpegWriter::flush_encoders() {
847 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)
848 return;
849#if (LIBAVFORMAT_VERSION_MAJOR < 58)
850 // FFmpeg < 4.0
851 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)
852 return;
853#else
854 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)
855 return;
856#endif
857
858 // FLUSH VIDEO ENCODER
859 if (info.has_video) {
860 for (;;) {
861
862 // Increment PTS (in frames and scaled to the codec's timebase)
863 video_timestamp += av_rescale_q(1, av_make_q(info.fps.den, info.fps.num), video_codec_ctx->time_base);
864
865#if IS_FFMPEG_3_2
866 AVPacket* pkt = av_packet_alloc();
867#else
868 AVPacket* pkt;
869 av_init_packet(pkt);
870#endif
871 pkt->data = NULL;
872 pkt->size = 0;
873
874 /* encode the image */
875 int got_packet = 0;
876 int error_code = 0;
877
878#if IS_FFMPEG_3_2
879 // Encode video packet (latest version of FFmpeg)
880 error_code = avcodec_send_frame(video_codec_ctx, NULL);
881 got_packet = 0;
882 while (error_code >= 0) {
883 error_code = avcodec_receive_packet(video_codec_ctx, pkt);
884 if (error_code == AVERROR(EAGAIN)|| error_code == AVERROR_EOF) {
885 got_packet = 0;
886 // Write packet
887 avcodec_flush_buffers(video_codec_ctx);
888 break;
889 }
890 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
891 pkt->stream_index = video_st->index;
892 error_code = av_interleaved_write_frame(oc, pkt);
893 }
894#else // IS_FFMPEG_3_2
895
896 // Encode video packet (older than FFmpeg 3.2)
897 error_code = avcodec_encode_video2(video_codec_ctx, pkt, NULL, &got_packet);
898
899#endif // IS_FFMPEG_3_2
900
901 if (error_code < 0) {
903 "FFmpegWriter::flush_encoders ERROR ["
904 + av_err2string(error_code) + "]",
905 "error_code", error_code);
906 }
907 if (!got_packet) {
908 break;
909 }
910
911 // set the timestamp
912 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
913 pkt->stream_index = video_st->index;
914
915 // Write packet
916 error_code = av_interleaved_write_frame(oc, pkt);
917 if (error_code < 0) {
919 "FFmpegWriter::flush_encoders ERROR ["
920 + av_err2string(error_code) + "]",
921 "error_code", error_code);
922 }
923 }
924 }
925
926 // FLUSH AUDIO ENCODER
927 if (info.has_audio) {
928 for (;;) {
929#if IS_FFMPEG_3_2
930 AVPacket* pkt = av_packet_alloc();
931#else
932 AVPacket* pkt;
933 av_init_packet(pkt);
934#endif
935 pkt->data = NULL;
936 pkt->size = 0;
937 pkt->pts = pkt->dts = audio_timestamp;
938
939 /* encode the image */
940 int error_code = 0;
941 int got_packet = 0;
942#if IS_FFMPEG_3_2
943 error_code = avcodec_send_frame(audio_codec_ctx, NULL);
944#else
945 error_code = avcodec_encode_audio2(audio_codec_ctx, pkt, NULL, &got_packet);
946#endif
947 if (error_code < 0) {
949 "FFmpegWriter::flush_encoders ERROR ["
950 + av_err2string(error_code) + "]",
951 "error_code", error_code);
952 }
953 if (!got_packet) {
954 break;
955 }
956
957 // Since the PTS can change during encoding, set the value again. This seems like a huge hack,
958 // but it fixes lots of PTS related issues when I do this.
959 pkt->pts = pkt->dts = audio_timestamp;
960
961 // Scale the PTS to the audio stream timebase (which is sometimes different than the codec's timebase)
962 av_packet_rescale_ts(pkt, audio_codec_ctx->time_base, audio_st->time_base);
963
964 // set stream
965 pkt->stream_index = audio_st->index;
966 pkt->flags |= AV_PKT_FLAG_KEY;
967
968 // Write packet
969 error_code = av_interleaved_write_frame(oc, pkt);
970 if (error_code < 0) {
972 "FFmpegWriter::flush_encoders ERROR ["
973 + av_err2string(error_code) + "]",
974 "error_code", error_code);
975 }
976
977 // Increment PTS by duration of packet
978 audio_timestamp += pkt->duration;
979
980 // deallocate memory for packet
981 AV_FREE_PACKET(pkt);
982 }
983 }
984
985}
986
987// Close the video codec
988void FFmpegWriter::close_video(AVFormatContext *oc, AVStream *st)
989{
990#if USE_HW_ACCEL
991 if (hw_en_on && hw_en_supported) {
992 if (hw_device_ctx) {
993 av_buffer_unref(&hw_device_ctx);
994 hw_device_ctx = NULL;
995 }
996 }
997#endif // USE_HW_ACCEL
998
999 // Free any previous memory allocations
1000 if (video_codec_ctx != nullptr) {
1001 AV_FREE_CONTEXT(video_codec_ctx);
1002 av_free(video_codec_ctx);
1003 }
1004}
1005
1006// Close the audio codec
1007void FFmpegWriter::close_audio(AVFormatContext *oc, AVStream *st)
1008{
1009 // Clear buffers
1010 delete[] samples;
1011 delete[] audio_outbuf;
1012 delete[] audio_encoder_buffer;
1013 samples = NULL;
1014 audio_outbuf = NULL;
1015 audio_encoder_buffer = NULL;
1016
1017 // Deallocate resample buffer
1018 if (avr) {
1019 SWR_CLOSE(avr);
1020 SWR_FREE(&avr);
1021 avr = NULL;
1022 }
1023
1024 if (avr_planar) {
1025 SWR_CLOSE(avr_planar);
1026 SWR_FREE(&avr_planar);
1027 avr_planar = NULL;
1028 }
1029
1030 // Free any previous memory allocations
1031 if (audio_codec_ctx != nullptr) {
1032 AV_FREE_CONTEXT(audio_codec_ctx);
1033 av_free(audio_codec_ctx);
1034 }
1035}
1036
1037// Close the writer
1039 // Write trailer (if needed)
1040 if (!write_trailer)
1041 WriteTrailer();
1042
1043 // Close each codec
1044 if (video_st)
1045 close_video(oc, video_st);
1046 if (audio_st)
1047 close_audio(oc, audio_st);
1048
1049 // Deallocate image scalers
1050 if (image_rescalers.size() > 0)
1051 RemoveScalers();
1052
1053 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
1054 /* close the output file */
1055 avio_close(oc->pb);
1056 }
1057
1058 // Reset frame counters
1059 video_timestamp = 0;
1060 audio_timestamp = 0;
1061
1062 // Free the context which frees the streams too
1063 avformat_free_context(oc);
1064 oc = NULL;
1065
1066 // Close writer
1067 is_open = false;
1068 prepare_streams = false;
1069 write_header = false;
1070 write_trailer = false;
1071
1072 ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::Close");
1073}
1074
1075// Add an AVFrame to the cache
1076void FFmpegWriter::add_avframe(std::shared_ptr<Frame> frame, AVFrame *av_frame) {
1077 // Add AVFrame to map (if it does not already exist)
1078 if (!av_frames.count(frame)) {
1079 // Add av_frame
1080 av_frames[frame] = av_frame;
1081 } else {
1082 // Do not add, and deallocate this AVFrame
1083 AV_FREE_FRAME(&av_frame);
1084 }
1085}
1086
1087// Add an audio output stream
1088AVStream *FFmpegWriter::add_audio_stream() {
1089 // Find the audio codec
1090 const AVCodec *codec = avcodec_find_encoder_by_name(info.acodec.c_str());
1091 if (codec == NULL)
1092 throw InvalidCodec("A valid audio codec could not be found for this file.", path);
1093
1094 // Free any previous memory allocations
1095 if (audio_codec_ctx != nullptr) {
1096 AV_FREE_CONTEXT(audio_codec_ctx);
1097 }
1098
1099 // Create a new audio stream
1100 AVStream* st = avformat_new_stream(oc, codec);
1101 if (!st)
1102 throw OutOfMemory("Could not allocate memory for the video stream.", path);
1103
1104 // Allocate a new codec context for the stream
1105 ALLOC_CODEC_CTX(audio_codec_ctx, codec, st)
1106#if (LIBAVFORMAT_VERSION_MAJOR >= 58)
1107 st->codecpar->codec_id = codec->id;
1108#endif
1109 AVCodecContext* c = audio_codec_ctx;
1110
1111 c->codec_id = codec->id;
1112 c->codec_type = AVMEDIA_TYPE_AUDIO;
1113
1114 // Set the sample parameters
1115 c->bit_rate = info.audio_bit_rate;
1116#if !HAVE_CH_LAYOUT
1117 c->channels = info.channels;
1118#endif
1119
1120 // Set valid sample rate (or throw error)
1121 if (codec->supported_samplerates) {
1122 int i;
1123 for (i = 0; codec->supported_samplerates[i] != 0; i++)
1124 if (info.sample_rate == codec->supported_samplerates[i]) {
1125 // Set the valid sample rate
1126 c->sample_rate = info.sample_rate;
1127 break;
1128 }
1129 if (codec->supported_samplerates[i] == 0)
1130 throw InvalidSampleRate("An invalid sample rate was detected for this codec.", path);
1131 } else
1132 // Set sample rate
1133 c->sample_rate = info.sample_rate;
1134
1135
1136#if HAVE_CH_LAYOUT
1137 // Set a valid number of channels (or throw error)
1138 AVChannelLayout ch_layout;
1139 av_channel_layout_from_mask(&ch_layout, info.channel_layout);
1140 if (codec->ch_layouts) {
1141 int i;
1142 for (i = 0; av_channel_layout_check(&codec->ch_layouts[i]); i++)
1143 if (av_channel_layout_compare(&ch_layout, &codec->ch_layouts[i])) {
1144 // Set valid channel layout
1145 av_channel_layout_copy(&c->ch_layout, &ch_layout);
1146 break;
1147 }
1148 if (!av_channel_layout_check(&codec->ch_layouts[i]))
1149 throw InvalidChannels("An invalid channel layout was detected (i.e. MONO / STEREO).", path);
1150 } else
1151 // Set valid channel layout
1152 av_channel_layout_copy(&c->ch_layout, &ch_layout);
1153#else
1154 // Set a valid number of channels (or throw error)
1155 const uint64_t channel_layout = info.channel_layout;
1156 if (codec->channel_layouts) {
1157 int i;
1158 for (i = 0; codec->channel_layouts[i] != 0; i++)
1159 if (channel_layout == codec->channel_layouts[i]) {
1160 // Set valid channel layout
1161 c->channel_layout = channel_layout;
1162 break;
1163 }
1164 if (codec->channel_layouts[i] == 0)
1165 throw InvalidChannels("An invalid channel layout was detected (i.e. MONO / STEREO).", path);
1166 } else
1167 // Set valid channel layout
1168 c->channel_layout = channel_layout;
1169#endif
1170
1171 // Choose a valid sample_fmt
1172 if (codec->sample_fmts) {
1173 for (int i = 0; codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) {
1174 // Set sample format to 1st valid format (and then exit loop)
1175 c->sample_fmt = codec->sample_fmts[i];
1176 break;
1177 }
1178 }
1179 if (c->sample_fmt == AV_SAMPLE_FMT_NONE) {
1180 // Default if no sample formats found
1181 c->sample_fmt = AV_SAMPLE_FMT_S16;
1182 }
1183
1184 // some formats want stream headers to be separate
1185 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1186#if (LIBAVCODEC_VERSION_MAJOR >= 57)
1187 // FFmpeg 3.0+
1188 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1189#else
1190 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1191#endif
1192
1194
1195int nb_channels;
1196uint64_t channel_layout;
1197const char* nb_channels_label;
1198const char* channel_layout_label;
1199
1200#if HAVE_CH_LAYOUT
1201 nb_channels = c->ch_layout.nb_channels;
1202 channel_layout = c->ch_layout.u.mask;
1203 nb_channels_label = "c->ch_layout.nb_channels";
1204 channel_layout_label = "c->ch_layout.u.mask";
1205#else
1206 nb_channels = c->channels;
1207 channel_layout = c->channel_layout;
1208 nb_channels_label = "c->channels";
1209 channel_layout_label = "c->channel_layout";
1210#endif
1211
1213 "FFmpegWriter::add_audio_stream",
1214 "c->codec_id", c->codec_id,
1215 "c->bit_rate", c->bit_rate,
1216 nb_channels_label, nb_channels,
1217 "c->sample_fmt", c->sample_fmt,
1218 channel_layout_label, channel_layout,
1219 "c->sample_rate", c->sample_rate);
1220
1221 return st;
1222}
1223
1224// Add a video output stream
1225AVStream *FFmpegWriter::add_video_stream() {
1226 // Find the video codec
1227 const AVCodec *codec = avcodec_find_encoder_by_name(info.vcodec.c_str());
1228 if (codec == NULL)
1229 throw InvalidCodec("A valid video codec could not be found for this file.", path);
1230
1231 // Free any previous memory allocations
1232 if (video_codec_ctx != nullptr) {
1233 AV_FREE_CONTEXT(video_codec_ctx);
1234 }
1235
1236 // Create a new video stream
1237 AVStream* st = avformat_new_stream(oc, codec);
1238 if (!st)
1239 throw OutOfMemory("Could not allocate memory for the video stream.", path);
1240
1241 // Allocate a new codec context for the stream
1242 ALLOC_CODEC_CTX(video_codec_ctx, codec, st)
1243#if (LIBAVFORMAT_VERSION_MAJOR >= 58)
1244 st->codecpar->codec_id = codec->id;
1245#endif
1246
1247 AVCodecContext* c = video_codec_ctx;
1248
1249 c->codec_id = codec->id;
1250 c->codec_type = AVMEDIA_TYPE_VIDEO;
1251
1252 // Set sample aspect ratio
1253 c->sample_aspect_ratio.num = info.pixel_ratio.num;
1254 c->sample_aspect_ratio.den = info.pixel_ratio.den;
1255
1256 /* Init video encoder options */
1257 if (info.video_bit_rate >= 1000
1258#if (LIBAVCODEC_VERSION_MAJOR >= 58)
1259 && c->codec_id != AV_CODEC_ID_AV1
1260#endif
1261 ) {
1262 c->bit_rate = info.video_bit_rate;
1263 if (info.video_bit_rate >= 1500000) {
1264 if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
1265 c->qmin = 2;
1266 c->qmax = 30;
1267 }
1268 }
1269 // Here should be the setting for low fixed bitrate
1270 // Defaults are used because mpeg2 otherwise had problems
1271 } else {
1272 // Check if codec supports crf or qp
1273 switch (c->codec_id) {
1274#if (LIBAVCODEC_VERSION_MAJOR >= 58)
1275 // FFmpeg 4.0+
1276 case AV_CODEC_ID_AV1 :
1277 // TODO: Set `crf` or `qp` according to bitrate, as bitrate is not supported by these encoders yet.
1278 if (info.video_bit_rate >= 1000) {
1279 c->bit_rate = 0;
1280 if (strstr(info.vcodec.c_str(), "aom") != NULL) {
1281 int calculated_quality = 35;
1282 if (info.video_bit_rate < 500000) calculated_quality = 50;
1283 if (info.video_bit_rate > 5000000) calculated_quality = 10;
1284 av_opt_set_int(c->priv_data, "crf", calculated_quality, 0);
1285 info.video_bit_rate = calculated_quality;
1286 } else {
1287 int calculated_quality = 50;
1288 if (info.video_bit_rate < 500000) calculated_quality = 60;
1289 if (info.video_bit_rate > 5000000) calculated_quality = 15;
1290 av_opt_set_int(c->priv_data, "qp", calculated_quality, 0);
1291 info.video_bit_rate = calculated_quality;
1292 } // medium
1293 }
1294 if (strstr(info.vcodec.c_str(), "svtav1") != NULL) {
1295 av_opt_set_int(c->priv_data, "preset", 6, 0);
1296 av_opt_set_int(c->priv_data, "forced-idr",1,0);
1297 }
1298 else if (strstr(info.vcodec.c_str(), "rav1e") != NULL) {
1299 av_opt_set_int(c->priv_data, "speed", 7, 0);
1300 av_opt_set_int(c->priv_data, "tile-rows", 2, 0);
1301 av_opt_set_int(c->priv_data, "tile-columns", 4, 0);
1302 }
1303 else if (strstr(info.vcodec.c_str(), "aom") != NULL) {
1304 // Set number of tiles to a fixed value
1305 // TODO: Allow user to chose their own number of tiles
1306 av_opt_set_int(c->priv_data, "tile-rows", 1, 0); // log2 of number of rows
1307 av_opt_set_int(c->priv_data, "tile-columns", 2, 0); // log2 of number of columns
1308 av_opt_set_int(c->priv_data, "row-mt", 1, 0); // use multiple cores
1309 av_opt_set_int(c->priv_data, "cpu-used", 3, 0); // default is 1, usable is 4
1310 }
1311 //break;
1312#endif
1313 case AV_CODEC_ID_VP9 :
1314 case AV_CODEC_ID_HEVC :
1315 case AV_CODEC_ID_VP8 :
1316 case AV_CODEC_ID_H264 :
1317 if (info.video_bit_rate < 40) {
1318 c->qmin = 0;
1319 c->qmax = 63;
1320 } else {
1321 c->qmin = info.video_bit_rate - 5;
1322 c->qmax = 63;
1323 }
1324 break;
1325 default:
1326 // Here should be the setting for codecs that don't support crf
1327 // For now defaults are used
1328 break;
1329 }
1330 }
1331
1332 //TODO: Implement variable bitrate feature (which actually works). This implementation throws
1333 //invalid bitrate errors and rc buffer underflow errors, etc...
1334 //c->rc_min_rate = info.video_bit_rate;
1335 //c->rc_max_rate = info.video_bit_rate;
1336 //c->rc_buffer_size = FFMAX(c->rc_max_rate, 15000000) * 112L / 15000000 * 16384;
1337 //if ( !c->rc_initial_buffer_occupancy )
1338 // c->rc_initial_buffer_occupancy = c->rc_buffer_size * 3/4;
1339
1340 /* resolution must be a multiple of two */
1341 // TODO: require /2 height and width
1342 c->width = info.width;
1343 c->height = info.height;
1344
1345 /* time base: this is the fundamental unit of time (in seconds) in terms
1346 of which frame timestamps are represented. for fixed-fps content,
1347 timebase should be 1/framerate and timestamp increments should be
1348 identically 1. */
1349 c->time_base.num = info.video_timebase.num;
1350 c->time_base.den = info.video_timebase.den;
1351// AVCodecContext->framerate was added in FFmpeg 2.6
1352#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 26, 0)
1353 c->framerate = av_inv_q(c->time_base);
1354#endif
1355 st->avg_frame_rate = av_inv_q(c->time_base);
1356 st->time_base.num = info.video_timebase.num;
1357 st->time_base.den = info.video_timebase.den;
1358
1359 c->gop_size = 12; /* TODO: add this to "info"... emit one intra frame every twelve frames at most */
1360 c->max_b_frames = 10;
1361 if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO)
1362 /* just for testing, we also add B frames */
1363 c->max_b_frames = 2;
1364 if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO)
1365 /* Needed to avoid using macroblocks in which some coeffs overflow.
1366 This does not happen with normal video, it just happens here as
1367 the motion of the chroma plane does not match the luma plane. */
1368 c->mb_decision = 2;
1369 // some formats want stream headers to be separate
1370 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1371#if (LIBAVCODEC_VERSION_MAJOR >= 57)
1372 // FFmpeg 3.0+
1373 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1374#else
1375 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1376#endif
1377
1378 // Find all supported pixel formats for this codec
1379 const PixelFormat *supported_pixel_formats = codec->pix_fmts;
1380 while (supported_pixel_formats != NULL && *supported_pixel_formats != PIX_FMT_NONE) {
1381 // Assign the 1st valid pixel format (if one is missing)
1382 if (c->pix_fmt == PIX_FMT_NONE)
1383 c->pix_fmt = *supported_pixel_formats;
1384 ++supported_pixel_formats;
1385 }
1386
1387 // Codec doesn't have any pix formats?
1388 if (c->pix_fmt == PIX_FMT_NONE) {
1389 if (oc->oformat->video_codec == AV_CODEC_ID_RAWVIDEO) {
1390 // Raw video should use RGB24
1391 c->pix_fmt = PIX_FMT_RGB24;
1392
1393#if (LIBAVFORMAT_VERSION_MAJOR < 58)
1394 // FFmpeg < 4.0
1395 if (strcmp(oc->oformat->name, "gif") != 0)
1396 // If not GIF format, skip the encoding process
1397 // Set raw picture flag (so we don't encode this video)
1398 oc->oformat->flags |= AVFMT_RAWPICTURE;
1399#endif
1400 } else {
1401 // Set the default codec
1402 c->pix_fmt = PIX_FMT_YUV420P;
1403 }
1404 }
1405
1408 "FFmpegWriter::add_video_stream ("
1409 + (std::string)oc->oformat->name + " : "
1410 + (std::string)av_get_pix_fmt_name(c->pix_fmt) + ")",
1411 "c->codec_id", c->codec_id,
1412 "c->bit_rate", c->bit_rate,
1413 "c->pix_fmt", c->pix_fmt,
1414 "oc->oformat->flags", oc->oformat->flags);
1415 return st;
1416}
1417
1418// open audio codec
1419void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st) {
1420 const AVCodec *codec;
1421 AV_GET_CODEC_FROM_STREAM(st, audio_codec_ctx)
1422
1423 // Set number of threads equal to number of processors (not to exceed 16)
1424 audio_codec_ctx->thread_count = std::min(FF_NUM_PROCESSORS, 16);
1425
1426 // Find the audio encoder
1427 codec = avcodec_find_encoder_by_name(info.acodec.c_str());
1428 if (!codec)
1429 codec = avcodec_find_encoder(audio_codec_ctx->codec_id);
1430 if (!codec)
1431 throw InvalidCodec("Could not find codec", path);
1432
1433 // Init options
1434 AVDictionary *opts = NULL;
1435 av_dict_set(&opts, "strict", "experimental", 0);
1436
1437 // Open the codec
1438 if (avcodec_open2(audio_codec_ctx, codec, &opts) < 0)
1439 throw InvalidCodec("Could not open audio codec", path);
1440 AV_COPY_PARAMS_FROM_CONTEXT(st, audio_codec_ctx);
1441
1442 // Free options
1443 av_dict_free(&opts);
1444
1445 // Calculate the size of the input frame (i..e how many samples per packet), and the output buffer
1446 // TODO: Ugly hack for PCM codecs (will be removed ASAP with new PCM support to compute the input frame size in samples
1447 if (audio_codec_ctx->frame_size <= 1) {
1448 // No frame size found... so calculate
1449 audio_input_frame_size = 50000 / info.channels;
1450
1451 int s = AV_FIND_DECODER_CODEC_ID(st);
1452 switch (s) {
1453 case AV_CODEC_ID_PCM_S16LE:
1454 case AV_CODEC_ID_PCM_S16BE:
1455 case AV_CODEC_ID_PCM_U16LE:
1456 case AV_CODEC_ID_PCM_U16BE:
1457 audio_input_frame_size >>= 1;
1458 break;
1459 default:
1460 break;
1461 }
1462 } else {
1463 // Set frame size based on the codec
1464 audio_input_frame_size = audio_codec_ctx->frame_size;
1465 }
1466
1467 // Set the initial frame size (since it might change during resampling)
1468 initial_audio_input_frame_size = audio_input_frame_size;
1469
1470 // Allocate array for samples
1471 samples = new int16_t[AVCODEC_MAX_AUDIO_FRAME_SIZE];
1472
1473 // Set audio output buffer (used to store the encoded audio)
1474 audio_outbuf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
1475 audio_outbuf = new uint8_t[audio_outbuf_size];
1476
1477 // Set audio packet encoding buffer
1478 audio_encoder_buffer_size = AUDIO_PACKET_ENCODING_SIZE;
1479 audio_encoder_buffer = new uint8_t[audio_encoder_buffer_size];
1480
1481 // Add audio metadata (if any)
1482 for (std::map<std::string, std::string>::iterator iter = info.metadata.begin(); iter != info.metadata.end(); ++iter) {
1483 av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1484 }
1485
1487 "FFmpegWriter::open_audio",
1488 "audio_codec_ctx->thread_count", audio_codec_ctx->thread_count,
1489 "audio_input_frame_size", audio_input_frame_size,
1491}
1492
1493// open video codec
1494void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) {
1495 const AVCodec *codec;
1496 AV_GET_CODEC_FROM_STREAM(st, video_codec_ctx)
1497
1498 // Set number of threads equal to number of processors (not to exceed 16)
1499 video_codec_ctx->thread_count = std::min(FF_NUM_PROCESSORS, 16);
1500
1501#if USE_HW_ACCEL
1502 if (hw_en_on && hw_en_supported) {
1503 //char *dev_hw = NULL;
1504 char adapter[256];
1505 char *adapter_ptr = NULL;
1506 int adapter_num;
1507 // Use the hw device given in the environment variable HW_EN_DEVICE_SET or the default if not set
1509 std::clog << "Encoding Device Nr: " << adapter_num << "\n";
1510 if (adapter_num < 3 && adapter_num >=0) {
1511#if defined(__linux__)
1512 snprintf(adapter,sizeof(adapter),"/dev/dri/renderD%d", adapter_num+128);
1513 // Maybe 127 is better because the first card would be 1?!
1514 adapter_ptr = adapter;
1515#elif defined(_WIN32) || defined(__APPLE__)
1516 adapter_ptr = NULL;
1517#endif
1518 }
1519 else {
1520 adapter_ptr = NULL; // Just to be sure
1521 }
1522// Check if it is there and writable
1523#if defined(__linux__)
1524 if( adapter_ptr != NULL && access( adapter_ptr, W_OK ) == 0 ) {
1525#elif defined(_WIN32) || defined(__APPLE__)
1526 if( adapter_ptr != NULL ) {
1527#endif
1529 "Encode Device present using device",
1530 "adapter", adapter_num);
1531 }
1532 else {
1533 adapter_ptr = NULL; // use default
1535 "Encode Device not present, using default");
1536 }
1537 if (av_hwdevice_ctx_create(&hw_device_ctx,
1538 hw_en_av_device_type, adapter_ptr, NULL, 0) < 0)
1539 {
1541 "FFmpegWriter::open_video ERROR creating hwdevice, Codec name:",
1542 info.vcodec.c_str(), -1);
1543 throw InvalidCodec("Could not create hwdevice", path);
1544 }
1545 }
1546#endif // USE_HW_ACCEL
1547
1548 /* find the video encoder */
1549 codec = avcodec_find_encoder_by_name(info.vcodec.c_str());
1550 if (!codec)
1551 codec = avcodec_find_encoder(AV_FIND_DECODER_CODEC_ID(st));
1552 if (!codec)
1553 throw InvalidCodec("Could not find codec", path);
1554
1555 /* Force max_b_frames to 0 in some cases (i.e. for mjpeg image sequences */
1556 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)
1557 video_codec_ctx->max_b_frames = 0;
1558
1559 // Init options
1560 AVDictionary *opts = NULL;
1561 av_dict_set(&opts, "strict", "experimental", 0);
1562
1563#if USE_HW_ACCEL
1565 video_codec_ctx->pix_fmt = hw_en_av_pix_fmt;
1566
1567 // for the list of possible options, see the list of codec-specific options:
1568 // e.g. ffmpeg -h encoder=h264_vaapi or ffmpeg -h encoder=hevc_vaapi
1569 // and "man ffmpeg-codecs"
1570
1571 // For VAAPI, it is safer to explicitly set rc_mode instead of relying on auto-selection
1572 // which is ffmpeg version-specific.
1573 if (hw_en_av_pix_fmt == AV_PIX_FMT_VAAPI) {
1574 int64_t qp;
1575 if (av_opt_get_int(video_codec_ctx->priv_data, "qp", 0, &qp) != 0 || qp == 0) {
1576 // unless "qp" was set for CQP, switch to VBR RC mode
1577 av_opt_set(video_codec_ctx->priv_data, "rc_mode", "VBR", 0);
1578
1579 // In the current state (ffmpeg-4.2-4 libva-mesa-driver-19.1.5-1) to use VBR,
1580 // one has to specify both bit_rate and maxrate, otherwise a small low quality file is generated on Intel iGPU).
1581 video_codec_ctx->rc_max_rate = video_codec_ctx->bit_rate;
1582 }
1583 }
1584
1585 switch (video_codec_ctx->codec_id) {
1586 case AV_CODEC_ID_H264:
1587 video_codec_ctx->max_b_frames = 0; // At least this GPU doesn't support b-frames
1588 video_codec_ctx->profile = FF_PROFILE_H264_BASELINE | FF_PROFILE_H264_CONSTRAINED;
1589 av_opt_set(video_codec_ctx->priv_data, "preset", "slow", 0);
1590 av_opt_set(video_codec_ctx->priv_data, "tune", "zerolatency", 0);
1591 av_opt_set(video_codec_ctx->priv_data, "vprofile", "baseline", AV_OPT_SEARCH_CHILDREN);
1592 break;
1593 case AV_CODEC_ID_HEVC:
1594 // tested to work with defaults
1595 break;
1596 case AV_CODEC_ID_VP9:
1597 // tested to work with defaults
1598 break;
1599 default:
1601 "No codec-specific options defined for this codec. HW encoding may fail",
1602 "codec_id", video_codec_ctx->codec_id);
1603 break;
1604 }
1605
1606 // set hw_frames_ctx for encoder's AVCodecContext
1607 int err;
1608 if ((err = set_hwframe_ctx(video_codec_ctx, hw_device_ctx, info.width, info.height)) < 0)
1609 {
1611 "FFmpegWriter::open_video (set_hwframe_ctx) ERROR faled to set hwframe context",
1612 "width", info.width,
1613 "height", info.height,
1614 av_err2string(err), -1);
1615 }
1616 }
1617#endif // USE_HW_ACCEL
1618
1619 /* open the codec */
1620 if (avcodec_open2(video_codec_ctx, codec, &opts) < 0)
1621 throw InvalidCodec("Could not open video codec", path);
1622 AV_COPY_PARAMS_FROM_CONTEXT(st, video_codec_ctx);
1623
1624 // Free options
1625 av_dict_free(&opts);
1626
1627 // Add video metadata (if any)
1628 for (std::map<std::string, std::string>::iterator iter = info.metadata.begin(); iter != info.metadata.end(); ++iter) {
1629 av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1630 }
1631
1633 "FFmpegWriter::open_video",
1634 "video_codec_ctx->thread_count", video_codec_ctx->thread_count);
1635
1636}
1637
1638// write all queued frames' audio to the video file
1639void FFmpegWriter::write_audio_packets(bool is_final) {
1640 // Init audio buffers / variables
1641 int total_frame_samples = 0;
1642 int frame_position = 0;
1643 int channels_in_frame = 0;
1644 int sample_rate_in_frame = 0;
1645 int samples_in_frame = 0;
1646 ChannelLayout channel_layout_in_frame = LAYOUT_MONO; // default channel layout
1647
1648 // Create a new array (to hold all S16 audio samples, for the current queued frames
1649 unsigned int all_queued_samples_size = sizeof(int16_t) * (queued_audio_frames.size() * AVCODEC_MAX_AUDIO_FRAME_SIZE);
1650 int16_t *all_queued_samples = (int16_t *) av_malloc(all_queued_samples_size);
1651 int16_t *all_resampled_samples = NULL;
1652 int16_t *final_samples_planar = NULL;
1653 int16_t *final_samples = NULL;
1654
1655 // Loop through each queued audio frame
1656 while (!queued_audio_frames.empty()) {
1657 // Get front frame (from the queue)
1658 std::shared_ptr<Frame> frame = queued_audio_frames.front();
1659
1660 // Get the audio details from this frame
1661 sample_rate_in_frame = frame->SampleRate();
1662 samples_in_frame = frame->GetAudioSamplesCount();
1663 channels_in_frame = frame->GetAudioChannelsCount();
1664 channel_layout_in_frame = frame->ChannelsLayout();
1665
1666 // Get audio sample array
1667 float *frame_samples_float = NULL;
1668 // Get samples interleaved together (c1 c2 c1 c2 c1 c2)
1669 frame_samples_float = frame->GetInterleavedAudioSamples(&samples_in_frame);
1670
1671 // Calculate total samples
1672 total_frame_samples = samples_in_frame * channels_in_frame;
1673
1674 // Translate audio sample values back to 16 bit integers with saturation
1675 const int16_t max16 = 32767;
1676 const int16_t min16 = -32768;
1677 for (int s = 0; s < total_frame_samples; s++, frame_position++) {
1678 float valF = frame_samples_float[s] * (1 << 15);
1679 int16_t conv;
1680 if (valF > max16) {
1681 conv = max16;
1682 } else if (valF < min16) {
1683 conv = min16;
1684 } else {
1685 conv = int(valF + 32768.5) - 32768; // +0.5 is for rounding
1686 }
1687
1688 // Copy into buffer
1689 all_queued_samples[frame_position] = conv;
1690 }
1691
1692 // Deallocate float array
1693 delete[] frame_samples_float;
1694
1695 // Remove front item
1696 queued_audio_frames.pop_front();
1697
1698 } // end while
1699
1700
1701 // Update total samples (since we've combined all queued frames)
1702 total_frame_samples = frame_position;
1703 int remaining_frame_samples = total_frame_samples;
1704 int samples_position = 0;
1705
1706
1708 "FFmpegWriter::write_audio_packets",
1709 "is_final", is_final,
1710 "total_frame_samples", total_frame_samples,
1711 "channel_layout_in_frame", channel_layout_in_frame,
1712 "channels_in_frame", channels_in_frame,
1713 "samples_in_frame", samples_in_frame,
1714 "LAYOUT_MONO", LAYOUT_MONO);
1715
1716 // Keep track of the original sample format
1717 AVSampleFormat output_sample_fmt = audio_codec_ctx->sample_fmt;
1718
1719 AVFrame *audio_frame = NULL;
1720 if (!is_final) {
1721 // Create input frame (and allocate arrays)
1722 audio_frame = AV_ALLOCATE_FRAME();
1723 AV_RESET_FRAME(audio_frame);
1724 audio_frame->nb_samples = total_frame_samples / channels_in_frame;
1725
1726 // Fill input frame with sample data
1727 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);
1728 if (error_code < 0) {
1730 "FFmpegWriter::write_audio_packets ERROR ["
1731 + av_err2string(error_code) + "]",
1732 "error_code", error_code);
1733 }
1734
1735 // Do not convert audio to planar format (yet). We need to keep everything interleaved at this point.
1736 switch (audio_codec_ctx->sample_fmt) {
1737 case AV_SAMPLE_FMT_FLTP: {
1738 output_sample_fmt = AV_SAMPLE_FMT_FLT;
1739 break;
1740 }
1741 case AV_SAMPLE_FMT_S32P: {
1742 output_sample_fmt = AV_SAMPLE_FMT_S32;
1743 break;
1744 }
1745 case AV_SAMPLE_FMT_S16P: {
1746 output_sample_fmt = AV_SAMPLE_FMT_S16;
1747 break;
1748 }
1749 case AV_SAMPLE_FMT_U8P: {
1750 output_sample_fmt = AV_SAMPLE_FMT_U8;
1751 break;
1752 }
1753 default: {
1754 // This is only here to silence unused-enum warnings
1755 break;
1756 }
1757 }
1758
1759 // Update total samples & input frame size (due to bigger or smaller data types)
1760 total_frame_samples *= (float(info.sample_rate) / sample_rate_in_frame); // adjust for different byte sizes
1761 total_frame_samples *= (float(info.channels) / channels_in_frame); // adjust for different # of channels
1762
1763 // Create output frame (and allocate arrays)
1764 AVFrame *audio_converted = AV_ALLOCATE_FRAME();
1765 AV_RESET_FRAME(audio_converted);
1766 audio_converted->nb_samples = total_frame_samples / channels_in_frame;
1767 av_samples_alloc(audio_converted->data, audio_converted->linesize, info.channels, audio_converted->nb_samples, output_sample_fmt, 0);
1768
1770 "FFmpegWriter::write_audio_packets (1st resampling)",
1771 "in_sample_fmt", AV_SAMPLE_FMT_S16,
1772 "out_sample_fmt", output_sample_fmt,
1773 "in_sample_rate", sample_rate_in_frame,
1774 "out_sample_rate", info.sample_rate,
1775 "in_channels", channels_in_frame,
1776 "out_channels", info.channels);
1777
1778 // setup resample context
1779 if (!avr) {
1780 avr = SWR_ALLOC();
1781#if HAVE_CH_LAYOUT
1782 AVChannelLayout in_chlayout;
1783 AVChannelLayout out_chlayout;
1784 av_channel_layout_from_mask(&in_chlayout, channel_layout_in_frame);
1785 av_channel_layout_from_mask(&out_chlayout, info.channel_layout);
1786 av_opt_set_chlayout(avr, "in_chlayout", &in_chlayout, 0);
1787 av_opt_set_chlayout(avr, "out_chlayout", &out_chlayout, 0);
1788#else
1789 av_opt_set_int(avr, "in_channel_layout", channel_layout_in_frame, 0);
1790 av_opt_set_int(avr, "out_channel_layout", info.channel_layout, 0);
1791 av_opt_set_int(avr, "in_channels", channels_in_frame, 0);
1792 av_opt_set_int(avr, "out_channels", info.channels, 0);
1793#endif
1794 av_opt_set_int(avr, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
1795 av_opt_set_int(avr, "out_sample_fmt", output_sample_fmt, 0); // planar not allowed here
1796 av_opt_set_int(avr, "in_sample_rate", sample_rate_in_frame, 0);
1797 av_opt_set_int(avr, "out_sample_rate", info.sample_rate, 0);
1798 SWR_INIT(avr);
1799 }
1800 // Convert audio samples
1801 int nb_samples = SWR_CONVERT(
1802 avr, // audio resample context
1803 audio_converted->data, // output data pointers
1804 audio_converted->linesize[0], // output plane size, in bytes. (0 if unknown)
1805 audio_converted->nb_samples, // maximum number of samples that the output buffer can hold
1806 audio_frame->data, // input data pointers
1807 audio_frame->linesize[0], // input plane size, in bytes (0 if unknown)
1808 audio_frame->nb_samples // number of input samples to convert
1809 );
1810
1811 // Set remaining samples
1812 remaining_frame_samples = total_frame_samples;
1813
1814 // Create a new array (to hold all resampled S16 audio samples)
1815 all_resampled_samples = (int16_t *) av_malloc(
1816 sizeof(int16_t) * nb_samples * info.channels
1817 * (av_get_bytes_per_sample(output_sample_fmt) /
1818 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1819 );
1820
1821 // Copy audio samples over original samples
1822 memcpy(all_resampled_samples, audio_converted->data[0],
1823 static_cast<size_t>(nb_samples)
1824 * info.channels
1825 * av_get_bytes_per_sample(output_sample_fmt));
1826
1827 // Remove converted audio
1828 av_freep(&(audio_frame->data[0]));
1829 AV_FREE_FRAME(&audio_frame);
1830 av_freep(&audio_converted->data[0]);
1831 AV_FREE_FRAME(&audio_converted);
1832 all_queued_samples = NULL; // this array cleared with above call
1833
1835 "FFmpegWriter::write_audio_packets (Successfully completed 1st resampling)",
1836 "nb_samples", nb_samples,
1837 "remaining_frame_samples", remaining_frame_samples);
1838 }
1839
1840 // Loop until no more samples
1841 while (remaining_frame_samples > 0 || is_final) {
1842 // Get remaining samples needed for this packet
1843 int remaining_packet_samples = (audio_input_frame_size * info.channels) - audio_input_position;
1844
1845 // Determine how many samples we need
1846 int diff = 0;
1847 if (remaining_frame_samples >= remaining_packet_samples) {
1848 diff = remaining_packet_samples;
1849 } else {
1850 diff = remaining_frame_samples;
1851 }
1852
1853 // Copy frame samples into the packet samples array
1854 if (!is_final)
1855 //TODO: Make this more sane
1856 memcpy(
1857 samples + (audio_input_position
1858 * (av_get_bytes_per_sample(output_sample_fmt) /
1859 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1860 ),
1861 all_resampled_samples + samples_position,
1862 static_cast<size_t>(diff)
1863 * av_get_bytes_per_sample(output_sample_fmt)
1864 );
1865
1866 // Increment counters
1867 audio_input_position += diff;
1868 samples_position += diff * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16));
1869 remaining_frame_samples -= diff;
1870
1871 // Do we have enough samples to proceed?
1872 if (audio_input_position < (audio_input_frame_size * info.channels) && !is_final)
1873 // Not enough samples to encode... so wait until the next frame
1874 break;
1875
1876 // Convert to planar (if needed by audio codec)
1877 AVFrame *frame_final = AV_ALLOCATE_FRAME();
1878 AV_RESET_FRAME(frame_final);
1879 if (av_sample_fmt_is_planar(audio_codec_ctx->sample_fmt)) {
1881 "FFmpegWriter::write_audio_packets (2nd resampling for Planar formats)",
1882 "in_sample_fmt", output_sample_fmt,
1883 "out_sample_fmt", audio_codec_ctx->sample_fmt,
1884 "in_sample_rate", info.sample_rate,
1885 "out_sample_rate", info.sample_rate,
1886 "in_channels", info.channels,
1887 "out_channels", info.channels
1888 );
1889
1890 // setup resample context
1891 if (!avr_planar) {
1892 avr_planar = SWR_ALLOC();
1893#if HAVE_CH_LAYOUT
1894 AVChannelLayout layout;
1895 av_channel_layout_from_mask(&layout, info.channel_layout);
1896 av_opt_set_chlayout(avr_planar, "in_chlayout", &layout, 0);
1897 av_opt_set_chlayout(avr_planar, "out_chlayout", &layout, 0);
1898#else
1899 av_opt_set_int(avr_planar, "in_channel_layout", info.channel_layout, 0);
1900 av_opt_set_int(avr_planar, "out_channel_layout", info.channel_layout, 0);
1901 av_opt_set_int(avr_planar, "in_channels", info.channels, 0);
1902 av_opt_set_int(avr_planar, "out_channels", info.channels, 0);
1903#endif
1904 av_opt_set_int(avr_planar, "in_sample_fmt", output_sample_fmt, 0);
1905 av_opt_set_int(avr_planar, "out_sample_fmt", audio_codec_ctx->sample_fmt, 0); // planar not allowed here
1906 av_opt_set_int(avr_planar, "in_sample_rate", info.sample_rate, 0);
1907 av_opt_set_int(avr_planar, "out_sample_rate", info.sample_rate, 0);
1908 SWR_INIT(avr_planar);
1909 }
1910
1911 // Create input frame (and allocate arrays)
1912 audio_frame = AV_ALLOCATE_FRAME();
1913 AV_RESET_FRAME(audio_frame);
1914 audio_frame->nb_samples = audio_input_position / info.channels;
1915
1916 // Create a new array
1917 final_samples_planar = (int16_t *) av_malloc(
1918 sizeof(int16_t) * audio_frame->nb_samples * info.channels
1919 * (av_get_bytes_per_sample(output_sample_fmt) /
1920 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1921 );
1922
1923 // Copy audio into buffer for frame
1924 memcpy(final_samples_planar, samples,
1925 static_cast<size_t>(audio_frame->nb_samples)
1926 * info.channels
1927 * av_get_bytes_per_sample(output_sample_fmt));
1928
1929 // Fill input frame with sample data
1930 avcodec_fill_audio_frame(audio_frame, info.channels, output_sample_fmt,
1931 (uint8_t *) final_samples_planar, audio_encoder_buffer_size, 0);
1932
1933 // Create output frame (and allocate arrays)
1934 frame_final->nb_samples = audio_input_frame_size;
1935#if HAVE_CH_LAYOUT
1936 av_channel_layout_from_mask(&frame_final->ch_layout, info.channel_layout);
1937#else
1938 frame_final->channels = info.channels;
1939 frame_final->channel_layout = info.channel_layout;
1940#endif
1941 frame_final->format = audio_codec_ctx->sample_fmt;
1942 av_samples_alloc(frame_final->data, frame_final->linesize, info.channels,
1943 frame_final->nb_samples, audio_codec_ctx->sample_fmt, 0);
1944
1945 // Convert audio samples
1946 int nb_samples = SWR_CONVERT(
1947 avr_planar, // audio resample context
1948 frame_final->data, // output data pointers
1949 frame_final->linesize[0], // output plane size, in bytes. (0 if unknown)
1950 frame_final->nb_samples, // maximum number of samples that the output buffer can hold
1951 audio_frame->data, // input data pointers
1952 audio_frame->linesize[0], // input plane size, in bytes (0 if unknown)
1953 audio_frame->nb_samples // number of input samples to convert
1954 );
1955
1956 // Copy audio samples over original samples
1957 const auto copy_length = static_cast<size_t>(nb_samples)
1958 * av_get_bytes_per_sample(audio_codec_ctx->sample_fmt)
1959 * info.channels;
1960
1961 if (nb_samples > 0)
1962 memcpy(samples, frame_final->data[0], copy_length);
1963
1964 // deallocate AVFrame
1965 av_freep(&(audio_frame->data[0]));
1966 AV_FREE_FRAME(&audio_frame);
1967 all_queued_samples = NULL; // this array cleared with above call
1968
1970 "FFmpegWriter::write_audio_packets (Successfully completed 2nd resampling for Planar formats)",
1971 "nb_samples", nb_samples);
1972
1973 } else {
1974 // Create a new array
1975 const auto buf_size = static_cast<size_t>(audio_input_position)
1976 * (av_get_bytes_per_sample(audio_codec_ctx->sample_fmt) /
1977 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)
1978 );
1979 final_samples = reinterpret_cast<int16_t*>(
1980 av_malloc(sizeof(int16_t) * buf_size));
1981
1982 // Copy audio into buffer for frame
1983 memcpy(final_samples, samples,
1984 audio_input_position * av_get_bytes_per_sample(audio_codec_ctx->sample_fmt));
1985
1986 // Init the nb_samples property
1987 frame_final->nb_samples = audio_input_frame_size;
1988
1989 // Fill the final_frame AVFrame with audio (non planar)
1990#if HAVE_CH_LAYOUT
1991 int nb_channels = audio_codec_ctx->ch_layout.nb_channels;
1992#else
1993 int nb_channels = audio_codec_ctx->channels;
1994#endif
1995 avcodec_fill_audio_frame(frame_final, nb_channels,
1996 audio_codec_ctx->sample_fmt, (uint8_t *) final_samples,
1997 audio_encoder_buffer_size, 0);
1998 }
1999
2000 // Set the AVFrame's PTS
2001 frame_final->pts = audio_timestamp;
2002
2003 // Init the packet
2004#if IS_FFMPEG_3_2
2005 AVPacket* pkt = av_packet_alloc();
2006#else
2007 AVPacket* pkt;
2008 av_init_packet(pkt);
2009#endif
2010 pkt->data = audio_encoder_buffer;
2011 pkt->size = audio_encoder_buffer_size;
2012
2013 // Set the packet's PTS prior to encoding
2014 pkt->pts = pkt->dts = audio_timestamp;
2015
2016 /* encode the audio samples */
2017 int got_packet_ptr = 0;
2018
2019#if IS_FFMPEG_3_2
2020 // Encode audio (latest version of FFmpeg)
2021 int error_code;
2022 int ret = 0;
2023 int frame_finished = 0;
2024 error_code = ret = avcodec_send_frame(audio_codec_ctx, frame_final);
2025 if (ret < 0 && ret != AVERROR(EINVAL) && ret != AVERROR_EOF) {
2026 avcodec_send_frame(audio_codec_ctx, NULL);
2027 }
2028 else {
2029 if (ret >= 0)
2030 pkt->size = 0;
2031 ret = avcodec_receive_packet(audio_codec_ctx, pkt);
2032 if (ret >= 0)
2033 frame_finished = 1;
2034 if(ret == AVERROR(EINVAL) || ret == AVERROR_EOF) {
2035 avcodec_flush_buffers(audio_codec_ctx);
2036 ret = 0;
2037 }
2038 if (ret >= 0) {
2039 ret = frame_finished;
2040 }
2041 }
2042 if (!pkt->data && !frame_finished)
2043 {
2044 ret = -1;
2045 }
2046 got_packet_ptr = ret;
2047#else
2048 // Encode audio (older versions of FFmpeg)
2049 int error_code = avcodec_encode_audio2(audio_codec_ctx, pkt, frame_final, &got_packet_ptr);
2050#endif
2051 /* if zero size, it means the image was buffered */
2052 if (error_code == 0 && got_packet_ptr) {
2053
2054 // Since the PTS can change during encoding, set the value again. This seems like a huge hack,
2055 // but it fixes lots of PTS related issues when I do this.
2056 pkt->pts = pkt->dts = audio_timestamp;
2057
2058 // Scale the PTS to the audio stream timebase (which is sometimes different than the codec's timebase)
2059 av_packet_rescale_ts(pkt, audio_codec_ctx->time_base, audio_st->time_base);
2060
2061 // set stream
2062 pkt->stream_index = audio_st->index;
2063 pkt->flags |= AV_PKT_FLAG_KEY;
2064
2065 /* write the compressed frame in the media file */
2066 error_code = av_interleaved_write_frame(oc, pkt);
2067 }
2068
2069 if (error_code < 0) {
2071 "FFmpegWriter::write_audio_packets ERROR ["
2072 + av_err2string(error_code) + "]",
2073 "error_code", error_code);
2074 }
2075
2076 // Increment PTS (no pkt.duration, so calculate with maths)
2077 audio_timestamp += FFMIN(audio_input_frame_size, audio_input_position);
2078
2079 // deallocate AVFrame
2080 av_freep(&(frame_final->data[0]));
2081 AV_FREE_FRAME(&frame_final);
2082
2083 // deallocate memory for packet
2084 AV_FREE_PACKET(pkt);
2085
2086 // Reset position
2087 audio_input_position = 0;
2088 is_final = false;
2089 }
2090
2091 // Delete arrays (if needed)
2092 if (all_resampled_samples) {
2093 av_freep(&all_resampled_samples);
2094 all_resampled_samples = NULL;
2095 }
2096 if (all_queued_samples) {
2097 av_freep(&all_queued_samples);
2098 all_queued_samples = NULL;
2099 }
2100}
2101
2102// Allocate an AVFrame object
2103AVFrame *FFmpegWriter::allocate_avframe(PixelFormat pix_fmt, int width, int height, int *buffer_size, uint8_t *new_buffer) {
2104 // Create an RGB AVFrame
2105 AVFrame *new_av_frame = NULL;
2106
2107 // Allocate an AVFrame structure
2108 new_av_frame = AV_ALLOCATE_FRAME();
2109 if (new_av_frame == NULL)
2110 throw OutOfMemory("Could not allocate AVFrame", path);
2111
2112 // Determine required buffer size and allocate buffer
2113 *buffer_size = AV_GET_IMAGE_SIZE(pix_fmt, width, height);
2114
2115 // Create buffer (if not provided)
2116 if (!new_buffer) {
2117 // New Buffer
2118 new_buffer = (uint8_t *) av_malloc(*buffer_size * sizeof(uint8_t));
2119 // Attach buffer to AVFrame
2120 AV_COPY_PICTURE_DATA(new_av_frame, new_buffer, pix_fmt, width, height);
2121 new_av_frame->width = width;
2122 new_av_frame->height = height;
2123 new_av_frame->format = pix_fmt;
2124 }
2125
2126 // return AVFrame
2127 return new_av_frame;
2128}
2129
2130// process video frame
2131void FFmpegWriter::process_video_packet(std::shared_ptr<Frame> frame) {
2132 // Determine the height & width of the source image
2133 int source_image_width = frame->GetWidth();
2134 int source_image_height = frame->GetHeight();
2135
2136 // Do nothing if size is 1x1 (i.e. no image in this frame)
2137 if (source_image_height == 1 && source_image_width == 1)
2138 return;
2139
2140 // Init rescalers (if not initialized yet)
2141 if (image_rescalers.size() == 0)
2142 InitScalers(source_image_width, source_image_height);
2143
2144 // Get a unique rescaler (for this thread)
2145 SwsContext *scaler = image_rescalers[rescaler_position];
2146 rescaler_position++;
2147 if (rescaler_position == num_of_rescalers)
2148 rescaler_position = 0;
2149
2150 // Allocate an RGB frame & final output frame
2151 int bytes_source = 0;
2152 int bytes_final = 0;
2153 AVFrame *frame_source = NULL;
2154 const uchar *pixels = NULL;
2155
2156 // Get a list of pixels from source image
2157 pixels = frame->GetPixels();
2158
2159 // Init AVFrame for source image & final (converted image)
2160 frame_source = allocate_avframe(PIX_FMT_RGBA, source_image_width, source_image_height, &bytes_source, (uint8_t *) pixels);
2161#if IS_FFMPEG_3_2
2162 AVFrame *frame_final;
2163#if USE_HW_ACCEL
2164 if (hw_en_on && hw_en_supported) {
2165 frame_final = allocate_avframe(AV_PIX_FMT_NV12, info.width, info.height, &bytes_final, NULL);
2166 } else
2167#endif // USE_HW_ACCEL
2168 {
2169 frame_final = allocate_avframe(
2170 (AVPixelFormat)(video_st->codecpar->format),
2171 info.width, info.height, &bytes_final, NULL
2172 );
2173 }
2174#else
2175 AVFrame *frame_final = allocate_avframe(video_codec_ctx->pix_fmt, info.width, info.height, &bytes_final, NULL);
2176#endif // IS_FFMPEG_3_2
2177
2178 // Fill with data
2179 AV_COPY_PICTURE_DATA(frame_source, (uint8_t *) pixels, PIX_FMT_RGBA, source_image_width, source_image_height);
2181 "FFmpegWriter::process_video_packet",
2182 "frame->number", frame->number,
2183 "bytes_source", bytes_source,
2184 "bytes_final", bytes_final);
2185
2186 // Resize & convert pixel format
2187 sws_scale(scaler, frame_source->data, frame_source->linesize, 0,
2188 source_image_height, frame_final->data, frame_final->linesize);
2189
2190 // Add resized AVFrame to av_frames map
2191 add_avframe(frame, frame_final);
2192
2193 // Deallocate memory
2194 AV_FREE_FRAME(&frame_source);
2195}
2196
2197// write video frame
2198bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *frame_final) {
2199#if (LIBAVFORMAT_VERSION_MAJOR >= 58)
2200 // FFmpeg 4.0+
2202 "FFmpegWriter::write_video_packet",
2203 "frame->number", frame->number,
2204 "oc->oformat->flags", oc->oformat->flags);
2205
2206 if (AV_GET_CODEC_TYPE(video_st) == AVMEDIA_TYPE_VIDEO && AV_FIND_DECODER_CODEC_ID(video_st) == AV_CODEC_ID_RAWVIDEO) {
2207#else
2208 // TODO: Should we have moved away from oc->oformat->flags / AVFMT_RAWPICTURE
2209 // on ffmpeg < 4.0 as well?
2210 // Does AV_CODEC_ID_RAWVIDEO not work in ffmpeg 3.x?
2212 "FFmpegWriter::write_video_packet",
2213 "frame->number", frame->number,
2214 "oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE);
2215
2216 if (oc->oformat->flags & AVFMT_RAWPICTURE) {
2217#endif
2218 // Raw video case.
2219#if IS_FFMPEG_3_2
2220 AVPacket* pkt = av_packet_alloc();
2221#else
2222 AVPacket* pkt;
2223 av_init_packet(pkt);
2224#endif
2225
2226 av_packet_from_data(
2227 pkt, frame_final->data[0],
2228 frame_final->linesize[0] * frame_final->height);
2229
2230 pkt->flags |= AV_PKT_FLAG_KEY;
2231 pkt->stream_index = video_st->index;
2232
2233 // Set PTS (in frames and scaled to the codec's timebase)
2234 pkt->pts = video_timestamp;
2235
2236 /* write the compressed frame in the media file */
2237 int error_code = av_interleaved_write_frame(oc, pkt);
2238 if (error_code < 0) {
2240 "FFmpegWriter::write_video_packet ERROR ["
2241 + av_err2string(error_code) + "]",
2242 "error_code", error_code);
2243 return false;
2244 }
2245
2246 // Deallocate packet
2247 AV_FREE_PACKET(pkt);
2248
2249 } else
2250 {
2251
2252#if IS_FFMPEG_3_2
2253 AVPacket* pkt = av_packet_alloc();
2254#else
2255 AVPacket* pkt;
2256 av_init_packet(pkt);
2257#endif
2258 pkt->data = NULL;
2259 pkt->size = 0;
2260 pkt->pts = pkt->dts = AV_NOPTS_VALUE;
2261
2262 // Assign the initial AVFrame PTS from the frame counter
2263 frame_final->pts = video_timestamp;
2264#if USE_HW_ACCEL
2265 if (hw_en_on && hw_en_supported) {
2266 if (!(hw_frame = av_frame_alloc())) {
2267 std::clog << "Error code: av_hwframe_alloc\n";
2268 }
2269 if (av_hwframe_get_buffer(video_codec_ctx->hw_frames_ctx, hw_frame, 0) < 0) {
2270 std::clog << "Error code: av_hwframe_get_buffer\n";
2271 }
2272 if (!hw_frame->hw_frames_ctx) {
2273 std::clog << "Error hw_frames_ctx.\n";
2274 }
2275 hw_frame->format = AV_PIX_FMT_NV12;
2276 if ( av_hwframe_transfer_data(hw_frame, frame_final, 0) < 0) {
2277 std::clog << "Error while transferring frame data to surface.\n";
2278 }
2279 av_frame_copy_props(hw_frame, frame_final);
2280 }
2281#endif // USE_HW_ACCEL
2282 /* encode the image */
2283 int got_packet_ptr = 0;
2284 int error_code = 0;
2285#if IS_FFMPEG_3_2
2286 // Write video packet
2287 int ret;
2288
2289 #if USE_HW_ACCEL
2290 if (hw_en_on && hw_en_supported) {
2291 ret = avcodec_send_frame(video_codec_ctx, hw_frame); //hw_frame!!!
2292 } else
2293 #endif // USE_HW_ACCEL
2294 {
2295 ret = avcodec_send_frame(video_codec_ctx, frame_final);
2296 }
2297 error_code = ret;
2298 if (ret < 0 ) {
2300 "FFmpegWriter::write_video_packet (Frame not sent)");
2301 if (ret == AVERROR(EAGAIN) ) {
2302 std::clog << "Frame EAGAIN\n";
2303 }
2304 if (ret == AVERROR_EOF ) {
2305 std::clog << "Frame AVERROR_EOF\n";
2306 }
2307 avcodec_send_frame(video_codec_ctx, NULL);
2308 }
2309 else {
2310 while (ret >= 0) {
2311 ret = avcodec_receive_packet(video_codec_ctx, pkt);
2312
2313 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
2314 avcodec_flush_buffers(video_codec_ctx);
2315 got_packet_ptr = 0;
2316 break;
2317 }
2318 if (ret == 0) {
2319 got_packet_ptr = 1;
2320 break;
2321 }
2322 }
2323 }
2324#else
2325 // Write video packet (older than FFmpeg 3.2)
2326 error_code = avcodec_encode_video2(video_codec_ctx, pkt, frame_final, &got_packet_ptr);
2327 if (error_code != 0) {
2329 "FFmpegWriter::write_video_packet ERROR ["
2330 + av_err2string(error_code) + "]",
2331 "error_code", error_code);
2332 }
2333 if (got_packet_ptr == 0) {
2335 "FFmpegWriter::write_video_packet (Frame gotpacket error)");
2336 }
2337#endif // IS_FFMPEG_3_2
2338
2339 /* if zero size, it means the image was buffered */
2340 if (error_code == 0 && got_packet_ptr) {
2341 // set the timestamp
2342 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
2343 pkt->stream_index = video_st->index;
2344
2345 /* write the compressed frame in the media file */
2346 int result = av_interleaved_write_frame(oc, pkt);
2347 if (result < 0) {
2349 "FFmpegWriter::write_video_packet ERROR ["
2350 + av_err2string(result) + "]",
2351 "result", result);
2352 return false;
2353 }
2354 }
2355
2356 // Deallocate packet
2357 AV_FREE_PACKET(pkt);
2358#if USE_HW_ACCEL
2359 if (hw_en_on && hw_en_supported) {
2360 if (hw_frame) {
2361 av_frame_free(&hw_frame);
2362 hw_frame = NULL;
2363 }
2364 }
2365#endif // USE_HW_ACCEL
2366 }
2367
2368 // Increment PTS (in frames and scaled to the codec's timebase)
2369 video_timestamp += av_rescale_q(1, av_make_q(info.fps.den, info.fps.num), video_codec_ctx->time_base);
2370
2371 // Success
2372 return true;
2373}
2374
2375// Output the ffmpeg info about this format, streams, and codecs (i.e. dump format)
2377 // output debug info
2378 av_dump_format(oc, 0, path.c_str(), 1);
2379}
2380
2381// Init a collection of software rescalers (thread safe)
2382void FFmpegWriter::InitScalers(int source_width, int source_height) {
2383 int scale_mode = SWS_FAST_BILINEAR;
2384 if (openshot::Settings::Instance()->HIGH_QUALITY_SCALING) {
2385 scale_mode = SWS_BICUBIC;
2386 }
2387
2388 // Init software rescalers vector (many of them, one for each thread)
2389 for (int x = 0; x < num_of_rescalers; x++) {
2390 // Init the software scaler from FFMpeg
2391#if USE_HW_ACCEL
2392 if (hw_en_on && hw_en_supported) {
2393 img_convert_ctx = sws_getContext(source_width, source_height, PIX_FMT_RGBA,
2394 info.width, info.height, AV_PIX_FMT_NV12, scale_mode, NULL, NULL, NULL);
2395 } else
2396#endif // USE_HW_ACCEL
2397 {
2398 img_convert_ctx = sws_getContext(source_width, source_height, PIX_FMT_RGBA,
2399 info.width, info.height, AV_GET_CODEC_PIXEL_FORMAT(video_st, video_st->codec),
2400 scale_mode, NULL, NULL, NULL);
2401 }
2402
2403 // Add rescaler to vector
2404 image_rescalers.push_back(img_convert_ctx);
2405 }
2406}
2407
2408// Set audio resample options
2409void FFmpegWriter::ResampleAudio(int sample_rate, int channels) {
2410 original_sample_rate = sample_rate;
2411 original_channels = channels;
2412}
2413
2414// Remove & deallocate all software scalers
2416 // Close all rescalers
2417 for (int x = 0; x < num_of_rescalers; x++)
2418 sws_freeContext(image_rescalers[x]);
2419
2420 // Clear vector
2421 image_rescalers.clear();
2422}
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
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_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.
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