42 static AVBufferRef *hw_device_ctx = NULL;
45 static int set_hwframe_ctx(AVCodecContext *ctx, AVBufferRef *hw_device_ctx, int64_t width, int64_t height)
47 AVBufferRef *hw_frames_ref;
48 AVHWFramesContext *frames_ctx = NULL;
51 if (!(hw_frames_ref = av_hwframe_ctx_alloc(hw_device_ctx))) {
52 std::clog <<
"Failed to create HW frame context.\n";
55 frames_ctx = (AVHWFramesContext *)(hw_frames_ref->data);
57 frames_ctx->sw_format = AV_PIX_FMT_NV12;
58 frames_ctx->width = width;
59 frames_ctx->height = height;
60 frames_ctx->initial_pool_size = 20;
61 if ((err = av_hwframe_ctx_init(hw_frames_ref)) < 0) {
62 std::clog <<
"Failed to initialize HW frame context. " <<
63 "Error code: " << av_err2string(err) <<
"\n";
64 av_buffer_unref(&hw_frames_ref);
67 ctx->hw_frames_ctx = av_buffer_ref(hw_frames_ref);
68 if (!ctx->hw_frames_ctx)
69 err = AVERROR(ENOMEM);
71 av_buffer_unref(&hw_frames_ref);
74 #endif // USE_HW_ACCEL
77 path(
path), oc(NULL), audio_st(NULL), video_st(NULL), samples(NULL),
78 audio_outbuf(NULL), audio_outbuf_size(0), audio_input_frame_size(0), audio_input_position(0),
79 initial_audio_input_frame_size(0), img_convert_ctx(NULL),
80 video_codec_ctx(NULL), audio_codec_ctx(NULL), is_writing(false), video_timestamp(0), audio_timestamp(0),
81 original_sample_rate(0), original_channels(0), avr(NULL), avr_planar(NULL), is_open(false), prepare_streams(false),
82 write_header(false), write_trailer(false), allow_b_frames(false), audio_encoder_buffer_size(0), audio_encoder_buffer(NULL) {
102 if (!prepare_streams)
107 open_video(oc, video_st);
109 open_audio(oc, audio_st);
118 void FFmpegWriter::auto_detect_format() {
124 "Could not allocate memory for AVFormatContext.", path);
128 oc->oformat = av_guess_format(NULL, path.c_str(), NULL);
129 if (oc->oformat ==
nullptr) {
130 throw InvalidFormat(
"Could not deduce output format from file extension.", path);
134 if (oc->oformat->video_codec != AV_CODEC_ID_NONE &&
info.
has_video) {
135 const AVCodec *vcodec = avcodec_find_encoder(oc->oformat->video_codec);
136 info.
vcodec = vcodec ? vcodec->name : std::string();
138 if (oc->oformat->audio_codec != AV_CODEC_ID_NONE &&
info.
has_audio) {
139 const AVCodec *acodec = avcodec_find_encoder(oc->oformat->audio_codec);
140 info.
acodec = acodec ? acodec->name : std::string();
145 void FFmpegWriter::initialize_streams() {
147 "FFmpegWriter::initialize_streams",
148 "oc->oformat->video_codec", oc->oformat->video_codec,
149 "oc->oformat->audio_codec", oc->oformat->audio_codec,
150 "AV_CODEC_ID_NONE", AV_CODEC_ID_NONE);
155 if (oc->oformat->video_codec != AV_CODEC_ID_NONE &&
info.
has_video)
157 video_st = add_video_stream();
159 if (oc->oformat->audio_codec != AV_CODEC_ID_NONE &&
info.
has_audio)
161 audio_st = add_audio_stream();
167 if (
codec.length() > 0) {
168 const AVCodec *new_codec;
171 #if defined(__linux__)
172 if (strstr(
codec.c_str(),
"_vaapi") != NULL) {
173 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
178 }
else if (strstr(
codec.c_str(),
"_nvenc") != NULL) {
179 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
185 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
189 #elif defined(_WIN32)
190 if (strstr(
codec.c_str(),
"_dxva2") != NULL) {
191 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
196 }
else if (strstr(
codec.c_str(),
"_nvenc") != NULL) {
197 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
203 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
207 #elif defined(__APPLE__)
208 if (strstr(
codec.c_str(),
"_videotoolbox") != NULL) {
209 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
215 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
220 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
221 #endif //__linux__/_WIN32/__APPLE__
222 #else // USE_HW_ACCEL
223 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
224 #endif // USE_HW_ACCEL
225 if (new_codec == NULL)
226 throw InvalidCodec(
"A valid video codec could not be found for this file.", path);
245 if (pixel_ratio.
num > 0) {
249 if (bit_rate >= 1000)
251 if ((bit_rate >= 0) && (bit_rate < 256))
268 "FFmpegWriter::SetVideoOptions (" +
codec +
")",
269 "width", width,
"height", height,
270 "size.num", size.
num,
"size.den", size.
den,
271 "fps.num", fps.
num,
"fps.den", fps.
den);
281 true,
codec, fps, width, height,
290 if (
codec.length() > 0) {
291 const AVCodec *new_codec = avcodec_find_encoder_by_name(
codec.c_str());
292 if (new_codec == NULL)
293 throw InvalidCodec(
"A valid audio codec could not be found for this file.", path);
299 if (sample_rate > 7999)
308 if (original_sample_rate == 0)
310 if (original_channels == 0)
314 "FFmpegWriter::SetAudioOptions (" +
codec +
")",
315 "sample_rate", sample_rate,
316 "channels", channels,
317 "bit_rate", bit_rate);
328 true,
codec, sample_rate, 2,
337 AVCodecContext *c = NULL;
339 std::stringstream convert(value);
358 throw NoStreamsFound(
"The stream was not found. Be sure to call PrepareStreams() first.", path);
361 const AVOption *option = NULL;
369 if (option || (name ==
"g" || name ==
"qmin" || name ==
"qmax" || name ==
"max_b_frames" || name ==
"mb_decision" ||
370 name ==
"level" || name ==
"profile" || name ==
"slices" || name ==
"rc_min_rate" || name ==
"rc_max_rate" ||
371 name ==
"rc_buffer_size" || name ==
"crf" || name ==
"cqp" || name ==
"qp" || name ==
"allow_b_frames")) {
375 convert >> c->gop_size;
377 else if (name ==
"qmin")
381 else if (name ==
"qmax")
385 else if (name ==
"max_b_frames")
387 convert >> c->max_b_frames;
389 else if (name ==
"allow_b_frames")
392 allow_b_frames = (value ==
"1" || value ==
"true" || value ==
"yes" || value ==
"on");
394 else if (name ==
"mb_decision")
396 convert >> c->mb_decision;
398 else if (name ==
"level")
402 else if (name ==
"profile")
404 convert >> c->profile;
406 else if (name ==
"slices")
408 convert >> c->slices;
410 else if (name ==
"rc_min_rate")
412 convert >> c->rc_min_rate;
414 else if (name ==
"rc_max_rate")
416 convert >> c->rc_max_rate;
418 else if (name ==
"rc_buffer_size")
420 convert >> c->rc_buffer_size;
422 else if (name ==
"cqp") {
426 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),63), 0);
428 #endif // USE_HW_ACCEL
430 switch (c->codec_id) {
431 #if (LIBAVCODEC_VERSION_MAJOR >= 58)
433 case AV_CODEC_ID_AV1 :
435 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),63), 0);
438 case AV_CODEC_ID_VP8 :
439 c->bit_rate = 10000000;
440 av_opt_set_int(c->priv_data,
"qp", std::max(std::min(std::stoi(value), 63), 4), 0);
442 case AV_CODEC_ID_VP9 :
444 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value), 63), 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);
450 case AV_CODEC_ID_H264 :
451 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value), 51), 0);
452 if (std::stoi(value) == 0) {
453 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
457 case AV_CODEC_ID_HEVC :
458 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value), 51), 0);
459 if (std::stoi(value) == 0) {
460 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
461 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
466 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value), 63), 0);
470 }
else if (name ==
"crf") {
474 double mbs = 15000000.0;
483 c->bit_rate = (int)(mbs);
485 #endif // USE_HW_ACCEL
487 switch (c->codec_id) {
488 #if (LIBAVCODEC_VERSION_MAJOR >= 58)
490 case AV_CODEC_ID_AV1 :
493 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value),63), 0);
496 case AV_CODEC_ID_VP8 :
497 c->bit_rate = 10000000;
498 av_opt_set_int(c->priv_data,
"crf", std::max(std::min(std::stoi(value), 63), 4), 0);
500 case AV_CODEC_ID_VP9 :
502 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value), 63), 0);
503 if (std::stoi(value) == 0) {
504 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
505 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
508 case AV_CODEC_ID_H264 :
509 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value), 51), 0);
510 if (std::stoi(value) == 0) {
511 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
515 case AV_CODEC_ID_HEVC :
516 if (strstr(
info.
vcodec.c_str(),
"svt_hevc") != NULL) {
517 av_opt_set_int(c->priv_data,
"preset", 7, 0);
518 av_opt_set_int(c->priv_data,
"forced-idr",1,0);
519 av_opt_set_int(c->priv_data,
"qp",std::min(std::stoi(value), 51),0);
522 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value), 51), 0);
524 if (std::stoi(value) == 0) {
525 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
526 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
532 double mbs = 15000000.0;
540 c->bit_rate = (int) (mbs);
543 }
else if (name ==
"qp") {
545 #if (LIBAVCODEC_VERSION_MAJOR >= 58)
547 switch (c->codec_id) {
548 case AV_CODEC_ID_AV1 :
550 if (strstr(
info.
vcodec.c_str(),
"svtav1") != NULL) {
551 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),63), 0);
553 else if (strstr(
info.
vcodec.c_str(),
"rav1e") != NULL) {
556 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),255), 0);
558 else if (strstr(
info.
vcodec.c_str(),
"aom") != NULL) {
562 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value),63), 0);
565 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value),63), 0);
567 case AV_CODEC_ID_HEVC :
569 if (strstr(
info.
vcodec.c_str(),
"svt_hevc") != NULL) {
570 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),51), 0);
571 av_opt_set_int(c->priv_data,
"preset", 7, 0);
572 av_opt_set_int(c->priv_data,
"forced-idr",1,0);
576 #endif // FFmpeg 4.0+
579 AV_OPTION_SET(st, c->priv_data, name.c_str(), value.c_str(), c);
583 "FFmpegWriter::SetOption (" + (std::string)name +
")",
588 }
else if (name ==
"muxing_preset") {
589 if (value ==
"mp4_faststart") {
591 av_dict_set(&
mux_dict,
"movflags",
"faststart", 0);
592 }
else if (value ==
"mp4_fragmented") {
594 av_dict_set(&
mux_dict,
"movflags",
"frag_keyframe", 0);
595 av_dict_set(&
mux_dict,
"min_frag_duration",
"8000000", 0);
598 throw InvalidOptions(
"The option is not valid for this codec.", path);
609 return avcodec_find_encoder_by_name(codec_name.c_str()) != NULL;
615 throw InvalidOptions(
"No video or audio options have been set. You must set has_video or has_audio (or both).", path);
618 "FFmpegWriter::PrepareStreams [" + path +
"]",
623 initialize_streams();
626 prepare_streams =
true;
632 throw InvalidOptions(
"No video or audio options have been set. You must set has_video or has_audio (or both).", path);
635 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
636 if (avio_open(&oc->pb, path.c_str(), AVIO_FLAG_WRITE) < 0)
637 throw InvalidFile(
"Could not open or write file.", path);
645 av_dict_set(&oc->metadata, iter->first.c_str(), iter->second.c_str(), 0);
649 AVDictionary *dict = NULL;
655 if (avformat_write_header(oc, &dict) != 0) {
657 "FFmpegWriter::WriteHeader (avformat_write_header)");
658 throw InvalidFile(
"Could not write header to file.", path);
662 if (dict) av_dict_free(&dict);
675 throw WriterClosed(
"The FFmpegWriter is closed. Call Open() before calling this method.", path);
678 "FFmpegWriter::WriteFrame",
679 "frame->number", frame->number,
680 "is_writing", is_writing);
692 throw WriterClosed(
"The FFmpegWriter is closed. Call Open() before calling this method.", path);
694 if (frame_number < 1) {
699 "FFmpegWriter::WriteFrameAt",
700 "frame->number", frame->number,
701 "output_frame_number", frame_number,
702 "is_writing", is_writing);
704 const int64_t previous_video_timestamp = video_timestamp;
706 video_timestamp = av_rescale_q(
709 video_codec_ctx->time_base);
715 video_timestamp = previous_video_timestamp;
722 void FFmpegWriter::write_frame(std::shared_ptr<Frame> frame) {
727 bool has_error_encoding_video =
false;
731 write_audio_packets(
false, frame);
735 process_video_packet(frame);
739 if (av_frames.count(frame)) {
741 AVFrame *frame_final = av_frames[frame];
744 if (!write_video_packet(frame, frame_final)) {
745 has_error_encoding_video =
true;
749 av_freep(&(frame_final->data[0]));
751 av_frames.erase(frame);
759 if (has_error_encoding_video)
766 "FFmpegWriter::WriteFrame (from Reader)",
771 for (int64_t number = start; number <= length; number++) {
773 std::shared_ptr<Frame> f = reader->
GetFrame(number);
784 write_audio_packets(
true, NULL);
789 if (
info.
has_audio && audio_st && audio_codec_ctx && audio_timestamp > 0) {
790 audio_st->duration = av_rescale_q(
792 audio_codec_ctx->time_base,
793 audio_st->time_base);
800 av_write_trailer(oc);
803 write_trailer =
true;
809 void FFmpegWriter::flush_encoders() {
812 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
826 video_timestamp += av_rescale_q(1, av_make_q(
info.
fps.
den,
info.
fps.
num), video_codec_ctx->time_base);
829 AVPacket* pkt = av_packet_alloc();
843 error_code = avcodec_send_frame(video_codec_ctx, NULL);
845 while (error_code >= 0) {
846 error_code = avcodec_receive_packet(video_codec_ctx, pkt);
847 if (error_code == AVERROR(EAGAIN)|| error_code == AVERROR_EOF) {
850 avcodec_flush_buffers(video_codec_ctx);
853 if (pkt->duration <= 0) {
854 pkt->duration = av_rescale_q(1, av_make_q(
info.
fps.
den,
info.
fps.
num), video_codec_ctx->time_base);
856 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
857 pkt->stream_index = video_st->index;
858 error_code = av_interleaved_write_frame(oc, pkt);
860 #else // IS_FFMPEG_3_2
863 error_code = avcodec_encode_video2(video_codec_ctx, pkt, NULL, &got_packet);
865 #endif // IS_FFMPEG_3_2
867 if (error_code < 0) {
869 "FFmpegWriter::flush_encoders ERROR ["
870 + av_err2string(error_code) +
"]",
871 "error_code", error_code);
878 if (pkt->duration <= 0) {
879 pkt->duration = av_rescale_q(1, av_make_q(
info.
fps.
den,
info.
fps.
num), video_codec_ctx->time_base);
881 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
882 pkt->stream_index = video_st->index;
885 error_code = av_interleaved_write_frame(oc, pkt);
886 if (error_code < 0) {
888 "FFmpegWriter::flush_encoders ERROR ["
889 + av_err2string(error_code) +
"]",
890 "error_code", error_code);
899 AVPacket* pkt = av_packet_alloc();
906 pkt->pts = pkt->dts = audio_timestamp;
912 if (!audio_codec_ctx->codec || !(audio_codec_ctx->codec->capabilities & AV_CODEC_CAP_DELAY)) {
913 av_packet_free(&pkt);
916 error_code = avcodec_send_frame(audio_codec_ctx, NULL);
917 if (error_code < 0 && error_code != AVERROR_EOF) {
919 "FFmpegWriter::flush_encoders ERROR ["
920 + av_err2string(error_code) +
"]",
921 "error_code", error_code);
924 error_code = avcodec_receive_packet(audio_codec_ctx, pkt);
925 if (error_code == AVERROR(EAGAIN) || error_code == AVERROR_EOF) {
929 if (error_code < 0) {
931 "FFmpegWriter::flush_encoders ERROR ["
932 + av_err2string(error_code) +
"]",
933 "error_code", error_code);
939 if (pkt->pts == AV_NOPTS_VALUE) {
940 pkt->pts = audio_timestamp;
942 if (pkt->dts == AV_NOPTS_VALUE) {
945 if (pkt->duration <= 0) {
946 pkt->duration = audio_codec_ctx->frame_size > 0 ? audio_codec_ctx->frame_size : audio_input_frame_size;
948 const int64_t packet_duration = pkt->duration;
949 av_packet_rescale_ts(pkt, audio_codec_ctx->time_base, audio_st->time_base);
950 pkt->stream_index = audio_st->index;
951 pkt->flags |= AV_PKT_FLAG_KEY;
953 error_code = av_interleaved_write_frame(oc, pkt);
954 if (error_code < 0) {
956 "FFmpegWriter::flush_encoders ERROR ["
957 + av_err2string(error_code) +
"]",
958 "error_code", error_code);
960 audio_timestamp += packet_duration;
963 av_packet_free(&pkt);
966 error_code = avcodec_encode_audio2(audio_codec_ctx, pkt, NULL, &got_packet);
967 if (error_code < 0) {
969 "FFmpegWriter::flush_encoders ERROR ["
970 + av_err2string(error_code) +
"]",
971 "error_code", error_code);
979 pkt->pts = pkt->dts = audio_timestamp;
980 if (pkt->duration <= 0) {
981 pkt->duration = audio_codec_ctx->frame_size > 0 ? audio_codec_ctx->frame_size : audio_input_frame_size;
985 av_packet_rescale_ts(pkt, audio_codec_ctx->time_base, audio_st->time_base);
988 pkt->stream_index = audio_st->index;
989 pkt->flags |= AV_PKT_FLAG_KEY;
992 error_code = av_interleaved_write_frame(oc, pkt);
993 if (error_code < 0) {
995 "FFmpegWriter::flush_encoders ERROR ["
996 + av_err2string(error_code) +
"]",
997 "error_code", error_code);
1001 audio_timestamp += pkt->duration;
1012 void FFmpegWriter::close_video(AVFormatContext *oc, AVStream *st)
1016 if (hw_device_ctx) {
1017 av_buffer_unref(&hw_device_ctx);
1018 hw_device_ctx = NULL;
1021 #endif // USE_HW_ACCEL
1024 if (video_codec_ctx !=
nullptr) {
1026 av_free(video_codec_ctx);
1031 void FFmpegWriter::close_audio(AVFormatContext *oc, AVStream *st)
1035 delete[] audio_outbuf;
1036 delete[] audio_encoder_buffer;
1038 audio_outbuf = NULL;
1039 audio_encoder_buffer = NULL;
1055 if (audio_codec_ctx !=
nullptr) {
1057 av_free(audio_codec_ctx);
1069 close_video(oc, video_st);
1071 close_audio(oc, audio_st);
1074 if (img_convert_ctx)
1075 sws_freeContext(img_convert_ctx);
1077 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
1083 video_timestamp = 0;
1084 audio_timestamp = 0;
1087 avformat_free_context(oc);
1092 prepare_streams =
false;
1093 write_header =
false;
1094 write_trailer =
false;
1100 void FFmpegWriter::add_avframe(std::shared_ptr<Frame> frame, AVFrame *av_frame) {
1102 if (!av_frames.count(frame)) {
1104 av_frames[frame] = av_frame;
1112 AVStream *FFmpegWriter::add_audio_stream() {
1114 const AVCodec *
codec = avcodec_find_encoder_by_name(
info.
acodec.c_str());
1116 throw InvalidCodec(
"A valid audio codec could not be found for this file.", path);
1119 if (audio_codec_ctx !=
nullptr) {
1124 AVStream* st = avformat_new_stream(oc,
codec);
1126 throw OutOfMemory(
"Could not allocate memory for the audio stream.", path);
1130 #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
1131 st->codecpar->codec_id =
codec->id;
1133 AVCodecContext* c = audio_codec_ctx;
1135 c->codec_id =
codec->id;
1136 c->codec_type = AVMEDIA_TYPE_AUDIO;
1145 if (
codec->supported_samplerates) {
1147 for (i = 0;
codec->supported_samplerates[i] != 0; i++)
1153 if (
codec->supported_samplerates[i] == 0)
1154 throw InvalidSampleRate(
"An invalid sample rate was detected for this codec.", path);
1159 c->time_base = AVRational{1, c->sample_rate};
1160 st->time_base = c->time_base;
1165 AVChannelLayout ch_layout;
1167 if (
codec->ch_layouts) {
1169 for (i = 0; av_channel_layout_check(&
codec->ch_layouts[i]); i++)
1170 if (av_channel_layout_compare(&ch_layout, &
codec->ch_layouts[i])) {
1172 av_channel_layout_copy(&c->ch_layout, &ch_layout);
1175 if (!av_channel_layout_check(&
codec->ch_layouts[i]))
1176 throw InvalidChannels(
"An invalid channel layout was detected (i.e. MONO / STEREO).", path);
1179 av_channel_layout_copy(&c->ch_layout, &ch_layout);
1182 if (
codec->channel_layouts) {
1184 for (i = 0;
codec->channel_layouts[i] != 0; i++)
1185 if (channel_layout ==
codec->channel_layouts[i]) {
1187 c->channel_layout = channel_layout;
1190 if (
codec->channel_layouts[i] == 0)
1191 throw InvalidChannels(
"An invalid channel layout was detected (i.e. MONO / STEREO).", path);
1194 c->channel_layout = channel_layout;
1198 if (
codec->sample_fmts) {
1199 for (
int i = 0;
codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) {
1201 c->sample_fmt =
codec->sample_fmts[i];
1205 if (c->sample_fmt == AV_SAMPLE_FMT_NONE) {
1207 c->sample_fmt = AV_SAMPLE_FMT_S16;
1211 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1212 #if (LIBAVCODEC_VERSION_MAJOR >= 57)
1214 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1216 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1222 const char* nb_channels_label;
1223 const char* channel_layout_label;
1226 nb_channels = c->ch_layout.nb_channels;
1227 channel_layout = c->ch_layout.u.mask;
1228 nb_channels_label =
"c->ch_layout.nb_channels";
1229 channel_layout_label =
"c->ch_layout.u.mask";
1231 nb_channels = c->channels;
1232 nb_channels_label =
"c->channels";
1233 channel_layout_label =
"c->channel_layout";
1237 "FFmpegWriter::add_audio_stream",
1238 "c->codec_id", c->codec_id,
1239 "c->bit_rate", c->bit_rate,
1240 nb_channels_label, nb_channels,
1241 "c->sample_fmt", c->sample_fmt,
1242 channel_layout_label, channel_layout,
1243 "c->sample_rate", c->sample_rate);
1249 AVStream *FFmpegWriter::add_video_stream() {
1251 const AVCodec *
codec = avcodec_find_encoder_by_name(
info.
vcodec.c_str());
1253 throw InvalidCodec(
"A valid video codec could not be found for this file.", path);
1256 if (video_codec_ctx !=
nullptr) {
1261 AVStream* st = avformat_new_stream(oc,
codec);
1263 throw OutOfMemory(
"Could not allocate memory for the video stream.", path);
1267 #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
1268 st->codecpar->codec_id =
codec->id;
1271 AVCodecContext* c = video_codec_ctx;
1273 c->codec_id =
codec->id;
1274 c->codec_type = AVMEDIA_TYPE_VIDEO;
1282 #
if (LIBAVCODEC_VERSION_MAJOR >= 58)
1283 && c->codec_id != AV_CODEC_ID_AV1
1288 if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
1297 switch (c->codec_id) {
1298 #if (LIBAVCODEC_VERSION_MAJOR >= 58)
1300 case AV_CODEC_ID_AV1 :
1304 if (strstr(
info.
vcodec.c_str(),
"aom") != NULL) {
1305 int calculated_quality = 35;
1308 av_opt_set_int(c->priv_data,
"crf", calculated_quality, 0);
1311 int calculated_quality = 50;
1314 av_opt_set_int(c->priv_data,
"qp", calculated_quality, 0);
1318 if (strstr(
info.
vcodec.c_str(),
"svtav1") != NULL) {
1319 av_opt_set_int(c->priv_data,
"preset", 6, 0);
1320 av_opt_set_int(c->priv_data,
"forced-idr",1,0);
1322 else if (strstr(
info.
vcodec.c_str(),
"rav1e") != NULL) {
1323 av_opt_set_int(c->priv_data,
"speed", 7, 0);
1324 av_opt_set_int(c->priv_data,
"tile-rows", 2, 0);
1325 av_opt_set_int(c->priv_data,
"tile-columns", 4, 0);
1327 else if (strstr(
info.
vcodec.c_str(),
"aom") != NULL) {
1330 av_opt_set_int(c->priv_data,
"tile-rows", 1, 0);
1331 av_opt_set_int(c->priv_data,
"tile-columns", 2, 0);
1332 av_opt_set_int(c->priv_data,
"row-mt", 1, 0);
1333 av_opt_set_int(c->priv_data,
"cpu-used", 3, 0);
1337 case AV_CODEC_ID_VP9 :
1338 case AV_CODEC_ID_HEVC :
1339 case AV_CODEC_ID_VP8 :
1340 case AV_CODEC_ID_H264 :
1376 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 26, 0)
1377 c->framerate = av_inv_q(c->time_base);
1379 st->avg_frame_rate = av_inv_q(c->time_base);
1380 st->r_frame_rate = av_inv_q(c->time_base);
1385 c->max_b_frames = 10;
1386 if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO)
1388 c->max_b_frames = 2;
1389 if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO)
1395 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1396 #if (LIBAVCODEC_VERSION_MAJOR >= 57)
1398 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1400 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1405 while (supported_pixel_formats != NULL && *supported_pixel_formats !=
PIX_FMT_NONE) {
1408 c->pix_fmt = *supported_pixel_formats;
1409 ++supported_pixel_formats;
1414 if (oc->oformat->video_codec == AV_CODEC_ID_RAWVIDEO) {
1418 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
1420 if (strcmp(oc->oformat->name,
"gif") != 0)
1423 oc->oformat->flags |= AVFMT_RAWPICTURE;
1433 "FFmpegWriter::add_video_stream ("
1434 + (std::string)oc->oformat->name +
" : "
1435 + (std::string)av_get_pix_fmt_name(c->pix_fmt) +
")",
1436 "c->codec_id", c->codec_id,
1437 "c->bit_rate", c->bit_rate,
1438 "c->pix_fmt", c->pix_fmt,
1439 "oc->oformat->flags", oc->oformat->flags);
1444 void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st) {
1445 const AVCodec *
codec;
1454 codec = avcodec_find_encoder(audio_codec_ctx->codec_id);
1459 AVDictionary *
opts = NULL;
1460 av_dict_set(&
opts,
"strict",
"experimental", 0);
1463 if (avcodec_open2(audio_codec_ctx,
codec, &
opts) < 0)
1464 throw InvalidCodec(
"Could not open audio codec", path);
1468 av_dict_free(&
opts);
1472 if (audio_codec_ctx->frame_size <= 1) {
1478 case AV_CODEC_ID_PCM_S16LE:
1479 case AV_CODEC_ID_PCM_S16BE:
1480 case AV_CODEC_ID_PCM_U16LE:
1481 case AV_CODEC_ID_PCM_U16BE:
1482 audio_input_frame_size >>= 1;
1489 audio_input_frame_size = audio_codec_ctx->frame_size;
1493 initial_audio_input_frame_size = audio_input_frame_size;
1500 audio_outbuf =
new uint8_t[audio_outbuf_size];
1504 audio_encoder_buffer =
new uint8_t[audio_encoder_buffer_size];
1507 for (std::map<std::string, std::string>::iterator iter =
info.
metadata.begin(); iter !=
info.
metadata.end(); ++iter) {
1508 av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1512 "FFmpegWriter::open_audio",
1513 "audio_codec_ctx->thread_count", audio_codec_ctx->thread_count,
1514 "audio_input_frame_size", audio_input_frame_size,
1519 void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) {
1520 const AVCodec *
codec;
1530 char *adapter_ptr = NULL;
1534 std::clog <<
"Encoding Device Nr: " << adapter_num <<
"\n";
1535 if (adapter_num < 3 && adapter_num >=0) {
1536 #if defined(__linux__)
1537 snprintf(adapter,
sizeof(adapter),
"/dev/dri/renderD%d", adapter_num+128);
1539 adapter_ptr = adapter;
1540 #elif defined(_WIN32) || defined(__APPLE__)
1548 #if defined(__linux__)
1549 if( adapter_ptr != NULL && access( adapter_ptr, W_OK ) == 0 ) {
1550 #elif defined(_WIN32) || defined(__APPLE__)
1551 if( adapter_ptr != NULL ) {
1554 "Encode Device present using device",
1555 "adapter", adapter_num);
1560 "Encode Device not present, using default");
1562 if (av_hwdevice_ctx_create(&hw_device_ctx,
1566 "FFmpegWriter::open_video ERROR creating hwdevice, Codec name:",
1571 #endif // USE_HW_ACCEL
1582 if (!allow_b_frames && video_codec_ctx->max_b_frames &&
1583 video_codec_ctx->codec_id != AV_CODEC_ID_MPEG4 &&
1584 video_codec_ctx->codec_id != AV_CODEC_ID_MPEG1VIDEO &&
1585 video_codec_ctx->codec_id != AV_CODEC_ID_MPEG2VIDEO)
1586 video_codec_ctx->max_b_frames = 0;
1590 av_dict_set(&
opts,
"strict",
"experimental", 0);
1604 if (av_opt_get_int(video_codec_ctx->priv_data,
"qp", 0, &qp) != 0 || qp == 0) {
1606 av_opt_set(video_codec_ctx->priv_data,
"rc_mode",
"VBR", 0);
1610 video_codec_ctx->rc_max_rate = video_codec_ctx->bit_rate;
1614 switch (video_codec_ctx->codec_id) {
1615 case AV_CODEC_ID_H264:
1616 video_codec_ctx->max_b_frames = 0;
1617 video_codec_ctx->profile = AV_PROFILE_H264_CONSTRAINED_BASELINE;
1618 av_opt_set(video_codec_ctx->priv_data,
"preset",
"slow", 0);
1619 av_opt_set(video_codec_ctx->priv_data,
"tune",
"zerolatency", 0);
1620 av_opt_set(video_codec_ctx->priv_data,
"vprofile",
"baseline", AV_OPT_SEARCH_CHILDREN);
1622 case AV_CODEC_ID_HEVC:
1625 case AV_CODEC_ID_VP9:
1630 "No codec-specific options defined for this codec. HW encoding may fail",
1631 "codec_id", video_codec_ctx->codec_id);
1640 "FFmpegWriter::open_video (set_hwframe_ctx) ERROR faled to set hwframe context",
1643 av_err2string(err), -1);
1646 #endif // USE_HW_ACCEL
1651 video_codec_ctx->codec_tag = MKTAG(
'h',
'v',
'c',
'1');
1654 if (video_codec_ctx->codec_id == AV_CODEC_ID_HEVC) {
1655 video_codec_ctx->codec_tag = MKTAG(
'h',
'v',
'c',
'1');
1660 if (avcodec_open2(video_codec_ctx,
codec, &
opts) < 0)
1661 throw InvalidCodec(
"Could not open video codec", path);
1667 av_dict_free(&
opts);
1671 av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1675 "FFmpegWriter::open_video",
1676 "video_codec_ctx->thread_count", video_codec_ctx->thread_count);
1681 void FFmpegWriter::write_audio_packets(
bool is_final, std::shared_ptr<openshot::Frame> frame) {
1682 if (!frame && !is_final)
1686 int total_frame_samples = 0;
1687 int frame_position = 0;
1688 int channels_in_frame = 0;
1689 int sample_rate_in_frame = 0;
1690 int samples_in_frame = 0;
1695 int16_t *all_queued_samples = (int16_t *) av_malloc(all_queued_samples_size);
1696 int16_t *all_resampled_samples = NULL;
1697 int16_t *final_samples_planar = NULL;
1698 int16_t *final_samples = NULL;
1701 float *frame_samples_float = NULL;
1705 sample_rate_in_frame = frame->SampleRate();
1706 samples_in_frame = frame->GetAudioSamplesCount();
1707 channels_in_frame = frame->GetAudioChannelsCount();
1708 channel_layout_in_frame = frame->ChannelsLayout();
1711 frame_samples_float = frame->GetInterleavedAudioSamples(&samples_in_frame);
1715 total_frame_samples = samples_in_frame * channels_in_frame;
1718 const int16_t max16 = 32767;
1719 const int16_t min16 = -32768;
1720 for (
int s = 0; s < total_frame_samples; s++, frame_position++) {
1721 float valF = frame_samples_float[s] * (1 << 15);
1725 }
else if (valF < min16) {
1728 conv = int(valF + 32768.5) - 32768;
1732 all_queued_samples[frame_position] = conv;
1736 delete[] frame_samples_float;
1740 total_frame_samples = frame_position;
1741 int remaining_frame_samples = total_frame_samples;
1742 int samples_position = 0;
1746 "FFmpegWriter::write_audio_packets",
1747 "is_final", is_final,
1748 "total_frame_samples", total_frame_samples,
1749 "channel_layout_in_frame", channel_layout_in_frame,
1750 "channels_in_frame", channels_in_frame,
1751 "samples_in_frame", samples_in_frame,
1755 AVSampleFormat output_sample_fmt = audio_codec_ctx->sample_fmt;
1757 AVFrame *audio_frame = NULL;
1762 audio_frame->nb_samples = total_frame_samples / channels_in_frame;
1765 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);
1766 if (error_code < 0) {
1768 "FFmpegWriter::write_audio_packets ERROR ["
1769 + av_err2string(error_code) +
"]",
1770 "error_code", error_code);
1774 switch (audio_codec_ctx->sample_fmt) {
1775 case AV_SAMPLE_FMT_FLTP: {
1776 output_sample_fmt = AV_SAMPLE_FMT_FLT;
1779 case AV_SAMPLE_FMT_S32P: {
1780 output_sample_fmt = AV_SAMPLE_FMT_S32;
1783 case AV_SAMPLE_FMT_S16P: {
1784 output_sample_fmt = AV_SAMPLE_FMT_S16;
1787 case AV_SAMPLE_FMT_U8P: {
1788 output_sample_fmt = AV_SAMPLE_FMT_U8;
1798 total_frame_samples *= (float(
info.
sample_rate) / sample_rate_in_frame);
1799 total_frame_samples *= (float(
info.
channels) / channels_in_frame);
1804 audio_converted->nb_samples = total_frame_samples / channels_in_frame;
1805 av_samples_alloc(audio_converted->data, audio_converted->linesize,
info.
channels, audio_converted->nb_samples, output_sample_fmt, 0);
1808 "FFmpegWriter::write_audio_packets (1st resampling)",
1809 "in_sample_fmt", AV_SAMPLE_FMT_S16,
1810 "out_sample_fmt", output_sample_fmt,
1811 "in_sample_rate", sample_rate_in_frame,
1813 "in_channels", channels_in_frame,
1820 AVChannelLayout in_chlayout = ffmpeg_default_channel_layout(channels_in_frame);
1821 AVChannelLayout out_chlayout = ffmpeg_default_channel_layout(
info.
channels);
1822 if (channel_layout_in_frame > 0) {
1823 av_channel_layout_from_mask(&in_chlayout, channel_layout_in_frame);
1828 av_opt_set_chlayout(avr,
"in_chlayout", &in_chlayout, 0);
1829 av_opt_set_chlayout(avr,
"out_chlayout", &out_chlayout, 0);
1831 av_opt_set_int(avr,
"in_channel_layout", channel_layout_in_frame, 0);
1833 av_opt_set_int(avr,
"in_channels", channels_in_frame, 0);
1836 av_opt_set_int(avr,
"in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
1837 av_opt_set_int(avr,
"out_sample_fmt", output_sample_fmt, 0);
1838 av_opt_set_int(avr,
"in_sample_rate", sample_rate_in_frame, 0);
1845 audio_converted->data,
1846 audio_converted->linesize[0],
1847 audio_converted->nb_samples,
1849 audio_frame->linesize[0],
1850 audio_frame->nb_samples
1854 remaining_frame_samples = total_frame_samples;
1857 all_resampled_samples = (int16_t *) av_malloc(
1859 * (av_get_bytes_per_sample(output_sample_fmt) /
1860 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1864 memcpy(all_resampled_samples, audio_converted->data[0],
1865 static_cast<size_t>(nb_samples)
1867 * av_get_bytes_per_sample(output_sample_fmt));
1870 av_freep(&(audio_frame->data[0]));
1872 av_freep(&audio_converted->data[0]);
1874 all_queued_samples = NULL;
1877 "FFmpegWriter::write_audio_packets (Successfully completed 1st resampling)",
1878 "nb_samples", nb_samples,
1879 "remaining_frame_samples", remaining_frame_samples);
1882 if (is_final && remaining_frame_samples <= 0 && audio_input_position <= 0) {
1883 if (all_queued_samples) {
1884 av_freep(&all_queued_samples);
1890 while (remaining_frame_samples > 0 || is_final) {
1892 int remaining_packet_samples = (audio_input_frame_size *
info.
channels) - audio_input_position;
1896 if (remaining_frame_samples >= remaining_packet_samples) {
1897 diff = remaining_packet_samples;
1899 diff = remaining_frame_samples;
1906 samples + (audio_input_position
1907 * (av_get_bytes_per_sample(output_sample_fmt) /
1908 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1910 all_resampled_samples + samples_position,
1911 static_cast<size_t>(diff)
1912 * av_get_bytes_per_sample(output_sample_fmt)
1916 audio_input_position += diff;
1917 samples_position += diff * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16));
1918 remaining_frame_samples -= diff;
1921 if (audio_input_position < (audio_input_frame_size *
info.
channels) && !is_final)
1928 const int frame_nb_samples = audio_input_position /
info.
channels;
1929 if (av_sample_fmt_is_planar(audio_codec_ctx->sample_fmt)) {
1931 "FFmpegWriter::write_audio_packets (2nd resampling for Planar formats)",
1932 "in_sample_fmt", output_sample_fmt,
1933 "out_sample_fmt", audio_codec_ctx->sample_fmt,
1944 AVChannelLayout layout = ffmpeg_default_channel_layout(
info.
channels);
1948 av_opt_set_chlayout(avr_planar,
"in_chlayout", &layout, 0);
1949 av_opt_set_chlayout(avr_planar,
"out_chlayout", &layout, 0);
1953 av_opt_set_int(avr_planar,
"in_channels",
info.
channels, 0);
1954 av_opt_set_int(avr_planar,
"out_channels",
info.
channels, 0);
1956 av_opt_set_int(avr_planar,
"in_sample_fmt", output_sample_fmt, 0);
1957 av_opt_set_int(avr_planar,
"out_sample_fmt", audio_codec_ctx->sample_fmt, 0);
1966 audio_frame->nb_samples = audio_input_position /
info.
channels;
1969 final_samples_planar = (int16_t *) av_malloc(
1970 sizeof(int16_t) * audio_frame->nb_samples *
info.
channels
1971 * (av_get_bytes_per_sample(output_sample_fmt) /
1972 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1976 memcpy(final_samples_planar, samples,
1977 static_cast<size_t>(audio_frame->nb_samples)
1979 * av_get_bytes_per_sample(output_sample_fmt));
1982 avcodec_fill_audio_frame(audio_frame,
info.
channels, output_sample_fmt,
1983 (uint8_t *) final_samples_planar, audio_encoder_buffer_size, 0);
1986 frame_final->nb_samples = frame_nb_samples;
1993 frame_final->format = audio_codec_ctx->sample_fmt;
1994 av_samples_alloc(frame_final->data, frame_final->linesize,
info.
channels,
1995 frame_final->nb_samples, audio_codec_ctx->sample_fmt, 0);
2001 frame_final->linesize[0],
2002 frame_final->nb_samples,
2004 audio_frame->linesize[0],
2005 audio_frame->nb_samples
2009 const auto copy_length =
static_cast<size_t>(nb_samples)
2010 * av_get_bytes_per_sample(audio_codec_ctx->sample_fmt)
2014 memcpy(samples, frame_final->data[0], copy_length);
2017 av_freep(&(audio_frame->data[0]));
2019 all_queued_samples = NULL;
2022 "FFmpegWriter::write_audio_packets (Successfully completed 2nd resampling for Planar formats)",
2023 "nb_samples", nb_samples);
2027 const auto buf_size =
static_cast<size_t>(audio_input_position)
2028 * (av_get_bytes_per_sample(audio_codec_ctx->sample_fmt) /
2029 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)
2031 final_samples =
reinterpret_cast<int16_t*
>(
2032 av_malloc(
sizeof(int16_t) * buf_size));
2035 memcpy(final_samples, samples,
2036 audio_input_position * av_get_bytes_per_sample(audio_codec_ctx->sample_fmt));
2039 frame_final->nb_samples = frame_nb_samples;
2040 frame_final->format = audio_codec_ctx->sample_fmt;
2042 av_channel_layout_copy(&frame_final->ch_layout, &audio_codec_ctx->ch_layout);
2044 frame_final->channels = audio_codec_ctx->channels;
2045 frame_final->channel_layout = audio_codec_ctx->channel_layout;
2050 int nb_channels = audio_codec_ctx->ch_layout.nb_channels;
2052 int nb_channels = audio_codec_ctx->channels;
2054 avcodec_fill_audio_frame(frame_final, nb_channels,
2055 audio_codec_ctx->sample_fmt, (uint8_t *) final_samples,
2056 audio_encoder_buffer_size, 0);
2060 frame_final->pts = audio_timestamp;
2064 AVPacket* pkt = av_packet_alloc();
2067 av_init_packet(pkt);
2068 pkt->data = audio_encoder_buffer;
2069 pkt->size = audio_encoder_buffer_size;
2073 pkt->pts = pkt->dts = audio_timestamp;
2076 int got_packet_ptr = 0;
2082 int frame_finished = 0;
2083 error_code = ret = avcodec_send_frame(audio_codec_ctx, frame_final);
2084 if (ret < 0 && ret != AVERROR(EINVAL) && ret != AVERROR_EOF
2085 && audio_codec_ctx->codec
2086 && (audio_codec_ctx->codec->capabilities & AV_CODEC_CAP_DELAY)) {
2087 avcodec_send_frame(audio_codec_ctx, NULL);
2092 ret = avcodec_receive_packet(audio_codec_ctx, pkt);
2095 if(ret == AVERROR(EINVAL) || ret == AVERROR_EOF) {
2099 ret = frame_finished;
2102 if (!pkt->data && !frame_finished)
2106 got_packet_ptr = ret;
2109 int error_code = avcodec_encode_audio2(audio_codec_ctx, pkt, frame_final, &got_packet_ptr);
2112 if (error_code == 0 && got_packet_ptr) {
2116 pkt->pts = pkt->dts = audio_timestamp;
2117 if (pkt->duration <= 0) {
2118 pkt->duration = frame_nb_samples;
2122 av_packet_rescale_ts(pkt, audio_codec_ctx->time_base, audio_st->time_base);
2125 pkt->stream_index = audio_st->index;
2126 pkt->flags |= AV_PKT_FLAG_KEY;
2129 error_code = av_interleaved_write_frame(oc, pkt);
2132 if (error_code < 0) {
2134 "FFmpegWriter::write_audio_packets ERROR ["
2135 + av_err2string(error_code) +
"]",
2136 "error_code", error_code);
2140 audio_timestamp += FFMIN(audio_input_frame_size, audio_input_position);
2143 av_freep(&(frame_final->data[0]));
2150 audio_input_position = 0;
2155 if (all_resampled_samples) {
2156 av_freep(&all_resampled_samples);
2157 all_resampled_samples = NULL;
2159 if (all_queued_samples) {
2160 av_freep(&all_queued_samples);
2161 all_queued_samples = NULL;
2166 AVFrame *FFmpegWriter::allocate_avframe(
PixelFormat pix_fmt,
int width,
int height,
int *buffer_size, uint8_t *new_buffer) {
2168 AVFrame *new_av_frame = NULL;
2172 if (new_av_frame == NULL)
2173 throw OutOfMemory(
"Could not allocate AVFrame", path);
2181 new_buffer = (uint8_t *) av_malloc(*buffer_size *
sizeof(uint8_t));
2184 new_av_frame->width = width;
2185 new_av_frame->height = height;
2186 new_av_frame->format = pix_fmt;
2190 return new_av_frame;
2194 void FFmpegWriter::process_video_packet(std::shared_ptr<Frame> frame) {
2196 int src_w = frame->GetWidth();
2197 int src_h = frame->GetHeight();
2200 if (src_w == 1 && src_h == 1)
2204 const uchar* pixels = frame->GetPixels();
2205 if (!persistent_src_frame) {
2206 persistent_src_frame = av_frame_alloc();
2207 if (!persistent_src_frame)
2208 throw OutOfMemory(
"Could not allocate persistent_src_frame", path);
2209 persistent_src_frame->format = AV_PIX_FMT_RGBA;
2210 persistent_src_frame->width = src_w;
2211 persistent_src_frame->height = src_h;
2212 persistent_src_frame->linesize[0] = src_w * 4;
2214 persistent_src_frame->data[0] =
const_cast<uint8_t*
>(
2215 reinterpret_cast<const uint8_t*
>(pixels)
2219 if (!persistent_dst_frame) {
2220 persistent_dst_frame = av_frame_alloc();
2221 if (!persistent_dst_frame)
2222 throw OutOfMemory(
"Could not allocate persistent_dst_frame", path);
2225 AVPixelFormat dst_fmt = video_codec_ctx->pix_fmt;
2228 dst_fmt = AV_PIX_FMT_NV12;
2231 persistent_dst_frame->format = dst_fmt;
2232 persistent_dst_frame->width =
info.
width;
2235 persistent_dst_size = av_image_get_buffer_size(
2238 if (persistent_dst_size < 0)
2241 persistent_dst_buffer =
static_cast<uint8_t*
>(
2242 av_malloc(persistent_dst_size)
2244 if (!persistent_dst_buffer)
2245 throw OutOfMemory(
"Could not allocate persistent_dst_buffer", path);
2247 av_image_fill_arrays(
2248 persistent_dst_frame->data,
2249 persistent_dst_frame->linesize,
2250 persistent_dst_buffer,
2259 if (!img_convert_ctx) {
2260 int flags = SWS_FAST_BILINEAR;
2262 flags = SWS_BICUBIC;
2264 AVPixelFormat dst_fmt = video_codec_ctx->pix_fmt;
2267 dst_fmt = AV_PIX_FMT_NV12;
2270 img_convert_ctx = sws_getContext(
2271 src_w, src_h, AV_PIX_FMT_RGBA,
2273 flags, NULL, NULL, NULL
2275 if (!img_convert_ctx)
2282 persistent_src_frame->data,
2283 persistent_src_frame->linesize,
2285 persistent_dst_frame->data,
2286 persistent_dst_frame->linesize
2290 int bytes_final = 0;
2291 AVPixelFormat dst_fmt = video_codec_ctx->pix_fmt;
2294 dst_fmt = AV_PIX_FMT_NV12;
2298 AVFrame* new_frame = allocate_avframe(
2306 throw OutOfMemory(
"Could not allocate new_frame via allocate_avframe", path);
2311 persistent_dst_buffer,
2312 static_cast<size_t>(bytes_final)
2316 add_avframe(frame, new_frame);
2320 bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *frame_final) {
2321 #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
2324 "FFmpegWriter::write_video_packet",
2325 "frame->number", frame->number,
2326 "oc->oformat->flags", oc->oformat->flags);
2334 "FFmpegWriter::write_video_packet",
2335 "frame->number", frame->number,
2336 "oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE);
2338 if (oc->oformat->flags & AVFMT_RAWPICTURE) {
2342 AVPacket* pkt = av_packet_alloc();
2345 av_init_packet(pkt);
2348 av_packet_from_data(
2349 pkt, frame_final->data[0],
2350 frame_final->linesize[0] * frame_final->height);
2352 pkt->flags |= AV_PKT_FLAG_KEY;
2353 pkt->stream_index = video_st->index;
2356 pkt->pts = video_timestamp;
2357 pkt->duration = av_rescale_q(1, av_make_q(
info.
fps.
den,
info.
fps.
num), video_codec_ctx->time_base);
2360 int error_code = av_interleaved_write_frame(oc, pkt);
2361 if (error_code < 0) {
2363 "FFmpegWriter::write_video_packet ERROR ["
2364 + av_err2string(error_code) +
"]",
2365 "error_code", error_code);
2376 AVPacket* pkt = av_packet_alloc();
2379 av_init_packet(pkt);
2383 pkt->pts = pkt->dts = AV_NOPTS_VALUE;
2386 frame_final->pts = video_timestamp;
2389 if (!(
hw_frame = av_frame_alloc())) {
2390 std::clog <<
"Error code: av_hwframe_alloc\n";
2392 if (av_hwframe_get_buffer(video_codec_ctx->hw_frames_ctx,
hw_frame, 0) < 0) {
2393 std::clog <<
"Error code: av_hwframe_get_buffer\n";
2396 std::clog <<
"Error hw_frames_ctx.\n";
2398 hw_frame->format = AV_PIX_FMT_NV12;
2399 if ( av_hwframe_transfer_data(
hw_frame, frame_final, 0) < 0) {
2400 std::clog <<
"Error while transferring frame data to surface.\n";
2402 av_frame_copy_props(
hw_frame, frame_final);
2404 #endif // USE_HW_ACCEL
2406 int got_packet_ptr = 0;
2414 ret = avcodec_send_frame(video_codec_ctx,
hw_frame);
2416 #endif // USE_HW_ACCEL
2418 ret = avcodec_send_frame(video_codec_ctx, frame_final);
2423 "FFmpegWriter::write_video_packet (Frame not sent)");
2424 if (ret == AVERROR(EAGAIN) ) {
2425 std::clog <<
"Frame EAGAIN\n";
2427 if (ret == AVERROR_EOF ) {
2428 std::clog <<
"Frame AVERROR_EOF\n";
2430 avcodec_send_frame(video_codec_ctx, NULL);
2434 ret = avcodec_receive_packet(video_codec_ctx, pkt);
2436 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
2448 error_code = avcodec_encode_video2(video_codec_ctx, pkt, frame_final, &got_packet_ptr);
2449 if (error_code != 0) {
2451 "FFmpegWriter::write_video_packet ERROR ["
2452 + av_err2string(error_code) +
"]",
2453 "error_code", error_code);
2455 if (got_packet_ptr == 0) {
2457 "FFmpegWriter::write_video_packet (Frame gotpacket error)");
2459 #endif // IS_FFMPEG_3_2
2462 if (error_code == 0 && got_packet_ptr) {
2464 if (pkt->duration <= 0) {
2465 pkt->duration = av_rescale_q(1, av_make_q(
info.
fps.
den,
info.
fps.
num), video_codec_ctx->time_base);
2467 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
2468 pkt->stream_index = video_st->index;
2471 int result = av_interleaved_write_frame(oc, pkt);
2474 "FFmpegWriter::write_video_packet ERROR ["
2475 + av_err2string(result) +
"]",
2490 #endif // USE_HW_ACCEL
2494 video_timestamp += av_rescale_q(1, av_make_q(
info.
fps.
den,
info.
fps.
num), video_codec_ctx->time_base);
2503 av_dump_format(oc, 0, path.c_str(), 1);
2508 original_sample_rate = sample_rate;
2509 original_channels = channels;
2518 oc->strict_std_compliance = FF_COMPLIANCE_UNOFFICIAL;
2520 #if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 0, 0)
2522 int proj = av_spherical_from_name(projection.c_str());
2524 proj = AV_SPHERICAL_EQUIRECTANGULAR;
2528 AVSphericalMapping* map = av_spherical_alloc(&sd_size);
2532 map->projection =
static_cast<AVSphericalProjection
>(proj);
2534 map->yaw =
static_cast<int32_t
>(yaw_deg * (1 << 16));
2535 map->pitch =
static_cast<int32_t
>(pitch_deg * (1 << 16));
2536 map->roll =
static_cast<int32_t
>(roll_deg * (1 << 16));
2538 ffmpeg_stream_add_side_data(video_st, AV_PKT_DATA_SPHERICAL,
2539 reinterpret_cast<uint8_t*
>(map), sd_size);