42static AVBufferRef *hw_device_ctx = NULL;
45static 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), 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);
118void 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();
145void 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());
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" || 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);
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);
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);
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);
690void FFmpegWriter::write_frame(std::shared_ptr<Frame> frame) {
695 bool has_error_encoding_video =
false;
699 write_audio_packets(
false, frame);
703 process_video_packet(frame);
707 if (av_frames.count(frame)) {
709 AVFrame *frame_final = av_frames[frame];
712 if (!write_video_packet(frame, frame_final)) {
713 has_error_encoding_video =
true;
717 av_freep(&(frame_final->data[0]));
719 av_frames.erase(frame);
727 if (has_error_encoding_video)
734 "FFmpegWriter::WriteFrame (from Reader)",
739 for (int64_t number = start; number <= length; number++) {
741 std::shared_ptr<Frame> f = reader->
GetFrame(number);
752 write_audio_packets(
true, NULL);
761 av_write_trailer(oc);
764 write_trailer =
true;
770void FFmpegWriter::flush_encoders() {
773#if (LIBAVFORMAT_VERSION_MAJOR < 58)
787 video_timestamp += av_rescale_q(1, av_make_q(
info.
fps.
den,
info.
fps.
num), video_codec_ctx->time_base);
790 AVPacket* pkt = av_packet_alloc();
804 error_code = avcodec_send_frame(video_codec_ctx, NULL);
806 while (error_code >= 0) {
807 error_code = avcodec_receive_packet(video_codec_ctx, pkt);
808 if (error_code == AVERROR(EAGAIN)|| error_code == AVERROR_EOF) {
811 avcodec_flush_buffers(video_codec_ctx);
814 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
815 pkt->stream_index = video_st->index;
816 error_code = av_interleaved_write_frame(oc, pkt);
821 error_code = avcodec_encode_video2(video_codec_ctx, pkt, NULL, &got_packet);
825 if (error_code < 0) {
827 "FFmpegWriter::flush_encoders ERROR ["
828 + av_err2string(error_code) +
"]",
829 "error_code", error_code);
836 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
837 pkt->stream_index = video_st->index;
840 error_code = av_interleaved_write_frame(oc, pkt);
841 if (error_code < 0) {
843 "FFmpegWriter::flush_encoders ERROR ["
844 + av_err2string(error_code) +
"]",
845 "error_code", error_code);
854 AVPacket* pkt = av_packet_alloc();
861 pkt->pts = pkt->dts = audio_timestamp;
867 error_code = avcodec_send_frame(audio_codec_ctx, NULL);
869 error_code = avcodec_encode_audio2(audio_codec_ctx, pkt, NULL, &got_packet);
871 if (error_code < 0) {
873 "FFmpegWriter::flush_encoders ERROR ["
874 + av_err2string(error_code) +
"]",
875 "error_code", error_code);
883 pkt->pts = pkt->dts = audio_timestamp;
886 av_packet_rescale_ts(pkt, audio_codec_ctx->time_base, audio_st->time_base);
889 pkt->stream_index = audio_st->index;
890 pkt->flags |= AV_PKT_FLAG_KEY;
893 error_code = av_interleaved_write_frame(oc, pkt);
894 if (error_code < 0) {
896 "FFmpegWriter::flush_encoders ERROR ["
897 + av_err2string(error_code) +
"]",
898 "error_code", error_code);
902 audio_timestamp += pkt->duration;
912void FFmpegWriter::close_video(AVFormatContext *oc, AVStream *st)
917 av_buffer_unref(&hw_device_ctx);
918 hw_device_ctx = NULL;
924 if (video_codec_ctx !=
nullptr) {
926 av_free(video_codec_ctx);
931void FFmpegWriter::close_audio(AVFormatContext *oc, AVStream *st)
935 delete[] audio_outbuf;
936 delete[] audio_encoder_buffer;
939 audio_encoder_buffer = NULL;
955 if (audio_codec_ctx !=
nullptr) {
957 av_free(audio_codec_ctx);
969 close_video(oc, video_st);
971 close_audio(oc, audio_st);
975 sws_freeContext(img_convert_ctx);
977 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
987 avformat_free_context(oc);
992 prepare_streams =
false;
993 write_header =
false;
994 write_trailer =
false;
1000void FFmpegWriter::add_avframe(std::shared_ptr<Frame> frame, AVFrame *av_frame) {
1002 if (!av_frames.count(frame)) {
1004 av_frames[frame] = av_frame;
1012AVStream *FFmpegWriter::add_audio_stream() {
1014 const AVCodec *
codec = avcodec_find_encoder_by_name(
info.
acodec.c_str());
1016 throw InvalidCodec(
"A valid audio codec could not be found for this file.", path);
1019 if (audio_codec_ctx !=
nullptr) {
1024 AVStream* st = avformat_new_stream(oc,
codec);
1026 throw OutOfMemory(
"Could not allocate memory for the audio stream.", path);
1030#if (LIBAVFORMAT_VERSION_MAJOR >= 58)
1031 st->codecpar->codec_id =
codec->id;
1033 AVCodecContext* c = audio_codec_ctx;
1035 c->codec_id =
codec->id;
1036 c->codec_type = AVMEDIA_TYPE_AUDIO;
1045 if (
codec->supported_samplerates) {
1047 for (i = 0;
codec->supported_samplerates[i] != 0; i++)
1053 if (
codec->supported_samplerates[i] == 0)
1054 throw InvalidSampleRate(
"An invalid sample rate was detected for this codec.", path);
1062 AVChannelLayout ch_layout;
1064 if (
codec->ch_layouts) {
1066 for (i = 0; av_channel_layout_check(&
codec->ch_layouts[i]); i++)
1067 if (av_channel_layout_compare(&ch_layout, &
codec->ch_layouts[i])) {
1069 av_channel_layout_copy(&c->ch_layout, &ch_layout);
1072 if (!av_channel_layout_check(&
codec->ch_layouts[i]))
1073 throw InvalidChannels(
"An invalid channel layout was detected (i.e. MONO / STEREO).", path);
1076 av_channel_layout_copy(&c->ch_layout, &ch_layout);
1079 if (
codec->channel_layouts) {
1081 for (i = 0;
codec->channel_layouts[i] != 0; i++)
1082 if (channel_layout ==
codec->channel_layouts[i]) {
1084 c->channel_layout = channel_layout;
1087 if (
codec->channel_layouts[i] == 0)
1088 throw InvalidChannels(
"An invalid channel layout was detected (i.e. MONO / STEREO).", path);
1091 c->channel_layout = channel_layout;
1095 if (
codec->sample_fmts) {
1096 for (
int i = 0;
codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) {
1098 c->sample_fmt =
codec->sample_fmts[i];
1102 if (c->sample_fmt == AV_SAMPLE_FMT_NONE) {
1104 c->sample_fmt = AV_SAMPLE_FMT_S16;
1108 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1109#if (LIBAVCODEC_VERSION_MAJOR >= 57)
1111 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1113 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1119 const char* nb_channels_label;
1120 const char* channel_layout_label;
1123 nb_channels = c->ch_layout.nb_channels;
1124 channel_layout = c->ch_layout.u.mask;
1125 nb_channels_label =
"c->ch_layout.nb_channels";
1126 channel_layout_label =
"c->ch_layout.u.mask";
1128 nb_channels = c->channels;
1129 nb_channels_label =
"c->channels";
1130 channel_layout_label =
"c->channel_layout";
1134 "FFmpegWriter::add_audio_stream",
1135 "c->codec_id", c->codec_id,
1136 "c->bit_rate", c->bit_rate,
1137 nb_channels_label, nb_channels,
1138 "c->sample_fmt", c->sample_fmt,
1139 channel_layout_label, channel_layout,
1140 "c->sample_rate", c->sample_rate);
1146AVStream *FFmpegWriter::add_video_stream() {
1148 const AVCodec *
codec = avcodec_find_encoder_by_name(
info.
vcodec.c_str());
1150 throw InvalidCodec(
"A valid video codec could not be found for this file.", path);
1153 if (video_codec_ctx !=
nullptr) {
1158 AVStream* st = avformat_new_stream(oc,
codec);
1160 throw OutOfMemory(
"Could not allocate memory for the video stream.", path);
1164#if (LIBAVFORMAT_VERSION_MAJOR >= 58)
1165 st->codecpar->codec_id =
codec->id;
1168 AVCodecContext* c = video_codec_ctx;
1170 c->codec_id =
codec->id;
1171 c->codec_type = AVMEDIA_TYPE_VIDEO;
1179#
if (LIBAVCODEC_VERSION_MAJOR >= 58)
1180 && c->codec_id != AV_CODEC_ID_AV1
1185 if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
1194 switch (c->codec_id) {
1195#if (LIBAVCODEC_VERSION_MAJOR >= 58)
1197 case AV_CODEC_ID_AV1 :
1201 if (strstr(
info.
vcodec.c_str(),
"aom") != NULL) {
1202 int calculated_quality = 35;
1205 av_opt_set_int(c->priv_data,
"crf", calculated_quality, 0);
1208 int calculated_quality = 50;
1211 av_opt_set_int(c->priv_data,
"qp", calculated_quality, 0);
1215 if (strstr(
info.
vcodec.c_str(),
"svtav1") != NULL) {
1216 av_opt_set_int(c->priv_data,
"preset", 6, 0);
1217 av_opt_set_int(c->priv_data,
"forced-idr",1,0);
1219 else if (strstr(
info.
vcodec.c_str(),
"rav1e") != NULL) {
1220 av_opt_set_int(c->priv_data,
"speed", 7, 0);
1221 av_opt_set_int(c->priv_data,
"tile-rows", 2, 0);
1222 av_opt_set_int(c->priv_data,
"tile-columns", 4, 0);
1224 else if (strstr(
info.
vcodec.c_str(),
"aom") != NULL) {
1227 av_opt_set_int(c->priv_data,
"tile-rows", 1, 0);
1228 av_opt_set_int(c->priv_data,
"tile-columns", 2, 0);
1229 av_opt_set_int(c->priv_data,
"row-mt", 1, 0);
1230 av_opt_set_int(c->priv_data,
"cpu-used", 3, 0);
1234 case AV_CODEC_ID_VP9 :
1235 case AV_CODEC_ID_HEVC :
1236 case AV_CODEC_ID_VP8 :
1237 case AV_CODEC_ID_H264 :
1273#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 26, 0)
1274 c->framerate = av_inv_q(c->time_base);
1276 st->avg_frame_rate = av_inv_q(c->time_base);
1281 c->max_b_frames = 10;
1282 if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO)
1284 c->max_b_frames = 2;
1285 if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO)
1291 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1292#if (LIBAVCODEC_VERSION_MAJOR >= 57)
1294 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1296 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1301 while (supported_pixel_formats != NULL && *supported_pixel_formats !=
PIX_FMT_NONE) {
1304 c->pix_fmt = *supported_pixel_formats;
1305 ++supported_pixel_formats;
1310 if (oc->oformat->video_codec == AV_CODEC_ID_RAWVIDEO) {
1314#if (LIBAVFORMAT_VERSION_MAJOR < 58)
1316 if (strcmp(oc->oformat->name,
"gif") != 0)
1319 oc->oformat->flags |= AVFMT_RAWPICTURE;
1329 "FFmpegWriter::add_video_stream ("
1330 + (std::string)oc->oformat->name +
" : "
1331 + (std::string)av_get_pix_fmt_name(c->pix_fmt) +
")",
1332 "c->codec_id", c->codec_id,
1333 "c->bit_rate", c->bit_rate,
1334 "c->pix_fmt", c->pix_fmt,
1335 "oc->oformat->flags", oc->oformat->flags);
1340void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st) {
1341 const AVCodec *
codec;
1350 codec = avcodec_find_encoder(audio_codec_ctx->codec_id);
1355 AVDictionary *
opts = NULL;
1356 av_dict_set(&
opts,
"strict",
"experimental", 0);
1359 if (avcodec_open2(audio_codec_ctx,
codec, &
opts) < 0)
1360 throw InvalidCodec(
"Could not open audio codec", path);
1364 av_dict_free(&
opts);
1368 if (audio_codec_ctx->frame_size <= 1) {
1374 case AV_CODEC_ID_PCM_S16LE:
1375 case AV_CODEC_ID_PCM_S16BE:
1376 case AV_CODEC_ID_PCM_U16LE:
1377 case AV_CODEC_ID_PCM_U16BE:
1378 audio_input_frame_size >>= 1;
1385 audio_input_frame_size = audio_codec_ctx->frame_size;
1389 initial_audio_input_frame_size = audio_input_frame_size;
1396 audio_outbuf =
new uint8_t[audio_outbuf_size];
1400 audio_encoder_buffer =
new uint8_t[audio_encoder_buffer_size];
1403 for (std::map<std::string, std::string>::iterator iter =
info.
metadata.begin(); iter !=
info.
metadata.end(); ++iter) {
1404 av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1408 "FFmpegWriter::open_audio",
1409 "audio_codec_ctx->thread_count", audio_codec_ctx->thread_count,
1410 "audio_input_frame_size", audio_input_frame_size,
1415void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) {
1416 const AVCodec *
codec;
1426 char *adapter_ptr = NULL;
1430 std::clog <<
"Encoding Device Nr: " << adapter_num <<
"\n";
1431 if (adapter_num < 3 && adapter_num >=0) {
1432#if defined(__linux__)
1433 snprintf(adapter,
sizeof(adapter),
"/dev/dri/renderD%d", adapter_num+128);
1435 adapter_ptr = adapter;
1436#elif defined(_WIN32) || defined(__APPLE__)
1444#if defined(__linux__)
1445 if( adapter_ptr != NULL && access( adapter_ptr, W_OK ) == 0 ) {
1446#elif defined(_WIN32) || defined(__APPLE__)
1447 if( adapter_ptr != NULL ) {
1450 "Encode Device present using device",
1451 "adapter", adapter_num);
1456 "Encode Device not present, using default");
1458 if (av_hwdevice_ctx_create(&hw_device_ctx,
1462 "FFmpegWriter::open_video ERROR creating hwdevice, Codec name:",
1478 if (!allow_b_frames && video_codec_ctx->max_b_frames &&
1479 video_codec_ctx->codec_id != AV_CODEC_ID_MPEG4 &&
1480 video_codec_ctx->codec_id != AV_CODEC_ID_MPEG1VIDEO &&
1481 video_codec_ctx->codec_id != AV_CODEC_ID_MPEG2VIDEO)
1482 video_codec_ctx->max_b_frames = 0;
1486 av_dict_set(&
opts,
"strict",
"experimental", 0);
1500 if (av_opt_get_int(video_codec_ctx->priv_data,
"qp", 0, &qp) != 0 || qp == 0) {
1502 av_opt_set(video_codec_ctx->priv_data,
"rc_mode",
"VBR", 0);
1506 video_codec_ctx->rc_max_rate = video_codec_ctx->bit_rate;
1510 switch (video_codec_ctx->codec_id) {
1511 case AV_CODEC_ID_H264:
1512 video_codec_ctx->max_b_frames = 0;
1513 video_codec_ctx->profile = FF_PROFILE_H264_BASELINE | FF_PROFILE_H264_CONSTRAINED;
1514 av_opt_set(video_codec_ctx->priv_data,
"preset",
"slow", 0);
1515 av_opt_set(video_codec_ctx->priv_data,
"tune",
"zerolatency", 0);
1516 av_opt_set(video_codec_ctx->priv_data,
"vprofile",
"baseline", AV_OPT_SEARCH_CHILDREN);
1518 case AV_CODEC_ID_HEVC:
1521 case AV_CODEC_ID_VP9:
1526 "No codec-specific options defined for this codec. HW encoding may fail",
1527 "codec_id", video_codec_ctx->codec_id);
1536 "FFmpegWriter::open_video (set_hwframe_ctx) ERROR faled to set hwframe context",
1539 av_err2string(err), -1);
1547 video_codec_ctx->codec_tag = MKTAG(
'h',
'v',
'c',
'1');
1550 if (video_codec_ctx->codec_id == AV_CODEC_ID_HEVC) {
1551 video_codec_ctx->codec_tag = MKTAG(
'h',
'v',
'c',
'1');
1557 throw InvalidCodec(
"Could not open video codec", path);
1561 av_dict_free(&
opts);
1565 av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1569 "FFmpegWriter::open_video",
1570 "video_codec_ctx->thread_count", video_codec_ctx->thread_count);
1575void FFmpegWriter::write_audio_packets(
bool is_final, std::shared_ptr<openshot::Frame> frame) {
1576 if (!frame && !is_final)
1580 int total_frame_samples = 0;
1581 int frame_position = 0;
1582 int channels_in_frame = 0;
1583 int sample_rate_in_frame = 0;
1584 int samples_in_frame = 0;
1589 int16_t *all_queued_samples = (int16_t *) av_malloc(all_queued_samples_size);
1590 int16_t *all_resampled_samples = NULL;
1591 int16_t *final_samples_planar = NULL;
1592 int16_t *final_samples = NULL;
1595 float *frame_samples_float = NULL;
1599 sample_rate_in_frame = frame->SampleRate();
1600 samples_in_frame = frame->GetAudioSamplesCount();
1601 channels_in_frame = frame->GetAudioChannelsCount();
1602 channel_layout_in_frame = frame->ChannelsLayout();
1605 frame_samples_float = frame->GetInterleavedAudioSamples(&samples_in_frame);
1609 total_frame_samples = samples_in_frame * channels_in_frame;
1612 const int16_t max16 = 32767;
1613 const int16_t min16 = -32768;
1614 for (
int s = 0; s < total_frame_samples; s++, frame_position++) {
1615 float valF = frame_samples_float[s] * (1 << 15);
1619 }
else if (valF < min16) {
1622 conv = int(valF + 32768.5) - 32768;
1626 all_queued_samples[frame_position] = conv;
1630 delete[] frame_samples_float;
1634 total_frame_samples = frame_position;
1635 int remaining_frame_samples = total_frame_samples;
1636 int samples_position = 0;
1640 "FFmpegWriter::write_audio_packets",
1641 "is_final", is_final,
1642 "total_frame_samples", total_frame_samples,
1643 "channel_layout_in_frame", channel_layout_in_frame,
1644 "channels_in_frame", channels_in_frame,
1645 "samples_in_frame", samples_in_frame,
1649 AVSampleFormat output_sample_fmt = audio_codec_ctx->sample_fmt;
1651 AVFrame *audio_frame = NULL;
1656 audio_frame->nb_samples = total_frame_samples / channels_in_frame;
1659 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);
1660 if (error_code < 0) {
1662 "FFmpegWriter::write_audio_packets ERROR ["
1663 + av_err2string(error_code) +
"]",
1664 "error_code", error_code);
1668 switch (audio_codec_ctx->sample_fmt) {
1669 case AV_SAMPLE_FMT_FLTP: {
1670 output_sample_fmt = AV_SAMPLE_FMT_FLT;
1673 case AV_SAMPLE_FMT_S32P: {
1674 output_sample_fmt = AV_SAMPLE_FMT_S32;
1677 case AV_SAMPLE_FMT_S16P: {
1678 output_sample_fmt = AV_SAMPLE_FMT_S16;
1681 case AV_SAMPLE_FMT_U8P: {
1682 output_sample_fmt = AV_SAMPLE_FMT_U8;
1692 total_frame_samples *= (float(
info.
sample_rate) / sample_rate_in_frame);
1693 total_frame_samples *= (float(
info.
channels) / channels_in_frame);
1698 audio_converted->nb_samples = total_frame_samples / channels_in_frame;
1699 av_samples_alloc(audio_converted->data, audio_converted->linesize,
info.
channels, audio_converted->nb_samples, output_sample_fmt, 0);
1702 "FFmpegWriter::write_audio_packets (1st resampling)",
1703 "in_sample_fmt", AV_SAMPLE_FMT_S16,
1704 "out_sample_fmt", output_sample_fmt,
1705 "in_sample_rate", sample_rate_in_frame,
1707 "in_channels", channels_in_frame,
1714 AVChannelLayout in_chlayout;
1715 AVChannelLayout out_chlayout;
1716 av_channel_layout_from_mask(&in_chlayout, channel_layout_in_frame);
1718 av_opt_set_chlayout(avr,
"in_chlayout", &in_chlayout, 0);
1719 av_opt_set_chlayout(avr,
"out_chlayout", &out_chlayout, 0);
1721 av_opt_set_int(avr,
"in_channel_layout", channel_layout_in_frame, 0);
1723 av_opt_set_int(avr,
"in_channels", channels_in_frame, 0);
1726 av_opt_set_int(avr,
"in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
1727 av_opt_set_int(avr,
"out_sample_fmt", output_sample_fmt, 0);
1728 av_opt_set_int(avr,
"in_sample_rate", sample_rate_in_frame, 0);
1735 audio_converted->data,
1736 audio_converted->linesize[0],
1737 audio_converted->nb_samples,
1739 audio_frame->linesize[0],
1740 audio_frame->nb_samples
1744 remaining_frame_samples = total_frame_samples;
1747 all_resampled_samples = (int16_t *) av_malloc(
1749 * (av_get_bytes_per_sample(output_sample_fmt) /
1750 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1754 memcpy(all_resampled_samples, audio_converted->data[0],
1755 static_cast<size_t>(nb_samples)
1757 * av_get_bytes_per_sample(output_sample_fmt));
1760 av_freep(&(audio_frame->data[0]));
1762 av_freep(&audio_converted->data[0]);
1764 all_queued_samples = NULL;
1767 "FFmpegWriter::write_audio_packets (Successfully completed 1st resampling)",
1768 "nb_samples", nb_samples,
1769 "remaining_frame_samples", remaining_frame_samples);
1773 while (remaining_frame_samples > 0 || is_final) {
1775 int remaining_packet_samples = (audio_input_frame_size *
info.
channels) - audio_input_position;
1779 if (remaining_frame_samples >= remaining_packet_samples) {
1780 diff = remaining_packet_samples;
1782 diff = remaining_frame_samples;
1789 samples + (audio_input_position
1790 * (av_get_bytes_per_sample(output_sample_fmt) /
1791 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1793 all_resampled_samples + samples_position,
1794 static_cast<size_t>(diff)
1795 * av_get_bytes_per_sample(output_sample_fmt)
1799 audio_input_position += diff;
1800 samples_position += diff * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16));
1801 remaining_frame_samples -= diff;
1804 if (audio_input_position < (audio_input_frame_size *
info.
channels) && !is_final)
1811 if (av_sample_fmt_is_planar(audio_codec_ctx->sample_fmt)) {
1813 "FFmpegWriter::write_audio_packets (2nd resampling for Planar formats)",
1814 "in_sample_fmt", output_sample_fmt,
1815 "out_sample_fmt", audio_codec_ctx->sample_fmt,
1826 AVChannelLayout layout;
1828 av_opt_set_chlayout(avr_planar,
"in_chlayout", &layout, 0);
1829 av_opt_set_chlayout(avr_planar,
"out_chlayout", &layout, 0);
1833 av_opt_set_int(avr_planar,
"in_channels",
info.
channels, 0);
1834 av_opt_set_int(avr_planar,
"out_channels",
info.
channels, 0);
1836 av_opt_set_int(avr_planar,
"in_sample_fmt", output_sample_fmt, 0);
1837 av_opt_set_int(avr_planar,
"out_sample_fmt", audio_codec_ctx->sample_fmt, 0);
1846 audio_frame->nb_samples = audio_input_position /
info.
channels;
1849 final_samples_planar = (int16_t *) av_malloc(
1850 sizeof(int16_t) * audio_frame->nb_samples *
info.
channels
1851 * (av_get_bytes_per_sample(output_sample_fmt) /
1852 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1856 memcpy(final_samples_planar, samples,
1857 static_cast<size_t>(audio_frame->nb_samples)
1859 * av_get_bytes_per_sample(output_sample_fmt));
1862 avcodec_fill_audio_frame(audio_frame,
info.
channels, output_sample_fmt,
1863 (uint8_t *) final_samples_planar, audio_encoder_buffer_size, 0);
1866 frame_final->nb_samples = audio_input_frame_size;
1873 frame_final->format = audio_codec_ctx->sample_fmt;
1874 av_samples_alloc(frame_final->data, frame_final->linesize,
info.
channels,
1875 frame_final->nb_samples, audio_codec_ctx->sample_fmt, 0);
1881 frame_final->linesize[0],
1882 frame_final->nb_samples,
1884 audio_frame->linesize[0],
1885 audio_frame->nb_samples
1889 const auto copy_length =
static_cast<size_t>(nb_samples)
1890 * av_get_bytes_per_sample(audio_codec_ctx->sample_fmt)
1894 memcpy(samples, frame_final->data[0], copy_length);
1897 av_freep(&(audio_frame->data[0]));
1899 all_queued_samples = NULL;
1902 "FFmpegWriter::write_audio_packets (Successfully completed 2nd resampling for Planar formats)",
1903 "nb_samples", nb_samples);
1907 const auto buf_size =
static_cast<size_t>(audio_input_position)
1908 * (av_get_bytes_per_sample(audio_codec_ctx->sample_fmt) /
1909 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)
1911 final_samples =
reinterpret_cast<int16_t*
>(
1912 av_malloc(
sizeof(int16_t) * buf_size));
1915 memcpy(final_samples, samples,
1916 audio_input_position * av_get_bytes_per_sample(audio_codec_ctx->sample_fmt));
1919 frame_final->nb_samples = audio_input_frame_size;
1923 int nb_channels = audio_codec_ctx->ch_layout.nb_channels;
1925 int nb_channels = audio_codec_ctx->channels;
1927 avcodec_fill_audio_frame(frame_final, nb_channels,
1928 audio_codec_ctx->sample_fmt, (uint8_t *) final_samples,
1929 audio_encoder_buffer_size, 0);
1933 frame_final->pts = audio_timestamp;
1937 AVPacket* pkt = av_packet_alloc();
1940 av_init_packet(pkt);
1942 pkt->data = audio_encoder_buffer;
1943 pkt->size = audio_encoder_buffer_size;
1946 pkt->pts = pkt->dts = audio_timestamp;
1949 int got_packet_ptr = 0;
1955 int frame_finished = 0;
1956 error_code = ret = avcodec_send_frame(audio_codec_ctx, frame_final);
1957 if (ret < 0 && ret != AVERROR(EINVAL) && ret != AVERROR_EOF) {
1958 avcodec_send_frame(audio_codec_ctx, NULL);
1963 ret = avcodec_receive_packet(audio_codec_ctx, pkt);
1966 if(ret == AVERROR(EINVAL) || ret == AVERROR_EOF) {
1967 avcodec_flush_buffers(audio_codec_ctx);
1971 ret = frame_finished;
1974 if (!pkt->data && !frame_finished)
1978 got_packet_ptr = ret;
1981 int error_code = avcodec_encode_audio2(audio_codec_ctx, pkt, frame_final, &got_packet_ptr);
1984 if (error_code == 0 && got_packet_ptr) {
1988 pkt->pts = pkt->dts = audio_timestamp;
1991 av_packet_rescale_ts(pkt, audio_codec_ctx->time_base, audio_st->time_base);
1994 pkt->stream_index = audio_st->index;
1995 pkt->flags |= AV_PKT_FLAG_KEY;
1998 error_code = av_interleaved_write_frame(oc, pkt);
2001 if (error_code < 0) {
2003 "FFmpegWriter::write_audio_packets ERROR ["
2004 + av_err2string(error_code) +
"]",
2005 "error_code", error_code);
2009 audio_timestamp += FFMIN(audio_input_frame_size, audio_input_position);
2012 av_freep(&(frame_final->data[0]));
2019 audio_input_position = 0;
2024 if (all_resampled_samples) {
2025 av_freep(&all_resampled_samples);
2026 all_resampled_samples = NULL;
2028 if (all_queued_samples) {
2029 av_freep(&all_queued_samples);
2030 all_queued_samples = NULL;
2035AVFrame *FFmpegWriter::allocate_avframe(
PixelFormat pix_fmt,
int width,
int height,
int *buffer_size, uint8_t *new_buffer) {
2037 AVFrame *new_av_frame = NULL;
2041 if (new_av_frame == NULL)
2042 throw OutOfMemory(
"Could not allocate AVFrame", path);
2050 new_buffer = (uint8_t *) av_malloc(*buffer_size *
sizeof(uint8_t));
2053 new_av_frame->width = width;
2054 new_av_frame->height = height;
2055 new_av_frame->format = pix_fmt;
2059 return new_av_frame;
2063void FFmpegWriter::process_video_packet(std::shared_ptr<Frame> frame) {
2065 int src_w = frame->GetWidth();
2066 int src_h = frame->GetHeight();
2069 if (src_w == 1 && src_h == 1)
2073 const uchar* pixels = frame->GetPixels();
2074 if (!persistent_src_frame) {
2075 persistent_src_frame = av_frame_alloc();
2076 if (!persistent_src_frame)
2077 throw OutOfMemory(
"Could not allocate persistent_src_frame", path);
2078 persistent_src_frame->format = AV_PIX_FMT_RGBA;
2079 persistent_src_frame->width = src_w;
2080 persistent_src_frame->height = src_h;
2081 persistent_src_frame->linesize[0] = src_w * 4;
2083 persistent_src_frame->data[0] =
const_cast<uint8_t*
>(
2084 reinterpret_cast<const uint8_t*
>(pixels)
2088 if (!persistent_dst_frame) {
2089 persistent_dst_frame = av_frame_alloc();
2090 if (!persistent_dst_frame)
2091 throw OutOfMemory(
"Could not allocate persistent_dst_frame", path);
2094 AVPixelFormat dst_fmt = video_codec_ctx->pix_fmt;
2097 dst_fmt = AV_PIX_FMT_NV12;
2100 persistent_dst_frame->format = dst_fmt;
2101 persistent_dst_frame->width =
info.
width;
2104 persistent_dst_size = av_image_get_buffer_size(
2107 if (persistent_dst_size < 0)
2110 persistent_dst_buffer =
static_cast<uint8_t*
>(
2111 av_malloc(persistent_dst_size)
2113 if (!persistent_dst_buffer)
2114 throw OutOfMemory(
"Could not allocate persistent_dst_buffer", path);
2116 av_image_fill_arrays(
2117 persistent_dst_frame->data,
2118 persistent_dst_frame->linesize,
2119 persistent_dst_buffer,
2128 if (!img_convert_ctx) {
2129 int flags = SWS_FAST_BILINEAR;
2131 flags = SWS_BICUBIC;
2133 AVPixelFormat dst_fmt = video_codec_ctx->pix_fmt;
2136 dst_fmt = AV_PIX_FMT_NV12;
2139 img_convert_ctx = sws_getContext(
2140 src_w, src_h, AV_PIX_FMT_RGBA,
2142 flags, NULL, NULL, NULL
2144 if (!img_convert_ctx)
2151 persistent_src_frame->data,
2152 persistent_src_frame->linesize,
2154 persistent_dst_frame->data,
2155 persistent_dst_frame->linesize
2159 int bytes_final = 0;
2160 AVPixelFormat dst_fmt = video_codec_ctx->pix_fmt;
2163 dst_fmt = AV_PIX_FMT_NV12;
2167 AVFrame* new_frame = allocate_avframe(
2175 throw OutOfMemory(
"Could not allocate new_frame via allocate_avframe", path);
2180 persistent_dst_buffer,
2181 static_cast<size_t>(bytes_final)
2185 add_avframe(frame, new_frame);
2189bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *frame_final) {
2190#if (LIBAVFORMAT_VERSION_MAJOR >= 58)
2193 "FFmpegWriter::write_video_packet",
2194 "frame->number", frame->number,
2195 "oc->oformat->flags", oc->oformat->flags);
2203 "FFmpegWriter::write_video_packet",
2204 "frame->number", frame->number,
2205 "oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE);
2207 if (oc->oformat->flags & AVFMT_RAWPICTURE) {
2211 AVPacket* pkt = av_packet_alloc();
2214 av_init_packet(pkt);
2217 av_packet_from_data(
2218 pkt, frame_final->data[0],
2219 frame_final->linesize[0] * frame_final->height);
2221 pkt->flags |= AV_PKT_FLAG_KEY;
2222 pkt->stream_index = video_st->index;
2225 pkt->pts = video_timestamp;
2228 int error_code = av_interleaved_write_frame(oc, pkt);
2229 if (error_code < 0) {
2231 "FFmpegWriter::write_video_packet ERROR ["
2232 + av_err2string(error_code) +
"]",
2233 "error_code", error_code);
2244 AVPacket* pkt = av_packet_alloc();
2247 av_init_packet(pkt);
2251 pkt->pts = pkt->dts = AV_NOPTS_VALUE;
2254 frame_final->pts = video_timestamp;
2257 if (!(
hw_frame = av_frame_alloc())) {
2258 std::clog <<
"Error code: av_hwframe_alloc\n";
2260 if (av_hwframe_get_buffer(video_codec_ctx->hw_frames_ctx,
hw_frame, 0) < 0) {
2261 std::clog <<
"Error code: av_hwframe_get_buffer\n";
2264 std::clog <<
"Error hw_frames_ctx.\n";
2266 hw_frame->format = AV_PIX_FMT_NV12;
2267 if ( av_hwframe_transfer_data(
hw_frame, frame_final, 0) < 0) {
2268 std::clog <<
"Error while transferring frame data to surface.\n";
2270 av_frame_copy_props(
hw_frame, frame_final);
2274 int got_packet_ptr = 0;
2282 ret = avcodec_send_frame(video_codec_ctx,
hw_frame);
2286 ret = avcodec_send_frame(video_codec_ctx, frame_final);
2291 "FFmpegWriter::write_video_packet (Frame not sent)");
2292 if (ret == AVERROR(EAGAIN) ) {
2293 std::clog <<
"Frame EAGAIN\n";
2295 if (ret == AVERROR_EOF ) {
2296 std::clog <<
"Frame AVERROR_EOF\n";
2298 avcodec_send_frame(video_codec_ctx, NULL);
2302 ret = avcodec_receive_packet(video_codec_ctx, pkt);
2304 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
2316 error_code = avcodec_encode_video2(video_codec_ctx, pkt, frame_final, &got_packet_ptr);
2317 if (error_code != 0) {
2319 "FFmpegWriter::write_video_packet ERROR ["
2320 + av_err2string(error_code) +
"]",
2321 "error_code", error_code);
2323 if (got_packet_ptr == 0) {
2325 "FFmpegWriter::write_video_packet (Frame gotpacket error)");
2330 if (error_code == 0 && got_packet_ptr) {
2332 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
2333 pkt->stream_index = video_st->index;
2336 int result = av_interleaved_write_frame(oc, pkt);
2339 "FFmpegWriter::write_video_packet ERROR ["
2340 + av_err2string(result) +
"]",
2359 video_timestamp += av_rescale_q(1, av_make_q(
info.
fps.
den,
info.
fps.
num), video_codec_ctx->time_base);
2368 av_dump_format(oc, 0, path.c_str(), 1);
2373 original_sample_rate = sample_rate;
2374 original_channels = channels;
2383 oc->strict_std_compliance = FF_COMPLIANCE_UNOFFICIAL;
2385#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 0, 0)
2387 int proj = av_spherical_from_name(projection.c_str());
2389 proj = AV_SPHERICAL_EQUIRECTANGULAR;
2393 AVSphericalMapping* map = av_spherical_alloc(&sd_size);
2397 map->projection =
static_cast<AVSphericalProjection
>(proj);
2399 map->yaw =
static_cast<int32_t
>(yaw_deg * (1 << 16));
2400 map->pitch =
static_cast<int32_t
>(pitch_deg * (1 << 16));
2401 map->roll =
static_cast<int32_t
>(roll_deg * (1 << 16));
2403 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_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec)
#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
if(avcodec_open2(video_codec_ctx, codec, &opts)< 0) throw InvalidCodec("Could not open video codec"
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.