23# include <AUD_Device.h>
24# include <AUD_Special.h>
45# include <libavcodec/avcodec.h>
46# include <libavformat/avformat.h>
47# include <libavutil/buffer.h>
48# include <libavutil/channel_layout.h>
49# include <libavutil/imgutils.h>
50# include <libavutil/opt.h>
51# include <libavutil/rational.h>
52# include <libavutil/samplefmt.h>
53# include <libswscale/swscale.h>
63constexpr int64_t swscale_cache_max_entries = 32;
65struct SwscaleContext {
66 int src_width = 0, src_height = 0;
67 int dst_width = 0, dst_height = 0;
68 AVPixelFormat src_format = AV_PIX_FMT_NONE, dst_format = AV_PIX_FMT_NONE;
71 SwsContext *context =
nullptr;
76static ThreadMutex swscale_cache_lock = PTHREAD_MUTEX_INITIALIZER;
77static int64_t swscale_cache_timestamp = 0;
82 AVCodecID ffmpeg_codec;
83 AVCodecID ffmpeg_audio_codec;
84 int ffmpeg_video_bitrate;
85 int ffmpeg_audio_bitrate;
87 int ffmpeg_max_b_frames;
89 int ffmpeg_autosplit_count;
95 AVFormatContext *outfile;
96 AVCodecContext *video_codec;
97 AVCodecContext *audio_codec;
98 AVStream *video_stream;
99 AVStream *audio_stream;
100 AVFrame *current_frame;
104 AVFrame *img_convert_frame;
105 SwsContext *img_convert_ctx;
108 uint8_t *audio_deinterleave_buffer;
109 int audio_input_samples;
111 double audio_time_total;
112 bool audio_deinterleave;
113 int audio_sample_size;
117# ifdef WITH_AUDASPACE
118 AUD_Device *audio_mixdown_device;
122# define FFMPEG_AUTOSPLIT_SIZE 2000000000
125 if (G.debug & G_DEBUG_FFMPEG) \
128static void ffmpeg_dict_set_int(AVDictionary **dict,
const char *key,
int value);
129static void ffmpeg_filepath_get(FFMpegContext *context,
137static void delete_picture(AVFrame *f)
144static int request_float_audio_buffer(
int codec_id)
147 return codec_id == AV_CODEC_ID_AAC || codec_id == AV_CODEC_ID_AC3 ||
148 codec_id == AV_CODEC_ID_VORBIS;
151# ifdef WITH_AUDASPACE
153static int write_audio_frame(FFMpegContext *context)
155 AVFrame *frame =
nullptr;
156 AVCodecContext *c = context->audio_codec;
159 context->audio_mixdown_device, context->audio_input_buffer, context->audio_input_samples);
161 frame = av_frame_alloc();
162 frame->pts = context->audio_time / av_q2d(c->time_base);
163 frame->nb_samples = context->audio_input_samples;
164 frame->format = c->sample_fmt;
165# ifdef FFMPEG_USE_OLD_CHANNEL_VARS
166 frame->channels = c->channels;
167 frame->channel_layout = c->channel_layout;
168 const int num_channels = c->channels;
170 av_channel_layout_copy(&frame->ch_layout, &c->ch_layout);
171 const int num_channels = c->ch_layout.nb_channels;
174 if (context->audio_deinterleave) {
178 for (channel = 0; channel < num_channels; channel++) {
179 for (i = 0; i < frame->nb_samples; i++) {
180 memcpy(context->audio_deinterleave_buffer +
181 (i + channel * frame->nb_samples) * context->audio_sample_size,
182 context->audio_input_buffer +
183 (num_channels * i + channel) * context->audio_sample_size,
184 context->audio_sample_size);
188 temp = context->audio_deinterleave_buffer;
189 context->audio_deinterleave_buffer = context->audio_input_buffer;
190 context->audio_input_buffer = temp;
193 avcodec_fill_audio_frame(frame,
196 context->audio_input_buffer,
197 context->audio_input_samples * num_channels *
198 context->audio_sample_size,
203 char error_str[AV_ERROR_MAX_STRING_SIZE];
204 int ret = avcodec_send_frame(c, frame);
207 av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE,
ret);
208 fprintf(stderr,
"Can't send audio frame: %s\n", error_str);
212 AVPacket *pkt = av_packet_alloc();
216 ret = avcodec_receive_packet(c, pkt);
217 if (
ret == AVERROR(EAGAIN) ||
ret == AVERROR_EOF) {
221 av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE,
ret);
222 fprintf(stderr,
"Error encoding audio frame: %s\n", error_str);
226 pkt->stream_index = context->audio_stream->index;
227 av_packet_rescale_ts(pkt, c->time_base, context->audio_stream->time_base);
228# ifdef FFMPEG_USE_DURATION_WORKAROUND
232 pkt->flags |= AV_PKT_FLAG_KEY;
234 int write_ret = av_interleaved_write_frame(context->outfile, pkt);
235 if (write_ret != 0) {
236 av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE,
ret);
237 fprintf(stderr,
"Error writing audio packet: %s\n", error_str);
243 av_packet_free(&pkt);
244 av_frame_free(&frame);
251static AVFrame *alloc_picture(AVPixelFormat pix_fmt,
int width,
int height)
254 AVFrame *f = av_frame_alloc();
261 int size = av_image_get_buffer_size(pix_fmt, width, height, align);
262 AVBufferRef *buf = av_buffer_alloc(size);
263 if (buf ==
nullptr) {
268 av_image_fill_arrays(f->data, f->linesize, buf->data, pix_fmt, width, height, align);
279static const char **get_file_extensions(
int format)
283 static const char *rv[] = {
".dv",
nullptr};
287 static const char *rv[] = {
".mpg",
".mpeg",
nullptr};
291 static const char *rv[] = {
".dvd",
".vob",
".mpg",
".mpeg",
nullptr};
295 static const char *rv[] = {
".mp4",
".mpg",
".mpeg",
nullptr};
299 static const char *rv[] = {
".avi",
nullptr};
303 static const char *rv[] = {
".mov",
nullptr};
308 static const char *rv[] = {
".avi",
nullptr};
314 static const char *rv[] = {
".avi",
nullptr};
318 static const char *rv[] = {
".flv",
nullptr};
322 static const char *rv[] = {
".mkv",
nullptr};
326 static const char *rv[] = {
".ogv",
".ogg",
nullptr};
330 static const char *rv[] = {
".webm",
nullptr};
334 static const char *rv[] = {
".mp4",
".mkv",
nullptr};
343static bool write_video_frame(FFMpegContext *context, AVFrame *frame,
ReportList *reports)
345 int ret, success = 1;
346 AVPacket *packet = av_packet_alloc();
348 AVCodecContext *c = context->video_codec;
350 frame->pts = context->video_time;
351 context->video_time++;
353 char error_str[AV_ERROR_MAX_STRING_SIZE];
354 ret = avcodec_send_frame(c, frame);
357 av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE,
ret);
358 fprintf(stderr,
"Can't send video frame: %s\n", error_str);
363 ret = avcodec_receive_packet(c, packet);
365 if (
ret == AVERROR(EAGAIN) ||
ret == AVERROR_EOF) {
370 av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE,
ret);
371 fprintf(stderr,
"Error encoding frame: %s\n", error_str);
375 packet->stream_index = context->video_stream->index;
376 av_packet_rescale_ts(packet, c->time_base, context->video_stream->time_base);
377# ifdef FFMPEG_USE_DURATION_WORKAROUND
381 if (av_interleaved_write_frame(context->outfile, packet) != 0) {
389 av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE,
ret);
390 PRINT(
"Error writing frame: %s\n", error_str);
393 av_packet_free(&packet);
399static AVFrame *generate_video_frame(FFMpegContext *context,
const ImBuf *image)
402 const uint8_t *pixels = image->byte_buffer.data;
403 if (pixels ==
nullptr) {
407 AVCodecParameters *codec = context->video_stream->codecpar;
408 int height = codec->height;
411 if (context->img_convert_frame !=
nullptr) {
413 rgb_frame = context->img_convert_frame;
417 rgb_frame = context->current_frame;
422 av_frame_make_writable(rgb_frame);
426 int linesize = rgb_frame->linesize[0];
427 int linesize_src = rgb_frame->width * 4;
428 for (
int y = 0; y < height; y++) {
429 uint8_t *target = rgb_frame->data[0] + linesize * (height - y - 1);
430 const uint8_t *src = pixels + linesize_src *
y;
432# if ENDIAN_ORDER == L_ENDIAN
433 memcpy(target, src, linesize_src);
435# elif ENDIAN_ORDER == B_ENDIAN
436 const uint8_t *end = src + linesize_src;
447# error ENDIAN_ORDER should either be L_ENDIAN or B_ENDIAN.
452 if (context->img_convert_frame !=
nullptr) {
455 av_frame_make_writable(context->current_frame);
456 BKE_ffmpeg_sws_scale_frame(context->img_convert_ctx, context->current_frame, rgb_frame);
459 return context->current_frame;
462static AVRational calc_time_base(
uint den,
double num,
int codec_id)
469 float eps = FLT_EPSILON;
470 const uint DENUM_MAX = (codec_id == AV_CODEC_ID_MPEG4) ? (1UL << 16) - 1 : (1UL << 31) - 1;
481 eps =
float(1 << num_integer_bits) * FLT_EPSILON;
485 const int max_num_shift =
fabsf(log10f(
eps));
487 const int max_den_shift = log10f(DENUM_MAX) - log10f(den);
488 const int max_iter =
min_ii(max_num_shift, max_den_shift);
490 for (
int i = 0; i < max_iter &&
fabs(num -
round(num)) >
eps; i++) {
497 AVRational time_base;
499 time_base.num =
int(num);
504static const AVCodec *get_av1_encoder(
505 FFMpegContext *context,
RenderData *rd, AVDictionary **opts,
int rectx,
int recty)
511 const AVCodec *codec =
nullptr;
512 switch (context->ffmpeg_preset) {
516 codec = avcodec_find_encoder_by_name(
"librav1e");
519 codec = avcodec_find_encoder_by_name(
"libaom-av1");
523 codec = avcodec_find_encoder_by_name(
"libsvtav1");
527 codec = avcodec_find_encoder_by_name(
"libaom-av1");
533 codec = avcodec_find_encoder(AV_CODEC_ID_AV1);
538 if (
STREQ(codec->name,
"librav1e")) {
541 ffmpeg_dict_set_int(opts,
"tiles", rd->
threads);
544 ffmpeg_dict_set_int(opts,
"tiles", 8);
550 switch (context->ffmpeg_preset) {
552 ffmpeg_dict_set_int(opts,
"speed", 4);
555 ffmpeg_dict_set_int(opts,
"speed", 10);
559 ffmpeg_dict_set_int(opts,
"speed", 6);
562 if (context->ffmpeg_crf >= 0) {
565 uint qp_value =
float(context->ffmpeg_crf) * 255.0f / 51.0f;
566 if (qp_value > 255) {
569 ffmpeg_dict_set_int(opts,
"qp", qp_value);
573 SNPRINTF(buffer,
"keyint=%d", context->ffmpeg_gop_size);
574 av_dict_set(opts,
"rav1e-params", buffer, 0);
576 else if (
STREQ(codec->name,
"libsvtav1")) {
580 switch (context->ffmpeg_preset) {
582 ffmpeg_dict_set_int(opts,
"preset", 8);
585 ffmpeg_dict_set_int(opts,
"preset", 3);
589 ffmpeg_dict_set_int(opts,
"preset", 5);
592 if (context->ffmpeg_crf >= 0) {
595 ffmpeg_dict_set_int(opts,
"qp", context->ffmpeg_crf);
598 else if (
STREQ(codec->name,
"libaom-av1")) {
600 ffmpeg_dict_set_int(opts,
"row-mt", 1);
601 const char *tiles_string =
nullptr;
602 bool tiles_string_is_dynamic =
false;
606 if (threads_sqrt < 4) {
613 for (
int t_sqrt_copy = threads_sqrt; t_sqrt_copy > 0; t_sqrt_copy /= 10) {
617 char *tiles_string_mut = (
char *)calloc(digits * 2 + 2, 1);
618 BLI_snprintf(tiles_string_mut, digits * 2 + 2,
"%dx%d", threads_sqrt, threads_sqrt);
619 tiles_string_is_dynamic =
true;
620 tiles_string = tiles_string_mut;
631 if (sqrt_p2_next < 1) {
634 if (sqrt_p2 > sqrt_p2_next) {
637 sqrt_p2 = sqrt_p2_next;
640 int combined_digits = 0;
641 for (
int sqrt_p2_copy = sqrt_p2; sqrt_p2_copy > 0; sqrt_p2_copy /= 10) {
644 for (
int sqrt_p2_copy = sqrt_p2_next; sqrt_p2_copy > 0; sqrt_p2_copy /= 10) {
648 char *tiles_string_mut = (
char *)calloc(combined_digits + 2, 1);
650 BLI_snprintf(tiles_string_mut, combined_digits + 2,
"%dx%d", sqrt_p2_next, sqrt_p2);
652 else if (rectx < recty) {
653 BLI_snprintf(tiles_string_mut, combined_digits + 2,
"%dx%d", sqrt_p2, sqrt_p2_next);
656 BLI_snprintf(tiles_string_mut, combined_digits + 2,
"%dx%d", sqrt_p2, sqrt_p2);
658 tiles_string_is_dynamic =
true;
659 tiles_string = tiles_string_mut;
665 tiles_string =
"4x2";
667 else if (rectx < recty) {
668 tiles_string =
"2x4";
671 tiles_string =
"2x2";
674 av_dict_set(opts,
"tiles", tiles_string, 0);
675 if (tiles_string_is_dynamic) {
676 free((
void *)tiles_string);
682 switch (context->ffmpeg_preset) {
684 ffmpeg_dict_set_int(opts,
"cpu-used", 8);
687 ffmpeg_dict_set_int(opts,
"cpu-used", 4);
691 ffmpeg_dict_set_int(opts,
"cpu-used", 6);
703static SwsContext *sws_create_context(
int src_width,
711# if defined(FFMPEG_SWSCALE_THREADING)
714 SwsContext *c = sws_alloc_context();
718 av_opt_set_int(c,
"srcw", src_width, 0);
719 av_opt_set_int(c,
"srch", src_height, 0);
720 av_opt_set_int(c,
"src_format", av_src_format, 0);
721 av_opt_set_int(c,
"dstw", dst_width, 0);
722 av_opt_set_int(c,
"dsth", dst_height, 0);
723 av_opt_set_int(c,
"dst_format", av_dst_format, 0);
724 av_opt_set_int(c,
"sws_flags", sws_flags, 0);
727 if (sws_init_context(c,
nullptr,
nullptr) < 0) {
732 SwsContext *c = sws_getContext(src_width,
734 AVPixelFormat(av_src_format),
737 AVPixelFormat(av_dst_format),
747static void init_swscale_cache_if_needed()
749 if (swscale_cache ==
nullptr) {
751 swscale_cache_timestamp = 0;
755static bool remove_oldest_swscale_context()
759 for (
int64_t index = 0; index < swscale_cache->
size(); index++) {
760 SwscaleContext &ctx = (*swscale_cache)[index];
764 int64_t time = swscale_cache_timestamp - ctx.last_use_timestamp;
765 if (time > oldest_time) {
767 oldest_index = index;
771 if (oldest_index >= 0) {
772 SwscaleContext &ctx = (*swscale_cache)[oldest_index];
773 sws_freeContext(ctx.context);
780static void maintain_swscale_cache_size()
782 while (swscale_cache->
size() > swscale_cache_max_entries) {
783 if (!remove_oldest_swscale_context()) {
791SwsContext *BKE_ffmpeg_sws_get_context(
int src_width,
801 init_swscale_cache_if_needed();
803 swscale_cache_timestamp++;
806 SwsContext *ctx =
nullptr;
807 for (SwscaleContext &c : *swscale_cache) {
808 if (!c.is_used && c.src_width == src_width && c.src_height == src_height &&
809 c.src_format == av_src_format && c.dst_width == dst_width && c.dst_height == dst_height &&
810 c.dst_format == av_dst_format && c.flags == sws_flags)
815 c.last_use_timestamp = swscale_cache_timestamp;
819 if (ctx ==
nullptr) {
821 ctx = sws_create_context(
822 src_width, src_height, av_src_format, dst_width, dst_height, av_dst_format, sws_flags);
824 c.src_width = src_width;
825 c.src_height = src_height;
826 c.dst_width = dst_width;
827 c.dst_height = dst_height;
828 c.src_format = AVPixelFormat(av_src_format);
829 c.dst_format = AVPixelFormat(av_dst_format);
833 c.last_use_timestamp = swscale_cache_timestamp;
836 maintain_swscale_cache_size();
843void BKE_ffmpeg_sws_release_context(SwsContext *ctx)
846 init_swscale_cache_if_needed();
849 for (SwscaleContext &c : *swscale_cache) {
850 if (c.context == ctx) {
851 BLI_assert_msg(c.is_used,
"Releasing ffmpeg swscale context that is not in use");
857 BLI_assert_msg(found,
"Releasing ffmpeg swscale context that is not in cache");
859 maintain_swscale_cache_size();
864void BKE_ffmpeg_exit()
867 if (swscale_cache !=
nullptr) {
868 for (SwscaleContext &c : *swscale_cache) {
869 sws_freeContext(c.context);
871 delete swscale_cache;
872 swscale_cache =
nullptr;
877void BKE_ffmpeg_sws_scale_frame(SwsContext *ctx, AVFrame *dst,
const AVFrame *src)
879# if defined(FFMPEG_SWSCALE_THREADING)
880 sws_scale_frame(ctx, dst, src);
882 sws_scale(ctx, src->data, src->linesize, 0, src->height, dst->data, dst->linesize);
888static AVStream *alloc_video_stream(FFMpegContext *context,
898 const AVCodec *codec;
899 AVDictionary *opts =
nullptr;
903 st = avformat_new_stream(of,
nullptr);
911 if (codec_id == AV_CODEC_ID_AV1) {
914 codec = get_av1_encoder(context, rd, &opts, rectx, recty);
917 codec = avcodec_find_encoder(codec_id);
920 fprintf(stderr,
"Couldn't find valid video codec\n");
921 context->video_codec =
nullptr;
925 context->video_codec = avcodec_alloc_context3(codec);
926 AVCodecContext *c = context->video_codec;
933 if (context->ffmpeg_type == FFMPEG_DV && rd->
frs_sec != 25) {
935 c->time_base.den = 2997;
936 c->time_base.num = 100;
939 c->time_base.den = rd->
frs_sec;
952 if (c->time_base.num != 1) {
953 AVRational new_time_base;
955 &new_time_base.num, &new_time_base.den, c->time_base.num, c->time_base.den, INT_MAX))
958 c->time_base = new_time_base;
962 st->time_base = c->time_base;
964 c->gop_size = context->ffmpeg_gop_size;
965 c->max_b_frames = context->ffmpeg_max_b_frames;
967 if (context->ffmpeg_type == FFMPEG_WEBM && context->ffmpeg_crf == 0) {
968 ffmpeg_dict_set_int(&opts,
"lossless", 1);
970 else if (context->ffmpeg_crf >= 0) {
976 ffmpeg_dict_set_int(&opts,
"crf", context->ffmpeg_crf);
979 c->bit_rate = context->ffmpeg_video_bitrate * 1000;
985 if (context->ffmpeg_preset) {
989 char const *preset_name =
nullptr;
990 char const *deadline_name =
nullptr;
991 switch (context->ffmpeg_preset) {
993 preset_name =
"medium";
994 deadline_name =
"good";
997 preset_name =
"slower";
998 deadline_name =
"best";
1001 preset_name =
"superfast";
1002 deadline_name =
"realtime";
1005 printf(
"Unknown preset number %i, ignoring.\n", context->ffmpeg_preset);
1009 if (preset_name !=
nullptr && codec_id != AV_CODEC_ID_AV1) {
1010 av_dict_set(&opts,
"preset", preset_name, 0);
1012 if (deadline_name !=
nullptr) {
1013 av_dict_set(&opts,
"deadline", deadline_name, 0);
1019 if (codec->pix_fmts) {
1020 c->pix_fmt = codec->pix_fmts[0];
1024 c->pix_fmt = AV_PIX_FMT_YUV422P;
1027 if (context->ffmpeg_type == FFMPEG_XVID) {
1029 c->pix_fmt = AV_PIX_FMT_YUV420P;
1030 c->codec_tag = ((
'D' << 24) + (
'I' << 16) + (
'V' << 8) +
'X');
1034 if (codec_id == AV_CODEC_ID_HUFFYUV) {
1036 c->pix_fmt = AV_PIX_FMT_BGRA;
1039 c->pix_fmt = AV_PIX_FMT_RGB32;
1043 if (codec_id == AV_CODEC_ID_DNXHD) {
1050 if (codec_id == AV_CODEC_ID_FFV1) {
1051 c->pix_fmt = AV_PIX_FMT_RGB32;
1054 if (codec_id == AV_CODEC_ID_QTRLE) {
1056 c->pix_fmt = AV_PIX_FMT_ARGB;
1061 c->pix_fmt = AV_PIX_FMT_YUVA420P;
1063 else if (
ELEM(codec_id, AV_CODEC_ID_H264, AV_CODEC_ID_VP9) && (context->ffmpeg_crf == 0)) {
1065 c->pix_fmt = AV_PIX_FMT_YUV444P;
1068 if (codec_id == AV_CODEC_ID_PNG) {
1070 c->pix_fmt = AV_PIX_FMT_RGBA;
1074 if (of->oformat->flags & AVFMT_GLOBALHEADER) {
1075 PRINT(
"Using global header\n");
1076 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1081 st->sample_aspect_ratio = c->sample_aspect_ratio = av_d2q((
double(rd->
xasp) /
double(rd->
yasp)),
1083 st->avg_frame_rate = av_inv_q(c->time_base);
1085 if (codec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
1086 c->thread_count = 0;
1092 if (codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) {
1093 c->thread_type = FF_THREAD_FRAME;
1095 else if (codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) {
1096 c->thread_type = FF_THREAD_SLICE;
1099 int ret = avcodec_open2(c, codec, &opts);
1102 char error_str[AV_ERROR_MAX_STRING_SIZE];
1103 av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE,
ret);
1104 fprintf(stderr,
"Couldn't initialize video codec: %s\n", error_str);
1106 av_dict_free(&opts);
1107 avcodec_free_context(&c);
1108 context->video_codec =
nullptr;
1111 av_dict_free(&opts);
1114 context->current_frame = alloc_picture(c->pix_fmt, c->width, c->height);
1116 if (c->pix_fmt == AV_PIX_FMT_RGBA) {
1118 context->img_convert_frame =
nullptr;
1119 context->img_convert_ctx =
nullptr;
1123 context->img_convert_frame = alloc_picture(AV_PIX_FMT_RGBA, c->width, c->height);
1124 context->img_convert_ctx = BKE_ffmpeg_sws_get_context(
1125 c->width, c->height, AV_PIX_FMT_RGBA, c->width, c->height, c->pix_fmt, SWS_BICUBIC);
1128 avcodec_parameters_from_context(st->codecpar, c);
1130 context->video_time = 0.0f;
1135static AVStream *alloc_audio_stream(FFMpegContext *context,
1138 AVFormatContext *of,
1143 const AVCodec *codec;
1147 st = avformat_new_stream(of,
nullptr);
1153 codec = avcodec_find_encoder(codec_id);
1155 fprintf(stderr,
"Couldn't find valid audio codec\n");
1156 context->audio_codec =
nullptr;
1160 context->audio_codec = avcodec_alloc_context3(codec);
1161 AVCodecContext *c = context->audio_codec;
1163 c->thread_type = FF_THREAD_SLICE;
1166 c->bit_rate = context->ffmpeg_audio_bitrate * 1000;
1167 c->sample_fmt = AV_SAMPLE_FMT_S16;
1170 int channel_layout_mask = 0;
1173 channel_layout_mask = AV_CH_LAYOUT_MONO;
1176 channel_layout_mask = AV_CH_LAYOUT_STEREO;
1179 channel_layout_mask = AV_CH_LAYOUT_QUAD;
1182 channel_layout_mask = AV_CH_LAYOUT_5POINT1_BACK;
1185 channel_layout_mask = AV_CH_LAYOUT_7POINT1;
1190# ifdef FFMPEG_USE_OLD_CHANNEL_VARS
1191 c->channels = num_channels;
1192 c->channel_layout = channel_layout_mask;
1194 av_channel_layout_from_mask(&c->ch_layout, channel_layout_mask);
1197 if (request_float_audio_buffer(codec_id)) {
1199 c->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
1200 c->sample_fmt = AV_SAMPLE_FMT_FLT;
1203 if (codec->sample_fmts) {
1209 const enum AVSampleFormat *p = codec->sample_fmts;
1210 for (; *p != -1; p++) {
1211 if (*p == c->sample_fmt) {
1217 c->sample_fmt = codec->sample_fmts[0];
1221 if (codec->supported_samplerates) {
1222 const int *p = codec->supported_samplerates;
1224 int best_dist = INT_MAX;
1226 int dist =
abs(c->sample_rate - *p);
1227 if (dist < best_dist) {
1233 c->sample_rate = best;
1236 if (of->oformat->flags & AVFMT_GLOBALHEADER) {
1237 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1240 int ret = avcodec_open2(c, codec,
nullptr);
1243 char error_str[AV_ERROR_MAX_STRING_SIZE];
1244 av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE,
ret);
1245 fprintf(stderr,
"Couldn't initialize audio codec: %s\n", error_str);
1247 avcodec_free_context(&c);
1248 context->audio_codec =
nullptr;
1254 c->time_base.num = 1;
1255 c->time_base.den = c->sample_rate;
1257 if (c->frame_size == 0) {
1261 context->audio_input_samples = AV_INPUT_BUFFER_MIN_SIZE * 8 / c->bits_per_coded_sample /
1265 context->audio_input_samples = c->frame_size;
1268 context->audio_deinterleave = av_sample_fmt_is_planar(c->sample_fmt);
1270 context->audio_sample_size = av_get_bytes_per_sample(c->sample_fmt);
1272 context->audio_input_buffer = (
uint8_t *)av_malloc(context->audio_input_samples * num_channels *
1273 context->audio_sample_size);
1274 if (context->audio_deinterleave) {
1275 context->audio_deinterleave_buffer = (
uint8_t *)av_malloc(
1276 context->audio_input_samples * num_channels * context->audio_sample_size);
1279 context->audio_time = 0.0f;
1281 avcodec_parameters_from_context(st->codecpar, c);
1287static void ffmpeg_dict_set_int(AVDictionary **dict,
const char *key,
int value)
1293 av_dict_set(dict, key, buffer, 0);
1296static void ffmpeg_add_metadata_callback(
void *data,
1297 const char *propname,
1301 AVDictionary **metadata = (AVDictionary **)data;
1302 av_dict_set(metadata, propname, propvalue, 0);
1305static bool start_ffmpeg_impl(FFMpegContext *context,
1313 AVFormatContext *of;
1314 const AVOutputFormat *fmt;
1334 ffmpeg_filepath_get(context, filepath, rd, context->ffmpeg_preview, suffix);
1336 "Starting output to %s(FFMPEG)...\n"
1337 " Using type=%d, codec=%d, audio_codec=%d,\n"
1338 " video_bitrate=%d, audio_bitrate=%d,\n"
1339 " gop_size=%d, autosplit=%d\n"
1340 " render width=%d, render height=%d\n",
1342 context->ffmpeg_type,
1343 context->ffmpeg_codec,
1344 context->ffmpeg_audio_codec,
1345 context->ffmpeg_video_bitrate,
1346 context->ffmpeg_audio_bitrate,
1347 context->ffmpeg_gop_size,
1348 context->ffmpeg_autosplit,
1353 exts = get_file_extensions(context->ffmpeg_type);
1359 fmt = av_guess_format(
nullptr, exts[0],
nullptr);
1365 of = avformat_alloc_context();
1371 enum AVCodecID audio_codec = context->ffmpeg_audio_codec;
1372 enum AVCodecID video_codec = context->ffmpeg_codec;
1374 of->url = av_strdup(filepath);
1376 switch (context->ffmpeg_type) {
1378 video_codec = AV_CODEC_ID_THEORA;
1381 video_codec = AV_CODEC_ID_DVVIDEO;
1384 video_codec = AV_CODEC_ID_MPEG1VIDEO;
1387 video_codec = AV_CODEC_ID_MPEG2VIDEO;
1390 video_codec = AV_CODEC_ID_H264;
1393 video_codec = AV_CODEC_ID_MPEG4;
1396 video_codec = AV_CODEC_ID_FLV1;
1399 video_codec = AV_CODEC_ID_AV1;
1404 video_codec = context->ffmpeg_codec;
1410# if LIBAVFORMAT_VERSION_MAJOR >= 59
1414 of->oformat = (AVOutputFormat *)fmt;
1417 if (video_codec == AV_CODEC_ID_DVVIDEO) {
1422 if (rd->
frs_sec != 25 && recty != 480) {
1426 if (rd->
frs_sec == 25 && recty != 576) {
1432 if (context->ffmpeg_type == FFMPEG_DV) {
1433 audio_codec = AV_CODEC_ID_PCM_S16LE;
1434 if (context->ffmpeg_audio_codec != AV_CODEC_ID_NONE &&
1442 if (video_codec != AV_CODEC_ID_NONE) {
1443 context->video_stream = alloc_video_stream(
1444 context, rd, video_codec, of, rectx, recty,
error,
sizeof(
error));
1445 PRINT(
"alloc video stream %p\n", context->video_stream);
1446 if (!context->video_stream) {
1453 PRINT(
"Error initializing video stream");
1459 if (context->ffmpeg_audio_codec != AV_CODEC_ID_NONE) {
1460 context->audio_stream = alloc_audio_stream(context, rd, audio_codec, of,
error,
sizeof(
error));
1461 if (!context->audio_stream) {
1468 PRINT(
"Error initializing audio stream");
1473 if (!(fmt->flags & AVFMT_NOFILE)) {
1474 if (avio_open(&of->pb, filepath, AVIO_FLAG_WRITE) < 0) {
1476 PRINT(
"Could not open file for writing\n");
1481 if (context->stamp_data !=
nullptr) {
1483 &of->metadata, context->stamp_data, ffmpeg_add_metadata_callback,
false);
1486 ret = avformat_write_header(of,
nullptr);
1490 "Could not initialize streams, probably unsupported codec combination");
1491 char error_str[AV_ERROR_MAX_STRING_SIZE];
1492 av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE,
ret);
1493 PRINT(
"Could not write media header: %s\n", error_str);
1497 context->outfile = of;
1498 av_dump_format(of, 0, filepath, 1);
1507 if (context->video_stream) {
1508 context->video_stream =
nullptr;
1511 if (context->audio_stream) {
1512 context->audio_stream =
nullptr;
1515 avformat_free_context(of);
1536static void flush_ffmpeg(AVCodecContext *c, AVStream *stream, AVFormatContext *outfile)
1538 char error_str[AV_ERROR_MAX_STRING_SIZE];
1539 AVPacket *packet = av_packet_alloc();
1541 avcodec_send_frame(c,
nullptr);
1546 ret = avcodec_receive_packet(c, packet);
1548 if (
ret == AVERROR(EAGAIN) ||
ret == AVERROR_EOF) {
1553 av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE,
ret);
1554 fprintf(stderr,
"Error encoding delayed frame: %s\n", error_str);
1558 packet->stream_index = stream->index;
1559 av_packet_rescale_ts(packet, c->time_base, stream->time_base);
1560# ifdef FFMPEG_USE_DURATION_WORKAROUND
1564 int write_ret = av_interleaved_write_frame(outfile, packet);
1565 if (write_ret != 0) {
1566 av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE,
ret);
1567 fprintf(stderr,
"Error writing delayed frame: %s\n", error_str);
1572 av_packet_free(&packet);
1580static void ffmpeg_filepath_get(FFMpegContext *context,
1589 const char **fe = exts;
1592 if (!filepath || !exts) {
1610 autosplit[0] =
'\0';
1614 SNPRINTF(autosplit,
"_%03d", context->ffmpeg_autosplit_count);
1620 if (
BLI_strcasecmp(filepath + strlen(filepath) - strlen(*fe), *fe) == 0) {
1626 if (*fe ==
nullptr) {
1633 *(filepath + strlen(filepath) - strlen(*fe)) =
'\0';
1649void BKE_ffmpeg_filepath_get(
char filepath[ 1024],
1654 ffmpeg_filepath_get(
nullptr, filepath, rd, preview, suffix);
1657bool BKE_ffmpeg_start(
void *context_v,
1666 FFMpegContext *context =
static_cast<FFMpegContext *
>(context_v);
1668 context->ffmpeg_autosplit_count = 0;
1669 context->ffmpeg_preview = preview;
1672 bool success = start_ffmpeg_impl(context, rd, rectx, recty, suffix, reports);
1673# ifdef WITH_AUDASPACE
1674 if (context->audio_stream) {
1675 AVCodecContext *c = context->audio_codec;
1677 AUD_DeviceSpecs specs;
1678# ifdef FFMPEG_USE_OLD_CHANNEL_VARS
1679 specs.channels = AUD_Channels(c->channels);
1681 specs.channels = AUD_Channels(c->ch_layout.nb_channels);
1684 switch (av_get_packed_sample_fmt(c->sample_fmt)) {
1685 case AV_SAMPLE_FMT_U8:
1686 specs.format = AUD_FORMAT_U8;
1688 case AV_SAMPLE_FMT_S16:
1689 specs.format = AUD_FORMAT_S16;
1691 case AV_SAMPLE_FMT_S32:
1692 specs.format = AUD_FORMAT_S32;
1694 case AV_SAMPLE_FMT_FLT:
1695 specs.format = AUD_FORMAT_FLOAT32;
1697 case AV_SAMPLE_FMT_DBL:
1698 specs.format = AUD_FORMAT_FLOAT64;
1705 context->audio_mixdown_device = BKE_sound_mixdown(
1706 scene, specs, preview ? rd->
psfra : rd->sfra, rd->ffcodecdata.audio_volume);
1712static void end_ffmpeg_impl(FFMpegContext *context,
int is_autosplit);
1714# ifdef WITH_AUDASPACE
1715static void write_audio_frames(FFMpegContext *context,
double to_pts)
1717 AVCodecContext *c = context->audio_codec;
1719 while (context->audio_stream) {
1720 if ((context->audio_time_total >= to_pts) || !write_audio_frame(context)) {
1723 context->audio_time_total +=
double(context->audio_input_samples) /
double(c->sample_rate);
1724 context->audio_time +=
double(context->audio_input_samples) /
double(c->sample_rate);
1729bool BKE_ffmpeg_append(
void *context_v,
1737 FFMpegContext *context =
static_cast<FFMpegContext *
>(context_v);
1739 bool success =
true;
1741 PRINT(
"Writing frame %i, render width=%d, render height=%d\n", frame, image->x, image->y);
1743 if (context->video_stream) {
1744 avframe = generate_video_frame(context, image);
1745 success = (avframe && write_video_frame(context, avframe, reports));
1746# ifdef WITH_AUDASPACE
1754 if (context->ffmpeg_autosplit) {
1755 if (avio_tell(context->outfile->pb) > FFMPEG_AUTOSPLIT_SIZE) {
1756 end_ffmpeg_impl(context,
true);
1757 context->ffmpeg_autosplit_count++;
1759 success &= start_ffmpeg_impl(context, rd, image->x, image->y, suffix, reports);
1767static void end_ffmpeg_impl(FFMpegContext *context,
int is_autosplit)
1769 PRINT(
"Closing FFMPEG...\n");
1771# ifdef WITH_AUDASPACE
1772 if (is_autosplit ==
false) {
1773 if (context->audio_mixdown_device) {
1774 AUD_Device_free(context->audio_mixdown_device);
1775 context->audio_mixdown_device =
nullptr;
1782 if (context->video_stream) {
1783 PRINT(
"Flushing delayed video frames...\n");
1784 flush_ffmpeg(context->video_codec, context->video_stream, context->outfile);
1787 if (context->audio_stream) {
1788 PRINT(
"Flushing delayed audio frames...\n");
1789 flush_ffmpeg(context->audio_codec, context->audio_stream, context->outfile);
1792 if (context->outfile) {
1793 av_write_trailer(context->outfile);
1798 if (context->video_stream !=
nullptr) {
1799 PRINT(
"zero video stream %p\n", context->video_stream);
1800 context->video_stream =
nullptr;
1803 if (context->audio_stream !=
nullptr) {
1804 context->audio_stream =
nullptr;
1808 if (context->current_frame !=
nullptr) {
1809 delete_picture(context->current_frame);
1810 context->current_frame =
nullptr;
1812 if (context->img_convert_frame !=
nullptr) {
1813 delete_picture(context->img_convert_frame);
1814 context->img_convert_frame =
nullptr;
1817 if (context->outfile !=
nullptr && context->outfile->oformat) {
1818 if (!(context->outfile->oformat->flags & AVFMT_NOFILE)) {
1819 avio_close(context->outfile->pb);
1823 if (context->video_codec !=
nullptr) {
1824 avcodec_free_context(&context->video_codec);
1825 context->video_codec =
nullptr;
1827 if (context->audio_codec !=
nullptr) {
1828 avcodec_free_context(&context->audio_codec);
1829 context->audio_codec =
nullptr;
1832 if (context->outfile !=
nullptr) {
1833 avformat_free_context(context->outfile);
1834 context->outfile =
nullptr;
1836 if (context->audio_input_buffer !=
nullptr) {
1837 av_free(context->audio_input_buffer);
1838 context->audio_input_buffer =
nullptr;
1841 if (context->audio_deinterleave_buffer !=
nullptr) {
1842 av_free(context->audio_deinterleave_buffer);
1843 context->audio_deinterleave_buffer =
nullptr;
1846 if (context->img_convert_ctx !=
nullptr) {
1847 BKE_ffmpeg_sws_release_context(context->img_convert_ctx);
1848 context->img_convert_ctx =
nullptr;
1852void BKE_ffmpeg_end(
void *context_v)
1854 FFMpegContext *context =
static_cast<FFMpegContext *
>(context_v);
1855 end_ffmpeg_impl(context,
false);
1858void BKE_ffmpeg_preset_set(
RenderData *rd,
int preset)
1860 bool is_ntsc = (rd->
frs_sec != 25);
1863 case FFMPEG_PRESET_H264:
1875 case FFMPEG_PRESET_THEORA:
1876 case FFMPEG_PRESET_XVID:
1877 if (preset == FFMPEG_PRESET_XVID) {
1881 else if (preset == FFMPEG_PRESET_THEORA) {
1895 case FFMPEG_PRESET_AV1:
1917 BKE_ffmpeg_preset_set(rd, FFMPEG_PRESET_H264);
1930 BKE_ffmpeg_preset_set(rd, FFMPEG_PRESET_H264);
1936 BKE_ffmpeg_preset_set(rd, FFMPEG_PRESET_XVID);
1942 BKE_ffmpeg_preset_set(rd, FFMPEG_PRESET_THEORA);
1948 BKE_ffmpeg_preset_set(rd, FFMPEG_PRESET_AV1);
1959bool BKE_ffmpeg_alpha_channel_is_supported(
const RenderData *rd)
1968 AV_CODEC_ID_HUFFYUV);
1971void *BKE_ffmpeg_context_create()
1974 FFMpegContext *context =
static_cast<FFMpegContext *
>(
1975 MEM_callocN(
sizeof(FFMpegContext),
"new FFMPEG context"));
1977 context->ffmpeg_codec = AV_CODEC_ID_MPEG4;
1978 context->ffmpeg_audio_codec = AV_CODEC_ID_NONE;
1979 context->ffmpeg_video_bitrate = 1150;
1980 context->ffmpeg_audio_bitrate = 128;
1981 context->ffmpeg_gop_size = 12;
1982 context->ffmpeg_autosplit = 0;
1983 context->ffmpeg_autosplit_count = 0;
1984 context->ffmpeg_preview =
false;
1985 context->stamp_data =
nullptr;
1986 context->audio_time_total = 0.0;
1991void BKE_ffmpeg_context_free(
void *context_v)
1993 FFMpegContext *context =
static_cast<FFMpegContext *
>(context_v);
1994 if (context ==
nullptr) {
1997 if (context->stamp_data) {
StampData * BKE_stamp_info_from_scene_static(const Scene *scene)
void BKE_stamp_info_callback(void *data, StampData *stamp_data, StampCallback callback, bool noskip)
const char * BKE_main_blendfile_path_from_global()
void BKE_report(ReportList *reports, eReportType type, const char *message)
#define BLI_assert_msg(a, msg)
bool BLI_file_ensure_parent_dir_exists(const char *filepath) ATTR_NONNULL(1)
void BLI_kdtree_nd_ free(KDTree *tree)
MINLINE int power_of_2_min_i(int n)
MINLINE int min_ii(int a, int b)
MINLINE int is_power_of_2_i(int n)
MINLINE unsigned int log2_floor_u(unsigned int x)
bool BLI_path_abs(char path[FILE_MAX], const char *basepath) ATTR_NONNULL(1
bool bool BLI_path_suffix(char *path, size_t path_maxncpy, const char *suffix, const char *sep) ATTR_NONNULL(1
bool void bool BLI_path_frame_check_chars(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
bool BLI_path_frame_range(char *path, size_t path_maxncpy, int sta, int end, int digits) ATTR_NONNULL(1)
#define SNPRINTF(dst, format,...)
char char size_t char * BLI_strncat(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
int char char int BLI_strcasecmp(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
size_t BLI_snprintf(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
int BLI_system_thread_count(void)
void BLI_mutex_lock(ThreadMutex *mutex)
void BLI_mutex_unlock(ThreadMutex *mutex)
pthread_mutex_t ThreadMutex
#define UNUSED_VARS_NDEBUG(...)
typedef double(DMatrix)[4][4]
@ FFMPEG_AUTOSPLIT_OUTPUT
@ FFMPEG_USE_MAX_B_FRAMES
@ FFM_CHANNELS_SURROUND51
@ FFM_CHANNELS_SURROUND71
const char * IMB_ffmpeg_last_error()
Read Guarded memory(de)allocation.
void remove_and_reorder(const int64_t index)
void append(const T &value)
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
FFMPEG_INLINE size_t ffmpeg_get_buffer_alignment()
FFMPEG_INLINE void my_guess_pkt_duration(AVFormatContext *s, AVStream *st, AVPacket *pkt)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
ccl_device_inline float2 fabs(const float2 a)
static void error(const char *str)
#define PRINT(format,...)
struct ImageFormatData im_format
struct FFMpegCodecData ffcodecdata
ccl_device_inline int abs(int x)