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;
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;
1912 pixels = frame->GetPixels();
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);
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);
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)
1954 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_video_packet",
"frame->number", frame->number,
"oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE);
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);
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);
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;
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);
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) {
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();
#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.