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);
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());
224 new_codec = avcodec_find_encoder_by_name(codec.c_str());
227 new_codec = avcodec_find_encoder_by_name(codec.c_str());
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);
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);
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);
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;
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;
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) {
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);
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();
1513 sample_rate_in_frame = frame->SampleRate();
1514 samples_in_frame = frame->GetAudioSamplesCount();
1515 channels_in_frame = frame->GetAudioChannelsCount();
1516 channel_layout_in_frame = frame->ChannelsLayout();
1520 float *frame_samples_float = NULL;
1522 frame_samples_float = frame->GetInterleavedAudioSamples(sample_rate_in_frame, NULL, &samples_in_frame);
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;
1715 frame_final->format = audio_codec->sample_fmt;
1717 av_samples_alloc(frame_final->data, frame_final->linesize,
info.
channels, frame_final->nb_samples, audio_codec->sample_fmt, 0);
1722 frame_final->linesize[0],
1723 frame_final->nb_samples,
1725 audio_frame->linesize[0],
1726 audio_frame->nb_samples);
1730 memcpy(samples, frame_final->data[0], nb_samples * av_get_bytes_per_sample(audio_codec->sample_fmt) *
info.
channels);
1733 av_freep(&(audio_frame->data[0]));
1735 all_queued_samples = NULL;
1741 final_samples = (int16_t *) av_malloc(
1742 sizeof(int16_t) * audio_input_position * (av_get_bytes_per_sample(audio_codec->sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)));
1745 memcpy(final_samples, samples, audio_input_position * av_get_bytes_per_sample(audio_codec->sample_fmt));
1748 frame_final->nb_samples = audio_input_frame_size;
1751 avcodec_fill_audio_frame(frame_final, audio_codec->channels, audio_codec->sample_fmt, (uint8_t *) final_samples,
1752 audio_encoder_buffer_size, 0);
1756 write_audio_count += FFMIN(audio_input_frame_size, audio_input_position);
1757 frame_final->pts = write_audio_count;
1761 av_init_packet(&pkt);
1762 pkt.data = audio_encoder_buffer;
1763 pkt.size = audio_encoder_buffer_size;
1766 pkt.pts = pkt.dts = write_audio_count;
1769 int got_packet_ptr = 0;
1775 int frame_finished = 0;
1776 error_code = ret = avcodec_send_frame(audio_codec, frame_final);
1777 if (ret < 0 && ret != AVERROR(EINVAL) && ret != AVERROR_EOF) {
1778 avcodec_send_frame(audio_codec, NULL);
1783 ret = avcodec_receive_packet(audio_codec, &pkt);
1786 if(ret == AVERROR(EINVAL) || ret == AVERROR_EOF) {
1787 avcodec_flush_buffers(audio_codec);
1791 ret = frame_finished;
1794 if (!pkt.data && !frame_finished)
1798 got_packet_ptr = ret;
1801 int error_code = avcodec_encode_audio2(audio_codec, &pkt, frame_final, &got_packet_ptr);
1804 if (error_code == 0 && got_packet_ptr) {
1808 pkt.pts = pkt.dts = write_audio_count;
1811 if (pkt.pts != AV_NOPTS_VALUE)
1812 pkt.pts = av_rescale_q(pkt.pts, audio_codec->time_base, audio_st->time_base);
1813 if (pkt.dts != AV_NOPTS_VALUE)
1814 pkt.dts = av_rescale_q(pkt.dts, audio_codec->time_base, audio_st->time_base);
1815 if (pkt.duration > 0)
1816 pkt.duration = av_rescale_q(pkt.duration, audio_codec->time_base, audio_st->time_base);
1819 pkt.stream_index = audio_st->index;
1820 pkt.flags |= AV_PKT_FLAG_KEY;
1823 int error_code = av_interleaved_write_frame(oc, &pkt);
1824 if (error_code < 0) {
1829 if (error_code < 0) {
1834 av_freep(&(frame_final->data[0]));
1841 audio_input_position = 0;
1846 if (all_resampled_samples) {
1847 av_freep(&all_resampled_samples);
1848 all_resampled_samples = NULL;
1850 if (all_queued_samples) {
1851 av_freep(&all_queued_samples);
1852 all_queued_samples = NULL;
1859 AVFrame *FFmpegWriter::allocate_avframe(
PixelFormat pix_fmt,
int width,
int height,
int *buffer_size, uint8_t *new_buffer) {
1861 AVFrame *new_av_frame = NULL;
1865 if (new_av_frame == NULL)
1866 throw OutOfMemory(
"Could not allocate AVFrame", path);
1874 new_buffer = (uint8_t *) av_malloc(*buffer_size *
sizeof(uint8_t));
1877 new_av_frame->width = width;
1878 new_av_frame->height = height;
1879 new_av_frame->format = pix_fmt;
1883 return new_av_frame;
1887 void FFmpegWriter::process_video_packet(std::shared_ptr<Frame> frame) {
1889 int source_image_width = frame->GetWidth();
1890 int source_image_height = frame->GetHeight();
1893 if (source_image_height == 1 && source_image_width == 1)
1897 if (image_rescalers.size() == 0)
1898 InitScalers(source_image_width, source_image_height);
1901 SwsContext *scaler = image_rescalers[rescaler_position];
1902 rescaler_position++;
1903 if (rescaler_position == num_of_rescalers)
1904 rescaler_position = 0;
1906 #pragma omp task firstprivate(frame, scaler, source_image_width, source_image_height)
1909 int bytes_source = 0;
1910 int bytes_final = 0;
1911 AVFrame *frame_source = NULL;
1912 const uchar *pixels = NULL;
1915 pixels = frame->GetPixels();
1918 frame_source = allocate_avframe(
PIX_FMT_RGBA, source_image_width, source_image_height, &bytes_source, (uint8_t *) pixels);
1920 AVFrame *frame_final;
1922 if (hw_en_on && hw_en_supported) {
1923 frame_final = allocate_avframe(AV_PIX_FMT_NV12,
info.
width,
info.
height, &bytes_final, NULL);
1927 frame_final = allocate_avframe((AVPixelFormat)(video_st->codecpar->format),
info.
width,
info.
height, &bytes_final, NULL);
1930 AVFrame *frame_final = allocate_avframe(video_codec->pix_fmt,
info.
width,
info.
height, &bytes_final, NULL);
1938 sws_scale(scaler, frame_source->data, frame_source->linesize, 0,
1939 source_image_height, frame_final->data, frame_final->linesize);
1942 #pragma omp critical (av_frames_section)
1943 add_avframe(frame, frame_final);
1953 bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *frame_final) {
1954 #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
1957 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_video_packet",
"frame->number", frame->number,
"oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE);
1959 if (oc->oformat->flags & AVFMT_RAWPICTURE) {
1962 av_init_packet(&pkt);
1964 pkt.flags |= AV_PKT_FLAG_KEY;
1965 pkt.stream_index = video_st->index;
1966 pkt.data = (uint8_t *) frame_final->data;
1967 pkt.size =
sizeof(AVPicture);
1970 write_video_count += av_rescale_q(1, (AVRational) {
info.
fps.
den,
info.
fps.
num}, video_codec->time_base);
1971 pkt.pts = write_video_count;
1974 int error_code = av_interleaved_write_frame(oc, &pkt);
1975 if (error_code < 0) {
1988 av_init_packet(&pkt);
1991 pkt.pts = pkt.dts = AV_NOPTS_VALUE;
1994 uint8_t *video_outbuf = NULL;
1997 write_video_count += av_rescale_q(1, (AVRational) {
info.
fps.
den,
info.
fps.
num}, video_codec->time_base);
2000 frame_final->pts = write_video_count;
2002 if (hw_en_on && hw_en_supported) {
2003 if (!(hw_frame = av_frame_alloc())) {
2004 fprintf(stderr,
"Error code: av_hwframe_alloc\n");
2006 if (av_hwframe_get_buffer(video_codec->hw_frames_ctx, hw_frame, 0) < 0) {
2007 fprintf(stderr,
"Error code: av_hwframe_get_buffer\n");
2009 if (!hw_frame->hw_frames_ctx) {
2010 fprintf(stderr,
"Error hw_frames_ctx.\n");
2012 hw_frame->format = AV_PIX_FMT_NV12;
2013 if ( av_hwframe_transfer_data(hw_frame, frame_final, 0) < 0) {
2014 fprintf(stderr,
"Error while transferring frame data to surface.\n");
2016 av_frame_copy_props(hw_frame, frame_final);
2020 int got_packet_ptr = 0;
2024 int frameFinished = 0;
2028 if (hw_en_on && hw_en_supported) {
2029 ret = avcodec_send_frame(video_codec, hw_frame);
2033 ret = avcodec_send_frame(video_codec, frame_final);
2038 if (ret == AVERROR(EAGAIN) ) {
2039 std::cerr <<
"Frame EAGAIN" <<
"\n";
2041 if (ret == AVERROR_EOF ) {
2042 std::cerr <<
"Frame AVERROR_EOF" <<
"\n";
2044 avcodec_send_frame(video_codec, NULL);
2048 ret = avcodec_receive_packet(video_codec, &pkt);
2050 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
2051 avcodec_flush_buffers(video_codec);
2062 #if LIBAVFORMAT_VERSION_MAJOR >= 54
2064 error_code = avcodec_encode_video2(video_codec, &pkt, frame_final, &got_packet_ptr);
2065 if (error_code != 0) {
2066 std::cerr <<
"Frame AVERROR_EOF" <<
"\n";
2068 if (got_packet_ptr == 0) {
2069 std::cerr <<
"Frame gotpacket error" <<
"\n";
2073 int video_outbuf_size = 200000;
2074 video_outbuf = (uint8_t*) av_malloc(200000);
2077 int out_size = avcodec_encode_video(video_codec, video_outbuf, video_outbuf_size, frame_final);
2081 if(video_codec->coded_frame->key_frame)
2082 pkt.flags |= AV_PKT_FLAG_KEY;
2083 pkt.data= video_outbuf;
2093 if (error_code == 0 && got_packet_ptr) {
2100 if (pkt.pts != AV_NOPTS_VALUE)
2101 pkt.pts = av_rescale_q(pkt.pts, video_codec->time_base, video_st->time_base);
2102 if (pkt.dts != AV_NOPTS_VALUE)
2103 pkt.dts = av_rescale_q(pkt.dts, video_codec->time_base, video_st->time_base);
2104 if (pkt.duration > 0)
2105 pkt.duration = av_rescale_q(pkt.duration, video_codec->time_base, video_st->time_base);
2106 pkt.stream_index = video_st->index;
2109 int error_code = av_interleaved_write_frame(oc, &pkt);
2110 if (error_code < 0) {
2118 delete[] video_outbuf;
2123 if (hw_en_on && hw_en_supported) {
2125 av_frame_free(&hw_frame);
2139 av_dump_format(oc, 0, path.c_str(), 1);
2143 void FFmpegWriter::InitScalers(
int source_width,
int source_height) {
2144 int scale_mode = SWS_FAST_BILINEAR;
2146 scale_mode = SWS_BICUBIC;
2150 for (
int x = 0; x < num_of_rescalers; x++) {
2153 if (hw_en_on && hw_en_supported) {
2163 image_rescalers.push_back(img_convert_ctx);
2169 original_sample_rate = sample_rate;
2170 original_channels = channels;
2176 for (
int x = 0; x < num_of_rescalers; x++)
2177 sws_freeContext(image_rescalers[x]);
2180 image_rescalers.clear();
#define AUDIO_PACKET_ENCODING_SIZE
#define AV_GET_CODEC_FROM_STREAM(av_stream, codec_in)
#define AV_SET_FILENAME(oc, f)
#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 AV_GET_CODEC_TYPE(av_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_FORMAT_NEW_STREAM(oc, st_codec, av_codec, av_st)
#define AV_ALLOCATE_FRAME()
#define AV_GET_CODEC_PAR_CONTEXT(av_stream, av_codec)
#define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height)
#define AV_OPTION_SET(av_stream, priv_data, name, value, avcodec)
#define AV_FREE_PACKET(av_packet)
#define av_err2str(errnum)
#define AVCODEC_MAX_AUDIO_FRAME_SIZE
#define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context)
#define MY_INPUT_BUFFER_PADDING_SIZE
#define AV_RESET_FRAME(av_frame)
#define FF_NUM_PROCESSORS
#define OPEN_MP_NUM_PROCESSORS
Exception when encoding audio packet.
void Close()
Close the writer.
void SetAudioOptions(bool has_audio, std::string codec, int sample_rate, int channels, openshot::ChannelLayout channel_layout, int bit_rate)
Set audio export options.
void SetOption(openshot::StreamType stream, std::string name, std::string value)
Set custom options (some codecs accept additional params). This must be called after the PrepareStrea...
void PrepareStreams()
Prepare & initialize streams and open codecs. This method is called automatically by the Open() metho...
void SetVideoOptions(bool has_video, std::string codec, openshot::Fraction fps, int width, int height, openshot::Fraction pixel_ratio, bool interlaced, bool top_field_first, int bit_rate)
Set video export options.
void ResampleAudio(int sample_rate, int channels)
Set audio resample options.
FFmpegWriter(std::string path)
Constructor for FFmpegWriter. Throws one of the following exceptions.
void WriteHeader()
Write the file header (after the options are set). This method is called automatically by the Open() ...
static bool IsValidCodec(std::string codec_name)
Determine if codec name is valid.
void OutputStreamInfo()
Output the ffmpeg info about this format, streams, and codecs (i.e. dump format)
void WriteFrame(std::shared_ptr< openshot::Frame > frame)
Add a frame to the stack waiting to be encoded.
void WriteTrailer()
Write the file trailer (after all frames are written). This is called automatically by the Close() me...
void RemoveScalers()
Remove & deallocate all software scalers.
This class represents a fraction.
int num
Numerator for the fraction.
void Reduce()
Reduce this fraction (i.e. 640/480 = 4/3)
int den
Denominator for the fraction.
Exception when an invalid # of audio channels are detected.
Exception when no valid codec is found for a file.
Exception for files that can not be found or opened.
Exception when invalid encoding options are used.
Exception when invalid sample rate is detected during encoding.
Exception when no streams are found in the file.
Exception when memory could not be allocated.
This abstract class is the base class, used by all readers in libopenshot.
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)
int HW_EN_DEVICE_SET
Which GPU to use to encode (0 is the first)
WriterInfo info
Information about the current media file.
Exception when a writer is closed, and a frame is requested.
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)
This namespace is the default namespace for all code in the openshot library.
ChannelLayout
This enumeration determines the audio channel layout (such as stereo, mono, 5 point surround,...
StreamType
This enumeration designates the type of stream when encoding (video or audio)
@ 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)
int audio_bit_rate
The bit rate of the audio stream (in bytes)
int video_bit_rate
The bit rate of the video stream (in bytes)
bool has_audio
Determines if this file has an audio stream.
bool top_field_first
Which interlaced field should be displayed first.
int channels
The number of audio channels used in the audio stream.
std::string vcodec
The name of the video codec used to encode / decode the video stream.
bool has_video
Determines if this file has a video stream.
std::map< std::string, std::string > metadata
An optional map/dictionary of video & audio metadata.
openshot::Fraction fps
Frames per second, as a fraction (i.e. 24/1 = 24 fps)
std::string acodec
The name of the audio codec used to encode / decode the video stream.
openshot::Fraction video_timebase
The video timebase determines how long each frame stays on the screen.
openshot::ChannelLayout channel_layout
The channel layout (mono, stereo, 5 point surround, etc...)
openshot::Fraction display_ratio
The ratio of width to height of the video stream (i.e. 640x480 has a ratio of 4/3)
int width
The width of the video (in pixels)
openshot::Fraction pixel_ratio
The pixel ratio of the video stream as a fraction (i.e. some pixels are not square)
int sample_rate
The number of audio samples per second (44100 is a common sample rate)
bool interlaced_frame
Are the contents of this frame interlaced.