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);
647 av_dict_set(&oc->metadata, iter->first.c_str(), iter->second.c_str(), 0);
651 AVDictionary *dict = NULL;
657 if (avformat_write_header(oc, &dict) != 0) {
659 "FFmpegWriter::WriteHeader (avformat_write_header)");
660 throw InvalidFile(
"Could not write header to file.", path);
664 if (dict) av_dict_free(&dict);
677 throw WriterClosed(
"The FFmpegWriter is closed. Call Open() before calling this method.", path);
680 "FFmpegWriter::WriteFrame",
681 "frame->number", frame->number,
682 "is_writing", is_writing);
692 void FFmpegWriter::write_frame(std::shared_ptr<Frame> frame) {
697 bool has_error_encoding_video =
false;
701 write_audio_packets(
false, frame);
705 process_video_packet(frame);
709 if (av_frames.count(frame)) {
711 AVFrame *frame_final = av_frames[frame];
714 if (!write_video_packet(frame, frame_final)) {
715 has_error_encoding_video =
true;
719 av_freep(&(frame_final->data[0]));
721 av_frames.erase(frame);
729 if (has_error_encoding_video)
736 "FFmpegWriter::WriteFrame (from Reader)",
741 for (int64_t number = start; number <= length; number++) {
743 std::shared_ptr<Frame> f = reader->
GetFrame(number);
754 write_audio_packets(
true, NULL);
763 av_write_trailer(oc);
766 write_trailer =
true;
772 void FFmpegWriter::flush_encoders() {
775 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
789 video_timestamp += av_rescale_q(1, av_make_q(
info.
fps.
den,
info.
fps.
num), video_codec_ctx->time_base);
792 AVPacket* pkt = av_packet_alloc();
806 error_code = avcodec_send_frame(video_codec_ctx, NULL);
808 while (error_code >= 0) {
809 error_code = avcodec_receive_packet(video_codec_ctx, pkt);
810 if (error_code == AVERROR(EAGAIN)|| error_code == AVERROR_EOF) {
813 avcodec_flush_buffers(video_codec_ctx);
816 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
817 pkt->stream_index = video_st->index;
818 error_code = av_interleaved_write_frame(oc, pkt);
820 #else // IS_FFMPEG_3_2
823 error_code = avcodec_encode_video2(video_codec_ctx, pkt, NULL, &got_packet);
825 #endif // IS_FFMPEG_3_2
827 if (error_code < 0) {
829 "FFmpegWriter::flush_encoders ERROR ["
830 + av_err2string(error_code) +
"]",
831 "error_code", error_code);
838 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
839 pkt->stream_index = video_st->index;
842 error_code = av_interleaved_write_frame(oc, pkt);
843 if (error_code < 0) {
845 "FFmpegWriter::flush_encoders ERROR ["
846 + av_err2string(error_code) +
"]",
847 "error_code", error_code);
856 AVPacket* pkt = av_packet_alloc();
863 pkt->pts = pkt->dts = audio_timestamp;
869 error_code = avcodec_send_frame(audio_codec_ctx, NULL);
871 error_code = avcodec_encode_audio2(audio_codec_ctx, pkt, NULL, &got_packet);
873 if (error_code < 0) {
875 "FFmpegWriter::flush_encoders ERROR ["
876 + av_err2string(error_code) +
"]",
877 "error_code", error_code);
885 pkt->pts = pkt->dts = audio_timestamp;
888 av_packet_rescale_ts(pkt, audio_codec_ctx->time_base, audio_st->time_base);
891 pkt->stream_index = audio_st->index;
892 pkt->flags |= AV_PKT_FLAG_KEY;
895 error_code = av_interleaved_write_frame(oc, pkt);
896 if (error_code < 0) {
898 "FFmpegWriter::flush_encoders ERROR ["
899 + av_err2string(error_code) +
"]",
900 "error_code", error_code);
904 audio_timestamp += pkt->duration;
914 void FFmpegWriter::close_video(AVFormatContext *oc, AVStream *st)
919 av_buffer_unref(&hw_device_ctx);
920 hw_device_ctx = NULL;
923 #endif // USE_HW_ACCEL
926 if (video_codec_ctx !=
nullptr) {
928 av_free(video_codec_ctx);
933 void FFmpegWriter::close_audio(AVFormatContext *oc, AVStream *st)
937 delete[] audio_outbuf;
938 delete[] audio_encoder_buffer;
941 audio_encoder_buffer = NULL;
957 if (audio_codec_ctx !=
nullptr) {
959 av_free(audio_codec_ctx);
971 close_video(oc, video_st);
973 close_audio(oc, audio_st);
976 if (image_rescalers.size() > 0)
979 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
989 avformat_free_context(oc);
994 prepare_streams =
false;
995 write_header =
false;
996 write_trailer =
false;
1002 void FFmpegWriter::add_avframe(std::shared_ptr<Frame> frame, AVFrame *av_frame) {
1004 if (!av_frames.count(frame)) {
1006 av_frames[frame] = av_frame;
1014 AVStream *FFmpegWriter::add_audio_stream() {
1016 const AVCodec *
codec = avcodec_find_encoder_by_name(
info.
acodec.c_str());
1018 throw InvalidCodec(
"A valid audio codec could not be found for this file.", path);
1021 if (audio_codec_ctx !=
nullptr) {
1026 AVStream* st = avformat_new_stream(oc,
codec);
1028 throw OutOfMemory(
"Could not allocate memory for the video stream.", path);
1032 #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
1033 st->codecpar->codec_id =
codec->id;
1035 AVCodecContext* c = audio_codec_ctx;
1037 c->codec_id =
codec->id;
1038 c->codec_type = AVMEDIA_TYPE_AUDIO;
1047 if (
codec->supported_samplerates) {
1049 for (i = 0;
codec->supported_samplerates[i] != 0; i++)
1055 if (
codec->supported_samplerates[i] == 0)
1056 throw InvalidSampleRate(
"An invalid sample rate was detected for this codec.", path);
1064 AVChannelLayout ch_layout;
1066 if (
codec->ch_layouts) {
1068 for (i = 0; av_channel_layout_check(&
codec->ch_layouts[i]); i++)
1069 if (av_channel_layout_compare(&ch_layout, &
codec->ch_layouts[i])) {
1071 av_channel_layout_copy(&c->ch_layout, &ch_layout);
1074 if (!av_channel_layout_check(&
codec->ch_layouts[i]))
1075 throw InvalidChannels(
"An invalid channel layout was detected (i.e. MONO / STEREO).", path);
1078 av_channel_layout_copy(&c->ch_layout, &ch_layout);
1081 if (
codec->channel_layouts) {
1083 for (i = 0;
codec->channel_layouts[i] != 0; i++)
1084 if (channel_layout ==
codec->channel_layouts[i]) {
1086 c->channel_layout = channel_layout;
1089 if (
codec->channel_layouts[i] == 0)
1090 throw InvalidChannels(
"An invalid channel layout was detected (i.e. MONO / STEREO).", path);
1093 c->channel_layout = channel_layout;
1097 if (
codec->sample_fmts) {
1098 for (
int i = 0;
codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) {
1100 c->sample_fmt =
codec->sample_fmts[i];
1104 if (c->sample_fmt == AV_SAMPLE_FMT_NONE) {
1106 c->sample_fmt = AV_SAMPLE_FMT_S16;
1110 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1111 #if (LIBAVCODEC_VERSION_MAJOR >= 57)
1113 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1115 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1121 const char* nb_channels_label;
1122 const char* channel_layout_label;
1125 nb_channels = c->ch_layout.nb_channels;
1126 channel_layout = c->ch_layout.u.mask;
1127 nb_channels_label =
"c->ch_layout.nb_channels";
1128 channel_layout_label =
"c->ch_layout.u.mask";
1130 nb_channels = c->channels;
1131 nb_channels_label =
"c->channels";
1132 channel_layout_label =
"c->channel_layout";
1136 "FFmpegWriter::add_audio_stream",
1137 "c->codec_id", c->codec_id,
1138 "c->bit_rate", c->bit_rate,
1139 nb_channels_label, nb_channels,
1140 "c->sample_fmt", c->sample_fmt,
1141 channel_layout_label, channel_layout,
1142 "c->sample_rate", c->sample_rate);
1148 AVStream *FFmpegWriter::add_video_stream() {
1150 const AVCodec *
codec = avcodec_find_encoder_by_name(
info.
vcodec.c_str());
1152 throw InvalidCodec(
"A valid video codec could not be found for this file.", path);
1155 if (video_codec_ctx !=
nullptr) {
1160 AVStream* st = avformat_new_stream(oc,
codec);
1162 throw OutOfMemory(
"Could not allocate memory for the video stream.", path);
1166 #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
1167 st->codecpar->codec_id =
codec->id;
1170 AVCodecContext* c = video_codec_ctx;
1172 c->codec_id =
codec->id;
1173 c->codec_type = AVMEDIA_TYPE_VIDEO;
1181 #
if (LIBAVCODEC_VERSION_MAJOR >= 58)
1182 && c->codec_id != AV_CODEC_ID_AV1
1187 if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
1196 switch (c->codec_id) {
1197 #if (LIBAVCODEC_VERSION_MAJOR >= 58)
1199 case AV_CODEC_ID_AV1 :
1203 if (strstr(
info.
vcodec.c_str(),
"aom") != NULL) {
1204 int calculated_quality = 35;
1207 av_opt_set_int(c->priv_data,
"crf", calculated_quality, 0);
1210 int calculated_quality = 50;
1213 av_opt_set_int(c->priv_data,
"qp", calculated_quality, 0);
1217 if (strstr(
info.
vcodec.c_str(),
"svtav1") != NULL) {
1218 av_opt_set_int(c->priv_data,
"preset", 6, 0);
1219 av_opt_set_int(c->priv_data,
"forced-idr",1,0);
1221 else if (strstr(
info.
vcodec.c_str(),
"rav1e") != NULL) {
1222 av_opt_set_int(c->priv_data,
"speed", 7, 0);
1223 av_opt_set_int(c->priv_data,
"tile-rows", 2, 0);
1224 av_opt_set_int(c->priv_data,
"tile-columns", 4, 0);
1226 else if (strstr(
info.
vcodec.c_str(),
"aom") != NULL) {
1229 av_opt_set_int(c->priv_data,
"tile-rows", 1, 0);
1230 av_opt_set_int(c->priv_data,
"tile-columns", 2, 0);
1231 av_opt_set_int(c->priv_data,
"row-mt", 1, 0);
1232 av_opt_set_int(c->priv_data,
"cpu-used", 3, 0);
1236 case AV_CODEC_ID_VP9 :
1237 case AV_CODEC_ID_HEVC :
1238 case AV_CODEC_ID_VP8 :
1239 case AV_CODEC_ID_H264 :
1275 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 26, 0)
1276 c->framerate = av_inv_q(c->time_base);
1278 st->avg_frame_rate = av_inv_q(c->time_base);
1283 c->max_b_frames = 10;
1284 if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO)
1286 c->max_b_frames = 2;
1287 if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO)
1293 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1294 #if (LIBAVCODEC_VERSION_MAJOR >= 57)
1296 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1298 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1303 while (supported_pixel_formats != NULL && *supported_pixel_formats !=
PIX_FMT_NONE) {
1306 c->pix_fmt = *supported_pixel_formats;
1307 ++supported_pixel_formats;
1312 if (oc->oformat->video_codec == AV_CODEC_ID_RAWVIDEO) {
1316 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
1318 if (strcmp(oc->oformat->name,
"gif") != 0)
1321 oc->oformat->flags |= AVFMT_RAWPICTURE;
1331 "FFmpegWriter::add_video_stream ("
1332 + (std::string)oc->oformat->name +
" : "
1333 + (std::string)av_get_pix_fmt_name(c->pix_fmt) +
")",
1334 "c->codec_id", c->codec_id,
1335 "c->bit_rate", c->bit_rate,
1336 "c->pix_fmt", c->pix_fmt,
1337 "oc->oformat->flags", oc->oformat->flags);
1342 void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st) {
1343 const AVCodec *
codec;
1352 codec = avcodec_find_encoder(audio_codec_ctx->codec_id);
1357 AVDictionary *
opts = NULL;
1358 av_dict_set(&
opts,
"strict",
"experimental", 0);
1361 if (avcodec_open2(audio_codec_ctx,
codec, &
opts) < 0)
1362 throw InvalidCodec(
"Could not open audio codec", path);
1366 av_dict_free(&
opts);
1370 if (audio_codec_ctx->frame_size <= 1) {
1376 case AV_CODEC_ID_PCM_S16LE:
1377 case AV_CODEC_ID_PCM_S16BE:
1378 case AV_CODEC_ID_PCM_U16LE:
1379 case AV_CODEC_ID_PCM_U16BE:
1380 audio_input_frame_size >>= 1;
1387 audio_input_frame_size = audio_codec_ctx->frame_size;
1391 initial_audio_input_frame_size = audio_input_frame_size;
1398 audio_outbuf =
new uint8_t[audio_outbuf_size];
1402 audio_encoder_buffer =
new uint8_t[audio_encoder_buffer_size];
1405 for (std::map<std::string, std::string>::iterator iter =
info.
metadata.begin(); iter !=
info.
metadata.end(); ++iter) {
1406 av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1410 "FFmpegWriter::open_audio",
1411 "audio_codec_ctx->thread_count", audio_codec_ctx->thread_count,
1412 "audio_input_frame_size", audio_input_frame_size,
1417 void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) {
1418 const AVCodec *
codec;
1428 char *adapter_ptr = NULL;
1432 std::clog <<
"Encoding Device Nr: " << adapter_num <<
"\n";
1433 if (adapter_num < 3 && adapter_num >=0) {
1434 #if defined(__linux__)
1435 snprintf(adapter,
sizeof(adapter),
"/dev/dri/renderD%d", adapter_num+128);
1437 adapter_ptr = adapter;
1438 #elif defined(_WIN32) || defined(__APPLE__)
1446 #if defined(__linux__)
1447 if( adapter_ptr != NULL && access( adapter_ptr, W_OK ) == 0 ) {
1448 #elif defined(_WIN32) || defined(__APPLE__)
1449 if( adapter_ptr != NULL ) {
1452 "Encode Device present using device",
1453 "adapter", adapter_num);
1458 "Encode Device not present, using default");
1460 if (av_hwdevice_ctx_create(&hw_device_ctx,
1464 "FFmpegWriter::open_video ERROR creating hwdevice, Codec name:",
1469 #endif // USE_HW_ACCEL
1479 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)
1480 video_codec_ctx->max_b_frames = 0;
1484 av_dict_set(&
opts,
"strict",
"experimental", 0);
1498 if (av_opt_get_int(video_codec_ctx->priv_data,
"qp", 0, &qp) != 0 || qp == 0) {
1500 av_opt_set(video_codec_ctx->priv_data,
"rc_mode",
"VBR", 0);
1504 video_codec_ctx->rc_max_rate = video_codec_ctx->bit_rate;
1508 switch (video_codec_ctx->codec_id) {
1509 case AV_CODEC_ID_H264:
1510 video_codec_ctx->max_b_frames = 0;
1511 video_codec_ctx->profile = FF_PROFILE_H264_BASELINE | FF_PROFILE_H264_CONSTRAINED;
1512 av_opt_set(video_codec_ctx->priv_data,
"preset",
"slow", 0);
1513 av_opt_set(video_codec_ctx->priv_data,
"tune",
"zerolatency", 0);
1514 av_opt_set(video_codec_ctx->priv_data,
"vprofile",
"baseline", AV_OPT_SEARCH_CHILDREN);
1516 case AV_CODEC_ID_HEVC:
1519 case AV_CODEC_ID_VP9:
1524 "No codec-specific options defined for this codec. HW encoding may fail",
1525 "codec_id", video_codec_ctx->codec_id);
1534 "FFmpegWriter::open_video (set_hwframe_ctx) ERROR faled to set hwframe context",
1537 av_err2string(err), -1);
1540 #endif // USE_HW_ACCEL
1545 video_codec_ctx->codec_tag = MKTAG(
'h',
'v',
'c',
'1');
1548 if (video_codec_ctx->codec_id == AV_CODEC_ID_HEVC) {
1549 video_codec_ctx->codec_tag = MKTAG(
'h',
'v',
'c',
'1');
1554 if (avcodec_open2(video_codec_ctx,
codec, &
opts) < 0)
1555 throw InvalidCodec(
"Could not open video codec", path);
1559 av_dict_free(&
opts);
1563 av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1567 "FFmpegWriter::open_video",
1568 "video_codec_ctx->thread_count", video_codec_ctx->thread_count);
1573 void FFmpegWriter::write_audio_packets(
bool is_final, std::shared_ptr<openshot::Frame> frame) {
1574 if (!frame && !is_final)
1578 int total_frame_samples = 0;
1579 int frame_position = 0;
1580 int channels_in_frame = 0;
1581 int sample_rate_in_frame = 0;
1582 int samples_in_frame = 0;
1587 int16_t *all_queued_samples = (int16_t *) av_malloc(all_queued_samples_size);
1588 int16_t *all_resampled_samples = NULL;
1589 int16_t *final_samples_planar = NULL;
1590 int16_t *final_samples = NULL;
1593 float *frame_samples_float = NULL;
1597 sample_rate_in_frame = frame->SampleRate();
1598 samples_in_frame = frame->GetAudioSamplesCount();
1599 channels_in_frame = frame->GetAudioChannelsCount();
1600 channel_layout_in_frame = frame->ChannelsLayout();
1603 frame_samples_float = frame->GetInterleavedAudioSamples(&samples_in_frame);
1607 total_frame_samples = samples_in_frame * channels_in_frame;
1610 const int16_t max16 = 32767;
1611 const int16_t min16 = -32768;
1612 for (
int s = 0; s < total_frame_samples; s++, frame_position++) {
1613 float valF = frame_samples_float[s] * (1 << 15);
1617 }
else if (valF < min16) {
1620 conv = int(valF + 32768.5) - 32768;
1624 all_queued_samples[frame_position] = conv;
1628 delete[] frame_samples_float;
1632 total_frame_samples = frame_position;
1633 int remaining_frame_samples = total_frame_samples;
1634 int samples_position = 0;
1638 "FFmpegWriter::write_audio_packets",
1639 "is_final", is_final,
1640 "total_frame_samples", total_frame_samples,
1641 "channel_layout_in_frame", channel_layout_in_frame,
1642 "channels_in_frame", channels_in_frame,
1643 "samples_in_frame", samples_in_frame,
1647 AVSampleFormat output_sample_fmt = audio_codec_ctx->sample_fmt;
1649 AVFrame *audio_frame = NULL;
1654 audio_frame->nb_samples = total_frame_samples / channels_in_frame;
1657 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);
1658 if (error_code < 0) {
1660 "FFmpegWriter::write_audio_packets ERROR ["
1661 + av_err2string(error_code) +
"]",
1662 "error_code", error_code);
1666 switch (audio_codec_ctx->sample_fmt) {
1667 case AV_SAMPLE_FMT_FLTP: {
1668 output_sample_fmt = AV_SAMPLE_FMT_FLT;
1671 case AV_SAMPLE_FMT_S32P: {
1672 output_sample_fmt = AV_SAMPLE_FMT_S32;
1675 case AV_SAMPLE_FMT_S16P: {
1676 output_sample_fmt = AV_SAMPLE_FMT_S16;
1679 case AV_SAMPLE_FMT_U8P: {
1680 output_sample_fmt = AV_SAMPLE_FMT_U8;
1690 total_frame_samples *= (float(
info.
sample_rate) / sample_rate_in_frame);
1691 total_frame_samples *= (float(
info.
channels) / channels_in_frame);
1696 audio_converted->nb_samples = total_frame_samples / channels_in_frame;
1697 av_samples_alloc(audio_converted->data, audio_converted->linesize,
info.
channels, audio_converted->nb_samples, output_sample_fmt, 0);
1700 "FFmpegWriter::write_audio_packets (1st resampling)",
1701 "in_sample_fmt", AV_SAMPLE_FMT_S16,
1702 "out_sample_fmt", output_sample_fmt,
1703 "in_sample_rate", sample_rate_in_frame,
1705 "in_channels", channels_in_frame,
1712 AVChannelLayout in_chlayout;
1713 AVChannelLayout out_chlayout;
1714 av_channel_layout_from_mask(&in_chlayout, channel_layout_in_frame);
1716 av_opt_set_chlayout(avr,
"in_chlayout", &in_chlayout, 0);
1717 av_opt_set_chlayout(avr,
"out_chlayout", &out_chlayout, 0);
1719 av_opt_set_int(avr,
"in_channel_layout", channel_layout_in_frame, 0);
1721 av_opt_set_int(avr,
"in_channels", channels_in_frame, 0);
1724 av_opt_set_int(avr,
"in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
1725 av_opt_set_int(avr,
"out_sample_fmt", output_sample_fmt, 0);
1726 av_opt_set_int(avr,
"in_sample_rate", sample_rate_in_frame, 0);
1733 audio_converted->data,
1734 audio_converted->linesize[0],
1735 audio_converted->nb_samples,
1737 audio_frame->linesize[0],
1738 audio_frame->nb_samples
1742 remaining_frame_samples = total_frame_samples;
1745 all_resampled_samples = (int16_t *) av_malloc(
1747 * (av_get_bytes_per_sample(output_sample_fmt) /
1748 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1752 memcpy(all_resampled_samples, audio_converted->data[0],
1753 static_cast<size_t>(nb_samples)
1755 * av_get_bytes_per_sample(output_sample_fmt));
1758 av_freep(&(audio_frame->data[0]));
1760 av_freep(&audio_converted->data[0]);
1762 all_queued_samples = NULL;
1765 "FFmpegWriter::write_audio_packets (Successfully completed 1st resampling)",
1766 "nb_samples", nb_samples,
1767 "remaining_frame_samples", remaining_frame_samples);
1771 while (remaining_frame_samples > 0 || is_final) {
1773 int remaining_packet_samples = (audio_input_frame_size *
info.
channels) - audio_input_position;
1777 if (remaining_frame_samples >= remaining_packet_samples) {
1778 diff = remaining_packet_samples;
1780 diff = remaining_frame_samples;
1787 samples + (audio_input_position
1788 * (av_get_bytes_per_sample(output_sample_fmt) /
1789 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1791 all_resampled_samples + samples_position,
1792 static_cast<size_t>(diff)
1793 * av_get_bytes_per_sample(output_sample_fmt)
1797 audio_input_position += diff;
1798 samples_position += diff * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16));
1799 remaining_frame_samples -= diff;
1802 if (audio_input_position < (audio_input_frame_size *
info.
channels) && !is_final)
1809 if (av_sample_fmt_is_planar(audio_codec_ctx->sample_fmt)) {
1811 "FFmpegWriter::write_audio_packets (2nd resampling for Planar formats)",
1812 "in_sample_fmt", output_sample_fmt,
1813 "out_sample_fmt", audio_codec_ctx->sample_fmt,
1824 AVChannelLayout layout;
1826 av_opt_set_chlayout(avr_planar,
"in_chlayout", &layout, 0);
1827 av_opt_set_chlayout(avr_planar,
"out_chlayout", &layout, 0);
1831 av_opt_set_int(avr_planar,
"in_channels",
info.
channels, 0);
1832 av_opt_set_int(avr_planar,
"out_channels",
info.
channels, 0);
1834 av_opt_set_int(avr_planar,
"in_sample_fmt", output_sample_fmt, 0);
1835 av_opt_set_int(avr_planar,
"out_sample_fmt", audio_codec_ctx->sample_fmt, 0);
1844 audio_frame->nb_samples = audio_input_position /
info.
channels;
1847 final_samples_planar = (int16_t *) av_malloc(
1848 sizeof(int16_t) * audio_frame->nb_samples *
info.
channels
1849 * (av_get_bytes_per_sample(output_sample_fmt) /
1850 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1854 memcpy(final_samples_planar, samples,
1855 static_cast<size_t>(audio_frame->nb_samples)
1857 * av_get_bytes_per_sample(output_sample_fmt));
1860 avcodec_fill_audio_frame(audio_frame,
info.
channels, output_sample_fmt,
1861 (uint8_t *) final_samples_planar, audio_encoder_buffer_size, 0);
1864 frame_final->nb_samples = audio_input_frame_size;
1871 frame_final->format = audio_codec_ctx->sample_fmt;
1872 av_samples_alloc(frame_final->data, frame_final->linesize,
info.
channels,
1873 frame_final->nb_samples, audio_codec_ctx->sample_fmt, 0);
1879 frame_final->linesize[0],
1880 frame_final->nb_samples,
1882 audio_frame->linesize[0],
1883 audio_frame->nb_samples
1887 const auto copy_length =
static_cast<size_t>(nb_samples)
1888 * av_get_bytes_per_sample(audio_codec_ctx->sample_fmt)
1892 memcpy(samples, frame_final->data[0], copy_length);
1895 av_freep(&(audio_frame->data[0]));
1897 all_queued_samples = NULL;
1900 "FFmpegWriter::write_audio_packets (Successfully completed 2nd resampling for Planar formats)",
1901 "nb_samples", nb_samples);
1905 const auto buf_size =
static_cast<size_t>(audio_input_position)
1906 * (av_get_bytes_per_sample(audio_codec_ctx->sample_fmt) /
1907 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)
1909 final_samples =
reinterpret_cast<int16_t*
>(
1910 av_malloc(
sizeof(int16_t) * buf_size));
1913 memcpy(final_samples, samples,
1914 audio_input_position * av_get_bytes_per_sample(audio_codec_ctx->sample_fmt));
1917 frame_final->nb_samples = audio_input_frame_size;
1921 int nb_channels = audio_codec_ctx->ch_layout.nb_channels;
1923 int nb_channels = audio_codec_ctx->channels;
1925 avcodec_fill_audio_frame(frame_final, nb_channels,
1926 audio_codec_ctx->sample_fmt, (uint8_t *) final_samples,
1927 audio_encoder_buffer_size, 0);
1931 frame_final->pts = audio_timestamp;
1935 AVPacket* pkt = av_packet_alloc();
1938 av_init_packet(pkt);
1940 pkt->data = audio_encoder_buffer;
1941 pkt->size = audio_encoder_buffer_size;
1944 pkt->pts = pkt->dts = audio_timestamp;
1947 int got_packet_ptr = 0;
1953 int frame_finished = 0;
1954 error_code = ret = avcodec_send_frame(audio_codec_ctx, frame_final);
1955 if (ret < 0 && ret != AVERROR(EINVAL) && ret != AVERROR_EOF) {
1956 avcodec_send_frame(audio_codec_ctx, NULL);
1961 ret = avcodec_receive_packet(audio_codec_ctx, pkt);
1964 if(ret == AVERROR(EINVAL) || ret == AVERROR_EOF) {
1965 avcodec_flush_buffers(audio_codec_ctx);
1969 ret = frame_finished;
1972 if (!pkt->data && !frame_finished)
1976 got_packet_ptr = ret;
1979 int error_code = avcodec_encode_audio2(audio_codec_ctx, pkt, frame_final, &got_packet_ptr);
1982 if (error_code == 0 && got_packet_ptr) {
1986 pkt->pts = pkt->dts = audio_timestamp;
1989 av_packet_rescale_ts(pkt, audio_codec_ctx->time_base, audio_st->time_base);
1992 pkt->stream_index = audio_st->index;
1993 pkt->flags |= AV_PKT_FLAG_KEY;
1996 error_code = av_interleaved_write_frame(oc, pkt);
1999 if (error_code < 0) {
2001 "FFmpegWriter::write_audio_packets ERROR ["
2002 + av_err2string(error_code) +
"]",
2003 "error_code", error_code);
2007 audio_timestamp += FFMIN(audio_input_frame_size, audio_input_position);
2010 av_freep(&(frame_final->data[0]));
2017 audio_input_position = 0;
2022 if (all_resampled_samples) {
2023 av_freep(&all_resampled_samples);
2024 all_resampled_samples = NULL;
2026 if (all_queued_samples) {
2027 av_freep(&all_queued_samples);
2028 all_queued_samples = NULL;
2033 AVFrame *FFmpegWriter::allocate_avframe(
PixelFormat pix_fmt,
int width,
int height,
int *buffer_size, uint8_t *new_buffer) {
2035 AVFrame *new_av_frame = NULL;
2039 if (new_av_frame == NULL)
2040 throw OutOfMemory(
"Could not allocate AVFrame", path);
2048 new_buffer = (uint8_t *) av_malloc(*buffer_size *
sizeof(uint8_t));
2051 new_av_frame->width = width;
2052 new_av_frame->height = height;
2053 new_av_frame->format = pix_fmt;
2057 return new_av_frame;
2061 void FFmpegWriter::process_video_packet(std::shared_ptr<Frame> frame) {
2063 int source_image_width = frame->GetWidth();
2064 int source_image_height = frame->GetHeight();
2067 if (source_image_height == 1 && source_image_width == 1)
2071 if (image_rescalers.size() == 0)
2072 InitScalers(source_image_width, source_image_height);
2075 SwsContext *scaler = image_rescalers[rescaler_position];
2076 rescaler_position++;
2077 if (rescaler_position == num_of_rescalers)
2078 rescaler_position = 0;
2081 int bytes_source = 0;
2082 int bytes_final = 0;
2083 AVFrame *frame_source = NULL;
2084 const uchar *pixels = NULL;
2087 pixels = frame->GetPixels();
2090 frame_source = allocate_avframe(
PIX_FMT_RGBA, source_image_width, source_image_height, &bytes_source, (uint8_t *) pixels);
2092 AVFrame *frame_final;
2095 frame_final = allocate_avframe(AV_PIX_FMT_NV12,
info.
width,
info.
height, &bytes_final, NULL);
2097 #endif // USE_HW_ACCEL
2099 frame_final = allocate_avframe(
2100 (AVPixelFormat)(video_st->codecpar->format),
2105 AVFrame *frame_final = allocate_avframe(video_codec_ctx->pix_fmt,
info.
width,
info.
height, &bytes_final, NULL);
2106 #endif // IS_FFMPEG_3_2
2111 "FFmpegWriter::process_video_packet",
2112 "frame->number", frame->number,
2113 "bytes_source", bytes_source,
2114 "bytes_final", bytes_final);
2117 sws_scale(scaler, frame_source->data, frame_source->linesize, 0,
2118 source_image_height, frame_final->data, frame_final->linesize);
2121 add_avframe(frame, frame_final);
2128 bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *frame_final) {
2129 #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
2132 "FFmpegWriter::write_video_packet",
2133 "frame->number", frame->number,
2134 "oc->oformat->flags", oc->oformat->flags);
2142 "FFmpegWriter::write_video_packet",
2143 "frame->number", frame->number,
2144 "oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE);
2146 if (oc->oformat->flags & AVFMT_RAWPICTURE) {
2150 AVPacket* pkt = av_packet_alloc();
2153 av_init_packet(pkt);
2156 av_packet_from_data(
2157 pkt, frame_final->data[0],
2158 frame_final->linesize[0] * frame_final->height);
2160 pkt->flags |= AV_PKT_FLAG_KEY;
2161 pkt->stream_index = video_st->index;
2164 pkt->pts = video_timestamp;
2167 int error_code = av_interleaved_write_frame(oc, pkt);
2168 if (error_code < 0) {
2170 "FFmpegWriter::write_video_packet ERROR ["
2171 + av_err2string(error_code) +
"]",
2172 "error_code", error_code);
2183 AVPacket* pkt = av_packet_alloc();
2186 av_init_packet(pkt);
2190 pkt->pts = pkt->dts = AV_NOPTS_VALUE;
2193 frame_final->pts = video_timestamp;
2196 if (!(
hw_frame = av_frame_alloc())) {
2197 std::clog <<
"Error code: av_hwframe_alloc\n";
2199 if (av_hwframe_get_buffer(video_codec_ctx->hw_frames_ctx,
hw_frame, 0) < 0) {
2200 std::clog <<
"Error code: av_hwframe_get_buffer\n";
2203 std::clog <<
"Error hw_frames_ctx.\n";
2205 hw_frame->format = AV_PIX_FMT_NV12;
2206 if ( av_hwframe_transfer_data(
hw_frame, frame_final, 0) < 0) {
2207 std::clog <<
"Error while transferring frame data to surface.\n";
2209 av_frame_copy_props(
hw_frame, frame_final);
2211 #endif // USE_HW_ACCEL
2213 int got_packet_ptr = 0;
2221 ret = avcodec_send_frame(video_codec_ctx,
hw_frame);
2223 #endif // USE_HW_ACCEL
2225 ret = avcodec_send_frame(video_codec_ctx, frame_final);
2230 "FFmpegWriter::write_video_packet (Frame not sent)");
2231 if (ret == AVERROR(EAGAIN) ) {
2232 std::clog <<
"Frame EAGAIN\n";
2234 if (ret == AVERROR_EOF ) {
2235 std::clog <<
"Frame AVERROR_EOF\n";
2237 avcodec_send_frame(video_codec_ctx, NULL);
2241 ret = avcodec_receive_packet(video_codec_ctx, pkt);
2243 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
2255 error_code = avcodec_encode_video2(video_codec_ctx, pkt, frame_final, &got_packet_ptr);
2256 if (error_code != 0) {
2258 "FFmpegWriter::write_video_packet ERROR ["
2259 + av_err2string(error_code) +
"]",
2260 "error_code", error_code);
2262 if (got_packet_ptr == 0) {
2264 "FFmpegWriter::write_video_packet (Frame gotpacket error)");
2266 #endif // IS_FFMPEG_3_2
2269 if (error_code == 0 && got_packet_ptr) {
2271 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
2272 pkt->stream_index = video_st->index;
2275 int result = av_interleaved_write_frame(oc, pkt);
2278 "FFmpegWriter::write_video_packet ERROR ["
2279 + av_err2string(result) +
"]",
2294 #endif // USE_HW_ACCEL
2298 video_timestamp += av_rescale_q(1, av_make_q(
info.
fps.
den,
info.
fps.
num), video_codec_ctx->time_base);
2307 av_dump_format(oc, 0, path.c_str(), 1);
2311 void FFmpegWriter::InitScalers(
int source_width,
int source_height) {
2312 int scale_mode = SWS_FAST_BILINEAR;
2314 scale_mode = SWS_BICUBIC;
2318 for (
int x = 0; x < num_of_rescalers; x++) {
2322 img_convert_ctx = sws_getContext(source_width, source_height,
PIX_FMT_RGBA,
2325 #endif // USE_HW_ACCEL
2327 img_convert_ctx = sws_getContext(source_width, source_height,
PIX_FMT_RGBA,
2329 scale_mode, NULL, NULL, NULL);
2333 image_rescalers.push_back(img_convert_ctx);
2339 original_sample_rate = sample_rate;
2340 original_channels = channels;
2346 for (
int x = 0; x < num_of_rescalers; x++)
2347 sws_freeContext(image_rescalers[x]);
2350 image_rescalers.clear();