41static AVBufferRef *hw_device_ctx = NULL;
44static int set_hwframe_ctx(AVCodecContext *ctx, AVBufferRef *hw_device_ctx, int64_t width, int64_t height)
46 AVBufferRef *hw_frames_ref;
47 AVHWFramesContext *frames_ctx = NULL;
50 if (!(hw_frames_ref = av_hwframe_ctx_alloc(hw_device_ctx))) {
51 std::clog <<
"Failed to create HW frame context.\n";
54 frames_ctx = (AVHWFramesContext *)(hw_frames_ref->data);
56 frames_ctx->sw_format = AV_PIX_FMT_NV12;
57 frames_ctx->width = width;
58 frames_ctx->height = height;
59 frames_ctx->initial_pool_size = 20;
60 if ((err = av_hwframe_ctx_init(hw_frames_ref)) < 0) {
61 std::clog <<
"Failed to initialize HW frame context. " <<
62 "Error code: " << av_err2string(err) <<
"\n";
63 av_buffer_unref(&hw_frames_ref);
66 ctx->hw_frames_ctx = av_buffer_ref(hw_frames_ref);
67 if (!ctx->hw_frames_ctx)
68 err = AVERROR(ENOMEM);
70 av_buffer_unref(&hw_frames_ref);
76 path(
path), oc(NULL), audio_st(NULL), video_st(NULL), samples(NULL),
77 audio_outbuf(NULL), audio_outbuf_size(0), audio_input_frame_size(0), audio_input_position(0),
78 initial_audio_input_frame_size(0), img_convert_ctx(NULL),
79 video_codec_ctx(NULL), audio_codec_ctx(NULL), is_writing(false), video_timestamp(0), audio_timestamp(0),
80 original_sample_rate(0), original_channels(0), avr(NULL), avr_planar(NULL), is_open(false), prepare_streams(false),
81 write_header(false), write_trailer(false), audio_encoder_buffer_size(0), audio_encoder_buffer(NULL) {
101 if (!prepare_streams)
106 open_video(oc, video_st);
108 open_audio(oc, audio_st);
117void FFmpegWriter::auto_detect_format() {
123 "Could not allocate memory for AVFormatContext.", path);
127 oc->oformat = av_guess_format(NULL, path.c_str(), NULL);
128 if (oc->oformat ==
nullptr) {
129 throw InvalidFormat(
"Could not deduce output format from file extension.", path);
133 if (oc->oformat->video_codec != AV_CODEC_ID_NONE &&
info.
has_video) {
134 const AVCodec *vcodec = avcodec_find_encoder(oc->oformat->video_codec);
135 info.
vcodec = vcodec ? vcodec->name : std::string();
137 if (oc->oformat->audio_codec != AV_CODEC_ID_NONE &&
info.
has_audio) {
138 const AVCodec *acodec = avcodec_find_encoder(oc->oformat->audio_codec);
139 info.
acodec = acodec ? acodec->name : std::string();
144void FFmpegWriter::initialize_streams() {
146 "FFmpegWriter::initialize_streams",
147 "oc->oformat->video_codec", oc->oformat->video_codec,
148 "oc->oformat->audio_codec", oc->oformat->audio_codec,
149 "AV_CODEC_ID_NONE", AV_CODEC_ID_NONE);
154 if (oc->oformat->video_codec != AV_CODEC_ID_NONE &&
info.
has_video)
156 video_st = add_video_stream();
158 if (oc->oformat->audio_codec != AV_CODEC_ID_NONE &&
info.
has_audio)
160 audio_st = add_audio_stream();
166 if (
codec.length() > 0) {
167 const AVCodec *new_codec;
170#if defined(__linux__)
171 if (strstr(
codec.c_str(),
"_vaapi") != NULL) {
172 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
177 }
else if (strstr(
codec.c_str(),
"_nvenc") != NULL) {
178 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
184 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
189 if (strstr(
codec.c_str(),
"_dxva2") != NULL) {
190 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
195 }
else if (strstr(
codec.c_str(),
"_nvenc") != NULL) {
196 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
202 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
206#elif defined(__APPLE__)
207 if (strstr(
codec.c_str(),
"_videotoolbox") != NULL) {
208 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
214 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
219 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
222 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
224 if (new_codec == NULL)
225 throw InvalidCodec(
"A valid video codec could not be found for this file.", path);
244 if (pixel_ratio.
num > 0) {
248 if (bit_rate >= 1000)
250 if ((bit_rate >= 0) && (bit_rate < 256))
267 "FFmpegWriter::SetVideoOptions (" +
codec +
")",
268 "width", width,
"height", height,
269 "size.num", size.
num,
"size.den", size.
den,
270 "fps.num", fps.
num,
"fps.den", fps.
den);
280 true,
codec, fps, width, height,
289 if (
codec.length() > 0) {
290 const AVCodec *new_codec = avcodec_find_encoder_by_name(
codec.c_str());
291 if (new_codec == NULL)
292 throw InvalidCodec(
"A valid audio codec could not be found for this file.", path);
298 if (sample_rate > 7999)
307 if (original_sample_rate == 0)
309 if (original_channels == 0)
313 "FFmpegWriter::SetAudioOptions (" +
codec +
")",
314 "sample_rate", sample_rate,
315 "channels", channels,
316 "bit_rate", bit_rate);
327 true,
codec, sample_rate, 2,
336 AVCodecContext *c = NULL;
338 std::stringstream convert(value);
357 throw NoStreamsFound(
"The stream was not found. Be sure to call PrepareStreams() first.", path);
360 const AVOption *option = NULL;
368 if (option || (name ==
"g" || name ==
"qmin" || name ==
"qmax" || name ==
"max_b_frames" || name ==
"mb_decision" ||
369 name ==
"level" || name ==
"profile" || name ==
"slices" || name ==
"rc_min_rate" || name ==
"rc_max_rate" ||
370 name ==
"rc_buffer_size" || name ==
"crf" || name ==
"cqp" || name ==
"qp")) {
374 convert >> c->gop_size;
376 else if (name ==
"qmin")
380 else if (name ==
"qmax")
384 else if (name ==
"max_b_frames")
386 convert >> c->max_b_frames;
388 else if (name ==
"mb_decision")
390 convert >> c->mb_decision;
392 else if (name ==
"level")
396 else if (name ==
"profile")
398 convert >> c->profile;
400 else if (name ==
"slices")
402 convert >> c->slices;
404 else if (name ==
"rc_min_rate")
406 convert >> c->rc_min_rate;
408 else if (name ==
"rc_max_rate")
410 convert >> c->rc_max_rate;
412 else if (name ==
"rc_buffer_size")
414 convert >> c->rc_buffer_size;
416 else if (name ==
"cqp") {
420 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),63), 0);
424 switch (c->codec_id) {
425#if (LIBAVCODEC_VERSION_MAJOR >= 58)
427 case AV_CODEC_ID_AV1 :
429 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),63), 0);
432 case AV_CODEC_ID_VP8 :
433 c->bit_rate = 10000000;
434 av_opt_set_int(c->priv_data,
"qp", std::max(std::min(std::stoi(value), 63), 4), 0);
436 case AV_CODEC_ID_VP9 :
438 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value), 63), 0);
439 if (std::stoi(value) == 0) {
440 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
441 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
444 case AV_CODEC_ID_H264 :
445 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value), 51), 0);
446 if (std::stoi(value) == 0) {
447 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
451 case AV_CODEC_ID_HEVC :
452 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value), 51), 0);
453 if (std::stoi(value) == 0) {
454 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
455 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
460 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value), 63), 0);
464 }
else if (name ==
"crf") {
468 double mbs = 15000000.0;
477 c->bit_rate = (int)(mbs);
481 switch (c->codec_id) {
482#if (LIBAVCODEC_VERSION_MAJOR >= 58)
484 case AV_CODEC_ID_AV1 :
487 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value),63), 0);
490 case AV_CODEC_ID_VP8 :
491 c->bit_rate = 10000000;
492 av_opt_set_int(c->priv_data,
"crf", std::max(std::min(std::stoi(value), 63), 4), 0);
494 case AV_CODEC_ID_VP9 :
496 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value), 63), 0);
497 if (std::stoi(value) == 0) {
498 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
499 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
502 case AV_CODEC_ID_H264 :
503 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value), 51), 0);
504 if (std::stoi(value) == 0) {
505 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
509 case AV_CODEC_ID_HEVC :
510 if (strstr(
info.
vcodec.c_str(),
"svt_hevc") != NULL) {
511 av_opt_set_int(c->priv_data,
"preset", 7, 0);
512 av_opt_set_int(c->priv_data,
"forced-idr",1,0);
513 av_opt_set_int(c->priv_data,
"qp",std::min(std::stoi(value), 51),0);
516 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value), 51), 0);
518 if (std::stoi(value) == 0) {
519 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
520 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
526 double mbs = 15000000.0;
534 c->bit_rate = (int) (mbs);
537 }
else if (name ==
"qp") {
539#if (LIBAVCODEC_VERSION_MAJOR >= 58)
541 switch (c->codec_id) {
542 case AV_CODEC_ID_AV1 :
544 if (strstr(
info.
vcodec.c_str(),
"svtav1") != NULL) {
545 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),63), 0);
547 else if (strstr(
info.
vcodec.c_str(),
"rav1e") != NULL) {
550 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),255), 0);
552 else if (strstr(
info.
vcodec.c_str(),
"aom") != NULL) {
556 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value),63), 0);
559 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value),63), 0);
561 case AV_CODEC_ID_HEVC :
563 if (strstr(
info.
vcodec.c_str(),
"svt_hevc") != NULL) {
564 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),51), 0);
565 av_opt_set_int(c->priv_data,
"preset", 7, 0);
566 av_opt_set_int(c->priv_data,
"forced-idr",1,0);
573 AV_OPTION_SET(st, c->priv_data, name.c_str(), value.c_str(), c);
577 "FFmpegWriter::SetOption (" + (std::string)name +
")",
582 }
else if (name ==
"muxing_preset") {
583 if (value ==
"mp4_faststart") {
585 av_dict_set(&
mux_dict,
"movflags",
"faststart", 0);
586 }
else if (value ==
"mp4_fragmented") {
588 av_dict_set(&
mux_dict,
"movflags",
"frag_keyframe", 0);
589 av_dict_set(&
mux_dict,
"min_frag_duration",
"8000000", 0);
592 throw InvalidOptions(
"The option is not valid for this codec.", path);
603 return avcodec_find_encoder_by_name(codec_name.c_str()) != NULL;
609 throw InvalidOptions(
"No video or audio options have been set. You must set has_video or has_audio (or both).", path);
612 "FFmpegWriter::PrepareStreams [" + path +
"]",
617 initialize_streams();
620 prepare_streams =
true;
626 throw InvalidOptions(
"No video or audio options have been set. You must set has_video or has_audio (or both).", path);
629 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
630 if (avio_open(&oc->pb, path.c_str(), AVIO_FLAG_WRITE) < 0)
631 throw InvalidFile(
"Could not open or write file.", path);
639 av_dict_set(&oc->metadata, iter->first.c_str(), iter->second.c_str(), 0);
643 AVDictionary *dict = NULL;
649 if (avformat_write_header(oc, &dict) != 0) {
651 "FFmpegWriter::WriteHeader (avformat_write_header)");
652 throw InvalidFile(
"Could not write header to file.", path);
656 if (dict) av_dict_free(&dict);
669 throw WriterClosed(
"The FFmpegWriter is closed. Call Open() before calling this method.", path);
672 "FFmpegWriter::WriteFrame",
673 "frame->number", frame->number,
674 "is_writing", is_writing);
684void FFmpegWriter::write_frame(std::shared_ptr<Frame> frame) {
689 bool has_error_encoding_video =
false;
693 write_audio_packets(
false, frame);
697 process_video_packet(frame);
701 if (av_frames.count(frame)) {
703 AVFrame *frame_final = av_frames[frame];
706 if (!write_video_packet(frame, frame_final)) {
707 has_error_encoding_video =
true;
711 av_freep(&(frame_final->data[0]));
713 av_frames.erase(frame);
721 if (has_error_encoding_video)
728 "FFmpegWriter::WriteFrame (from Reader)",
733 for (int64_t number = start; number <= length; number++) {
735 std::shared_ptr<Frame> f = reader->
GetFrame(number);
746 write_audio_packets(
true, NULL);
755 av_write_trailer(oc);
758 write_trailer =
true;
764void FFmpegWriter::flush_encoders() {
767#if (LIBAVFORMAT_VERSION_MAJOR < 58)
781 video_timestamp += av_rescale_q(1, av_make_q(
info.
fps.
den,
info.
fps.
num), video_codec_ctx->time_base);
784 AVPacket* pkt = av_packet_alloc();
798 error_code = avcodec_send_frame(video_codec_ctx, NULL);
800 while (error_code >= 0) {
801 error_code = avcodec_receive_packet(video_codec_ctx, pkt);
802 if (error_code == AVERROR(EAGAIN)|| error_code == AVERROR_EOF) {
805 avcodec_flush_buffers(video_codec_ctx);
808 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
809 pkt->stream_index = video_st->index;
810 error_code = av_interleaved_write_frame(oc, pkt);
815 error_code = avcodec_encode_video2(video_codec_ctx, pkt, NULL, &got_packet);
819 if (error_code < 0) {
821 "FFmpegWriter::flush_encoders ERROR ["
822 + av_err2string(error_code) +
"]",
823 "error_code", error_code);
830 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
831 pkt->stream_index = video_st->index;
834 error_code = av_interleaved_write_frame(oc, pkt);
835 if (error_code < 0) {
837 "FFmpegWriter::flush_encoders ERROR ["
838 + av_err2string(error_code) +
"]",
839 "error_code", error_code);
848 AVPacket* pkt = av_packet_alloc();
855 pkt->pts = pkt->dts = audio_timestamp;
861 error_code = avcodec_send_frame(audio_codec_ctx, NULL);
863 error_code = avcodec_encode_audio2(audio_codec_ctx, pkt, NULL, &got_packet);
865 if (error_code < 0) {
867 "FFmpegWriter::flush_encoders ERROR ["
868 + av_err2string(error_code) +
"]",
869 "error_code", error_code);
877 pkt->pts = pkt->dts = audio_timestamp;
880 av_packet_rescale_ts(pkt, audio_codec_ctx->time_base, audio_st->time_base);
883 pkt->stream_index = audio_st->index;
884 pkt->flags |= AV_PKT_FLAG_KEY;
887 error_code = av_interleaved_write_frame(oc, pkt);
888 if (error_code < 0) {
890 "FFmpegWriter::flush_encoders ERROR ["
891 + av_err2string(error_code) +
"]",
892 "error_code", error_code);
896 audio_timestamp += pkt->duration;
906void FFmpegWriter::close_video(AVFormatContext *oc, AVStream *st)
911 av_buffer_unref(&hw_device_ctx);
912 hw_device_ctx = NULL;
918 if (video_codec_ctx !=
nullptr) {
920 av_free(video_codec_ctx);
925void FFmpegWriter::close_audio(AVFormatContext *oc, AVStream *st)
929 delete[] audio_outbuf;
930 delete[] audio_encoder_buffer;
933 audio_encoder_buffer = NULL;
949 if (audio_codec_ctx !=
nullptr) {
951 av_free(audio_codec_ctx);
963 close_video(oc, video_st);
965 close_audio(oc, audio_st);
969 sws_freeContext(img_convert_ctx);
971 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
981 avformat_free_context(oc);
986 prepare_streams =
false;
987 write_header =
false;
988 write_trailer =
false;
994void FFmpegWriter::add_avframe(std::shared_ptr<Frame> frame, AVFrame *av_frame) {
996 if (!av_frames.count(frame)) {
998 av_frames[frame] = av_frame;
1006AVStream *FFmpegWriter::add_audio_stream() {
1008 const AVCodec *
codec = avcodec_find_encoder_by_name(
info.
acodec.c_str());
1010 throw InvalidCodec(
"A valid audio codec could not be found for this file.", path);
1013 if (audio_codec_ctx !=
nullptr) {
1018 AVStream* st = avformat_new_stream(oc,
codec);
1020 throw OutOfMemory(
"Could not allocate memory for the audio stream.", path);
1024#if (LIBAVFORMAT_VERSION_MAJOR >= 58)
1025 st->codecpar->codec_id =
codec->id;
1027 AVCodecContext* c = audio_codec_ctx;
1029 c->codec_id =
codec->id;
1030 c->codec_type = AVMEDIA_TYPE_AUDIO;
1039 if (
codec->supported_samplerates) {
1041 for (i = 0;
codec->supported_samplerates[i] != 0; i++)
1047 if (
codec->supported_samplerates[i] == 0)
1048 throw InvalidSampleRate(
"An invalid sample rate was detected for this codec.", path);
1056 AVChannelLayout ch_layout;
1058 if (
codec->ch_layouts) {
1060 for (i = 0; av_channel_layout_check(&
codec->ch_layouts[i]); i++)
1061 if (av_channel_layout_compare(&ch_layout, &
codec->ch_layouts[i])) {
1063 av_channel_layout_copy(&c->ch_layout, &ch_layout);
1066 if (!av_channel_layout_check(&
codec->ch_layouts[i]))
1067 throw InvalidChannels(
"An invalid channel layout was detected (i.e. MONO / STEREO).", path);
1070 av_channel_layout_copy(&c->ch_layout, &ch_layout);
1073 if (
codec->channel_layouts) {
1075 for (i = 0;
codec->channel_layouts[i] != 0; i++)
1076 if (channel_layout ==
codec->channel_layouts[i]) {
1078 c->channel_layout = channel_layout;
1081 if (
codec->channel_layouts[i] == 0)
1082 throw InvalidChannels(
"An invalid channel layout was detected (i.e. MONO / STEREO).", path);
1085 c->channel_layout = channel_layout;
1089 if (
codec->sample_fmts) {
1090 for (
int i = 0;
codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) {
1092 c->sample_fmt =
codec->sample_fmts[i];
1096 if (c->sample_fmt == AV_SAMPLE_FMT_NONE) {
1098 c->sample_fmt = AV_SAMPLE_FMT_S16;
1102 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1103#if (LIBAVCODEC_VERSION_MAJOR >= 57)
1105 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1107 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1113 const char* nb_channels_label;
1114 const char* channel_layout_label;
1117 nb_channels = c->ch_layout.nb_channels;
1118 channel_layout = c->ch_layout.u.mask;
1119 nb_channels_label =
"c->ch_layout.nb_channels";
1120 channel_layout_label =
"c->ch_layout.u.mask";
1122 nb_channels = c->channels;
1123 nb_channels_label =
"c->channels";
1124 channel_layout_label =
"c->channel_layout";
1128 "FFmpegWriter::add_audio_stream",
1129 "c->codec_id", c->codec_id,
1130 "c->bit_rate", c->bit_rate,
1131 nb_channels_label, nb_channels,
1132 "c->sample_fmt", c->sample_fmt,
1133 channel_layout_label, channel_layout,
1134 "c->sample_rate", c->sample_rate);
1140AVStream *FFmpegWriter::add_video_stream() {
1142 const AVCodec *
codec = avcodec_find_encoder_by_name(
info.
vcodec.c_str());
1144 throw InvalidCodec(
"A valid video codec could not be found for this file.", path);
1147 if (video_codec_ctx !=
nullptr) {
1152 AVStream* st = avformat_new_stream(oc,
codec);
1154 throw OutOfMemory(
"Could not allocate memory for the video stream.", path);
1158#if (LIBAVFORMAT_VERSION_MAJOR >= 58)
1159 st->codecpar->codec_id =
codec->id;
1162 AVCodecContext* c = video_codec_ctx;
1164 c->codec_id =
codec->id;
1165 c->codec_type = AVMEDIA_TYPE_VIDEO;
1173#
if (LIBAVCODEC_VERSION_MAJOR >= 58)
1174 && c->codec_id != AV_CODEC_ID_AV1
1179 if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
1188 switch (c->codec_id) {
1189#if (LIBAVCODEC_VERSION_MAJOR >= 58)
1191 case AV_CODEC_ID_AV1 :
1195 if (strstr(
info.
vcodec.c_str(),
"aom") != NULL) {
1196 int calculated_quality = 35;
1199 av_opt_set_int(c->priv_data,
"crf", calculated_quality, 0);
1202 int calculated_quality = 50;
1205 av_opt_set_int(c->priv_data,
"qp", calculated_quality, 0);
1209 if (strstr(
info.
vcodec.c_str(),
"svtav1") != NULL) {
1210 av_opt_set_int(c->priv_data,
"preset", 6, 0);
1211 av_opt_set_int(c->priv_data,
"forced-idr",1,0);
1213 else if (strstr(
info.
vcodec.c_str(),
"rav1e") != NULL) {
1214 av_opt_set_int(c->priv_data,
"speed", 7, 0);
1215 av_opt_set_int(c->priv_data,
"tile-rows", 2, 0);
1216 av_opt_set_int(c->priv_data,
"tile-columns", 4, 0);
1218 else if (strstr(
info.
vcodec.c_str(),
"aom") != NULL) {
1221 av_opt_set_int(c->priv_data,
"tile-rows", 1, 0);
1222 av_opt_set_int(c->priv_data,
"tile-columns", 2, 0);
1223 av_opt_set_int(c->priv_data,
"row-mt", 1, 0);
1224 av_opt_set_int(c->priv_data,
"cpu-used", 3, 0);
1228 case AV_CODEC_ID_VP9 :
1229 case AV_CODEC_ID_HEVC :
1230 case AV_CODEC_ID_VP8 :
1231 case AV_CODEC_ID_H264 :
1267#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 26, 0)
1268 c->framerate = av_inv_q(c->time_base);
1270 st->avg_frame_rate = av_inv_q(c->time_base);
1275 c->max_b_frames = 10;
1276 if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO)
1278 c->max_b_frames = 2;
1279 if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO)
1285 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1286#if (LIBAVCODEC_VERSION_MAJOR >= 57)
1288 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1290 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1295 while (supported_pixel_formats != NULL && *supported_pixel_formats !=
PIX_FMT_NONE) {
1298 c->pix_fmt = *supported_pixel_formats;
1299 ++supported_pixel_formats;
1304 if (oc->oformat->video_codec == AV_CODEC_ID_RAWVIDEO) {
1308#if (LIBAVFORMAT_VERSION_MAJOR < 58)
1310 if (strcmp(oc->oformat->name,
"gif") != 0)
1313 oc->oformat->flags |= AVFMT_RAWPICTURE;
1323 "FFmpegWriter::add_video_stream ("
1324 + (std::string)oc->oformat->name +
" : "
1325 + (std::string)av_get_pix_fmt_name(c->pix_fmt) +
")",
1326 "c->codec_id", c->codec_id,
1327 "c->bit_rate", c->bit_rate,
1328 "c->pix_fmt", c->pix_fmt,
1329 "oc->oformat->flags", oc->oformat->flags);
1334void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st) {
1335 const AVCodec *
codec;
1344 codec = avcodec_find_encoder(audio_codec_ctx->codec_id);
1349 AVDictionary *
opts = NULL;
1350 av_dict_set(&
opts,
"strict",
"experimental", 0);
1353 if (avcodec_open2(audio_codec_ctx,
codec, &
opts) < 0)
1354 throw InvalidCodec(
"Could not open audio codec", path);
1358 av_dict_free(&
opts);
1362 if (audio_codec_ctx->frame_size <= 1) {
1368 case AV_CODEC_ID_PCM_S16LE:
1369 case AV_CODEC_ID_PCM_S16BE:
1370 case AV_CODEC_ID_PCM_U16LE:
1371 case AV_CODEC_ID_PCM_U16BE:
1372 audio_input_frame_size >>= 1;
1379 audio_input_frame_size = audio_codec_ctx->frame_size;
1383 initial_audio_input_frame_size = audio_input_frame_size;
1390 audio_outbuf =
new uint8_t[audio_outbuf_size];
1394 audio_encoder_buffer =
new uint8_t[audio_encoder_buffer_size];
1397 for (std::map<std::string, std::string>::iterator iter =
info.
metadata.begin(); iter !=
info.
metadata.end(); ++iter) {
1398 av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1402 "FFmpegWriter::open_audio",
1403 "audio_codec_ctx->thread_count", audio_codec_ctx->thread_count,
1404 "audio_input_frame_size", audio_input_frame_size,
1409void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) {
1410 const AVCodec *
codec;
1420 char *adapter_ptr = NULL;
1424 std::clog <<
"Encoding Device Nr: " << adapter_num <<
"\n";
1425 if (adapter_num < 3 && adapter_num >=0) {
1426#if defined(__linux__)
1427 snprintf(adapter,
sizeof(adapter),
"/dev/dri/renderD%d", adapter_num+128);
1429 adapter_ptr = adapter;
1430#elif defined(_WIN32) || defined(__APPLE__)
1438#if defined(__linux__)
1439 if( adapter_ptr != NULL && access( adapter_ptr, W_OK ) == 0 ) {
1440#elif defined(_WIN32) || defined(__APPLE__)
1441 if( adapter_ptr != NULL ) {
1444 "Encode Device present using device",
1445 "adapter", adapter_num);
1450 "Encode Device not present, using default");
1452 if (av_hwdevice_ctx_create(&hw_device_ctx,
1456 "FFmpegWriter::open_video ERROR creating hwdevice, Codec name:",
1471 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)
1472 video_codec_ctx->max_b_frames = 0;
1476 av_dict_set(&
opts,
"strict",
"experimental", 0);
1490 if (av_opt_get_int(video_codec_ctx->priv_data,
"qp", 0, &qp) != 0 || qp == 0) {
1492 av_opt_set(video_codec_ctx->priv_data,
"rc_mode",
"VBR", 0);
1496 video_codec_ctx->rc_max_rate = video_codec_ctx->bit_rate;
1500 switch (video_codec_ctx->codec_id) {
1501 case AV_CODEC_ID_H264:
1502 video_codec_ctx->max_b_frames = 0;
1503 video_codec_ctx->profile = AV_PROFILE_H264_BASELINE | AV_PROFILE_H264_CONSTRAINED;
1504 av_opt_set(video_codec_ctx->priv_data,
"preset",
"slow", 0);
1505 av_opt_set(video_codec_ctx->priv_data,
"tune",
"zerolatency", 0);
1506 av_opt_set(video_codec_ctx->priv_data,
"vprofile",
"baseline", AV_OPT_SEARCH_CHILDREN);
1508 case AV_CODEC_ID_HEVC:
1511 case AV_CODEC_ID_VP9:
1516 "No codec-specific options defined for this codec. HW encoding may fail",
1517 "codec_id", video_codec_ctx->codec_id);
1526 "FFmpegWriter::open_video (set_hwframe_ctx) ERROR faled to set hwframe context",
1529 av_err2string(err), -1);
1537 video_codec_ctx->codec_tag = MKTAG(
'h',
'v',
'c',
'1');
1540 if (video_codec_ctx->codec_id == AV_CODEC_ID_HEVC) {
1541 video_codec_ctx->codec_tag = MKTAG(
'h',
'v',
'c',
'1');
1547 throw InvalidCodec(
"Could not open video codec", path);
1551 av_dict_free(&
opts);
1555 av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1559 "FFmpegWriter::open_video",
1560 "video_codec_ctx->thread_count", video_codec_ctx->thread_count);
1565void FFmpegWriter::write_audio_packets(
bool is_final, std::shared_ptr<openshot::Frame> frame) {
1566 if (!frame && !is_final)
1570 int total_frame_samples = 0;
1571 int frame_position = 0;
1572 int channels_in_frame = 0;
1573 int sample_rate_in_frame = 0;
1574 int samples_in_frame = 0;
1579 int16_t *all_queued_samples = (int16_t *) av_malloc(all_queued_samples_size);
1580 int16_t *all_resampled_samples = NULL;
1581 int16_t *final_samples_planar = NULL;
1582 int16_t *final_samples = NULL;
1585 float *frame_samples_float = NULL;
1589 sample_rate_in_frame = frame->SampleRate();
1590 samples_in_frame = frame->GetAudioSamplesCount();
1591 channels_in_frame = frame->GetAudioChannelsCount();
1592 channel_layout_in_frame = frame->ChannelsLayout();
1595 frame_samples_float = frame->GetInterleavedAudioSamples(&samples_in_frame);
1599 total_frame_samples = samples_in_frame * channels_in_frame;
1602 const int16_t max16 = 32767;
1603 const int16_t min16 = -32768;
1604 for (
int s = 0; s < total_frame_samples; s++, frame_position++) {
1605 float valF = frame_samples_float[s] * (1 << 15);
1609 }
else if (valF < min16) {
1612 conv = int(valF + 32768.5) - 32768;
1616 all_queued_samples[frame_position] = conv;
1620 delete[] frame_samples_float;
1624 total_frame_samples = frame_position;
1625 int remaining_frame_samples = total_frame_samples;
1626 int samples_position = 0;
1630 "FFmpegWriter::write_audio_packets",
1631 "is_final", is_final,
1632 "total_frame_samples", total_frame_samples,
1633 "channel_layout_in_frame", channel_layout_in_frame,
1634 "channels_in_frame", channels_in_frame,
1635 "samples_in_frame", samples_in_frame,
1639 AVSampleFormat output_sample_fmt = audio_codec_ctx->sample_fmt;
1641 AVFrame *audio_frame = NULL;
1646 audio_frame->nb_samples = total_frame_samples / channels_in_frame;
1649 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);
1650 if (error_code < 0) {
1652 "FFmpegWriter::write_audio_packets ERROR ["
1653 + av_err2string(error_code) +
"]",
1654 "error_code", error_code);
1658 switch (audio_codec_ctx->sample_fmt) {
1659 case AV_SAMPLE_FMT_FLTP: {
1660 output_sample_fmt = AV_SAMPLE_FMT_FLT;
1663 case AV_SAMPLE_FMT_S32P: {
1664 output_sample_fmt = AV_SAMPLE_FMT_S32;
1667 case AV_SAMPLE_FMT_S16P: {
1668 output_sample_fmt = AV_SAMPLE_FMT_S16;
1671 case AV_SAMPLE_FMT_U8P: {
1672 output_sample_fmt = AV_SAMPLE_FMT_U8;
1682 total_frame_samples *= (float(
info.
sample_rate) / sample_rate_in_frame);
1683 total_frame_samples *= (float(
info.
channels) / channels_in_frame);
1688 audio_converted->nb_samples = total_frame_samples / channels_in_frame;
1689 av_samples_alloc(audio_converted->data, audio_converted->linesize,
info.
channels, audio_converted->nb_samples, output_sample_fmt, 0);
1692 "FFmpegWriter::write_audio_packets (1st resampling)",
1693 "in_sample_fmt", AV_SAMPLE_FMT_S16,
1694 "out_sample_fmt", output_sample_fmt,
1695 "in_sample_rate", sample_rate_in_frame,
1697 "in_channels", channels_in_frame,
1704 AVChannelLayout in_chlayout;
1705 AVChannelLayout out_chlayout;
1706 av_channel_layout_from_mask(&in_chlayout, channel_layout_in_frame);
1708 av_opt_set_chlayout(avr,
"in_chlayout", &in_chlayout, 0);
1709 av_opt_set_chlayout(avr,
"out_chlayout", &out_chlayout, 0);
1711 av_opt_set_int(avr,
"in_channel_layout", channel_layout_in_frame, 0);
1713 av_opt_set_int(avr,
"in_channels", channels_in_frame, 0);
1716 av_opt_set_int(avr,
"in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
1717 av_opt_set_int(avr,
"out_sample_fmt", output_sample_fmt, 0);
1718 av_opt_set_int(avr,
"in_sample_rate", sample_rate_in_frame, 0);
1725 audio_converted->data,
1726 audio_converted->linesize[0],
1727 audio_converted->nb_samples,
1729 audio_frame->linesize[0],
1730 audio_frame->nb_samples
1734 remaining_frame_samples = total_frame_samples;
1737 all_resampled_samples = (int16_t *) av_malloc(
1739 * (av_get_bytes_per_sample(output_sample_fmt) /
1740 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1744 memcpy(all_resampled_samples, audio_converted->data[0],
1745 static_cast<size_t>(nb_samples)
1747 * av_get_bytes_per_sample(output_sample_fmt));
1750 av_freep(&(audio_frame->data[0]));
1752 av_freep(&audio_converted->data[0]);
1754 all_queued_samples = NULL;
1757 "FFmpegWriter::write_audio_packets (Successfully completed 1st resampling)",
1758 "nb_samples", nb_samples,
1759 "remaining_frame_samples", remaining_frame_samples);
1763 while (remaining_frame_samples > 0 || is_final) {
1765 int remaining_packet_samples = (audio_input_frame_size *
info.
channels) - audio_input_position;
1769 if (remaining_frame_samples >= remaining_packet_samples) {
1770 diff = remaining_packet_samples;
1772 diff = remaining_frame_samples;
1779 samples + (audio_input_position
1780 * (av_get_bytes_per_sample(output_sample_fmt) /
1781 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1783 all_resampled_samples + samples_position,
1784 static_cast<size_t>(diff)
1785 * av_get_bytes_per_sample(output_sample_fmt)
1789 audio_input_position += diff;
1790 samples_position += diff * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16));
1791 remaining_frame_samples -= diff;
1794 if (audio_input_position < (audio_input_frame_size *
info.
channels) && !is_final)
1801 if (av_sample_fmt_is_planar(audio_codec_ctx->sample_fmt)) {
1803 "FFmpegWriter::write_audio_packets (2nd resampling for Planar formats)",
1804 "in_sample_fmt", output_sample_fmt,
1805 "out_sample_fmt", audio_codec_ctx->sample_fmt,
1816 AVChannelLayout layout;
1818 av_opt_set_chlayout(avr_planar,
"in_chlayout", &layout, 0);
1819 av_opt_set_chlayout(avr_planar,
"out_chlayout", &layout, 0);
1823 av_opt_set_int(avr_planar,
"in_channels",
info.
channels, 0);
1824 av_opt_set_int(avr_planar,
"out_channels",
info.
channels, 0);
1826 av_opt_set_int(avr_planar,
"in_sample_fmt", output_sample_fmt, 0);
1827 av_opt_set_int(avr_planar,
"out_sample_fmt", audio_codec_ctx->sample_fmt, 0);
1836 audio_frame->nb_samples = audio_input_position /
info.
channels;
1839 final_samples_planar = (int16_t *) av_malloc(
1840 sizeof(int16_t) * audio_frame->nb_samples *
info.
channels
1841 * (av_get_bytes_per_sample(output_sample_fmt) /
1842 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1846 memcpy(final_samples_planar, samples,
1847 static_cast<size_t>(audio_frame->nb_samples)
1849 * av_get_bytes_per_sample(output_sample_fmt));
1852 avcodec_fill_audio_frame(audio_frame,
info.
channels, output_sample_fmt,
1853 (uint8_t *) final_samples_planar, audio_encoder_buffer_size, 0);
1856 frame_final->nb_samples = audio_input_frame_size;
1863 frame_final->format = audio_codec_ctx->sample_fmt;
1864 av_samples_alloc(frame_final->data, frame_final->linesize,
info.
channels,
1865 frame_final->nb_samples, audio_codec_ctx->sample_fmt, 0);
1871 frame_final->linesize[0],
1872 frame_final->nb_samples,
1874 audio_frame->linesize[0],
1875 audio_frame->nb_samples
1879 const auto copy_length =
static_cast<size_t>(nb_samples)
1880 * av_get_bytes_per_sample(audio_codec_ctx->sample_fmt)
1884 memcpy(samples, frame_final->data[0], copy_length);
1887 av_freep(&(audio_frame->data[0]));
1889 all_queued_samples = NULL;
1892 "FFmpegWriter::write_audio_packets (Successfully completed 2nd resampling for Planar formats)",
1893 "nb_samples", nb_samples);
1897 const auto buf_size =
static_cast<size_t>(audio_input_position)
1898 * (av_get_bytes_per_sample(audio_codec_ctx->sample_fmt) /
1899 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)
1901 final_samples =
reinterpret_cast<int16_t*
>(
1902 av_malloc(
sizeof(int16_t) * buf_size));
1905 memcpy(final_samples, samples,
1906 audio_input_position * av_get_bytes_per_sample(audio_codec_ctx->sample_fmt));
1909 frame_final->nb_samples = audio_input_frame_size;
1913 int nb_channels = audio_codec_ctx->ch_layout.nb_channels;
1915 int nb_channels = audio_codec_ctx->channels;
1917 avcodec_fill_audio_frame(frame_final, nb_channels,
1918 audio_codec_ctx->sample_fmt, (uint8_t *) final_samples,
1919 audio_encoder_buffer_size, 0);
1923 frame_final->pts = audio_timestamp;
1927 AVPacket* pkt = av_packet_alloc();
1930 av_init_packet(pkt);
1932 pkt->data = audio_encoder_buffer;
1933 pkt->size = audio_encoder_buffer_size;
1936 pkt->pts = pkt->dts = audio_timestamp;
1939 int got_packet_ptr = 0;
1945 int frame_finished = 0;
1946 error_code = ret = avcodec_send_frame(audio_codec_ctx, frame_final);
1947 if (ret < 0 && ret != AVERROR(EINVAL) && ret != AVERROR_EOF) {
1948 avcodec_send_frame(audio_codec_ctx, NULL);
1953 ret = avcodec_receive_packet(audio_codec_ctx, pkt);
1956 if(ret == AVERROR(EINVAL) || ret == AVERROR_EOF) {
1957 avcodec_flush_buffers(audio_codec_ctx);
1961 ret = frame_finished;
1964 if (!pkt->data && !frame_finished)
1968 got_packet_ptr = ret;
1971 int error_code = avcodec_encode_audio2(audio_codec_ctx, pkt, frame_final, &got_packet_ptr);
1974 if (error_code == 0 && got_packet_ptr) {
1978 pkt->pts = pkt->dts = audio_timestamp;
1981 av_packet_rescale_ts(pkt, audio_codec_ctx->time_base, audio_st->time_base);
1984 pkt->stream_index = audio_st->index;
1985 pkt->flags |= AV_PKT_FLAG_KEY;
1988 error_code = av_interleaved_write_frame(oc, pkt);
1991 if (error_code < 0) {
1993 "FFmpegWriter::write_audio_packets ERROR ["
1994 + av_err2string(error_code) +
"]",
1995 "error_code", error_code);
1999 audio_timestamp += FFMIN(audio_input_frame_size, audio_input_position);
2002 av_freep(&(frame_final->data[0]));
2009 audio_input_position = 0;
2014 if (all_resampled_samples) {
2015 av_freep(&all_resampled_samples);
2016 all_resampled_samples = NULL;
2018 if (all_queued_samples) {
2019 av_freep(&all_queued_samples);
2020 all_queued_samples = NULL;
2025AVFrame *FFmpegWriter::allocate_avframe(
PixelFormat pix_fmt,
int width,
int height,
int *buffer_size, uint8_t *new_buffer) {
2027 AVFrame *new_av_frame = NULL;
2031 if (new_av_frame == NULL)
2032 throw OutOfMemory(
"Could not allocate AVFrame", path);
2040 new_buffer = (uint8_t *) av_malloc(*buffer_size *
sizeof(uint8_t));
2043 new_av_frame->width = width;
2044 new_av_frame->height = height;
2045 new_av_frame->format = pix_fmt;
2049 return new_av_frame;
2053void FFmpegWriter::process_video_packet(std::shared_ptr<Frame> frame) {
2055 int src_w = frame->GetWidth();
2056 int src_h = frame->GetHeight();
2059 if (src_w == 1 && src_h == 1)
2063 const uchar* pixels = frame->GetPixels();
2064 if (!persistent_src_frame) {
2065 persistent_src_frame = av_frame_alloc();
2066 if (!persistent_src_frame)
2067 throw OutOfMemory(
"Could not allocate persistent_src_frame", path);
2068 persistent_src_frame->format = AV_PIX_FMT_RGBA;
2069 persistent_src_frame->width = src_w;
2070 persistent_src_frame->height = src_h;
2071 persistent_src_frame->linesize[0] = src_w * 4;
2073 persistent_src_frame->data[0] =
const_cast<uint8_t*
>(
2074 reinterpret_cast<const uint8_t*
>(pixels)
2078 if (!persistent_dst_frame) {
2079 persistent_dst_frame = av_frame_alloc();
2080 if (!persistent_dst_frame)
2081 throw OutOfMemory(
"Could not allocate persistent_dst_frame", path);
2084 AVPixelFormat dst_fmt = video_codec_ctx->pix_fmt;
2087 dst_fmt = AV_PIX_FMT_NV12;
2090 persistent_dst_frame->format = dst_fmt;
2091 persistent_dst_frame->width =
info.
width;
2094 persistent_dst_size = av_image_get_buffer_size(
2097 if (persistent_dst_size < 0)
2100 persistent_dst_buffer =
static_cast<uint8_t*
>(
2101 av_malloc(persistent_dst_size)
2103 if (!persistent_dst_buffer)
2104 throw OutOfMemory(
"Could not allocate persistent_dst_buffer", path);
2106 av_image_fill_arrays(
2107 persistent_dst_frame->data,
2108 persistent_dst_frame->linesize,
2109 persistent_dst_buffer,
2118 if (!img_convert_ctx) {
2119 int flags = SWS_FAST_BILINEAR;
2121 flags = SWS_BICUBIC;
2123 AVPixelFormat dst_fmt = video_codec_ctx->pix_fmt;
2126 dst_fmt = AV_PIX_FMT_NV12;
2129 img_convert_ctx = sws_getContext(
2130 src_w, src_h, AV_PIX_FMT_RGBA,
2132 flags, NULL, NULL, NULL
2134 if (!img_convert_ctx)
2141 persistent_src_frame->data,
2142 persistent_src_frame->linesize,
2144 persistent_dst_frame->data,
2145 persistent_dst_frame->linesize
2149 int bytes_final = 0;
2150 AVPixelFormat dst_fmt = video_codec_ctx->pix_fmt;
2153 dst_fmt = AV_PIX_FMT_NV12;
2157 AVFrame* new_frame = allocate_avframe(
2165 throw OutOfMemory(
"Could not allocate new_frame via allocate_avframe", path);
2170 persistent_dst_buffer,
2171 static_cast<size_t>(bytes_final)
2175 add_avframe(frame, new_frame);
2179bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *frame_final) {
2180#if (LIBAVFORMAT_VERSION_MAJOR >= 58)
2183 "FFmpegWriter::write_video_packet",
2184 "frame->number", frame->number,
2185 "oc->oformat->flags", oc->oformat->flags);
2193 "FFmpegWriter::write_video_packet",
2194 "frame->number", frame->number,
2195 "oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE);
2197 if (oc->oformat->flags & AVFMT_RAWPICTURE) {
2201 AVPacket* pkt = av_packet_alloc();
2204 av_init_packet(pkt);
2207 av_packet_from_data(
2208 pkt, frame_final->data[0],
2209 frame_final->linesize[0] * frame_final->height);
2211 pkt->flags |= AV_PKT_FLAG_KEY;
2212 pkt->stream_index = video_st->index;
2215 pkt->pts = video_timestamp;
2218 int error_code = av_interleaved_write_frame(oc, pkt);
2219 if (error_code < 0) {
2221 "FFmpegWriter::write_video_packet ERROR ["
2222 + av_err2string(error_code) +
"]",
2223 "error_code", error_code);
2234 AVPacket* pkt = av_packet_alloc();
2237 av_init_packet(pkt);
2241 pkt->pts = pkt->dts = AV_NOPTS_VALUE;
2244 frame_final->pts = video_timestamp;
2247 if (!(
hw_frame = av_frame_alloc())) {
2248 std::clog <<
"Error code: av_hwframe_alloc\n";
2250 if (av_hwframe_get_buffer(video_codec_ctx->hw_frames_ctx,
hw_frame, 0) < 0) {
2251 std::clog <<
"Error code: av_hwframe_get_buffer\n";
2254 std::clog <<
"Error hw_frames_ctx.\n";
2256 hw_frame->format = AV_PIX_FMT_NV12;
2257 if ( av_hwframe_transfer_data(
hw_frame, frame_final, 0) < 0) {
2258 std::clog <<
"Error while transferring frame data to surface.\n";
2260 av_frame_copy_props(
hw_frame, frame_final);
2264 int got_packet_ptr = 0;
2272 ret = avcodec_send_frame(video_codec_ctx,
hw_frame);
2276 ret = avcodec_send_frame(video_codec_ctx, frame_final);
2281 "FFmpegWriter::write_video_packet (Frame not sent)");
2282 if (ret == AVERROR(EAGAIN) ) {
2283 std::clog <<
"Frame EAGAIN\n";
2285 if (ret == AVERROR_EOF ) {
2286 std::clog <<
"Frame AVERROR_EOF\n";
2288 avcodec_send_frame(video_codec_ctx, NULL);
2292 ret = avcodec_receive_packet(video_codec_ctx, pkt);
2294 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
2306 error_code = avcodec_encode_video2(video_codec_ctx, pkt, frame_final, &got_packet_ptr);
2307 if (error_code != 0) {
2309 "FFmpegWriter::write_video_packet ERROR ["
2310 + av_err2string(error_code) +
"]",
2311 "error_code", error_code);
2313 if (got_packet_ptr == 0) {
2315 "FFmpegWriter::write_video_packet (Frame gotpacket error)");
2320 if (error_code == 0 && got_packet_ptr) {
2322 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
2323 pkt->stream_index = video_st->index;
2326 int result = av_interleaved_write_frame(oc, pkt);
2329 "FFmpegWriter::write_video_packet ERROR ["
2330 + av_err2string(result) +
"]",
2349 video_timestamp += av_rescale_q(1, av_make_q(
info.
fps.
den,
info.
fps.
num), video_codec_ctx->time_base);
2358 av_dump_format(oc, 0, path.c_str(), 1);
2363 original_sample_rate = sample_rate;
2364 original_channels = channels;
2373 oc->strict_std_compliance = FF_COMPLIANCE_UNOFFICIAL;
2375#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 0, 0)
2377 int proj = av_spherical_from_name(projection.c_str());
2379 proj = AV_SPHERICAL_EQUIRECTANGULAR;
2383 AVSphericalMapping* map = av_spherical_alloc(&sd_size);
2387 map->projection =
static_cast<AVSphericalProjection
>(proj);
2389 map->yaw =
static_cast<int32_t
>(yaw_deg * (1 << 16));
2390 map->pitch =
static_cast<int32_t
>(pitch_deg * (1 << 16));
2391 map->roll =
static_cast<int32_t
>(roll_deg * (1 << 16));
2394#if (LIBAVFORMAT_VERSION_MAJOR < 62)
2395 av_stream_add_side_data(video_st, AV_PKT_DATA_SPHERICAL,
reinterpret_cast<uint8_t*
>(map), sd_size);
2397 av_packet_side_data_add(&video_st->codecpar->coded_side_data, &video_st->codecpar->nb_coded_side_data, AV_PKT_DATA_SPHERICAL,
reinterpret_cast<uint8_t *
>(map), sd_size, 0);
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.