34 #include "../include/FFmpegWriter.h" 39 #pragma message "You are compiling with experimental hardware encode" 41 #pragma message "You are compiling only with software encode" 52 static AVBufferRef *hw_device_ctx = NULL;
55 static int set_hwframe_ctx(AVCodecContext *ctx, AVBufferRef *hw_device_ctx, int64_t width, int64_t height)
57 AVBufferRef *hw_frames_ref;
58 AVHWFramesContext *frames_ctx = NULL;
61 if (!(hw_frames_ref = av_hwframe_ctx_alloc(hw_device_ctx))) {
62 fprintf(stderr,
"Failed to create HW frame context.\n");
65 frames_ctx = (AVHWFramesContext *)(hw_frames_ref->data);
67 frames_ctx->sw_format = AV_PIX_FMT_NV12;
68 frames_ctx->width = width;
69 frames_ctx->height = height;
70 frames_ctx->initial_pool_size = 20;
71 if ((err = av_hwframe_ctx_init(hw_frames_ref)) < 0) {
72 fprintf(stderr,
"Failed to initialize HW frame context." 74 av_buffer_unref(&hw_frames_ref);
77 ctx->hw_frames_ctx = av_buffer_ref(hw_frames_ref);
78 if (!ctx->hw_frames_ctx)
79 err = AVERROR(ENOMEM);
81 av_buffer_unref(&hw_frames_ref);
87 path(path), fmt(NULL), oc(NULL), audio_st(NULL), video_st(NULL), audio_pts(0), video_pts(0), samples(NULL),
88 audio_outbuf(NULL), audio_outbuf_size(0), audio_input_frame_size(0), audio_input_position(0),
89 initial_audio_input_frame_size(0), img_convert_ctx(NULL), cache_size(8), num_of_rescalers(32),
90 rescaler_position(0), video_codec(NULL), audio_codec(NULL), is_writing(false), write_video_count(0), write_audio_count(0),
91 original_sample_rate(0), original_channels(0), avr(NULL), avr_planar(NULL), is_open(false), prepare_streams(false),
92 write_header(false), write_trailer(false), audio_encoder_buffer_size(0), audio_encoder_buffer(NULL) {
102 auto_detect_format();
112 if (!prepare_streams)
117 open_video(oc, video_st);
119 open_audio(oc, audio_st);
128 void FFmpegWriter::auto_detect_format() {
130 fmt = av_guess_format(NULL, path.c_str(), NULL);
132 throw InvalidFormat(
"Could not deduce output format from file extension.", path);
137 throw OutOfMemory(
"Could not allocate memory for AVFormatContext.", path);
145 info.
vcodec = avcodec_find_encoder(fmt->video_codec)->name;
149 info.
acodec = avcodec_find_encoder(fmt->audio_codec)->name;
153 void FFmpegWriter::initialize_streams() {
154 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::initialize_streams",
"fmt->video_codec", fmt->video_codec,
"fmt->audio_codec", fmt->audio_codec,
"AV_CODEC_ID_NONE", AV_CODEC_ID_NONE);
161 video_st = add_video_stream();
165 audio_st = add_audio_stream();
171 if (codec.length() > 0) {
175 #if defined(__linux__) 176 if (strstr(codec.c_str(),
"_vaapi") != NULL) {
177 new_codec = avcodec_find_encoder_by_name(codec.c_str());
182 }
else if (strstr(codec.c_str(),
"_nvenc") != NULL) {
183 new_codec = avcodec_find_encoder_by_name(codec.c_str());
189 new_codec = avcodec_find_encoder_by_name(codec.c_str());
193 #elif defined(_WIN32) 194 if (strstr(codec.c_str(),
"_dxva2") != NULL) {
195 new_codec = avcodec_find_encoder_by_name(codec.c_str());
200 }
else if (strstr(codec.c_str(),
"_nvenc") != NULL) {
201 new_codec = avcodec_find_encoder_by_name(codec.c_str());
207 new_codec = avcodec_find_encoder_by_name(codec.c_str());
211 #elif defined(__APPLE__) 212 if (strstr(codec.c_str(),
"_videotoolbox") != NULL) {
213 new_codec = avcodec_find_encoder_by_name(codec.c_str());
219 new_codec = avcodec_find_encoder_by_name(codec.c_str());
223 #else // is FFmpeg 3 but not linux 224 new_codec = avcodec_find_encoder_by_name(codec.c_str());
226 #else // not ffmpeg 3 227 new_codec = avcodec_find_encoder_by_name(codec.c_str());
228 #endif //IS_FFMPEG_3_2 229 if (new_codec == NULL)
230 throw InvalidCodec(
"A valid video codec could not be found for this file.", path);
236 fmt->video_codec = new_codec->id;
252 if (pixel_ratio.
num > 0) {
256 if (bit_rate >= 1000)
258 if ((bit_rate >= 0) && (bit_rate < 64))
274 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::SetVideoOptions (" + codec +
")",
"width", width,
"height", height,
"size.num", size.
num,
"size.den", size.
den,
"fps.num", fps.
num,
"fps.den", fps.
den);
283 if (codec.length() > 0) {
284 AVCodec *new_codec = avcodec_find_encoder_by_name(codec.c_str());
285 if (new_codec == NULL)
286 throw InvalidCodec(
"A valid audio codec could not be found for this file.", path);
292 fmt->audio_codec = new_codec->id;
295 if (sample_rate > 7999)
304 if (original_sample_rate == 0)
306 if (original_channels == 0)
318 AVCodecContext *c = NULL;
320 std::stringstream convert(value);
331 throw NoStreamsFound(
"The stream was not found. Be sure to call PrepareStreams() first.", path);
334 const AVOption *option = NULL;
342 if (option || (name ==
"g" || name ==
"qmin" || name ==
"qmax" || name ==
"max_b_frames" || name ==
"mb_decision" ||
343 name ==
"level" || name ==
"profile" || name ==
"slices" || name ==
"rc_min_rate" || name ==
"rc_max_rate" ||
344 name ==
"rc_buffer_size" || name ==
"crf" || name ==
"cqp")) {
348 convert >> c->gop_size;
350 else if (name ==
"qmin")
354 else if (name ==
"qmax")
358 else if (name ==
"max_b_frames")
360 convert >> c->max_b_frames;
362 else if (name ==
"mb_decision")
364 convert >> c->mb_decision;
366 else if (name ==
"level")
370 else if (name ==
"profile")
372 convert >> c->profile;
374 else if (name ==
"slices")
376 convert >> c->slices;
378 else if (name ==
"rc_min_rate")
380 convert >> c->rc_min_rate;
382 else if (name ==
"rc_max_rate")
384 convert >> c->rc_max_rate;
386 else if (name ==
"rc_buffer_size")
388 convert >> c->rc_buffer_size;
390 else if (name ==
"cqp") {
394 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 39, 101) 397 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),63), 0);
401 switch (c->codec_id) {
402 #if (LIBAVCODEC_VERSION_MAJOR >= 58) 403 case AV_CODEC_ID_AV1 :
405 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value),63), 0);
408 case AV_CODEC_ID_VP8 :
409 c->bit_rate = 10000000;
410 av_opt_set_int(c->priv_data,
"qp", std::max(std::min(std::stoi(value), 63), 4), 0);
412 case AV_CODEC_ID_VP9 :
414 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value), 63), 0);
415 if (std::stoi(value) == 0) {
416 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
417 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
420 case AV_CODEC_ID_H264 :
421 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value), 51), 0);
422 if (std::stoi(value) == 0) {
423 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
426 case AV_CODEC_ID_HEVC :
427 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value), 51), 0);
428 if (std::stoi(value) == 0) {
429 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
430 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
435 av_opt_set_int(c->priv_data,
"qp", std::min(std::stoi(value), 63), 0);
440 }
else if (name ==
"crf") {
444 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 39, 101) 447 double mbs = 15000000.0;
456 c->bit_rate = (int)(mbs);
460 switch (c->codec_id) {
461 #if (LIBAVCODEC_VERSION_MAJOR >= 58) 462 case AV_CODEC_ID_AV1 :
464 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value),63), 0);
467 case AV_CODEC_ID_VP8 :
468 c->bit_rate = 10000000;
469 av_opt_set_int(c->priv_data,
"crf", std::max(std::min(std::stoi(value), 63), 4), 0);
471 case AV_CODEC_ID_VP9 :
473 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value), 63), 0);
474 if (std::stoi(value) == 0) {
475 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
476 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
479 case AV_CODEC_ID_H264 :
480 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value), 51), 0);
481 if (std::stoi(value) == 0) {
482 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
485 case AV_CODEC_ID_HEVC :
486 av_opt_set_int(c->priv_data,
"crf", std::min(std::stoi(value), 51), 0);
487 if (std::stoi(value) == 0) {
488 av_opt_set(c->priv_data,
"preset",
"veryslow", 0);
489 av_opt_set_int(c->priv_data,
"lossless", 1, 0);
495 double mbs = 15000000.0;
503 c->bit_rate = (int) (mbs);
509 AV_OPTION_SET(st, c->priv_data, name.c_str(), value.c_str(), c);
516 }
else if (name ==
"muxing_preset") {
517 if (value ==
"mp4_faststart") {
519 av_dict_set(&
mux_dict,
"movflags",
"faststart", 0);
520 }
else if (value ==
"mp4_fragmented") {
522 av_dict_set(&
mux_dict,
"movflags",
"frag_keyframe", 0);
523 av_dict_set(&
mux_dict,
"min_frag_duration",
"8000000", 0);
526 throw InvalidOptions(
"The option is not valid for this codec.", path);
537 if (avcodec_find_encoder_by_name(codec_name.c_str()) == NULL)
546 throw InvalidOptions(
"No video or audio options have been set. You must set has_video or has_audio (or both).", path);
551 initialize_streams();
554 prepare_streams =
true;
560 throw InvalidOptions(
"No video or audio options have been set. You must set has_video or has_audio (or both).", path);
563 if (!(fmt->flags & AVFMT_NOFILE)) {
564 if (avio_open(&oc->pb, path.c_str(), AVIO_FLAG_WRITE) < 0)
565 throw InvalidFile(
"Could not open or write file.", path);
572 for (std::map<std::string, std::string>::iterator iter =
info.
metadata.begin(); iter !=
info.
metadata.end(); ++iter) {
573 av_dict_set(&oc->metadata, iter->first.c_str(), iter->second.c_str(), 0);
577 AVDictionary *dict = NULL;
579 bool is_mp4 = strcmp(oc->oformat->name,
"mp4");
580 bool is_mov = strcmp(oc->oformat->name,
"mov");
582 if (is_mp4 || is_mov)
586 if (avformat_write_header(oc, &dict) != 0) {
588 throw InvalidFile(
"Could not write header to file.", path);
592 if (dict) av_dict_free(&dict);
605 throw WriterClosed(
"The FFmpegWriter is closed. Call Open() before calling this method.", path);
610 spooled_video_frames.push_back(frame);
613 spooled_audio_frames.push_back(frame);
615 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::WriteFrame",
"frame->number", frame->number,
"spooled_video_frames.size()", spooled_video_frames.size(),
"spooled_audio_frames.size()", spooled_audio_frames.size(),
"cache_size", cache_size,
"is_writing", is_writing);
618 if ((
int)spooled_video_frames.size() == cache_size || (int)spooled_audio_frames.size() == cache_size) {
622 write_queued_frames();
626 write_queued_frames();
635 void FFmpegWriter::write_queued_frames() {
636 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_queued_frames",
"spooled_video_frames.size()", spooled_video_frames.size(),
"spooled_audio_frames.size()", spooled_audio_frames.size());
642 queued_video_frames = spooled_video_frames;
643 queued_audio_frames = spooled_audio_frames;
646 spooled_video_frames.clear();
647 spooled_audio_frames.clear();
652 omp_set_nested(
true);
655 bool has_error_encoding_video =
false;
662 if (
info.
has_audio && audio_st && !queued_audio_frames.empty())
663 write_audio_packets(
false);
666 while (!queued_video_frames.empty()) {
668 std::shared_ptr<Frame> frame = queued_video_frames.front();
671 processed_frames.push_back(frame);
675 process_video_packet(frame);
678 queued_video_frames.pop_front();
686 while (!processed_frames.empty()) {
688 std::shared_ptr<Frame> frame = processed_frames.front();
692 deallocate_frames.push_back(frame);
695 if (av_frames.count(frame)) {
697 AVFrame *frame_final = av_frames[frame];
700 bool success = write_video_packet(frame, frame_final);
702 has_error_encoding_video =
true;
707 processed_frames.pop_front();
711 while (!deallocate_frames.empty()) {
713 std::shared_ptr<Frame> frame = deallocate_frames.front();
716 if (av_frames.count(frame)) {
718 AVFrame *av_frame = av_frames[frame];
721 av_freep(&(av_frame->data[0]));
723 av_frames.erase(frame);
727 deallocate_frames.pop_front();
738 if (has_error_encoding_video)
747 for (int64_t number = start; number <= length; number++) {
749 std::shared_ptr<Frame> f = reader->
GetFrame(number);
759 write_queued_frames();
763 write_audio_packets(
true);
772 av_write_trailer(oc);
775 write_trailer =
true;
781 void FFmpegWriter::flush_encoders() {
784 #if (LIBAVFORMAT_VERSION_MAJOR < 58) 790 int stop_encoding = 1;
797 write_video_count += av_rescale_q(1, (AVRational) {
info.
fps.
den,
info.
fps.
num}, video_codec->time_base);
800 av_init_packet(&pkt);
805 uint8_t *video_outbuf = NULL;
812 #pragma omp critical (write_video_packet) 815 error_code = avcodec_send_frame(video_codec, NULL);
817 while (error_code >= 0) {
818 error_code = avcodec_receive_packet(video_codec, &pkt);
819 if (error_code == AVERROR(EAGAIN)|| error_code == AVERROR_EOF) {
822 avcodec_flush_buffers(video_codec);
825 if (pkt.pts != AV_NOPTS_VALUE)
826 pkt.pts = av_rescale_q(pkt.pts, video_codec->time_base, video_st->time_base);
827 if (pkt.dts != AV_NOPTS_VALUE)
828 pkt.dts = av_rescale_q(pkt.dts, video_codec->time_base, video_st->time_base);
829 if (pkt.duration > 0)
830 pkt.duration = av_rescale_q(pkt.duration, video_codec->time_base, video_st->time_base);
831 pkt.stream_index = video_st->index;
832 error_code = av_interleaved_write_frame(oc, &pkt);
835 #else // IS_FFMPEG_3_2 837 #if LIBAVFORMAT_VERSION_MAJOR >= 54 839 error_code = avcodec_encode_video2(video_codec, &pkt, NULL, &got_packet);
843 int video_outbuf_size = 0;
846 int out_size = avcodec_encode_video(video_codec, NULL, video_outbuf_size, NULL);
850 if(video_codec->coded_frame->key_frame)
851 pkt.flags |= AV_PKT_FLAG_KEY;
852 pkt.data= video_outbuf;
858 #endif // LIBAVFORMAT_VERSION_MAJOR >= 54 859 #endif // IS_FFMPEG_3_2 861 if (error_code < 0) {
873 if (pkt.pts != AV_NOPTS_VALUE)
874 pkt.pts = av_rescale_q(pkt.pts, video_codec->time_base, video_st->time_base);
875 if (pkt.dts != AV_NOPTS_VALUE)
876 pkt.dts = av_rescale_q(pkt.dts, video_codec->time_base, video_st->time_base);
877 if (pkt.duration > 0)
878 pkt.duration = av_rescale_q(pkt.duration, video_codec->time_base, video_st->time_base);
879 pkt.stream_index = video_st->index;
882 error_code = av_interleaved_write_frame(oc, &pkt);
883 if (error_code < 0) {
889 av_freep(&video_outbuf);
897 #if LIBAVFORMAT_VERSION_MAJOR >= 54 899 write_audio_count += av_rescale_q(audio_input_position / (audio_codec->channels * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)), (AVRational){1,
info.
sample_rate}, audio_codec->time_base);
901 write_audio_count += av_rescale_q(audio_input_position / audio_codec->channels, (AVRational){1, info.sample_rate}, audio_codec->time_base);
905 av_init_packet(&pkt);
908 pkt.pts = pkt.dts = write_audio_count;
913 avcodec_send_frame(audio_codec, NULL);
916 error_code = avcodec_encode_audio2(audio_codec, &pkt, NULL, &got_packet);
918 if (error_code < 0) {
928 pkt.pts = pkt.dts = write_audio_count;
931 if (pkt.pts != AV_NOPTS_VALUE)
932 pkt.pts = av_rescale_q(pkt.pts, audio_codec->time_base, audio_st->time_base);
933 if (pkt.dts != AV_NOPTS_VALUE)
934 pkt.dts = av_rescale_q(pkt.dts, audio_codec->time_base, audio_st->time_base);
935 if (pkt.duration > 0)
936 pkt.duration = av_rescale_q(pkt.duration, audio_codec->time_base, audio_st->time_base);
939 pkt.stream_index = audio_st->index;
940 pkt.flags |= AV_PKT_FLAG_KEY;
943 error_code = av_interleaved_write_frame(oc, &pkt);
944 if (error_code < 0) {
956 void FFmpegWriter::close_video(AVFormatContext *oc, AVStream *st)
962 av_buffer_unref(&hw_device_ctx);
963 hw_device_ctx = NULL;
971 void FFmpegWriter::close_audio(AVFormatContext *oc, AVStream *st)
975 delete[] audio_outbuf;
976 delete[] audio_encoder_buffer;
979 audio_encoder_buffer = NULL;
1003 close_video(oc, video_st);
1005 close_audio(oc, audio_st);
1008 if (image_rescalers.size() > 0)
1011 if (!(fmt->flags & AVFMT_NOFILE)) {
1017 write_video_count = 0;
1018 write_audio_count = 0;
1021 avformat_free_context(oc);
1026 prepare_streams =
false;
1027 write_header =
false;
1028 write_trailer =
false;
1034 void FFmpegWriter::add_avframe(std::shared_ptr<Frame> frame, AVFrame *av_frame) {
1036 if (!av_frames.count(frame)) {
1038 av_frames[frame] = av_frame;
1046 AVStream *FFmpegWriter::add_audio_stream() {
1053 throw InvalidCodec(
"A valid audio codec could not be found for this file.", path);
1058 c->codec_id = codec->id;
1059 #if LIBAVFORMAT_VERSION_MAJOR >= 53 1060 c->codec_type = AVMEDIA_TYPE_AUDIO;
1062 c->codec_type = CODEC_TYPE_AUDIO;
1070 if (codec->supported_samplerates) {
1072 for (i = 0; codec->supported_samplerates[i] != 0; i++)
1078 if (codec->supported_samplerates[i] == 0)
1079 throw InvalidSampleRate(
"An invalid sample rate was detected for this codec.", path);
1087 if (codec->channel_layouts) {
1089 for (i = 0; codec->channel_layouts[i] != 0; i++)
1090 if (channel_layout == codec->channel_layouts[i]) {
1092 c->channel_layout = channel_layout;
1095 if (codec->channel_layouts[i] == 0)
1096 throw InvalidChannels(
"An invalid channel layout was detected (i.e. MONO / STEREO).", path);
1099 c->channel_layout = channel_layout;
1102 if (codec->sample_fmts) {
1103 for (
int i = 0; codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) {
1105 c->sample_fmt = codec->sample_fmts[i];
1109 if (c->sample_fmt == AV_SAMPLE_FMT_NONE) {
1111 c->sample_fmt = AV_SAMPLE_FMT_S16;
1115 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1116 #if (LIBAVCODEC_VERSION_MAJOR >= 57) 1117 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1119 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1123 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::add_audio_stream",
"c->codec_id", c->codec_id,
"c->bit_rate", c->bit_rate,
"c->channels", c->channels,
"c->sample_fmt", c->sample_fmt,
"c->channel_layout", c->channel_layout,
"c->sample_rate", c->sample_rate);
1129 AVStream *FFmpegWriter::add_video_stream() {
1136 throw InvalidCodec(
"A valid video codec could not be found for this file.", path);
1141 c->codec_id = codec->id;
1142 #if LIBAVFORMAT_VERSION_MAJOR >= 53 1143 c->codec_type = AVMEDIA_TYPE_VIDEO;
1145 c->codec_type = CODEC_TYPE_VIDEO;
1159 switch (c->codec_id) {
1160 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 39, 101) 1161 #if (LIBAVCODEC_VERSION_MAJOR >= 58) 1162 case AV_CODEC_ID_AV1 :
1164 case AV_CODEC_ID_VP9 :
1165 case AV_CODEC_ID_HEVC :
1167 case AV_CODEC_ID_VP8 :
1168 case AV_CODEC_ID_H264 :
1204 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 26, 0) 1205 c->framerate = av_inv_q(c->time_base);
1207 st->avg_frame_rate = av_inv_q(c->time_base);
1212 c->max_b_frames = 10;
1213 if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO)
1215 c->max_b_frames = 2;
1216 if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO)
1222 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1223 #if (LIBAVCODEC_VERSION_MAJOR >= 57) 1224 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1226 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1230 const PixelFormat *supported_pixel_formats = codec->pix_fmts;
1231 while (supported_pixel_formats != NULL && *supported_pixel_formats !=
PIX_FMT_NONE) {
1234 c->pix_fmt = *supported_pixel_formats;
1235 ++supported_pixel_formats;
1240 if (fmt->video_codec == AV_CODEC_ID_RAWVIDEO) {
1244 #if (LIBAVFORMAT_VERSION_MAJOR < 58) 1245 if (strcmp(fmt->name,
"gif") != 0)
1248 oc->oformat->flags |= AVFMT_RAWPICTURE;
1257 #if (LIBAVFORMAT_VERSION_MAJOR < 58) 1258 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::add_video_stream (" + (std::string)fmt->name +
" : " + (std::string)av_get_pix_fmt_name(c->pix_fmt) +
")",
"c->codec_id", c->codec_id,
"c->bit_rate", c->bit_rate,
"c->pix_fmt", c->pix_fmt,
"oc->oformat->flags", oc->oformat->flags,
"AVFMT_RAWPICTURE", AVFMT_RAWPICTURE);
1260 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::add_video_stream (" + (std::string)fmt->name +
" : " + (std::string)av_get_pix_fmt_name(c->pix_fmt) +
")",
"c->codec_id", c->codec_id,
"c->bit_rate", c->bit_rate,
"c->pix_fmt", c->pix_fmt,
"oc->oformat->flags", oc->oformat->flags);
1267 void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st) {
1275 codec = avcodec_find_encoder_by_name(
info.
acodec.c_str());
1277 codec = avcodec_find_encoder(audio_codec->codec_id);
1282 AVDictionary *
opts = NULL;
1283 av_dict_set(&opts,
"strict",
"experimental", 0);
1286 if (avcodec_open2(audio_codec, codec, &opts) < 0)
1287 throw InvalidCodec(
"Could not open audio codec", path);
1291 av_dict_free(&opts);
1295 if (audio_codec->frame_size <= 1) {
1301 case AV_CODEC_ID_PCM_S16LE:
1302 case AV_CODEC_ID_PCM_S16BE:
1303 case AV_CODEC_ID_PCM_U16LE:
1304 case AV_CODEC_ID_PCM_U16BE:
1305 audio_input_frame_size >>= 1;
1312 audio_input_frame_size = audio_codec->frame_size;
1316 initial_audio_input_frame_size = audio_input_frame_size;
1323 audio_outbuf =
new uint8_t[audio_outbuf_size];
1327 audio_encoder_buffer =
new uint8_t[audio_encoder_buffer_size];
1330 for (std::map<std::string, std::string>::iterator iter =
info.
metadata.begin(); iter !=
info.
metadata.end(); ++iter) {
1331 av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1338 void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st) {
1349 char *adapter_ptr = NULL;
1353 fprintf(stderr,
"\n\nEncodiing Device Nr: %d\n", adapter_num);
1354 if (adapter_num < 3 && adapter_num >=0) {
1355 #if defined(__linux__) 1356 snprintf(adapter,
sizeof(adapter),
"/dev/dri/renderD%d", adapter_num+128);
1358 adapter_ptr = adapter;
1359 #elif defined(_WIN32) 1361 #elif defined(__APPLE__) 1369 #if defined(__linux__) 1370 if( adapter_ptr != NULL && access( adapter_ptr, W_OK ) == 0 ) {
1371 #elif defined(_WIN32) 1372 if( adapter_ptr != NULL ) {
1373 #elif defined(__APPLE__) 1374 if( adapter_ptr != NULL ) {
1383 adapter_ptr, NULL, 0) < 0) {
1398 if (video_codec->max_b_frames && video_codec->codec_id != AV_CODEC_ID_MPEG4 && video_codec->codec_id != AV_CODEC_ID_MPEG1VIDEO && video_codec->codec_id != AV_CODEC_ID_MPEG2VIDEO)
1399 video_codec->max_b_frames = 0;
1403 av_dict_set(&opts,
"strict",
"experimental", 0);
1417 if (av_opt_get_int(video_codec->priv_data,
"qp", 0, &qp) != 0 || qp == 0) {
1419 av_opt_set(video_codec->priv_data,
"rc_mode",
"VBR", 0);
1423 video_codec->rc_max_rate = video_codec->bit_rate;
1427 switch (video_codec->codec_id) {
1428 case AV_CODEC_ID_H264:
1429 video_codec->max_b_frames = 0;
1430 video_codec->profile = FF_PROFILE_H264_BASELINE | FF_PROFILE_H264_CONSTRAINED;
1431 av_opt_set(video_codec->priv_data,
"preset",
"slow", 0);
1432 av_opt_set(video_codec->priv_data,
"tune",
"zerolatency", 0);
1433 av_opt_set(video_codec->priv_data,
"vprofile",
"baseline", AV_OPT_SEARCH_CHILDREN);
1435 case AV_CODEC_ID_HEVC:
1438 case AV_CODEC_ID_VP9:
1443 "codec_id", video_codec->codec_id);
1457 if (avcodec_open2(video_codec, codec, &opts) < 0)
1458 throw InvalidCodec(
"Could not open video codec", path);
1462 av_dict_free(&opts);
1466 av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1474 void FFmpegWriter::write_audio_packets(
bool is_final) {
1475 #pragma omp task firstprivate(is_final) 1478 int total_frame_samples = 0;
1479 int frame_position = 0;
1480 int channels_in_frame = 0;
1481 int sample_rate_in_frame = 0;
1482 int samples_in_frame = 0;
1487 int16_t *all_queued_samples = (int16_t *) av_malloc(all_queued_samples_size);
1488 int16_t *all_resampled_samples = NULL;
1489 int16_t *final_samples_planar = NULL;
1490 int16_t *final_samples = NULL;
1493 while (!queued_audio_frames.empty()) {
1495 std::shared_ptr<Frame> frame = queued_audio_frames.front();
1498 sample_rate_in_frame = frame->SampleRate();
1499 samples_in_frame = frame->GetAudioSamplesCount();
1500 channels_in_frame = frame->GetAudioChannelsCount();
1501 channel_layout_in_frame = frame->ChannelsLayout();
1505 float *frame_samples_float = NULL;
1507 frame_samples_float = frame->GetInterleavedAudioSamples(sample_rate_in_frame, NULL, &samples_in_frame);
1511 total_frame_samples = samples_in_frame * channels_in_frame;
1514 for (
int s = 0; s < total_frame_samples; s++, frame_position++)
1516 all_queued_samples[frame_position] =
int(frame_samples_float[s] * (1 << 15));
1520 delete[] frame_samples_float;
1523 queued_audio_frames.pop_front();
1529 total_frame_samples = frame_position;
1530 int remaining_frame_samples = total_frame_samples;
1531 int samples_position = 0;
1534 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_audio_packets",
"is_final", is_final,
"total_frame_samples", total_frame_samples,
"channel_layout_in_frame", channel_layout_in_frame,
"channels_in_frame", channels_in_frame,
"samples_in_frame", samples_in_frame,
"LAYOUT_MONO",
LAYOUT_MONO);
1537 AVSampleFormat output_sample_fmt = audio_codec->sample_fmt;
1539 AVFrame *audio_frame = NULL;
1544 audio_frame->nb_samples = total_frame_samples / channels_in_frame;
1547 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);
1548 if (error_code < 0) {
1553 switch (audio_codec->sample_fmt) {
1554 case AV_SAMPLE_FMT_FLTP: {
1555 output_sample_fmt = AV_SAMPLE_FMT_FLT;
1558 case AV_SAMPLE_FMT_S32P: {
1559 output_sample_fmt = AV_SAMPLE_FMT_S32;
1562 case AV_SAMPLE_FMT_S16P: {
1563 output_sample_fmt = AV_SAMPLE_FMT_S16;
1566 case AV_SAMPLE_FMT_U8P: {
1567 output_sample_fmt = AV_SAMPLE_FMT_U8;
1577 total_frame_samples *= (float(
info.
sample_rate) / sample_rate_in_frame);
1578 total_frame_samples *= (float(
info.
channels) / channels_in_frame);
1583 audio_converted->nb_samples = total_frame_samples / channels_in_frame;
1584 av_samples_alloc(audio_converted->data, audio_converted->linesize,
info.
channels, audio_converted->nb_samples, output_sample_fmt, 0);
1586 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_audio_packets (1st resampling)",
"in_sample_fmt", AV_SAMPLE_FMT_S16,
"out_sample_fmt", output_sample_fmt,
"in_sample_rate", sample_rate_in_frame,
"out_sample_rate",
info.
sample_rate,
"in_channels", channels_in_frame,
"out_channels",
info.
channels);
1591 av_opt_set_int(avr,
"in_channel_layout", channel_layout_in_frame, 0);
1593 av_opt_set_int(avr,
"in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
1594 av_opt_set_int(avr,
"out_sample_fmt", output_sample_fmt, 0);
1595 av_opt_set_int(avr,
"in_sample_rate", sample_rate_in_frame, 0);
1597 av_opt_set_int(avr,
"in_channels", channels_in_frame, 0);
1605 audio_converted->data,
1606 audio_converted->linesize[0],
1607 audio_converted->nb_samples,
1609 audio_frame->linesize[0],
1610 audio_frame->nb_samples);
1613 remaining_frame_samples = nb_samples * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);
1616 all_resampled_samples = (int16_t *) av_malloc(
1617 sizeof(int16_t) * nb_samples *
info.
channels * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)));
1620 memcpy(all_resampled_samples, audio_converted->data[0], nb_samples *
info.
channels * av_get_bytes_per_sample(output_sample_fmt));
1623 av_freep(&(audio_frame->data[0]));
1625 av_freep(&audio_converted->data[0]);
1627 all_queued_samples = NULL;
1629 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_audio_packets (Successfully completed 1st resampling)",
"nb_samples", nb_samples,
"remaining_frame_samples", remaining_frame_samples);
1633 while (remaining_frame_samples > 0 || is_final) {
1635 int remaining_packet_samples = (audio_input_frame_size *
info.
channels) - audio_input_position;
1639 if (remaining_frame_samples >= remaining_packet_samples)
1640 diff = remaining_packet_samples;
1641 else if (remaining_frame_samples < remaining_packet_samples)
1642 diff = remaining_frame_samples;
1647 memcpy(samples + (audio_input_position * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16))),
1648 all_resampled_samples + samples_position, diff * av_get_bytes_per_sample(output_sample_fmt));
1651 audio_input_position += diff;
1652 samples_position += diff * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16));
1653 remaining_frame_samples -= diff;
1654 remaining_packet_samples -= diff;
1657 if (audio_input_position < (audio_input_frame_size *
info.
channels) && !is_final)
1664 if (av_sample_fmt_is_planar(audio_codec->sample_fmt)) {
1665 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_audio_packets (2nd resampling for Planar formats)",
"in_sample_fmt", output_sample_fmt,
"out_sample_fmt", audio_codec->sample_fmt,
"in_sample_rate",
info.
sample_rate,
"out_sample_rate",
info.
sample_rate,
"in_channels",
info.
channels,
"out_channels",
info.
channels);
1672 av_opt_set_int(avr_planar,
"in_sample_fmt", output_sample_fmt, 0);
1673 av_opt_set_int(avr_planar,
"out_sample_fmt", audio_codec->sample_fmt, 0);
1676 av_opt_set_int(avr_planar,
"in_channels",
info.
channels, 0);
1677 av_opt_set_int(avr_planar,
"out_channels",
info.
channels, 0);
1684 audio_frame->nb_samples = audio_input_position /
info.
channels;
1687 final_samples_planar = (int16_t *) av_malloc(
1688 sizeof(int16_t) * audio_frame->nb_samples *
info.
channels * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)));
1691 memcpy(final_samples_planar, samples, audio_frame->nb_samples *
info.
channels * av_get_bytes_per_sample(output_sample_fmt));
1694 avcodec_fill_audio_frame(audio_frame,
info.
channels, output_sample_fmt, (uint8_t *) final_samples_planar,
1695 audio_encoder_buffer_size, 0);
1698 frame_final->nb_samples = audio_input_frame_size;
1699 av_samples_alloc(frame_final->data, frame_final->linesize,
info.
channels, frame_final->nb_samples, audio_codec->sample_fmt, 0);
1704 frame_final->linesize[0],
1705 frame_final->nb_samples,
1707 audio_frame->linesize[0],
1708 audio_frame->nb_samples);
1712 memcpy(samples, frame_final->data[0], nb_samples * av_get_bytes_per_sample(audio_codec->sample_fmt) *
info.
channels);
1715 av_freep(&(audio_frame->data[0]));
1717 all_queued_samples = NULL;
1723 final_samples = (int16_t *) av_malloc(
1724 sizeof(int16_t) * audio_input_position * (av_get_bytes_per_sample(audio_codec->sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)));
1727 memcpy(final_samples, samples, audio_input_position * av_get_bytes_per_sample(audio_codec->sample_fmt));
1730 frame_final->nb_samples = audio_input_frame_size;
1733 avcodec_fill_audio_frame(frame_final, audio_codec->channels, audio_codec->sample_fmt, (uint8_t *) final_samples,
1734 audio_encoder_buffer_size, 0);
1738 write_audio_count += FFMIN(audio_input_frame_size, audio_input_position);
1739 frame_final->pts = write_audio_count;
1743 av_init_packet(&pkt);
1744 pkt.data = audio_encoder_buffer;
1745 pkt.size = audio_encoder_buffer_size;
1748 pkt.pts = pkt.dts = write_audio_count;
1751 int got_packet_ptr = 0;
1757 int frame_finished = 0;
1758 error_code = ret = avcodec_send_frame(audio_codec, frame_final);
1759 if (ret < 0 && ret != AVERROR(EINVAL) && ret != AVERROR_EOF) {
1760 avcodec_send_frame(audio_codec, NULL);
1765 ret = avcodec_receive_packet(audio_codec, &pkt);
1768 if(ret == AVERROR(EINVAL) || ret == AVERROR_EOF) {
1769 avcodec_flush_buffers(audio_codec);
1773 ret = frame_finished;
1776 if (!pkt.data && !frame_finished)
1780 got_packet_ptr = ret;
1783 int error_code = avcodec_encode_audio2(audio_codec, &pkt, frame_final, &got_packet_ptr);
1786 if (error_code == 0 && got_packet_ptr) {
1790 pkt.pts = pkt.dts = write_audio_count;
1793 if (pkt.pts != AV_NOPTS_VALUE)
1794 pkt.pts = av_rescale_q(pkt.pts, audio_codec->time_base, audio_st->time_base);
1795 if (pkt.dts != AV_NOPTS_VALUE)
1796 pkt.dts = av_rescale_q(pkt.dts, audio_codec->time_base, audio_st->time_base);
1797 if (pkt.duration > 0)
1798 pkt.duration = av_rescale_q(pkt.duration, audio_codec->time_base, audio_st->time_base);
1801 pkt.stream_index = audio_st->index;
1802 pkt.flags |= AV_PKT_FLAG_KEY;
1805 int error_code = av_interleaved_write_frame(oc, &pkt);
1806 if (error_code < 0) {
1811 if (error_code < 0) {
1816 av_freep(&(frame_final->data[0]));
1823 audio_input_position = 0;
1828 if (all_resampled_samples) {
1829 av_freep(&all_resampled_samples);
1830 all_resampled_samples = NULL;
1832 if (all_queued_samples) {
1833 av_freep(&all_queued_samples);
1834 all_queued_samples = NULL;
1841 AVFrame *FFmpegWriter::allocate_avframe(
PixelFormat pix_fmt,
int width,
int height,
int *buffer_size, uint8_t *new_buffer) {
1843 AVFrame *new_av_frame = NULL;
1847 if (new_av_frame == NULL)
1848 throw OutOfMemory(
"Could not allocate AVFrame", path);
1856 new_buffer = (uint8_t *) av_malloc(*buffer_size *
sizeof(uint8_t));
1859 new_av_frame->width = width;
1860 new_av_frame->height = height;
1861 new_av_frame->format = pix_fmt;
1865 return new_av_frame;
1869 void FFmpegWriter::process_video_packet(std::shared_ptr<Frame> frame) {
1871 int source_image_width = frame->GetWidth();
1872 int source_image_height = frame->GetHeight();
1875 if (source_image_height == 1 && source_image_width == 1)
1879 if (image_rescalers.size() == 0)
1880 InitScalers(source_image_width, source_image_height);
1883 SwsContext *scaler = image_rescalers[rescaler_position];
1884 rescaler_position++;
1885 if (rescaler_position == num_of_rescalers)
1886 rescaler_position = 0;
1888 #pragma omp task firstprivate(frame, scaler, source_image_width, source_image_height) 1891 int bytes_source = 0;
1892 int bytes_final = 0;
1893 AVFrame *frame_source = NULL;
1894 const uchar *pixels = NULL;
1897 pixels = frame->GetPixels();
1900 frame_source = allocate_avframe(
PIX_FMT_RGBA, source_image_width, source_image_height, &bytes_source, (uint8_t *) pixels);
1902 AVFrame *frame_final;
1904 frame_final = allocate_avframe(AV_PIX_FMT_NV12,
info.
width,
info.
height, &bytes_final, NULL);
1906 frame_final = allocate_avframe((AVPixelFormat)(video_st->codecpar->format),
info.
width,
info.
height, &bytes_final, NULL);
1909 AVFrame *frame_final = allocate_avframe(video_codec->pix_fmt,
info.
width,
info.
height, &bytes_final, NULL);
1917 sws_scale(scaler, frame_source->data, frame_source->linesize, 0,
1918 source_image_height, frame_final->data, frame_final->linesize);
1921 #pragma omp critical (av_frames_section) 1922 add_avframe(frame, frame_final);
1932 bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *frame_final) {
1933 #if (LIBAVFORMAT_VERSION_MAJOR >= 58) 1936 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_video_packet",
"frame->number", frame->number,
"oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE);
1938 if (oc->oformat->flags & AVFMT_RAWPICTURE) {
1941 av_init_packet(&pkt);
1943 pkt.flags |= AV_PKT_FLAG_KEY;
1944 pkt.stream_index = video_st->index;
1945 pkt.data = (uint8_t *) frame_final->data;
1946 pkt.size =
sizeof(AVPicture);
1949 write_video_count += av_rescale_q(1, (AVRational) {
info.
fps.
den,
info.
fps.
num}, video_codec->time_base);
1950 pkt.pts = write_video_count;
1953 int error_code = av_interleaved_write_frame(oc, &pkt);
1954 if (error_code < 0) {
1967 av_init_packet(&pkt);
1970 pkt.pts = pkt.dts = AV_NOPTS_VALUE;
1973 uint8_t *video_outbuf = NULL;
1976 write_video_count += av_rescale_q(1, (AVRational) {
info.
fps.
den,
info.
fps.
num}, video_codec->time_base);
1979 frame_final->pts = write_video_count;
1982 if (!(
hw_frame = av_frame_alloc())) {
1983 fprintf(stderr,
"Error code: av_hwframe_alloc\n");
1985 if (av_hwframe_get_buffer(video_codec->hw_frames_ctx,
hw_frame, 0) < 0) {
1986 fprintf(stderr,
"Error code: av_hwframe_get_buffer\n");
1989 fprintf(stderr,
"Error hw_frames_ctx.\n");
1991 hw_frame->format = AV_PIX_FMT_NV12;
1992 if ( av_hwframe_transfer_data(
hw_frame, frame_final, 0) < 0) {
1993 fprintf(stderr,
"Error while transferring frame data to surface.\n");
1995 av_frame_copy_props(
hw_frame, frame_final);
1999 int got_packet_ptr = 0;
2003 int frameFinished = 0;
2007 ret = avcodec_send_frame(video_codec,
hw_frame);
2009 ret = avcodec_send_frame(video_codec, frame_final);
2014 if (ret == AVERROR(EAGAIN) ) {
2015 std::cerr <<
"Frame EAGAIN" <<
"\n";
2017 if (ret == AVERROR_EOF ) {
2018 std::cerr <<
"Frame AVERROR_EOF" <<
"\n";
2020 avcodec_send_frame(video_codec, NULL);
2024 ret = avcodec_receive_packet(video_codec, &pkt);
2026 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
2027 avcodec_flush_buffers(video_codec);
2038 #if LIBAVFORMAT_VERSION_MAJOR >= 54 2040 error_code = avcodec_encode_video2(video_codec, &pkt, frame_final, &got_packet_ptr);
2041 if (error_code != 0) {
2042 std::cerr <<
"Frame AVERROR_EOF" <<
"\n";
2044 if (got_packet_ptr == 0) {
2045 std::cerr <<
"Frame gotpacket error" <<
"\n";
2049 int video_outbuf_size = 200000;
2050 video_outbuf = (uint8_t*) av_malloc(200000);
2053 int out_size = avcodec_encode_video(video_codec, video_outbuf, video_outbuf_size, frame_final);
2057 if(video_codec->coded_frame->key_frame)
2058 pkt.flags |= AV_PKT_FLAG_KEY;
2059 pkt.data= video_outbuf;
2069 if (error_code == 0 && got_packet_ptr) {
2076 if (pkt.pts != AV_NOPTS_VALUE)
2077 pkt.pts = av_rescale_q(pkt.pts, video_codec->time_base, video_st->time_base);
2078 if (pkt.dts != AV_NOPTS_VALUE)
2079 pkt.dts = av_rescale_q(pkt.dts, video_codec->time_base, video_st->time_base);
2080 if (pkt.duration > 0)
2081 pkt.duration = av_rescale_q(pkt.duration, video_codec->time_base, video_st->time_base);
2082 pkt.stream_index = video_st->index;
2085 int error_code = av_interleaved_write_frame(oc, &pkt);
2086 if (error_code < 0) {
2094 delete[] video_outbuf;
2115 av_dump_format(oc, 0, path.c_str(), 1);
2119 void FFmpegWriter::InitScalers(
int source_width,
int source_height) {
2120 int scale_mode = SWS_FAST_BILINEAR;
2122 scale_mode = SWS_BICUBIC;
2126 for (
int x = 0; x < num_of_rescalers; x++) {
2139 image_rescalers.push_back(img_convert_ctx);
2145 original_sample_rate = sample_rate;
2146 original_channels = channels;
2152 for (
int x = 0; x < num_of_rescalers; x++)
2153 sws_freeContext(image_rescalers[x]);
2156 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)
#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.
#define AV_GET_CODEC_FROM_STREAM(av_stream, codec_in)
#define AV_OPTION_FIND(priv_data, name)
AV_COPY_PARAMS_FROM_CONTEXT(st, video_codec)
#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)
#define OPEN_MP_NUM_PROCESSORS
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
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.
#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.
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...
void WriteTrailer()
Write the file trailer (after all frames are written). This is called automatically by the Close() me...
#define av_err2str(errnum)
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 a writer is closed, and a frame is requested.
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)
FFmpegWriter(std::string path)
Constructor for FFmpegWriter. Throws one of the following exceptions.
int den
Denominator for the fraction.
#define AV_FORMAT_NEW_STREAM(oc, st_codec, av_codec, av_st)
openshot::Fraction fps
Frames per second, as a fraction (i.e. 24/1 = 24 fps)
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)