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);
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), 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());
223 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
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")) {
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 ==
"mb_decision")
391 convert >> c->mb_decision;
393 else if (name ==
"level")
397 else if (name ==
"profile")
399 convert >> c->profile;
401 else if (name ==
"slices")
403 convert >> c->slices;
405 else if (name ==
"rc_min_rate")
407 convert >> c->rc_min_rate;
409 else if (name ==
"rc_max_rate")
411 convert >> c->rc_max_rate;
413 else if (name ==
"rc_buffer_size")
415 convert >> c->rc_buffer_size;
417 else if (name ==
"cqp") {
421 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),63), 0);
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") {
469 double mbs = 15000000.0;
478 c->bit_rate = (int)(mbs);
482 switch (c->codec_id) {
483 #if (LIBAVCODEC_VERSION_MAJOR >= 58)
485 case AV_CODEC_ID_AV1 :
488 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value),63), 0);
491 case AV_CODEC_ID_VP8 :
492 c->bit_rate = 10000000;
493 av_opt_set_int(c->priv_data,
"crf", std::max(std::min(std::stoi(value), 63), 4), 0);
495 case AV_CODEC_ID_VP9 :
497 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value), 63), 0);
498 if (std::stoi(value) == 0) {
499 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
500 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
503 case AV_CODEC_ID_H264 :
504 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value), 51), 0);
505 if (std::stoi(value) == 0) {
506 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
510 case AV_CODEC_ID_HEVC :
511 if (strstr(
info.
vcodec.c_str(),
"svt_hevc") != NULL) {
512 av_opt_set_int(c->priv_data,
"preset", 7, 0);
513 av_opt_set_int(c->priv_data,
"forced-idr",1,0);
514 av_opt_set_int(c->priv_data,
"qp",std::min(std::stoi(value), 51),0);
517 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value), 51), 0);
519 if (std::stoi(value) == 0) {
520 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
521 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
527 double mbs = 15000000.0;
535 c->bit_rate = (int) (mbs);
538 }
else if (name ==
"qp") {
540 #if (LIBAVCODEC_VERSION_MAJOR >= 58)
542 switch (c->codec_id) {
543 case AV_CODEC_ID_AV1 :
545 if (strstr(
info.
vcodec.c_str(),
"svtav1") != NULL) {
546 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),63), 0);
548 else if (strstr(
info.
vcodec.c_str(),
"rav1e") != NULL) {
551 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),255), 0);
553 else if (strstr(
info.
vcodec.c_str(),
"aom") != NULL) {
557 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value),63), 0);
560 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value),63), 0);
562 case AV_CODEC_ID_HEVC :
564 if (strstr(
info.
vcodec.c_str(),
"svt_hevc") != NULL) {
565 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),51), 0);
566 av_opt_set_int(c->priv_data,
"preset", 7, 0);
567 av_opt_set_int(c->priv_data,
"forced-idr",1,0);
574 AV_OPTION_SET(st, c->priv_data, name.c_str(), value.c_str(), c);
578 "FFmpegWriter::SetOption (" + (std::string)name +
")",
583 }
else if (name ==
"muxing_preset") {
584 if (value ==
"mp4_faststart") {
586 av_dict_set(&
mux_dict,
"movflags",
"faststart", 0);
587 }
else if (value ==
"mp4_fragmented") {
589 av_dict_set(&
mux_dict,
"movflags",
"frag_keyframe", 0);
590 av_dict_set(&
mux_dict,
"min_frag_duration",
"8000000", 0);
593 throw InvalidOptions(
"The option is not valid for this codec.", path);
604 return avcodec_find_encoder_by_name(codec_name.c_str()) != NULL;
610 throw InvalidOptions(
"No video or audio options have been set. You must set has_video or has_audio (or both).", path);
613 "FFmpegWriter::PrepareStreams [" + path +
"]",
618 initialize_streams();
621 prepare_streams =
true;
627 throw InvalidOptions(
"No video or audio options have been set. You must set has_video or has_audio (or both).", path);
630 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
631 if (avio_open(&oc->pb, path.c_str(), AVIO_FLAG_WRITE) < 0)
632 throw InvalidFile(
"Could not open or write file.", path);
640 av_dict_set(&oc->metadata, iter->first.c_str(), iter->second.c_str(), 0);
644 AVDictionary *dict = NULL;
650 if (avformat_write_header(oc, &dict) != 0) {
652 "FFmpegWriter::WriteHeader (avformat_write_header)");
653 throw InvalidFile(
"Could not write header to file.", path);
657 if (dict) av_dict_free(&dict);
670 throw WriterClosed(
"The FFmpegWriter is closed. Call Open() before calling this method.", path);
673 "FFmpegWriter::WriteFrame",
674 "frame->number", frame->number,
675 "is_writing", is_writing);
685 void FFmpegWriter::write_frame(std::shared_ptr<Frame> frame) {
690 bool has_error_encoding_video =
false;
694 write_audio_packets(
false, frame);
698 process_video_packet(frame);
702 if (av_frames.count(frame)) {
704 AVFrame *frame_final = av_frames[frame];
707 if (!write_video_packet(frame, frame_final)) {
708 has_error_encoding_video =
true;
712 av_freep(&(frame_final->data[0]));
714 av_frames.erase(frame);
722 if (has_error_encoding_video)
729 "FFmpegWriter::WriteFrame (from Reader)",
734 for (int64_t number = start; number <= length; number++) {
736 std::shared_ptr<Frame> f = reader->
GetFrame(number);
747 write_audio_packets(
true, NULL);
756 av_write_trailer(oc);
759 write_trailer =
true;
765 void FFmpegWriter::flush_encoders() {
768 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
782 video_timestamp += av_rescale_q(1, av_make_q(
info.
fps.
den,
info.
fps.
num), video_codec_ctx->time_base);
785 AVPacket* pkt = av_packet_alloc();
799 error_code = avcodec_send_frame(video_codec_ctx, NULL);
801 while (error_code >= 0) {
802 error_code = avcodec_receive_packet(video_codec_ctx, pkt);
803 if (error_code == AVERROR(EAGAIN)|| error_code == AVERROR_EOF) {
806 avcodec_flush_buffers(video_codec_ctx);
809 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
810 pkt->stream_index = video_st->index;
811 error_code = av_interleaved_write_frame(oc, pkt);
816 error_code = avcodec_encode_video2(video_codec_ctx, pkt, NULL, &got_packet);
820 if (error_code < 0) {
822 "FFmpegWriter::flush_encoders ERROR ["
823 + av_err2string(error_code) +
"]",
824 "error_code", error_code);
831 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
832 pkt->stream_index = video_st->index;
835 error_code = av_interleaved_write_frame(oc, pkt);
836 if (error_code < 0) {
838 "FFmpegWriter::flush_encoders ERROR ["
839 + av_err2string(error_code) +
"]",
840 "error_code", error_code);
849 AVPacket* pkt = av_packet_alloc();
856 pkt->pts = pkt->dts = audio_timestamp;
862 error_code = avcodec_send_frame(audio_codec_ctx, NULL);
864 error_code = avcodec_encode_audio2(audio_codec_ctx, pkt, NULL, &got_packet);
866 if (error_code < 0) {
868 "FFmpegWriter::flush_encoders ERROR ["
869 + av_err2string(error_code) +
"]",
870 "error_code", error_code);
878 pkt->pts = pkt->dts = audio_timestamp;
881 av_packet_rescale_ts(pkt, audio_codec_ctx->time_base, audio_st->time_base);
884 pkt->stream_index = audio_st->index;
885 pkt->flags |= AV_PKT_FLAG_KEY;
888 error_code = av_interleaved_write_frame(oc, pkt);
889 if (error_code < 0) {
891 "FFmpegWriter::flush_encoders ERROR ["
892 + av_err2string(error_code) +
"]",
893 "error_code", error_code);
897 audio_timestamp += pkt->duration;
907 void FFmpegWriter::close_video(AVFormatContext *oc, AVStream *st)
912 av_buffer_unref(&hw_device_ctx);
913 hw_device_ctx = NULL;
919 if (video_codec_ctx !=
nullptr) {
921 av_free(video_codec_ctx);
926 void FFmpegWriter::close_audio(AVFormatContext *oc, AVStream *st)
930 delete[] audio_outbuf;
931 delete[] audio_encoder_buffer;
934 audio_encoder_buffer = NULL;
950 if (audio_codec_ctx !=
nullptr) {
952 av_free(audio_codec_ctx);
964 close_video(oc, video_st);
966 close_audio(oc, audio_st);
970 sws_freeContext(img_convert_ctx);
972 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
982 avformat_free_context(oc);
987 prepare_streams =
false;
988 write_header =
false;
989 write_trailer =
false;
995 void FFmpegWriter::add_avframe(std::shared_ptr<Frame> frame, AVFrame *av_frame) {
997 if (!av_frames.count(frame)) {
999 av_frames[frame] = av_frame;
1007 AVStream *FFmpegWriter::add_audio_stream() {
1009 const AVCodec *
codec = avcodec_find_encoder_by_name(
info.
acodec.c_str());
1011 throw InvalidCodec(
"A valid audio codec could not be found for this file.", path);
1014 if (audio_codec_ctx !=
nullptr) {
1019 AVStream* st = avformat_new_stream(oc,
codec);
1021 throw OutOfMemory(
"Could not allocate memory for the audio stream.", path);
1025 #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
1026 st->codecpar->codec_id =
codec->id;
1028 AVCodecContext* c = audio_codec_ctx;
1030 c->codec_id =
codec->id;
1031 c->codec_type = AVMEDIA_TYPE_AUDIO;
1040 if (
codec->supported_samplerates) {
1042 for (i = 0;
codec->supported_samplerates[i] != 0; i++)
1048 if (
codec->supported_samplerates[i] == 0)
1049 throw InvalidSampleRate(
"An invalid sample rate was detected for this codec.", path);
1057 AVChannelLayout ch_layout;
1059 if (
codec->ch_layouts) {
1061 for (i = 0; av_channel_layout_check(&
codec->ch_layouts[i]); i++)
1062 if (av_channel_layout_compare(&ch_layout, &
codec->ch_layouts[i])) {
1064 av_channel_layout_copy(&c->ch_layout, &ch_layout);
1067 if (!av_channel_layout_check(&
codec->ch_layouts[i]))
1068 throw InvalidChannels(
"An invalid channel layout was detected (i.e. MONO / STEREO).", path);
1071 av_channel_layout_copy(&c->ch_layout, &ch_layout);
1074 if (
codec->channel_layouts) {
1076 for (i = 0;
codec->channel_layouts[i] != 0; i++)
1077 if (channel_layout ==
codec->channel_layouts[i]) {
1079 c->channel_layout = channel_layout;
1082 if (
codec->channel_layouts[i] == 0)
1083 throw InvalidChannels(
"An invalid channel layout was detected (i.e. MONO / STEREO).", path);
1086 c->channel_layout = channel_layout;
1090 if (
codec->sample_fmts) {
1091 for (
int i = 0;
codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) {
1093 c->sample_fmt =
codec->sample_fmts[i];
1097 if (c->sample_fmt == AV_SAMPLE_FMT_NONE) {
1099 c->sample_fmt = AV_SAMPLE_FMT_S16;
1103 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1104 #if (LIBAVCODEC_VERSION_MAJOR >= 57)
1106 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1108 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1114 const char* nb_channels_label;
1115 const char* channel_layout_label;
1118 nb_channels = c->ch_layout.nb_channels;
1119 channel_layout = c->ch_layout.u.mask;
1120 nb_channels_label =
"c->ch_layout.nb_channels";
1121 channel_layout_label =
"c->ch_layout.u.mask";
1123 nb_channels = c->channels;
1124 nb_channels_label =
"c->channels";
1125 channel_layout_label =
"c->channel_layout";
1129 "FFmpegWriter::add_audio_stream",
1130 "c->codec_id", c->codec_id,
1131 "c->bit_rate", c->bit_rate,
1132 nb_channels_label, nb_channels,
1133 "c->sample_fmt", c->sample_fmt,
1134 channel_layout_label, channel_layout,
1135 "c->sample_rate", c->sample_rate);
1141 AVStream *FFmpegWriter::add_video_stream() {
1143 const AVCodec *
codec = avcodec_find_encoder_by_name(
info.
vcodec.c_str());
1145 throw InvalidCodec(
"A valid video codec could not be found for this file.", path);
1148 if (video_codec_ctx !=
nullptr) {
1153 AVStream* st = avformat_new_stream(oc,
codec);
1155 throw OutOfMemory(
"Could not allocate memory for the video stream.", path);
1159 #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
1160 st->codecpar->codec_id =
codec->id;
1163 AVCodecContext* c = video_codec_ctx;
1165 c->codec_id =
codec->id;
1166 c->codec_type = AVMEDIA_TYPE_VIDEO;
1174 #
if (LIBAVCODEC_VERSION_MAJOR >= 58)
1175 && c->codec_id != AV_CODEC_ID_AV1
1180 if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
1189 switch (c->codec_id) {
1190 #if (LIBAVCODEC_VERSION_MAJOR >= 58)
1192 case AV_CODEC_ID_AV1 :
1196 if (strstr(
info.
vcodec.c_str(),
"aom") != NULL) {
1197 int calculated_quality = 35;
1200 av_opt_set_int(c->priv_data,
"crf", calculated_quality, 0);
1203 int calculated_quality = 50;
1206 av_opt_set_int(c->priv_data,
"qp", calculated_quality, 0);
1210 if (strstr(
info.
vcodec.c_str(),
"svtav1") != NULL) {
1211 av_opt_set_int(c->priv_data,
"preset", 6, 0);
1212 av_opt_set_int(c->priv_data,
"forced-idr",1,0);
1214 else if (strstr(
info.
vcodec.c_str(),
"rav1e") != NULL) {
1215 av_opt_set_int(c->priv_data,
"speed", 7, 0);
1216 av_opt_set_int(c->priv_data,
"tile-rows", 2, 0);
1217 av_opt_set_int(c->priv_data,
"tile-columns", 4, 0);
1219 else if (strstr(
info.
vcodec.c_str(),
"aom") != NULL) {
1222 av_opt_set_int(c->priv_data,
"tile-rows", 1, 0);
1223 av_opt_set_int(c->priv_data,
"tile-columns", 2, 0);
1224 av_opt_set_int(c->priv_data,
"row-mt", 1, 0);
1225 av_opt_set_int(c->priv_data,
"cpu-used", 3, 0);
1229 case AV_CODEC_ID_VP9 :
1230 case AV_CODEC_ID_HEVC :
1231 case AV_CODEC_ID_VP8 :
1232 case AV_CODEC_ID_H264 :
1268 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 26, 0)
1269 c->framerate = av_inv_q(c->time_base);
1271 st->avg_frame_rate = av_inv_q(c->time_base);
1276 c->max_b_frames = 10;
1277 if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO)
1279 c->max_b_frames = 2;
1280 if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO)
1286 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1287 #if (LIBAVCODEC_VERSION_MAJOR >= 57)
1289 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1291 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1296 while (supported_pixel_formats != NULL && *supported_pixel_formats !=
PIX_FMT_NONE) {
1299 c->pix_fmt = *supported_pixel_formats;
1300 ++supported_pixel_formats;
1305 if (oc->oformat->video_codec == AV_CODEC_ID_RAWVIDEO) {
1309 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
1311 if (strcmp(oc->oformat->name,
"gif") != 0)
1314 oc->oformat->flags |= AVFMT_RAWPICTURE;
1324 "FFmpegWriter::add_video_stream ("
1325 + (std::string)oc->oformat->name +
" : "
1326 + (std::string)av_get_pix_fmt_name(c->pix_fmt) +
")",
1327 "c->codec_id", c->codec_id,
1328 "c->bit_rate", c->bit_rate,
1329 "c->pix_fmt", c->pix_fmt,
1330 "oc->oformat->flags", oc->oformat->flags);
1335 void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st) {
1336 const AVCodec *
codec;
1345 codec = avcodec_find_encoder(audio_codec_ctx->codec_id);
1350 AVDictionary *
opts = NULL;
1351 av_dict_set(&
opts,
"strict",
"experimental", 0);
1354 if (avcodec_open2(audio_codec_ctx,
codec, &
opts) < 0)
1355 throw InvalidCodec(
"Could not open audio codec", path);
1359 av_dict_free(&
opts);
1363 if (audio_codec_ctx->frame_size <= 1) {
1369 case AV_CODEC_ID_PCM_S16LE:
1370 case AV_CODEC_ID_PCM_S16BE:
1371 case AV_CODEC_ID_PCM_U16LE:
1372 case AV_CODEC_ID_PCM_U16BE:
1373 audio_input_frame_size >>= 1;
1380 audio_input_frame_size = audio_codec_ctx->frame_size;
1384 initial_audio_input_frame_size = audio_input_frame_size;
1391 audio_outbuf =
new uint8_t[audio_outbuf_size];
1395 audio_encoder_buffer =
new uint8_t[audio_encoder_buffer_size];
1398 for (std::map<std::string, std::string>::iterator iter =
info.
metadata.begin(); iter !=
info.
metadata.end(); ++iter) {
1399 av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1403 "FFmpegWriter::open_audio",
1404 "audio_codec_ctx->thread_count", audio_codec_ctx->thread_count,
1405 "audio_input_frame_size", audio_input_frame_size,
1410 void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) {
1411 const AVCodec *
codec;
1421 char *adapter_ptr = NULL;
1425 std::clog <<
"Encoding Device Nr: " << adapter_num <<
"\n";
1426 if (adapter_num < 3 && adapter_num >=0) {
1427 #if defined(__linux__)
1428 snprintf(adapter,
sizeof(adapter),
"/dev/dri/renderD%d", adapter_num+128);
1430 adapter_ptr = adapter;
1431 #elif defined(_WIN32) || defined(__APPLE__)
1439 #if defined(__linux__)
1440 if( adapter_ptr != NULL && access( adapter_ptr, W_OK ) == 0 ) {
1441 #elif defined(_WIN32) || defined(__APPLE__)
1442 if( adapter_ptr != NULL ) {
1445 "Encode Device present using device",
1446 "adapter", adapter_num);
1451 "Encode Device not present, using default");
1453 if (av_hwdevice_ctx_create(&hw_device_ctx,
1457 "FFmpegWriter::open_video ERROR creating hwdevice, Codec name:",
1472 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)
1473 video_codec_ctx->max_b_frames = 0;
1477 av_dict_set(&
opts,
"strict",
"experimental", 0);
1491 if (av_opt_get_int(video_codec_ctx->priv_data,
"qp", 0, &qp) != 0 || qp == 0) {
1493 av_opt_set(video_codec_ctx->priv_data,
"rc_mode",
"VBR", 0);
1497 video_codec_ctx->rc_max_rate = video_codec_ctx->bit_rate;
1501 switch (video_codec_ctx->codec_id) {
1502 case AV_CODEC_ID_H264:
1503 video_codec_ctx->max_b_frames = 0;
1504 video_codec_ctx->profile = FF_PROFILE_H264_BASELINE | FF_PROFILE_H264_CONSTRAINED;
1505 av_opt_set(video_codec_ctx->priv_data,
"preset",
"slow", 0);
1506 av_opt_set(video_codec_ctx->priv_data,
"tune",
"zerolatency", 0);
1507 av_opt_set(video_codec_ctx->priv_data,
"vprofile",
"baseline", AV_OPT_SEARCH_CHILDREN);
1509 case AV_CODEC_ID_HEVC:
1512 case AV_CODEC_ID_VP9:
1517 "No codec-specific options defined for this codec. HW encoding may fail",
1518 "codec_id", video_codec_ctx->codec_id);
1527 "FFmpegWriter::open_video (set_hwframe_ctx) ERROR faled to set hwframe context",
1530 av_err2string(err), -1);
1538 video_codec_ctx->codec_tag = MKTAG(
'h',
'v',
'c',
'1');
1541 if (video_codec_ctx->codec_id == AV_CODEC_ID_HEVC) {
1542 video_codec_ctx->codec_tag = MKTAG(
'h',
'v',
'c',
'1');
1548 throw InvalidCodec(
"Could not open video codec", path);
1552 av_dict_free(&
opts);
1556 av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1560 "FFmpegWriter::open_video",
1561 "video_codec_ctx->thread_count", video_codec_ctx->thread_count);
1566 void FFmpegWriter::write_audio_packets(
bool is_final, std::shared_ptr<openshot::Frame> frame) {
1567 if (!frame && !is_final)
1571 int total_frame_samples = 0;
1572 int frame_position = 0;
1573 int channels_in_frame = 0;
1574 int sample_rate_in_frame = 0;
1575 int samples_in_frame = 0;
1580 int16_t *all_queued_samples = (int16_t *) av_malloc(all_queued_samples_size);
1581 int16_t *all_resampled_samples = NULL;
1582 int16_t *final_samples_planar = NULL;
1583 int16_t *final_samples = NULL;
1586 float *frame_samples_float = NULL;
1590 sample_rate_in_frame = frame->SampleRate();
1591 samples_in_frame = frame->GetAudioSamplesCount();
1592 channels_in_frame = frame->GetAudioChannelsCount();
1593 channel_layout_in_frame = frame->ChannelsLayout();
1596 frame_samples_float = frame->GetInterleavedAudioSamples(&samples_in_frame);
1600 total_frame_samples = samples_in_frame * channels_in_frame;
1603 const int16_t max16 = 32767;
1604 const int16_t min16 = -32768;
1605 for (
int s = 0; s < total_frame_samples; s++, frame_position++) {
1606 float valF = frame_samples_float[s] * (1 << 15);
1610 }
else if (valF < min16) {
1613 conv = int(valF + 32768.5) - 32768;
1617 all_queued_samples[frame_position] = conv;
1621 delete[] frame_samples_float;
1625 total_frame_samples = frame_position;
1626 int remaining_frame_samples = total_frame_samples;
1627 int samples_position = 0;
1631 "FFmpegWriter::write_audio_packets",
1632 "is_final", is_final,
1633 "total_frame_samples", total_frame_samples,
1634 "channel_layout_in_frame", channel_layout_in_frame,
1635 "channels_in_frame", channels_in_frame,
1636 "samples_in_frame", samples_in_frame,
1640 AVSampleFormat output_sample_fmt = audio_codec_ctx->sample_fmt;
1642 AVFrame *audio_frame = NULL;
1647 audio_frame->nb_samples = total_frame_samples / channels_in_frame;
1650 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);
1651 if (error_code < 0) {
1653 "FFmpegWriter::write_audio_packets ERROR ["
1654 + av_err2string(error_code) +
"]",
1655 "error_code", error_code);
1659 switch (audio_codec_ctx->sample_fmt) {
1660 case AV_SAMPLE_FMT_FLTP: {
1661 output_sample_fmt = AV_SAMPLE_FMT_FLT;
1664 case AV_SAMPLE_FMT_S32P: {
1665 output_sample_fmt = AV_SAMPLE_FMT_S32;
1668 case AV_SAMPLE_FMT_S16P: {
1669 output_sample_fmt = AV_SAMPLE_FMT_S16;
1672 case AV_SAMPLE_FMT_U8P: {
1673 output_sample_fmt = AV_SAMPLE_FMT_U8;
1683 total_frame_samples *= (float(
info.
sample_rate) / sample_rate_in_frame);
1684 total_frame_samples *= (float(
info.
channels) / channels_in_frame);
1689 audio_converted->nb_samples = total_frame_samples / channels_in_frame;
1690 av_samples_alloc(audio_converted->data, audio_converted->linesize,
info.
channels, audio_converted->nb_samples, output_sample_fmt, 0);
1693 "FFmpegWriter::write_audio_packets (1st resampling)",
1694 "in_sample_fmt", AV_SAMPLE_FMT_S16,
1695 "out_sample_fmt", output_sample_fmt,
1696 "in_sample_rate", sample_rate_in_frame,
1698 "in_channels", channels_in_frame,
1705 AVChannelLayout in_chlayout;
1706 AVChannelLayout out_chlayout;
1707 av_channel_layout_from_mask(&in_chlayout, channel_layout_in_frame);
1709 av_opt_set_chlayout(avr,
"in_chlayout", &in_chlayout, 0);
1710 av_opt_set_chlayout(avr,
"out_chlayout", &out_chlayout, 0);
1712 av_opt_set_int(avr,
"in_channel_layout", channel_layout_in_frame, 0);
1714 av_opt_set_int(avr,
"in_channels", channels_in_frame, 0);
1717 av_opt_set_int(avr,
"in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
1718 av_opt_set_int(avr,
"out_sample_fmt", output_sample_fmt, 0);
1719 av_opt_set_int(avr,
"in_sample_rate", sample_rate_in_frame, 0);
1726 audio_converted->data,
1727 audio_converted->linesize[0],
1728 audio_converted->nb_samples,
1730 audio_frame->linesize[0],
1731 audio_frame->nb_samples
1735 remaining_frame_samples = total_frame_samples;
1738 all_resampled_samples = (int16_t *) av_malloc(
1740 * (av_get_bytes_per_sample(output_sample_fmt) /
1741 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1745 memcpy(all_resampled_samples, audio_converted->data[0],
1746 static_cast<size_t>(nb_samples)
1748 * av_get_bytes_per_sample(output_sample_fmt));
1751 av_freep(&(audio_frame->data[0]));
1753 av_freep(&audio_converted->data[0]);
1755 all_queued_samples = NULL;
1758 "FFmpegWriter::write_audio_packets (Successfully completed 1st resampling)",
1759 "nb_samples", nb_samples,
1760 "remaining_frame_samples", remaining_frame_samples);
1764 while (remaining_frame_samples > 0 || is_final) {
1766 int remaining_packet_samples = (audio_input_frame_size *
info.
channels) - audio_input_position;
1770 if (remaining_frame_samples >= remaining_packet_samples) {
1771 diff = remaining_packet_samples;
1773 diff = remaining_frame_samples;
1780 samples + (audio_input_position
1781 * (av_get_bytes_per_sample(output_sample_fmt) /
1782 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1784 all_resampled_samples + samples_position,
1785 static_cast<size_t>(diff)
1786 * av_get_bytes_per_sample(output_sample_fmt)
1790 audio_input_position += diff;
1791 samples_position += diff * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16));
1792 remaining_frame_samples -= diff;
1795 if (audio_input_position < (audio_input_frame_size *
info.
channels) && !is_final)
1802 if (av_sample_fmt_is_planar(audio_codec_ctx->sample_fmt)) {
1804 "FFmpegWriter::write_audio_packets (2nd resampling for Planar formats)",
1805 "in_sample_fmt", output_sample_fmt,
1806 "out_sample_fmt", audio_codec_ctx->sample_fmt,
1817 AVChannelLayout layout;
1819 av_opt_set_chlayout(avr_planar,
"in_chlayout", &layout, 0);
1820 av_opt_set_chlayout(avr_planar,
"out_chlayout", &layout, 0);
1824 av_opt_set_int(avr_planar,
"in_channels",
info.
channels, 0);
1825 av_opt_set_int(avr_planar,
"out_channels",
info.
channels, 0);
1827 av_opt_set_int(avr_planar,
"in_sample_fmt", output_sample_fmt, 0);
1828 av_opt_set_int(avr_planar,
"out_sample_fmt", audio_codec_ctx->sample_fmt, 0);
1837 audio_frame->nb_samples = audio_input_position /
info.
channels;
1840 final_samples_planar = (int16_t *) av_malloc(
1841 sizeof(int16_t) * audio_frame->nb_samples *
info.
channels
1842 * (av_get_bytes_per_sample(output_sample_fmt) /
1843 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1847 memcpy(final_samples_planar, samples,
1848 static_cast<size_t>(audio_frame->nb_samples)
1850 * av_get_bytes_per_sample(output_sample_fmt));
1853 avcodec_fill_audio_frame(audio_frame,
info.
channels, output_sample_fmt,
1854 (uint8_t *) final_samples_planar, audio_encoder_buffer_size, 0);
1857 frame_final->nb_samples = audio_input_frame_size;
1864 frame_final->format = audio_codec_ctx->sample_fmt;
1865 av_samples_alloc(frame_final->data, frame_final->linesize,
info.
channels,
1866 frame_final->nb_samples, audio_codec_ctx->sample_fmt, 0);
1872 frame_final->linesize[0],
1873 frame_final->nb_samples,
1875 audio_frame->linesize[0],
1876 audio_frame->nb_samples
1880 const auto copy_length =
static_cast<size_t>(nb_samples)
1881 * av_get_bytes_per_sample(audio_codec_ctx->sample_fmt)
1885 memcpy(samples, frame_final->data[0], copy_length);
1888 av_freep(&(audio_frame->data[0]));
1890 all_queued_samples = NULL;
1893 "FFmpegWriter::write_audio_packets (Successfully completed 2nd resampling for Planar formats)",
1894 "nb_samples", nb_samples);
1898 const auto buf_size =
static_cast<size_t>(audio_input_position)
1899 * (av_get_bytes_per_sample(audio_codec_ctx->sample_fmt) /
1900 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)
1902 final_samples =
reinterpret_cast<int16_t*
>(
1903 av_malloc(
sizeof(int16_t) * buf_size));
1906 memcpy(final_samples, samples,
1907 audio_input_position * av_get_bytes_per_sample(audio_codec_ctx->sample_fmt));
1910 frame_final->nb_samples = audio_input_frame_size;
1914 int nb_channels = audio_codec_ctx->ch_layout.nb_channels;
1916 int nb_channels = audio_codec_ctx->channels;
1918 avcodec_fill_audio_frame(frame_final, nb_channels,
1919 audio_codec_ctx->sample_fmt, (uint8_t *) final_samples,
1920 audio_encoder_buffer_size, 0);
1924 frame_final->pts = audio_timestamp;
1928 AVPacket* pkt = av_packet_alloc();
1931 av_init_packet(pkt);
1933 pkt->data = audio_encoder_buffer;
1934 pkt->size = audio_encoder_buffer_size;
1937 pkt->pts = pkt->dts = audio_timestamp;
1940 int got_packet_ptr = 0;
1946 int frame_finished = 0;
1947 error_code = ret = avcodec_send_frame(audio_codec_ctx, frame_final);
1948 if (ret < 0 && ret != AVERROR(EINVAL) && ret != AVERROR_EOF) {
1949 avcodec_send_frame(audio_codec_ctx, NULL);
1954 ret = avcodec_receive_packet(audio_codec_ctx, pkt);
1957 if(ret == AVERROR(EINVAL) || ret == AVERROR_EOF) {
1958 avcodec_flush_buffers(audio_codec_ctx);
1962 ret = frame_finished;
1965 if (!pkt->data && !frame_finished)
1969 got_packet_ptr = ret;
1972 int error_code = avcodec_encode_audio2(audio_codec_ctx, pkt, frame_final, &got_packet_ptr);
1975 if (error_code == 0 && got_packet_ptr) {
1979 pkt->pts = pkt->dts = audio_timestamp;
1982 av_packet_rescale_ts(pkt, audio_codec_ctx->time_base, audio_st->time_base);
1985 pkt->stream_index = audio_st->index;
1986 pkt->flags |= AV_PKT_FLAG_KEY;
1989 error_code = av_interleaved_write_frame(oc, pkt);
1992 if (error_code < 0) {
1994 "FFmpegWriter::write_audio_packets ERROR ["
1995 + av_err2string(error_code) +
"]",
1996 "error_code", error_code);
2000 audio_timestamp += FFMIN(audio_input_frame_size, audio_input_position);
2003 av_freep(&(frame_final->data[0]));
2010 audio_input_position = 0;
2015 if (all_resampled_samples) {
2016 av_freep(&all_resampled_samples);
2017 all_resampled_samples = NULL;
2019 if (all_queued_samples) {
2020 av_freep(&all_queued_samples);
2021 all_queued_samples = NULL;
2026 AVFrame *FFmpegWriter::allocate_avframe(
PixelFormat pix_fmt,
int width,
int height,
int *buffer_size, uint8_t *new_buffer) {
2028 AVFrame *new_av_frame = NULL;
2032 if (new_av_frame == NULL)
2033 throw OutOfMemory(
"Could not allocate AVFrame", path);
2041 new_buffer = (uint8_t *) av_malloc(*buffer_size *
sizeof(uint8_t));
2044 new_av_frame->width = width;
2045 new_av_frame->height = height;
2046 new_av_frame->format = pix_fmt;
2050 return new_av_frame;
2054 void FFmpegWriter::process_video_packet(std::shared_ptr<Frame> frame) {
2056 int src_w = frame->GetWidth();
2057 int src_h = frame->GetHeight();
2060 if (src_w == 1 && src_h == 1)
2064 const uchar* pixels = frame->GetPixels();
2065 if (!persistent_src_frame) {
2066 persistent_src_frame = av_frame_alloc();
2067 if (!persistent_src_frame)
2068 throw OutOfMemory(
"Could not allocate persistent_src_frame", path);
2069 persistent_src_frame->format = AV_PIX_FMT_RGBA;
2070 persistent_src_frame->width = src_w;
2071 persistent_src_frame->height = src_h;
2072 persistent_src_frame->linesize[0] = src_w * 4;
2074 persistent_src_frame->data[0] =
const_cast<uint8_t*
>(
2075 reinterpret_cast<const uint8_t*
>(pixels)
2079 if (!persistent_dst_frame) {
2080 persistent_dst_frame = av_frame_alloc();
2081 if (!persistent_dst_frame)
2082 throw OutOfMemory(
"Could not allocate persistent_dst_frame", path);
2085 AVPixelFormat dst_fmt = video_codec_ctx->pix_fmt;
2088 dst_fmt = AV_PIX_FMT_NV12;
2091 persistent_dst_frame->format = dst_fmt;
2092 persistent_dst_frame->width =
info.
width;
2095 persistent_dst_size = av_image_get_buffer_size(
2098 if (persistent_dst_size < 0)
2101 persistent_dst_buffer =
static_cast<uint8_t*
>(
2102 av_malloc(persistent_dst_size)
2104 if (!persistent_dst_buffer)
2105 throw OutOfMemory(
"Could not allocate persistent_dst_buffer", path);
2107 av_image_fill_arrays(
2108 persistent_dst_frame->data,
2109 persistent_dst_frame->linesize,
2110 persistent_dst_buffer,
2119 if (!img_convert_ctx) {
2120 int flags = SWS_FAST_BILINEAR;
2122 flags = SWS_BICUBIC;
2124 AVPixelFormat dst_fmt = video_codec_ctx->pix_fmt;
2127 dst_fmt = AV_PIX_FMT_NV12;
2130 img_convert_ctx = sws_getContext(
2131 src_w, src_h, AV_PIX_FMT_RGBA,
2133 flags, NULL, NULL, NULL
2135 if (!img_convert_ctx)
2142 persistent_src_frame->data,
2143 persistent_src_frame->linesize,
2145 persistent_dst_frame->data,
2146 persistent_dst_frame->linesize
2150 int bytes_final = 0;
2151 AVPixelFormat dst_fmt = video_codec_ctx->pix_fmt;
2154 dst_fmt = AV_PIX_FMT_NV12;
2158 AVFrame* new_frame = allocate_avframe(
2166 throw OutOfMemory(
"Could not allocate new_frame via allocate_avframe", path);
2171 persistent_dst_buffer,
2172 static_cast<size_t>(bytes_final)
2176 add_avframe(frame, new_frame);
2180 bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *frame_final) {
2181 #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
2184 "FFmpegWriter::write_video_packet",
2185 "frame->number", frame->number,
2186 "oc->oformat->flags", oc->oformat->flags);
2194 "FFmpegWriter::write_video_packet",
2195 "frame->number", frame->number,
2196 "oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE);
2198 if (oc->oformat->flags & AVFMT_RAWPICTURE) {
2202 AVPacket* pkt = av_packet_alloc();
2205 av_init_packet(pkt);
2208 av_packet_from_data(
2209 pkt, frame_final->data[0],
2210 frame_final->linesize[0] * frame_final->height);
2212 pkt->flags |= AV_PKT_FLAG_KEY;
2213 pkt->stream_index = video_st->index;
2216 pkt->pts = video_timestamp;
2219 int error_code = av_interleaved_write_frame(oc, pkt);
2220 if (error_code < 0) {
2222 "FFmpegWriter::write_video_packet ERROR ["
2223 + av_err2string(error_code) +
"]",
2224 "error_code", error_code);
2235 AVPacket* pkt = av_packet_alloc();
2238 av_init_packet(pkt);
2242 pkt->pts = pkt->dts = AV_NOPTS_VALUE;
2245 frame_final->pts = video_timestamp;
2248 if (!(
hw_frame = av_frame_alloc())) {
2249 std::clog <<
"Error code: av_hwframe_alloc\n";
2251 if (av_hwframe_get_buffer(video_codec_ctx->hw_frames_ctx,
hw_frame, 0) < 0) {
2252 std::clog <<
"Error code: av_hwframe_get_buffer\n";
2255 std::clog <<
"Error hw_frames_ctx.\n";
2257 hw_frame->format = AV_PIX_FMT_NV12;
2258 if ( av_hwframe_transfer_data(
hw_frame, frame_final, 0) < 0) {
2259 std::clog <<
"Error while transferring frame data to surface.\n";
2261 av_frame_copy_props(
hw_frame, frame_final);
2265 int got_packet_ptr = 0;
2273 ret = avcodec_send_frame(video_codec_ctx,
hw_frame);
2277 ret = avcodec_send_frame(video_codec_ctx, frame_final);
2282 "FFmpegWriter::write_video_packet (Frame not sent)");
2283 if (ret == AVERROR(EAGAIN) ) {
2284 std::clog <<
"Frame EAGAIN\n";
2286 if (ret == AVERROR_EOF ) {
2287 std::clog <<
"Frame AVERROR_EOF\n";
2289 avcodec_send_frame(video_codec_ctx, NULL);
2293 ret = avcodec_receive_packet(video_codec_ctx, pkt);
2295 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
2307 error_code = avcodec_encode_video2(video_codec_ctx, pkt, frame_final, &got_packet_ptr);
2308 if (error_code != 0) {
2310 "FFmpegWriter::write_video_packet ERROR ["
2311 + av_err2string(error_code) +
"]",
2312 "error_code", error_code);
2314 if (got_packet_ptr == 0) {
2316 "FFmpegWriter::write_video_packet (Frame gotpacket error)");
2321 if (error_code == 0 && got_packet_ptr) {
2323 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
2324 pkt->stream_index = video_st->index;
2327 int result = av_interleaved_write_frame(oc, pkt);
2330 "FFmpegWriter::write_video_packet ERROR ["
2331 + av_err2string(result) +
"]",
2350 video_timestamp += av_rescale_q(1, av_make_q(
info.
fps.
den,
info.
fps.
num), video_codec_ctx->time_base);
2359 av_dump_format(oc, 0, path.c_str(), 1);
2364 original_sample_rate = sample_rate;
2365 original_channels = channels;
2374 oc->strict_std_compliance = FF_COMPLIANCE_UNOFFICIAL;
2376 #if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 0, 0)
2378 int proj = av_spherical_from_name(projection.c_str());
2380 proj = AV_SPHERICAL_EQUIRECTANGULAR;
2384 AVSphericalMapping* map = av_spherical_alloc(&sd_size);
2388 map->projection =
static_cast<AVSphericalProjection
>(proj);
2390 map->yaw =
static_cast<int32_t
>(yaw_deg * (1 << 16));
2391 map->pitch =
static_cast<int32_t
>(pitch_deg * (1 << 16));
2392 map->roll =
static_cast<int32_t
>(roll_deg * (1 << 16));
2394 av_stream_add_side_data(video_st, AV_PKT_DATA_SPHERICAL,
reinterpret_cast<uint8_t*
>(map), sd_size);
Header file for all Exception classes.
Header file for FFmpegUtilities.
#define AV_FREE_CONTEXT(av_context)
#define AUDIO_PACKET_ENCODING_SIZE
#define AV_GET_CODEC_FROM_STREAM(av_stream, codec_in)
#define AV_SET_FILENAME(oc, f)
#define AV_FREE_FRAME(av_frame)
#define SWR_CONVERT(ctx, out, linesize, out_count, in, linesize2, in_count)
#define AV_GET_IMAGE_SIZE(pix_fmt, width, height)
#define AV_OPTION_FIND(priv_data, name)
#define AV_OUTPUT_CONTEXT(output_context, path)
#define AV_GET_CODEC_TYPE(av_stream)
#define ALLOC_CODEC_CTX(ctx, codec, stream)
#define AV_FIND_DECODER_CODEC_ID(av_stream)
#define AV_ALLOCATE_FRAME()
#define AV_GET_CODEC_PAR_CONTEXT(av_stream, av_codec)
#define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height)
#define AV_OPTION_SET(av_stream, priv_data, name, value, avcodec)
#define AV_FREE_PACKET(av_packet)
#define AVCODEC_MAX_AUDIO_FRAME_SIZE
#define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context)
#define MY_INPUT_BUFFER_PADDING_SIZE
#define AV_RESET_FRAME(av_frame)
AVPixelFormat hw_en_av_pix_fmt
AV_COPY_PARAMS_FROM_CONTEXT(st, video_codec_ctx)
AVHWDeviceType hw_en_av_device_type
Header file for FFmpegWriter class.
Header file for Frame class.
Header file for OpenMPUtilities (set some common macros)
#define FF_VIDEO_NUM_PROCESSORS
#define FF_AUDIO_NUM_PROCESSORS
Header file for global Settings class.
Header file for ZeroMQ-based Logger class.
Exception when encoding audio packet.
void Close()
Close the writer.
void SetAudioOptions(bool has_audio, std::string codec, int sample_rate, int channels, openshot::ChannelLayout channel_layout, int bit_rate)
Set audio export options.
void SetOption(openshot::StreamType stream, std::string name, std::string value)
Set custom options (some codecs accept additional params). This must be called after the PrepareStrea...
void PrepareStreams()
Prepare & initialize streams and open codecs. This method is called automatically by the Open() metho...
void SetVideoOptions(bool has_video, std::string codec, openshot::Fraction fps, int width, int height, openshot::Fraction pixel_ratio, bool interlaced, bool top_field_first, int bit_rate)
Set video export options.
void ResampleAudio(int sample_rate, int channels)
Set audio resample options.
void AddSphericalMetadata(const std::string &projection="equirectangular", float yaw_deg=0.0f, float pitch_deg=0.0f, float roll_deg=0.0f)
Add spherical (360°) video metadata to the video stream.
void WriteHeader()
Write the file header (after the options are set). This method is called automatically by the Open() ...
FFmpegWriter(const std::string &path)
Constructor for FFmpegWriter. Throws an exception on failure to open path.
static bool IsValidCodec(std::string codec_name)
Determine if codec name is valid.
void OutputStreamInfo()
Output the ffmpeg info about this format, streams, and codecs (i.e. dump format)
void WriteFrame(std::shared_ptr< openshot::Frame > frame)
Add a frame to the stack waiting to be encoded.
void WriteTrailer()
Write the file trailer (after all frames are written). This is called automatically by the Close() me...
This class represents a fraction.
int num
Numerator for the fraction.
void Reduce()
Reduce this fraction (i.e. 640/480 = 4/3)
int den
Denominator for the fraction.
Exception when an invalid # of audio channels are detected.
Exception when no valid codec is found for a file.
Exception for files that can not be found or opened.
Exception when invalid encoding options are used.
Exception when invalid sample rate is detected during encoding.
Exception when no streams are found in the file.
Exception when memory could not be allocated.
This abstract class is the base class, used by all readers in libopenshot.
virtual std::shared_ptr< openshot::Frame > GetFrame(int64_t number)=0
static Settings * Instance()
Create or get an instance of this logger singleton (invoke the class with this method)
int HW_EN_DEVICE_SET
Which GPU to use to encode (0 is the first)
WriterInfo info
Information about the current media file.
Exception when a writer is closed, and a frame is requested.
void AppendDebugMethod(std::string method_name, std::string arg1_name="", float arg1_value=-1.0, std::string arg2_name="", float arg2_value=-1.0, std::string arg3_name="", float arg3_value=-1.0, std::string arg4_name="", float arg4_value=-1.0, std::string arg5_name="", float arg5_value=-1.0, std::string arg6_name="", float arg6_value=-1.0)
Append debug information.
static ZmqLogger * Instance()
Create or get an instance of this logger singleton (invoke the class with this method)
This namespace is the default namespace for all code in the openshot library.
ChannelLayout
This enumeration determines the audio channel layout (such as stereo, mono, 5 point surround,...
StreamType
This enumeration designates the type of stream when encoding (video or audio)
@ AUDIO_STREAM
An audio stream (used to determine which type of stream)
@ VIDEO_STREAM
A video stream (used to determine which type of stream)
int height
The height of the video (in pixels)
int audio_bit_rate
The bit rate of the audio stream (in bytes)
int video_bit_rate
The bit rate of the video stream (in bytes)
bool has_audio
Determines if this file has an audio stream.
bool top_field_first
Which interlaced field should be displayed first.
int channels
The number of audio channels used in the audio stream.
std::string vcodec
The name of the video codec used to encode / decode the video stream.
bool has_video
Determines if this file has a video stream.
std::map< std::string, std::string > metadata
An optional map/dictionary of video & audio metadata.
openshot::Fraction fps
Frames per second, as a fraction (i.e. 24/1 = 24 fps)
std::string acodec
The name of the audio codec used to encode / decode the video stream.
openshot::Fraction video_timebase
The video timebase determines how long each frame stays on the screen.
openshot::ChannelLayout channel_layout
The channel layout (mono, stereo, 5 point surround, etc...)
openshot::Fraction display_ratio
The ratio of width to height of the video stream (i.e. 640x480 has a ratio of 4/3)
int width
The width of the video (in pixels)
openshot::Fraction pixel_ratio
The pixel ratio of the video stream as a fraction (i.e. some pixels are not square)
int sample_rate
The number of audio samples per second (44100 is a common sample rate)
bool interlaced_frame
Are the contents of this frame interlaced.