41 static AVBufferRef *hw_device_ctx = NULL;
44 static 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);
73 #endif // USE_HW_ACCEL 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), cache_size(8), num_of_rescalers(32),
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);
117 void 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;
143 void 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());
187 #elif defined(_WIN32) 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());
219 #endif //__linux__/_WIN32/__APPLE__ 220 #else // USE_HW_ACCEL 221 new_codec = avcodec_find_encoder_by_name(codec.c_str());
222 #endif // USE_HW_ACCEL 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);
423 #endif // USE_HW_ACCEL 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);
482 #endif // USE_HW_ACCEL 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);
575 #endif // FFmpeg 4.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);
685 spooled_video_frames.push_back(frame);
688 spooled_audio_frames.push_back(frame);
691 "FFmpegWriter::WriteFrame",
692 "frame->number", frame->number,
693 "spooled_video_frames.size()", spooled_video_frames.size(),
694 "spooled_audio_frames.size()", spooled_audio_frames.size(),
695 "cache_size", cache_size,
696 "is_writing", is_writing);
699 if ((
int)spooled_video_frames.size() == cache_size || (int)spooled_audio_frames.size() == cache_size) {
701 write_queued_frames();
709 void FFmpegWriter::write_queued_frames() {
711 "FFmpegWriter::write_queued_frames",
712 "spooled_video_frames.size()", spooled_video_frames.size(),
713 "spooled_audio_frames.size()", spooled_audio_frames.size());
719 queued_video_frames = spooled_video_frames;
720 queued_audio_frames = spooled_audio_frames;
723 spooled_video_frames.clear();
724 spooled_audio_frames.clear();
727 bool has_error_encoding_video =
false;
730 if (
info.
has_audio && audio_st && !queued_audio_frames.empty())
731 write_audio_packets(
false);
734 while (!queued_video_frames.empty()) {
736 std::shared_ptr<Frame> frame = queued_video_frames.front();
739 processed_frames.push_back(frame);
743 process_video_packet(frame);
746 queued_video_frames.pop_front();
752 while (!processed_frames.empty()) {
754 std::shared_ptr<Frame> frame = processed_frames.front();
758 deallocate_frames.push_back(frame);
761 if (av_frames.count(frame)) {
763 AVFrame *frame_final = av_frames[frame];
766 bool success = write_video_packet(frame, frame_final);
768 has_error_encoding_video =
true;
773 processed_frames.pop_front();
777 while (!deallocate_frames.empty()) {
779 std::shared_ptr<Frame> frame = deallocate_frames.front();
782 if (av_frames.count(frame)) {
784 AVFrame *av_frame = av_frames[frame];
787 av_freep(&(av_frame->data[0]));
789 av_frames.erase(frame);
793 deallocate_frames.pop_front();
800 if (has_error_encoding_video)
807 "FFmpegWriter::WriteFrame (from Reader)",
812 for (int64_t number = start; number <= length; number++) {
814 std::shared_ptr<Frame> f = reader->
GetFrame(number);
824 write_queued_frames();
828 write_audio_packets(
true);
837 av_write_trailer(oc);
840 write_trailer =
true;
846 void FFmpegWriter::flush_encoders() {
849 #if (LIBAVFORMAT_VERSION_MAJOR < 58) 863 video_timestamp += av_rescale_q(1, av_make_q(
info.
fps.
den,
info.
fps.
num), video_codec_ctx->time_base);
866 AVPacket* pkt = av_packet_alloc();
880 error_code = avcodec_send_frame(video_codec_ctx, NULL);
882 while (error_code >= 0) {
883 error_code = avcodec_receive_packet(video_codec_ctx, pkt);
884 if (error_code == AVERROR(EAGAIN)|| error_code == AVERROR_EOF) {
887 avcodec_flush_buffers(video_codec_ctx);
890 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
891 pkt->stream_index = video_st->index;
892 error_code = av_interleaved_write_frame(oc, pkt);
894 #else // IS_FFMPEG_3_2 897 error_code = avcodec_encode_video2(video_codec_ctx, pkt, NULL, &got_packet);
899 #endif // IS_FFMPEG_3_2 901 if (error_code < 0) {
903 "FFmpegWriter::flush_encoders ERROR [" 904 + av_err2string(error_code) +
"]",
905 "error_code", error_code);
912 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
913 pkt->stream_index = video_st->index;
916 error_code = av_interleaved_write_frame(oc, pkt);
917 if (error_code < 0) {
919 "FFmpegWriter::flush_encoders ERROR [" 920 + av_err2string(error_code) +
"]",
921 "error_code", error_code);
930 AVPacket* pkt = av_packet_alloc();
937 pkt->pts = pkt->dts = audio_timestamp;
943 error_code = avcodec_send_frame(audio_codec_ctx, NULL);
945 error_code = avcodec_encode_audio2(audio_codec_ctx, pkt, NULL, &got_packet);
947 if (error_code < 0) {
949 "FFmpegWriter::flush_encoders ERROR [" 950 + av_err2string(error_code) +
"]",
951 "error_code", error_code);
959 pkt->pts = pkt->dts = audio_timestamp;
962 av_packet_rescale_ts(pkt, audio_codec_ctx->time_base, audio_st->time_base);
965 pkt->stream_index = audio_st->index;
966 pkt->flags |= AV_PKT_FLAG_KEY;
969 error_code = av_interleaved_write_frame(oc, pkt);
970 if (error_code < 0) {
972 "FFmpegWriter::flush_encoders ERROR [" 973 + av_err2string(error_code) +
"]",
974 "error_code", error_code);
978 audio_timestamp += pkt->duration;
988 void FFmpegWriter::close_video(AVFormatContext *oc, AVStream *st)
993 av_buffer_unref(&hw_device_ctx);
994 hw_device_ctx = NULL;
997 #endif // USE_HW_ACCEL 1001 void FFmpegWriter::close_audio(AVFormatContext *oc, AVStream *st)
1005 delete[] audio_outbuf;
1006 delete[] audio_encoder_buffer;
1008 audio_outbuf = NULL;
1009 audio_encoder_buffer = NULL;
1033 close_video(oc, video_st);
1035 close_audio(oc, audio_st);
1038 if (image_rescalers.size() > 0)
1041 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
1047 video_timestamp = 0;
1048 audio_timestamp = 0;
1051 avformat_free_context(oc);
1056 prepare_streams =
false;
1057 write_header =
false;
1058 write_trailer =
false;
1064 void FFmpegWriter::add_avframe(std::shared_ptr<Frame> frame, AVFrame *av_frame) {
1066 if (!av_frames.count(frame)) {
1068 av_frames[frame] = av_frame;
1076 AVStream *FFmpegWriter::add_audio_stream() {
1078 const AVCodec *
codec = avcodec_find_encoder_by_name(
info.
acodec.c_str());
1080 throw InvalidCodec(
"A valid audio codec could not be found for this file.", path);
1083 if (audio_codec_ctx !=
nullptr) {
1088 AVStream* st = avformat_new_stream(oc, codec);
1090 throw OutOfMemory(
"Could not allocate memory for the video stream.", path);
1094 #if (LIBAVFORMAT_VERSION_MAJOR >= 58) 1095 st->codecpar->codec_id = codec->id;
1097 AVCodecContext* c = audio_codec_ctx;
1099 c->codec_id = codec->id;
1100 c->codec_type = AVMEDIA_TYPE_AUDIO;
1107 if (codec->supported_samplerates) {
1109 for (i = 0; codec->supported_samplerates[i] != 0; i++)
1115 if (codec->supported_samplerates[i] == 0)
1116 throw InvalidSampleRate(
"An invalid sample rate was detected for this codec.", path);
1124 if (codec->channel_layouts) {
1126 for (i = 0; codec->channel_layouts[i] != 0; i++)
1127 if (channel_layout == codec->channel_layouts[i]) {
1129 c->channel_layout = channel_layout;
1132 if (codec->channel_layouts[i] == 0)
1133 throw InvalidChannels(
"An invalid channel layout was detected (i.e. MONO / STEREO).", path);
1136 c->channel_layout = channel_layout;
1139 if (codec->sample_fmts) {
1140 for (
int i = 0; codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) {
1142 c->sample_fmt = codec->sample_fmts[i];
1146 if (c->sample_fmt == AV_SAMPLE_FMT_NONE) {
1148 c->sample_fmt = AV_SAMPLE_FMT_S16;
1152 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1153 #if (LIBAVCODEC_VERSION_MAJOR >= 57) 1155 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1157 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1163 "FFmpegWriter::add_audio_stream",
1164 "c->codec_id", c->codec_id,
1165 "c->bit_rate", c->bit_rate,
1166 "c->channels", c->channels,
1167 "c->sample_fmt", c->sample_fmt,
1168 "c->channel_layout", c->channel_layout,
1169 "c->sample_rate", c->sample_rate);
1175 AVStream *FFmpegWriter::add_video_stream() {
1177 const AVCodec *
codec = avcodec_find_encoder_by_name(
info.
vcodec.c_str());
1179 throw InvalidCodec(
"A valid video codec could not be found for this file.", path);
1182 if (video_codec_ctx !=
nullptr) {
1187 AVStream* st = avformat_new_stream(oc, codec);
1189 throw OutOfMemory(
"Could not allocate memory for the video stream.", path);
1193 #if (LIBAVFORMAT_VERSION_MAJOR >= 58) 1194 st->codecpar->codec_id = codec->id;
1197 AVCodecContext* c = video_codec_ctx;
1199 c->codec_id = codec->id;
1200 c->codec_type = AVMEDIA_TYPE_VIDEO;
1208 #
if (LIBAVCODEC_VERSION_MAJOR >= 58)
1209 && c->codec_id != AV_CODEC_ID_AV1
1214 if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
1223 switch (c->codec_id) {
1224 #if (LIBAVCODEC_VERSION_MAJOR >= 58) 1226 case AV_CODEC_ID_AV1 :
1230 if (strstr(
info.
vcodec.c_str(),
"aom") != NULL) {
1231 int calculated_quality = 35;
1234 av_opt_set_int(c->priv_data,
"crf", calculated_quality, 0);
1237 int calculated_quality = 50;
1240 av_opt_set_int(c->priv_data,
"qp", calculated_quality, 0);
1244 if (strstr(
info.
vcodec.c_str(),
"svtav1") != NULL) {
1245 av_opt_set_int(c->priv_data,
"preset", 6, 0);
1246 av_opt_set_int(c->priv_data,
"forced-idr",1,0);
1248 else if (strstr(
info.
vcodec.c_str(),
"rav1e") != NULL) {
1249 av_opt_set_int(c->priv_data,
"speed", 7, 0);
1250 av_opt_set_int(c->priv_data,
"tile-rows", 2, 0);
1251 av_opt_set_int(c->priv_data,
"tile-columns", 4, 0);
1253 else if (strstr(
info.
vcodec.c_str(),
"aom") != NULL) {
1256 av_opt_set_int(c->priv_data,
"tile-rows", 1, 0);
1257 av_opt_set_int(c->priv_data,
"tile-columns", 2, 0);
1258 av_opt_set_int(c->priv_data,
"row-mt", 1, 0);
1259 av_opt_set_int(c->priv_data,
"cpu-used", 3, 0);
1263 case AV_CODEC_ID_VP9 :
1264 case AV_CODEC_ID_HEVC :
1265 case AV_CODEC_ID_VP8 :
1266 case AV_CODEC_ID_H264 :
1302 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 26, 0) 1303 c->framerate = av_inv_q(c->time_base);
1305 st->avg_frame_rate = av_inv_q(c->time_base);
1310 c->max_b_frames = 10;
1311 if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO)
1313 c->max_b_frames = 2;
1314 if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO)
1320 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1321 #if (LIBAVCODEC_VERSION_MAJOR >= 57) 1323 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1325 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1329 const PixelFormat *supported_pixel_formats = codec->pix_fmts;
1330 while (supported_pixel_formats != NULL && *supported_pixel_formats !=
PIX_FMT_NONE) {
1333 c->pix_fmt = *supported_pixel_formats;
1334 ++supported_pixel_formats;
1339 if (oc->oformat->video_codec == AV_CODEC_ID_RAWVIDEO) {
1343 #if (LIBAVFORMAT_VERSION_MAJOR < 58) 1345 if (strcmp(oc->oformat->name,
"gif") != 0)
1348 oc->oformat->flags |= AVFMT_RAWPICTURE;
1358 "FFmpegWriter::add_video_stream (" 1359 + (std::string)oc->oformat->name +
" : " 1360 + (std::string)av_get_pix_fmt_name(c->pix_fmt) +
")",
1361 "c->codec_id", c->codec_id,
1362 "c->bit_rate", c->bit_rate,
1363 "c->pix_fmt", c->pix_fmt,
1364 "oc->oformat->flags", oc->oformat->flags);
1369 void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st) {
1370 const AVCodec *
codec;
1377 codec = avcodec_find_encoder_by_name(
info.
acodec.c_str());
1379 codec = avcodec_find_encoder(audio_codec_ctx->codec_id);
1384 AVDictionary *
opts = NULL;
1385 av_dict_set(&opts,
"strict",
"experimental", 0);
1388 if (avcodec_open2(audio_codec_ctx, codec, &opts) < 0)
1389 throw InvalidCodec(
"Could not open audio codec", path);
1393 av_dict_free(&opts);
1397 if (audio_codec_ctx->frame_size <= 1) {
1403 case AV_CODEC_ID_PCM_S16LE:
1404 case AV_CODEC_ID_PCM_S16BE:
1405 case AV_CODEC_ID_PCM_U16LE:
1406 case AV_CODEC_ID_PCM_U16BE:
1407 audio_input_frame_size >>= 1;
1414 audio_input_frame_size = audio_codec_ctx->frame_size;
1418 initial_audio_input_frame_size = audio_input_frame_size;
1425 audio_outbuf =
new uint8_t[audio_outbuf_size];
1429 audio_encoder_buffer =
new uint8_t[audio_encoder_buffer_size];
1432 for (std::map<std::string, std::string>::iterator iter =
info.
metadata.begin(); iter !=
info.
metadata.end(); ++iter) {
1433 av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1437 "FFmpegWriter::open_audio",
1438 "audio_codec_ctx->thread_count", audio_codec_ctx->thread_count,
1439 "audio_input_frame_size", audio_input_frame_size,
1445 void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) {
1446 const AVCodec *
codec;
1456 char *adapter_ptr = NULL;
1460 std::clog <<
"Encoding Device Nr: " << adapter_num <<
"\n";
1461 if (adapter_num < 3 && adapter_num >=0) {
1462 #if defined(__linux__) 1463 snprintf(adapter,
sizeof(adapter),
"/dev/dri/renderD%d", adapter_num+128);
1465 adapter_ptr = adapter;
1466 #elif defined(_WIN32) || defined(__APPLE__) 1474 #if defined(__linux__) 1475 if( adapter_ptr != NULL && access( adapter_ptr, W_OK ) == 0 ) {
1476 #elif defined(_WIN32) || defined(__APPLE__) 1477 if( adapter_ptr != NULL ) {
1480 "Encode Device present using device",
1481 "adapter", adapter_num);
1486 "Encode Device not present, using default");
1488 if (av_hwdevice_ctx_create(&hw_device_ctx,
1492 "FFmpegWriter::open_video ERROR creating hwdevice, Codec name:",
1497 #endif // USE_HW_ACCEL 1507 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)
1508 video_codec_ctx->max_b_frames = 0;
1512 av_dict_set(&opts,
"strict",
"experimental", 0);
1526 if (av_opt_get_int(video_codec_ctx->priv_data,
"qp", 0, &qp) != 0 || qp == 0) {
1528 av_opt_set(video_codec_ctx->priv_data,
"rc_mode",
"VBR", 0);
1532 video_codec_ctx->rc_max_rate = video_codec_ctx->bit_rate;
1536 switch (video_codec_ctx->codec_id) {
1537 case AV_CODEC_ID_H264:
1538 video_codec_ctx->max_b_frames = 0;
1539 video_codec_ctx->profile = FF_PROFILE_H264_BASELINE | FF_PROFILE_H264_CONSTRAINED;
1540 av_opt_set(video_codec_ctx->priv_data,
"preset",
"slow", 0);
1541 av_opt_set(video_codec_ctx->priv_data,
"tune",
"zerolatency", 0);
1542 av_opt_set(video_codec_ctx->priv_data,
"vprofile",
"baseline", AV_OPT_SEARCH_CHILDREN);
1544 case AV_CODEC_ID_HEVC:
1547 case AV_CODEC_ID_VP9:
1552 "No codec-specific options defined for this codec. HW encoding may fail",
1553 "codec_id", video_codec_ctx->codec_id);
1559 if ((err = set_hwframe_ctx(
1560 video_codec_ctx, hw_device_ctx,
1564 "FFmpegWriter::open_video (set_hwframe_ctx) ERROR faled to set hwframe context",
1567 av_err2string(err), -1);
1570 #endif // USE_HW_ACCEL 1573 if (avcodec_open2(video_codec_ctx, codec, &opts) < 0)
1574 throw InvalidCodec(
"Could not open video codec", path);
1578 av_dict_free(&opts);
1582 av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1586 "FFmpegWriter::open_video",
1587 "video_codec_ctx->thread_count", video_codec_ctx->thread_count);
1592 void FFmpegWriter::write_audio_packets(
bool is_final) {
1594 int total_frame_samples = 0;
1595 int frame_position = 0;
1596 int channels_in_frame = 0;
1597 int sample_rate_in_frame = 0;
1598 int samples_in_frame = 0;
1603 int16_t *all_queued_samples = (int16_t *) av_malloc(all_queued_samples_size);
1604 int16_t *all_resampled_samples = NULL;
1605 int16_t *final_samples_planar = NULL;
1606 int16_t *final_samples = NULL;
1609 while (!queued_audio_frames.empty()) {
1611 std::shared_ptr<Frame> frame = queued_audio_frames.front();
1614 sample_rate_in_frame = frame->SampleRate();
1615 samples_in_frame = frame->GetAudioSamplesCount();
1616 channels_in_frame = frame->GetAudioChannelsCount();
1617 channel_layout_in_frame = frame->ChannelsLayout();
1620 float *frame_samples_float = NULL;
1622 frame_samples_float = frame->GetInterleavedAudioSamples(sample_rate_in_frame, NULL, &samples_in_frame);
1625 total_frame_samples = samples_in_frame * channels_in_frame;
1628 const int16_t max16 = 32767;
1629 const int16_t min16 = -32768;
1630 for (
int s = 0; s < total_frame_samples; s++, frame_position++) {
1631 float valF = frame_samples_float[s] * (1 << 15);
1635 }
else if (valF < min16) {
1638 conv = int(valF + 32768.5) - 32768;
1642 all_queued_samples[frame_position] = conv;
1646 delete[] frame_samples_float;
1649 queued_audio_frames.pop_front();
1655 total_frame_samples = frame_position;
1656 int remaining_frame_samples = total_frame_samples;
1657 int samples_position = 0;
1661 "FFmpegWriter::write_audio_packets",
1662 "is_final", is_final,
1663 "total_frame_samples", total_frame_samples,
1664 "channel_layout_in_frame", channel_layout_in_frame,
1665 "channels_in_frame", channels_in_frame,
1666 "samples_in_frame", samples_in_frame,
1670 AVSampleFormat output_sample_fmt = audio_codec_ctx->sample_fmt;
1672 AVFrame *audio_frame = NULL;
1677 audio_frame->nb_samples = total_frame_samples / channels_in_frame;
1680 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);
1681 if (error_code < 0) {
1683 "FFmpegWriter::write_audio_packets ERROR [" 1684 + av_err2string(error_code) +
"]",
1685 "error_code", error_code);
1689 switch (audio_codec_ctx->sample_fmt) {
1690 case AV_SAMPLE_FMT_FLTP: {
1691 output_sample_fmt = AV_SAMPLE_FMT_FLT;
1694 case AV_SAMPLE_FMT_S32P: {
1695 output_sample_fmt = AV_SAMPLE_FMT_S32;
1698 case AV_SAMPLE_FMT_S16P: {
1699 output_sample_fmt = AV_SAMPLE_FMT_S16;
1702 case AV_SAMPLE_FMT_U8P: {
1703 output_sample_fmt = AV_SAMPLE_FMT_U8;
1713 total_frame_samples *= (float(
info.
sample_rate) / sample_rate_in_frame);
1714 total_frame_samples *= (float(
info.
channels) / channels_in_frame);
1719 audio_converted->nb_samples = total_frame_samples / channels_in_frame;
1720 av_samples_alloc(audio_converted->data, audio_converted->linesize,
info.
channels, audio_converted->nb_samples, output_sample_fmt, 0);
1723 "FFmpegWriter::write_audio_packets (1st resampling)",
1724 "in_sample_fmt", AV_SAMPLE_FMT_S16,
1725 "out_sample_fmt", output_sample_fmt,
1726 "in_sample_rate", sample_rate_in_frame,
1728 "in_channels", channels_in_frame,
1734 av_opt_set_int(avr,
"in_channel_layout", channel_layout_in_frame, 0);
1736 av_opt_set_int(avr,
"in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
1737 av_opt_set_int(avr,
"out_sample_fmt", output_sample_fmt, 0);
1738 av_opt_set_int(avr,
"in_sample_rate", sample_rate_in_frame, 0);
1740 av_opt_set_int(avr,
"in_channels", channels_in_frame, 0);
1747 audio_converted->data,
1748 audio_converted->linesize[0],
1749 audio_converted->nb_samples,
1751 audio_frame->linesize[0],
1752 audio_frame->nb_samples
1756 remaining_frame_samples = total_frame_samples;
1759 all_resampled_samples = (int16_t *) av_malloc(
1761 * (av_get_bytes_per_sample(output_sample_fmt) /
1762 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1766 memcpy(all_resampled_samples, audio_converted->data[0],
1767 static_cast<size_t>(nb_samples)
1769 * av_get_bytes_per_sample(output_sample_fmt));
1772 av_freep(&(audio_frame->data[0]));
1774 av_freep(&audio_converted->data[0]);
1776 all_queued_samples = NULL;
1779 "FFmpegWriter::write_audio_packets (Successfully completed 1st resampling)",
1780 "nb_samples", nb_samples,
1781 "remaining_frame_samples", remaining_frame_samples);
1785 while (remaining_frame_samples > 0 || is_final) {
1787 int remaining_packet_samples = (audio_input_frame_size *
info.
channels) - audio_input_position;
1791 if (remaining_frame_samples >= remaining_packet_samples) {
1792 diff = remaining_packet_samples;
1794 diff = remaining_frame_samples;
1801 samples + (audio_input_position
1802 * (av_get_bytes_per_sample(output_sample_fmt) /
1803 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1805 all_resampled_samples + samples_position,
1806 static_cast<size_t>(diff)
1807 * av_get_bytes_per_sample(output_sample_fmt)
1811 audio_input_position += diff;
1812 samples_position += diff * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16));
1813 remaining_frame_samples -= diff;
1816 if (audio_input_position < (audio_input_frame_size *
info.
channels) && !is_final)
1823 if (av_sample_fmt_is_planar(audio_codec_ctx->sample_fmt)) {
1825 "FFmpegWriter::write_audio_packets (2nd resampling for Planar formats)",
1826 "in_sample_fmt", output_sample_fmt,
1827 "out_sample_fmt", audio_codec_ctx->sample_fmt,
1839 av_opt_set_int(avr_planar,
"in_sample_fmt", output_sample_fmt, 0);
1840 av_opt_set_int(avr_planar,
"out_sample_fmt", audio_codec_ctx->sample_fmt, 0);
1843 av_opt_set_int(avr_planar,
"in_channels",
info.
channels, 0);
1844 av_opt_set_int(avr_planar,
"out_channels",
info.
channels, 0);
1851 audio_frame->nb_samples = audio_input_position /
info.
channels;
1854 final_samples_planar = (int16_t *) av_malloc(
1855 sizeof(int16_t) * audio_frame->nb_samples *
info.
channels 1856 * (av_get_bytes_per_sample(output_sample_fmt) /
1857 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) )
1861 memcpy(final_samples_planar, samples,
1862 static_cast<size_t>(audio_frame->nb_samples)
1864 * av_get_bytes_per_sample(output_sample_fmt));
1867 avcodec_fill_audio_frame(audio_frame,
info.
channels, output_sample_fmt,
1868 (uint8_t *) final_samples_planar, audio_encoder_buffer_size, 0);
1871 frame_final->nb_samples = audio_input_frame_size;
1873 frame_final->format = audio_codec_ctx->sample_fmt;
1875 av_samples_alloc(frame_final->data, frame_final->linesize,
info.
channels,
1876 frame_final->nb_samples, audio_codec_ctx->sample_fmt, 0);
1882 frame_final->linesize[0],
1883 frame_final->nb_samples,
1885 audio_frame->linesize[0],
1886 audio_frame->nb_samples
1890 const auto copy_length =
static_cast<size_t>(nb_samples)
1891 * av_get_bytes_per_sample(audio_codec_ctx->sample_fmt)
1895 memcpy(samples, frame_final->data[0], copy_length);
1898 av_freep(&(audio_frame->data[0]));
1900 all_queued_samples = NULL;
1903 "FFmpegWriter::write_audio_packets (Successfully completed 2nd resampling for Planar formats)",
1904 "nb_samples", nb_samples);
1908 const auto buf_size =
static_cast<size_t>(audio_input_position)
1909 * (av_get_bytes_per_sample(audio_codec_ctx->sample_fmt) /
1910 av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)
1912 final_samples =
reinterpret_cast<int16_t*
>(
1913 av_malloc(
sizeof(int16_t) * buf_size));
1916 memcpy(final_samples, samples,
1917 audio_input_position * av_get_bytes_per_sample(audio_codec_ctx->sample_fmt));
1920 frame_final->nb_samples = audio_input_frame_size;
1923 avcodec_fill_audio_frame(frame_final, audio_codec_ctx->channels,
1924 audio_codec_ctx->sample_fmt, (uint8_t *) final_samples,
1925 audio_encoder_buffer_size, 0);
1929 frame_final->pts = audio_timestamp;
1933 AVPacket* pkt = av_packet_alloc();
1936 av_init_packet(pkt);
1938 pkt->data = audio_encoder_buffer;
1939 pkt->size = audio_encoder_buffer_size;
1942 pkt->pts = pkt->dts = audio_timestamp;
1945 int got_packet_ptr = 0;
1951 int frame_finished = 0;
1952 error_code = ret = avcodec_send_frame(audio_codec_ctx, frame_final);
1953 if (ret < 0 && ret != AVERROR(EINVAL) && ret != AVERROR_EOF) {
1954 avcodec_send_frame(audio_codec_ctx, NULL);
1959 ret = avcodec_receive_packet(audio_codec_ctx, pkt);
1962 if(ret == AVERROR(EINVAL) || ret == AVERROR_EOF) {
1963 avcodec_flush_buffers(audio_codec_ctx);
1967 ret = frame_finished;
1970 if (!pkt->data && !frame_finished)
1974 got_packet_ptr = ret;
1977 int error_code = avcodec_encode_audio2(audio_codec_ctx, pkt, frame_final, &got_packet_ptr);
1980 if (error_code == 0 && got_packet_ptr) {
1984 pkt->pts = pkt->dts = audio_timestamp;
1987 av_packet_rescale_ts(pkt, audio_codec_ctx->time_base, audio_st->time_base);
1990 pkt->stream_index = audio_st->index;
1991 pkt->flags |= AV_PKT_FLAG_KEY;
1994 error_code = av_interleaved_write_frame(oc, pkt);
1997 if (error_code < 0) {
1999 "FFmpegWriter::write_audio_packets ERROR [" 2000 + av_err2string(error_code) +
"]",
2001 "error_code", error_code);
2005 audio_timestamp += FFMIN(audio_input_frame_size, audio_input_position);
2008 av_freep(&(frame_final->data[0]));
2015 audio_input_position = 0;
2020 if (all_resampled_samples) {
2021 av_freep(&all_resampled_samples);
2022 all_resampled_samples = NULL;
2024 if (all_queued_samples) {
2025 av_freep(&all_queued_samples);
2026 all_queued_samples = NULL;
2031 AVFrame *FFmpegWriter::allocate_avframe(
PixelFormat pix_fmt,
int width,
int height,
int *buffer_size, uint8_t *new_buffer) {
2033 AVFrame *new_av_frame = NULL;
2037 if (new_av_frame == NULL)
2038 throw OutOfMemory(
"Could not allocate AVFrame", path);
2046 new_buffer = (uint8_t *) av_malloc(*buffer_size *
sizeof(uint8_t));
2049 new_av_frame->width = width;
2050 new_av_frame->height = height;
2051 new_av_frame->format = pix_fmt;
2055 return new_av_frame;
2059 void FFmpegWriter::process_video_packet(std::shared_ptr<Frame> frame) {
2061 int source_image_width = frame->GetWidth();
2062 int source_image_height = frame->GetHeight();
2065 if (source_image_height == 1 && source_image_width == 1)
2069 if (image_rescalers.size() == 0)
2070 InitScalers(source_image_width, source_image_height);
2073 SwsContext *scaler = image_rescalers[rescaler_position];
2074 rescaler_position++;
2075 if (rescaler_position == num_of_rescalers)
2076 rescaler_position = 0;
2079 int bytes_source = 0;
2080 int bytes_final = 0;
2081 AVFrame *frame_source = NULL;
2082 const uchar *pixels = NULL;
2085 pixels = frame->GetPixels();
2088 frame_source = allocate_avframe(
PIX_FMT_RGBA, source_image_width, source_image_height, &bytes_source, (uint8_t *) pixels);
2090 AVFrame *frame_final;
2093 frame_final = allocate_avframe(AV_PIX_FMT_NV12,
info.
width,
info.
height, &bytes_final, NULL);
2095 #endif // USE_HW_ACCEL 2097 frame_final = allocate_avframe(
2098 (AVPixelFormat)(video_st->codecpar->format),
2103 AVFrame *frame_final = allocate_avframe(video_codec_ctx->pix_fmt,
info.
width,
info.
height, &bytes_final, NULL);
2104 #endif // IS_FFMPEG_3_2 2109 "FFmpegWriter::process_video_packet",
2110 "frame->number", frame->number,
2111 "bytes_source", bytes_source,
2112 "bytes_final", bytes_final);
2115 sws_scale(scaler, frame_source->data, frame_source->linesize, 0,
2116 source_image_height, frame_final->data, frame_final->linesize);
2119 add_avframe(frame, frame_final);
2126 bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *frame_final) {
2127 #if (LIBAVFORMAT_VERSION_MAJOR >= 58) 2130 "FFmpegWriter::write_video_packet",
2131 "frame->number", frame->number,
2132 "oc->oformat->flags", oc->oformat->flags);
2140 "FFmpegWriter::write_video_packet",
2141 "frame->number", frame->number,
2142 "oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE);
2144 if (oc->oformat->flags & AVFMT_RAWPICTURE) {
2148 AVPacket* pkt = av_packet_alloc();
2151 av_init_packet(pkt);
2154 av_packet_from_data(
2155 pkt, frame_final->data[0],
2156 frame_final->linesize[0] * frame_final->height);
2158 pkt->flags |= AV_PKT_FLAG_KEY;
2159 pkt->stream_index = video_st->index;
2162 pkt->pts = video_timestamp;
2165 int error_code = av_interleaved_write_frame(oc, pkt);
2166 if (error_code < 0) {
2168 "FFmpegWriter::write_video_packet ERROR [" 2169 + av_err2string(error_code) +
"]",
2170 "error_code", error_code);
2181 AVPacket* pkt = av_packet_alloc();
2184 av_init_packet(pkt);
2188 pkt->pts = pkt->dts = AV_NOPTS_VALUE;
2191 frame_final->pts = video_timestamp;
2194 if (!(
hw_frame = av_frame_alloc())) {
2195 std::clog <<
"Error code: av_hwframe_alloc\n";
2197 if (av_hwframe_get_buffer(video_codec_ctx->hw_frames_ctx,
hw_frame, 0) < 0) {
2198 std::clog <<
"Error code: av_hwframe_get_buffer\n";
2201 std::clog <<
"Error hw_frames_ctx.\n";
2203 hw_frame->format = AV_PIX_FMT_NV12;
2204 if ( av_hwframe_transfer_data(
hw_frame, frame_final, 0) < 0) {
2205 std::clog <<
"Error while transferring frame data to surface.\n";
2207 av_frame_copy_props(
hw_frame, frame_final);
2209 #endif // USE_HW_ACCEL 2211 int got_packet_ptr = 0;
2219 ret = avcodec_send_frame(video_codec_ctx,
hw_frame);
2221 #endif // USE_HW_ACCEL 2223 ret = avcodec_send_frame(video_codec_ctx, frame_final);
2228 "FFmpegWriter::write_video_packet (Frame not sent)");
2229 if (ret == AVERROR(EAGAIN) ) {
2230 std::clog <<
"Frame EAGAIN\n";
2232 if (ret == AVERROR_EOF ) {
2233 std::clog <<
"Frame AVERROR_EOF\n";
2235 avcodec_send_frame(video_codec_ctx, NULL);
2239 ret = avcodec_receive_packet(video_codec_ctx, pkt);
2241 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
2242 avcodec_flush_buffers(video_codec_ctx);
2254 error_code = avcodec_encode_video2(video_codec_ctx, pkt, frame_final, &got_packet_ptr);
2255 if (error_code != 0) {
2257 "FFmpegWriter::write_video_packet ERROR [" 2258 + av_err2string(error_code) +
"]",
2259 "error_code", error_code);
2261 if (got_packet_ptr == 0) {
2263 "FFmpegWriter::write_video_packet (Frame gotpacket error)");
2265 #endif // IS_FFMPEG_3_2 2268 if (error_code == 0 && got_packet_ptr) {
2270 av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
2271 pkt->stream_index = video_st->index;
2274 int result = av_interleaved_write_frame(oc, pkt);
2277 "FFmpegWriter::write_video_packet ERROR [" 2278 + av_err2string(result) +
"]",
2293 #endif // USE_HW_ACCEL 2297 video_timestamp += av_rescale_q(1, av_make_q(
info.
fps.
den,
info.
fps.
num), video_codec_ctx->time_base);
2306 av_dump_format(oc, 0, path.c_str(), 1);
2310 void FFmpegWriter::InitScalers(
int source_width,
int source_height) {
2311 int scale_mode = SWS_FAST_BILINEAR;
2313 scale_mode = SWS_BICUBIC;
2317 for (
int x = 0; x < num_of_rescalers; x++) {
2321 img_convert_ctx = sws_getContext(source_width, source_height,
PIX_FMT_RGBA,
2324 #endif // USE_HW_ACCEL 2326 img_convert_ctx = sws_getContext(source_width, source_height,
PIX_FMT_RGBA,
2328 scale_mode, NULL, NULL, NULL);
2332 image_rescalers.push_back(img_convert_ctx);
2338 original_sample_rate = sample_rate;
2339 original_channels = channels;
2345 for (
int x = 0; x < num_of_rescalers; x++)
2346 sws_freeContext(image_rescalers[x]);
2349 image_rescalers.clear();
#define AV_RESET_FRAME(av_frame)
int channels
The number of audio channels used in the audio stream.
A video stream (used to determine which type of stream)
#define AV_FREE_FRAME(av_frame)
int num
Numerator for the fraction.
WriterInfo info
Information about the current media file.
void OutputStreamInfo()
Output the ffmpeg info about this format, streams, and codecs (i.e. dump format)
#define AV_FIND_DECODER_CODEC_ID(av_stream)
An audio stream (used to determine which type of stream)
int video_bit_rate
The bit rate of the video stream (in bytes)
Exception when an invalid # of audio channels are detected.
#define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height)
Header file for OpenMPUtilities (set some common macros)
#define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context)
openshot::Fraction display_ratio
The ratio of width to height of the video stream (i.e. 640x480 has a ratio of 4/3) ...
void Reduce()
Reduce this fraction (i.e. 640/480 = 4/3)
static bool IsValidCodec(std::string codec_name)
Determine if codec name is valid.
AV_COPY_PARAMS_FROM_CONTEXT(st, video_codec_ctx)
#define AV_GET_CODEC_FROM_STREAM(av_stream, codec_in)
#define AV_OPTION_FIND(priv_data, name)
#define AVCODEC_MAX_AUDIO_FRAME_SIZE
This abstract class is the base class, used by all readers in libopenshot.
int width
The width of the video (in pixels)
int audio_bit_rate
The bit rate of the audio stream (in bytes)
Header file for FFmpegWriter class.
openshot::Fraction video_timebase
The video timebase determines how long each frame stays on the screen.
std::string acodec
The name of the audio codec used to encode / decode the video stream.
openshot::ChannelLayout channel_layout
The channel layout (mono, stereo, 5 point surround, etc...)
openshot::Fraction pixel_ratio
The pixel ratio of the video stream as a fraction (i.e. some pixels are not square) ...
AVPixelFormat hw_en_av_pix_fmt
Exception when encoding audio packet.
Exception when invalid sample rate is detected during encoding.
void WriteFrame(std::shared_ptr< openshot::Frame > frame)
Add a frame to the stack waiting to be encoded.
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.
AVHWDeviceType hw_en_av_device_type
virtual std::shared_ptr< openshot::Frame > GetFrame(int64_t number)=0
Header file for all Exception classes.
#define AV_FREE_CONTEXT(av_context)
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.
Exception when no valid codec is found for a file.
Exception when memory could not be allocated.
Header file for Frame class.
#define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context)
Exception when invalid encoding options are used.
#define FF_NUM_PROCESSORS
void SetAudioOptions(bool has_audio, std::string codec, int sample_rate, int channels, openshot::ChannelLayout channel_layout, int bit_rate)
Set audio export options.
#define AV_FREE_PACKET(av_packet)
Exception when no streams are found in the file.
void RemoveScalers()
Remove & deallocate all software scalers.
#define AV_ALLOCATE_FRAME()
bool top_field_first
Which interlaced field should be displayed first.
Exception for files that can not be found or opened.
This class represents a fraction.
Header file for ZeroMQ-based Logger class.
void ResampleAudio(int sample_rate, int channels)
Set audio resample options.
ChannelLayout
This enumeration determines the audio channel layout (such as stereo, mono, 5 point surround...
Header file for global Settings class.
void WriteTrailer()
Write the file trailer (after all frames are written). This is called automatically by the Close() me...
void WriteHeader()
Write the file header (after the options are set). This method is called automatically by the Open() ...
void Close()
Close the writer.
bool interlaced_frame
Are the contents of this frame interlaced.
int sample_rate
The number of audio samples per second (44100 is a common sample rate)
#define MY_INPUT_BUFFER_PADDING_SIZE
#define AV_GET_IMAGE_SIZE(pix_fmt, width, height)
#define AV_OUTPUT_CONTEXT(output_context, path)
bool has_video
Determines if this file has a video stream.
static ZmqLogger * Instance()
Create or get an instance of this logger singleton (invoke the class with this method) ...
std::map< std::string, std::string > metadata
An optional map/dictionary of video & audio metadata.
This namespace is the default namespace for all code in the openshot library.
#define SWR_CONVERT(ctx, out, linesize, out_count, in, linesize2, in_count)
#define AV_GET_CODEC_TYPE(av_stream)
#define AV_OPTION_SET(av_stream, priv_data, name, value, avcodec)
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)
bool has_audio
Determines if this file has an audio stream.
#define AV_SET_FILENAME(oc, f)
std::string vcodec
The name of the video codec used to encode / decode the video stream.
Exception when too many seek attempts happen.
void PrepareStreams()
Prepare & initialize streams and open codecs. This method is called automatically by the Open() metho...
int height
The height of the video (in pixels)
int den
Denominator for the fraction.
Header file for FFmpegUtilities.
FFmpegWriter(const std::string &path)
Constructor for FFmpegWriter. Throws an exception on failure to open path.
openshot::Fraction fps
Frames per second, as a fraction (i.e. 24/1 = 24 fps)
#define ALLOC_CODEC_CTX(ctx, codec, stream)
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...
#define AUDIO_PACKET_ENCODING_SIZE
StreamType
This enumeration designates the type of stream when encoding (video or audio)
#define AV_GET_CODEC_PAR_CONTEXT(av_stream, av_codec)