34 #include "../include/FFmpegWriter.h"
39 #pragma message "You are compiling with experimental hardware encode"
41 #pragma message "You are compiling only with software encode"
49 int hw_en_supported = 0;
50 AVPixelFormat hw_en_av_pix_fmt = AV_PIX_FMT_NONE;
51 AVHWDeviceType hw_en_av_device_type = AV_HWDEVICE_TYPE_VAAPI;
52 static AVBufferRef *hw_device_ctx = NULL;
53 AVFrame *hw_frame = NULL;
55 static int set_hwframe_ctx(AVCodecContext *ctx, AVBufferRef *hw_device_ctx, int64_t width, int64_t height)
57 AVBufferRef *hw_frames_ref;
58 AVHWFramesContext *frames_ctx = NULL;
61 if (!(hw_frames_ref = av_hwframe_ctx_alloc(hw_device_ctx))) {
62 fprintf(stderr,
"Failed to create HW frame context.\n");
65 frames_ctx = (AVHWFramesContext *)(hw_frames_ref->data);
66 frames_ctx->format = hw_en_av_pix_fmt;
67 frames_ctx->sw_format = AV_PIX_FMT_NV12;
68 frames_ctx->width = width;
69 frames_ctx->height = height;
70 frames_ctx->initial_pool_size = 20;
71 if ((err = av_hwframe_ctx_init(hw_frames_ref)) < 0) {
72 fprintf(stderr,
"Failed to initialize HW frame context."
74 av_buffer_unref(&hw_frames_ref);
77 ctx->hw_frames_ctx = av_buffer_ref(hw_frames_ref);
78 if (!ctx->hw_frames_ctx)
79 err = AVERROR(ENOMEM);
81 av_buffer_unref(&hw_frames_ref);
84 #endif // HAVE_HW_ACCEL
87 path(path), fmt(NULL), oc(NULL), audio_st(NULL), video_st(NULL), audio_pts(0), video_pts(0), samples(NULL),
88 audio_outbuf(NULL), audio_outbuf_size(0), audio_input_frame_size(0), audio_input_position(0),
89 initial_audio_input_frame_size(0), img_convert_ctx(NULL), cache_size(8), num_of_rescalers(32),
90 rescaler_position(0), video_codec(NULL), audio_codec(NULL), is_writing(false), write_video_count(0), write_audio_count(0),
91 original_sample_rate(0), original_channels(0), avr(NULL), avr_planar(NULL), is_open(false), prepare_streams(false),
92 write_header(false), write_trailer(false), audio_encoder_buffer_size(0), audio_encoder_buffer(NULL) {
102 auto_detect_format();
112 if (!prepare_streams)
117 open_video(oc, video_st);
119 open_audio(oc, audio_st);
128 void FFmpegWriter::auto_detect_format() {
130 fmt = av_guess_format(NULL, path.c_str(), NULL);
132 throw InvalidFormat(
"Could not deduce output format from file extension.", path);
137 throw OutOfMemory(
"Could not allocate memory for AVFormatContext.", path);
145 info.
vcodec = avcodec_find_encoder(fmt->video_codec)->name;
149 info.
acodec = avcodec_find_encoder(fmt->audio_codec)->name;
153 void FFmpegWriter::initialize_streams() {
154 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::initialize_streams",
"fmt->video_codec", fmt->video_codec,
"fmt->audio_codec", fmt->audio_codec,
"AV_CODEC_ID_NONE", AV_CODEC_ID_NONE);
161 video_st = add_video_stream();
165 audio_st = add_audio_stream();
171 if (codec.length() > 0) {
175 #if defined(__linux__)
176 if (strstr(codec.c_str(),
"_vaapi") != NULL) {
177 new_codec = avcodec_find_encoder_by_name(codec.c_str());
180 hw_en_av_pix_fmt = AV_PIX_FMT_VAAPI;
181 hw_en_av_device_type = AV_HWDEVICE_TYPE_VAAPI;
182 }
else if (strstr(codec.c_str(),
"_nvenc") != NULL) {
183 new_codec = avcodec_find_encoder_by_name(codec.c_str());
186 hw_en_av_pix_fmt = AV_PIX_FMT_CUDA;
187 hw_en_av_device_type = AV_HWDEVICE_TYPE_CUDA;
189 new_codec = avcodec_find_encoder_by_name(codec.c_str());
193 #elif defined(_WIN32)
194 if (strstr(codec.c_str(),
"_dxva2") != NULL) {
195 new_codec = avcodec_find_encoder_by_name(codec.c_str());
198 hw_en_av_pix_fmt = AV_PIX_FMT_DXVA2_VLD;
199 hw_en_av_device_type = AV_HWDEVICE_TYPE_DXVA2;
200 }
else if (strstr(codec.c_str(),
"_nvenc") != NULL) {
201 new_codec = avcodec_find_encoder_by_name(codec.c_str());
204 hw_en_av_pix_fmt = AV_PIX_FMT_CUDA;
205 hw_en_av_device_type = AV_HWDEVICE_TYPE_CUDA;
207 new_codec = avcodec_find_encoder_by_name(codec.c_str());
211 #elif defined(__APPLE__)
212 if (strstr(codec.c_str(),
"_videotoolbox") != NULL) {
213 new_codec = avcodec_find_encoder_by_name(codec.c_str());
216 hw_en_av_pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX;
217 hw_en_av_device_type = AV_HWDEVICE_TYPE_VIDEOTOOLBOX;
219 new_codec = avcodec_find_encoder_by_name(codec.c_str());
223 #else // is FFmpeg 3 but not linux
224 new_codec = avcodec_find_encoder_by_name(codec.c_str());
226 #else // not ffmpeg 3
227 new_codec = avcodec_find_encoder_by_name(codec.c_str());
228 #endif // HAVE_HW_ACCEL
229 if (new_codec == NULL)
230 throw InvalidCodec(
"A valid video codec could not be found for this file.", path);
236 fmt->video_codec = new_codec->id;
252 if (pixel_ratio.
num > 0) {
256 if (bit_rate >= 1000)
258 if ((bit_rate >= 0) && (bit_rate < 64))
274 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::SetVideoOptions (" + codec +
")",
"width", width,
"height", height,
"size.num", size.
num,
"size.den", size.
den,
"fps.num", fps.
num,
"fps.den", fps.
den);
291 if (codec.length() > 0) {
292 AVCodec *new_codec = avcodec_find_encoder_by_name(codec.c_str());
293 if (new_codec == NULL)
294 throw InvalidCodec(
"A valid audio codec could not be found for this file.", path);
300 fmt->audio_codec = new_codec->id;
303 if (sample_rate > 7999)
312 if (original_sample_rate == 0)
314 if (original_channels == 0)
335 AVCodecContext *c = NULL;
337 std::stringstream convert(value);
348 throw NoStreamsFound(
"The stream was not found. Be sure to call PrepareStreams() first.", path);
351 const AVOption *option = NULL;
359 if (option || (name ==
"g" || name ==
"qmin" || name ==
"qmax" || name ==
"max_b_frames" || name ==
"mb_decision" ||
360 name ==
"level" || name ==
"profile" || name ==
"slices" || name ==
"rc_min_rate" || name ==
"rc_max_rate" ||
361 name ==
"rc_buffer_size" || name ==
"crf" || name ==
"cqp")) {
365 convert >> c->gop_size;
367 else if (name ==
"qmin")
371 else if (name ==
"qmax")
375 else if (name ==
"max_b_frames")
377 convert >> c->max_b_frames;
379 else if (name ==
"mb_decision")
381 convert >> c->mb_decision;
383 else if (name ==
"level")
387 else if (name ==
"profile")
389 convert >> c->profile;
391 else if (name ==
"slices")
393 convert >> c->slices;
395 else if (name ==
"rc_min_rate")
397 convert >> c->rc_min_rate;
399 else if (name ==
"rc_max_rate")
401 convert >> c->rc_max_rate;
403 else if (name ==
"rc_buffer_size")
405 convert >> c->rc_buffer_size;
407 else if (name ==
"cqp") {
411 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 39, 101)
414 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),63), 0);
416 #endif // HAVE_HW_ACCEL
418 switch (c->codec_id) {
419 #if (LIBAVCODEC_VERSION_MAJOR >= 58)
420 case AV_CODEC_ID_AV1 :
422 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),63), 0);
425 case AV_CODEC_ID_VP8 :
426 c->bit_rate = 10000000;
427 av_opt_set_int(c->priv_data,
"qp", std::max(std::min(std::stoi(value), 63), 4), 0);
429 case AV_CODEC_ID_VP9 :
431 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value), 63), 0);
432 if (std::stoi(value) == 0) {
433 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
434 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
437 case AV_CODEC_ID_H264 :
438 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value), 51), 0);
439 if (std::stoi(value) == 0) {
440 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
443 case AV_CODEC_ID_HEVC :
444 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value), 51), 0);
445 if (std::stoi(value) == 0) {
446 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
447 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
452 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value), 63), 0);
457 }
else if (name ==
"crf") {
461 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 39, 101)
464 double mbs = 15000000.0;
473 c->bit_rate = (int)(mbs);
475 #endif // HAVE_HW_ACCEL
477 switch (c->codec_id) {
478 #if (LIBAVCODEC_VERSION_MAJOR >= 58)
479 case AV_CODEC_ID_AV1 :
481 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value),63), 0);
484 case AV_CODEC_ID_VP8 :
485 c->bit_rate = 10000000;
486 av_opt_set_int(c->priv_data,
"crf", std::max(std::min(std::stoi(value), 63), 4), 0);
488 case AV_CODEC_ID_VP9 :
490 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value), 63), 0);
491 if (std::stoi(value) == 0) {
492 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
493 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
496 case AV_CODEC_ID_H264 :
497 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value), 51), 0);
498 if (std::stoi(value) == 0) {
499 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
502 case AV_CODEC_ID_HEVC :
503 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value), 51), 0);
504 if (std::stoi(value) == 0) {
505 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
506 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
512 double mbs = 15000000.0;
520 c->bit_rate = (int) (mbs);
526 AV_OPTION_SET(st, c->priv_data, name.c_str(), value.c_str(), c);
533 }
else if (name ==
"muxing_preset") {
534 if (value ==
"mp4_faststart") {
536 av_dict_set(&
mux_dict,
"movflags",
"faststart", 0);
537 }
else if (value ==
"mp4_fragmented") {
539 av_dict_set(&
mux_dict,
"movflags",
"frag_keyframe", 0);
540 av_dict_set(&
mux_dict,
"min_frag_duration",
"8000000", 0);
543 throw InvalidOptions(
"The option is not valid for this codec.", path);
554 if (avcodec_find_encoder_by_name(codec_name.c_str()) == NULL)
563 throw InvalidOptions(
"No video or audio options have been set. You must set has_video or has_audio (or both).", path);
568 initialize_streams();
571 prepare_streams =
true;
577 throw InvalidOptions(
"No video or audio options have been set. You must set has_video or has_audio (or both).", path);
580 if (!(fmt->flags & AVFMT_NOFILE)) {
581 if (avio_open(&oc->pb, path.c_str(), AVIO_FLAG_WRITE) < 0)
582 throw InvalidFile(
"Could not open or write file.", path);
589 for (std::map<std::string, std::string>::iterator iter =
info.
metadata.begin(); iter !=
info.
metadata.end(); ++iter) {
590 av_dict_set(&oc->metadata, iter->first.c_str(), iter->second.c_str(), 0);
594 AVDictionary *dict = NULL;
596 bool is_mp4 = strcmp(oc->oformat->name,
"mp4");
597 bool is_mov = strcmp(oc->oformat->name,
"mov");
599 if (is_mp4 || is_mov)
603 if (avformat_write_header(oc, &dict) != 0) {
605 throw InvalidFile(
"Could not write header to file.", path);
609 if (dict) av_dict_free(&dict);
622 throw WriterClosed(
"The FFmpegWriter is closed. Call Open() before calling this method.", path);
627 spooled_video_frames.push_back(frame);
630 spooled_audio_frames.push_back(frame);
632 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::WriteFrame",
"frame->number", frame->
number,
"spooled_video_frames.size()", spooled_video_frames.size(),
"spooled_audio_frames.size()", spooled_audio_frames.size(),
"cache_size", cache_size,
"is_writing", is_writing);
635 if ((
int)spooled_video_frames.size() == cache_size || (
int)spooled_audio_frames.size() == cache_size) {
639 write_queued_frames();
643 write_queued_frames();
652 void FFmpegWriter::write_queued_frames() {
653 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_queued_frames",
"spooled_video_frames.size()", spooled_video_frames.size(),
"spooled_audio_frames.size()", spooled_audio_frames.size());
659 queued_video_frames = spooled_video_frames;
660 queued_audio_frames = spooled_audio_frames;
663 spooled_video_frames.clear();
664 spooled_audio_frames.clear();
669 omp_set_nested(
true);
672 bool has_error_encoding_video =
false;
679 if (
info.
has_audio && audio_st && !queued_audio_frames.empty())
680 write_audio_packets(
false);
683 while (!queued_video_frames.empty()) {
685 std::shared_ptr<Frame> frame = queued_video_frames.front();
688 processed_frames.push_back(frame);
692 process_video_packet(frame);
695 queued_video_frames.pop_front();
703 while (!processed_frames.empty()) {
705 std::shared_ptr<Frame> frame = processed_frames.front();
709 deallocate_frames.push_back(frame);
712 if (av_frames.count(frame)) {
714 AVFrame *frame_final = av_frames[frame];
717 bool success = write_video_packet(frame, frame_final);
719 has_error_encoding_video =
true;
724 processed_frames.pop_front();
728 while (!deallocate_frames.empty()) {
730 std::shared_ptr<Frame> frame = deallocate_frames.front();
733 if (av_frames.count(frame)) {
735 AVFrame *av_frame = av_frames[frame];
738 av_freep(&(av_frame->data[0]));
740 av_frames.erase(frame);
744 deallocate_frames.pop_front();
755 if (has_error_encoding_video)
764 for (int64_t number = start; number <= length; number++) {
766 std::shared_ptr<Frame> f = reader->
GetFrame(number);
776 write_queued_frames();
780 write_audio_packets(
true);
789 av_write_trailer(oc);
792 write_trailer =
true;
798 void FFmpegWriter::flush_encoders() {
801 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
807 int stop_encoding = 1;
814 write_video_count += av_rescale_q(1, (AVRational) {
info.
fps.
den,
info.
fps.
num}, video_codec->time_base);
817 av_init_packet(&pkt);
822 uint8_t *video_outbuf = NULL;
829 #pragma omp critical (write_video_packet)
832 error_code = avcodec_send_frame(video_codec, NULL);
834 while (error_code >= 0) {
835 error_code = avcodec_receive_packet(video_codec, &pkt);
836 if (error_code == AVERROR(EAGAIN)|| error_code == AVERROR_EOF) {
839 avcodec_flush_buffers(video_codec);
842 if (pkt.pts != AV_NOPTS_VALUE)
843 pkt.pts = av_rescale_q(pkt.pts, video_codec->time_base, video_st->time_base);
844 if (pkt.dts != AV_NOPTS_VALUE)
845 pkt.dts = av_rescale_q(pkt.dts, video_codec->time_base, video_st->time_base);
846 if (pkt.duration > 0)
847 pkt.duration = av_rescale_q(pkt.duration, video_codec->time_base, video_st->time_base);
848 pkt.stream_index = video_st->index;
849 error_code = av_interleaved_write_frame(oc, &pkt);
852 #else // IS_FFMPEG_3_2
854 #if LIBAVFORMAT_VERSION_MAJOR >= 54
856 error_code = avcodec_encode_video2(video_codec, &pkt, NULL, &got_packet);
860 int video_outbuf_size = 0;
863 int out_size = avcodec_encode_video(video_codec, NULL, video_outbuf_size, NULL);
867 if(video_codec->coded_frame->key_frame)
868 pkt.flags |= AV_PKT_FLAG_KEY;
869 pkt.data= video_outbuf;
875 #endif // LIBAVFORMAT_VERSION_MAJOR >= 54
876 #endif // IS_FFMPEG_3_2
878 if (error_code < 0) {
890 if (pkt.pts != AV_NOPTS_VALUE)
891 pkt.pts = av_rescale_q(pkt.pts, video_codec->time_base, video_st->time_base);
892 if (pkt.dts != AV_NOPTS_VALUE)
893 pkt.dts = av_rescale_q(pkt.dts, video_codec->time_base, video_st->time_base);
894 if (pkt.duration > 0)
895 pkt.duration = av_rescale_q(pkt.duration, video_codec->time_base, video_st->time_base);
896 pkt.stream_index = video_st->index;
899 error_code = av_interleaved_write_frame(oc, &pkt);
900 if (error_code < 0) {
906 av_freep(&video_outbuf);
914 #if LIBAVFORMAT_VERSION_MAJOR >= 54
916 write_audio_count += av_rescale_q(audio_input_position / (audio_codec->channels * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)), (AVRational){1,
info.
sample_rate}, audio_codec->time_base);
918 write_audio_count += av_rescale_q(audio_input_position / audio_codec->channels, (AVRational){1, info.sample_rate}, audio_codec->time_base);
922 av_init_packet(&pkt);
925 pkt.pts = pkt.dts = write_audio_count;
930 avcodec_send_frame(audio_codec, NULL);
933 error_code = avcodec_encode_audio2(audio_codec, &pkt, NULL, &got_packet);
935 if (error_code < 0) {
945 pkt.pts = pkt.dts = write_audio_count;
948 if (pkt.pts != AV_NOPTS_VALUE)
949 pkt.pts = av_rescale_q(pkt.pts, audio_codec->time_base, audio_st->time_base);
950 if (pkt.dts != AV_NOPTS_VALUE)
951 pkt.dts = av_rescale_q(pkt.dts, audio_codec->time_base, audio_st->time_base);
952 if (pkt.duration > 0)
953 pkt.duration = av_rescale_q(pkt.duration, audio_codec->time_base, audio_st->time_base);
956 pkt.stream_index = audio_st->index;
957 pkt.flags |= AV_PKT_FLAG_KEY;
960 error_code = av_interleaved_write_frame(oc, &pkt);
961 if (error_code < 0) {
973 void FFmpegWriter::close_video(AVFormatContext *oc, AVStream *st)
976 if (hw_en_on && hw_en_supported) {
978 av_buffer_unref(&hw_device_ctx);
979 hw_device_ctx = NULL;
982 #endif // HAVE_HW_ACCEL
986 void FFmpegWriter::close_audio(AVFormatContext *oc, AVStream *st)
990 delete[] audio_outbuf;
991 delete[] audio_encoder_buffer;
994 audio_encoder_buffer = NULL;
1018 close_video(oc, video_st);
1020 close_audio(oc, audio_st);
1023 if (image_rescalers.size() > 0)
1026 if (!(fmt->flags & AVFMT_NOFILE)) {
1032 write_video_count = 0;
1033 write_audio_count = 0;
1036 avformat_free_context(oc);
1041 prepare_streams =
false;
1042 write_header =
false;
1043 write_trailer =
false;
1049 void FFmpegWriter::add_avframe(std::shared_ptr<Frame> frame, AVFrame *av_frame) {
1051 if (!av_frames.count(frame)) {
1053 av_frames[frame] = av_frame;
1061 AVStream *FFmpegWriter::add_audio_stream() {
1066 AVCodec *codec = avcodec_find_encoder_by_name(
info.
acodec.c_str());
1068 throw InvalidCodec(
"A valid audio codec could not be found for this file.", path);
1073 c->codec_id = codec->id;
1074 #if LIBAVFORMAT_VERSION_MAJOR >= 53
1075 c->codec_type = AVMEDIA_TYPE_AUDIO;
1077 c->codec_type = CODEC_TYPE_AUDIO;
1085 if (codec->supported_samplerates) {
1087 for (i = 0; codec->supported_samplerates[i] != 0; i++)
1093 if (codec->supported_samplerates[i] == 0)
1094 throw InvalidSampleRate(
"An invalid sample rate was detected for this codec.", path);
1102 if (codec->channel_layouts) {
1104 for (i = 0; codec->channel_layouts[i] != 0; i++)
1105 if (channel_layout == codec->channel_layouts[i]) {
1107 c->channel_layout = channel_layout;
1110 if (codec->channel_layouts[i] == 0)
1111 throw InvalidChannels(
"An invalid channel layout was detected (i.e. MONO / STEREO).", path);
1114 c->channel_layout = channel_layout;
1117 if (codec->sample_fmts) {
1118 for (
int i = 0; codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) {
1120 c->sample_fmt = codec->sample_fmts[i];
1124 if (c->sample_fmt == AV_SAMPLE_FMT_NONE) {
1126 c->sample_fmt = AV_SAMPLE_FMT_S16;
1130 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1131 #if (LIBAVCODEC_VERSION_MAJOR >= 57)
1132 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1134 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1138 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::add_audio_stream",
"c->codec_id", c->codec_id,
"c->bit_rate", c->bit_rate,
"c->channels", c->channels,
"c->sample_fmt", c->sample_fmt,
"c->channel_layout", c->channel_layout,
"c->sample_rate", c->sample_rate);
1144 AVStream *FFmpegWriter::add_video_stream() {
1149 AVCodec *codec = avcodec_find_encoder_by_name(
info.
vcodec.c_str());
1151 throw InvalidCodec(
"A valid video codec could not be found for this file.", path);
1156 c->codec_id = codec->id;
1157 #if LIBAVFORMAT_VERSION_MAJOR >= 53
1158 c->codec_type = AVMEDIA_TYPE_VIDEO;
1160 c->codec_type = CODEC_TYPE_VIDEO;
1174 switch (c->codec_id) {
1175 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 39, 101)
1176 #if (LIBAVCODEC_VERSION_MAJOR >= 58)
1177 case AV_CODEC_ID_AV1 :
1179 case AV_CODEC_ID_VP9 :
1180 case AV_CODEC_ID_HEVC :
1182 case AV_CODEC_ID_VP8 :
1183 case AV_CODEC_ID_H264 :
1219 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 26, 0)
1220 c->framerate = av_inv_q(c->time_base);
1222 st->avg_frame_rate = av_inv_q(c->time_base);
1227 c->max_b_frames = 10;
1228 if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO)
1230 c->max_b_frames = 2;
1231 if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO)
1237 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1238 #if (LIBAVCODEC_VERSION_MAJOR >= 57)
1239 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1241 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1245 const PixelFormat *supported_pixel_formats = codec->pix_fmts;
1246 while (supported_pixel_formats != NULL && *supported_pixel_formats !=
PIX_FMT_NONE) {
1249 c->pix_fmt = *supported_pixel_formats;
1250 ++supported_pixel_formats;
1255 if (fmt->video_codec == AV_CODEC_ID_RAWVIDEO) {
1259 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
1260 if (strcmp(fmt->name,
"gif") != 0)
1263 oc->oformat->flags |= AVFMT_RAWPICTURE;
1272 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
1273 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::add_video_stream (" + (std::string)fmt->name +
" : " + (std::string)av_get_pix_fmt_name(c->pix_fmt) +
")",
"c->codec_id", c->codec_id,
"c->bit_rate", c->bit_rate,
"c->pix_fmt", c->pix_fmt,
"oc->oformat->flags", oc->oformat->flags,
"AVFMT_RAWPICTURE", AVFMT_RAWPICTURE);
1275 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::add_video_stream (" + (std::string)fmt->name +
" : " + (std::string)av_get_pix_fmt_name(c->pix_fmt) +
")",
"c->codec_id", c->codec_id,
"c->bit_rate", c->bit_rate,
"c->pix_fmt", c->pix_fmt,
"oc->oformat->flags", oc->oformat->flags);
1282 void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st) {
1290 codec = avcodec_find_encoder_by_name(
info.
acodec.c_str());
1292 codec = avcodec_find_encoder(audio_codec->codec_id);
1297 AVDictionary *opts = NULL;
1298 av_dict_set(&opts,
"strict",
"experimental", 0);
1301 if (avcodec_open2(audio_codec, codec, &opts) < 0)
1302 throw InvalidCodec(
"Could not open audio codec", path);
1306 av_dict_free(&opts);
1310 if (audio_codec->frame_size <= 1) {
1316 case AV_CODEC_ID_PCM_S16LE:
1317 case AV_CODEC_ID_PCM_S16BE:
1318 case AV_CODEC_ID_PCM_U16LE:
1319 case AV_CODEC_ID_PCM_U16BE:
1320 audio_input_frame_size >>= 1;
1327 audio_input_frame_size = audio_codec->frame_size;
1331 initial_audio_input_frame_size = audio_input_frame_size;
1338 audio_outbuf =
new uint8_t[audio_outbuf_size];
1342 audio_encoder_buffer =
new uint8_t[audio_encoder_buffer_size];
1345 for (std::map<std::string, std::string>::iterator iter =
info.
metadata.begin(); iter !=
info.
metadata.end(); ++iter) {
1346 av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1353 void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) {
1361 if (hw_en_on && hw_en_supported) {
1364 char *adapter_ptr = NULL;
1368 fprintf(stderr,
"\n\nEncodiing Device Nr: %d\n", adapter_num);
1369 if (adapter_num < 3 && adapter_num >=0) {
1370 #if defined(__linux__)
1371 snprintf(adapter,
sizeof(adapter),
"/dev/dri/renderD%d", adapter_num+128);
1373 adapter_ptr = adapter;
1374 #elif defined(_WIN32)
1376 #elif defined(__APPLE__)
1384 #if defined(__linux__)
1385 if( adapter_ptr != NULL && access( adapter_ptr, W_OK ) == 0 ) {
1386 #elif defined(_WIN32)
1387 if( adapter_ptr != NULL ) {
1388 #elif defined(__APPLE__)
1389 if( adapter_ptr != NULL ) {
1397 if (av_hwdevice_ctx_create(&hw_device_ctx, hw_en_av_device_type,
1398 adapter_ptr, NULL, 0) < 0) {
1403 #endif // HAVE_HW_ACCEL
1406 codec = avcodec_find_encoder_by_name(
info.
vcodec.c_str());
1413 if (video_codec->max_b_frames && video_codec->codec_id != AV_CODEC_ID_MPEG4 && video_codec->codec_id != AV_CODEC_ID_MPEG1VIDEO && video_codec->codec_id != AV_CODEC_ID_MPEG2VIDEO)
1414 video_codec->max_b_frames = 0;
1417 AVDictionary *opts = NULL;
1418 av_dict_set(&opts,
"strict",
"experimental", 0);
1421 if (hw_en_on && hw_en_supported) {
1422 video_codec->pix_fmt = hw_en_av_pix_fmt;
1430 if (hw_en_av_pix_fmt == AV_PIX_FMT_VAAPI) {
1432 if (av_opt_get_int(video_codec->priv_data,
"qp", 0, &qp) != 0 || qp == 0) {
1434 av_opt_set(video_codec->priv_data,
"rc_mode",
"VBR", 0);
1438 video_codec->rc_max_rate = video_codec->bit_rate;
1442 switch (video_codec->codec_id) {
1443 case AV_CODEC_ID_H264:
1444 video_codec->max_b_frames = 0;
1445 video_codec->profile = FF_PROFILE_H264_BASELINE | FF_PROFILE_H264_CONSTRAINED;
1446 av_opt_set(video_codec->priv_data,
"preset",
"slow", 0);
1447 av_opt_set(video_codec->priv_data,
"tune",
"zerolatency", 0);
1448 av_opt_set(video_codec->priv_data,
"vprofile",
"baseline", AV_OPT_SEARCH_CHILDREN);
1450 case AV_CODEC_ID_HEVC:
1453 case AV_CODEC_ID_VP9:
1458 "codec_id", video_codec->codec_id);
1469 #endif // HAVE_HW_ACCEL
1472 if (avcodec_open2(video_codec, codec, &opts) < 0)
1473 throw InvalidCodec(
"Could not open video codec", path);
1477 av_dict_free(&opts);
1480 for (std::map<std::string, std::string>::iterator iter =
info.
metadata.begin(); iter !=
info.
metadata.end(); ++iter) {
1481 av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1489 void FFmpegWriter::write_audio_packets(
bool is_final) {
1490 #pragma omp task firstprivate(is_final)
1493 int total_frame_samples = 0;
1494 int frame_position = 0;
1495 int channels_in_frame = 0;
1496 int sample_rate_in_frame = 0;
1497 int samples_in_frame = 0;
1502 int16_t *all_queued_samples = (int16_t *) av_malloc(all_queued_samples_size);
1503 int16_t *all_resampled_samples = NULL;
1504 int16_t *final_samples_planar = NULL;
1505 int16_t *final_samples = NULL;
1508 while (!queued_audio_frames.empty()) {
1510 std::shared_ptr<Frame> frame = queued_audio_frames.front();
1520 float *frame_samples_float = NULL;
1526 total_frame_samples = samples_in_frame * channels_in_frame;
1529 for (
int s = 0; s < total_frame_samples; s++, frame_position++)
1531 all_queued_samples[frame_position] =
int(frame_samples_float[s] * (1 << 15));
1535 delete[] frame_samples_float;
1538 queued_audio_frames.pop_front();
1544 total_frame_samples = frame_position;
1545 int remaining_frame_samples = total_frame_samples;
1546 int samples_position = 0;
1549 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_audio_packets",
"is_final", is_final,
"total_frame_samples", total_frame_samples,
"channel_layout_in_frame", channel_layout_in_frame,
"channels_in_frame", channels_in_frame,
"samples_in_frame", samples_in_frame,
"LAYOUT_MONO",
LAYOUT_MONO);
1552 AVSampleFormat output_sample_fmt = audio_codec->sample_fmt;
1554 AVFrame *audio_frame = NULL;
1559 audio_frame->nb_samples = total_frame_samples / channels_in_frame;
1562 int error_code = avcodec_fill_audio_frame(audio_frame, channels_in_frame, AV_SAMPLE_FMT_S16, (uint8_t *) all_queued_samples, all_queued_samples_size, 0);
1563 if (error_code < 0) {
1568 switch (audio_codec->sample_fmt) {
1569 case AV_SAMPLE_FMT_FLTP: {
1570 output_sample_fmt = AV_SAMPLE_FMT_FLT;
1573 case AV_SAMPLE_FMT_S32P: {
1574 output_sample_fmt = AV_SAMPLE_FMT_S32;
1577 case AV_SAMPLE_FMT_S16P: {
1578 output_sample_fmt = AV_SAMPLE_FMT_S16;
1581 case AV_SAMPLE_FMT_U8P: {
1582 output_sample_fmt = AV_SAMPLE_FMT_U8;
1592 total_frame_samples *= (float(
info.
sample_rate) / sample_rate_in_frame);
1593 total_frame_samples *= (float(
info.
channels) / channels_in_frame);
1598 audio_converted->nb_samples = total_frame_samples / channels_in_frame;
1599 av_samples_alloc(audio_converted->data, audio_converted->linesize,
info.
channels, audio_converted->nb_samples, output_sample_fmt, 0);
1601 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_audio_packets (1st resampling)",
"in_sample_fmt", AV_SAMPLE_FMT_S16,
"out_sample_fmt", output_sample_fmt,
"in_sample_rate", sample_rate_in_frame,
"out_sample_rate",
info.
sample_rate,
"in_channels", channels_in_frame,
"out_channels",
info.
channels);
1606 av_opt_set_int(avr,
"in_channel_layout", channel_layout_in_frame, 0);
1608 av_opt_set_int(avr,
"in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
1609 av_opt_set_int(avr,
"out_sample_fmt", output_sample_fmt, 0);
1610 av_opt_set_int(avr,
"in_sample_rate", sample_rate_in_frame, 0);
1612 av_opt_set_int(avr,
"in_channels", channels_in_frame, 0);
1620 audio_converted->data,
1621 audio_converted->linesize[0],
1622 audio_converted->nb_samples,
1624 audio_frame->linesize[0],
1625 audio_frame->nb_samples);
1628 remaining_frame_samples = nb_samples * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);
1631 all_resampled_samples = (int16_t *) av_malloc(
1632 sizeof(int16_t) * nb_samples *
info.
channels * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)));
1635 memcpy(all_resampled_samples, audio_converted->data[0], nb_samples *
info.
channels * av_get_bytes_per_sample(output_sample_fmt));
1638 av_freep(&(audio_frame->data[0]));
1640 av_freep(&audio_converted->data[0]);
1642 all_queued_samples = NULL;
1644 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_audio_packets (Successfully completed 1st resampling)",
"nb_samples", nb_samples,
"remaining_frame_samples", remaining_frame_samples);
1648 while (remaining_frame_samples > 0 || is_final) {
1650 int remaining_packet_samples = (audio_input_frame_size *
info.
channels) - audio_input_position;
1654 if (remaining_frame_samples >= remaining_packet_samples)
1655 diff = remaining_packet_samples;
1656 else if (remaining_frame_samples < remaining_packet_samples)
1657 diff = remaining_frame_samples;
1662 memcpy(samples + (audio_input_position * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16))),
1663 all_resampled_samples + samples_position, diff * av_get_bytes_per_sample(output_sample_fmt));
1666 audio_input_position += diff;
1667 samples_position += diff * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16));
1668 remaining_frame_samples -= diff;
1669 remaining_packet_samples -= diff;
1672 if (audio_input_position < (audio_input_frame_size *
info.
channels) && !is_final)
1679 if (av_sample_fmt_is_planar(audio_codec->sample_fmt)) {
1680 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_audio_packets (2nd resampling for Planar formats)",
"in_sample_fmt", output_sample_fmt,
"out_sample_fmt", audio_codec->sample_fmt,
"in_sample_rate",
info.
sample_rate,
"out_sample_rate",
info.
sample_rate,
"in_channels",
info.
channels,
"out_channels",
info.
channels);
1687 av_opt_set_int(avr_planar,
"in_sample_fmt", output_sample_fmt, 0);
1688 av_opt_set_int(avr_planar,
"out_sample_fmt", audio_codec->sample_fmt, 0);
1691 av_opt_set_int(avr_planar,
"in_channels",
info.
channels, 0);
1692 av_opt_set_int(avr_planar,
"out_channels",
info.
channels, 0);
1699 audio_frame->nb_samples = audio_input_position /
info.
channels;
1702 final_samples_planar = (int16_t *) av_malloc(
1703 sizeof(int16_t) * audio_frame->nb_samples *
info.
channels * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)));
1706 memcpy(final_samples_planar, samples, audio_frame->nb_samples *
info.
channels * av_get_bytes_per_sample(output_sample_fmt));
1709 avcodec_fill_audio_frame(audio_frame,
info.
channels, output_sample_fmt, (uint8_t *) final_samples_planar,
1710 audio_encoder_buffer_size, 0);
1713 frame_final->nb_samples = audio_input_frame_size;
1714 av_samples_alloc(frame_final->data, frame_final->linesize,
info.
channels, frame_final->nb_samples, audio_codec->sample_fmt, 0);
1719 frame_final->linesize[0],
1720 frame_final->nb_samples,
1722 audio_frame->linesize[0],
1723 audio_frame->nb_samples);
1727 memcpy(samples, frame_final->data[0], nb_samples * av_get_bytes_per_sample(audio_codec->sample_fmt) *
info.
channels);
1730 av_freep(&(audio_frame->data[0]));
1732 all_queued_samples = NULL;
1738 final_samples = (int16_t *) av_malloc(
1739 sizeof(int16_t) * audio_input_position * (av_get_bytes_per_sample(audio_codec->sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)));
1742 memcpy(final_samples, samples, audio_input_position * av_get_bytes_per_sample(audio_codec->sample_fmt));
1745 frame_final->nb_samples = audio_input_frame_size;
1748 avcodec_fill_audio_frame(frame_final, audio_codec->channels, audio_codec->sample_fmt, (uint8_t *) final_samples,
1749 audio_encoder_buffer_size, 0);
1753 write_audio_count += FFMIN(audio_input_frame_size, audio_input_position);
1754 frame_final->pts = write_audio_count;
1758 av_init_packet(&pkt);
1759 pkt.data = audio_encoder_buffer;
1760 pkt.size = audio_encoder_buffer_size;
1763 pkt.pts = pkt.dts = write_audio_count;
1766 int got_packet_ptr = 0;
1772 int frame_finished = 0;
1773 error_code = ret = avcodec_send_frame(audio_codec, frame_final);
1774 if (ret < 0 && ret != AVERROR(EINVAL) && ret != AVERROR_EOF) {
1775 avcodec_send_frame(audio_codec, NULL);
1780 ret = avcodec_receive_packet(audio_codec, &pkt);
1783 if(ret == AVERROR(EINVAL) || ret == AVERROR_EOF) {
1784 avcodec_flush_buffers(audio_codec);
1788 ret = frame_finished;
1791 if (!pkt.data && !frame_finished)
1795 got_packet_ptr = ret;
1798 int error_code = avcodec_encode_audio2(audio_codec, &pkt, frame_final, &got_packet_ptr);
1801 if (error_code == 0 && got_packet_ptr) {
1805 pkt.pts = pkt.dts = write_audio_count;
1808 if (pkt.pts != AV_NOPTS_VALUE)
1809 pkt.pts = av_rescale_q(pkt.pts, audio_codec->time_base, audio_st->time_base);
1810 if (pkt.dts != AV_NOPTS_VALUE)
1811 pkt.dts = av_rescale_q(pkt.dts, audio_codec->time_base, audio_st->time_base);
1812 if (pkt.duration > 0)
1813 pkt.duration = av_rescale_q(pkt.duration, audio_codec->time_base, audio_st->time_base);
1816 pkt.stream_index = audio_st->index;
1817 pkt.flags |= AV_PKT_FLAG_KEY;
1820 int error_code = av_interleaved_write_frame(oc, &pkt);
1821 if (error_code < 0) {
1826 if (error_code < 0) {
1831 av_freep(&(frame_final->data[0]));
1838 audio_input_position = 0;
1843 if (all_resampled_samples) {
1844 av_freep(&all_resampled_samples);
1845 all_resampled_samples = NULL;
1847 if (all_queued_samples) {
1848 av_freep(&all_queued_samples);
1849 all_queued_samples = NULL;
1856 AVFrame *FFmpegWriter::allocate_avframe(
PixelFormat pix_fmt,
int width,
int height,
int *buffer_size, uint8_t *new_buffer) {
1858 AVFrame *new_av_frame = NULL;
1862 if (new_av_frame == NULL)
1863 throw OutOfMemory(
"Could not allocate AVFrame", path);
1871 new_buffer = (uint8_t *) av_malloc(*buffer_size *
sizeof(uint8_t));
1874 new_av_frame->width = width;
1875 new_av_frame->height = height;
1876 new_av_frame->format = pix_fmt;
1880 return new_av_frame;
1884 void FFmpegWriter::process_video_packet(std::shared_ptr<Frame> frame) {
1886 int source_image_width = frame->
GetWidth();
1887 int source_image_height = frame->
GetHeight();
1890 if (source_image_height == 1 && source_image_width == 1)
1894 if (image_rescalers.size() == 0)
1895 InitScalers(source_image_width, source_image_height);
1898 SwsContext *scaler = image_rescalers[rescaler_position];
1899 rescaler_position++;
1900 if (rescaler_position == num_of_rescalers)
1901 rescaler_position = 0;
1903 #pragma omp task firstprivate(frame, scaler, source_image_width, source_image_height)
1906 int bytes_source = 0;
1907 int bytes_final = 0;
1908 AVFrame *frame_source = NULL;
1909 const uchar *pixels = NULL;
1915 frame_source = allocate_avframe(
PIX_FMT_RGBA, source_image_width, source_image_height, &bytes_source, (uint8_t *) pixels);
1917 AVFrame *frame_final;
1919 if (hw_en_on && hw_en_supported) {
1920 frame_final = allocate_avframe(AV_PIX_FMT_NV12,
info.
width,
info.
height, &bytes_final, NULL);
1922 #endif // HAVE_HW_ACCEL
1924 frame_final = allocate_avframe((AVPixelFormat)(video_st->codecpar->format),
info.
width,
info.
height, &bytes_final, NULL);
1927 AVFrame *frame_final = allocate_avframe(video_codec->pix_fmt,
info.
width,
info.
height, &bytes_final, NULL);
1928 #endif // IS_FFMPEG_3_2
1935 sws_scale(scaler, frame_source->data, frame_source->linesize, 0,
1936 source_image_height, frame_final->data, frame_final->linesize);
1939 #pragma omp critical (av_frames_section)
1940 add_avframe(frame, frame_final);
1950 bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *frame_final) {
1951 #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
1956 if (oc->oformat->flags & AVFMT_RAWPICTURE) {
1959 av_init_packet(&pkt);
1961 pkt.flags |= AV_PKT_FLAG_KEY;
1962 pkt.stream_index = video_st->index;
1963 pkt.data = (uint8_t *) frame_final->data;
1964 pkt.size =
sizeof(AVPicture);
1967 write_video_count += av_rescale_q(1, (AVRational) {
info.
fps.
den,
info.
fps.
num}, video_codec->time_base);
1968 pkt.pts = write_video_count;
1971 int error_code = av_interleaved_write_frame(oc, &pkt);
1972 if (error_code < 0) {
1985 av_init_packet(&pkt);
1988 pkt.pts = pkt.dts = AV_NOPTS_VALUE;
1991 uint8_t *video_outbuf = NULL;
1994 write_video_count += av_rescale_q(1, (AVRational) {
info.
fps.
den,
info.
fps.
num}, video_codec->time_base);
1997 frame_final->pts = write_video_count;
1999 if (hw_en_on && hw_en_supported) {
2000 if (!(hw_frame = av_frame_alloc())) {
2001 fprintf(stderr,
"Error code: av_hwframe_alloc\n");
2003 if (av_hwframe_get_buffer(video_codec->hw_frames_ctx, hw_frame, 0) < 0) {
2004 fprintf(stderr,
"Error code: av_hwframe_get_buffer\n");
2006 if (!hw_frame->hw_frames_ctx) {
2007 fprintf(stderr,
"Error hw_frames_ctx.\n");
2009 hw_frame->format = AV_PIX_FMT_NV12;
2010 if ( av_hwframe_transfer_data(hw_frame, frame_final, 0) < 0) {
2011 fprintf(stderr,
"Error while transferring frame data to surface.\n");
2013 av_frame_copy_props(hw_frame, frame_final);
2015 #endif // HAVE_HW_ACCEL
2017 int got_packet_ptr = 0;
2021 int frameFinished = 0;
2025 if (hw_en_on && hw_en_supported) {
2026 ret = avcodec_send_frame(video_codec, hw_frame);
2028 #endif // HAVE_HW_ACCEL
2030 ret = avcodec_send_frame(video_codec, frame_final);
2035 if (ret == AVERROR(EAGAIN) ) {
2036 std::cerr <<
"Frame EAGAIN" <<
"\n";
2038 if (ret == AVERROR_EOF ) {
2039 std::cerr <<
"Frame AVERROR_EOF" <<
"\n";
2041 avcodec_send_frame(video_codec, NULL);
2045 ret = avcodec_receive_packet(video_codec, &pkt);
2047 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
2048 avcodec_flush_buffers(video_codec);
2059 #if LIBAVFORMAT_VERSION_MAJOR >= 54
2061 error_code = avcodec_encode_video2(video_codec, &pkt, frame_final, &got_packet_ptr);
2062 if (error_code != 0) {
2063 std::cerr <<
"Frame AVERROR_EOF" <<
"\n";
2065 if (got_packet_ptr == 0) {
2066 std::cerr <<
"Frame gotpacket error" <<
"\n";
2070 int video_outbuf_size = 200000;
2071 video_outbuf = (uint8_t*) av_malloc(200000);
2074 int out_size = avcodec_encode_video(video_codec, video_outbuf, video_outbuf_size, frame_final);
2078 if(video_codec->coded_frame->key_frame)
2079 pkt.flags |= AV_PKT_FLAG_KEY;
2080 pkt.data= video_outbuf;
2086 #endif // LIBAVFORMAT_VERSION_MAJOR >= 54
2087 #endif // IS_FFMPEG_3_2
2090 if (error_code == 0 && got_packet_ptr) {
2097 if (pkt.pts != AV_NOPTS_VALUE)
2098 pkt.pts = av_rescale_q(pkt.pts, video_codec->time_base, video_st->time_base);
2099 if (pkt.dts != AV_NOPTS_VALUE)
2100 pkt.dts = av_rescale_q(pkt.dts, video_codec->time_base, video_st->time_base);
2101 if (pkt.duration > 0)
2102 pkt.duration = av_rescale_q(pkt.duration, video_codec->time_base, video_st->time_base);
2103 pkt.stream_index = video_st->index;
2106 int error_code = av_interleaved_write_frame(oc, &pkt);
2107 if (error_code < 0) {
2115 delete[] video_outbuf;
2120 if (hw_en_on && hw_en_supported) {
2122 av_frame_free(&hw_frame);
2126 #endif // HAVE_HW_ACCEL
2136 av_dump_format(oc, 0, path.c_str(), 1);
2140 void FFmpegWriter::InitScalers(
int source_width,
int source_height) {
2141 int scale_mode = SWS_FAST_BILINEAR;
2143 scale_mode = SWS_BICUBIC;
2147 for (
int x = 0; x < num_of_rescalers; x++) {
2150 if (hw_en_on && hw_en_supported) {
2153 #endif // HAVE_HW_ACCEL
2160 image_rescalers.push_back(img_convert_ctx);
2166 original_sample_rate = sample_rate;
2167 original_channels = channels;
2173 for (
int x = 0; x < num_of_rescalers; x++)
2174 sws_freeContext(image_rescalers[x]);
2177 image_rescalers.clear();