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), num_of_rescalers(1),
79 rescaler_position(0), video_codec_ctx(NULL), audio_codec_ctx(NULL), is_writing(false), video_timestamp(0), audio_timestamp(0),
80 original_sample_rate(0), original_channels(0), avr(NULL), avr_planar(NULL), is_open(false), prepare_streams(false),
81 write_header(false), write_trailer(false), audio_encoder_buffer_size(0), audio_encoder_buffer(NULL) {
101 if (!prepare_streams)
106 open_video(oc, video_st);
108 open_audio(oc, audio_st);
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) {
130 "Could not deduce output format from file extension.", path);
134 if (oc->oformat->video_codec != AV_CODEC_ID_NONE &&
info.
has_video)
135 info.
vcodec = avcodec_find_encoder(oc->oformat->video_codec)->name;
138 if (oc->oformat->audio_codec != AV_CODEC_ID_NONE &&
info.
has_audio)
139 info.
acodec = avcodec_find_encoder(oc->oformat->audio_codec)->name;
143void FFmpegWriter::initialize_streams() {
145 "FFmpegWriter::initialize_streams",
146 "oc->oformat->video_codec", oc->oformat->video_codec,
147 "oc->oformat->audio_codec", oc->oformat->audio_codec,
148 "AV_CODEC_ID_NONE", AV_CODEC_ID_NONE);
153 if (oc->oformat->video_codec != AV_CODEC_ID_NONE &&
info.
has_video)
155 video_st = add_video_stream();
157 if (oc->oformat->audio_codec != AV_CODEC_ID_NONE &&
info.
has_audio)
159 audio_st = add_audio_stream();
165 if (
codec.length() > 0) {
166 const AVCodec *new_codec;
169#if defined(__linux__)
170 if (strstr(
codec.c_str(),
"_vaapi") != NULL) {
171 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
176 }
else if (strstr(
codec.c_str(),
"_nvenc") != NULL) {
177 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
183 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
188 if (strstr(
codec.c_str(),
"_dxva2") != NULL) {
189 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
194 }
else if (strstr(
codec.c_str(),
"_nvenc") != NULL) {
195 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
201 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
205#elif defined(__APPLE__)
206 if (strstr(
codec.c_str(),
"_videotoolbox") != NULL) {
207 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
213 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
218 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
221 new_codec = avcodec_find_encoder_by_name(
codec.c_str());
223 if (new_codec == NULL)
224 throw InvalidCodec(
"A valid video codec could not be found for this file.", path);
243 if (pixel_ratio.
num > 0) {
247 if (bit_rate >= 1000)
249 if ((bit_rate >= 0) && (bit_rate < 256))
266 "FFmpegWriter::SetVideoOptions (" +
codec +
")",
267 "width", width,
"height", height,
268 "size.num", size.
num,
"size.den", size.
den,
269 "fps.num", fps.
num,
"fps.den", fps.
den);
279 true,
codec, fps, width, height,
288 if (
codec.length() > 0) {
289 const AVCodec *new_codec = avcodec_find_encoder_by_name(
codec.c_str());
290 if (new_codec == NULL)
291 throw InvalidCodec(
"A valid audio codec could not be found for this file.", path);
297 if (sample_rate > 7999)
306 if (original_sample_rate == 0)
308 if (original_channels == 0)
312 "FFmpegWriter::SetAudioOptions (" +
codec +
")",
313 "sample_rate", sample_rate,
314 "channels", channels,
315 "bit_rate", bit_rate);
326 true,
codec, sample_rate, 2,
335 AVCodecContext *c = NULL;
337 std::stringstream convert(value);
356 throw NoStreamsFound(
"The stream was not found. Be sure to call PrepareStreams() first.", path);
359 const AVOption *option = NULL;
367 if (option || (name ==
"g" || name ==
"qmin" || name ==
"qmax" || name ==
"max_b_frames" || name ==
"mb_decision" ||
368 name ==
"level" || name ==
"profile" || name ==
"slices" || name ==
"rc_min_rate" || name ==
"rc_max_rate" ||
369 name ==
"rc_buffer_size" || name ==
"crf" || name ==
"cqp" || name ==
"qp")) {
373 convert >> c->gop_size;
375 else if (name ==
"qmin")
379 else if (name ==
"qmax")
383 else if (name ==
"max_b_frames")
385 convert >> c->max_b_frames;
387 else if (name ==
"mb_decision")
389 convert >> c->mb_decision;
391 else if (name ==
"level")
395 else if (name ==
"profile")
397 convert >> c->profile;
399 else if (name ==
"slices")
401 convert >> c->slices;
403 else if (name ==
"rc_min_rate")
405 convert >> c->rc_min_rate;
407 else if (name ==
"rc_max_rate")
409 convert >> c->rc_max_rate;
411 else if (name ==
"rc_buffer_size")
413 convert >> c->rc_buffer_size;
415 else if (name ==
"cqp") {
421 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),63), 0);
425 switch (c->codec_id) {
426#if (LIBAVCODEC_VERSION_MAJOR >= 58)
428 case AV_CODEC_ID_AV1 :
430 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),63), 0);
433 case AV_CODEC_ID_VP8 :
434 c->bit_rate = 10000000;
435 av_opt_set_int(c->priv_data,
"qp", std::max(std::min(std::stoi(value), 63), 4), 0);
437 case AV_CODEC_ID_VP9 :
439 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value), 63), 0);
440 if (std::stoi(value) == 0) {
441 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
442 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
445 case AV_CODEC_ID_H264 :
446 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value), 51), 0);
447 if (std::stoi(value) == 0) {
448 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
452 case AV_CODEC_ID_HEVC :
453 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value), 51), 0);
454 if (std::stoi(value) == 0) {
455 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
456 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
461 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value), 63), 0);
465 }
else if (name ==
"crf") {
471 double mbs = 15000000.0;
480 c->bit_rate = (int)(mbs);
484 switch (c->codec_id) {
485#if (LIBAVCODEC_VERSION_MAJOR >= 58)
487 case AV_CODEC_ID_AV1 :
490 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value),63), 0);
493 case AV_CODEC_ID_VP8 :
494 c->bit_rate = 10000000;
495 av_opt_set_int(c->priv_data,
"crf", std::max(std::min(std::stoi(value), 63), 4), 0);
497 case AV_CODEC_ID_VP9 :
499 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value), 63), 0);
500 if (std::stoi(value) == 0) {
501 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
502 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
505 case AV_CODEC_ID_H264 :
506 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value), 51), 0);
507 if (std::stoi(value) == 0) {
508 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
512 case AV_CODEC_ID_HEVC :
513 if (strstr(
info.
vcodec.c_str(),
"svt_hevc") != NULL) {
514 av_opt_set_int(c->priv_data,
"preset", 7, 0);
515 av_opt_set_int(c->priv_data,
"forced-idr",1,0);
516 av_opt_set_int(c->priv_data,
"qp",std::min(std::stoi(value), 51),0);
519 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value), 51), 0);
521 if (std::stoi(value) == 0) {
522 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
523 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
529 double mbs = 15000000.0;
537 c->bit_rate = (int) (mbs);
540 }
else if (name ==
"qp") {
544#if (LIBAVCODEC_VERSION_MAJOR >= 58)
546 switch (c->codec_id) {
547 case AV_CODEC_ID_AV1 :
549 if (strstr(
info.
vcodec.c_str(),
"svtav1") != NULL) {
550 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),63), 0);
552 else if (strstr(
info.
vcodec.c_str(),
"rav1e") != NULL) {
555 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),255), 0);
557 else if (strstr(
info.
vcodec.c_str(),
"aom") != NULL) {
561 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value),63), 0);
564 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value),63), 0);
566 case AV_CODEC_ID_HEVC :
568 if (strstr(
info.
vcodec.c_str(),
"svt_hevc") != NULL) {
569 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),51), 0);
570 av_opt_set_int(c->priv_data,
"preset", 7, 0);
571 av_opt_set_int(c->priv_data,
"forced-idr",1,0);
578 AV_OPTION_SET(st, c->priv_data, name.c_str(), value.c_str(), c);
582 "FFmpegWriter::SetOption (" + (std::string)name +
")",
587 }
else if (name ==
"muxing_preset") {
588 if (value ==
"mp4_faststart") {
590 av_dict_set(&
mux_dict,
"movflags",
"faststart", 0);
591 }
else if (value ==
"mp4_fragmented") {
593 av_dict_set(&
mux_dict,
"movflags",
"frag_keyframe", 0);
594 av_dict_set(&
mux_dict,
"min_frag_duration",
"8000000", 0);
597 throw InvalidOptions(
"The option is not valid for this codec.", path);
608 if (avcodec_find_encoder_by_name(codec_name.c_str()) == NULL)
617 throw InvalidOptions(
"No video or audio options have been set. You must set has_video or has_audio (or both).", path);
620 "FFmpegWriter::PrepareStreams [" + path +
"]",
625 initialize_streams();
628 prepare_streams =
true;
634 throw InvalidOptions(
"No video or audio options have been set. You must set has_video or has_audio (or both).", path);
637 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
638 if (avio_open(&oc->pb, path.c_str(), AVIO_FLAG_WRITE) < 0)
639 throw InvalidFile(
"Could not open or write file.", path);
646 for (std::map<std::string, std::string>::iterator iter =
info.
metadata.begin(); iter !=
info.
metadata.end(); ++iter) {
647 av_dict_set(&oc->metadata, iter->first.c_str(), iter->second.c_str(), 0);
651 AVDictionary *dict = NULL;
653 bool is_mp4 = strcmp(oc->oformat->name,
"mp4");
654 bool is_mov = strcmp(oc->oformat->name,
"mov");
656 if (is_mp4 || is_mov)
660 if (avformat_write_header(oc, &dict) != 0) {
662 "FFmpegWriter::WriteHeader (avformat_write_header)");
663 throw InvalidFile(
"Could not write header to file.", path);
667 if (dict) av_dict_free(&dict);
680 throw WriterClosed(
"The FFmpegWriter is closed. Call Open() before calling this method.", path);
683 "FFmpegWriter::WriteFrame",
684 "frame->number", frame->number,
685 "is_writing", is_writing);
695void FFmpegWriter::write_frame(std::shared_ptr<Frame> frame) {
700 bool has_error_encoding_video =
false;
704 write_audio_packets(
false, frame);
708 process_video_packet(frame);
712 if (av_frames.count(frame)) {
714 AVFrame *frame_final = av_frames[frame];
717 if (!write_video_packet(frame, frame_final)) {
718 has_error_encoding_video =
true;
722 av_freep(&(frame_final->data[0]));
724 av_frames.erase(frame);
732 if (has_error_encoding_video)
739 "FFmpegWriter::WriteFrame (from Reader)",
744 for (int64_t number = start; number <= length; number++) {
746 std::shared_ptr<Frame> f = reader->
GetFrame(number);
757 write_audio_packets(
true, NULL);
766 av_write_trailer(oc);
769 write_trailer =
true;
775void FFmpegWriter::flush_encoders() {
778#if (LIBAVFORMAT_VERSION_MAJOR < 58)
792 video_timestamp += av_rescale_q(1, av_make_q(
info.
fps.
den,
info.
fps.
num), video_codec_ctx->time_base);
795 AVPacket* pkt = av_packet_alloc();
809 error_code = avcodec_send_frame(video_codec_ctx, NULL);
811 while (error_code >= 0) {
812 error_code = avcodec_receive_packet(video_codec_ctx, pkt);
813 if (error_code == AVERROR(EAGAIN)|| error_code == AVERROR_EOF) {
816 avcodec_flush_buffers(video_codec_ctx);
819 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
820 pkt->stream_index = video_st->index;
821 error_code = av_interleaved_write_frame(oc, pkt);
826 error_code = avcodec_encode_video2(video_codec_ctx, pkt, NULL, &got_packet);
830 if (error_code < 0) {
832 "FFmpegWriter::flush_encoders ERROR ["
833 + av_err2string(error_code) +
"]",
834 "error_code", error_code);
841 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
842 pkt->stream_index = video_st->index;
845 error_code = av_interleaved_write_frame(oc, pkt);
846 if (error_code < 0) {
848 "FFmpegWriter::flush_encoders ERROR ["
849 + av_err2string(error_code) +
"]",
850 "error_code", error_code);
859 AVPacket* pkt = av_packet_alloc();
866 pkt->pts = pkt->dts = audio_timestamp;
872 error_code = avcodec_send_frame(audio_codec_ctx, NULL);
874 error_code = avcodec_encode_audio2(audio_codec_ctx, pkt, NULL, &got_packet);
876 if (error_code < 0) {
878 "FFmpegWriter::flush_encoders ERROR ["
879 + av_err2string(error_code) +
"]",
880 "error_code", error_code);
888 pkt->pts = pkt->dts = audio_timestamp;
891 av_packet_rescale_ts(pkt, audio_codec_ctx->time_base, audio_st->time_base);
894 pkt->stream_index = audio_st->index;
895 pkt->flags |= AV_PKT_FLAG_KEY;
898 error_code = av_interleaved_write_frame(oc, pkt);
899 if (error_code < 0) {
901 "FFmpegWriter::flush_encoders ERROR ["
902 + av_err2string(error_code) +
"]",
903 "error_code", error_code);
907 audio_timestamp += pkt->duration;
917void FFmpegWriter::close_video(AVFormatContext *oc, AVStream *st)
922 av_buffer_unref(&hw_device_ctx);
923 hw_device_ctx = NULL;
929 if (video_codec_ctx !=
nullptr) {
931 av_free(video_codec_ctx);
936void FFmpegWriter::close_audio(AVFormatContext *oc, AVStream *st)
940 delete[] audio_outbuf;
941 delete[] audio_encoder_buffer;
944 audio_encoder_buffer = NULL;
960 if (audio_codec_ctx !=
nullptr) {
962 av_free(audio_codec_ctx);
974 close_video(oc, video_st);
976 close_audio(oc, audio_st);
979 if (image_rescalers.size() > 0)
982 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
992 avformat_free_context(oc);
997 prepare_streams =
false;
998 write_header =
false;
999 write_trailer =
false;
1005void FFmpegWriter::add_avframe(std::shared_ptr<Frame> frame, AVFrame *av_frame) {
1007 if (!av_frames.count(frame)) {
1009 av_frames[frame] = av_frame;
1017AVStream *FFmpegWriter::add_audio_stream() {
1019 const AVCodec *
codec = avcodec_find_encoder_by_name(
info.
acodec.c_str());
1021 throw InvalidCodec(
"A valid audio codec could not be found for this file.", path);
1024 if (audio_codec_ctx !=
nullptr) {
1029 AVStream* st = avformat_new_stream(oc,
codec);
1031 throw OutOfMemory(
"Could not allocate memory for the video stream.", path);
1035#if (LIBAVFORMAT_VERSION_MAJOR >= 58)
1036 st->codecpar->codec_id =
codec->id;
1038 AVCodecContext* c = audio_codec_ctx;
1040 c->codec_id =
codec->id;
1041 c->codec_type = AVMEDIA_TYPE_AUDIO;
1050 if (
codec->supported_samplerates) {
1052 for (i = 0;
codec->supported_samplerates[i] != 0; i++)
1058 if (
codec->supported_samplerates[i] == 0)
1059 throw InvalidSampleRate(
"An invalid sample rate was detected for this codec.", path);
1067 AVChannelLayout ch_layout;
1069 if (
codec->ch_layouts) {
1071 for (i = 0; av_channel_layout_check(&
codec->ch_layouts[i]); i++)
1072 if (av_channel_layout_compare(&ch_layout, &
codec->ch_layouts[i])) {
1074 av_channel_layout_copy(&c->ch_layout, &ch_layout);
1077 if (!av_channel_layout_check(&
codec->ch_layouts[i]))
1078 throw InvalidChannels(
"An invalid channel layout was detected (i.e. MONO / STEREO).", path);
1081 av_channel_layout_copy(&c->ch_layout, &ch_layout);
1084 if (
codec->channel_layouts) {
1086 for (i = 0;
codec->channel_layouts[i] != 0; i++)
1087 if (channel_layout ==
codec->channel_layouts[i]) {
1089 c->channel_layout = channel_layout;
1092 if (
codec->channel_layouts[i] == 0)
1093 throw InvalidChannels(
"An invalid channel layout was detected (i.e. MONO / STEREO).", path);
1096 c->channel_layout = channel_layout;
1100 if (
codec->sample_fmts) {
1101 for (
int i = 0;
codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) {
1103 c->sample_fmt =
codec->sample_fmts[i];
1107 if (c->sample_fmt == AV_SAMPLE_FMT_NONE) {
1109 c->sample_fmt = AV_SAMPLE_FMT_S16;
1113 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1114#if (LIBAVCODEC_VERSION_MAJOR >= 57)
1116 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1118 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1124const char* nb_channels_label;
1125const char* channel_layout_label;
1128 nb_channels = c->ch_layout.nb_channels;
1129 channel_layout = c->ch_layout.u.mask;
1130 nb_channels_label =
"c->ch_layout.nb_channels";
1131 channel_layout_label =
"c->ch_layout.u.mask";
1133 nb_channels = c->channels;
1134 nb_channels_label =
"c->channels";
1135 channel_layout_label =
"c->channel_layout";
1139 "FFmpegWriter::add_audio_stream",
1140 "c->codec_id", c->codec_id,
1141 "c->bit_rate", c->bit_rate,
1142 nb_channels_label, nb_channels,
1143 "c->sample_fmt", c->sample_fmt,
1144 channel_layout_label, channel_layout,
1145 "c->sample_rate", c->sample_rate);
1151AVStream *FFmpegWriter::add_video_stream() {
1153 const AVCodec *
codec = avcodec_find_encoder_by_name(
info.
vcodec.c_str());
1155 throw InvalidCodec(
"A valid video codec could not be found for this file.", path);
1158 if (video_codec_ctx !=
nullptr) {
1163 AVStream* st = avformat_new_stream(oc,
codec);
1165 throw OutOfMemory(
"Could not allocate memory for the video stream.", path);
1169#if (LIBAVFORMAT_VERSION_MAJOR >= 58)
1170 st->codecpar->codec_id =
codec->id;
1173 AVCodecContext* c = video_codec_ctx;
1175 c->codec_id =
codec->id;
1176 c->codec_type = AVMEDIA_TYPE_VIDEO;
1184#
if (LIBAVCODEC_VERSION_MAJOR >= 58)
1185 && c->codec_id != AV_CODEC_ID_AV1
1190 if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
1199 switch (c->codec_id) {
1200#if (LIBAVCODEC_VERSION_MAJOR >= 58)
1202 case AV_CODEC_ID_AV1 :
1206 if (strstr(
info.
vcodec.c_str(),
"aom") != NULL) {
1207 int calculated_quality = 35;
1210 av_opt_set_int(c->priv_data,
"crf", calculated_quality, 0);
1213 int calculated_quality = 50;
1216 av_opt_set_int(c->priv_data,
"qp", calculated_quality, 0);
1220 if (strstr(
info.
vcodec.c_str(),
"svtav1") != NULL) {
1221 av_opt_set_int(c->priv_data,
"preset", 6, 0);
1222 av_opt_set_int(c->priv_data,
"forced-idr",1,0);
1224 else if (strstr(
info.
vcodec.c_str(),
"rav1e") != NULL) {
1225 av_opt_set_int(c->priv_data,
"speed", 7, 0);
1226 av_opt_set_int(c->priv_data,
"tile-rows", 2, 0);
1227 av_opt_set_int(c->priv_data,
"tile-columns", 4, 0);
1229 else if (strstr(
info.
vcodec.c_str(),
"aom") != NULL) {
1232 av_opt_set_int(c->priv_data,
"tile-rows", 1, 0);
1233 av_opt_set_int(c->priv_data,
"tile-columns", 2, 0);
1234 av_opt_set_int(c->priv_data,
"row-mt", 1, 0);
1235 av_opt_set_int(c->priv_data,
"cpu-used", 3, 0);
1239 case AV_CODEC_ID_VP9 :
1240 case AV_CODEC_ID_HEVC :
1241 case AV_CODEC_ID_VP8 :
1242 case AV_CODEC_ID_H264 :
1278#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 26, 0)
1279 c->framerate = av_inv_q(c->time_base);
1281 st->avg_frame_rate = av_inv_q(c->time_base);
1286 c->max_b_frames = 10;
1287 if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO)
1289 c->max_b_frames = 2;
1290 if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO)
1296 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1297#if (LIBAVCODEC_VERSION_MAJOR >= 57)
1299 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1301 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1306 while (supported_pixel_formats != NULL && *supported_pixel_formats !=
PIX_FMT_NONE) {
1309 c->pix_fmt = *supported_pixel_formats;
1310 ++supported_pixel_formats;
1315 if (oc->oformat->video_codec == AV_CODEC_ID_RAWVIDEO) {
1319#if (LIBAVFORMAT_VERSION_MAJOR < 58)
1321 if (strcmp(oc->oformat->name,
"gif") != 0)
1324 oc->oformat->flags |= AVFMT_RAWPICTURE;
1334 "FFmpegWriter::add_video_stream ("
1335 + (std::string)oc->oformat->name +
" : "
1336 + (std::string)av_get_pix_fmt_name(c->pix_fmt) +
")",
1337 "c->codec_id", c->codec_id,
1338 "c->bit_rate", c->bit_rate,
1339 "c->pix_fmt", c->pix_fmt,
1340 "oc->oformat->flags", oc->oformat->flags);
1345void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st) {
1346 const AVCodec *
codec;
1355 codec = avcodec_find_encoder(audio_codec_ctx->codec_id);
1360 AVDictionary *
opts = NULL;
1361 av_dict_set(&
opts,
"strict",
"experimental", 0);
1364 if (avcodec_open2(audio_codec_ctx,
codec, &
opts) < 0)
1365 throw InvalidCodec(
"Could not open audio codec", path);
1369 av_dict_free(&
opts);
1373 if (audio_codec_ctx->frame_size <= 1) {
1379 case AV_CODEC_ID_PCM_S16LE:
1380 case AV_CODEC_ID_PCM_S16BE:
1381 case AV_CODEC_ID_PCM_U16LE:
1382 case AV_CODEC_ID_PCM_U16BE:
1383 audio_input_frame_size >>= 1;
1390 audio_input_frame_size = audio_codec_ctx->frame_size;
1394 initial_audio_input_frame_size = audio_input_frame_size;
1401 audio_outbuf =
new uint8_t[audio_outbuf_size];
1405 audio_encoder_buffer =
new uint8_t[audio_encoder_buffer_size];
1408 for (std::map<std::string, std::string>::iterator iter =
info.
metadata.begin(); iter !=
info.
metadata.end(); ++iter) {
1409 av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1413 "FFmpegWriter::open_audio",
1414 "audio_codec_ctx->thread_count", audio_codec_ctx->thread_count,
1415 "audio_input_frame_size", audio_input_frame_size,
1420void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) {
1421 const AVCodec *
codec;
1431 char *adapter_ptr = NULL;
1435 std::clog <<
"Encoding Device Nr: " << adapter_num <<
"\n";
1436 if (adapter_num < 3 && adapter_num >=0) {
1437#if defined(__linux__)
1438 snprintf(adapter,
sizeof(adapter),
"/dev/dri/renderD%d", adapter_num+128);
1440 adapter_ptr = adapter;
1441#elif defined(_WIN32) || defined(__APPLE__)
1449#if defined(__linux__)
1450 if( adapter_ptr != NULL && access( adapter_ptr, W_OK ) == 0 ) {
1451#elif defined(_WIN32) || defined(__APPLE__)
1452 if( adapter_ptr != NULL ) {
1455 "Encode Device present using device",
1456 "adapter", adapter_num);
1461 "Encode Device not present, using default");
1463 if (av_hwdevice_ctx_create(&hw_device_ctx,
1467 "FFmpegWriter::open_video ERROR creating hwdevice, Codec name:",
1482 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)
1483 video_codec_ctx->max_b_frames = 0;
1487 av_dict_set(&
opts,
"strict",
"experimental", 0);
1501 if (av_opt_get_int(video_codec_ctx->priv_data,
"qp", 0, &qp) != 0 || qp == 0) {
1503 av_opt_set(video_codec_ctx->priv_data,
"rc_mode",
"VBR", 0);
1507 video_codec_ctx->rc_max_rate = video_codec_ctx->bit_rate;
1511 switch (video_codec_ctx->codec_id) {
1512 case AV_CODEC_ID_H264:
1513 video_codec_ctx->max_b_frames = 0;
1514 video_codec_ctx->profile = FF_PROFILE_H264_BASELINE | FF_PROFILE_H264_CONSTRAINED;
1515 av_opt_set(video_codec_ctx->priv_data,
"preset",
"slow", 0);
1516 av_opt_set(video_codec_ctx->priv_data,
"tune",
"zerolatency", 0);
1517 av_opt_set(video_codec_ctx->priv_data,
"vprofile",
"baseline", AV_OPT_SEARCH_CHILDREN);
1519 case AV_CODEC_ID_HEVC:
1522 case AV_CODEC_ID_VP9:
1527 "No codec-specific options defined for this codec. HW encoding may fail",
1528 "codec_id", video_codec_ctx->codec_id);
1537 "FFmpegWriter::open_video (set_hwframe_ctx) ERROR faled to set hwframe context",
1540 av_err2string(err), -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 source_image_width = frame->GetWidth();
2056 int source_image_height = frame->GetHeight();
2059 if (source_image_height == 1 && source_image_width == 1)
2063 if (image_rescalers.size() == 0)
2064 InitScalers(source_image_width, source_image_height);
2067 SwsContext *scaler = image_rescalers[rescaler_position];
2068 rescaler_position++;
2069 if (rescaler_position == num_of_rescalers)
2070 rescaler_position = 0;
2073 int bytes_source = 0;
2074 int bytes_final = 0;
2075 AVFrame *frame_source = NULL;
2076 const uchar *pixels = NULL;
2079 pixels = frame->GetPixels();
2082 frame_source = allocate_avframe(
PIX_FMT_RGBA, source_image_width, source_image_height, &bytes_source, (uint8_t *) pixels);
2084 AVFrame *frame_final;
2087 frame_final = allocate_avframe(AV_PIX_FMT_NV12,
info.
width,
info.
height, &bytes_final, NULL);
2091 frame_final = allocate_avframe(
2092 (AVPixelFormat)(video_st->codecpar->format),
2097 AVFrame *frame_final = allocate_avframe(video_codec_ctx->pix_fmt,
info.
width,
info.
height, &bytes_final, NULL);
2103 "FFmpegWriter::process_video_packet",
2104 "frame->number", frame->number,
2105 "bytes_source", bytes_source,
2106 "bytes_final", bytes_final);
2109 sws_scale(scaler, frame_source->data, frame_source->linesize, 0,
2110 source_image_height, frame_final->data, frame_final->linesize);
2113 add_avframe(frame, frame_final);
2120bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *frame_final) {
2121#if (LIBAVFORMAT_VERSION_MAJOR >= 58)
2124 "FFmpegWriter::write_video_packet",
2125 "frame->number", frame->number,
2126 "oc->oformat->flags", oc->oformat->flags);
2134 "FFmpegWriter::write_video_packet",
2135 "frame->number", frame->number,
2136 "oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE);
2138 if (oc->oformat->flags & AVFMT_RAWPICTURE) {
2142 AVPacket* pkt = av_packet_alloc();
2145 av_init_packet(pkt);
2148 av_packet_from_data(
2149 pkt, frame_final->data[0],
2150 frame_final->linesize[0] * frame_final->height);
2152 pkt->flags |= AV_PKT_FLAG_KEY;
2153 pkt->stream_index = video_st->index;
2156 pkt->pts = video_timestamp;
2159 int error_code = av_interleaved_write_frame(oc, pkt);
2160 if (error_code < 0) {
2162 "FFmpegWriter::write_video_packet ERROR ["
2163 + av_err2string(error_code) +
"]",
2164 "error_code", error_code);
2175 AVPacket* pkt = av_packet_alloc();
2178 av_init_packet(pkt);
2182 pkt->pts = pkt->dts = AV_NOPTS_VALUE;
2185 frame_final->pts = video_timestamp;
2188 if (!(
hw_frame = av_frame_alloc())) {
2189 std::clog <<
"Error code: av_hwframe_alloc\n";
2191 if (av_hwframe_get_buffer(video_codec_ctx->hw_frames_ctx,
hw_frame, 0) < 0) {
2192 std::clog <<
"Error code: av_hwframe_get_buffer\n";
2195 std::clog <<
"Error hw_frames_ctx.\n";
2197 hw_frame->format = AV_PIX_FMT_NV12;
2198 if ( av_hwframe_transfer_data(
hw_frame, frame_final, 0) < 0) {
2199 std::clog <<
"Error while transferring frame data to surface.\n";
2201 av_frame_copy_props(
hw_frame, frame_final);
2205 int got_packet_ptr = 0;
2213 ret = avcodec_send_frame(video_codec_ctx,
hw_frame);
2217 ret = avcodec_send_frame(video_codec_ctx, frame_final);
2222 "FFmpegWriter::write_video_packet (Frame not sent)");
2223 if (ret == AVERROR(EAGAIN) ) {
2224 std::clog <<
"Frame EAGAIN\n";
2226 if (ret == AVERROR_EOF ) {
2227 std::clog <<
"Frame AVERROR_EOF\n";
2229 avcodec_send_frame(video_codec_ctx, NULL);
2233 ret = avcodec_receive_packet(video_codec_ctx, pkt);
2235 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
2236 avcodec_flush_buffers(video_codec_ctx);
2248 error_code = avcodec_encode_video2(video_codec_ctx, pkt, frame_final, &got_packet_ptr);
2249 if (error_code != 0) {
2251 "FFmpegWriter::write_video_packet ERROR ["
2252 + av_err2string(error_code) +
"]",
2253 "error_code", error_code);
2255 if (got_packet_ptr == 0) {
2257 "FFmpegWriter::write_video_packet (Frame gotpacket error)");
2262 if (error_code == 0 && got_packet_ptr) {
2264 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
2265 pkt->stream_index = video_st->index;
2268 int result = av_interleaved_write_frame(oc, pkt);
2271 "FFmpegWriter::write_video_packet ERROR ["
2272 + av_err2string(result) +
"]",
2291 video_timestamp += av_rescale_q(1, av_make_q(
info.
fps.
den,
info.
fps.
num), video_codec_ctx->time_base);
2300 av_dump_format(oc, 0, path.c_str(), 1);
2304void FFmpegWriter::InitScalers(
int source_width,
int source_height) {
2305 int scale_mode = SWS_FAST_BILINEAR;
2307 scale_mode = SWS_BICUBIC;
2311 for (
int x = 0; x < num_of_rescalers; x++) {
2315 img_convert_ctx = sws_getContext(source_width, source_height,
PIX_FMT_RGBA,
2320 img_convert_ctx = sws_getContext(source_width, source_height,
PIX_FMT_RGBA,
2322 scale_mode, NULL, NULL, NULL);
2326 image_rescalers.push_back(img_convert_ctx);
2332 original_sample_rate = sample_rate;
2333 original_channels = channels;
2339 for (
int x = 0; x < num_of_rescalers; x++)
2340 sws_freeContext(image_rescalers[x]);
2343 image_rescalers.clear();
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_GET_CODEC_PIXEL_FORMAT(av_stream, av_context)
#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_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 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...
void RemoveScalers()
Remove & deallocate all software scalers.
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.