41 static AVBufferRef *hw_device_ctx = NULL;
44 static int set_hwframe_ctx(AVCodecContext *ctx, AVBufferRef *hw_device_ctx, int64_t width, int64_t height)
46 AVBufferRef *hw_frames_ref;
47 AVHWFramesContext *frames_ctx = NULL;
50 if (!(hw_frames_ref = av_hwframe_ctx_alloc(hw_device_ctx))) {
51 std::clog <<
"Failed to create HW frame context.\n";
54 frames_ctx = (AVHWFramesContext *)(hw_frames_ref->data);
56 frames_ctx->sw_format = AV_PIX_FMT_NV12;
57 frames_ctx->width = width;
58 frames_ctx->height = height;
59 frames_ctx->initial_pool_size = 20;
60 if ((err = av_hwframe_ctx_init(hw_frames_ref)) < 0) {
61 std::clog <<
"Failed to initialize HW frame context. " <<
62 "Error code: " << av_err2string(err) <<
"\n";
63 av_buffer_unref(&hw_frames_ref);
66 ctx->hw_frames_ctx = av_buffer_ref(hw_frames_ref);
67 if (!ctx->hw_frames_ctx)
68 err = AVERROR(ENOMEM);
70 av_buffer_unref(&hw_frames_ref);
73 #endif // USE_HW_ACCEL
76 path(
path), oc(NULL), audio_st(NULL), video_st(NULL), samples(NULL),
77 audio_outbuf(NULL), audio_outbuf_size(0), audio_input_frame_size(0), audio_input_position(0),
78 initial_audio_input_frame_size(0), img_convert_ctx(NULL), num_of_rescalers(1),
79 rescaler_position(0), video_codec_ctx(NULL), audio_codec_ctx(NULL), is_writing(false), video_timestamp(0), audio_timestamp(0),
80 original_sample_rate(0), original_channels(0), avr(NULL), avr_planar(NULL), is_open(false), prepare_streams(false),
81 write_header(false), write_trailer(false), audio_encoder_buffer_size(0), audio_encoder_buffer(NULL) {
101 if (!prepare_streams)
106 open_video(oc, video_st);
108 open_audio(oc, audio_st);
117 void FFmpegWriter::auto_detect_format() {
123 "Could not allocate memory for AVFormatContext.", path);
127 oc->oformat = av_guess_format(NULL, path.c_str(), NULL);
128 if (oc->oformat ==
nullptr) {
130 "Could not deduce output format from file extension.", path);
134 if (oc->oformat->video_codec != AV_CODEC_ID_NONE &&
info.
has_video)
135 info.
vcodec = avcodec_find_encoder(oc->oformat->video_codec)->name;
138 if (oc->oformat->audio_codec != AV_CODEC_ID_NONE &&
info.
has_audio)
139 info.
acodec = avcodec_find_encoder(oc->oformat->audio_codec)->name;
143 void FFmpegWriter::initialize_streams() {
145 "FFmpegWriter::initialize_streams",
146 "oc->oformat->video_codec", oc->oformat->video_codec,
147 "oc->oformat->audio_codec", oc->oformat->audio_codec,
148 "AV_CODEC_ID_NONE", AV_CODEC_ID_NONE);
153 if (oc->oformat->video_codec != AV_CODEC_ID_NONE &&
info.
has_video)
155 video_st = add_video_stream();
157 if (oc->oformat->audio_codec != AV_CODEC_ID_NONE &&
info.
has_audio)
159 audio_st = add_audio_stream();
165 if (
codec.length() > 0) {
166 const AVCodec *new_codec;
169 #if defined(__linux__)
170 if (strstr(
codec.c_str(),
"_vaapi") != NULL) {
171 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
176 }
else if (strstr(
codec.c_str(),
"_nvenc") != NULL) {
177 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
183 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
187 #elif defined(_WIN32)
188 if (strstr(
codec.c_str(),
"_dxva2") != NULL) {
189 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
194 }
else if (strstr(
codec.c_str(),
"_nvenc") != NULL) {
195 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
201 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
205 #elif defined(__APPLE__)
206 if (strstr(
codec.c_str(),
"_videotoolbox") != NULL) {
207 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
213 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
218 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
219 #endif //__linux__/_WIN32/__APPLE__
220 #else // USE_HW_ACCEL
221 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
222 #endif // USE_HW_ACCEL
223 if (new_codec == NULL)
224 throw InvalidCodec(
"A valid video codec could not be found for this file.", path);
243 if (pixel_ratio.
num > 0) {
247 if (bit_rate >= 1000)
249 if ((bit_rate >= 0) && (bit_rate < 256))
266 "FFmpegWriter::SetVideoOptions (" +
codec +
")",
267 "width", width,
"height", height,
268 "size.num", size.
num,
"size.den", size.
den,
269 "fps.num", fps.
num,
"fps.den", fps.
den);
279 true,
codec, fps, width, height,
288 if (
codec.length() > 0) {
289 const AVCodec *new_codec = avcodec_find_encoder_by_name(
codec.c_str());
290 if (new_codec == NULL)
291 throw InvalidCodec(
"A valid audio codec could not be found for this file.", path);
297 if (sample_rate > 7999)
306 if (original_sample_rate == 0)
308 if (original_channels == 0)
312 "FFmpegWriter::SetAudioOptions (" +
codec +
")",
313 "sample_rate", sample_rate,
314 "channels", channels,
315 "bit_rate", bit_rate);
326 true,
codec, sample_rate, 2,
335 AVCodecContext *c = NULL;
337 std::stringstream convert(value);
356 throw NoStreamsFound(
"The stream was not found. Be sure to call PrepareStreams() first.", path);
359 const AVOption *option = NULL;
367 if (option || (name ==
"g" || name ==
"qmin" || name ==
"qmax" || name ==
"max_b_frames" || name ==
"mb_decision" ||
368 name ==
"level" || name ==
"profile" || name ==
"slices" || name ==
"rc_min_rate" || name ==
"rc_max_rate" ||
369 name ==
"rc_buffer_size" || name ==
"crf" || name ==
"cqp" || name ==
"qp")) {
373 convert >> c->gop_size;
375 else if (name ==
"qmin")
379 else if (name ==
"qmax")
383 else if (name ==
"max_b_frames")
385 convert >> c->max_b_frames;
387 else if (name ==
"mb_decision")
389 convert >> c->mb_decision;
391 else if (name ==
"level")
395 else if (name ==
"profile")
397 convert >> c->profile;
399 else if (name ==
"slices")
401 convert >> c->slices;
403 else if (name ==
"rc_min_rate")
405 convert >> c->rc_min_rate;
407 else if (name ==
"rc_max_rate")
409 convert >> c->rc_max_rate;
411 else if (name ==
"rc_buffer_size")
413 convert >> c->rc_buffer_size;
415 else if (name ==
"cqp") {
421 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),63), 0);
423 #endif // USE_HW_ACCEL
425 switch (c->codec_id) {
426 #if (LIBAVCODEC_VERSION_MAJOR >= 58)
428 case AV_CODEC_ID_AV1 :
430 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),63), 0);
433 case AV_CODEC_ID_VP8 :
434 c->bit_rate = 10000000;
435 av_opt_set_int(c->priv_data,
"qp", std::max(std::min(std::stoi(value), 63), 4), 0);
437 case AV_CODEC_ID_VP9 :
439 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value), 63), 0);
440 if (std::stoi(value) == 0) {
441 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
442 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
445 case AV_CODEC_ID_H264 :
446 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value), 51), 0);
447 if (std::stoi(value) == 0) {
448 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
452 case AV_CODEC_ID_HEVC :
453 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value), 51), 0);
454 if (std::stoi(value) == 0) {
455 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
456 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
461 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value), 63), 0);
465 }
else if (name ==
"crf") {
471 double mbs = 15000000.0;
480 c->bit_rate = (int)(mbs);
482 #endif // USE_HW_ACCEL
484 switch (c->codec_id) {
485 #if (LIBAVCODEC_VERSION_MAJOR >= 58)
487 case AV_CODEC_ID_AV1 :
490 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value),63), 0);
493 case AV_CODEC_ID_VP8 :
494 c->bit_rate = 10000000;
495 av_opt_set_int(c->priv_data,
"crf", std::max(std::min(std::stoi(value), 63), 4), 0);
497 case AV_CODEC_ID_VP9 :
499 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value), 63), 0);
500 if (std::stoi(value) == 0) {
501 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
502 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
505 case AV_CODEC_ID_H264 :
506 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value), 51), 0);
507 if (std::stoi(value) == 0) {
508 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
512 case AV_CODEC_ID_HEVC :
513 if (strstr(
info.
vcodec.c_str(),
"svt_hevc") != NULL) {
514 av_opt_set_int(c->priv_data,
"preset", 7, 0);
515 av_opt_set_int(c->priv_data,
"forced-idr",1,0);
516 av_opt_set_int(c->priv_data,
"qp",std::min(std::stoi(value), 51),0);
519 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value), 51), 0);
521 if (std::stoi(value) == 0) {
522 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
523 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
529 double mbs = 15000000.0;
537 c->bit_rate = (int) (mbs);
540 }
else if (name ==
"qp") {
544 #if (LIBAVCODEC_VERSION_MAJOR >= 58)
546 switch (c->codec_id) {
547 case AV_CODEC_ID_AV1 :
549 if (strstr(
info.
vcodec.c_str(),
"svtav1") != NULL) {
550 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),63), 0);
552 else if (strstr(
info.
vcodec.c_str(),
"rav1e") != NULL) {
555 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),255), 0);
557 else if (strstr(
info.
vcodec.c_str(),
"aom") != NULL) {
561 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value),63), 0);
564 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value),63), 0);
566 case AV_CODEC_ID_HEVC :
568 if (strstr(
info.
vcodec.c_str(),
"svt_hevc") != NULL) {
569 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),51), 0);
570 av_opt_set_int(c->priv_data,
"preset", 7, 0);
571 av_opt_set_int(c->priv_data,
"forced-idr",1,0);
575 #endif // FFmpeg 4.0+
578 AV_OPTION_SET(st, c->priv_data, name.c_str(), value.c_str(), c);
582 "FFmpegWriter::SetOption (" + (std::string)name +
")",
587 }
else if (name ==
"muxing_preset") {
588 if (value ==
"mp4_faststart") {
590 av_dict_set(&
mux_dict,
"movflags",
"faststart", 0);
591 }
else if (value ==
"mp4_fragmented") {
593 av_dict_set(&
mux_dict,
"movflags",
"frag_keyframe", 0);
594 av_dict_set(&
mux_dict,
"min_frag_duration",
"8000000", 0);
597 throw InvalidOptions(
"The option is not valid for this codec.", path);
608 if (avcodec_find_encoder_by_name(codec_name.c_str()) == NULL)
617 throw InvalidOptions(
"No video or audio options have been set. You must set has_video or has_audio (or both).", path);
620 "FFmpegWriter::PrepareStreams [" + path +
"]",
625 initialize_streams();
628 prepare_streams =
true;
634 throw InvalidOptions(
"No video or audio options have been set. You must set has_video or has_audio (or both).", path);
637 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
638 if (avio_open(&oc->pb, path.c_str(), AVIO_FLAG_WRITE) < 0)
639 throw InvalidFile(
"Could not open or write file.", path);
646 for (std::map<std::string, std::string>::iterator iter =
info.
metadata.begin(); iter !=
info.
metadata.end(); ++iter) {
647 av_dict_set(&oc->metadata, iter->first.c_str(), iter->second.c_str(), 0);
651 AVDictionary *dict = NULL;
653 bool is_mp4 = strcmp(oc->oformat->name,
"mp4");
654 bool is_mov = strcmp(oc->oformat->name,
"mov");
656 if (is_mp4 || is_mov)
660 if (avformat_write_header(oc, &dict) != 0) {
662 "FFmpegWriter::WriteHeader (avformat_write_header)");
663 throw InvalidFile(
"Could not write header to file.", path);
667 if (dict) av_dict_free(&dict);
680 throw WriterClosed(
"The FFmpegWriter is closed. Call Open() before calling this method.", path);
683 "FFmpegWriter::WriteFrame",
684 "frame->number", frame->number,
685 "is_writing", is_writing);
695 void FFmpegWriter::write_frame(std::shared_ptr<Frame> frame) {
700 bool has_error_encoding_video =
false;
704 write_audio_packets(
false, frame);
708 process_video_packet(frame);
712 if (av_frames.count(frame)) {
714 AVFrame *frame_final = av_frames[frame];
717 if (!write_video_packet(frame, frame_final)) {
718 has_error_encoding_video =
true;
722 av_freep(&(frame_final->data[0]));
724 av_frames.erase(frame);
732 if (has_error_encoding_video)
739 "FFmpegWriter::WriteFrame (from Reader)",
744 for (int64_t number = start; number <= length; number++) {
746 std::shared_ptr<Frame> f = reader->
GetFrame(number);
757 write_audio_packets(
true, NULL);
766 av_write_trailer(oc);
769 write_trailer =
true;
775 void FFmpegWriter::flush_encoders() {
778 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
792 video_timestamp += av_rescale_q(1, av_make_q(
info.
fps.
den,
info.
fps.
num), video_codec_ctx->time_base);
795 AVPacket* pkt = av_packet_alloc();
809 error_code = avcodec_send_frame(video_codec_ctx, NULL);
811 while (error_code >= 0) {
812 error_code = avcodec_receive_packet(video_codec_ctx, pkt);
813 if (error_code == AVERROR(EAGAIN)|| error_code == AVERROR_EOF) {
816 avcodec_flush_buffers(video_codec_ctx);
819 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
820 pkt->stream_index = video_st->index;
821 error_code = av_interleaved_write_frame(oc, pkt);
823 #else // IS_FFMPEG_3_2
826 error_code = avcodec_encode_video2(video_codec_ctx, pkt, NULL, &got_packet);
828 #endif // IS_FFMPEG_3_2
830 if (error_code < 0) {
832 "FFmpegWriter::flush_encoders ERROR ["
833 + av_err2string(error_code) +
"]",
834 "error_code", error_code);
841 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
842 pkt->stream_index = video_st->index;
845 error_code = av_interleaved_write_frame(oc, pkt);
846 if (error_code < 0) {
848 "FFmpegWriter::flush_encoders ERROR ["
849 + av_err2string(error_code) +
"]",
850 "error_code", error_code);
859 AVPacket* pkt = av_packet_alloc();
866 pkt->pts = pkt->dts = audio_timestamp;
872 error_code = avcodec_send_frame(audio_codec_ctx, NULL);
874 error_code = avcodec_encode_audio2(audio_codec_ctx, pkt, NULL, &got_packet);
876 if (error_code < 0) {
878 "FFmpegWriter::flush_encoders ERROR ["
879 + av_err2string(error_code) +
"]",
880 "error_code", error_code);
888 pkt->pts = pkt->dts = audio_timestamp;
891 av_packet_rescale_ts(pkt, audio_codec_ctx->time_base, audio_st->time_base);
894 pkt->stream_index = audio_st->index;
895 pkt->flags |= AV_PKT_FLAG_KEY;
898 error_code = av_interleaved_write_frame(oc, pkt);
899 if (error_code < 0) {
901 "FFmpegWriter::flush_encoders ERROR ["
902 + av_err2string(error_code) +
"]",
903 "error_code", error_code);
907 audio_timestamp += pkt->duration;
917 void FFmpegWriter::close_video(AVFormatContext *oc, AVStream *st)
922 av_buffer_unref(&hw_device_ctx);
923 hw_device_ctx = NULL;
926 #endif // USE_HW_ACCEL
929 if (video_codec_ctx !=
nullptr) {
931 av_free(video_codec_ctx);
936 void FFmpegWriter::close_audio(AVFormatContext *oc, AVStream *st)
940 delete[] audio_outbuf;
941 delete[] audio_encoder_buffer;
944 audio_encoder_buffer = NULL;
960 if (audio_codec_ctx !=
nullptr) {
962 av_free(audio_codec_ctx);
974 close_video(oc, video_st);
976 close_audio(oc, audio_st);
979 if (image_rescalers.size() > 0)
982 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
992 avformat_free_context(oc);
997 prepare_streams =
false;
998 write_header =
false;
999 write_trailer =
false;
1005 void FFmpegWriter::add_avframe(std::shared_ptr<Frame> frame, AVFrame *av_frame) {
1007 if (!av_frames.count(frame)) {
1009 av_frames[frame] = av_frame;
1017 AVStream *FFmpegWriter::add_audio_stream() {
1019 const AVCodec *
codec = avcodec_find_encoder_by_name(
info.
acodec.c_str());
1021 throw InvalidCodec(
"A valid audio codec could not be found for this file.", path);
1024 if (audio_codec_ctx !=
nullptr) {
1029 AVStream* st = avformat_new_stream(oc,
codec);
1031 throw OutOfMemory(
"Could not allocate memory for the video stream.", path);
1035 #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
1036 st->codecpar->codec_id =
codec->id;
1038 AVCodecContext* c = audio_codec_ctx;
1040 c->codec_id =
codec->id;
1041 c->codec_type = AVMEDIA_TYPE_AUDIO;
1048 if (
codec->supported_samplerates) {
1050 for (i = 0;
codec->supported_samplerates[i] != 0; i++)
1056 if (
codec->supported_samplerates[i] == 0)
1057 throw InvalidSampleRate(
"An invalid sample rate was detected for this codec.", path);
1065 if (
codec->channel_layouts) {
1067 for (i = 0;
codec->channel_layouts[i] != 0; i++)
1068 if (channel_layout ==
codec->channel_layouts[i]) {
1070 c->channel_layout = channel_layout;
1073 if (
codec->channel_layouts[i] == 0)
1074 throw InvalidChannels(
"An invalid channel layout was detected (i.e. MONO / STEREO).", path);
1077 c->channel_layout = channel_layout;
1080 if (
codec->sample_fmts) {
1081 for (
int i = 0;
codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) {
1083 c->sample_fmt =
codec->sample_fmts[i];
1087 if (c->sample_fmt == AV_SAMPLE_FMT_NONE) {
1089 c->sample_fmt = AV_SAMPLE_FMT_S16;
1093 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1094 #if (LIBAVCODEC_VERSION_MAJOR >= 57)
1096 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1098 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1104 "FFmpegWriter::add_audio_stream",
1105 "c->codec_id", c->codec_id,
1106 "c->bit_rate", c->bit_rate,
1107 "c->channels", c->channels,
1108 "c->sample_fmt", c->sample_fmt,
1109 "c->channel_layout", c->channel_layout,
1110 "c->sample_rate", c->sample_rate);
1116 AVStream *FFmpegWriter::add_video_stream() {
1118 const AVCodec *
codec = avcodec_find_encoder_by_name(
info.
vcodec.c_str());
1120 throw InvalidCodec(
"A valid video codec could not be found for this file.", path);
1123 if (video_codec_ctx !=
nullptr) {
1128 AVStream* st = avformat_new_stream(oc,
codec);
1130 throw OutOfMemory(
"Could not allocate memory for the video stream.", path);
1134 #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
1135 st->codecpar->codec_id =
codec->id;
1138 AVCodecContext* c = video_codec_ctx;
1140 c->codec_id =
codec->id;
1141 c->codec_type = AVMEDIA_TYPE_VIDEO;
1149 #
if (LIBAVCODEC_VERSION_MAJOR >= 58)
1150 && c->codec_id != AV_CODEC_ID_AV1
1155 if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
1164 switch (c->codec_id) {
1165 #if (LIBAVCODEC_VERSION_MAJOR >= 58)
1167 case AV_CODEC_ID_AV1 :
1171 if (strstr(
info.
vcodec.c_str(),
"aom") != NULL) {
1172 int calculated_quality = 35;
1175 av_opt_set_int(c->priv_data,
"crf", calculated_quality, 0);
1178 int calculated_quality = 50;
1181 av_opt_set_int(c->priv_data,
"qp", calculated_quality, 0);
1185 if (strstr(
info.
vcodec.c_str(),
"svtav1") != NULL) {
1186 av_opt_set_int(c->priv_data,
"preset", 6, 0);
1187 av_opt_set_int(c->priv_data,
"forced-idr",1,0);
1189 else if (strstr(
info.
vcodec.c_str(),
"rav1e") != NULL) {
1190 av_opt_set_int(c->priv_data,
"speed", 7, 0);
1191 av_opt_set_int(c->priv_data,
"tile-rows", 2, 0);
1192 av_opt_set_int(c->priv_data,
"tile-columns", 4, 0);
1194 else if (strstr(
info.
vcodec.c_str(),
"aom") != NULL) {
1197 av_opt_set_int(c->priv_data,
"tile-rows", 1, 0);
1198 av_opt_set_int(c->priv_data,
"tile-columns", 2, 0);
1199 av_opt_set_int(c->priv_data,
"row-mt", 1, 0);
1200 av_opt_set_int(c->priv_data,
"cpu-used", 3, 0);
1204 case AV_CODEC_ID_VP9 :
1205 case AV_CODEC_ID_HEVC :
1206 case AV_CODEC_ID_VP8 :
1207 case AV_CODEC_ID_H264 :
1243 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 26, 0)
1244 c->framerate = av_inv_q(c->time_base);
1246 st->avg_frame_rate = av_inv_q(c->time_base);
1251 c->max_b_frames = 10;
1252 if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO)
1254 c->max_b_frames = 2;
1255 if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO)
1261 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1262 #if (LIBAVCODEC_VERSION_MAJOR >= 57)
1264 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1266 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1271 while (supported_pixel_formats != NULL && *supported_pixel_formats !=
PIX_FMT_NONE) {
1274 c->pix_fmt = *supported_pixel_formats;
1275 ++supported_pixel_formats;
1280 if (oc->oformat->video_codec == AV_CODEC_ID_RAWVIDEO) {
1284 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
1286 if (strcmp(oc->oformat->name,
"gif") != 0)
1289 oc->oformat->flags |= AVFMT_RAWPICTURE;
1299 "FFmpegWriter::add_video_stream ("
1300 + (std::string)oc->oformat->name +
" : "
1301 + (std::string)av_get_pix_fmt_name(c->pix_fmt) +
")",
1302 "c->codec_id", c->codec_id,
1303 "c->bit_rate", c->bit_rate,
1304 "c->pix_fmt", c->pix_fmt,
1305 "oc->oformat->flags", oc->oformat->flags);
1310 void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st) {
1311 const AVCodec *
codec;
1320 codec = avcodec_find_encoder(audio_codec_ctx->codec_id);
1325 AVDictionary *
opts = NULL;
1326 av_dict_set(&
opts,
"strict",
"experimental", 0);
1329 if (avcodec_open2(audio_codec_ctx,
codec, &
opts) < 0)
1330 throw InvalidCodec(
"Could not open audio codec", path);
1334 av_dict_free(&
opts);
1338 if (audio_codec_ctx->frame_size <= 1) {
1344 case AV_CODEC_ID_PCM_S16LE:
1345 case AV_CODEC_ID_PCM_S16BE:
1346 case AV_CODEC_ID_PCM_U16LE:
1347 case AV_CODEC_ID_PCM_U16BE:
1348 audio_input_frame_size >>= 1;
1355 audio_input_frame_size = audio_codec_ctx->frame_size;
1359 initial_audio_input_frame_size = audio_input_frame_size;
1366 audio_outbuf =
new uint8_t[audio_outbuf_size];
1370 audio_encoder_buffer =
new uint8_t[audio_encoder_buffer_size];
1373 for (std::map<std::string, std::string>::iterator iter =
info.
metadata.begin(); iter !=
info.
metadata.end(); ++iter) {
1374 av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1378 "FFmpegWriter::open_audio",
1379 "audio_codec_ctx->thread_count", audio_codec_ctx->thread_count,
1380 "audio_input_frame_size", audio_input_frame_size,
1385 void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) {
1386 const AVCodec *
codec;
1396 char *adapter_ptr = NULL;
1400 std::clog <<
"Encoding Device Nr: " << adapter_num <<
"\n";
1401 if (adapter_num < 3 && adapter_num >=0) {
1402 #if defined(__linux__)
1403 snprintf(adapter,
sizeof(adapter),
"/dev/dri/renderD%d", adapter_num+128);
1405 adapter_ptr = adapter;
1406 #elif defined(_WIN32) || defined(__APPLE__)
1414 #if defined(__linux__)
1415 if( adapter_ptr != NULL && access( adapter_ptr, W_OK ) == 0 ) {
1416 #elif defined(_WIN32) || defined(__APPLE__)
1417 if( adapter_ptr != NULL ) {
1420 "Encode Device present using device",
1421 "adapter", adapter_num);
1426 "Encode Device not present, using default");
1428 if (av_hwdevice_ctx_create(&hw_device_ctx,
1432 "FFmpegWriter::open_video ERROR creating hwdevice, Codec name:",
1437 #endif // USE_HW_ACCEL
1447 if (video_codec_ctx->max_b_frames && video_codec_ctx->codec_id != AV_CODEC_ID_MPEG4 && video_codec_ctx->codec_id != AV_CODEC_ID_MPEG1VIDEO && video_codec_ctx->codec_id != AV_CODEC_ID_MPEG2VIDEO)
1448 video_codec_ctx->max_b_frames = 0;
1452 av_dict_set(&
opts,
"strict",
"experimental", 0);
1466 if (av_opt_get_int(video_codec_ctx->priv_data,
"qp", 0, &qp) != 0 || qp == 0) {
1468 av_opt_set(video_codec_ctx->priv_data,
"rc_mode",
"VBR", 0);
1472 video_codec_ctx->rc_max_rate = video_codec_ctx->bit_rate;
1476 switch (video_codec_ctx->codec_id) {
1477 case AV_CODEC_ID_H264:
1478 video_codec_ctx->max_b_frames = 0;
1479 video_codec_ctx->profile = FF_PROFILE_H264_BASELINE | FF_PROFILE_H264_CONSTRAINED;
1480 av_opt_set(video_codec_ctx->priv_data,
"preset",
"slow", 0);
1481 av_opt_set(video_codec_ctx->priv_data,
"tune",
"zerolatency", 0);
1482 av_opt_set(video_codec_ctx->priv_data,
"vprofile",
"baseline", AV_OPT_SEARCH_CHILDREN);
1484 case AV_CODEC_ID_HEVC:
1487 case AV_CODEC_ID_VP9:
1492 "No codec-specific options defined for this codec. HW encoding may fail",
1493 "codec_id", video_codec_ctx->codec_id);
1502 "FFmpegWriter::open_video (set_hwframe_ctx) ERROR faled to set hwframe context",
1505 av_err2string(err), -1);
1508 #endif // USE_HW_ACCEL
1511 if (avcodec_open2(video_codec_ctx,
codec, &
opts) < 0)
1512 throw InvalidCodec(
"Could not open video codec", path);
1516 av_dict_free(&
opts);
1520 av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1524 "FFmpegWriter::open_video",
1525 "video_codec_ctx->thread_count", video_codec_ctx->thread_count);
1530 void FFmpegWriter::write_audio_packets(
bool is_final, std::shared_ptr<openshot::Frame> frame) {
1531 if (!frame && !is_final)
1535 int total_frame_samples = 0;
1536 int frame_position = 0;
1537 int channels_in_frame = 0;
1538 int sample_rate_in_frame = 0;
1539 int samples_in_frame = 0;
1544 int16_t *all_queued_samples = (int16_t *) av_malloc(all_queued_samples_size);
1545 int16_t *all_resampled_samples = NULL;
1546 int16_t *final_samples_planar = NULL;
1547 int16_t *final_samples = NULL;
1550 float *frame_samples_float = NULL;
1554 sample_rate_in_frame = frame->SampleRate();
1555 samples_in_frame = frame->GetAudioSamplesCount();
1556 channels_in_frame = frame->GetAudioChannelsCount();
1557 channel_layout_in_frame = frame->ChannelsLayout();
1560 frame_samples_float = frame->GetInterleavedAudioSamples(&samples_in_frame);
1564 total_frame_samples = samples_in_frame * channels_in_frame;
1567 const int16_t max16 = 32767;
1568 const int16_t min16 = -32768;
1569 for (
int s = 0; s < total_frame_samples; s++, frame_position++) {
1570 float valF = frame_samples_float[s] * (1 << 15);
1574 }
else if (valF < min16) {
1577 conv = int(valF + 32768.5) - 32768;
1581 all_queued_samples[frame_position] = conv;
1585 delete[] frame_samples_float;
1589 total_frame_samples = frame_position;
1590 int remaining_frame_samples = total_frame_samples;
1591 int samples_position = 0;
1595 "FFmpegWriter::write_audio_packets",
1596 "is_final", is_final,
1597 "total_frame_samples", total_frame_samples,
1598 "channel_layout_in_frame", channel_layout_in_frame,
1599 "channels_in_frame", channels_in_frame,
1600 "samples_in_frame", samples_in_frame,
1604 AVSampleFormat output_sample_fmt = audio_codec_ctx->sample_fmt;
1606 AVFrame *audio_frame = NULL;
1611 audio_frame->nb_samples = total_frame_samples / channels_in_frame;
1614 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);
1615 if (error_code < 0) {
1617 "FFmpegWriter::write_audio_packets ERROR ["
1618 + av_err2string(error_code) +
"]",
1619 "error_code", error_code);
1623 switch (audio_codec_ctx->sample_fmt) {
1624 case AV_SAMPLE_FMT_FLTP: {
1625 output_sample_fmt = AV_SAMPLE_FMT_FLT;
1628 case AV_SAMPLE_FMT_S32P: {
1629 output_sample_fmt = AV_SAMPLE_FMT_S32;
1632 case AV_SAMPLE_FMT_S16P: {
1633 output_sample_fmt = AV_SAMPLE_FMT_S16;
1636 case AV_SAMPLE_FMT_U8P: {
1637 output_sample_fmt = AV_SAMPLE_FMT_U8;
1647 total_frame_samples *= (float(
info.
sample_rate) / sample_rate_in_frame);
1648 total_frame_samples *= (float(
info.
channels) / channels_in_frame);
1653 audio_converted->nb_samples = total_frame_samples / channels_in_frame;
1654 av_samples_alloc(audio_converted->data, audio_converted->linesize,
info.
channels, audio_converted->nb_samples, output_sample_fmt, 0);
1657 "FFmpegWriter::write_audio_packets (1st resampling)",
1658 "in_sample_fmt", AV_SAMPLE_FMT_S16,
1659 "out_sample_fmt", output_sample_fmt,
1660 "in_sample_rate", sample_rate_in_frame,
1662 "in_channels", channels_in_frame,
1668 av_opt_set_int(avr,
"in_channel_layout", channel_layout_in_frame, 0);
1670 av_opt_set_int(avr,
"in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
1671 av_opt_set_int(avr,
"out_sample_fmt", output_sample_fmt, 0);
1672 av_opt_set_int(avr,
"in_sample_rate", sample_rate_in_frame, 0);
1674 av_opt_set_int(avr,
"in_channels", channels_in_frame, 0);
1681 audio_converted->data,
1682 audio_converted->linesize[0],
1683 audio_converted->nb_samples,
1685 audio_frame->linesize[0],
1686 audio_frame->nb_samples
1690 remaining_frame_samples = total_frame_samples;
1693 all_resampled_samples = (int16_t *) av_malloc(
1695 * (av_get_bytes_per_sample(output_sample_fmt) /
1696 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1700 memcpy(all_resampled_samples, audio_converted->data[0],
1701 static_cast<size_t>(nb_samples)
1703 * av_get_bytes_per_sample(output_sample_fmt));
1706 av_freep(&(audio_frame->data[0]));
1708 av_freep(&audio_converted->data[0]);
1710 all_queued_samples = NULL;
1713 "FFmpegWriter::write_audio_packets (Successfully completed 1st resampling)",
1714 "nb_samples", nb_samples,
1715 "remaining_frame_samples", remaining_frame_samples);
1719 while (remaining_frame_samples > 0 || is_final) {
1721 int remaining_packet_samples = (audio_input_frame_size *
info.
channels) - audio_input_position;
1725 if (remaining_frame_samples >= remaining_packet_samples) {
1726 diff = remaining_packet_samples;
1728 diff = remaining_frame_samples;
1735 samples + (audio_input_position
1736 * (av_get_bytes_per_sample(output_sample_fmt) /
1737 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1739 all_resampled_samples + samples_position,
1740 static_cast<size_t>(diff)
1741 * av_get_bytes_per_sample(output_sample_fmt)
1745 audio_input_position += diff;
1746 samples_position += diff * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16));
1747 remaining_frame_samples -= diff;
1750 if (audio_input_position < (audio_input_frame_size *
info.
channels) && !is_final)
1757 if (av_sample_fmt_is_planar(audio_codec_ctx->sample_fmt)) {
1759 "FFmpegWriter::write_audio_packets (2nd resampling for Planar formats)",
1760 "in_sample_fmt", output_sample_fmt,
1761 "out_sample_fmt", audio_codec_ctx->sample_fmt,
1773 av_opt_set_int(avr_planar,
"in_sample_fmt", output_sample_fmt, 0);
1774 av_opt_set_int(avr_planar,
"out_sample_fmt", audio_codec_ctx->sample_fmt, 0);
1777 av_opt_set_int(avr_planar,
"in_channels",
info.
channels, 0);
1778 av_opt_set_int(avr_planar,
"out_channels",
info.
channels, 0);
1785 audio_frame->nb_samples = audio_input_position /
info.
channels;
1788 final_samples_planar = (int16_t *) av_malloc(
1789 sizeof(int16_t) * audio_frame->nb_samples *
info.
channels
1790 * (av_get_bytes_per_sample(output_sample_fmt) /
1791 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1795 memcpy(final_samples_planar, samples,
1796 static_cast<size_t>(audio_frame->nb_samples)
1798 * av_get_bytes_per_sample(output_sample_fmt));
1801 avcodec_fill_audio_frame(audio_frame,
info.
channels, output_sample_fmt,
1802 (uint8_t *) final_samples_planar, audio_encoder_buffer_size, 0);
1805 frame_final->nb_samples = audio_input_frame_size;
1807 frame_final->format = audio_codec_ctx->sample_fmt;
1809 av_samples_alloc(frame_final->data, frame_final->linesize,
info.
channels,
1810 frame_final->nb_samples, audio_codec_ctx->sample_fmt, 0);
1816 frame_final->linesize[0],
1817 frame_final->nb_samples,
1819 audio_frame->linesize[0],
1820 audio_frame->nb_samples
1824 const auto copy_length =
static_cast<size_t>(nb_samples)
1825 * av_get_bytes_per_sample(audio_codec_ctx->sample_fmt)
1829 memcpy(samples, frame_final->data[0], copy_length);
1832 av_freep(&(audio_frame->data[0]));
1834 all_queued_samples = NULL;
1837 "FFmpegWriter::write_audio_packets (Successfully completed 2nd resampling for Planar formats)",
1838 "nb_samples", nb_samples);
1842 const auto buf_size =
static_cast<size_t>(audio_input_position)
1843 * (av_get_bytes_per_sample(audio_codec_ctx->sample_fmt) /
1844 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)
1846 final_samples =
reinterpret_cast<int16_t*
>(
1847 av_malloc(
sizeof(int16_t) * buf_size));
1850 memcpy(final_samples, samples,
1851 audio_input_position * av_get_bytes_per_sample(audio_codec_ctx->sample_fmt));
1854 frame_final->nb_samples = audio_input_frame_size;
1857 avcodec_fill_audio_frame(frame_final, audio_codec_ctx->channels,
1858 audio_codec_ctx->sample_fmt, (uint8_t *) final_samples,
1859 audio_encoder_buffer_size, 0);
1863 frame_final->pts = audio_timestamp;
1867 AVPacket* pkt = av_packet_alloc();
1870 av_init_packet(pkt);
1872 pkt->data = audio_encoder_buffer;
1873 pkt->size = audio_encoder_buffer_size;
1876 pkt->pts = pkt->dts = audio_timestamp;
1879 int got_packet_ptr = 0;
1885 int frame_finished = 0;
1886 error_code = ret = avcodec_send_frame(audio_codec_ctx, frame_final);
1887 if (ret < 0 && ret != AVERROR(EINVAL) && ret != AVERROR_EOF) {
1888 avcodec_send_frame(audio_codec_ctx, NULL);
1893 ret = avcodec_receive_packet(audio_codec_ctx, pkt);
1896 if(ret == AVERROR(EINVAL) || ret == AVERROR_EOF) {
1897 avcodec_flush_buffers(audio_codec_ctx);
1901 ret = frame_finished;
1904 if (!pkt->data && !frame_finished)
1908 got_packet_ptr = ret;
1911 int error_code = avcodec_encode_audio2(audio_codec_ctx, pkt, frame_final, &got_packet_ptr);
1914 if (error_code == 0 && got_packet_ptr) {
1918 pkt->pts = pkt->dts = audio_timestamp;
1921 av_packet_rescale_ts(pkt, audio_codec_ctx->time_base, audio_st->time_base);
1924 pkt->stream_index = audio_st->index;
1925 pkt->flags |= AV_PKT_FLAG_KEY;
1928 error_code = av_interleaved_write_frame(oc, pkt);
1931 if (error_code < 0) {
1933 "FFmpegWriter::write_audio_packets ERROR ["
1934 + av_err2string(error_code) +
"]",
1935 "error_code", error_code);
1939 audio_timestamp += FFMIN(audio_input_frame_size, audio_input_position);
1942 av_freep(&(frame_final->data[0]));
1949 audio_input_position = 0;
1954 if (all_resampled_samples) {
1955 av_freep(&all_resampled_samples);
1956 all_resampled_samples = NULL;
1958 if (all_queued_samples) {
1959 av_freep(&all_queued_samples);
1960 all_queued_samples = NULL;
1965 AVFrame *FFmpegWriter::allocate_avframe(
PixelFormat pix_fmt,
int width,
int height,
int *buffer_size, uint8_t *new_buffer) {
1967 AVFrame *new_av_frame = NULL;
1971 if (new_av_frame == NULL)
1972 throw OutOfMemory(
"Could not allocate AVFrame", path);
1980 new_buffer = (uint8_t *) av_malloc(*buffer_size *
sizeof(uint8_t));
1983 new_av_frame->width = width;
1984 new_av_frame->height = height;
1985 new_av_frame->format = pix_fmt;
1989 return new_av_frame;
1993 void FFmpegWriter::process_video_packet(std::shared_ptr<Frame> frame) {
1995 int source_image_width = frame->GetWidth();
1996 int source_image_height = frame->GetHeight();
1999 if (source_image_height == 1 && source_image_width == 1)
2003 if (image_rescalers.size() == 0)
2004 InitScalers(source_image_width, source_image_height);
2007 SwsContext *scaler = image_rescalers[rescaler_position];
2008 rescaler_position++;
2009 if (rescaler_position == num_of_rescalers)
2010 rescaler_position = 0;
2013 int bytes_source = 0;
2014 int bytes_final = 0;
2015 AVFrame *frame_source = NULL;
2016 const uchar *pixels = NULL;
2019 pixels = frame->GetPixels();
2022 frame_source = allocate_avframe(
PIX_FMT_RGBA, source_image_width, source_image_height, &bytes_source, (uint8_t *) pixels);
2024 AVFrame *frame_final;
2027 frame_final = allocate_avframe(AV_PIX_FMT_NV12,
info.
width,
info.
height, &bytes_final, NULL);
2029 #endif // USE_HW_ACCEL
2031 frame_final = allocate_avframe(
2032 (AVPixelFormat)(video_st->codecpar->format),
2037 AVFrame *frame_final = allocate_avframe(video_codec_ctx->pix_fmt,
info.
width,
info.
height, &bytes_final, NULL);
2038 #endif // IS_FFMPEG_3_2
2043 "FFmpegWriter::process_video_packet",
2044 "frame->number", frame->number,
2045 "bytes_source", bytes_source,
2046 "bytes_final", bytes_final);
2049 sws_scale(scaler, frame_source->data, frame_source->linesize, 0,
2050 source_image_height, frame_final->data, frame_final->linesize);
2053 add_avframe(frame, frame_final);
2060 bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *frame_final) {
2061 #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
2064 "FFmpegWriter::write_video_packet",
2065 "frame->number", frame->number,
2066 "oc->oformat->flags", oc->oformat->flags);
2074 "FFmpegWriter::write_video_packet",
2075 "frame->number", frame->number,
2076 "oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE);
2078 if (oc->oformat->flags & AVFMT_RAWPICTURE) {
2082 AVPacket* pkt = av_packet_alloc();
2085 av_init_packet(pkt);
2088 av_packet_from_data(
2089 pkt, frame_final->data[0],
2090 frame_final->linesize[0] * frame_final->height);
2092 pkt->flags |= AV_PKT_FLAG_KEY;
2093 pkt->stream_index = video_st->index;
2096 pkt->pts = video_timestamp;
2099 int error_code = av_interleaved_write_frame(oc, pkt);
2100 if (error_code < 0) {
2102 "FFmpegWriter::write_video_packet ERROR ["
2103 + av_err2string(error_code) +
"]",
2104 "error_code", error_code);
2115 AVPacket* pkt = av_packet_alloc();
2118 av_init_packet(pkt);
2122 pkt->pts = pkt->dts = AV_NOPTS_VALUE;
2125 frame_final->pts = video_timestamp;
2128 if (!(
hw_frame = av_frame_alloc())) {
2129 std::clog <<
"Error code: av_hwframe_alloc\n";
2131 if (av_hwframe_get_buffer(video_codec_ctx->hw_frames_ctx,
hw_frame, 0) < 0) {
2132 std::clog <<
"Error code: av_hwframe_get_buffer\n";
2135 std::clog <<
"Error hw_frames_ctx.\n";
2137 hw_frame->format = AV_PIX_FMT_NV12;
2138 if ( av_hwframe_transfer_data(
hw_frame, frame_final, 0) < 0) {
2139 std::clog <<
"Error while transferring frame data to surface.\n";
2141 av_frame_copy_props(
hw_frame, frame_final);
2143 #endif // USE_HW_ACCEL
2145 int got_packet_ptr = 0;
2153 ret = avcodec_send_frame(video_codec_ctx,
hw_frame);
2155 #endif // USE_HW_ACCEL
2157 ret = avcodec_send_frame(video_codec_ctx, frame_final);
2162 "FFmpegWriter::write_video_packet (Frame not sent)");
2163 if (ret == AVERROR(EAGAIN) ) {
2164 std::clog <<
"Frame EAGAIN\n";
2166 if (ret == AVERROR_EOF ) {
2167 std::clog <<
"Frame AVERROR_EOF\n";
2169 avcodec_send_frame(video_codec_ctx, NULL);
2173 ret = avcodec_receive_packet(video_codec_ctx, pkt);
2175 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
2176 avcodec_flush_buffers(video_codec_ctx);
2188 error_code = avcodec_encode_video2(video_codec_ctx, pkt, frame_final, &got_packet_ptr);
2189 if (error_code != 0) {
2191 "FFmpegWriter::write_video_packet ERROR ["
2192 + av_err2string(error_code) +
"]",
2193 "error_code", error_code);
2195 if (got_packet_ptr == 0) {
2197 "FFmpegWriter::write_video_packet (Frame gotpacket error)");
2199 #endif // IS_FFMPEG_3_2
2202 if (error_code == 0 && got_packet_ptr) {
2204 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
2205 pkt->stream_index = video_st->index;
2208 int result = av_interleaved_write_frame(oc, pkt);
2211 "FFmpegWriter::write_video_packet ERROR ["
2212 + av_err2string(result) +
"]",
2227 #endif // USE_HW_ACCEL
2231 video_timestamp += av_rescale_q(1, av_make_q(
info.
fps.
den,
info.
fps.
num), video_codec_ctx->time_base);
2240 av_dump_format(oc, 0, path.c_str(), 1);
2244 void FFmpegWriter::InitScalers(
int source_width,
int source_height) {
2245 int scale_mode = SWS_FAST_BILINEAR;
2247 scale_mode = SWS_BICUBIC;
2251 for (
int x = 0; x < num_of_rescalers; x++) {
2255 img_convert_ctx = sws_getContext(source_width, source_height,
PIX_FMT_RGBA,
2258 #endif // USE_HW_ACCEL
2260 img_convert_ctx = sws_getContext(source_width, source_height,
PIX_FMT_RGBA,
2262 scale_mode, NULL, NULL, NULL);
2266 image_rescalers.push_back(img_convert_ctx);
2272 original_sample_rate = sample_rate;
2273 original_channels = channels;
2279 for (
int x = 0; x < num_of_rescalers; x++)
2280 sws_freeContext(image_rescalers[x]);
2283 image_rescalers.clear();