2023-08-16 00:20:26 +10:00
|
|
|
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
2023-05-31 16:19:06 +02:00
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
2022-02-11 09:07:11 +11:00
|
|
|
* Partial Copyright 2006 Peter Schlaile. */
|
2006-02-05 19:14:46 +00:00
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
|
* \ingroup bke
|
2011-10-10 09:38:02 +00:00
|
|
|
*/
|
|
|
|
|
|
2006-02-05 19:14:46 +00:00
|
|
|
#ifdef WITH_FFMPEG
|
2024-01-08 11:32:49 +11:00
|
|
|
# include <cstdio>
|
|
|
|
|
# include <cstring>
|
2006-02-05 19:14:46 +00:00
|
|
|
|
2024-01-08 11:32:49 +11:00
|
|
|
# include <cstdlib>
|
2006-11-18 02:48:18 +00:00
|
|
|
|
2006-02-05 19:14:46 +00:00
|
|
|
# include "MEM_guardedalloc.h"
|
2009-12-22 12:01:32 +00:00
|
|
|
|
|
|
|
|
# include "DNA_scene_types.h"
|
|
|
|
|
|
2006-02-05 19:14:46 +00:00
|
|
|
# include "BLI_blenlib.h"
|
|
|
|
|
|
2011-06-23 09:27:56 +00:00
|
|
|
# ifdef WITH_AUDASPACE
|
2017-08-18 08:24:12 +02:00
|
|
|
# include <AUD_Device.h>
|
|
|
|
|
# include <AUD_Special.h>
|
2011-06-23 09:27:56 +00:00
|
|
|
# endif
|
2009-12-22 12:01:32 +00:00
|
|
|
|
2024-02-13 11:54:46 +11:00
|
|
|
# include "BLI_endian_defines.h"
|
2019-06-14 13:36:05 +02:00
|
|
|
# include "BLI_math_base.h"
|
2020-08-19 15:39:00 +02:00
|
|
|
# include "BLI_threads.h"
|
2012-02-07 17:11:56 +00:00
|
|
|
# include "BLI_utildefines.h"
|
2024-02-15 10:35:02 +01:00
|
|
|
# include "BLI_vector.hh"
|
2012-02-07 17:11:56 +00:00
|
|
|
|
2024-02-10 18:25:14 +01:00
|
|
|
# include "BKE_global.hh"
|
2018-04-05 16:31:59 +02:00
|
|
|
# include "BKE_image.h"
|
2023-12-01 19:43:16 +01:00
|
|
|
# include "BKE_main.hh"
|
2024-02-10 18:34:29 +01:00
|
|
|
# include "BKE_report.hh"
|
2009-12-22 12:01:32 +00:00
|
|
|
# include "BKE_sound.h"
|
2023-11-30 06:03:18 +01:00
|
|
|
# include "BKE_writeffmpeg.hh"
|
2006-02-05 19:14:46 +00:00
|
|
|
|
2024-01-18 22:50:23 +02:00
|
|
|
# include "IMB_imbuf.hh"
|
2006-02-05 19:14:46 +00:00
|
|
|
|
2019-06-28 22:53:58 -06:00
|
|
|
/* This needs to be included after BLI_math_base.h otherwise it will redefine some math defines
|
|
|
|
|
* like M_SQRT1_2 leading to warnings with MSVC */
|
2023-11-30 06:03:18 +01:00
|
|
|
extern "C" {
|
2019-06-28 22:53:58 -06:00
|
|
|
# include <libavcodec/avcodec.h>
|
2020-03-19 09:33:03 +01:00
|
|
|
# include <libavformat/avformat.h>
|
2023-12-15 12:35:59 +01:00
|
|
|
# include <libavutil/buffer.h>
|
2022-02-18 18:20:06 +01:00
|
|
|
# include <libavutil/channel_layout.h>
|
2024-04-02 13:03:05 +02:00
|
|
|
# include <libavutil/cpu.h>
|
2019-08-01 13:01:53 +02:00
|
|
|
# include <libavutil/imgutils.h>
|
2021-05-07 17:10:03 +02:00
|
|
|
# include <libavutil/opt.h>
|
2019-06-28 22:53:58 -06:00
|
|
|
# include <libavutil/rational.h>
|
|
|
|
|
# include <libavutil/samplefmt.h>
|
|
|
|
|
# include <libswscale/swscale.h>
|
|
|
|
|
|
2011-05-27 23:33:40 +00:00
|
|
|
# include "ffmpeg_compat.h"
|
2023-11-30 06:03:18 +01:00
|
|
|
}
|
2011-05-27 07:47:42 +00:00
|
|
|
|
2018-04-05 16:31:59 +02:00
|
|
|
struct StampData;
|
|
|
|
|
|
2024-02-15 10:35:02 +01:00
|
|
|
/* libswscale context creation and destruction is expensive.
|
|
|
|
|
* Maintain a cache of already created contexts. */
|
|
|
|
|
|
|
|
|
|
constexpr int64_t swscale_cache_max_entries = 32;
|
|
|
|
|
|
|
|
|
|
struct SwscaleContext {
|
|
|
|
|
int width = 0, height = 0;
|
|
|
|
|
AVPixelFormat src_format = AV_PIX_FMT_NONE, dst_format = AV_PIX_FMT_NONE;
|
|
|
|
|
int flags = 0;
|
|
|
|
|
|
|
|
|
|
SwsContext *context = nullptr;
|
|
|
|
|
int64_t last_use_timestamp = 0;
|
|
|
|
|
bool is_used = false;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static ThreadMutex swscale_cache_lock = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
|
static int64_t swscale_cache_timestamp = 0;
|
|
|
|
|
static blender::Vector<SwscaleContext> *swscale_cache = nullptr;
|
|
|
|
|
|
2023-11-30 06:03:18 +01:00
|
|
|
struct FFMpegContext {
|
2015-04-06 10:40:12 -03:00
|
|
|
int ffmpeg_type;
|
2023-11-30 06:03:18 +01:00
|
|
|
AVCodecID ffmpeg_codec;
|
|
|
|
|
AVCodecID ffmpeg_audio_codec;
|
2015-04-06 10:40:12 -03:00
|
|
|
int ffmpeg_video_bitrate;
|
|
|
|
|
int ffmpeg_audio_bitrate;
|
|
|
|
|
int ffmpeg_gop_size;
|
FFmpeg interface improvements
This patch changes a couple of things in the video output encoding.
{F362527}
- Clearer separation between container and codec. No more "format", as this is
too ambiguous. As a result, codecs were removed from the container list.
- Added FFmpeg speed presets, so the user can choosen from the range "Very
slow" to "Ultra fast". By default no preset is used.
- Added Constant Rate Factor (CRF) mode, which allows changing the bit-rate
depending on the desired quality and the input. This generally produces the
best quality videos, at the expense of not knowing the exact bit-rate and
file size.
- Added optional maximum of non-B-frames between B-frames (`max_b_frames`).
- Presets were adjusted for these changes, and new presets added. One of the
new presets is [recommended](https://trac.ffmpeg.org/wiki/Encode/VFX#H.264)
for reviewing videos, as it allows players to scrub through it easily. Might
be nice in weeklies. This preset also requires control over the
`max_b_frames` setting.
GUI-only changes:
- Renamed "MPEG" in the output file format menu with "FFmpeg", as this is more
accurate. After all, FFmpeg is used when this option is chosen, which can
also output non-MPEG files.
- Certain parts of the GUI are disabled when not in use:
- bit rate options are not used when a constant rate factor is given.
- audio bitrate & volume are not used when no audio is exported.
Note that I did not touch `BKE_ffmpeg_preset_set()`. There are currently two
preset systems for FFmpeg (`BKE_ffmpeg_preset_set()` and the Python preset
system). Before we do more work on `BKE_ffmpeg_preset_set()`, I think it's a
good idea to determine whether we want to keep it at all.
After this patch has been accepted, I'd be happy to go through the code and
remove any then-obsolete bits, such as the handling of "XVID" as a container
format.
Reviewers: sergey, mont29, brecht
Subscribers: mpan3, Blendify, brecht, fsiddi
Tags: #bf_blender
Differential Revision: https://developer.blender.org/D2242
2016-09-21 15:01:51 +02:00
|
|
|
int ffmpeg_max_b_frames;
|
2015-04-06 10:40:12 -03:00
|
|
|
int ffmpeg_autosplit;
|
|
|
|
|
int ffmpeg_autosplit_count;
|
|
|
|
|
bool ffmpeg_preview;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
FFmpeg interface improvements
This patch changes a couple of things in the video output encoding.
{F362527}
- Clearer separation between container and codec. No more "format", as this is
too ambiguous. As a result, codecs were removed from the container list.
- Added FFmpeg speed presets, so the user can choosen from the range "Very
slow" to "Ultra fast". By default no preset is used.
- Added Constant Rate Factor (CRF) mode, which allows changing the bit-rate
depending on the desired quality and the input. This generally produces the
best quality videos, at the expense of not knowing the exact bit-rate and
file size.
- Added optional maximum of non-B-frames between B-frames (`max_b_frames`).
- Presets were adjusted for these changes, and new presets added. One of the
new presets is [recommended](https://trac.ffmpeg.org/wiki/Encode/VFX#H.264)
for reviewing videos, as it allows players to scrub through it easily. Might
be nice in weeklies. This preset also requires control over the
`max_b_frames` setting.
GUI-only changes:
- Renamed "MPEG" in the output file format menu with "FFmpeg", as this is more
accurate. After all, FFmpeg is used when this option is chosen, which can
also output non-MPEG files.
- Certain parts of the GUI are disabled when not in use:
- bit rate options are not used when a constant rate factor is given.
- audio bitrate & volume are not used when no audio is exported.
Note that I did not touch `BKE_ffmpeg_preset_set()`. There are currently two
preset systems for FFmpeg (`BKE_ffmpeg_preset_set()` and the Python preset
system). Before we do more work on `BKE_ffmpeg_preset_set()`, I think it's a
good idea to determine whether we want to keep it at all.
After this patch has been accepted, I'd be happy to go through the code and
remove any then-obsolete bits, such as the handling of "XVID" as a container
format.
Reviewers: sergey, mont29, brecht
Subscribers: mpan3, Blendify, brecht, fsiddi
Tags: #bf_blender
Differential Revision: https://developer.blender.org/D2242
2016-09-21 15:01:51 +02:00
|
|
|
int ffmpeg_crf; /* set to 0 to not use CRF mode; we have another flag for lossless anyway. */
|
2017-10-17 13:43:10 +11:00
|
|
|
int ffmpeg_preset; /* see eFFMpegPreset */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
AVFormatContext *outfile;
|
2021-05-07 17:10:03 +02:00
|
|
|
AVCodecContext *video_codec;
|
|
|
|
|
AVCodecContext *audio_codec;
|
2015-04-06 10:40:12 -03:00
|
|
|
AVStream *video_stream;
|
|
|
|
|
AVStream *audio_stream;
|
2019-08-01 13:01:53 +02:00
|
|
|
AVFrame *current_frame; /* Image frame in output pixel format. */
|
2021-12-14 01:16:24 +01:00
|
|
|
int video_time;
|
2019-08-01 13:01:53 +02:00
|
|
|
|
|
|
|
|
/* Image frame in Blender's own pixel format, may need conversion to the output pixel format. */
|
|
|
|
|
AVFrame *img_convert_frame;
|
2023-11-30 06:03:18 +01:00
|
|
|
SwsContext *img_convert_ctx;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
uint8_t *audio_input_buffer;
|
|
|
|
|
uint8_t *audio_deinterleave_buffer;
|
|
|
|
|
int audio_input_samples;
|
|
|
|
|
double audio_time;
|
2021-12-14 01:16:24 +01:00
|
|
|
double audio_time_total;
|
2015-04-06 10:40:12 -03:00
|
|
|
bool audio_deinterleave;
|
|
|
|
|
int audio_sample_size;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-11-30 06:03:18 +01:00
|
|
|
StampData *stamp_data;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-06-23 16:10:48 +00:00
|
|
|
# ifdef WITH_AUDASPACE
|
2015-04-06 10:40:12 -03:00
|
|
|
AUD_Device *audio_mixdown_device;
|
2011-06-23 16:10:48 +00:00
|
|
|
# endif
|
2023-11-30 06:03:18 +01:00
|
|
|
};
|
2009-08-09 21:16:39 +00:00
|
|
|
|
2006-02-05 19:14:46 +00:00
|
|
|
# define FFMPEG_AUTOSPLIT_SIZE 2000000000
|
|
|
|
|
|
2012-08-26 11:01:14 +00:00
|
|
|
# define PRINT \
|
|
|
|
|
if (G.debug & G_DEBUG_FFMPEG) \
|
|
|
|
|
printf
|
|
|
|
|
|
2014-02-17 20:50:42 +06:00
|
|
|
static void ffmpeg_dict_set_int(AVDictionary **dict, const char *key, int value);
|
2020-03-13 17:27:11 +11:00
|
|
|
static void ffmpeg_filepath_get(FFMpegContext *context,
|
2023-05-30 10:31:31 +10:00
|
|
|
char filepath[FILE_MAX],
|
2023-06-03 08:36:28 +10:00
|
|
|
const RenderData *rd,
|
2020-03-13 17:27:11 +11:00
|
|
|
bool preview,
|
|
|
|
|
const char *suffix);
|
2014-02-17 20:50:42 +06:00
|
|
|
|
2006-02-05 19:14:46 +00:00
|
|
|
/* Delete a picture buffer */
|
|
|
|
|
|
2012-05-12 16:11:34 +00:00
|
|
|
static void delete_picture(AVFrame *f)
|
2006-02-05 19:14:46 +00:00
|
|
|
{
|
|
|
|
|
if (f) {
|
2023-12-15 12:35:59 +01:00
|
|
|
av_frame_free(&f);
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Patch #34204: [Render Animation] Fails with "Error: Specified sample_fmt is not supported" with ogg vorbis
Patch by Jehan Pages (pardon for mis-typing, emacs-nox works not so good with
urf-8 buffers here), with some own modifications. Thanks!
From the patch tracker:
The problem is because of several versions of ffmpeg, but even more because of
the fork situation libav/ffmpeg. So there are some installed versions out there
where you *must* use a float sample for some codec; whereas oppositely on some
other installations, you *must* use the int sample. So for some people, one
works not the other, and reciprocally.
As a consequence, you can't just have a switch codec-based, like in current
code, which decides on the float or int implementation, you must necessarily
have a runtime test because you won't know until then if ogg vorbis will use
one or another sample (note: that's true also for AC3 as I fixed the exact same
bug in DVDStyler for AC3 encoding a few months ago; and I guess it would be same
for AAC).
Some notes from self:
- New FFmpeg requires using FLTP for AAC, AC3 and Vorbis, it's not supported
by audaspace and result in this case would be just wrong. Throw an error
in cases FLTP is trying to be used.
- Moved strict_std_compliance a bit upper. When we'll support FLTP both
FLT and FLTP for AAC would need to be using FF_COMPLIANCE_EXPERIMENTAL.
- It is nice to have such check of supported by codec formats anyway.
2013-03-12 16:57:14 +00:00
|
|
|
static int request_float_audio_buffer(int codec_id)
|
2012-11-21 11:57:35 +00:00
|
|
|
{
|
Patch #34204: [Render Animation] Fails with "Error: Specified sample_fmt is not supported" with ogg vorbis
Patch by Jehan Pages (pardon for mis-typing, emacs-nox works not so good with
urf-8 buffers here), with some own modifications. Thanks!
From the patch tracker:
The problem is because of several versions of ffmpeg, but even more because of
the fork situation libav/ffmpeg. So there are some installed versions out there
where you *must* use a float sample for some codec; whereas oppositely on some
other installations, you *must* use the int sample. So for some people, one
works not the other, and reciprocally.
As a consequence, you can't just have a switch codec-based, like in current
code, which decides on the float or int implementation, you must necessarily
have a runtime test because you won't know until then if ogg vorbis will use
one or another sample (note: that's true also for AC3 as I fixed the exact same
bug in DVDStyler for AC3 encoding a few months ago; and I guess it would be same
for AAC).
Some notes from self:
- New FFmpeg requires using FLTP for AAC, AC3 and Vorbis, it's not supported
by audaspace and result in this case would be just wrong. Throw an error
in cases FLTP is trying to be used.
- Moved strict_std_compliance a bit upper. When we'll support FLTP both
FLT and FLTP for AAC would need to be using FF_COMPLIANCE_EXPERIMENTAL.
- It is nice to have such check of supported by codec formats anyway.
2013-03-12 16:57:14 +00:00
|
|
|
/* If any of these codecs, we prefer the float sample format (if supported) */
|
2014-01-16 15:40:37 +01:00
|
|
|
return codec_id == AV_CODEC_ID_AAC || codec_id == AV_CODEC_ID_AC3 ||
|
|
|
|
|
codec_id == AV_CODEC_ID_VORBIS;
|
2012-11-21 11:57:35 +00:00
|
|
|
}
|
|
|
|
|
|
2011-06-23 16:10:48 +00:00
|
|
|
# ifdef WITH_AUDASPACE
|
2021-05-07 17:10:03 +02:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
static int write_audio_frame(FFMpegContext *context)
|
2006-07-09 13:05:09 +00:00
|
|
|
{
|
2023-11-30 16:42:39 +11:00
|
|
|
AVFrame *frame = nullptr;
|
2021-05-07 17:10:03 +02:00
|
|
|
AVCodecContext *c = context->audio_codec;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Device_read(
|
|
|
|
|
context->audio_mixdown_device, context->audio_input_buffer, context->audio_input_samples);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-02-16 12:32:42 +01:00
|
|
|
frame = av_frame_alloc();
|
2015-04-06 10:40:12 -03:00
|
|
|
frame->pts = context->audio_time / av_q2d(c->time_base);
|
|
|
|
|
frame->nb_samples = context->audio_input_samples;
|
2013-04-01 15:31:27 +00:00
|
|
|
frame->format = c->sample_fmt;
|
2022-11-07 17:44:14 +01:00
|
|
|
# ifdef FFMPEG_USE_OLD_CHANNEL_VARS
|
|
|
|
|
frame->channels = c->channels;
|
|
|
|
|
frame->channel_layout = c->channel_layout;
|
|
|
|
|
const int num_channels = c->channels;
|
|
|
|
|
# else
|
2022-11-02 16:12:48 +01:00
|
|
|
av_channel_layout_copy(&frame->ch_layout, &c->ch_layout);
|
2022-11-07 17:44:14 +01:00
|
|
|
const int num_channels = c->ch_layout.nb_channels;
|
|
|
|
|
# endif
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
if (context->audio_deinterleave) {
|
2013-04-01 15:31:27 +00:00
|
|
|
int channel, i;
|
2013-04-03 01:36:00 +00:00
|
|
|
uint8_t *temp;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-11-07 17:44:14 +01:00
|
|
|
for (channel = 0; channel < num_channels; channel++) {
|
2013-04-03 01:36:00 +00:00
|
|
|
for (i = 0; i < frame->nb_samples; i++) {
|
2015-04-06 10:40:12 -03:00
|
|
|
memcpy(context->audio_deinterleave_buffer +
|
|
|
|
|
(i + channel * frame->nb_samples) * context->audio_sample_size,
|
2018-01-16 11:40:43 +11:00
|
|
|
context->audio_input_buffer +
|
2022-11-07 17:44:14 +01:00
|
|
|
(num_channels * i + channel) * context->audio_sample_size,
|
2018-01-16 11:40:43 +11:00
|
|
|
context->audio_sample_size);
|
2013-04-01 15:31:27 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
temp = context->audio_deinterleave_buffer;
|
|
|
|
|
context->audio_deinterleave_buffer = context->audio_input_buffer;
|
|
|
|
|
context->audio_input_buffer = temp;
|
2013-04-01 15:31:27 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
avcodec_fill_audio_frame(frame,
|
2022-11-07 17:44:14 +01:00
|
|
|
num_channels,
|
2015-04-06 10:40:12 -03:00
|
|
|
c->sample_fmt,
|
|
|
|
|
context->audio_input_buffer,
|
2022-11-07 17:44:14 +01:00
|
|
|
context->audio_input_samples * num_channels *
|
2022-11-02 16:12:48 +01:00
|
|
|
context->audio_sample_size,
|
2015-04-06 10:40:12 -03:00
|
|
|
1);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-05 14:16:02 +02:00
|
|
|
int success = 1;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-11-30 06:03:18 +01:00
|
|
|
char error_str[AV_ERROR_MAX_STRING_SIZE];
|
2021-05-07 17:10:03 +02:00
|
|
|
int ret = avcodec_send_frame(c, frame);
|
|
|
|
|
if (ret < 0) {
|
|
|
|
|
/* Can't send frame to encoder. This shouldn't happen. */
|
2023-11-30 06:03:18 +01:00
|
|
|
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
|
|
|
|
fprintf(stderr, "Can't send audio frame: %s\n", error_str);
|
2021-05-07 17:10:03 +02:00
|
|
|
success = -1;
|
2013-04-19 17:23:08 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-05-07 17:10:03 +02:00
|
|
|
AVPacket *pkt = av_packet_alloc();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-05-07 17:10:03 +02:00
|
|
|
while (ret >= 0) {
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-05-07 17:10:03 +02:00
|
|
|
ret = avcodec_receive_packet(c, pkt);
|
|
|
|
|
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
|
|
|
|
break;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2021-05-07 17:10:03 +02:00
|
|
|
if (ret < 0) {
|
2023-11-30 06:03:18 +01:00
|
|
|
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
|
|
|
|
fprintf(stderr, "Error encoding audio frame: %s\n", error_str);
|
2021-05-07 17:10:03 +02:00
|
|
|
success = -1;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2021-05-07 17:10:03 +02:00
|
|
|
|
|
|
|
|
pkt->stream_index = context->audio_stream->index;
|
2021-05-28 18:37:36 +02:00
|
|
|
av_packet_rescale_ts(pkt, c->time_base, context->audio_stream->time_base);
|
|
|
|
|
# ifdef FFMPEG_USE_DURATION_WORKAROUND
|
|
|
|
|
my_guess_pkt_duration(context->outfile, context->audio_stream, pkt);
|
|
|
|
|
# endif
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-05-07 17:10:03 +02:00
|
|
|
pkt->flags |= AV_PKT_FLAG_KEY;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-05-07 17:10:03 +02:00
|
|
|
int write_ret = av_interleaved_write_frame(context->outfile, pkt);
|
|
|
|
|
if (write_ret != 0) {
|
2023-11-30 06:03:18 +01:00
|
|
|
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
|
|
|
|
fprintf(stderr, "Error writing audio packet: %s\n", error_str);
|
2021-05-07 17:10:03 +02:00
|
|
|
success = -1;
|
|
|
|
|
break;
|
2013-04-01 15:31:27 +00:00
|
|
|
}
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-05-07 17:10:03 +02:00
|
|
|
av_packet_free(&pkt);
|
|
|
|
|
av_frame_free(&frame);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-05-07 17:10:03 +02:00
|
|
|
return success;
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
2011-06-23 16:10:48 +00:00
|
|
|
# endif /* #ifdef WITH_AUDASPACE */
|
2006-02-05 19:14:46 +00:00
|
|
|
|
|
|
|
|
/* Allocate a temporary frame */
|
2023-11-30 06:03:18 +01:00
|
|
|
static AVFrame *alloc_picture(AVPixelFormat pix_fmt, int width, int height)
|
2006-02-05 19:14:46 +00:00
|
|
|
{
|
|
|
|
|
/* allocate space for the struct */
|
2023-12-15 12:35:59 +01:00
|
|
|
AVFrame *f = av_frame_alloc();
|
|
|
|
|
if (f == nullptr) {
|
2023-11-30 16:42:39 +11:00
|
|
|
return nullptr;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2023-12-15 12:35:59 +01:00
|
|
|
|
2006-02-05 19:14:46 +00:00
|
|
|
/* allocate the actual picture buffer */
|
2024-04-02 13:03:05 +02:00
|
|
|
const size_t align = av_cpu_max_align();
|
|
|
|
|
int size = av_image_get_buffer_size(pix_fmt, width, height, align);
|
2023-12-15 12:35:59 +01:00
|
|
|
AVBufferRef *buf = av_buffer_alloc(size);
|
|
|
|
|
if (buf == nullptr) {
|
|
|
|
|
av_frame_free(&f);
|
2023-11-30 16:42:39 +11:00
|
|
|
return nullptr;
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
2021-05-07 17:10:03 +02:00
|
|
|
|
2024-04-02 13:03:05 +02:00
|
|
|
av_image_fill_arrays(f->data, f->linesize, buf->data, pix_fmt, width, height, align);
|
2023-12-15 12:35:59 +01:00
|
|
|
f->buf[0] = buf;
|
2019-08-01 13:01:53 +02:00
|
|
|
f->format = pix_fmt;
|
|
|
|
|
f->width = width;
|
|
|
|
|
f->height = height;
|
|
|
|
|
|
2006-02-05 19:14:46 +00:00
|
|
|
return f;
|
|
|
|
|
}
|
|
|
|
|
|
2006-07-09 13:05:09 +00:00
|
|
|
/* Get the correct file extensions for the requested format,
|
2012-04-22 11:54:53 +00:00
|
|
|
* first is always desired guess_format parameter */
|
2012-05-12 16:11:34 +00:00
|
|
|
static const char **get_file_extensions(int format)
|
2006-02-05 19:14:46 +00:00
|
|
|
{
|
2012-04-28 06:31:57 +00:00
|
|
|
switch (format) {
|
2012-09-08 08:59:47 +00:00
|
|
|
case FFMPEG_DV: {
|
2023-11-30 16:42:39 +11:00
|
|
|
static const char *rv[] = {".dv", nullptr};
|
2012-05-12 16:11:34 +00:00
|
|
|
return rv;
|
|
|
|
|
}
|
2012-09-08 08:59:47 +00:00
|
|
|
case FFMPEG_MPEG1: {
|
2023-11-30 16:42:39 +11:00
|
|
|
static const char *rv[] = {".mpg", ".mpeg", nullptr};
|
2012-05-12 16:11:34 +00:00
|
|
|
return rv;
|
|
|
|
|
}
|
2012-09-08 08:59:47 +00:00
|
|
|
case FFMPEG_MPEG2: {
|
2023-11-30 16:42:39 +11:00
|
|
|
static const char *rv[] = {".dvd", ".vob", ".mpg", ".mpeg", nullptr};
|
2012-05-12 16:11:34 +00:00
|
|
|
return rv;
|
|
|
|
|
}
|
2012-09-08 08:59:47 +00:00
|
|
|
case FFMPEG_MPEG4: {
|
2023-11-30 16:42:39 +11:00
|
|
|
static const char *rv[] = {".mp4", ".mpg", ".mpeg", nullptr};
|
2012-05-12 16:11:34 +00:00
|
|
|
return rv;
|
|
|
|
|
}
|
2012-09-08 08:59:47 +00:00
|
|
|
case FFMPEG_AVI: {
|
2023-11-30 16:42:39 +11:00
|
|
|
static const char *rv[] = {".avi", nullptr};
|
2012-05-12 16:11:34 +00:00
|
|
|
return rv;
|
|
|
|
|
}
|
2012-09-08 08:59:47 +00:00
|
|
|
case FFMPEG_MOV: {
|
2023-11-30 16:42:39 +11:00
|
|
|
static const char *rv[] = {".mov", nullptr};
|
2012-05-12 16:11:34 +00:00
|
|
|
return rv;
|
|
|
|
|
}
|
2012-09-08 08:59:47 +00:00
|
|
|
case FFMPEG_H264: {
|
2012-05-12 16:11:34 +00:00
|
|
|
/* FIXME: avi for now... */
|
2023-11-30 16:42:39 +11:00
|
|
|
static const char *rv[] = {".avi", nullptr};
|
2012-05-12 16:11:34 +00:00
|
|
|
return rv;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-09-08 08:59:47 +00:00
|
|
|
case FFMPEG_XVID: {
|
2012-05-12 16:11:34 +00:00
|
|
|
/* FIXME: avi for now... */
|
2023-11-30 16:42:39 +11:00
|
|
|
static const char *rv[] = {".avi", nullptr};
|
2012-05-12 16:11:34 +00:00
|
|
|
return rv;
|
|
|
|
|
}
|
2012-09-08 08:59:47 +00:00
|
|
|
case FFMPEG_FLV: {
|
2023-11-30 16:42:39 +11:00
|
|
|
static const char *rv[] = {".flv", nullptr};
|
2012-05-12 16:11:34 +00:00
|
|
|
return rv;
|
|
|
|
|
}
|
2012-09-08 08:59:47 +00:00
|
|
|
case FFMPEG_MKV: {
|
2023-11-30 16:42:39 +11:00
|
|
|
static const char *rv[] = {".mkv", nullptr};
|
2012-05-12 16:11:34 +00:00
|
|
|
return rv;
|
|
|
|
|
}
|
2012-09-08 08:59:47 +00:00
|
|
|
case FFMPEG_OGG: {
|
2023-11-30 16:42:39 +11:00
|
|
|
static const char *rv[] = {".ogv", ".ogg", nullptr};
|
2012-05-12 16:11:34 +00:00
|
|
|
return rv;
|
|
|
|
|
}
|
2019-07-31 11:20:21 +02:00
|
|
|
case FFMPEG_WEBM: {
|
2023-11-30 16:42:39 +11:00
|
|
|
static const char *rv[] = {".webm", nullptr};
|
2019-07-31 11:20:21 +02:00
|
|
|
return rv;
|
|
|
|
|
}
|
Video rendering: FFMpeg AV1 codec encoding support
Previously, the Blender video renderer did not have support for
encoding video to AV1 (not to be confused with the container AVI).
The proposed solution is to leverage the existing FFMpeg renderer
to encode to AV1.
Note that avcodec_find_encoder(AV_CODEC_ID_AV1) usually returns
"libaom-av1" which is the "reference implementation" for AV1 encoding
(the default for FFMpeg, and is slow). "libsvtav1" is faster and
preferred so there is extra handling when fetching the AV1 codec for
encoding such that "libsvtav1" is used when possible.
This commit should only affect the options available for video
rendering, which includes the additional AV1 codec to choose from, and
setting "-crf".
Also note that the current release of FFMpeg for ArchLinux does not
support "-crf" for "libsvtav1", but the equivalent option "-qp" is
supported and used as a fallback when "libsvtav1" is used (as
mentioned here: https://trac.ffmpeg.org/wiki/Encode/AV1#SVT-AV1 ).
(Actually, both "-crf" and "-qp" is specified with the same value in
the code. When a release of FFMpeg obtains support for "-crf" for
"libsvtav1" is released, the code shouldn't be needed to change.)
The usage of the AV1 codec should be very similar to the usage of the
H264 codec, but is limited to the "mp4" and "mkv" containers.
This patch pertains to the "VFX & Video" module, as its main purpose
is to supplement the Video Sequencer tool with the additional AV1
codec for encoded video output.
Differential Revision: https://developer.blender.org/D14920
Reviewed By: sergey , ISS, zeddb
2022-10-21 20:10:17 -06:00
|
|
|
case FFMPEG_AV1: {
|
2023-11-30 16:42:39 +11:00
|
|
|
static const char *rv[] = {".mp4", ".mkv", nullptr};
|
Video rendering: FFMpeg AV1 codec encoding support
Previously, the Blender video renderer did not have support for
encoding video to AV1 (not to be confused with the container AVI).
The proposed solution is to leverage the existing FFMpeg renderer
to encode to AV1.
Note that avcodec_find_encoder(AV_CODEC_ID_AV1) usually returns
"libaom-av1" which is the "reference implementation" for AV1 encoding
(the default for FFMpeg, and is slow). "libsvtav1" is faster and
preferred so there is extra handling when fetching the AV1 codec for
encoding such that "libsvtav1" is used when possible.
This commit should only affect the options available for video
rendering, which includes the additional AV1 codec to choose from, and
setting "-crf".
Also note that the current release of FFMpeg for ArchLinux does not
support "-crf" for "libsvtav1", but the equivalent option "-qp" is
supported and used as a fallback when "libsvtav1" is used (as
mentioned here: https://trac.ffmpeg.org/wiki/Encode/AV1#SVT-AV1 ).
(Actually, both "-crf" and "-qp" is specified with the same value in
the code. When a release of FFMpeg obtains support for "-crf" for
"libsvtav1" is released, the code shouldn't be needed to change.)
The usage of the AV1 codec should be very similar to the usage of the
H264 codec, but is limited to the "mp4" and "mkv" containers.
This patch pertains to the "VFX & Video" module, as its main purpose
is to supplement the Video Sequencer tool with the additional AV1
codec for encoded video output.
Differential Revision: https://developer.blender.org/D14920
Reviewed By: sergey , ISS, zeddb
2022-10-21 20:10:17 -06:00
|
|
|
return rv;
|
|
|
|
|
}
|
2012-05-12 16:11:34 +00:00
|
|
|
default:
|
2023-11-30 16:42:39 +11:00
|
|
|
return nullptr;
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Write a frame to the output file */
|
2024-02-21 12:57:36 +01:00
|
|
|
static bool write_video_frame(FFMpegContext *context, AVFrame *frame, ReportList *reports)
|
2006-07-09 13:05:09 +00:00
|
|
|
{
|
2012-05-12 16:11:34 +00:00
|
|
|
int ret, success = 1;
|
2021-05-07 17:10:03 +02:00
|
|
|
AVPacket *packet = av_packet_alloc();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-05-07 17:10:03 +02:00
|
|
|
AVCodecContext *c = context->video_codec;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-12-14 01:16:24 +01:00
|
|
|
frame->pts = context->video_time;
|
|
|
|
|
context->video_time++;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-11-30 06:03:18 +01:00
|
|
|
char error_str[AV_ERROR_MAX_STRING_SIZE];
|
2021-05-07 17:10:03 +02:00
|
|
|
ret = avcodec_send_frame(c, frame);
|
|
|
|
|
if (ret < 0) {
|
|
|
|
|
/* Can't send frame to encoder. This shouldn't happen. */
|
2023-11-30 06:03:18 +01:00
|
|
|
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
|
|
|
|
fprintf(stderr, "Can't send video frame: %s\n", error_str);
|
2021-05-07 17:10:03 +02:00
|
|
|
success = -1;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-05-07 17:10:03 +02:00
|
|
|
while (ret >= 0) {
|
|
|
|
|
ret = avcodec_receive_packet(c, packet);
|
|
|
|
|
|
|
|
|
|
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
|
|
|
|
/* No more packets available. */
|
|
|
|
|
break;
|
2014-01-28 23:00:28 +11:00
|
|
|
}
|
2021-05-07 17:10:03 +02:00
|
|
|
if (ret < 0) {
|
2023-11-30 06:03:18 +01:00
|
|
|
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
|
|
|
|
fprintf(stderr, "Error encoding frame: %s\n", error_str);
|
2021-05-07 17:10:03 +02:00
|
|
|
break;
|
2014-01-16 15:40:37 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-05-07 17:10:03 +02:00
|
|
|
packet->stream_index = context->video_stream->index;
|
|
|
|
|
av_packet_rescale_ts(packet, c->time_base, context->video_stream->time_base);
|
2021-05-28 18:37:36 +02:00
|
|
|
# ifdef FFMPEG_USE_DURATION_WORKAROUND
|
|
|
|
|
my_guess_pkt_duration(context->outfile, context->video_stream, packet);
|
|
|
|
|
# endif
|
|
|
|
|
|
2021-05-07 17:10:03 +02:00
|
|
|
if (av_interleaved_write_frame(context->outfile, packet) != 0) {
|
|
|
|
|
success = -1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2010-09-27 07:37:36 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (!success) {
|
2012-10-21 14:02:30 +00:00
|
|
|
BKE_report(reports, RPT_ERROR, "Error writing frame");
|
2023-11-30 06:03:18 +01:00
|
|
|
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
|
|
|
|
PRINT("Error writing frame: %s\n", error_str);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-05-07 17:10:03 +02:00
|
|
|
av_packet_free(&packet);
|
|
|
|
|
|
2009-12-22 12:01:32 +00:00
|
|
|
return success;
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
|
|
|
|
|
2021-07-05 14:16:02 +02:00
|
|
|
/* read and encode a frame of video from the buffer */
|
2024-02-21 12:57:36 +01:00
|
|
|
static AVFrame *generate_video_frame(FFMpegContext *context, const ImBuf *image)
|
2006-02-05 19:14:46 +00:00
|
|
|
{
|
2024-02-21 12:57:36 +01:00
|
|
|
/* For now only 8-bit/channel images are supported. */
|
|
|
|
|
const uint8_t *pixels = image->byte_buffer.data;
|
|
|
|
|
if (pixels == nullptr) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-07 17:10:03 +02:00
|
|
|
AVCodecParameters *codec = context->video_stream->codecpar;
|
|
|
|
|
int height = codec->height;
|
2012-05-12 16:11:34 +00:00
|
|
|
AVFrame *rgb_frame;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-11-30 16:42:39 +11:00
|
|
|
if (context->img_convert_frame != nullptr) {
|
2019-08-01 13:01:53 +02:00
|
|
|
/* Pixel format conversion is needed. */
|
|
|
|
|
rgb_frame = context->img_convert_frame;
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
2012-03-24 06:18:31 +00:00
|
|
|
else {
|
2019-08-01 13:01:53 +02:00
|
|
|
/* The output pixel format is Blender's internal pixel format. */
|
2015-04-06 10:40:12 -03:00
|
|
|
rgb_frame = context->current_frame;
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-03-07 14:58:15 +11:00
|
|
|
/* Copy the Blender pixels into the FFMPEG data-structure, taking care of endianness and flipping
|
2019-08-01 13:01:53 +02:00
|
|
|
* the image vertically. */
|
|
|
|
|
int linesize = rgb_frame->linesize[0];
|
2024-04-03 05:56:56 +02:00
|
|
|
int linesize_src = rgb_frame->width * 4;
|
2019-08-01 13:01:53 +02:00
|
|
|
for (int y = 0; y < height; y++) {
|
|
|
|
|
uint8_t *target = rgb_frame->data[0] + linesize * (height - y - 1);
|
2024-04-03 05:56:56 +02:00
|
|
|
const uint8_t *src = pixels + linesize_src * y;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-08-01 13:01:53 +02:00
|
|
|
# if ENDIAN_ORDER == L_ENDIAN
|
2024-04-03 05:56:56 +02:00
|
|
|
memcpy(target, src, linesize_src);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-08-01 13:01:53 +02:00
|
|
|
# elif ENDIAN_ORDER == B_ENDIAN
|
2024-04-03 05:56:56 +02:00
|
|
|
const uint8_t *end = src + linesize_src;
|
2019-08-01 13:01:53 +02:00
|
|
|
while (src != end) {
|
|
|
|
|
target[3] = src[0];
|
|
|
|
|
target[2] = src[1];
|
|
|
|
|
target[1] = src[2];
|
|
|
|
|
target[0] = src[3];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-08-01 13:01:53 +02:00
|
|
|
target += 4;
|
|
|
|
|
src += 4;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-08-01 13:01:53 +02:00
|
|
|
# else
|
|
|
|
|
# error ENDIAN_ORDER should either be L_ENDIAN or B_ENDIAN.
|
|
|
|
|
# endif
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-08-01 13:01:53 +02:00
|
|
|
/* Convert to the output pixel format, if it's different that Blender's internal one. */
|
2023-11-30 16:42:39 +11:00
|
|
|
if (context->img_convert_frame != nullptr) {
|
2019-08-01 13:01:53 +02:00
|
|
|
BLI_assert(context->img_convert_ctx != NULL);
|
ffmpeg: optimize ffmpeg_postprocess
After doing regular movie frame decoding, there's a "postprocess" step for
each incoming frame, that does deinterlacing if needed, then YUV->RGB
conversion, then vertical image flip and additional interlace filtering if
needed. While this postprocess step is not the "heavy" part of movie
playback, it still takes 2-3ms per each 1080p resolution input frame that
is being played.
This PR does two things:
- Similar to #116008, uses multi-threaded `sws_scale` to do YUV->RGB
conversion.
- Reintroduces "do vertical flip while converting to RGB", where possible.
That was removed in 2ed73fc97e due to issues on arm64 platform, and
theory that negative strides passed to sws_scale is not an officially
supported usage.
My take on the last point: negative strides to sws_scale is a fine and
supported usage, just ffmpeg had a bug specifically on arm64 where they
were accidentally not respected. They fixed that for ffmpeg 6.0, and
backported it to all versions back to 3.4.13 -- you would not backport
something to 10 releases unless that was an actual bug fix!
I have tested the glitch_480p.mp4 that was originally attached to the
bug report #94237 back then, and it works fine both on x64 (Windows)
and arm64 (Mac).
Timings, ffmpeg_postprocess cost for a single 1920x1080 resolution movie
strip inside VSE:
- Windows/VS2022 Ryzen 5950X: 3.04ms -> 1.18ms
- Mac/clang15 M1 Max: 1.10ms -> 0.71ms
Pull Request: https://projects.blender.org/blender/blender/pulls/116309
2023-12-19 18:28:51 +01:00
|
|
|
BKE_ffmpeg_sws_scale_frame(context->img_convert_ctx, context->current_frame, rgb_frame);
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
return context->current_frame;
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
|
|
|
|
|
2021-05-31 11:25:12 +02:00
|
|
|
static AVRational calc_time_base(uint den, double num, int codec_id)
|
|
|
|
|
{
|
|
|
|
|
/* Convert the input 'num' to an integer. Simply shift the decimal places until we get an integer
|
|
|
|
|
* (within a floating point error range).
|
2021-06-01 12:49:18 +10:00
|
|
|
* For example if we have `den = 3` and `num = 0.1` then the fps is: `den/num = 30` fps.
|
|
|
|
|
* When converting this to a FFMPEG time base, we want num to be an integer.
|
|
|
|
|
* So we simply move the decimal places of both numbers. i.e. `den = 30`, `num = 1`. */
|
2021-05-31 11:25:12 +02:00
|
|
|
float eps = FLT_EPSILON;
|
|
|
|
|
const uint DENUM_MAX = (codec_id == AV_CODEC_ID_MPEG4) ? (1UL << 16) - 1 : (1UL << 31) - 1;
|
|
|
|
|
|
|
|
|
|
/* Calculate the precision of the initial floating point number. */
|
|
|
|
|
if (num > 1.0) {
|
2023-11-30 16:42:39 +11:00
|
|
|
const uint num_integer_bits = log2_floor_u(uint(num));
|
2021-05-31 11:25:12 +02:00
|
|
|
|
|
|
|
|
/* Formula for calculating the epsilon value: (power of two range) / (pow mantissa bits)
|
2021-06-01 12:49:18 +10:00
|
|
|
* For example, a float has 23 mantissa bits and the float value 3.5f as a pow2 range of
|
2021-05-31 11:25:12 +02:00
|
|
|
* (4-2=2):
|
|
|
|
|
* (2) / pow2(23) = floating point precision for 3.5f
|
|
|
|
|
*/
|
2023-11-30 16:42:39 +11:00
|
|
|
eps = float(1 << num_integer_bits) * FLT_EPSILON;
|
2021-05-31 11:25:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Calculate how many decimal shifts we can do until we run out of precision. */
|
|
|
|
|
const int max_num_shift = fabsf(log10f(eps));
|
|
|
|
|
/* Calculate how many times we can shift the denominator. */
|
|
|
|
|
const int max_den_shift = log10f(DENUM_MAX) - log10f(den);
|
|
|
|
|
const int max_iter = min_ii(max_num_shift, max_den_shift);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < max_iter && fabs(num - round(num)) > eps; i++) {
|
|
|
|
|
/* Increase the number and denominator until both are integers. */
|
|
|
|
|
num *= 10;
|
|
|
|
|
den *= 10;
|
|
|
|
|
eps *= 10;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AVRational time_base;
|
|
|
|
|
time_base.den = den;
|
2023-11-30 16:42:39 +11:00
|
|
|
time_base.num = int(num);
|
2021-05-31 11:25:12 +02:00
|
|
|
|
|
|
|
|
return time_base;
|
|
|
|
|
}
|
|
|
|
|
|
Video rendering: FFMpeg AV1 codec encoding support
Previously, the Blender video renderer did not have support for
encoding video to AV1 (not to be confused with the container AVI).
The proposed solution is to leverage the existing FFMpeg renderer
to encode to AV1.
Note that avcodec_find_encoder(AV_CODEC_ID_AV1) usually returns
"libaom-av1" which is the "reference implementation" for AV1 encoding
(the default for FFMpeg, and is slow). "libsvtav1" is faster and
preferred so there is extra handling when fetching the AV1 codec for
encoding such that "libsvtav1" is used when possible.
This commit should only affect the options available for video
rendering, which includes the additional AV1 codec to choose from, and
setting "-crf".
Also note that the current release of FFMpeg for ArchLinux does not
support "-crf" for "libsvtav1", but the equivalent option "-qp" is
supported and used as a fallback when "libsvtav1" is used (as
mentioned here: https://trac.ffmpeg.org/wiki/Encode/AV1#SVT-AV1 ).
(Actually, both "-crf" and "-qp" is specified with the same value in
the code. When a release of FFMpeg obtains support for "-crf" for
"libsvtav1" is released, the code shouldn't be needed to change.)
The usage of the AV1 codec should be very similar to the usage of the
H264 codec, but is limited to the "mp4" and "mkv" containers.
This patch pertains to the "VFX & Video" module, as its main purpose
is to supplement the Video Sequencer tool with the additional AV1
codec for encoded video output.
Differential Revision: https://developer.blender.org/D14920
Reviewed By: sergey , ISS, zeddb
2022-10-21 20:10:17 -06:00
|
|
|
static const AVCodec *get_av1_encoder(
|
|
|
|
|
FFMpegContext *context, RenderData *rd, AVDictionary **opts, int rectx, int recty)
|
|
|
|
|
{
|
2023-02-03 12:41:01 +11:00
|
|
|
/* There are three possible encoders for AV1: `libaom-av1`, librav1e, and `libsvtav1`. librav1e
|
|
|
|
|
* tends to give the best compression quality while `libsvtav1` tends to be the fastest encoder.
|
|
|
|
|
* One of each will be picked based on the preset setting, and if a particular encoder is not
|
|
|
|
|
* available, then use the default returned by FFMpeg. */
|
2023-11-30 16:42:39 +11:00
|
|
|
const AVCodec *codec = nullptr;
|
Video rendering: FFMpeg AV1 codec encoding support
Previously, the Blender video renderer did not have support for
encoding video to AV1 (not to be confused with the container AVI).
The proposed solution is to leverage the existing FFMpeg renderer
to encode to AV1.
Note that avcodec_find_encoder(AV_CODEC_ID_AV1) usually returns
"libaom-av1" which is the "reference implementation" for AV1 encoding
(the default for FFMpeg, and is slow). "libsvtav1" is faster and
preferred so there is extra handling when fetching the AV1 codec for
encoding such that "libsvtav1" is used when possible.
This commit should only affect the options available for video
rendering, which includes the additional AV1 codec to choose from, and
setting "-crf".
Also note that the current release of FFMpeg for ArchLinux does not
support "-crf" for "libsvtav1", but the equivalent option "-qp" is
supported and used as a fallback when "libsvtav1" is used (as
mentioned here: https://trac.ffmpeg.org/wiki/Encode/AV1#SVT-AV1 ).
(Actually, both "-crf" and "-qp" is specified with the same value in
the code. When a release of FFMpeg obtains support for "-crf" for
"libsvtav1" is released, the code shouldn't be needed to change.)
The usage of the AV1 codec should be very similar to the usage of the
H264 codec, but is limited to the "mp4" and "mkv" containers.
This patch pertains to the "VFX & Video" module, as its main purpose
is to supplement the Video Sequencer tool with the additional AV1
codec for encoded video output.
Differential Revision: https://developer.blender.org/D14920
Reviewed By: sergey , ISS, zeddb
2022-10-21 20:10:17 -06:00
|
|
|
switch (context->ffmpeg_preset) {
|
|
|
|
|
case FFM_PRESET_BEST:
|
2023-02-03 12:41:01 +11:00
|
|
|
/* `libaom-av1` may produce better VMAF-scoring videos in several cases, but there are cases
|
2023-02-12 14:37:16 +11:00
|
|
|
* where using a different encoder is desirable, such as in #103849. */
|
2023-02-01 17:46:32 +01:00
|
|
|
codec = avcodec_find_encoder_by_name("librav1e");
|
Video rendering: FFMpeg AV1 codec encoding support
Previously, the Blender video renderer did not have support for
encoding video to AV1 (not to be confused with the container AVI).
The proposed solution is to leverage the existing FFMpeg renderer
to encode to AV1.
Note that avcodec_find_encoder(AV_CODEC_ID_AV1) usually returns
"libaom-av1" which is the "reference implementation" for AV1 encoding
(the default for FFMpeg, and is slow). "libsvtav1" is faster and
preferred so there is extra handling when fetching the AV1 codec for
encoding such that "libsvtav1" is used when possible.
This commit should only affect the options available for video
rendering, which includes the additional AV1 codec to choose from, and
setting "-crf".
Also note that the current release of FFMpeg for ArchLinux does not
support "-crf" for "libsvtav1", but the equivalent option "-qp" is
supported and used as a fallback when "libsvtav1" is used (as
mentioned here: https://trac.ffmpeg.org/wiki/Encode/AV1#SVT-AV1 ).
(Actually, both "-crf" and "-qp" is specified with the same value in
the code. When a release of FFMpeg obtains support for "-crf" for
"libsvtav1" is released, the code shouldn't be needed to change.)
The usage of the AV1 codec should be very similar to the usage of the
H264 codec, but is limited to the "mp4" and "mkv" containers.
This patch pertains to the "VFX & Video" module, as its main purpose
is to supplement the Video Sequencer tool with the additional AV1
codec for encoded video output.
Differential Revision: https://developer.blender.org/D14920
Reviewed By: sergey , ISS, zeddb
2022-10-21 20:10:17 -06:00
|
|
|
if (!codec) {
|
2023-02-03 12:41:01 +11:00
|
|
|
/* Fallback to `libaom-av1` if librav1e is not found. */
|
2023-02-01 17:46:32 +01:00
|
|
|
codec = avcodec_find_encoder_by_name("libaom-av1");
|
Video rendering: FFMpeg AV1 codec encoding support
Previously, the Blender video renderer did not have support for
encoding video to AV1 (not to be confused with the container AVI).
The proposed solution is to leverage the existing FFMpeg renderer
to encode to AV1.
Note that avcodec_find_encoder(AV_CODEC_ID_AV1) usually returns
"libaom-av1" which is the "reference implementation" for AV1 encoding
(the default for FFMpeg, and is slow). "libsvtav1" is faster and
preferred so there is extra handling when fetching the AV1 codec for
encoding such that "libsvtav1" is used when possible.
This commit should only affect the options available for video
rendering, which includes the additional AV1 codec to choose from, and
setting "-crf".
Also note that the current release of FFMpeg for ArchLinux does not
support "-crf" for "libsvtav1", but the equivalent option "-qp" is
supported and used as a fallback when "libsvtav1" is used (as
mentioned here: https://trac.ffmpeg.org/wiki/Encode/AV1#SVT-AV1 ).
(Actually, both "-crf" and "-qp" is specified with the same value in
the code. When a release of FFMpeg obtains support for "-crf" for
"libsvtav1" is released, the code shouldn't be needed to change.)
The usage of the AV1 codec should be very similar to the usage of the
H264 codec, but is limited to the "mp4" and "mkv" containers.
This patch pertains to the "VFX & Video" module, as its main purpose
is to supplement the Video Sequencer tool with the additional AV1
codec for encoded video output.
Differential Revision: https://developer.blender.org/D14920
Reviewed By: sergey , ISS, zeddb
2022-10-21 20:10:17 -06:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case FFM_PRESET_REALTIME:
|
|
|
|
|
codec = avcodec_find_encoder_by_name("libsvtav1");
|
|
|
|
|
break;
|
|
|
|
|
case FFM_PRESET_GOOD:
|
|
|
|
|
default:
|
|
|
|
|
codec = avcodec_find_encoder_by_name("libaom-av1");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Use the default AV1 encoder if the specified encoder wasn't found. */
|
|
|
|
|
if (!codec) {
|
|
|
|
|
codec = avcodec_find_encoder(AV_CODEC_ID_AV1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Apply AV1 encoder specific settings. */
|
|
|
|
|
if (codec) {
|
2022-10-29 12:05:16 +11:00
|
|
|
if (STREQ(codec->name, "librav1e")) {
|
Video rendering: FFMpeg AV1 codec encoding support
Previously, the Blender video renderer did not have support for
encoding video to AV1 (not to be confused with the container AVI).
The proposed solution is to leverage the existing FFMpeg renderer
to encode to AV1.
Note that avcodec_find_encoder(AV_CODEC_ID_AV1) usually returns
"libaom-av1" which is the "reference implementation" for AV1 encoding
(the default for FFMpeg, and is slow). "libsvtav1" is faster and
preferred so there is extra handling when fetching the AV1 codec for
encoding such that "libsvtav1" is used when possible.
This commit should only affect the options available for video
rendering, which includes the additional AV1 codec to choose from, and
setting "-crf".
Also note that the current release of FFMpeg for ArchLinux does not
support "-crf" for "libsvtav1", but the equivalent option "-qp" is
supported and used as a fallback when "libsvtav1" is used (as
mentioned here: https://trac.ffmpeg.org/wiki/Encode/AV1#SVT-AV1 ).
(Actually, both "-crf" and "-qp" is specified with the same value in
the code. When a release of FFMpeg obtains support for "-crf" for
"libsvtav1" is released, the code shouldn't be needed to change.)
The usage of the AV1 codec should be very similar to the usage of the
H264 codec, but is limited to the "mp4" and "mkv" containers.
This patch pertains to the "VFX & Video" module, as its main purpose
is to supplement the Video Sequencer tool with the additional AV1
codec for encoded video output.
Differential Revision: https://developer.blender.org/D14920
Reviewed By: sergey , ISS, zeddb
2022-10-21 20:10:17 -06:00
|
|
|
/* Set "tiles" to 8 to enable multi-threaded encoding. */
|
|
|
|
|
if (rd->threads > 8) {
|
|
|
|
|
ffmpeg_dict_set_int(opts, "tiles", rd->threads);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
ffmpeg_dict_set_int(opts, "tiles", 8);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Use a reasonable speed setting based on preset. Speed ranges from 0-10.
|
|
|
|
|
* Must check context->ffmpeg_preset again in case this encoder was selected due to the
|
|
|
|
|
* absence of another. */
|
|
|
|
|
switch (context->ffmpeg_preset) {
|
|
|
|
|
case FFM_PRESET_BEST:
|
|
|
|
|
ffmpeg_dict_set_int(opts, "speed", 4);
|
|
|
|
|
break;
|
|
|
|
|
case FFM_PRESET_REALTIME:
|
|
|
|
|
ffmpeg_dict_set_int(opts, "speed", 10);
|
|
|
|
|
break;
|
|
|
|
|
case FFM_PRESET_GOOD:
|
|
|
|
|
default:
|
|
|
|
|
ffmpeg_dict_set_int(opts, "speed", 6);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (context->ffmpeg_crf >= 0) {
|
2023-02-03 12:41:01 +11:00
|
|
|
/* librav1e does not use `-crf`, but uses `-qp` in the range of 0-255.
|
|
|
|
|
* Calculates the roughly equivalent float, and truncates it to an integer. */
|
2023-11-30 16:42:39 +11:00
|
|
|
uint qp_value = float(context->ffmpeg_crf) * 255.0f / 51.0f;
|
Video rendering: FFMpeg AV1 codec encoding support
Previously, the Blender video renderer did not have support for
encoding video to AV1 (not to be confused with the container AVI).
The proposed solution is to leverage the existing FFMpeg renderer
to encode to AV1.
Note that avcodec_find_encoder(AV_CODEC_ID_AV1) usually returns
"libaom-av1" which is the "reference implementation" for AV1 encoding
(the default for FFMpeg, and is slow). "libsvtav1" is faster and
preferred so there is extra handling when fetching the AV1 codec for
encoding such that "libsvtav1" is used when possible.
This commit should only affect the options available for video
rendering, which includes the additional AV1 codec to choose from, and
setting "-crf".
Also note that the current release of FFMpeg for ArchLinux does not
support "-crf" for "libsvtav1", but the equivalent option "-qp" is
supported and used as a fallback when "libsvtav1" is used (as
mentioned here: https://trac.ffmpeg.org/wiki/Encode/AV1#SVT-AV1 ).
(Actually, both "-crf" and "-qp" is specified with the same value in
the code. When a release of FFMpeg obtains support for "-crf" for
"libsvtav1" is released, the code shouldn't be needed to change.)
The usage of the AV1 codec should be very similar to the usage of the
H264 codec, but is limited to the "mp4" and "mkv" containers.
This patch pertains to the "VFX & Video" module, as its main purpose
is to supplement the Video Sequencer tool with the additional AV1
codec for encoded video output.
Differential Revision: https://developer.blender.org/D14920
Reviewed By: sergey , ISS, zeddb
2022-10-21 20:10:17 -06:00
|
|
|
if (qp_value > 255) {
|
|
|
|
|
qp_value = 255;
|
|
|
|
|
}
|
|
|
|
|
ffmpeg_dict_set_int(opts, "qp", qp_value);
|
|
|
|
|
}
|
|
|
|
|
/* Set gop_size as rav1e's "--keyint". */
|
|
|
|
|
char buffer[64];
|
2023-05-09 12:50:37 +10:00
|
|
|
SNPRINTF(buffer, "keyint=%d", context->ffmpeg_gop_size);
|
Video rendering: FFMpeg AV1 codec encoding support
Previously, the Blender video renderer did not have support for
encoding video to AV1 (not to be confused with the container AVI).
The proposed solution is to leverage the existing FFMpeg renderer
to encode to AV1.
Note that avcodec_find_encoder(AV_CODEC_ID_AV1) usually returns
"libaom-av1" which is the "reference implementation" for AV1 encoding
(the default for FFMpeg, and is slow). "libsvtav1" is faster and
preferred so there is extra handling when fetching the AV1 codec for
encoding such that "libsvtav1" is used when possible.
This commit should only affect the options available for video
rendering, which includes the additional AV1 codec to choose from, and
setting "-crf".
Also note that the current release of FFMpeg for ArchLinux does not
support "-crf" for "libsvtav1", but the equivalent option "-qp" is
supported and used as a fallback when "libsvtav1" is used (as
mentioned here: https://trac.ffmpeg.org/wiki/Encode/AV1#SVT-AV1 ).
(Actually, both "-crf" and "-qp" is specified with the same value in
the code. When a release of FFMpeg obtains support for "-crf" for
"libsvtav1" is released, the code shouldn't be needed to change.)
The usage of the AV1 codec should be very similar to the usage of the
H264 codec, but is limited to the "mp4" and "mkv" containers.
This patch pertains to the "VFX & Video" module, as its main purpose
is to supplement the Video Sequencer tool with the additional AV1
codec for encoded video output.
Differential Revision: https://developer.blender.org/D14920
Reviewed By: sergey , ISS, zeddb
2022-10-21 20:10:17 -06:00
|
|
|
av_dict_set(opts, "rav1e-params", buffer, 0);
|
|
|
|
|
}
|
2022-10-29 12:05:16 +11:00
|
|
|
else if (STREQ(codec->name, "libsvtav1")) {
|
Video rendering: FFMpeg AV1 codec encoding support
Previously, the Blender video renderer did not have support for
encoding video to AV1 (not to be confused with the container AVI).
The proposed solution is to leverage the existing FFMpeg renderer
to encode to AV1.
Note that avcodec_find_encoder(AV_CODEC_ID_AV1) usually returns
"libaom-av1" which is the "reference implementation" for AV1 encoding
(the default for FFMpeg, and is slow). "libsvtav1" is faster and
preferred so there is extra handling when fetching the AV1 codec for
encoding such that "libsvtav1" is used when possible.
This commit should only affect the options available for video
rendering, which includes the additional AV1 codec to choose from, and
setting "-crf".
Also note that the current release of FFMpeg for ArchLinux does not
support "-crf" for "libsvtav1", but the equivalent option "-qp" is
supported and used as a fallback when "libsvtav1" is used (as
mentioned here: https://trac.ffmpeg.org/wiki/Encode/AV1#SVT-AV1 ).
(Actually, both "-crf" and "-qp" is specified with the same value in
the code. When a release of FFMpeg obtains support for "-crf" for
"libsvtav1" is released, the code shouldn't be needed to change.)
The usage of the AV1 codec should be very similar to the usage of the
H264 codec, but is limited to the "mp4" and "mkv" containers.
This patch pertains to the "VFX & Video" module, as its main purpose
is to supplement the Video Sequencer tool with the additional AV1
codec for encoded video output.
Differential Revision: https://developer.blender.org/D14920
Reviewed By: sergey , ISS, zeddb
2022-10-21 20:10:17 -06:00
|
|
|
/* Set preset value based on ffmpeg_preset.
|
2023-02-03 12:41:01 +11:00
|
|
|
* Must check `context->ffmpeg_preset` again in case this encoder was selected due to the
|
Video rendering: FFMpeg AV1 codec encoding support
Previously, the Blender video renderer did not have support for
encoding video to AV1 (not to be confused with the container AVI).
The proposed solution is to leverage the existing FFMpeg renderer
to encode to AV1.
Note that avcodec_find_encoder(AV_CODEC_ID_AV1) usually returns
"libaom-av1" which is the "reference implementation" for AV1 encoding
(the default for FFMpeg, and is slow). "libsvtav1" is faster and
preferred so there is extra handling when fetching the AV1 codec for
encoding such that "libsvtav1" is used when possible.
This commit should only affect the options available for video
rendering, which includes the additional AV1 codec to choose from, and
setting "-crf".
Also note that the current release of FFMpeg for ArchLinux does not
support "-crf" for "libsvtav1", but the equivalent option "-qp" is
supported and used as a fallback when "libsvtav1" is used (as
mentioned here: https://trac.ffmpeg.org/wiki/Encode/AV1#SVT-AV1 ).
(Actually, both "-crf" and "-qp" is specified with the same value in
the code. When a release of FFMpeg obtains support for "-crf" for
"libsvtav1" is released, the code shouldn't be needed to change.)
The usage of the AV1 codec should be very similar to the usage of the
H264 codec, but is limited to the "mp4" and "mkv" containers.
This patch pertains to the "VFX & Video" module, as its main purpose
is to supplement the Video Sequencer tool with the additional AV1
codec for encoded video output.
Differential Revision: https://developer.blender.org/D14920
Reviewed By: sergey , ISS, zeddb
2022-10-21 20:10:17 -06:00
|
|
|
* absence of another. */
|
|
|
|
|
switch (context->ffmpeg_preset) {
|
|
|
|
|
case FFM_PRESET_REALTIME:
|
|
|
|
|
ffmpeg_dict_set_int(opts, "preset", 8);
|
|
|
|
|
break;
|
|
|
|
|
case FFM_PRESET_BEST:
|
|
|
|
|
ffmpeg_dict_set_int(opts, "preset", 3);
|
|
|
|
|
break;
|
|
|
|
|
case FFM_PRESET_GOOD:
|
|
|
|
|
default:
|
|
|
|
|
ffmpeg_dict_set_int(opts, "preset", 5);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (context->ffmpeg_crf >= 0) {
|
2023-12-07 12:15:45 +11:00
|
|
|
/* `libsvtav1` does not support CRF until FFMPEG builds since 2022-02-24,
|
2023-02-03 12:41:01 +11:00
|
|
|
* use `qp` as fallback. */
|
Video rendering: FFMpeg AV1 codec encoding support
Previously, the Blender video renderer did not have support for
encoding video to AV1 (not to be confused with the container AVI).
The proposed solution is to leverage the existing FFMpeg renderer
to encode to AV1.
Note that avcodec_find_encoder(AV_CODEC_ID_AV1) usually returns
"libaom-av1" which is the "reference implementation" for AV1 encoding
(the default for FFMpeg, and is slow). "libsvtav1" is faster and
preferred so there is extra handling when fetching the AV1 codec for
encoding such that "libsvtav1" is used when possible.
This commit should only affect the options available for video
rendering, which includes the additional AV1 codec to choose from, and
setting "-crf".
Also note that the current release of FFMpeg for ArchLinux does not
support "-crf" for "libsvtav1", but the equivalent option "-qp" is
supported and used as a fallback when "libsvtav1" is used (as
mentioned here: https://trac.ffmpeg.org/wiki/Encode/AV1#SVT-AV1 ).
(Actually, both "-crf" and "-qp" is specified with the same value in
the code. When a release of FFMpeg obtains support for "-crf" for
"libsvtav1" is released, the code shouldn't be needed to change.)
The usage of the AV1 codec should be very similar to the usage of the
H264 codec, but is limited to the "mp4" and "mkv" containers.
This patch pertains to the "VFX & Video" module, as its main purpose
is to supplement the Video Sequencer tool with the additional AV1
codec for encoded video output.
Differential Revision: https://developer.blender.org/D14920
Reviewed By: sergey , ISS, zeddb
2022-10-21 20:10:17 -06:00
|
|
|
ffmpeg_dict_set_int(opts, "qp", context->ffmpeg_crf);
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-10-29 12:05:16 +11:00
|
|
|
else if (STREQ(codec->name, "libaom-av1")) {
|
2023-02-03 12:41:01 +11:00
|
|
|
/* Speed up libaom-av1 encoding by enabling multi-threading and setting tiles. */
|
Video rendering: FFMpeg AV1 codec encoding support
Previously, the Blender video renderer did not have support for
encoding video to AV1 (not to be confused with the container AVI).
The proposed solution is to leverage the existing FFMpeg renderer
to encode to AV1.
Note that avcodec_find_encoder(AV_CODEC_ID_AV1) usually returns
"libaom-av1" which is the "reference implementation" for AV1 encoding
(the default for FFMpeg, and is slow). "libsvtav1" is faster and
preferred so there is extra handling when fetching the AV1 codec for
encoding such that "libsvtav1" is used when possible.
This commit should only affect the options available for video
rendering, which includes the additional AV1 codec to choose from, and
setting "-crf".
Also note that the current release of FFMpeg for ArchLinux does not
support "-crf" for "libsvtav1", but the equivalent option "-qp" is
supported and used as a fallback when "libsvtav1" is used (as
mentioned here: https://trac.ffmpeg.org/wiki/Encode/AV1#SVT-AV1 ).
(Actually, both "-crf" and "-qp" is specified with the same value in
the code. When a release of FFMpeg obtains support for "-crf" for
"libsvtav1" is released, the code shouldn't be needed to change.)
The usage of the AV1 codec should be very similar to the usage of the
H264 codec, but is limited to the "mp4" and "mkv" containers.
This patch pertains to the "VFX & Video" module, as its main purpose
is to supplement the Video Sequencer tool with the additional AV1
codec for encoded video output.
Differential Revision: https://developer.blender.org/D14920
Reviewed By: sergey , ISS, zeddb
2022-10-21 20:10:17 -06:00
|
|
|
ffmpeg_dict_set_int(opts, "row-mt", 1);
|
2023-11-30 16:42:39 +11:00
|
|
|
const char *tiles_string = nullptr;
|
Video rendering: FFMpeg AV1 codec encoding support
Previously, the Blender video renderer did not have support for
encoding video to AV1 (not to be confused with the container AVI).
The proposed solution is to leverage the existing FFMpeg renderer
to encode to AV1.
Note that avcodec_find_encoder(AV_CODEC_ID_AV1) usually returns
"libaom-av1" which is the "reference implementation" for AV1 encoding
(the default for FFMpeg, and is slow). "libsvtav1" is faster and
preferred so there is extra handling when fetching the AV1 codec for
encoding such that "libsvtav1" is used when possible.
This commit should only affect the options available for video
rendering, which includes the additional AV1 codec to choose from, and
setting "-crf".
Also note that the current release of FFMpeg for ArchLinux does not
support "-crf" for "libsvtav1", but the equivalent option "-qp" is
supported and used as a fallback when "libsvtav1" is used (as
mentioned here: https://trac.ffmpeg.org/wiki/Encode/AV1#SVT-AV1 ).
(Actually, both "-crf" and "-qp" is specified with the same value in
the code. When a release of FFMpeg obtains support for "-crf" for
"libsvtav1" is released, the code shouldn't be needed to change.)
The usage of the AV1 codec should be very similar to the usage of the
H264 codec, but is limited to the "mp4" and "mkv" containers.
This patch pertains to the "VFX & Video" module, as its main purpose
is to supplement the Video Sequencer tool with the additional AV1
codec for encoded video output.
Differential Revision: https://developer.blender.org/D14920
Reviewed By: sergey , ISS, zeddb
2022-10-21 20:10:17 -06:00
|
|
|
bool tiles_string_is_dynamic = false;
|
|
|
|
|
if (rd->threads > 0) {
|
|
|
|
|
/* See if threads is a square. */
|
|
|
|
|
int threads_sqrt = sqrtf(rd->threads);
|
|
|
|
|
if (threads_sqrt < 4) {
|
|
|
|
|
/* Ensure a default minimum. */
|
|
|
|
|
threads_sqrt = 4;
|
|
|
|
|
}
|
|
|
|
|
if (is_power_of_2_i(threads_sqrt) && threads_sqrt * threads_sqrt == rd->threads) {
|
|
|
|
|
/* Is a square num, therefore just do "sqrt x sqrt" for tiles parameter. */
|
|
|
|
|
int digits = 0;
|
|
|
|
|
for (int t_sqrt_copy = threads_sqrt; t_sqrt_copy > 0; t_sqrt_copy /= 10) {
|
|
|
|
|
++digits;
|
|
|
|
|
}
|
|
|
|
|
/* A char array need only an alignment of 1. */
|
|
|
|
|
char *tiles_string_mut = (char *)calloc(digits * 2 + 2, 1);
|
|
|
|
|
BLI_snprintf(tiles_string_mut, digits * 2 + 2, "%dx%d", threads_sqrt, threads_sqrt);
|
|
|
|
|
tiles_string_is_dynamic = true;
|
|
|
|
|
tiles_string = tiles_string_mut;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Is not a square num, set greater side based on longer side, or use a square if both
|
2023-03-09 10:39:49 +11:00
|
|
|
* sides are equal. */
|
Video rendering: FFMpeg AV1 codec encoding support
Previously, the Blender video renderer did not have support for
encoding video to AV1 (not to be confused with the container AVI).
The proposed solution is to leverage the existing FFMpeg renderer
to encode to AV1.
Note that avcodec_find_encoder(AV_CODEC_ID_AV1) usually returns
"libaom-av1" which is the "reference implementation" for AV1 encoding
(the default for FFMpeg, and is slow). "libsvtav1" is faster and
preferred so there is extra handling when fetching the AV1 codec for
encoding such that "libsvtav1" is used when possible.
This commit should only affect the options available for video
rendering, which includes the additional AV1 codec to choose from, and
setting "-crf".
Also note that the current release of FFMpeg for ArchLinux does not
support "-crf" for "libsvtav1", but the equivalent option "-qp" is
supported and used as a fallback when "libsvtav1" is used (as
mentioned here: https://trac.ffmpeg.org/wiki/Encode/AV1#SVT-AV1 ).
(Actually, both "-crf" and "-qp" is specified with the same value in
the code. When a release of FFMpeg obtains support for "-crf" for
"libsvtav1" is released, the code shouldn't be needed to change.)
The usage of the AV1 codec should be very similar to the usage of the
H264 codec, but is limited to the "mp4" and "mkv" containers.
This patch pertains to the "VFX & Video" module, as its main purpose
is to supplement the Video Sequencer tool with the additional AV1
codec for encoded video output.
Differential Revision: https://developer.blender.org/D14920
Reviewed By: sergey , ISS, zeddb
2022-10-21 20:10:17 -06:00
|
|
|
int sqrt_p2 = power_of_2_min_i(threads_sqrt);
|
|
|
|
|
if (sqrt_p2 < 2) {
|
|
|
|
|
/* Ensure a default minimum. */
|
|
|
|
|
sqrt_p2 = 2;
|
|
|
|
|
}
|
2023-11-30 16:42:39 +11:00
|
|
|
int sqrt_p2_next = power_of_2_min_i(int(rd->threads) / sqrt_p2);
|
Video rendering: FFMpeg AV1 codec encoding support
Previously, the Blender video renderer did not have support for
encoding video to AV1 (not to be confused with the container AVI).
The proposed solution is to leverage the existing FFMpeg renderer
to encode to AV1.
Note that avcodec_find_encoder(AV_CODEC_ID_AV1) usually returns
"libaom-av1" which is the "reference implementation" for AV1 encoding
(the default for FFMpeg, and is slow). "libsvtav1" is faster and
preferred so there is extra handling when fetching the AV1 codec for
encoding such that "libsvtav1" is used when possible.
This commit should only affect the options available for video
rendering, which includes the additional AV1 codec to choose from, and
setting "-crf".
Also note that the current release of FFMpeg for ArchLinux does not
support "-crf" for "libsvtav1", but the equivalent option "-qp" is
supported and used as a fallback when "libsvtav1" is used (as
mentioned here: https://trac.ffmpeg.org/wiki/Encode/AV1#SVT-AV1 ).
(Actually, both "-crf" and "-qp" is specified with the same value in
the code. When a release of FFMpeg obtains support for "-crf" for
"libsvtav1" is released, the code shouldn't be needed to change.)
The usage of the AV1 codec should be very similar to the usage of the
H264 codec, but is limited to the "mp4" and "mkv" containers.
This patch pertains to the "VFX & Video" module, as its main purpose
is to supplement the Video Sequencer tool with the additional AV1
codec for encoded video output.
Differential Revision: https://developer.blender.org/D14920
Reviewed By: sergey , ISS, zeddb
2022-10-21 20:10:17 -06:00
|
|
|
if (sqrt_p2_next < 1) {
|
|
|
|
|
sqrt_p2_next = 1;
|
|
|
|
|
}
|
|
|
|
|
if (sqrt_p2 > sqrt_p2_next) {
|
|
|
|
|
/* Ensure sqrt_p2_next is greater or equal to sqrt_p2. */
|
|
|
|
|
int temp = sqrt_p2;
|
|
|
|
|
sqrt_p2 = sqrt_p2_next;
|
|
|
|
|
sqrt_p2_next = temp;
|
|
|
|
|
}
|
|
|
|
|
int combined_digits = 0;
|
|
|
|
|
for (int sqrt_p2_copy = sqrt_p2; sqrt_p2_copy > 0; sqrt_p2_copy /= 10) {
|
|
|
|
|
++combined_digits;
|
|
|
|
|
}
|
|
|
|
|
for (int sqrt_p2_copy = sqrt_p2_next; sqrt_p2_copy > 0; sqrt_p2_copy /= 10) {
|
|
|
|
|
++combined_digits;
|
|
|
|
|
}
|
|
|
|
|
/* A char array need only an alignment of 1. */
|
|
|
|
|
char *tiles_string_mut = (char *)calloc(combined_digits + 2, 1);
|
|
|
|
|
if (rectx > recty) {
|
|
|
|
|
BLI_snprintf(tiles_string_mut, combined_digits + 2, "%dx%d", sqrt_p2_next, sqrt_p2);
|
|
|
|
|
}
|
|
|
|
|
else if (rectx < recty) {
|
|
|
|
|
BLI_snprintf(tiles_string_mut, combined_digits + 2, "%dx%d", sqrt_p2, sqrt_p2_next);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BLI_snprintf(tiles_string_mut, combined_digits + 2, "%dx%d", sqrt_p2, sqrt_p2);
|
|
|
|
|
}
|
|
|
|
|
tiles_string_is_dynamic = true;
|
|
|
|
|
tiles_string = tiles_string_mut;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Thread count unknown, default to 8. */
|
|
|
|
|
if (rectx > recty) {
|
|
|
|
|
tiles_string = "4x2";
|
|
|
|
|
}
|
|
|
|
|
else if (rectx < recty) {
|
|
|
|
|
tiles_string = "2x4";
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
tiles_string = "2x2";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
av_dict_set(opts, "tiles", tiles_string, 0);
|
|
|
|
|
if (tiles_string_is_dynamic) {
|
|
|
|
|
free((void *)tiles_string);
|
|
|
|
|
}
|
|
|
|
|
/* libaom-av1 uses "cpu-used" instead of "preset" for defining compression quality.
|
|
|
|
|
* This value is in a range from 0-8. 0 and 8 are extremes, but we will allow 8.
|
|
|
|
|
* Must check context->ffmpeg_preset again in case this encoder was selected due to the
|
|
|
|
|
* absence of another. */
|
|
|
|
|
switch (context->ffmpeg_preset) {
|
|
|
|
|
case FFM_PRESET_REALTIME:
|
|
|
|
|
ffmpeg_dict_set_int(opts, "cpu-used", 8);
|
|
|
|
|
break;
|
|
|
|
|
case FFM_PRESET_BEST:
|
|
|
|
|
ffmpeg_dict_set_int(opts, "cpu-used", 4);
|
|
|
|
|
break;
|
|
|
|
|
case FFM_PRESET_GOOD:
|
|
|
|
|
default:
|
|
|
|
|
ffmpeg_dict_set_int(opts, "cpu-used", 6);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* CRF related settings is similar to H264 for libaom-av1, so we will rely on those settings
|
|
|
|
|
* applied later. */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return codec;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-15 10:35:02 +01:00
|
|
|
static SwsContext *sws_create_context(
|
ffmpeg: optimize ffmpeg_postprocess
After doing regular movie frame decoding, there's a "postprocess" step for
each incoming frame, that does deinterlacing if needed, then YUV->RGB
conversion, then vertical image flip and additional interlace filtering if
needed. While this postprocess step is not the "heavy" part of movie
playback, it still takes 2-3ms per each 1080p resolution input frame that
is being played.
This PR does two things:
- Similar to #116008, uses multi-threaded `sws_scale` to do YUV->RGB
conversion.
- Reintroduces "do vertical flip while converting to RGB", where possible.
That was removed in 2ed73fc97e due to issues on arm64 platform, and
theory that negative strides passed to sws_scale is not an officially
supported usage.
My take on the last point: negative strides to sws_scale is a fine and
supported usage, just ffmpeg had a bug specifically on arm64 where they
were accidentally not respected. They fixed that for ffmpeg 6.0, and
backported it to all versions back to 3.4.13 -- you would not backport
something to 10 releases unless that was an actual bug fix!
I have tested the glitch_480p.mp4 that was originally attached to the
bug report #94237 back then, and it works fine both on x64 (Windows)
and arm64 (Mac).
Timings, ffmpeg_postprocess cost for a single 1920x1080 resolution movie
strip inside VSE:
- Windows/VS2022 Ryzen 5950X: 3.04ms -> 1.18ms
- Mac/clang15 M1 Max: 1.10ms -> 0.71ms
Pull Request: https://projects.blender.org/blender/blender/pulls/116309
2023-12-19 18:28:51 +01:00
|
|
|
int width, int height, int av_src_format, int av_dst_format, int sws_flags)
|
2023-12-15 12:35:59 +01:00
|
|
|
{
|
2023-12-15 19:29:57 +01:00
|
|
|
# if defined(FFMPEG_SWSCALE_THREADING)
|
2023-12-15 12:35:59 +01:00
|
|
|
/* sws_getContext does not allow passing flags that ask for multi-threaded
|
|
|
|
|
* scaling context, so do it the hard way. */
|
|
|
|
|
SwsContext *c = sws_alloc_context();
|
|
|
|
|
if (c == nullptr) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
av_opt_set_int(c, "srcw", width, 0);
|
|
|
|
|
av_opt_set_int(c, "srch", height, 0);
|
ffmpeg: optimize ffmpeg_postprocess
After doing regular movie frame decoding, there's a "postprocess" step for
each incoming frame, that does deinterlacing if needed, then YUV->RGB
conversion, then vertical image flip and additional interlace filtering if
needed. While this postprocess step is not the "heavy" part of movie
playback, it still takes 2-3ms per each 1080p resolution input frame that
is being played.
This PR does two things:
- Similar to #116008, uses multi-threaded `sws_scale` to do YUV->RGB
conversion.
- Reintroduces "do vertical flip while converting to RGB", where possible.
That was removed in 2ed73fc97e due to issues on arm64 platform, and
theory that negative strides passed to sws_scale is not an officially
supported usage.
My take on the last point: negative strides to sws_scale is a fine and
supported usage, just ffmpeg had a bug specifically on arm64 where they
were accidentally not respected. They fixed that for ffmpeg 6.0, and
backported it to all versions back to 3.4.13 -- you would not backport
something to 10 releases unless that was an actual bug fix!
I have tested the glitch_480p.mp4 that was originally attached to the
bug report #94237 back then, and it works fine both on x64 (Windows)
and arm64 (Mac).
Timings, ffmpeg_postprocess cost for a single 1920x1080 resolution movie
strip inside VSE:
- Windows/VS2022 Ryzen 5950X: 3.04ms -> 1.18ms
- Mac/clang15 M1 Max: 1.10ms -> 0.71ms
Pull Request: https://projects.blender.org/blender/blender/pulls/116309
2023-12-19 18:28:51 +01:00
|
|
|
av_opt_set_int(c, "src_format", av_src_format, 0);
|
2023-12-15 12:35:59 +01:00
|
|
|
av_opt_set_int(c, "dstw", width, 0);
|
|
|
|
|
av_opt_set_int(c, "dsth", height, 0);
|
ffmpeg: optimize ffmpeg_postprocess
After doing regular movie frame decoding, there's a "postprocess" step for
each incoming frame, that does deinterlacing if needed, then YUV->RGB
conversion, then vertical image flip and additional interlace filtering if
needed. While this postprocess step is not the "heavy" part of movie
playback, it still takes 2-3ms per each 1080p resolution input frame that
is being played.
This PR does two things:
- Similar to #116008, uses multi-threaded `sws_scale` to do YUV->RGB
conversion.
- Reintroduces "do vertical flip while converting to RGB", where possible.
That was removed in 2ed73fc97e due to issues on arm64 platform, and
theory that negative strides passed to sws_scale is not an officially
supported usage.
My take on the last point: negative strides to sws_scale is a fine and
supported usage, just ffmpeg had a bug specifically on arm64 where they
were accidentally not respected. They fixed that for ffmpeg 6.0, and
backported it to all versions back to 3.4.13 -- you would not backport
something to 10 releases unless that was an actual bug fix!
I have tested the glitch_480p.mp4 that was originally attached to the
bug report #94237 back then, and it works fine both on x64 (Windows)
and arm64 (Mac).
Timings, ffmpeg_postprocess cost for a single 1920x1080 resolution movie
strip inside VSE:
- Windows/VS2022 Ryzen 5950X: 3.04ms -> 1.18ms
- Mac/clang15 M1 Max: 1.10ms -> 0.71ms
Pull Request: https://projects.blender.org/blender/blender/pulls/116309
2023-12-19 18:28:51 +01:00
|
|
|
av_opt_set_int(c, "dst_format", av_dst_format, 0);
|
|
|
|
|
av_opt_set_int(c, "sws_flags", sws_flags, 0);
|
2023-12-15 12:35:59 +01:00
|
|
|
av_opt_set_int(c, "threads", BLI_system_thread_count(), 0);
|
|
|
|
|
|
|
|
|
|
if (sws_init_context(c, nullptr, nullptr) < 0) {
|
|
|
|
|
sws_freeContext(c);
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
2023-12-15 19:29:57 +01:00
|
|
|
# else
|
|
|
|
|
SwsContext *c = sws_getContext(width,
|
|
|
|
|
height,
|
ffmpeg: optimize ffmpeg_postprocess
After doing regular movie frame decoding, there's a "postprocess" step for
each incoming frame, that does deinterlacing if needed, then YUV->RGB
conversion, then vertical image flip and additional interlace filtering if
needed. While this postprocess step is not the "heavy" part of movie
playback, it still takes 2-3ms per each 1080p resolution input frame that
is being played.
This PR does two things:
- Similar to #116008, uses multi-threaded `sws_scale` to do YUV->RGB
conversion.
- Reintroduces "do vertical flip while converting to RGB", where possible.
That was removed in 2ed73fc97e due to issues on arm64 platform, and
theory that negative strides passed to sws_scale is not an officially
supported usage.
My take on the last point: negative strides to sws_scale is a fine and
supported usage, just ffmpeg had a bug specifically on arm64 where they
were accidentally not respected. They fixed that for ffmpeg 6.0, and
backported it to all versions back to 3.4.13 -- you would not backport
something to 10 releases unless that was an actual bug fix!
I have tested the glitch_480p.mp4 that was originally attached to the
bug report #94237 back then, and it works fine both on x64 (Windows)
and arm64 (Mac).
Timings, ffmpeg_postprocess cost for a single 1920x1080 resolution movie
strip inside VSE:
- Windows/VS2022 Ryzen 5950X: 3.04ms -> 1.18ms
- Mac/clang15 M1 Max: 1.10ms -> 0.71ms
Pull Request: https://projects.blender.org/blender/blender/pulls/116309
2023-12-19 18:28:51 +01:00
|
|
|
AVPixelFormat(av_src_format),
|
2023-12-15 19:29:57 +01:00
|
|
|
width,
|
|
|
|
|
height,
|
ffmpeg: optimize ffmpeg_postprocess
After doing regular movie frame decoding, there's a "postprocess" step for
each incoming frame, that does deinterlacing if needed, then YUV->RGB
conversion, then vertical image flip and additional interlace filtering if
needed. While this postprocess step is not the "heavy" part of movie
playback, it still takes 2-3ms per each 1080p resolution input frame that
is being played.
This PR does two things:
- Similar to #116008, uses multi-threaded `sws_scale` to do YUV->RGB
conversion.
- Reintroduces "do vertical flip while converting to RGB", where possible.
That was removed in 2ed73fc97e due to issues on arm64 platform, and
theory that negative strides passed to sws_scale is not an officially
supported usage.
My take on the last point: negative strides to sws_scale is a fine and
supported usage, just ffmpeg had a bug specifically on arm64 where they
were accidentally not respected. They fixed that for ffmpeg 6.0, and
backported it to all versions back to 3.4.13 -- you would not backport
something to 10 releases unless that was an actual bug fix!
I have tested the glitch_480p.mp4 that was originally attached to the
bug report #94237 back then, and it works fine both on x64 (Windows)
and arm64 (Mac).
Timings, ffmpeg_postprocess cost for a single 1920x1080 resolution movie
strip inside VSE:
- Windows/VS2022 Ryzen 5950X: 3.04ms -> 1.18ms
- Mac/clang15 M1 Max: 1.10ms -> 0.71ms
Pull Request: https://projects.blender.org/blender/blender/pulls/116309
2023-12-19 18:28:51 +01:00
|
|
|
AVPixelFormat(av_dst_format),
|
|
|
|
|
sws_flags,
|
2023-12-15 19:29:57 +01:00
|
|
|
nullptr,
|
|
|
|
|
nullptr,
|
|
|
|
|
nullptr);
|
|
|
|
|
# endif
|
2023-12-15 12:35:59 +01:00
|
|
|
|
|
|
|
|
return c;
|
|
|
|
|
}
|
2024-02-15 10:35:02 +01:00
|
|
|
|
|
|
|
|
static void init_swscale_cache_if_needed()
|
|
|
|
|
{
|
|
|
|
|
if (swscale_cache == nullptr) {
|
|
|
|
|
swscale_cache = new blender::Vector<SwscaleContext>();
|
|
|
|
|
swscale_cache_timestamp = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool remove_oldest_swscale_context()
|
|
|
|
|
{
|
|
|
|
|
int64_t oldest_index = -1;
|
|
|
|
|
int64_t oldest_time = 0;
|
|
|
|
|
for (int64_t index = 0; index < swscale_cache->size(); index++) {
|
|
|
|
|
SwscaleContext &ctx = (*swscale_cache)[index];
|
|
|
|
|
if (ctx.is_used) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
int64_t time = swscale_cache_timestamp - ctx.last_use_timestamp;
|
|
|
|
|
if (time > oldest_time) {
|
|
|
|
|
oldest_time = time;
|
|
|
|
|
oldest_index = index;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (oldest_index >= 0) {
|
|
|
|
|
SwscaleContext &ctx = (*swscale_cache)[oldest_index];
|
|
|
|
|
sws_freeContext(ctx.context);
|
|
|
|
|
swscale_cache->remove_and_reorder(oldest_index);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void maintain_swscale_cache_size()
|
|
|
|
|
{
|
|
|
|
|
while (swscale_cache->size() > swscale_cache_max_entries) {
|
|
|
|
|
if (!remove_oldest_swscale_context()) {
|
|
|
|
|
/* Could not remove anything (all contexts are actively used),
|
|
|
|
|
* stop trying. */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SwsContext *BKE_ffmpeg_sws_get_context(
|
|
|
|
|
int width, int height, int av_src_format, int av_dst_format, int sws_flags)
|
|
|
|
|
{
|
|
|
|
|
BLI_mutex_lock(&swscale_cache_lock);
|
|
|
|
|
|
|
|
|
|
init_swscale_cache_if_needed();
|
|
|
|
|
|
|
|
|
|
swscale_cache_timestamp++;
|
|
|
|
|
|
|
|
|
|
/* Search for unused context that has suitable parameters. */
|
|
|
|
|
SwsContext *ctx = nullptr;
|
|
|
|
|
for (SwscaleContext &c : *swscale_cache) {
|
|
|
|
|
if (!c.is_used && c.width == width && c.height == height && c.src_format == av_src_format &&
|
|
|
|
|
c.dst_format == av_dst_format && c.flags == sws_flags)
|
|
|
|
|
{
|
|
|
|
|
ctx = c.context;
|
|
|
|
|
/* Mark as used. */
|
|
|
|
|
c.is_used = true;
|
|
|
|
|
c.last_use_timestamp = swscale_cache_timestamp;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (ctx == nullptr) {
|
|
|
|
|
/* No free matching context in cache: create a new one. */
|
|
|
|
|
ctx = sws_create_context(width, height, av_src_format, av_dst_format, sws_flags);
|
|
|
|
|
SwscaleContext c;
|
|
|
|
|
c.width = width;
|
|
|
|
|
c.height = height;
|
|
|
|
|
c.src_format = AVPixelFormat(av_src_format);
|
|
|
|
|
c.dst_format = AVPixelFormat(av_dst_format);
|
|
|
|
|
c.flags = sws_flags;
|
|
|
|
|
c.context = ctx;
|
|
|
|
|
c.is_used = true;
|
|
|
|
|
c.last_use_timestamp = swscale_cache_timestamp;
|
|
|
|
|
swscale_cache->append(c);
|
|
|
|
|
|
|
|
|
|
maintain_swscale_cache_size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BLI_mutex_unlock(&swscale_cache_lock);
|
|
|
|
|
return ctx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BKE_ffmpeg_sws_release_context(SwsContext *ctx)
|
|
|
|
|
{
|
|
|
|
|
BLI_mutex_lock(&swscale_cache_lock);
|
|
|
|
|
init_swscale_cache_if_needed();
|
|
|
|
|
|
|
|
|
|
bool found = false;
|
|
|
|
|
for (SwscaleContext &c : *swscale_cache) {
|
|
|
|
|
if (c.context == ctx) {
|
|
|
|
|
BLI_assert_msg(c.is_used, "Releasing ffmpeg swscale context that is not in use");
|
|
|
|
|
c.is_used = false;
|
|
|
|
|
found = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
BLI_assert_msg(found, "Releasing ffmpeg swscale context that is not in cache");
|
2024-02-15 10:41:17 +01:00
|
|
|
UNUSED_VARS_NDEBUG(found);
|
2024-02-15 10:35:02 +01:00
|
|
|
maintain_swscale_cache_size();
|
|
|
|
|
|
|
|
|
|
BLI_mutex_unlock(&swscale_cache_lock);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BKE_ffmpeg_exit()
|
|
|
|
|
{
|
|
|
|
|
BLI_mutex_lock(&swscale_cache_lock);
|
|
|
|
|
if (swscale_cache != nullptr) {
|
|
|
|
|
for (SwscaleContext &c : *swscale_cache) {
|
|
|
|
|
sws_freeContext(c.context);
|
|
|
|
|
}
|
|
|
|
|
delete swscale_cache;
|
|
|
|
|
swscale_cache = nullptr;
|
|
|
|
|
}
|
|
|
|
|
BLI_mutex_unlock(&swscale_cache_lock);
|
|
|
|
|
}
|
|
|
|
|
|
ffmpeg: optimize ffmpeg_postprocess
After doing regular movie frame decoding, there's a "postprocess" step for
each incoming frame, that does deinterlacing if needed, then YUV->RGB
conversion, then vertical image flip and additional interlace filtering if
needed. While this postprocess step is not the "heavy" part of movie
playback, it still takes 2-3ms per each 1080p resolution input frame that
is being played.
This PR does two things:
- Similar to #116008, uses multi-threaded `sws_scale` to do YUV->RGB
conversion.
- Reintroduces "do vertical flip while converting to RGB", where possible.
That was removed in 2ed73fc97e due to issues on arm64 platform, and
theory that negative strides passed to sws_scale is not an officially
supported usage.
My take on the last point: negative strides to sws_scale is a fine and
supported usage, just ffmpeg had a bug specifically on arm64 where they
were accidentally not respected. They fixed that for ffmpeg 6.0, and
backported it to all versions back to 3.4.13 -- you would not backport
something to 10 releases unless that was an actual bug fix!
I have tested the glitch_480p.mp4 that was originally attached to the
bug report #94237 back then, and it works fine both on x64 (Windows)
and arm64 (Mac).
Timings, ffmpeg_postprocess cost for a single 1920x1080 resolution movie
strip inside VSE:
- Windows/VS2022 Ryzen 5950X: 3.04ms -> 1.18ms
- Mac/clang15 M1 Max: 1.10ms -> 0.71ms
Pull Request: https://projects.blender.org/blender/blender/pulls/116309
2023-12-19 18:28:51 +01:00
|
|
|
void BKE_ffmpeg_sws_scale_frame(SwsContext *ctx, AVFrame *dst, const AVFrame *src)
|
|
|
|
|
{
|
|
|
|
|
# if defined(FFMPEG_SWSCALE_THREADING)
|
|
|
|
|
sws_scale_frame(ctx, dst, src);
|
|
|
|
|
# else
|
|
|
|
|
sws_scale(ctx, src->data, src->linesize, 0, src->height, dst->data, dst->linesize);
|
|
|
|
|
# endif
|
|
|
|
|
}
|
2023-12-15 12:35:59 +01:00
|
|
|
|
2006-02-05 19:14:46 +00:00
|
|
|
/* prepare a video stream for the output file */
|
|
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
static AVStream *alloc_video_stream(FFMpegContext *context,
|
|
|
|
|
RenderData *rd,
|
2023-11-30 06:03:18 +01:00
|
|
|
AVCodecID codec_id,
|
2015-04-06 10:40:12 -03:00
|
|
|
AVFormatContext *of,
|
2012-08-26 11:01:14 +00:00
|
|
|
int rectx,
|
|
|
|
|
int recty,
|
|
|
|
|
char *error,
|
|
|
|
|
int error_size)
|
2006-02-05 19:14:46 +00:00
|
|
|
{
|
2012-05-12 16:11:34 +00:00
|
|
|
AVStream *st;
|
2022-02-18 18:20:06 +01:00
|
|
|
const AVCodec *codec;
|
2023-11-30 16:42:39 +11:00
|
|
|
AVDictionary *opts = nullptr;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-08-26 11:01:14 +00:00
|
|
|
error[0] = '\0';
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-11-30 16:42:39 +11:00
|
|
|
st = avformat_new_stream(of, nullptr);
|
2019-04-22 09:39:35 +10:00
|
|
|
if (!st) {
|
2023-11-30 16:42:39 +11:00
|
|
|
return nullptr;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2013-01-12 12:51:10 +00:00
|
|
|
st->id = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2006-02-05 19:14:46 +00:00
|
|
|
/* Set up the codec context */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Video rendering: FFMpeg AV1 codec encoding support
Previously, the Blender video renderer did not have support for
encoding video to AV1 (not to be confused with the container AVI).
The proposed solution is to leverage the existing FFMpeg renderer
to encode to AV1.
Note that avcodec_find_encoder(AV_CODEC_ID_AV1) usually returns
"libaom-av1" which is the "reference implementation" for AV1 encoding
(the default for FFMpeg, and is slow). "libsvtav1" is faster and
preferred so there is extra handling when fetching the AV1 codec for
encoding such that "libsvtav1" is used when possible.
This commit should only affect the options available for video
rendering, which includes the additional AV1 codec to choose from, and
setting "-crf".
Also note that the current release of FFMpeg for ArchLinux does not
support "-crf" for "libsvtav1", but the equivalent option "-qp" is
supported and used as a fallback when "libsvtav1" is used (as
mentioned here: https://trac.ffmpeg.org/wiki/Encode/AV1#SVT-AV1 ).
(Actually, both "-crf" and "-qp" is specified with the same value in
the code. When a release of FFMpeg obtains support for "-crf" for
"libsvtav1" is released, the code shouldn't be needed to change.)
The usage of the AV1 codec should be very similar to the usage of the
H264 codec, but is limited to the "mp4" and "mkv" containers.
This patch pertains to the "VFX & Video" module, as its main purpose
is to supplement the Video Sequencer tool with the additional AV1
codec for encoded video output.
Differential Revision: https://developer.blender.org/D14920
Reviewed By: sergey , ISS, zeddb
2022-10-21 20:10:17 -06:00
|
|
|
if (codec_id == AV_CODEC_ID_AV1) {
|
|
|
|
|
/* Use get_av1_encoder() to get the ideal (hopefully) encoder for AV1 based
|
|
|
|
|
* on given parameters, and also set up opts. */
|
|
|
|
|
codec = get_av1_encoder(context, rd, &opts, rectx, recty);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
codec = avcodec_find_encoder(codec_id);
|
|
|
|
|
}
|
2021-05-31 11:25:12 +02:00
|
|
|
if (!codec) {
|
|
|
|
|
fprintf(stderr, "Couldn't find valid video codec\n");
|
2023-11-30 16:42:39 +11:00
|
|
|
context->video_codec = nullptr;
|
|
|
|
|
return nullptr;
|
2021-05-31 11:25:12 +02:00
|
|
|
}
|
|
|
|
|
|
2022-02-18 18:20:06 +01:00
|
|
|
context->video_codec = avcodec_alloc_context3(codec);
|
|
|
|
|
AVCodecContext *c = context->video_codec;
|
2021-05-31 11:25:12 +02:00
|
|
|
|
2006-02-05 19:14:46 +00:00
|
|
|
/* Get some values from the current render settings */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2006-02-05 19:14:46 +00:00
|
|
|
c->width = rectx;
|
|
|
|
|
c->height = recty;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
if (context->ffmpeg_type == FFMPEG_DV && rd->frs_sec != 25) {
|
2021-05-31 11:25:12 +02:00
|
|
|
/* FIXME: Really bad hack (tm) for NTSC support */
|
2006-02-06 19:27:24 +00:00
|
|
|
c->time_base.den = 2997;
|
|
|
|
|
c->time_base.num = 100;
|
2012-03-24 06:18:31 +00:00
|
|
|
}
|
2023-11-30 16:42:39 +11:00
|
|
|
else if (float(int(rd->frs_sec_base)) == rd->frs_sec_base) {
|
2009-01-04 14:14:06 +00:00
|
|
|
c->time_base.den = rd->frs_sec;
|
2023-11-30 16:42:39 +11:00
|
|
|
c->time_base.num = int(rd->frs_sec_base);
|
2012-03-24 06:18:31 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2021-05-31 11:25:12 +02:00
|
|
|
c->time_base = calc_time_base(rd->frs_sec, rd->frs_sec_base, codec_id);
|
|
|
|
|
}
|
2019-06-11 15:51:39 +02:00
|
|
|
|
2021-06-01 12:49:18 +10:00
|
|
|
/* As per the time-base documentation here:
|
2021-05-31 11:25:12 +02:00
|
|
|
* https://www.ffmpeg.org/ffmpeg-codecs.html#Codec-Options
|
|
|
|
|
* We want to set the time base to (1 / fps) for fixed frame rate video.
|
2021-06-01 12:49:18 +10:00
|
|
|
* If it is not possible, we want to set the time-base numbers to something as
|
2021-05-31 11:25:12 +02:00
|
|
|
* small as possible.
|
|
|
|
|
*/
|
|
|
|
|
if (c->time_base.num != 1) {
|
|
|
|
|
AVRational new_time_base;
|
|
|
|
|
if (av_reduce(
|
2024-01-02 18:12:54 +01:00
|
|
|
&new_time_base.num, &new_time_base.den, c->time_base.num, c->time_base.den, INT_MAX))
|
|
|
|
|
{
|
2021-05-31 11:25:12 +02:00
|
|
|
/* Exact reduction was possible. Use the new value. */
|
|
|
|
|
c->time_base = new_time_base;
|
|
|
|
|
}
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-19 07:17:13 +02:00
|
|
|
st->time_base = c->time_base;
|
|
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
c->gop_size = context->ffmpeg_gop_size;
|
FFmpeg interface improvements
This patch changes a couple of things in the video output encoding.
{F362527}
- Clearer separation between container and codec. No more "format", as this is
too ambiguous. As a result, codecs were removed from the container list.
- Added FFmpeg speed presets, so the user can choosen from the range "Very
slow" to "Ultra fast". By default no preset is used.
- Added Constant Rate Factor (CRF) mode, which allows changing the bit-rate
depending on the desired quality and the input. This generally produces the
best quality videos, at the expense of not knowing the exact bit-rate and
file size.
- Added optional maximum of non-B-frames between B-frames (`max_b_frames`).
- Presets were adjusted for these changes, and new presets added. One of the
new presets is [recommended](https://trac.ffmpeg.org/wiki/Encode/VFX#H.264)
for reviewing videos, as it allows players to scrub through it easily. Might
be nice in weeklies. This preset also requires control over the
`max_b_frames` setting.
GUI-only changes:
- Renamed "MPEG" in the output file format menu with "FFmpeg", as this is more
accurate. After all, FFmpeg is used when this option is chosen, which can
also output non-MPEG files.
- Certain parts of the GUI are disabled when not in use:
- bit rate options are not used when a constant rate factor is given.
- audio bitrate & volume are not used when no audio is exported.
Note that I did not touch `BKE_ffmpeg_preset_set()`. There are currently two
preset systems for FFmpeg (`BKE_ffmpeg_preset_set()` and the Python preset
system). Before we do more work on `BKE_ffmpeg_preset_set()`, I think it's a
good idea to determine whether we want to keep it at all.
After this patch has been accepted, I'd be happy to go through the code and
remove any then-obsolete bits, such as the handling of "XVID" as a container
format.
Reviewers: sergey, mont29, brecht
Subscribers: mpan3, Blendify, brecht, fsiddi
Tags: #bf_blender
Differential Revision: https://developer.blender.org/D2242
2016-09-21 15:01:51 +02:00
|
|
|
c->max_b_frames = context->ffmpeg_max_b_frames;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-05-20 14:08:48 +02:00
|
|
|
if (context->ffmpeg_type == FFMPEG_WEBM && context->ffmpeg_crf == 0) {
|
|
|
|
|
ffmpeg_dict_set_int(&opts, "lossless", 1);
|
|
|
|
|
}
|
|
|
|
|
else if (context->ffmpeg_crf >= 0) {
|
2021-05-31 11:25:12 +02:00
|
|
|
/* As per https://trac.ffmpeg.org/wiki/Encode/VP9 we must set the bit rate to zero when
|
2023-12-07 12:15:45 +11:00
|
|
|
* encoding with VP9 in CRF mode.
|
2021-05-31 11:25:12 +02:00
|
|
|
* Set this to always be zero for other codecs as well.
|
2023-12-07 12:15:45 +11:00
|
|
|
* We don't care about bit rate in CRF mode. */
|
2021-05-31 11:25:12 +02:00
|
|
|
c->bit_rate = 0;
|
FFmpeg interface improvements
This patch changes a couple of things in the video output encoding.
{F362527}
- Clearer separation between container and codec. No more "format", as this is
too ambiguous. As a result, codecs were removed from the container list.
- Added FFmpeg speed presets, so the user can choosen from the range "Very
slow" to "Ultra fast". By default no preset is used.
- Added Constant Rate Factor (CRF) mode, which allows changing the bit-rate
depending on the desired quality and the input. This generally produces the
best quality videos, at the expense of not knowing the exact bit-rate and
file size.
- Added optional maximum of non-B-frames between B-frames (`max_b_frames`).
- Presets were adjusted for these changes, and new presets added. One of the
new presets is [recommended](https://trac.ffmpeg.org/wiki/Encode/VFX#H.264)
for reviewing videos, as it allows players to scrub through it easily. Might
be nice in weeklies. This preset also requires control over the
`max_b_frames` setting.
GUI-only changes:
- Renamed "MPEG" in the output file format menu with "FFmpeg", as this is more
accurate. After all, FFmpeg is used when this option is chosen, which can
also output non-MPEG files.
- Certain parts of the GUI are disabled when not in use:
- bit rate options are not used when a constant rate factor is given.
- audio bitrate & volume are not used when no audio is exported.
Note that I did not touch `BKE_ffmpeg_preset_set()`. There are currently two
preset systems for FFmpeg (`BKE_ffmpeg_preset_set()` and the Python preset
system). Before we do more work on `BKE_ffmpeg_preset_set()`, I think it's a
good idea to determine whether we want to keep it at all.
After this patch has been accepted, I'd be happy to go through the code and
remove any then-obsolete bits, such as the handling of "XVID" as a container
format.
Reviewers: sergey, mont29, brecht
Subscribers: mpan3, Blendify, brecht, fsiddi
Tags: #bf_blender
Differential Revision: https://developer.blender.org/D2242
2016-09-21 15:01:51 +02:00
|
|
|
ffmpeg_dict_set_int(&opts, "crf", context->ffmpeg_crf);
|
2017-03-13 04:25:21 +11:00
|
|
|
}
|
|
|
|
|
else {
|
FFmpeg interface improvements
This patch changes a couple of things in the video output encoding.
{F362527}
- Clearer separation between container and codec. No more "format", as this is
too ambiguous. As a result, codecs were removed from the container list.
- Added FFmpeg speed presets, so the user can choosen from the range "Very
slow" to "Ultra fast". By default no preset is used.
- Added Constant Rate Factor (CRF) mode, which allows changing the bit-rate
depending on the desired quality and the input. This generally produces the
best quality videos, at the expense of not knowing the exact bit-rate and
file size.
- Added optional maximum of non-B-frames between B-frames (`max_b_frames`).
- Presets were adjusted for these changes, and new presets added. One of the
new presets is [recommended](https://trac.ffmpeg.org/wiki/Encode/VFX#H.264)
for reviewing videos, as it allows players to scrub through it easily. Might
be nice in weeklies. This preset also requires control over the
`max_b_frames` setting.
GUI-only changes:
- Renamed "MPEG" in the output file format menu with "FFmpeg", as this is more
accurate. After all, FFmpeg is used when this option is chosen, which can
also output non-MPEG files.
- Certain parts of the GUI are disabled when not in use:
- bit rate options are not used when a constant rate factor is given.
- audio bitrate & volume are not used when no audio is exported.
Note that I did not touch `BKE_ffmpeg_preset_set()`. There are currently two
preset systems for FFmpeg (`BKE_ffmpeg_preset_set()` and the Python preset
system). Before we do more work on `BKE_ffmpeg_preset_set()`, I think it's a
good idea to determine whether we want to keep it at all.
After this patch has been accepted, I'd be happy to go through the code and
remove any then-obsolete bits, such as the handling of "XVID" as a container
format.
Reviewers: sergey, mont29, brecht
Subscribers: mpan3, Blendify, brecht, fsiddi
Tags: #bf_blender
Differential Revision: https://developer.blender.org/D2242
2016-09-21 15:01:51 +02:00
|
|
|
c->bit_rate = context->ffmpeg_video_bitrate * 1000;
|
|
|
|
|
c->rc_max_rate = rd->ffcodecdata.rc_max_rate * 1000;
|
|
|
|
|
c->rc_min_rate = rd->ffcodecdata.rc_min_rate * 1000;
|
|
|
|
|
c->rc_buffer_size = rd->ffcodecdata.rc_buffer_size * 1024;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
FFmpeg interface improvements
This patch changes a couple of things in the video output encoding.
{F362527}
- Clearer separation between container and codec. No more "format", as this is
too ambiguous. As a result, codecs were removed from the container list.
- Added FFmpeg speed presets, so the user can choosen from the range "Very
slow" to "Ultra fast". By default no preset is used.
- Added Constant Rate Factor (CRF) mode, which allows changing the bit-rate
depending on the desired quality and the input. This generally produces the
best quality videos, at the expense of not knowing the exact bit-rate and
file size.
- Added optional maximum of non-B-frames between B-frames (`max_b_frames`).
- Presets were adjusted for these changes, and new presets added. One of the
new presets is [recommended](https://trac.ffmpeg.org/wiki/Encode/VFX#H.264)
for reviewing videos, as it allows players to scrub through it easily. Might
be nice in weeklies. This preset also requires control over the
`max_b_frames` setting.
GUI-only changes:
- Renamed "MPEG" in the output file format menu with "FFmpeg", as this is more
accurate. After all, FFmpeg is used when this option is chosen, which can
also output non-MPEG files.
- Certain parts of the GUI are disabled when not in use:
- bit rate options are not used when a constant rate factor is given.
- audio bitrate & volume are not used when no audio is exported.
Note that I did not touch `BKE_ffmpeg_preset_set()`. There are currently two
preset systems for FFmpeg (`BKE_ffmpeg_preset_set()` and the Python preset
system). Before we do more work on `BKE_ffmpeg_preset_set()`, I think it's a
good idea to determine whether we want to keep it at all.
After this patch has been accepted, I'd be happy to go through the code and
remove any then-obsolete bits, such as the handling of "XVID" as a container
format.
Reviewers: sergey, mont29, brecht
Subscribers: mpan3, Blendify, brecht, fsiddi
Tags: #bf_blender
Differential Revision: https://developer.blender.org/D2242
2016-09-21 15:01:51 +02:00
|
|
|
if (context->ffmpeg_preset) {
|
2023-12-07 12:15:45 +11:00
|
|
|
/* 'preset' is used by h.264, 'deadline' is used by WEBM/VP9. I'm not
|
2018-04-09 15:27:11 +02:00
|
|
|
* setting those properties conditionally based on the video codec,
|
|
|
|
|
* as the FFmpeg encoder simply ignores unknown settings anyway. */
|
2023-12-07 12:15:45 +11:00
|
|
|
char const *preset_name = nullptr; /* Used by h.264. */
|
|
|
|
|
char const *deadline_name = nullptr; /* Used by WEBM/VP9. */
|
2017-03-13 04:25:21 +11:00
|
|
|
switch (context->ffmpeg_preset) {
|
2018-04-09 15:27:11 +02:00
|
|
|
case FFM_PRESET_GOOD:
|
|
|
|
|
preset_name = "medium";
|
|
|
|
|
deadline_name = "good";
|
|
|
|
|
break;
|
|
|
|
|
case FFM_PRESET_BEST:
|
|
|
|
|
preset_name = "slower";
|
|
|
|
|
deadline_name = "best";
|
|
|
|
|
break;
|
|
|
|
|
case FFM_PRESET_REALTIME:
|
|
|
|
|
preset_name = "superfast";
|
|
|
|
|
deadline_name = "realtime";
|
|
|
|
|
break;
|
FFmpeg interface improvements
This patch changes a couple of things in the video output encoding.
{F362527}
- Clearer separation between container and codec. No more "format", as this is
too ambiguous. As a result, codecs were removed from the container list.
- Added FFmpeg speed presets, so the user can choosen from the range "Very
slow" to "Ultra fast". By default no preset is used.
- Added Constant Rate Factor (CRF) mode, which allows changing the bit-rate
depending on the desired quality and the input. This generally produces the
best quality videos, at the expense of not knowing the exact bit-rate and
file size.
- Added optional maximum of non-B-frames between B-frames (`max_b_frames`).
- Presets were adjusted for these changes, and new presets added. One of the
new presets is [recommended](https://trac.ffmpeg.org/wiki/Encode/VFX#H.264)
for reviewing videos, as it allows players to scrub through it easily. Might
be nice in weeklies. This preset also requires control over the
`max_b_frames` setting.
GUI-only changes:
- Renamed "MPEG" in the output file format menu with "FFmpeg", as this is more
accurate. After all, FFmpeg is used when this option is chosen, which can
also output non-MPEG files.
- Certain parts of the GUI are disabled when not in use:
- bit rate options are not used when a constant rate factor is given.
- audio bitrate & volume are not used when no audio is exported.
Note that I did not touch `BKE_ffmpeg_preset_set()`. There are currently two
preset systems for FFmpeg (`BKE_ffmpeg_preset_set()` and the Python preset
system). Before we do more work on `BKE_ffmpeg_preset_set()`, I think it's a
good idea to determine whether we want to keep it at all.
After this patch has been accepted, I'd be happy to go through the code and
remove any then-obsolete bits, such as the handling of "XVID" as a container
format.
Reviewers: sergey, mont29, brecht
Subscribers: mpan3, Blendify, brecht, fsiddi
Tags: #bf_blender
Differential Revision: https://developer.blender.org/D2242
2016-09-21 15:01:51 +02:00
|
|
|
default:
|
|
|
|
|
printf("Unknown preset number %i, ignoring.\n", context->ffmpeg_preset);
|
|
|
|
|
}
|
Video rendering: FFMpeg AV1 codec encoding support
Previously, the Blender video renderer did not have support for
encoding video to AV1 (not to be confused with the container AVI).
The proposed solution is to leverage the existing FFMpeg renderer
to encode to AV1.
Note that avcodec_find_encoder(AV_CODEC_ID_AV1) usually returns
"libaom-av1" which is the "reference implementation" for AV1 encoding
(the default for FFMpeg, and is slow). "libsvtav1" is faster and
preferred so there is extra handling when fetching the AV1 codec for
encoding such that "libsvtav1" is used when possible.
This commit should only affect the options available for video
rendering, which includes the additional AV1 codec to choose from, and
setting "-crf".
Also note that the current release of FFMpeg for ArchLinux does not
support "-crf" for "libsvtav1", but the equivalent option "-qp" is
supported and used as a fallback when "libsvtav1" is used (as
mentioned here: https://trac.ffmpeg.org/wiki/Encode/AV1#SVT-AV1 ).
(Actually, both "-crf" and "-qp" is specified with the same value in
the code. When a release of FFMpeg obtains support for "-crf" for
"libsvtav1" is released, the code shouldn't be needed to change.)
The usage of the AV1 codec should be very similar to the usage of the
H264 codec, but is limited to the "mp4" and "mkv" containers.
This patch pertains to the "VFX & Video" module, as its main purpose
is to supplement the Video Sequencer tool with the additional AV1
codec for encoded video output.
Differential Revision: https://developer.blender.org/D14920
Reviewed By: sergey , ISS, zeddb
2022-10-21 20:10:17 -06:00
|
|
|
/* "codec_id != AV_CODEC_ID_AV1" is required due to "preset" already being set by an AV1 codec.
|
|
|
|
|
*/
|
2023-12-17 16:04:44 +11:00
|
|
|
if (preset_name != nullptr && codec_id != AV_CODEC_ID_AV1) {
|
FFmpeg interface improvements
This patch changes a couple of things in the video output encoding.
{F362527}
- Clearer separation between container and codec. No more "format", as this is
too ambiguous. As a result, codecs were removed from the container list.
- Added FFmpeg speed presets, so the user can choosen from the range "Very
slow" to "Ultra fast". By default no preset is used.
- Added Constant Rate Factor (CRF) mode, which allows changing the bit-rate
depending on the desired quality and the input. This generally produces the
best quality videos, at the expense of not knowing the exact bit-rate and
file size.
- Added optional maximum of non-B-frames between B-frames (`max_b_frames`).
- Presets were adjusted for these changes, and new presets added. One of the
new presets is [recommended](https://trac.ffmpeg.org/wiki/Encode/VFX#H.264)
for reviewing videos, as it allows players to scrub through it easily. Might
be nice in weeklies. This preset also requires control over the
`max_b_frames` setting.
GUI-only changes:
- Renamed "MPEG" in the output file format menu with "FFmpeg", as this is more
accurate. After all, FFmpeg is used when this option is chosen, which can
also output non-MPEG files.
- Certain parts of the GUI are disabled when not in use:
- bit rate options are not used when a constant rate factor is given.
- audio bitrate & volume are not used when no audio is exported.
Note that I did not touch `BKE_ffmpeg_preset_set()`. There are currently two
preset systems for FFmpeg (`BKE_ffmpeg_preset_set()` and the Python preset
system). Before we do more work on `BKE_ffmpeg_preset_set()`, I think it's a
good idea to determine whether we want to keep it at all.
After this patch has been accepted, I'd be happy to go through the code and
remove any then-obsolete bits, such as the handling of "XVID" as a container
format.
Reviewers: sergey, mont29, brecht
Subscribers: mpan3, Blendify, brecht, fsiddi
Tags: #bf_blender
Differential Revision: https://developer.blender.org/D2242
2016-09-21 15:01:51 +02:00
|
|
|
av_dict_set(&opts, "preset", preset_name, 0);
|
|
|
|
|
}
|
2023-11-30 16:42:39 +11:00
|
|
|
if (deadline_name != nullptr) {
|
2018-04-09 15:27:11 +02:00
|
|
|
av_dict_set(&opts, "deadline", deadline_name, 0);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-04-09 15:27:11 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2006-02-05 19:14:46 +00:00
|
|
|
/* Be sure to use the correct pixel format(e.g. RGB, YUV) */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2006-02-05 19:14:46 +00:00
|
|
|
if (codec->pix_fmts) {
|
|
|
|
|
c->pix_fmt = codec->pix_fmts[0];
|
2012-03-24 06:18:31 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2006-02-05 19:14:46 +00:00
|
|
|
/* makes HuffYUV happy ... */
|
2016-02-16 12:32:42 +01:00
|
|
|
c->pix_fmt = AV_PIX_FMT_YUV422P;
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
if (context->ffmpeg_type == FFMPEG_XVID) {
|
2023-12-07 12:15:45 +11:00
|
|
|
/* Alas! */
|
2016-02-16 12:32:42 +01:00
|
|
|
c->pix_fmt = AV_PIX_FMT_YUV420P;
|
2012-05-12 16:11:34 +00:00
|
|
|
c->codec_tag = (('D' << 24) + ('I' << 16) + ('V' << 8) + 'X');
|
2006-06-09 19:48:50 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-07-07 22:51:57 +00:00
|
|
|
/* Keep lossless encodes in the RGB domain. */
|
2014-01-16 15:40:37 +01:00
|
|
|
if (codec_id == AV_CODEC_ID_HUFFYUV) {
|
2014-12-24 18:54:38 +05:00
|
|
|
if (rd->im_format.planes == R_IMF_PLANES_RGBA) {
|
2016-02-16 12:32:42 +01:00
|
|
|
c->pix_fmt = AV_PIX_FMT_BGRA;
|
2014-12-24 18:54:38 +05:00
|
|
|
}
|
|
|
|
|
else {
|
2016-02-16 12:32:42 +01:00
|
|
|
c->pix_fmt = AV_PIX_FMT_RGB32;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2014-12-24 18:54:38 +05:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-02-18 18:20:06 +01:00
|
|
|
if (codec_id == AV_CODEC_ID_DNXHD) {
|
|
|
|
|
if (rd->ffcodecdata.flags & FFMPEG_LOSSLESS_OUTPUT) {
|
|
|
|
|
/* Set the block decision algorithm to be of the highest quality ("rd" == 2). */
|
|
|
|
|
c->mb_decision = 2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-16 15:40:37 +01:00
|
|
|
if (codec_id == AV_CODEC_ID_FFV1) {
|
2016-02-16 12:32:42 +01:00
|
|
|
c->pix_fmt = AV_PIX_FMT_RGB32;
|
2012-02-24 09:49:44 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-16 15:40:37 +01:00
|
|
|
if (codec_id == AV_CODEC_ID_QTRLE) {
|
2019-08-01 13:01:53 +02:00
|
|
|
if (rd->im_format.planes == R_IMF_PLANES_RGBA) {
|
|
|
|
|
c->pix_fmt = AV_PIX_FMT_ARGB;
|
|
|
|
|
}
|
2012-02-07 17:11:56 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-02-01 00:00:29 +01:00
|
|
|
if (codec_id == AV_CODEC_ID_VP9 && rd->im_format.planes == R_IMF_PLANES_RGBA) {
|
|
|
|
|
c->pix_fmt = AV_PIX_FMT_YUVA420P;
|
2019-07-31 11:18:55 +02:00
|
|
|
}
|
2022-03-09 09:35:37 +11:00
|
|
|
else if (ELEM(codec_id, AV_CODEC_ID_H264, AV_CODEC_ID_VP9) && (context->ffmpeg_crf == 0)) {
|
2022-02-01 00:00:29 +01:00
|
|
|
/* Use 4:4:4 instead of 4:2:0 pixel format for lossless rendering. */
|
2021-06-02 21:24:09 +02:00
|
|
|
c->pix_fmt = AV_PIX_FMT_YUV444P;
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-16 15:40:37 +01:00
|
|
|
if (codec_id == AV_CODEC_ID_PNG) {
|
2013-03-12 16:09:23 +00:00
|
|
|
if (rd->im_format.planes == R_IMF_PLANES_RGBA) {
|
2016-02-16 12:32:42 +01:00
|
|
|
c->pix_fmt = AV_PIX_FMT_RGBA;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2013-03-12 16:09:23 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-08-05 16:48:29 +10:00
|
|
|
if (of->oformat->flags & AVFMT_GLOBALHEADER) {
|
2012-08-26 11:01:14 +00:00
|
|
|
PRINT("Using global header\n");
|
2021-05-07 17:10:03 +02:00
|
|
|
c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2008-05-11 20:40:55 +00:00
|
|
|
/* xasp & yasp got float lately... */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-11-30 16:42:39 +11:00
|
|
|
st->sample_aspect_ratio = c->sample_aspect_ratio = av_d2q((double(rd->xasp) / double(rd->yasp)),
|
2012-08-26 11:01:18 +00:00
|
|
|
255);
|
2017-09-19 11:30:37 +05:00
|
|
|
st->avg_frame_rate = av_inv_q(c->time_base);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-03-02 15:12:35 +01:00
|
|
|
if (codec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
|
FFmpeg: improve threading settings
Generalize threading settings in proxy building and use them for encoding
and decoding in general. Check codec capabilities, prefer FF_THREAD_FRAME
threading over FF_THREAD_SLICE and automatic thread count over setting it
explicitly.
ffmpeg-codecs man page suggests that threads option is global and used by
codecs, that supports this option. Form some tests I have done, it seems that
`av_dict_set_int(&codec_opts, "threads", BLI_system_thread_count(), 0)`
has same effect as
```
pCodecCtx->thread_count = BLI_system_thread_count();
pCodecCtx->thread_type = FF_THREAD_FRAME;
```
Looking at `ff_frame_thread_encoder_init()` code, these cases are not
equivalent. It is probably safer to leave threading setup on libavcodec than
setting up each codec threading individually.
From what I have read all over the internet, frame multithreading should be
faster than slice multithreading. Slice multithreading is mainly used for low
latency streaming.
When running Blender with --debug-ffmpeg it complains about
`pCodecCtx->thread_count = BLI_system_thread_count()` that using thread count
above 16 is not recommended. Using too many threads can negatively affect image
quality, but I am not sure if this is the case for decoding as well - see
https://streaminglearningcenter.com/blogs/ffmpeg-command-threads-how-it-affects-quality-and-performance.html
This is fine for proxies but may be undesirable for final renders.
Number of threads is limited by image size, because of size of motion vectors,
so if it is possible let libavcodec determine optimal thread count.
Performance difference:
Proxy building: None
Playback speed: 2x better on 1920x1080 sample h264 file
Scrubbing: Hard to quantify, but it's much more responsive
Rendering speed: None on 1920x1080 sample h264 file, there is improvement with codecs that do support FF_THREAD_FRAME for encoding like MPNG
Reviewed By: sergey
Differential Revision: https://developer.blender.org/D10791
2021-03-26 12:41:13 +01:00
|
|
|
c->thread_count = 0;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
c->thread_count = BLI_system_thread_count();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) {
|
|
|
|
|
c->thread_type = FF_THREAD_FRAME;
|
|
|
|
|
}
|
|
|
|
|
else if (codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) {
|
|
|
|
|
c->thread_type = FF_THREAD_SLICE;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-31 11:25:12 +02:00
|
|
|
int ret = avcodec_open2(c, codec, &opts);
|
|
|
|
|
|
|
|
|
|
if (ret < 0) {
|
2023-11-30 06:03:18 +01:00
|
|
|
char error_str[AV_ERROR_MAX_STRING_SIZE];
|
|
|
|
|
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
|
|
|
|
fprintf(stderr, "Couldn't initialize video codec: %s\n", error_str);
|
2012-08-26 11:01:14 +00:00
|
|
|
BLI_strncpy(error, IMB_ffmpeg_last_error(), error_size);
|
2014-02-17 20:50:42 +06:00
|
|
|
av_dict_free(&opts);
|
2021-05-07 17:10:03 +02:00
|
|
|
avcodec_free_context(&c);
|
2023-11-30 16:42:39 +11:00
|
|
|
context->video_codec = nullptr;
|
|
|
|
|
return nullptr;
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
2014-02-17 20:50:42 +06:00
|
|
|
av_dict_free(&opts);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-12-07 12:15:45 +11:00
|
|
|
/* FFMPEG expects its data in the output pixel format. */
|
2015-04-06 10:40:12 -03:00
|
|
|
context->current_frame = alloc_picture(c->pix_fmt, c->width, c->height);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-08-01 13:01:53 +02:00
|
|
|
if (c->pix_fmt == AV_PIX_FMT_RGBA) {
|
|
|
|
|
/* Output pixel format is the same we use internally, no conversion necessary. */
|
2023-11-30 16:42:39 +11:00
|
|
|
context->img_convert_frame = nullptr;
|
|
|
|
|
context->img_convert_ctx = nullptr;
|
2019-08-01 13:01:53 +02:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Output pixel format is different, allocate frame for conversion. */
|
|
|
|
|
context->img_convert_frame = alloc_picture(AV_PIX_FMT_RGBA, c->width, c->height);
|
ffmpeg: optimize ffmpeg_postprocess
After doing regular movie frame decoding, there's a "postprocess" step for
each incoming frame, that does deinterlacing if needed, then YUV->RGB
conversion, then vertical image flip and additional interlace filtering if
needed. While this postprocess step is not the "heavy" part of movie
playback, it still takes 2-3ms per each 1080p resolution input frame that
is being played.
This PR does two things:
- Similar to #116008, uses multi-threaded `sws_scale` to do YUV->RGB
conversion.
- Reintroduces "do vertical flip while converting to RGB", where possible.
That was removed in 2ed73fc97e due to issues on arm64 platform, and
theory that negative strides passed to sws_scale is not an officially
supported usage.
My take on the last point: negative strides to sws_scale is a fine and
supported usage, just ffmpeg had a bug specifically on arm64 where they
were accidentally not respected. They fixed that for ffmpeg 6.0, and
backported it to all versions back to 3.4.13 -- you would not backport
something to 10 releases unless that was an actual bug fix!
I have tested the glitch_480p.mp4 that was originally attached to the
bug report #94237 back then, and it works fine both on x64 (Windows)
and arm64 (Mac).
Timings, ffmpeg_postprocess cost for a single 1920x1080 resolution movie
strip inside VSE:
- Windows/VS2022 Ryzen 5950X: 3.04ms -> 1.18ms
- Mac/clang15 M1 Max: 1.10ms -> 0.71ms
Pull Request: https://projects.blender.org/blender/blender/pulls/116309
2023-12-19 18:28:51 +01:00
|
|
|
context->img_convert_ctx = BKE_ffmpeg_sws_get_context(
|
|
|
|
|
c->width, c->height, AV_PIX_FMT_RGBA, c->pix_fmt, SWS_BICUBIC);
|
2019-08-01 13:01:53 +02:00
|
|
|
}
|
|
|
|
|
|
2021-05-07 17:10:03 +02:00
|
|
|
avcodec_parameters_from_context(st->codecpar, c);
|
|
|
|
|
|
2021-12-14 01:16:24 +01:00
|
|
|
context->video_time = 0.0f;
|
|
|
|
|
|
2006-02-05 19:14:46 +00:00
|
|
|
return st;
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
static AVStream *alloc_audio_stream(FFMpegContext *context,
|
|
|
|
|
RenderData *rd,
|
2023-11-30 06:03:18 +01:00
|
|
|
AVCodecID codec_id,
|
2015-04-06 10:40:12 -03:00
|
|
|
AVFormatContext *of,
|
|
|
|
|
char *error,
|
|
|
|
|
int error_size)
|
2006-02-05 19:14:46 +00:00
|
|
|
{
|
2012-05-12 16:11:34 +00:00
|
|
|
AVStream *st;
|
2022-02-18 18:20:06 +01:00
|
|
|
const AVCodec *codec;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-11-19 17:22:40 +00:00
|
|
|
error[0] = '\0';
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-11-30 16:42:39 +11:00
|
|
|
st = avformat_new_stream(of, nullptr);
|
2019-04-22 09:39:35 +10:00
|
|
|
if (!st) {
|
2023-11-30 16:42:39 +11:00
|
|
|
return nullptr;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2013-01-12 12:51:10 +00:00
|
|
|
st->id = 1;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-02-18 18:20:06 +01:00
|
|
|
codec = avcodec_find_encoder(codec_id);
|
2021-05-31 11:25:12 +02:00
|
|
|
if (!codec) {
|
|
|
|
|
fprintf(stderr, "Couldn't find valid audio codec\n");
|
2023-11-30 16:42:39 +11:00
|
|
|
context->audio_codec = nullptr;
|
|
|
|
|
return nullptr;
|
2021-05-31 11:25:12 +02:00
|
|
|
}
|
|
|
|
|
|
2022-02-18 18:20:06 +01:00
|
|
|
context->audio_codec = avcodec_alloc_context3(codec);
|
|
|
|
|
AVCodecContext *c = context->audio_codec;
|
|
|
|
|
c->thread_count = BLI_system_thread_count();
|
|
|
|
|
c->thread_type = FF_THREAD_SLICE;
|
2021-05-31 11:25:12 +02:00
|
|
|
|
2009-09-20 14:00:00 +00:00
|
|
|
c->sample_rate = rd->ffcodecdata.audio_mixrate;
|
2015-04-06 10:40:12 -03:00
|
|
|
c->bit_rate = context->ffmpeg_audio_bitrate * 1000;
|
2012-06-18 10:29:11 +00:00
|
|
|
c->sample_fmt = AV_SAMPLE_FMT_S16;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-11-07 17:44:14 +01:00
|
|
|
const int num_channels = rd->ffcodecdata.audio_channels;
|
|
|
|
|
int channel_layout_mask = 0;
|
2018-09-28 12:03:15 +02:00
|
|
|
switch (rd->ffcodecdata.audio_channels) {
|
|
|
|
|
case FFM_CHANNELS_MONO:
|
2022-11-07 17:44:14 +01:00
|
|
|
channel_layout_mask = AV_CH_LAYOUT_MONO;
|
2018-09-28 12:03:15 +02:00
|
|
|
break;
|
|
|
|
|
case FFM_CHANNELS_STEREO:
|
2022-11-07 17:44:14 +01:00
|
|
|
channel_layout_mask = AV_CH_LAYOUT_STEREO;
|
2018-09-28 12:03:15 +02:00
|
|
|
break;
|
|
|
|
|
case FFM_CHANNELS_SURROUND4:
|
2022-11-07 17:44:14 +01:00
|
|
|
channel_layout_mask = AV_CH_LAYOUT_QUAD;
|
2018-09-28 12:03:15 +02:00
|
|
|
break;
|
|
|
|
|
case FFM_CHANNELS_SURROUND51:
|
2022-11-07 17:44:14 +01:00
|
|
|
channel_layout_mask = AV_CH_LAYOUT_5POINT1_BACK;
|
2018-09-28 12:03:15 +02:00
|
|
|
break;
|
|
|
|
|
case FFM_CHANNELS_SURROUND71:
|
2022-11-07 17:44:14 +01:00
|
|
|
channel_layout_mask = AV_CH_LAYOUT_7POINT1;
|
2018-09-28 12:03:15 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2022-11-07 17:44:14 +01:00
|
|
|
BLI_assert(channel_layout_mask != 0);
|
|
|
|
|
|
|
|
|
|
# ifdef FFMPEG_USE_OLD_CHANNEL_VARS
|
|
|
|
|
c->channels = num_channels;
|
|
|
|
|
c->channel_layout = channel_layout_mask;
|
|
|
|
|
# else
|
|
|
|
|
av_channel_layout_from_mask(&c->ch_layout, channel_layout_mask);
|
|
|
|
|
# endif
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Patch #34204: [Render Animation] Fails with "Error: Specified sample_fmt is not supported" with ogg vorbis
Patch by Jehan Pages (pardon for mis-typing, emacs-nox works not so good with
urf-8 buffers here), with some own modifications. Thanks!
From the patch tracker:
The problem is because of several versions of ffmpeg, but even more because of
the fork situation libav/ffmpeg. So there are some installed versions out there
where you *must* use a float sample for some codec; whereas oppositely on some
other installations, you *must* use the int sample. So for some people, one
works not the other, and reciprocally.
As a consequence, you can't just have a switch codec-based, like in current
code, which decides on the float or int implementation, you must necessarily
have a runtime test because you won't know until then if ogg vorbis will use
one or another sample (note: that's true also for AC3 as I fixed the exact same
bug in DVDStyler for AC3 encoding a few months ago; and I guess it would be same
for AAC).
Some notes from self:
- New FFmpeg requires using FLTP for AAC, AC3 and Vorbis, it's not supported
by audaspace and result in this case would be just wrong. Throw an error
in cases FLTP is trying to be used.
- Moved strict_std_compliance a bit upper. When we'll support FLTP both
FLT and FLTP for AAC would need to be using FF_COMPLIANCE_EXPERIMENTAL.
- It is nice to have such check of supported by codec formats anyway.
2013-03-12 16:57:14 +00:00
|
|
|
if (request_float_audio_buffer(codec_id)) {
|
|
|
|
|
/* mainly for AAC codec which is experimental */
|
2012-11-21 11:57:35 +00:00
|
|
|
c->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
|
|
|
|
|
c->sample_fmt = AV_SAMPLE_FMT_FLT;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Patch #34204: [Render Animation] Fails with "Error: Specified sample_fmt is not supported" with ogg vorbis
Patch by Jehan Pages (pardon for mis-typing, emacs-nox works not so good with
urf-8 buffers here), with some own modifications. Thanks!
From the patch tracker:
The problem is because of several versions of ffmpeg, but even more because of
the fork situation libav/ffmpeg. So there are some installed versions out there
where you *must* use a float sample for some codec; whereas oppositely on some
other installations, you *must* use the int sample. So for some people, one
works not the other, and reciprocally.
As a consequence, you can't just have a switch codec-based, like in current
code, which decides on the float or int implementation, you must necessarily
have a runtime test because you won't know until then if ogg vorbis will use
one or another sample (note: that's true also for AC3 as I fixed the exact same
bug in DVDStyler for AC3 encoding a few months ago; and I guess it would be same
for AAC).
Some notes from self:
- New FFmpeg requires using FLTP for AAC, AC3 and Vorbis, it's not supported
by audaspace and result in this case would be just wrong. Throw an error
in cases FLTP is trying to be used.
- Moved strict_std_compliance a bit upper. When we'll support FLTP both
FLT and FLTP for AAC would need to be using FF_COMPLIANCE_EXPERIMENTAL.
- It is nice to have such check of supported by codec formats anyway.
2013-03-12 16:57:14 +00:00
|
|
|
if (codec->sample_fmts) {
|
2019-04-27 12:07:07 +10:00
|
|
|
/* Check if the preferred sample format for this codec is supported.
|
2023-12-07 12:15:45 +11:00
|
|
|
* this is because, depending on the version of LIBAV,
|
|
|
|
|
* and with the whole FFMPEG/LIBAV fork situation,
|
2019-04-27 12:07:07 +10:00
|
|
|
* you have various implementations around.
|
|
|
|
|
* Float samples in particular are not always supported. */
|
Patch #34204: [Render Animation] Fails with "Error: Specified sample_fmt is not supported" with ogg vorbis
Patch by Jehan Pages (pardon for mis-typing, emacs-nox works not so good with
urf-8 buffers here), with some own modifications. Thanks!
From the patch tracker:
The problem is because of several versions of ffmpeg, but even more because of
the fork situation libav/ffmpeg. So there are some installed versions out there
where you *must* use a float sample for some codec; whereas oppositely on some
other installations, you *must* use the int sample. So for some people, one
works not the other, and reciprocally.
As a consequence, you can't just have a switch codec-based, like in current
code, which decides on the float or int implementation, you must necessarily
have a runtime test because you won't know until then if ogg vorbis will use
one or another sample (note: that's true also for AC3 as I fixed the exact same
bug in DVDStyler for AC3 encoding a few months ago; and I guess it would be same
for AAC).
Some notes from self:
- New FFmpeg requires using FLTP for AAC, AC3 and Vorbis, it's not supported
by audaspace and result in this case would be just wrong. Throw an error
in cases FLTP is trying to be used.
- Moved strict_std_compliance a bit upper. When we'll support FLTP both
FLT and FLTP for AAC would need to be using FF_COMPLIANCE_EXPERIMENTAL.
- It is nice to have such check of supported by codec formats anyway.
2013-03-12 16:57:14 +00:00
|
|
|
const enum AVSampleFormat *p = codec->sample_fmts;
|
2014-08-12 10:31:07 +10:00
|
|
|
for (; *p != -1; p++) {
|
2021-05-07 17:10:03 +02:00
|
|
|
if (*p == c->sample_fmt) {
|
Patch #34204: [Render Animation] Fails with "Error: Specified sample_fmt is not supported" with ogg vorbis
Patch by Jehan Pages (pardon for mis-typing, emacs-nox works not so good with
urf-8 buffers here), with some own modifications. Thanks!
From the patch tracker:
The problem is because of several versions of ffmpeg, but even more because of
the fork situation libav/ffmpeg. So there are some installed versions out there
where you *must* use a float sample for some codec; whereas oppositely on some
other installations, you *must* use the int sample. So for some people, one
works not the other, and reciprocally.
As a consequence, you can't just have a switch codec-based, like in current
code, which decides on the float or int implementation, you must necessarily
have a runtime test because you won't know until then if ogg vorbis will use
one or another sample (note: that's true also for AC3 as I fixed the exact same
bug in DVDStyler for AC3 encoding a few months ago; and I guess it would be same
for AAC).
Some notes from self:
- New FFmpeg requires using FLTP for AAC, AC3 and Vorbis, it's not supported
by audaspace and result in this case would be just wrong. Throw an error
in cases FLTP is trying to be used.
- Moved strict_std_compliance a bit upper. When we'll support FLTP both
FLT and FLTP for AAC would need to be using FF_COMPLIANCE_EXPERIMENTAL.
- It is nice to have such check of supported by codec formats anyway.
2013-03-12 16:57:14 +00:00
|
|
|
break;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
Patch #34204: [Render Animation] Fails with "Error: Specified sample_fmt is not supported" with ogg vorbis
Patch by Jehan Pages (pardon for mis-typing, emacs-nox works not so good with
urf-8 buffers here), with some own modifications. Thanks!
From the patch tracker:
The problem is because of several versions of ffmpeg, but even more because of
the fork situation libav/ffmpeg. So there are some installed versions out there
where you *must* use a float sample for some codec; whereas oppositely on some
other installations, you *must* use the int sample. So for some people, one
works not the other, and reciprocally.
As a consequence, you can't just have a switch codec-based, like in current
code, which decides on the float or int implementation, you must necessarily
have a runtime test because you won't know until then if ogg vorbis will use
one or another sample (note: that's true also for AC3 as I fixed the exact same
bug in DVDStyler for AC3 encoding a few months ago; and I guess it would be same
for AAC).
Some notes from self:
- New FFmpeg requires using FLTP for AAC, AC3 and Vorbis, it's not supported
by audaspace and result in this case would be just wrong. Throw an error
in cases FLTP is trying to be used.
- Moved strict_std_compliance a bit upper. When we'll support FLTP both
FLT and FLTP for AAC would need to be using FF_COMPLIANCE_EXPERIMENTAL.
- It is nice to have such check of supported by codec formats anyway.
2013-03-12 16:57:14 +00:00
|
|
|
}
|
|
|
|
|
if (*p == -1) {
|
|
|
|
|
/* sample format incompatible with codec. Defaulting to a format known to work */
|
2021-05-07 17:10:03 +02:00
|
|
|
c->sample_fmt = codec->sample_fmts[0];
|
Patch #34204: [Render Animation] Fails with "Error: Specified sample_fmt is not supported" with ogg vorbis
Patch by Jehan Pages (pardon for mis-typing, emacs-nox works not so good with
urf-8 buffers here), with some own modifications. Thanks!
From the patch tracker:
The problem is because of several versions of ffmpeg, but even more because of
the fork situation libav/ffmpeg. So there are some installed versions out there
where you *must* use a float sample for some codec; whereas oppositely on some
other installations, you *must* use the int sample. So for some people, one
works not the other, and reciprocally.
As a consequence, you can't just have a switch codec-based, like in current
code, which decides on the float or int implementation, you must necessarily
have a runtime test because you won't know until then if ogg vorbis will use
one or another sample (note: that's true also for AC3 as I fixed the exact same
bug in DVDStyler for AC3 encoding a few months ago; and I guess it would be same
for AAC).
Some notes from self:
- New FFmpeg requires using FLTP for AAC, AC3 and Vorbis, it's not supported
by audaspace and result in this case would be just wrong. Throw an error
in cases FLTP is trying to be used.
- Moved strict_std_compliance a bit upper. When we'll support FLTP both
FLT and FLTP for AAC would need to be using FF_COMPLIANCE_EXPERIMENTAL.
- It is nice to have such check of supported by codec formats anyway.
2013-03-12 16:57:14 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Patch #34204: [Render Animation] Fails with "Error: Specified sample_fmt is not supported" with ogg vorbis
Patch by Jehan Pages (pardon for mis-typing, emacs-nox works not so good with
urf-8 buffers here), with some own modifications. Thanks!
From the patch tracker:
The problem is because of several versions of ffmpeg, but even more because of
the fork situation libav/ffmpeg. So there are some installed versions out there
where you *must* use a float sample for some codec; whereas oppositely on some
other installations, you *must* use the int sample. So for some people, one
works not the other, and reciprocally.
As a consequence, you can't just have a switch codec-based, like in current
code, which decides on the float or int implementation, you must necessarily
have a runtime test because you won't know until then if ogg vorbis will use
one or another sample (note: that's true also for AC3 as I fixed the exact same
bug in DVDStyler for AC3 encoding a few months ago; and I guess it would be same
for AAC).
Some notes from self:
- New FFmpeg requires using FLTP for AAC, AC3 and Vorbis, it's not supported
by audaspace and result in this case would be just wrong. Throw an error
in cases FLTP is trying to be used.
- Moved strict_std_compliance a bit upper. When we'll support FLTP both
FLT and FLTP for AAC would need to be using FF_COMPLIANCE_EXPERIMENTAL.
- It is nice to have such check of supported by codec formats anyway.
2013-03-12 16:57:14 +00:00
|
|
|
if (codec->supported_samplerates) {
|
|
|
|
|
const int *p = codec->supported_samplerates;
|
|
|
|
|
int best = 0;
|
|
|
|
|
int best_dist = INT_MAX;
|
2013-03-12 21:46:33 +00:00
|
|
|
for (; *p; p++) {
|
2021-05-07 17:10:03 +02:00
|
|
|
int dist = abs(c->sample_rate - *p);
|
2013-03-12 21:46:33 +00:00
|
|
|
if (dist < best_dist) {
|
Patch #34204: [Render Animation] Fails with "Error: Specified sample_fmt is not supported" with ogg vorbis
Patch by Jehan Pages (pardon for mis-typing, emacs-nox works not so good with
urf-8 buffers here), with some own modifications. Thanks!
From the patch tracker:
The problem is because of several versions of ffmpeg, but even more because of
the fork situation libav/ffmpeg. So there are some installed versions out there
where you *must* use a float sample for some codec; whereas oppositely on some
other installations, you *must* use the int sample. So for some people, one
works not the other, and reciprocally.
As a consequence, you can't just have a switch codec-based, like in current
code, which decides on the float or int implementation, you must necessarily
have a runtime test because you won't know until then if ogg vorbis will use
one or another sample (note: that's true also for AC3 as I fixed the exact same
bug in DVDStyler for AC3 encoding a few months ago; and I guess it would be same
for AAC).
Some notes from self:
- New FFmpeg requires using FLTP for AAC, AC3 and Vorbis, it's not supported
by audaspace and result in this case would be just wrong. Throw an error
in cases FLTP is trying to be used.
- Moved strict_std_compliance a bit upper. When we'll support FLTP both
FLT and FLTP for AAC would need to be using FF_COMPLIANCE_EXPERIMENTAL.
- It is nice to have such check of supported by codec formats anyway.
2013-03-12 16:57:14 +00:00
|
|
|
best_dist = dist;
|
|
|
|
|
best = *p;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
Patch #34204: [Render Animation] Fails with "Error: Specified sample_fmt is not supported" with ogg vorbis
Patch by Jehan Pages (pardon for mis-typing, emacs-nox works not so good with
urf-8 buffers here), with some own modifications. Thanks!
From the patch tracker:
The problem is because of several versions of ffmpeg, but even more because of
the fork situation libav/ffmpeg. So there are some installed versions out there
where you *must* use a float sample for some codec; whereas oppositely on some
other installations, you *must* use the int sample. So for some people, one
works not the other, and reciprocally.
As a consequence, you can't just have a switch codec-based, like in current
code, which decides on the float or int implementation, you must necessarily
have a runtime test because you won't know until then if ogg vorbis will use
one or another sample (note: that's true also for AC3 as I fixed the exact same
bug in DVDStyler for AC3 encoding a few months ago; and I guess it would be same
for AAC).
Some notes from self:
- New FFmpeg requires using FLTP for AAC, AC3 and Vorbis, it's not supported
by audaspace and result in this case would be just wrong. Throw an error
in cases FLTP is trying to be used.
- Moved strict_std_compliance a bit upper. When we'll support FLTP both
FLT and FLTP for AAC would need to be using FF_COMPLIANCE_EXPERIMENTAL.
- It is nice to have such check of supported by codec formats anyway.
2013-03-12 16:57:14 +00:00
|
|
|
}
|
|
|
|
|
/* best is the closest supported sample rate (same as selected if best_dist == 0) */
|
2021-05-07 17:10:03 +02:00
|
|
|
c->sample_rate = best;
|
Patch #34204: [Render Animation] Fails with "Error: Specified sample_fmt is not supported" with ogg vorbis
Patch by Jehan Pages (pardon for mis-typing, emacs-nox works not so good with
urf-8 buffers here), with some own modifications. Thanks!
From the patch tracker:
The problem is because of several versions of ffmpeg, but even more because of
the fork situation libav/ffmpeg. So there are some installed versions out there
where you *must* use a float sample for some codec; whereas oppositely on some
other installations, you *must* use the int sample. So for some people, one
works not the other, and reciprocally.
As a consequence, you can't just have a switch codec-based, like in current
code, which decides on the float or int implementation, you must necessarily
have a runtime test because you won't know until then if ogg vorbis will use
one or another sample (note: that's true also for AC3 as I fixed the exact same
bug in DVDStyler for AC3 encoding a few months ago; and I guess it would be same
for AAC).
Some notes from self:
- New FFmpeg requires using FLTP for AAC, AC3 and Vorbis, it's not supported
by audaspace and result in this case would be just wrong. Throw an error
in cases FLTP is trying to be used.
- Moved strict_std_compliance a bit upper. When we'll support FLTP both
FLT and FLTP for AAC would need to be using FF_COMPLIANCE_EXPERIMENTAL.
- It is nice to have such check of supported by codec formats anyway.
2013-03-12 16:57:14 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-02-17 18:08:53 +06:00
|
|
|
if (of->oformat->flags & AVFMT_GLOBALHEADER) {
|
2021-05-07 17:10:03 +02:00
|
|
|
c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
2014-02-17 18:08:53 +06:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-11-30 16:42:39 +11:00
|
|
|
int ret = avcodec_open2(c, codec, nullptr);
|
2021-05-31 11:25:12 +02:00
|
|
|
|
|
|
|
|
if (ret < 0) {
|
2023-11-30 06:03:18 +01:00
|
|
|
char error_str[AV_ERROR_MAX_STRING_SIZE];
|
|
|
|
|
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
|
|
|
|
fprintf(stderr, "Couldn't initialize audio codec: %s\n", error_str);
|
2012-11-19 17:22:40 +00:00
|
|
|
BLI_strncpy(error, IMB_ffmpeg_last_error(), error_size);
|
2021-05-07 17:10:03 +02:00
|
|
|
avcodec_free_context(&c);
|
2023-11-30 16:42:39 +11:00
|
|
|
context->audio_codec = nullptr;
|
|
|
|
|
return nullptr;
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-11-01 12:24:06 +11:00
|
|
|
/* Need to prevent floating point exception when using VORBIS audio codec,
|
2023-12-07 12:15:45 +11:00
|
|
|
* initialize this value in the same way as it's done in FFMPEG itself (sergey) */
|
2021-05-07 17:10:03 +02:00
|
|
|
c->time_base.num = 1;
|
|
|
|
|
c->time_base.den = c->sample_rate;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (c->frame_size == 0) {
|
2013-06-13 11:59:28 +00:00
|
|
|
/* Used to be if ((c->codec_id >= CODEC_ID_PCM_S16LE) && (c->codec_id <= CODEC_ID_PCM_DVD))
|
2013-04-01 15:31:27 +00:00
|
|
|
* not sure if that is needed anymore, so let's try out if there are any
|
2023-12-07 12:15:45 +11:00
|
|
|
* complaints regarding some FFMPEG versions users might have. */
|
2021-05-07 17:10:03 +02:00
|
|
|
context->audio_input_samples = AV_INPUT_BUFFER_MIN_SIZE * 8 / c->bits_per_coded_sample /
|
2022-11-07 17:44:14 +01:00
|
|
|
num_channels;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-03-06 18:40:15 +00:00
|
|
|
else {
|
2015-04-06 10:40:12 -03:00
|
|
|
context->audio_input_samples = c->frame_size;
|
2010-02-14 15:38:05 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
context->audio_deinterleave = av_sample_fmt_is_planar(c->sample_fmt);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
context->audio_sample_size = av_get_bytes_per_sample(c->sample_fmt);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-11-07 17:44:14 +01:00
|
|
|
context->audio_input_buffer = (uint8_t *)av_malloc(context->audio_input_samples * num_channels *
|
|
|
|
|
context->audio_sample_size);
|
2019-04-22 09:39:35 +10:00
|
|
|
if (context->audio_deinterleave) {
|
2015-04-06 10:40:12 -03:00
|
|
|
context->audio_deinterleave_buffer = (uint8_t *)av_malloc(
|
2022-11-07 17:44:14 +01:00
|
|
|
context->audio_input_samples * num_channels * context->audio_sample_size);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
context->audio_time = 0.0f;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-05-07 17:10:03 +02:00
|
|
|
avcodec_parameters_from_context(st->codecpar, c);
|
|
|
|
|
|
2006-02-05 19:14:46 +00:00
|
|
|
return st;
|
|
|
|
|
}
|
|
|
|
|
/* essential functions -- start, append, end */
|
|
|
|
|
|
2012-06-18 10:29:11 +00:00
|
|
|
static void ffmpeg_dict_set_int(AVDictionary **dict, const char *key, int value)
|
|
|
|
|
{
|
|
|
|
|
char buffer[32];
|
|
|
|
|
|
2023-05-09 12:50:37 +10:00
|
|
|
SNPRINTF(buffer, "%d", value);
|
2012-06-18 10:29:11 +00:00
|
|
|
|
|
|
|
|
av_dict_set(dict, key, buffer, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-05 16:31:59 +02:00
|
|
|
static void ffmpeg_add_metadata_callback(void *data,
|
|
|
|
|
const char *propname,
|
|
|
|
|
char *propvalue,
|
2023-11-30 06:03:18 +01:00
|
|
|
int /*propvalue_maxncpy*/)
|
2018-04-05 16:31:59 +02:00
|
|
|
{
|
|
|
|
|
AVDictionary **metadata = (AVDictionary **)data;
|
|
|
|
|
av_dict_set(metadata, propname, propvalue, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-21 12:57:36 +01:00
|
|
|
static bool start_ffmpeg_impl(FFMpegContext *context,
|
|
|
|
|
RenderData *rd,
|
|
|
|
|
int rectx,
|
|
|
|
|
int recty,
|
|
|
|
|
const char *suffix,
|
|
|
|
|
ReportList *reports)
|
2006-02-05 19:14:46 +00:00
|
|
|
{
|
|
|
|
|
/* Handle to the output file */
|
2012-05-12 16:11:34 +00:00
|
|
|
AVFormatContext *of;
|
2022-02-22 10:07:01 +11:00
|
|
|
const AVOutputFormat *fmt;
|
2023-05-03 14:13:27 +10:00
|
|
|
char filepath[FILE_MAX], error[1024];
|
2012-05-12 16:11:34 +00:00
|
|
|
const char **exts;
|
2023-11-30 06:03:18 +01:00
|
|
|
int ret = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
context->ffmpeg_type = rd->ffcodecdata.type;
|
2023-11-30 06:03:18 +01:00
|
|
|
context->ffmpeg_codec = AVCodecID(rd->ffcodecdata.codec);
|
|
|
|
|
context->ffmpeg_audio_codec = AVCodecID(rd->ffcodecdata.audio_codec);
|
2015-04-06 10:40:12 -03:00
|
|
|
context->ffmpeg_video_bitrate = rd->ffcodecdata.video_bitrate;
|
|
|
|
|
context->ffmpeg_audio_bitrate = rd->ffcodecdata.audio_bitrate;
|
|
|
|
|
context->ffmpeg_gop_size = rd->ffcodecdata.gop_size;
|
|
|
|
|
context->ffmpeg_autosplit = rd->ffcodecdata.flags & FFMPEG_AUTOSPLIT_OUTPUT;
|
FFmpeg interface improvements
This patch changes a couple of things in the video output encoding.
{F362527}
- Clearer separation between container and codec. No more "format", as this is
too ambiguous. As a result, codecs were removed from the container list.
- Added FFmpeg speed presets, so the user can choosen from the range "Very
slow" to "Ultra fast". By default no preset is used.
- Added Constant Rate Factor (CRF) mode, which allows changing the bit-rate
depending on the desired quality and the input. This generally produces the
best quality videos, at the expense of not knowing the exact bit-rate and
file size.
- Added optional maximum of non-B-frames between B-frames (`max_b_frames`).
- Presets were adjusted for these changes, and new presets added. One of the
new presets is [recommended](https://trac.ffmpeg.org/wiki/Encode/VFX#H.264)
for reviewing videos, as it allows players to scrub through it easily. Might
be nice in weeklies. This preset also requires control over the
`max_b_frames` setting.
GUI-only changes:
- Renamed "MPEG" in the output file format menu with "FFmpeg", as this is more
accurate. After all, FFmpeg is used when this option is chosen, which can
also output non-MPEG files.
- Certain parts of the GUI are disabled when not in use:
- bit rate options are not used when a constant rate factor is given.
- audio bitrate & volume are not used when no audio is exported.
Note that I did not touch `BKE_ffmpeg_preset_set()`. There are currently two
preset systems for FFmpeg (`BKE_ffmpeg_preset_set()` and the Python preset
system). Before we do more work on `BKE_ffmpeg_preset_set()`, I think it's a
good idea to determine whether we want to keep it at all.
After this patch has been accepted, I'd be happy to go through the code and
remove any then-obsolete bits, such as the handling of "XVID" as a container
format.
Reviewers: sergey, mont29, brecht
Subscribers: mpan3, Blendify, brecht, fsiddi
Tags: #bf_blender
Differential Revision: https://developer.blender.org/D2242
2016-09-21 15:01:51 +02:00
|
|
|
context->ffmpeg_crf = rd->ffcodecdata.constant_rate_factor;
|
|
|
|
|
context->ffmpeg_preset = rd->ffcodecdata.ffmpeg_preset;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
FFmpeg interface improvements
This patch changes a couple of things in the video output encoding.
{F362527}
- Clearer separation between container and codec. No more "format", as this is
too ambiguous. As a result, codecs were removed from the container list.
- Added FFmpeg speed presets, so the user can choosen from the range "Very
slow" to "Ultra fast". By default no preset is used.
- Added Constant Rate Factor (CRF) mode, which allows changing the bit-rate
depending on the desired quality and the input. This generally produces the
best quality videos, at the expense of not knowing the exact bit-rate and
file size.
- Added optional maximum of non-B-frames between B-frames (`max_b_frames`).
- Presets were adjusted for these changes, and new presets added. One of the
new presets is [recommended](https://trac.ffmpeg.org/wiki/Encode/VFX#H.264)
for reviewing videos, as it allows players to scrub through it easily. Might
be nice in weeklies. This preset also requires control over the
`max_b_frames` setting.
GUI-only changes:
- Renamed "MPEG" in the output file format menu with "FFmpeg", as this is more
accurate. After all, FFmpeg is used when this option is chosen, which can
also output non-MPEG files.
- Certain parts of the GUI are disabled when not in use:
- bit rate options are not used when a constant rate factor is given.
- audio bitrate & volume are not used when no audio is exported.
Note that I did not touch `BKE_ffmpeg_preset_set()`. There are currently two
preset systems for FFmpeg (`BKE_ffmpeg_preset_set()` and the Python preset
system). Before we do more work on `BKE_ffmpeg_preset_set()`, I think it's a
good idea to determine whether we want to keep it at all.
After this patch has been accepted, I'd be happy to go through the code and
remove any then-obsolete bits, such as the handling of "XVID" as a container
format.
Reviewers: sergey, mont29, brecht
Subscribers: mpan3, Blendify, brecht, fsiddi
Tags: #bf_blender
Differential Revision: https://developer.blender.org/D2242
2016-09-21 15:01:51 +02:00
|
|
|
if ((rd->ffcodecdata.flags & FFMPEG_USE_MAX_B_FRAMES) != 0) {
|
|
|
|
|
context->ffmpeg_max_b_frames = rd->ffcodecdata.max_b_frames;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2006-02-05 19:14:46 +00:00
|
|
|
/* Determine the correct filename */
|
2023-05-03 14:13:27 +10:00
|
|
|
ffmpeg_filepath_get(context, filepath, rd, context->ffmpeg_preview, suffix);
|
2012-08-26 11:01:14 +00:00
|
|
|
PRINT(
|
2023-12-07 12:15:45 +11:00
|
|
|
"Starting output to %s(FFMPEG)...\n"
|
2012-05-12 16:11:34 +00:00
|
|
|
" Using type=%d, codec=%d, audio_codec=%d,\n"
|
|
|
|
|
" video_bitrate=%d, audio_bitrate=%d,\n"
|
|
|
|
|
" gop_size=%d, autosplit=%d\n"
|
|
|
|
|
" render width=%d, render height=%d\n",
|
2023-05-03 14:13:27 +10:00
|
|
|
filepath,
|
2015-04-06 10:40:12 -03:00
|
|
|
context->ffmpeg_type,
|
|
|
|
|
context->ffmpeg_codec,
|
|
|
|
|
context->ffmpeg_audio_codec,
|
|
|
|
|
context->ffmpeg_video_bitrate,
|
|
|
|
|
context->ffmpeg_audio_bitrate,
|
|
|
|
|
context->ffmpeg_gop_size,
|
|
|
|
|
context->ffmpeg_autosplit,
|
|
|
|
|
rectx,
|
|
|
|
|
recty);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-02-18 18:20:06 +01:00
|
|
|
/* Sanity checks for the output file extensions. */
|
2015-04-06 10:40:12 -03:00
|
|
|
exts = get_file_extensions(context->ffmpeg_type);
|
2006-07-09 13:05:09 +00:00
|
|
|
if (!exts) {
|
2012-10-21 14:02:30 +00:00
|
|
|
BKE_report(reports, RPT_ERROR, "No valid formats found");
|
2024-02-21 12:57:36 +01:00
|
|
|
return false;
|
2006-07-09 13:05:09 +00:00
|
|
|
}
|
2022-02-18 18:20:06 +01:00
|
|
|
|
2023-12-17 16:04:44 +11:00
|
|
|
fmt = av_guess_format(nullptr, exts[0], nullptr);
|
2006-02-05 19:14:46 +00:00
|
|
|
if (!fmt) {
|
2012-10-21 14:02:30 +00:00
|
|
|
BKE_report(reports, RPT_ERROR, "No valid formats found");
|
2024-02-21 12:57:36 +01:00
|
|
|
return false;
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-05-26 21:57:02 +00:00
|
|
|
of = avformat_alloc_context();
|
2006-02-05 19:14:46 +00:00
|
|
|
if (!of) {
|
2024-02-05 17:08:17 +01:00
|
|
|
BKE_report(reports, RPT_ERROR, "Can't allocate FFmpeg format context");
|
2024-02-21 12:57:36 +01:00
|
|
|
return false;
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-02-18 18:20:06 +01:00
|
|
|
enum AVCodecID audio_codec = context->ffmpeg_audio_codec;
|
|
|
|
|
enum AVCodecID video_codec = context->ffmpeg_codec;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-05-03 14:13:27 +10:00
|
|
|
of->url = av_strdup(filepath);
|
2022-02-18 18:20:06 +01:00
|
|
|
/* Check if we need to force change the codec because of file type codec restrictions */
|
2015-04-06 10:40:12 -03:00
|
|
|
switch (context->ffmpeg_type) {
|
2012-05-12 16:11:34 +00:00
|
|
|
case FFMPEG_OGG:
|
2022-02-18 18:20:06 +01:00
|
|
|
video_codec = AV_CODEC_ID_THEORA;
|
2012-05-12 16:11:34 +00:00
|
|
|
break;
|
|
|
|
|
case FFMPEG_DV:
|
2022-02-18 18:20:06 +01:00
|
|
|
video_codec = AV_CODEC_ID_DVVIDEO;
|
2012-05-12 16:11:34 +00:00
|
|
|
break;
|
|
|
|
|
case FFMPEG_MPEG1:
|
2022-02-18 18:20:06 +01:00
|
|
|
video_codec = AV_CODEC_ID_MPEG1VIDEO;
|
2012-05-12 16:11:34 +00:00
|
|
|
break;
|
|
|
|
|
case FFMPEG_MPEG2:
|
2022-02-18 18:20:06 +01:00
|
|
|
video_codec = AV_CODEC_ID_MPEG2VIDEO;
|
2012-05-12 16:11:34 +00:00
|
|
|
break;
|
|
|
|
|
case FFMPEG_H264:
|
2022-02-18 18:20:06 +01:00
|
|
|
video_codec = AV_CODEC_ID_H264;
|
2012-05-12 16:11:34 +00:00
|
|
|
break;
|
|
|
|
|
case FFMPEG_XVID:
|
2022-02-18 18:20:06 +01:00
|
|
|
video_codec = AV_CODEC_ID_MPEG4;
|
2012-05-12 16:11:34 +00:00
|
|
|
break;
|
|
|
|
|
case FFMPEG_FLV:
|
2022-02-18 18:20:06 +01:00
|
|
|
video_codec = AV_CODEC_ID_FLV1;
|
2012-05-12 16:11:34 +00:00
|
|
|
break;
|
Video rendering: FFMpeg AV1 codec encoding support
Previously, the Blender video renderer did not have support for
encoding video to AV1 (not to be confused with the container AVI).
The proposed solution is to leverage the existing FFMpeg renderer
to encode to AV1.
Note that avcodec_find_encoder(AV_CODEC_ID_AV1) usually returns
"libaom-av1" which is the "reference implementation" for AV1 encoding
(the default for FFMpeg, and is slow). "libsvtav1" is faster and
preferred so there is extra handling when fetching the AV1 codec for
encoding such that "libsvtav1" is used when possible.
This commit should only affect the options available for video
rendering, which includes the additional AV1 codec to choose from, and
setting "-crf".
Also note that the current release of FFMpeg for ArchLinux does not
support "-crf" for "libsvtav1", but the equivalent option "-qp" is
supported and used as a fallback when "libsvtav1" is used (as
mentioned here: https://trac.ffmpeg.org/wiki/Encode/AV1#SVT-AV1 ).
(Actually, both "-crf" and "-qp" is specified with the same value in
the code. When a release of FFMpeg obtains support for "-crf" for
"libsvtav1" is released, the code shouldn't be needed to change.)
The usage of the AV1 codec should be very similar to the usage of the
H264 codec, but is limited to the "mp4" and "mkv" containers.
This patch pertains to the "VFX & Video" module, as its main purpose
is to supplement the Video Sequencer tool with the additional AV1
codec for encoded video output.
Differential Revision: https://developer.blender.org/D14920
Reviewed By: sergey , ISS, zeddb
2022-10-21 20:10:17 -06:00
|
|
|
case FFMPEG_AV1:
|
|
|
|
|
video_codec = AV_CODEC_ID_AV1;
|
|
|
|
|
break;
|
2012-05-12 16:11:34 +00:00
|
|
|
default:
|
2022-02-18 18:20:06 +01:00
|
|
|
/* These containers are not restricted to any specific codec types.
|
2024-05-04 15:06:46 +10:00
|
|
|
* Currently we expect these to be `.avi`, `.mov`, `.mkv`, and `.mp4`. */
|
2022-02-18 18:20:06 +01:00
|
|
|
video_codec = context->ffmpeg_codec;
|
2012-05-12 16:11:34 +00:00
|
|
|
break;
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
2022-02-18 18:20:06 +01:00
|
|
|
|
2022-02-22 22:38:29 +11:00
|
|
|
/* Returns after this must 'goto fail;' */
|
2022-02-18 18:20:06 +01:00
|
|
|
|
2022-02-22 22:38:29 +11:00
|
|
|
# if LIBAVFORMAT_VERSION_MAJOR >= 59
|
2022-02-18 18:20:06 +01:00
|
|
|
of->oformat = fmt;
|
2022-02-22 22:38:29 +11:00
|
|
|
# else
|
|
|
|
|
/* *DEPRECATED* 2022/08/01 For FFMPEG (<5.0) remove this else branch and the `ifdef` above. */
|
|
|
|
|
of->oformat = (AVOutputFormat *)fmt;
|
|
|
|
|
# endif
|
2022-02-18 18:20:06 +01:00
|
|
|
|
|
|
|
|
if (video_codec == AV_CODEC_ID_DVVIDEO) {
|
2006-06-07 12:53:51 +00:00
|
|
|
if (rectx != 720) {
|
2009-12-22 12:01:32 +00:00
|
|
|
BKE_report(reports, RPT_ERROR, "Render width has to be 720 pixels for DV!");
|
2015-10-23 18:36:46 +11:00
|
|
|
goto fail;
|
2006-06-07 12:53:51 +00:00
|
|
|
}
|
2009-01-04 14:14:06 +00:00
|
|
|
if (rd->frs_sec != 25 && recty != 480) {
|
2009-12-22 12:01:32 +00:00
|
|
|
BKE_report(reports, RPT_ERROR, "Render height has to be 480 pixels for DV-NTSC!");
|
2015-10-23 18:36:46 +11:00
|
|
|
goto fail;
|
2006-06-07 12:53:51 +00:00
|
|
|
}
|
2009-01-04 14:14:06 +00:00
|
|
|
if (rd->frs_sec == 25 && recty != 576) {
|
2009-12-22 12:01:32 +00:00
|
|
|
BKE_report(reports, RPT_ERROR, "Render height has to be 576 pixels for DV-PAL!");
|
2015-10-23 18:36:46 +11:00
|
|
|
goto fail;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2006-06-07 12:53:51 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
if (context->ffmpeg_type == FFMPEG_DV) {
|
2022-02-18 18:20:06 +01:00
|
|
|
audio_codec = AV_CODEC_ID_PCM_S16LE;
|
2015-04-06 10:40:12 -03:00
|
|
|
if (context->ffmpeg_audio_codec != AV_CODEC_ID_NONE &&
|
|
|
|
|
rd->ffcodecdata.audio_mixrate != 48000 && rd->ffcodecdata.audio_channels != 2)
|
|
|
|
|
{
|
2024-02-05 17:08:17 +01:00
|
|
|
BKE_report(reports, RPT_ERROR, "FFmpeg only supports 48khz / stereo audio for DV!");
|
2015-10-23 18:36:46 +11:00
|
|
|
goto fail;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2006-06-07 12:53:51 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-02-18 18:20:06 +01:00
|
|
|
if (video_codec != AV_CODEC_ID_NONE) {
|
2015-04-06 10:40:12 -03:00
|
|
|
context->video_stream = alloc_video_stream(
|
2022-02-18 18:20:06 +01:00
|
|
|
context, rd, video_codec, of, rectx, recty, error, sizeof(error));
|
2015-04-06 10:40:12 -03:00
|
|
|
PRINT("alloc video stream %p\n", context->video_stream);
|
|
|
|
|
if (!context->video_stream) {
|
2019-04-22 09:39:35 +10:00
|
|
|
if (error[0]) {
|
2012-08-26 11:01:14 +00:00
|
|
|
BKE_report(reports, RPT_ERROR, error);
|
2021-05-07 17:10:03 +02:00
|
|
|
PRINT("Video stream error: %s\n", error);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2012-10-21 14:02:30 +00:00
|
|
|
BKE_report(reports, RPT_ERROR, "Error initializing video stream");
|
2021-05-07 17:10:03 +02:00
|
|
|
PRINT("Error initializing video stream");
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2015-10-23 18:36:46 +11:00
|
|
|
goto fail;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2010-02-07 23:41:17 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
if (context->ffmpeg_audio_codec != AV_CODEC_ID_NONE) {
|
2022-02-18 18:20:06 +01:00
|
|
|
context->audio_stream = alloc_audio_stream(context, rd, audio_codec, of, error, sizeof(error));
|
2015-04-06 10:40:12 -03:00
|
|
|
if (!context->audio_stream) {
|
2019-04-22 09:39:35 +10:00
|
|
|
if (error[0]) {
|
2012-11-19 17:22:40 +00:00
|
|
|
BKE_report(reports, RPT_ERROR, error);
|
2021-05-07 17:10:03 +02:00
|
|
|
PRINT("Audio stream error: %s\n", error);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2012-11-19 17:22:40 +00:00
|
|
|
BKE_report(reports, RPT_ERROR, "Error initializing audio stream");
|
2021-05-07 17:10:03 +02:00
|
|
|
PRINT("Error initializing audio stream");
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2015-10-23 18:36:46 +11:00
|
|
|
goto fail;
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!(fmt->flags & AVFMT_NOFILE)) {
|
2023-05-03 14:13:27 +10:00
|
|
|
if (avio_open(&of->pb, filepath, AVIO_FLAG_WRITE) < 0) {
|
2012-10-21 14:02:30 +00:00
|
|
|
BKE_report(reports, RPT_ERROR, "Could not open file for writing");
|
2021-05-07 17:10:03 +02:00
|
|
|
PRINT("Could not open file for writing\n");
|
2015-10-23 18:36:46 +11:00
|
|
|
goto fail;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-11-30 16:42:39 +11:00
|
|
|
if (context->stamp_data != nullptr) {
|
2018-04-05 16:31:59 +02:00
|
|
|
BKE_stamp_info_callback(
|
|
|
|
|
&of->metadata, context->stamp_data, ffmpeg_add_metadata_callback, false);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-11-30 16:42:39 +11:00
|
|
|
ret = avformat_write_header(of, nullptr);
|
2021-05-07 17:10:03 +02:00
|
|
|
if (ret < 0) {
|
2012-10-21 14:02:30 +00:00
|
|
|
BKE_report(reports,
|
|
|
|
|
RPT_ERROR,
|
|
|
|
|
"Could not initialize streams, probably unsupported codec combination");
|
2023-11-30 06:03:18 +01:00
|
|
|
char error_str[AV_ERROR_MAX_STRING_SIZE];
|
|
|
|
|
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
|
|
|
|
PRINT("Could not write media header: %s\n", error_str);
|
2015-10-23 18:36:46 +11:00
|
|
|
goto fail;
|
2011-10-04 12:30:26 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
context->outfile = of;
|
2023-05-03 14:13:27 +10:00
|
|
|
av_dump_format(of, 0, filepath, 1);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-02-21 12:57:36 +01:00
|
|
|
return true;
|
2015-10-23 18:36:46 +11:00
|
|
|
|
|
|
|
|
fail:
|
|
|
|
|
if (of->pb) {
|
|
|
|
|
avio_close(of->pb);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-05-07 17:10:03 +02:00
|
|
|
if (context->video_stream) {
|
2023-11-30 16:42:39 +11:00
|
|
|
context->video_stream = nullptr;
|
2015-10-23 18:36:46 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-05-07 17:10:03 +02:00
|
|
|
if (context->audio_stream) {
|
2023-11-30 16:42:39 +11:00
|
|
|
context->audio_stream = nullptr;
|
2015-10-23 18:36:46 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-10-23 18:36:46 +11:00
|
|
|
avformat_free_context(of);
|
2024-02-21 12:57:36 +01:00
|
|
|
return false;
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
|
|
|
|
|
2010-09-27 07:37:36 +00:00
|
|
|
/**
|
2018-06-01 18:19:39 +02:00
|
|
|
* Writes any delayed frames in the encoder. This function is called before
|
2010-09-27 07:37:36 +00:00
|
|
|
* closing the encoder.
|
|
|
|
|
*
|
|
|
|
|
* <p>
|
2018-06-01 18:19:39 +02:00
|
|
|
* Since an encoder may use both past and future frames to predict
|
|
|
|
|
* inter-frames (H.264 B-frames, for example), it can output the frames
|
2010-09-27 07:37:36 +00:00
|
|
|
* in a different order from the one it was given.
|
|
|
|
|
* For example, when sending frames 1, 2, 3, 4 to the encoder, it may write
|
2012-09-26 20:05:38 +00:00
|
|
|
* them in the order 1, 4, 2, 3 - first the two frames used for prediction,
|
2018-06-01 18:19:39 +02:00
|
|
|
* and then the bidirectionally-predicted frames. What this means in practice
|
|
|
|
|
* is that the encoder may not immediately produce one output frame for each
|
|
|
|
|
* input frame. These delayed frames must be flushed before we close the
|
|
|
|
|
* stream. We do this by calling avcodec_encode_video with NULL for the last
|
2010-09-27 07:37:36 +00:00
|
|
|
* parameter.
|
|
|
|
|
* </p>
|
|
|
|
|
*/
|
2021-07-05 14:16:02 +02:00
|
|
|
static void flush_ffmpeg(AVCodecContext *c, AVStream *stream, AVFormatContext *outfile)
|
2010-09-27 07:37:36 +00:00
|
|
|
{
|
2023-11-30 06:03:18 +01:00
|
|
|
char error_str[AV_ERROR_MAX_STRING_SIZE];
|
2021-05-07 17:10:03 +02:00
|
|
|
AVPacket *packet = av_packet_alloc();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-11-30 16:42:39 +11:00
|
|
|
avcodec_send_frame(c, nullptr);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-05-07 17:10:03 +02:00
|
|
|
/* Get the packets frames. */
|
|
|
|
|
int ret = 1;
|
|
|
|
|
while (ret >= 0) {
|
|
|
|
|
ret = avcodec_receive_packet(c, packet);
|
|
|
|
|
|
|
|
|
|
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
|
|
|
|
/* No more packets to flush. */
|
2010-09-27 07:37:36 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2021-05-07 17:10:03 +02:00
|
|
|
if (ret < 0) {
|
2023-11-30 06:03:18 +01:00
|
|
|
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
|
|
|
|
fprintf(stderr, "Error encoding delayed frame: %s\n", error_str);
|
2010-09-27 07:37:36 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-05 14:16:02 +02:00
|
|
|
packet->stream_index = stream->index;
|
|
|
|
|
av_packet_rescale_ts(packet, c->time_base, stream->time_base);
|
2021-05-28 18:37:36 +02:00
|
|
|
# ifdef FFMPEG_USE_DURATION_WORKAROUND
|
2021-08-24 15:15:21 +02:00
|
|
|
my_guess_pkt_duration(outfile, stream, packet);
|
2021-05-28 18:37:36 +02:00
|
|
|
# endif
|
2021-05-07 17:10:03 +02:00
|
|
|
|
2021-07-05 14:16:02 +02:00
|
|
|
int write_ret = av_interleaved_write_frame(outfile, packet);
|
2021-05-07 17:10:03 +02:00
|
|
|
if (write_ret != 0) {
|
2023-11-30 06:03:18 +01:00
|
|
|
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret);
|
|
|
|
|
fprintf(stderr, "Error writing delayed frame: %s\n", error_str);
|
2010-09-27 07:37:36 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-05-07 17:10:03 +02:00
|
|
|
|
|
|
|
|
av_packet_free(&packet);
|
2010-09-27 07:37:36 +00:00
|
|
|
}
|
|
|
|
|
|
2006-07-09 13:05:09 +00:00
|
|
|
/* **********************************************************************
|
2012-04-22 11:54:53 +00:00
|
|
|
* * public interface
|
|
|
|
|
* ********************************************************************** */
|
2006-07-09 13:05:09 +00:00
|
|
|
|
|
|
|
|
/* Get the output filename-- similar to the other output formats */
|
2023-05-02 16:47:57 +10:00
|
|
|
static void ffmpeg_filepath_get(FFMpegContext *context,
|
2023-05-27 15:10:59 +10:00
|
|
|
char filepath[FILE_MAX],
|
2023-05-02 16:47:57 +10:00
|
|
|
const RenderData *rd,
|
|
|
|
|
bool preview,
|
|
|
|
|
const char *suffix)
|
2011-09-28 05:53:40 +00:00
|
|
|
{
|
2006-07-09 13:05:09 +00:00
|
|
|
char autosplit[20];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-12 16:11:34 +00:00
|
|
|
const char **exts = get_file_extensions(rd->ffcodecdata.type);
|
|
|
|
|
const char **fe = exts;
|
2015-03-26 14:49:59 +01:00
|
|
|
int sfra, efra;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-05-27 15:10:59 +10:00
|
|
|
if (!filepath || !exts) {
|
2006-07-09 13:05:09 +00:00
|
|
|
return;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-03-26 14:49:59 +01:00
|
|
|
if (preview) {
|
|
|
|
|
sfra = rd->psfra;
|
|
|
|
|
efra = rd->pefra;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
sfra = rd->sfra;
|
|
|
|
|
efra = rd->efra;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-05-27 15:10:59 +10:00
|
|
|
BLI_strncpy(filepath, rd->pic, FILE_MAX);
|
|
|
|
|
BLI_path_abs(filepath, BKE_main_blendfile_path_from_global());
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-05-27 15:10:59 +10:00
|
|
|
BLI_file_ensure_parent_dir_exists(filepath);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-01-11 00:08:16 +01:00
|
|
|
autosplit[0] = '\0';
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-01-04 14:14:06 +00:00
|
|
|
if ((rd->ffcodecdata.flags & FFMPEG_AUTOSPLIT_OUTPUT) != 0) {
|
2015-04-06 10:40:12 -03:00
|
|
|
if (context) {
|
2023-05-09 12:50:37 +10:00
|
|
|
SNPRINTF(autosplit, "_%03d", context->ffmpeg_autosplit_count);
|
2006-07-09 13:05:09 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2013-11-25 16:59:10 +11:00
|
|
|
if (rd->scemode & R_EXTENSION) {
|
|
|
|
|
while (*fe) {
|
2023-05-27 15:10:59 +10:00
|
|
|
if (BLI_strcasecmp(filepath + strlen(filepath) - strlen(*fe), *fe) == 0) {
|
2013-11-25 16:59:10 +11:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
fe++;
|
2006-07-09 13:05:09 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-11-30 16:42:39 +11:00
|
|
|
if (*fe == nullptr) {
|
2023-05-27 15:10:59 +10:00
|
|
|
BLI_strncat(filepath, autosplit, FILE_MAX);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-05-27 15:10:59 +10:00
|
|
|
BLI_path_frame_range(filepath, FILE_MAX, sfra, efra, 4);
|
|
|
|
|
BLI_strncat(filepath, *exts, FILE_MAX);
|
2013-11-25 16:59:10 +11:00
|
|
|
}
|
|
|
|
|
else {
|
2023-05-27 15:10:59 +10:00
|
|
|
*(filepath + strlen(filepath) - strlen(*fe)) = '\0';
|
|
|
|
|
BLI_strncat(filepath, autosplit, FILE_MAX);
|
|
|
|
|
BLI_strncat(filepath, *fe, FILE_MAX);
|
2013-11-25 16:59:10 +11:00
|
|
|
}
|
2012-03-24 06:18:31 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2023-05-27 15:10:59 +10:00
|
|
|
if (BLI_path_frame_check_chars(filepath)) {
|
|
|
|
|
BLI_path_frame_range(filepath, FILE_MAX, sfra, efra, 4);
|
2013-11-25 16:59:10 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-05-27 15:10:59 +10:00
|
|
|
BLI_strncat(filepath, autosplit, FILE_MAX);
|
2006-07-09 13:05:09 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-05-27 15:10:59 +10:00
|
|
|
BLI_path_suffix(filepath, FILE_MAX, suffix, "");
|
2006-07-09 13:05:09 +00:00
|
|
|
}
|
|
|
|
|
|
2023-06-19 12:36:18 +10:00
|
|
|
void BKE_ffmpeg_filepath_get(char filepath[/*FILE_MAX*/ 1024],
|
2023-05-03 14:13:27 +10:00
|
|
|
const RenderData *rd,
|
|
|
|
|
bool preview,
|
|
|
|
|
const char *suffix)
|
2015-04-06 10:40:12 -03:00
|
|
|
{
|
2023-11-30 16:42:39 +11:00
|
|
|
ffmpeg_filepath_get(nullptr, filepath, rd, preview, suffix);
|
2015-04-06 10:40:12 -03:00
|
|
|
}
|
|
|
|
|
|
2024-02-21 12:57:36 +01:00
|
|
|
bool BKE_ffmpeg_start(void *context_v,
|
|
|
|
|
const Scene *scene,
|
|
|
|
|
RenderData *rd,
|
|
|
|
|
int rectx,
|
|
|
|
|
int recty,
|
|
|
|
|
ReportList *reports,
|
|
|
|
|
bool preview,
|
|
|
|
|
const char *suffix)
|
2006-02-05 19:14:46 +00:00
|
|
|
{
|
2023-11-30 06:03:18 +01:00
|
|
|
FFMpegContext *context = static_cast<FFMpegContext *>(context_v);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
context->ffmpeg_autosplit_count = 0;
|
|
|
|
|
context->ffmpeg_preview = preview;
|
2018-04-05 16:31:59 +02:00
|
|
|
context->stamp_data = BKE_stamp_info_from_scene_static(scene);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-02-21 12:57:36 +01:00
|
|
|
bool success = start_ffmpeg_impl(context, rd, rectx, recty, suffix, reports);
|
2011-06-23 16:10:48 +00:00
|
|
|
# ifdef WITH_AUDASPACE
|
2015-04-06 10:40:12 -03:00
|
|
|
if (context->audio_stream) {
|
2021-05-07 17:10:03 +02:00
|
|
|
AVCodecContext *c = context->audio_codec;
|
|
|
|
|
|
2010-01-01 05:09:30 +00:00
|
|
|
AUD_DeviceSpecs specs;
|
2022-11-07 17:44:14 +01:00
|
|
|
# ifdef FFMPEG_USE_OLD_CHANNEL_VARS
|
2023-11-30 06:03:18 +01:00
|
|
|
specs.channels = AUD_Channels(c->channels);
|
2022-11-07 17:44:14 +01:00
|
|
|
# else
|
2023-11-30 06:03:18 +01:00
|
|
|
specs.channels = AUD_Channels(c->ch_layout.nb_channels);
|
2022-11-07 17:44:14 +01:00
|
|
|
# endif
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-04-03 01:36:00 +00:00
|
|
|
switch (av_get_packed_sample_fmt(c->sample_fmt)) {
|
2013-07-19 15:23:42 +00:00
|
|
|
case AV_SAMPLE_FMT_U8:
|
|
|
|
|
specs.format = AUD_FORMAT_U8;
|
|
|
|
|
break;
|
|
|
|
|
case AV_SAMPLE_FMT_S16:
|
|
|
|
|
specs.format = AUD_FORMAT_S16;
|
|
|
|
|
break;
|
|
|
|
|
case AV_SAMPLE_FMT_S32:
|
|
|
|
|
specs.format = AUD_FORMAT_S32;
|
|
|
|
|
break;
|
|
|
|
|
case AV_SAMPLE_FMT_FLT:
|
|
|
|
|
specs.format = AUD_FORMAT_FLOAT32;
|
|
|
|
|
break;
|
|
|
|
|
case AV_SAMPLE_FMT_DBL:
|
|
|
|
|
specs.format = AUD_FORMAT_FLOAT64;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return -31415;
|
2012-11-21 11:57:35 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-09-20 14:00:00 +00:00
|
|
|
specs.rate = rd->ffcodecdata.audio_mixrate;
|
2015-04-06 10:40:12 -03:00
|
|
|
context->audio_mixdown_device = BKE_sound_mixdown(
|
|
|
|
|
scene, specs, preview ? rd->psfra : rd->sfra, rd->ffcodecdata.audio_volume);
|
2009-08-09 21:16:39 +00:00
|
|
|
}
|
2011-06-23 16:10:48 +00:00
|
|
|
# endif
|
2009-12-22 12:01:32 +00:00
|
|
|
return success;
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
|
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
static void end_ffmpeg_impl(FFMpegContext *context, int is_autosplit);
|
2006-02-05 19:14:46 +00:00
|
|
|
|
2011-06-23 16:10:48 +00:00
|
|
|
# ifdef WITH_AUDASPACE
|
2015-04-06 10:40:12 -03:00
|
|
|
static void write_audio_frames(FFMpegContext *context, double to_pts)
|
2007-01-28 18:45:53 +00:00
|
|
|
{
|
2021-07-05 14:16:02 +02:00
|
|
|
AVCodecContext *c = context->audio_codec;
|
2007-01-28 18:45:53 +00:00
|
|
|
|
2021-07-05 14:16:02 +02:00
|
|
|
while (context->audio_stream) {
|
2021-12-14 01:16:24 +01:00
|
|
|
if ((context->audio_time_total >= to_pts) || !write_audio_frame(context)) {
|
2021-07-05 14:16:02 +02:00
|
|
|
break;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2023-11-30 16:42:39 +11:00
|
|
|
context->audio_time_total += double(context->audio_input_samples) / double(c->sample_rate);
|
|
|
|
|
context->audio_time += double(context->audio_input_samples) / double(c->sample_rate);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
2015-04-06 10:40:12 -03:00
|
|
|
# endif
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-02-21 12:57:36 +01:00
|
|
|
bool BKE_ffmpeg_append(void *context_v,
|
|
|
|
|
RenderData *rd,
|
|
|
|
|
int start_frame,
|
|
|
|
|
int frame,
|
|
|
|
|
const ImBuf *image,
|
|
|
|
|
const char *suffix,
|
|
|
|
|
ReportList *reports)
|
2006-02-05 19:14:46 +00:00
|
|
|
{
|
2023-11-30 06:03:18 +01:00
|
|
|
FFMpegContext *context = static_cast<FFMpegContext *>(context_v);
|
2012-05-12 16:11:34 +00:00
|
|
|
AVFrame *avframe;
|
2024-02-21 12:57:36 +01:00
|
|
|
bool success = true;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-02-21 12:57:36 +01:00
|
|
|
PRINT("Writing frame %i, render width=%d, render height=%d\n", frame, image->x, image->y);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
if (context->video_stream) {
|
2024-02-21 12:57:36 +01:00
|
|
|
avframe = generate_video_frame(context, image);
|
2021-12-14 01:16:24 +01:00
|
|
|
success = (avframe && write_video_frame(context, avframe, reports));
|
|
|
|
|
# ifdef WITH_AUDASPACE
|
|
|
|
|
/* Add +1 frame because we want to encode audio up until the next video frame. */
|
|
|
|
|
write_audio_frames(
|
2023-11-30 16:42:39 +11:00
|
|
|
context, (frame - start_frame + 1) / (double(rd->frs_sec) / double(rd->frs_sec_base)));
|
2022-01-14 11:55:36 +01:00
|
|
|
# else
|
|
|
|
|
UNUSED_VARS(start_frame);
|
2021-12-14 01:16:24 +01:00
|
|
|
# endif
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
if (context->ffmpeg_autosplit) {
|
|
|
|
|
if (avio_tell(context->outfile->pb) > FFMPEG_AUTOSPLIT_SIZE) {
|
|
|
|
|
end_ffmpeg_impl(context, true);
|
|
|
|
|
context->ffmpeg_autosplit_count++;
|
2021-12-14 01:16:24 +01:00
|
|
|
|
2024-02-21 12:57:36 +01:00
|
|
|
success &= start_ffmpeg_impl(context, rd, image->x, image->y, suffix, reports);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2010-02-07 23:41:17 +00:00
|
|
|
}
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-12-22 12:01:32 +00:00
|
|
|
return success;
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
|
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
static void end_ffmpeg_impl(FFMpegContext *context, int is_autosplit)
|
2006-02-05 19:14:46 +00:00
|
|
|
{
|
2023-12-07 12:15:45 +11:00
|
|
|
PRINT("Closing FFMPEG...\n");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-06-23 16:10:48 +00:00
|
|
|
# ifdef WITH_AUDASPACE
|
2014-04-01 11:34:00 +11:00
|
|
|
if (is_autosplit == false) {
|
2015-04-06 10:40:12 -03:00
|
|
|
if (context->audio_mixdown_device) {
|
2014-11-13 00:33:28 +13:00
|
|
|
AUD_Device_free(context->audio_mixdown_device);
|
2023-11-30 16:42:39 +11:00
|
|
|
context->audio_mixdown_device = nullptr;
|
2012-09-06 03:08:47 +00:00
|
|
|
}
|
2009-08-09 21:16:39 +00:00
|
|
|
}
|
2021-05-10 16:16:29 +10:00
|
|
|
# else
|
|
|
|
|
UNUSED_VARS(is_autosplit);
|
2011-06-23 16:10:48 +00:00
|
|
|
# endif
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-05-07 17:10:03 +02:00
|
|
|
if (context->video_stream) {
|
2021-07-05 14:16:02 +02:00
|
|
|
PRINT("Flushing delayed video frames...\n");
|
|
|
|
|
flush_ffmpeg(context->video_codec, context->video_stream, context->outfile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (context->audio_stream) {
|
|
|
|
|
PRINT("Flushing delayed audio frames...\n");
|
|
|
|
|
flush_ffmpeg(context->audio_codec, context->audio_stream, context->outfile);
|
2010-09-27 07:37:36 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
if (context->outfile) {
|
|
|
|
|
av_write_trailer(context->outfile);
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2006-02-05 19:14:46 +00:00
|
|
|
/* Close the video codec */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-11-30 16:42:39 +11:00
|
|
|
if (context->video_stream != nullptr) {
|
2015-04-06 10:40:12 -03:00
|
|
|
PRINT("zero video stream %p\n", context->video_stream);
|
2023-11-30 16:42:39 +11:00
|
|
|
context->video_stream = nullptr;
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-11-30 16:42:39 +11:00
|
|
|
if (context->audio_stream != nullptr) {
|
|
|
|
|
context->audio_stream = nullptr;
|
2015-10-23 18:36:46 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2006-02-05 19:14:46 +00:00
|
|
|
/* free the temp buffer */
|
2023-11-30 16:42:39 +11:00
|
|
|
if (context->current_frame != nullptr) {
|
2015-04-06 10:40:12 -03:00
|
|
|
delete_picture(context->current_frame);
|
2023-11-30 16:42:39 +11:00
|
|
|
context->current_frame = nullptr;
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
2023-11-30 16:42:39 +11:00
|
|
|
if (context->img_convert_frame != nullptr) {
|
2019-08-01 13:01:53 +02:00
|
|
|
delete_picture(context->img_convert_frame);
|
2023-11-30 16:42:39 +11:00
|
|
|
context->img_convert_frame = nullptr;
|
2019-08-01 13:01:53 +02:00
|
|
|
}
|
|
|
|
|
|
2023-12-17 16:04:44 +11:00
|
|
|
if (context->outfile != nullptr && context->outfile->oformat) {
|
2015-04-06 10:40:12 -03:00
|
|
|
if (!(context->outfile->oformat->flags & AVFMT_NOFILE)) {
|
|
|
|
|
avio_close(context->outfile->pb);
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
|
|
|
|
}
|
2021-05-07 17:10:03 +02:00
|
|
|
|
2023-11-30 16:42:39 +11:00
|
|
|
if (context->video_codec != nullptr) {
|
2021-05-07 17:10:03 +02:00
|
|
|
avcodec_free_context(&context->video_codec);
|
2023-11-30 16:42:39 +11:00
|
|
|
context->video_codec = nullptr;
|
2021-05-07 17:10:03 +02:00
|
|
|
}
|
2023-11-30 16:42:39 +11:00
|
|
|
if (context->audio_codec != nullptr) {
|
2021-05-07 17:10:03 +02:00
|
|
|
avcodec_free_context(&context->audio_codec);
|
2023-11-30 16:42:39 +11:00
|
|
|
context->audio_codec = nullptr;
|
2021-05-07 17:10:03 +02:00
|
|
|
}
|
|
|
|
|
|
2023-11-30 16:42:39 +11:00
|
|
|
if (context->outfile != nullptr) {
|
2015-09-22 21:09:39 +05:00
|
|
|
avformat_free_context(context->outfile);
|
2023-11-30 16:42:39 +11:00
|
|
|
context->outfile = nullptr;
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
2023-11-30 16:42:39 +11:00
|
|
|
if (context->audio_input_buffer != nullptr) {
|
2015-04-06 10:40:12 -03:00
|
|
|
av_free(context->audio_input_buffer);
|
2023-11-30 16:42:39 +11:00
|
|
|
context->audio_input_buffer = nullptr;
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-11-30 16:42:39 +11:00
|
|
|
if (context->audio_deinterleave_buffer != nullptr) {
|
2015-04-06 10:40:12 -03:00
|
|
|
av_free(context->audio_deinterleave_buffer);
|
2023-11-30 16:42:39 +11:00
|
|
|
context->audio_deinterleave_buffer = nullptr;
|
2013-04-01 15:31:27 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-11-30 16:42:39 +11:00
|
|
|
if (context->img_convert_ctx != nullptr) {
|
2024-02-15 10:35:02 +01:00
|
|
|
BKE_ffmpeg_sws_release_context(context->img_convert_ctx);
|
2023-11-30 16:42:39 +11:00
|
|
|
context->img_convert_ctx = nullptr;
|
2007-09-23 14:05:22 +00:00
|
|
|
}
|
2006-02-05 19:14:46 +00:00
|
|
|
}
|
2.5: Render
* UI layout for scene buttons has quite some changes, I tried to
better organize things according to the pipeline, and also showing
important properties by default, and collapsing less important ones.
Some changes compared to 2.4x:
* Panorama is now a Camera property.
* Sequence and Compositing are now enabled by default, but will only
do something when there is a node tree using nodes, or a strip in the
sequence editor.
* Enabling Full Sample now automatically enables Save Buffers too.
* Stamp option to include info in file is removed, it now simply always
does this if one of the stamp infos is enabled.
* Xvid, H.264 and Ogg Theora are now directly in the file format menu,
but still using FFMPEG. Unfortunately Ogg is broken at the moment
(also in 2.4x), so that's disabled. And Xvid crashes on 64bit linux,
maybe solvable by upgrading extern/xvidcore/, using ubuntu libs makes
it work.
* Organized file format menu by image/movie types.
Added:
* Render layers RNA wrapped, operatorized, layouted.
* FFMPEG format/codec options are now working.
Defaults changed:
* Compositing & Sequencer enabled.
* Tiles set to 8x8.
* Time/Date/Frame/Scene/Camera/Filename enabled for stamp.
2009-07-13 19:09:13 +00:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
void BKE_ffmpeg_end(void *context_v)
|
2012-09-06 03:08:47 +00:00
|
|
|
{
|
2023-11-30 06:03:18 +01:00
|
|
|
FFMpegContext *context = static_cast<FFMpegContext *>(context_v);
|
2015-04-06 10:40:12 -03:00
|
|
|
end_ffmpeg_impl(context, false);
|
2012-09-06 03:08:47 +00:00
|
|
|
}
|
|
|
|
|
|
2012-05-07 09:30:15 +00:00
|
|
|
void BKE_ffmpeg_preset_set(RenderData *rd, int preset)
|
2.5: Render
* UI layout for scene buttons has quite some changes, I tried to
better organize things according to the pipeline, and also showing
important properties by default, and collapsing less important ones.
Some changes compared to 2.4x:
* Panorama is now a Camera property.
* Sequence and Compositing are now enabled by default, but will only
do something when there is a node tree using nodes, or a strip in the
sequence editor.
* Enabling Full Sample now automatically enables Save Buffers too.
* Stamp option to include info in file is removed, it now simply always
does this if one of the stamp infos is enabled.
* Xvid, H.264 and Ogg Theora are now directly in the file format menu,
but still using FFMPEG. Unfortunately Ogg is broken at the moment
(also in 2.4x), so that's disabled. And Xvid crashes on 64bit linux,
maybe solvable by upgrading extern/xvidcore/, using ubuntu libs makes
it work.
* Organized file format menu by image/movie types.
Added:
* Render layers RNA wrapped, operatorized, layouted.
* FFMPEG format/codec options are now working.
Defaults changed:
* Compositing & Sequencer enabled.
* Tiles set to 8x8.
* Time/Date/Frame/Scene/Camera/Filename enabled for stamp.
2009-07-13 19:09:13 +00:00
|
|
|
{
|
2022-02-18 18:20:06 +01:00
|
|
|
bool is_ntsc = (rd->frs_sec != 25);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2.5: Render
* UI layout for scene buttons has quite some changes, I tried to
better organize things according to the pipeline, and also showing
important properties by default, and collapsing less important ones.
Some changes compared to 2.4x:
* Panorama is now a Camera property.
* Sequence and Compositing are now enabled by default, but will only
do something when there is a node tree using nodes, or a strip in the
sequence editor.
* Enabling Full Sample now automatically enables Save Buffers too.
* Stamp option to include info in file is removed, it now simply always
does this if one of the stamp infos is enabled.
* Xvid, H.264 and Ogg Theora are now directly in the file format menu,
but still using FFMPEG. Unfortunately Ogg is broken at the moment
(also in 2.4x), so that's disabled. And Xvid crashes on 64bit linux,
maybe solvable by upgrading extern/xvidcore/, using ubuntu libs makes
it work.
* Organized file format menu by image/movie types.
Added:
* Render layers RNA wrapped, operatorized, layouted.
* FFMPEG format/codec options are now working.
Defaults changed:
* Compositing & Sequencer enabled.
* Tiles set to 8x8.
* Time/Date/Frame/Scene/Camera/Filename enabled for stamp.
2009-07-13 19:09:13 +00:00
|
|
|
switch (preset) {
|
2012-05-12 16:11:34 +00:00
|
|
|
case FFMPEG_PRESET_H264:
|
2.5: Render
* UI layout for scene buttons has quite some changes, I tried to
better organize things according to the pipeline, and also showing
important properties by default, and collapsing less important ones.
Some changes compared to 2.4x:
* Panorama is now a Camera property.
* Sequence and Compositing are now enabled by default, but will only
do something when there is a node tree using nodes, or a strip in the
sequence editor.
* Enabling Full Sample now automatically enables Save Buffers too.
* Stamp option to include info in file is removed, it now simply always
does this if one of the stamp infos is enabled.
* Xvid, H.264 and Ogg Theora are now directly in the file format menu,
but still using FFMPEG. Unfortunately Ogg is broken at the moment
(also in 2.4x), so that's disabled. And Xvid crashes on 64bit linux,
maybe solvable by upgrading extern/xvidcore/, using ubuntu libs makes
it work.
* Organized file format menu by image/movie types.
Added:
* Render layers RNA wrapped, operatorized, layouted.
* FFMPEG format/codec options are now working.
Defaults changed:
* Compositing & Sequencer enabled.
* Tiles set to 8x8.
* Time/Date/Frame/Scene/Camera/Filename enabled for stamp.
2009-07-13 19:09:13 +00:00
|
|
|
rd->ffcodecdata.type = FFMPEG_AVI;
|
2014-01-16 15:40:37 +01:00
|
|
|
rd->ffcodecdata.codec = AV_CODEC_ID_H264;
|
2012-05-12 16:11:34 +00:00
|
|
|
rd->ffcodecdata.video_bitrate = 6000;
|
2022-02-18 18:20:06 +01:00
|
|
|
rd->ffcodecdata.gop_size = is_ntsc ? 18 : 15;
|
2012-05-12 16:11:34 +00:00
|
|
|
rd->ffcodecdata.rc_max_rate = 9000;
|
|
|
|
|
rd->ffcodecdata.rc_min_rate = 0;
|
|
|
|
|
rd->ffcodecdata.rc_buffer_size = 224 * 8;
|
|
|
|
|
rd->ffcodecdata.mux_packet_size = 2048;
|
|
|
|
|
rd->ffcodecdata.mux_rate = 10080000;
|
|
|
|
|
break;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-12 16:11:34 +00:00
|
|
|
case FFMPEG_PRESET_THEORA:
|
|
|
|
|
case FFMPEG_PRESET_XVID:
|
|
|
|
|
if (preset == FFMPEG_PRESET_XVID) {
|
|
|
|
|
rd->ffcodecdata.type = FFMPEG_AVI;
|
2014-01-16 15:40:37 +01:00
|
|
|
rd->ffcodecdata.codec = AV_CODEC_ID_MPEG4;
|
2012-05-12 16:11:34 +00:00
|
|
|
}
|
|
|
|
|
else if (preset == FFMPEG_PRESET_THEORA) {
|
|
|
|
|
rd->ffcodecdata.type = FFMPEG_OGG; /* XXX broken */
|
2014-01-16 15:40:37 +01:00
|
|
|
rd->ffcodecdata.codec = AV_CODEC_ID_THEORA;
|
2012-05-12 16:11:34 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-12 16:11:34 +00:00
|
|
|
rd->ffcodecdata.video_bitrate = 6000;
|
2022-02-18 18:20:06 +01:00
|
|
|
rd->ffcodecdata.gop_size = is_ntsc ? 18 : 15;
|
2012-05-12 16:11:34 +00:00
|
|
|
rd->ffcodecdata.rc_max_rate = 9000;
|
|
|
|
|
rd->ffcodecdata.rc_min_rate = 0;
|
|
|
|
|
rd->ffcodecdata.rc_buffer_size = 224 * 8;
|
|
|
|
|
rd->ffcodecdata.mux_packet_size = 2048;
|
|
|
|
|
rd->ffcodecdata.mux_rate = 10080000;
|
Video rendering: FFMpeg AV1 codec encoding support
Previously, the Blender video renderer did not have support for
encoding video to AV1 (not to be confused with the container AVI).
The proposed solution is to leverage the existing FFMpeg renderer
to encode to AV1.
Note that avcodec_find_encoder(AV_CODEC_ID_AV1) usually returns
"libaom-av1" which is the "reference implementation" for AV1 encoding
(the default for FFMpeg, and is slow). "libsvtav1" is faster and
preferred so there is extra handling when fetching the AV1 codec for
encoding such that "libsvtav1" is used when possible.
This commit should only affect the options available for video
rendering, which includes the additional AV1 codec to choose from, and
setting "-crf".
Also note that the current release of FFMpeg for ArchLinux does not
support "-crf" for "libsvtav1", but the equivalent option "-qp" is
supported and used as a fallback when "libsvtav1" is used (as
mentioned here: https://trac.ffmpeg.org/wiki/Encode/AV1#SVT-AV1 ).
(Actually, both "-crf" and "-qp" is specified with the same value in
the code. When a release of FFMpeg obtains support for "-crf" for
"libsvtav1" is released, the code shouldn't be needed to change.)
The usage of the AV1 codec should be very similar to the usage of the
H264 codec, but is limited to the "mp4" and "mkv" containers.
This patch pertains to the "VFX & Video" module, as its main purpose
is to supplement the Video Sequencer tool with the additional AV1
codec for encoded video output.
Differential Revision: https://developer.blender.org/D14920
Reviewed By: sergey , ISS, zeddb
2022-10-21 20:10:17 -06:00
|
|
|
break;
|
2024-02-12 09:45:13 +01:00
|
|
|
|
Video rendering: FFMpeg AV1 codec encoding support
Previously, the Blender video renderer did not have support for
encoding video to AV1 (not to be confused with the container AVI).
The proposed solution is to leverage the existing FFMpeg renderer
to encode to AV1.
Note that avcodec_find_encoder(AV_CODEC_ID_AV1) usually returns
"libaom-av1" which is the "reference implementation" for AV1 encoding
(the default for FFMpeg, and is slow). "libsvtav1" is faster and
preferred so there is extra handling when fetching the AV1 codec for
encoding such that "libsvtav1" is used when possible.
This commit should only affect the options available for video
rendering, which includes the additional AV1 codec to choose from, and
setting "-crf".
Also note that the current release of FFMpeg for ArchLinux does not
support "-crf" for "libsvtav1", but the equivalent option "-qp" is
supported and used as a fallback when "libsvtav1" is used (as
mentioned here: https://trac.ffmpeg.org/wiki/Encode/AV1#SVT-AV1 ).
(Actually, both "-crf" and "-qp" is specified with the same value in
the code. When a release of FFMpeg obtains support for "-crf" for
"libsvtav1" is released, the code shouldn't be needed to change.)
The usage of the AV1 codec should be very similar to the usage of the
H264 codec, but is limited to the "mp4" and "mkv" containers.
This patch pertains to the "VFX & Video" module, as its main purpose
is to supplement the Video Sequencer tool with the additional AV1
codec for encoded video output.
Differential Revision: https://developer.blender.org/D14920
Reviewed By: sergey , ISS, zeddb
2022-10-21 20:10:17 -06:00
|
|
|
case FFMPEG_PRESET_AV1:
|
|
|
|
|
rd->ffcodecdata.type = FFMPEG_AV1;
|
|
|
|
|
rd->ffcodecdata.codec = AV_CODEC_ID_AV1;
|
|
|
|
|
rd->ffcodecdata.video_bitrate = 6000;
|
|
|
|
|
rd->ffcodecdata.gop_size = is_ntsc ? 18 : 15;
|
|
|
|
|
rd->ffcodecdata.rc_max_rate = 9000;
|
|
|
|
|
rd->ffcodecdata.rc_min_rate = 0;
|
|
|
|
|
rd->ffcodecdata.rc_buffer_size = 224 * 8;
|
|
|
|
|
rd->ffcodecdata.mux_packet_size = 2048;
|
|
|
|
|
rd->ffcodecdata.mux_rate = 10080000;
|
2012-05-12 16:11:34 +00:00
|
|
|
break;
|
2.5: Render
* UI layout for scene buttons has quite some changes, I tried to
better organize things according to the pipeline, and also showing
important properties by default, and collapsing less important ones.
Some changes compared to 2.4x:
* Panorama is now a Camera property.
* Sequence and Compositing are now enabled by default, but will only
do something when there is a node tree using nodes, or a strip in the
sequence editor.
* Enabling Full Sample now automatically enables Save Buffers too.
* Stamp option to include info in file is removed, it now simply always
does this if one of the stamp infos is enabled.
* Xvid, H.264 and Ogg Theora are now directly in the file format menu,
but still using FFMPEG. Unfortunately Ogg is broken at the moment
(also in 2.4x), so that's disabled. And Xvid crashes on 64bit linux,
maybe solvable by upgrading extern/xvidcore/, using ubuntu libs makes
it work.
* Organized file format menu by image/movie types.
Added:
* Render layers RNA wrapped, operatorized, layouted.
* FFMPEG format/codec options are now working.
Defaults changed:
* Compositing & Sequencer enabled.
* Tiles set to 8x8.
* Time/Date/Frame/Scene/Camera/Filename enabled for stamp.
2009-07-13 19:09:13 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-14 21:27:58 -07:00
|
|
|
void BKE_ffmpeg_image_type_verify(RenderData *rd, const ImageFormatData *imf)
|
2.5: Render
* UI layout for scene buttons has quite some changes, I tried to
better organize things according to the pipeline, and also showing
important properties by default, and collapsing less important ones.
Some changes compared to 2.4x:
* Panorama is now a Camera property.
* Sequence and Compositing are now enabled by default, but will only
do something when there is a node tree using nodes, or a strip in the
sequence editor.
* Enabling Full Sample now automatically enables Save Buffers too.
* Stamp option to include info in file is removed, it now simply always
does this if one of the stamp infos is enabled.
* Xvid, H.264 and Ogg Theora are now directly in the file format menu,
but still using FFMPEG. Unfortunately Ogg is broken at the moment
(also in 2.4x), so that's disabled. And Xvid crashes on 64bit linux,
maybe solvable by upgrading extern/xvidcore/, using ubuntu libs makes
it work.
* Organized file format menu by image/movie types.
Added:
* Render layers RNA wrapped, operatorized, layouted.
* FFMPEG format/codec options are now working.
Defaults changed:
* Compositing & Sequencer enabled.
* Tiles set to 8x8.
* Time/Date/Frame/Scene/Camera/Filename enabled for stamp.
2009-07-13 19:09:13 +00:00
|
|
|
{
|
2012-05-12 16:11:34 +00:00
|
|
|
int audio = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:18:31 +00:00
|
|
|
if (imf->imtype == R_IMF_IMTYPE_FFMPEG) {
|
|
|
|
|
if (rd->ffcodecdata.type <= 0 || rd->ffcodecdata.codec <= 0 ||
|
2012-05-12 16:11:34 +00:00
|
|
|
rd->ffcodecdata.audio_codec <= 0 || rd->ffcodecdata.video_bitrate <= 1)
|
|
|
|
|
{
|
FFmpeg interface improvements
This patch changes a couple of things in the video output encoding.
{F362527}
- Clearer separation between container and codec. No more "format", as this is
too ambiguous. As a result, codecs were removed from the container list.
- Added FFmpeg speed presets, so the user can choosen from the range "Very
slow" to "Ultra fast". By default no preset is used.
- Added Constant Rate Factor (CRF) mode, which allows changing the bit-rate
depending on the desired quality and the input. This generally produces the
best quality videos, at the expense of not knowing the exact bit-rate and
file size.
- Added optional maximum of non-B-frames between B-frames (`max_b_frames`).
- Presets were adjusted for these changes, and new presets added. One of the
new presets is [recommended](https://trac.ffmpeg.org/wiki/Encode/VFX#H.264)
for reviewing videos, as it allows players to scrub through it easily. Might
be nice in weeklies. This preset also requires control over the
`max_b_frames` setting.
GUI-only changes:
- Renamed "MPEG" in the output file format menu with "FFmpeg", as this is more
accurate. After all, FFmpeg is used when this option is chosen, which can
also output non-MPEG files.
- Certain parts of the GUI are disabled when not in use:
- bit rate options are not used when a constant rate factor is given.
- audio bitrate & volume are not used when no audio is exported.
Note that I did not touch `BKE_ffmpeg_preset_set()`. There are currently two
preset systems for FFmpeg (`BKE_ffmpeg_preset_set()` and the Python preset
system). Before we do more work on `BKE_ffmpeg_preset_set()`, I think it's a
good idea to determine whether we want to keep it at all.
After this patch has been accepted, I'd be happy to go through the code and
remove any then-obsolete bits, such as the handling of "XVID" as a container
format.
Reviewers: sergey, mont29, brecht
Subscribers: mpan3, Blendify, brecht, fsiddi
Tags: #bf_blender
Differential Revision: https://developer.blender.org/D2242
2016-09-21 15:01:51 +02:00
|
|
|
BKE_ffmpeg_preset_set(rd, FFMPEG_PRESET_H264);
|
|
|
|
|
rd->ffcodecdata.constant_rate_factor = FFM_CRF_MEDIUM;
|
2018-04-09 15:27:11 +02:00
|
|
|
rd->ffcodecdata.ffmpeg_preset = FFM_PRESET_GOOD;
|
FFmpeg interface improvements
This patch changes a couple of things in the video output encoding.
{F362527}
- Clearer separation between container and codec. No more "format", as this is
too ambiguous. As a result, codecs were removed from the container list.
- Added FFmpeg speed presets, so the user can choosen from the range "Very
slow" to "Ultra fast". By default no preset is used.
- Added Constant Rate Factor (CRF) mode, which allows changing the bit-rate
depending on the desired quality and the input. This generally produces the
best quality videos, at the expense of not knowing the exact bit-rate and
file size.
- Added optional maximum of non-B-frames between B-frames (`max_b_frames`).
- Presets were adjusted for these changes, and new presets added. One of the
new presets is [recommended](https://trac.ffmpeg.org/wiki/Encode/VFX#H.264)
for reviewing videos, as it allows players to scrub through it easily. Might
be nice in weeklies. This preset also requires control over the
`max_b_frames` setting.
GUI-only changes:
- Renamed "MPEG" in the output file format menu with "FFmpeg", as this is more
accurate. After all, FFmpeg is used when this option is chosen, which can
also output non-MPEG files.
- Certain parts of the GUI are disabled when not in use:
- bit rate options are not used when a constant rate factor is given.
- audio bitrate & volume are not used when no audio is exported.
Note that I did not touch `BKE_ffmpeg_preset_set()`. There are currently two
preset systems for FFmpeg (`BKE_ffmpeg_preset_set()` and the Python preset
system). Before we do more work on `BKE_ffmpeg_preset_set()`, I think it's a
good idea to determine whether we want to keep it at all.
After this patch has been accepted, I'd be happy to go through the code and
remove any then-obsolete bits, such as the handling of "XVID" as a container
format.
Reviewers: sergey, mont29, brecht
Subscribers: mpan3, Blendify, brecht, fsiddi
Tags: #bf_blender
Differential Revision: https://developer.blender.org/D2242
2016-09-21 15:01:51 +02:00
|
|
|
rd->ffcodecdata.type = FFMPEG_MKV;
|
2.5: Render
* UI layout for scene buttons has quite some changes, I tried to
better organize things according to the pipeline, and also showing
important properties by default, and collapsing less important ones.
Some changes compared to 2.4x:
* Panorama is now a Camera property.
* Sequence and Compositing are now enabled by default, but will only
do something when there is a node tree using nodes, or a strip in the
sequence editor.
* Enabling Full Sample now automatically enables Save Buffers too.
* Stamp option to include info in file is removed, it now simply always
does this if one of the stamp infos is enabled.
* Xvid, H.264 and Ogg Theora are now directly in the file format menu,
but still using FFMPEG. Unfortunately Ogg is broken at the moment
(also in 2.4x), so that's disabled. And Xvid crashes on 64bit linux,
maybe solvable by upgrading extern/xvidcore/, using ubuntu libs makes
it work.
* Organized file format menu by image/movie types.
Added:
* Render layers RNA wrapped, operatorized, layouted.
* FFMPEG format/codec options are now working.
Defaults changed:
* Compositing & Sequencer enabled.
* Tiles set to 8x8.
* Time/Date/Frame/Scene/Camera/Filename enabled for stamp.
2009-07-13 19:09:13 +00:00
|
|
|
}
|
2012-03-24 06:18:31 +00:00
|
|
|
if (rd->ffcodecdata.type == FFMPEG_OGG) {
|
2011-08-10 07:36:44 +00:00
|
|
|
rd->ffcodecdata.type = FFMPEG_MPEG2;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-12 16:11:34 +00:00
|
|
|
audio = 1;
|
2.5: Render
* UI layout for scene buttons has quite some changes, I tried to
better organize things according to the pipeline, and also showing
important properties by default, and collapsing less important ones.
Some changes compared to 2.4x:
* Panorama is now a Camera property.
* Sequence and Compositing are now enabled by default, but will only
do something when there is a node tree using nodes, or a strip in the
sequence editor.
* Enabling Full Sample now automatically enables Save Buffers too.
* Stamp option to include info in file is removed, it now simply always
does this if one of the stamp infos is enabled.
* Xvid, H.264 and Ogg Theora are now directly in the file format menu,
but still using FFMPEG. Unfortunately Ogg is broken at the moment
(also in 2.4x), so that's disabled. And Xvid crashes on 64bit linux,
maybe solvable by upgrading extern/xvidcore/, using ubuntu libs makes
it work.
* Organized file format menu by image/movie types.
Added:
* Render layers RNA wrapped, operatorized, layouted.
* FFMPEG format/codec options are now working.
Defaults changed:
* Compositing & Sequencer enabled.
* Tiles set to 8x8.
* Time/Date/Frame/Scene/Camera/Filename enabled for stamp.
2009-07-13 19:09:13 +00:00
|
|
|
}
|
2012-03-24 06:18:31 +00:00
|
|
|
else if (imf->imtype == R_IMF_IMTYPE_H264) {
|
2014-01-16 15:40:37 +01:00
|
|
|
if (rd->ffcodecdata.codec != AV_CODEC_ID_H264) {
|
2012-05-07 09:30:15 +00:00
|
|
|
BKE_ffmpeg_preset_set(rd, FFMPEG_PRESET_H264);
|
2012-05-12 16:11:34 +00:00
|
|
|
audio = 1;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2.5: Render
* UI layout for scene buttons has quite some changes, I tried to
better organize things according to the pipeline, and also showing
important properties by default, and collapsing less important ones.
Some changes compared to 2.4x:
* Panorama is now a Camera property.
* Sequence and Compositing are now enabled by default, but will only
do something when there is a node tree using nodes, or a strip in the
sequence editor.
* Enabling Full Sample now automatically enables Save Buffers too.
* Stamp option to include info in file is removed, it now simply always
does this if one of the stamp infos is enabled.
* Xvid, H.264 and Ogg Theora are now directly in the file format menu,
but still using FFMPEG. Unfortunately Ogg is broken at the moment
(also in 2.4x), so that's disabled. And Xvid crashes on 64bit linux,
maybe solvable by upgrading extern/xvidcore/, using ubuntu libs makes
it work.
* Organized file format menu by image/movie types.
Added:
* Render layers RNA wrapped, operatorized, layouted.
* FFMPEG format/codec options are now working.
Defaults changed:
* Compositing & Sequencer enabled.
* Tiles set to 8x8.
* Time/Date/Frame/Scene/Camera/Filename enabled for stamp.
2009-07-13 19:09:13 +00:00
|
|
|
}
|
2012-03-24 06:18:31 +00:00
|
|
|
else if (imf->imtype == R_IMF_IMTYPE_XVID) {
|
2014-01-16 15:40:37 +01:00
|
|
|
if (rd->ffcodecdata.codec != AV_CODEC_ID_MPEG4) {
|
2012-05-07 09:30:15 +00:00
|
|
|
BKE_ffmpeg_preset_set(rd, FFMPEG_PRESET_XVID);
|
2012-05-12 16:11:34 +00:00
|
|
|
audio = 1;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2.5: Render
* UI layout for scene buttons has quite some changes, I tried to
better organize things according to the pipeline, and also showing
important properties by default, and collapsing less important ones.
Some changes compared to 2.4x:
* Panorama is now a Camera property.
* Sequence and Compositing are now enabled by default, but will only
do something when there is a node tree using nodes, or a strip in the
sequence editor.
* Enabling Full Sample now automatically enables Save Buffers too.
* Stamp option to include info in file is removed, it now simply always
does this if one of the stamp infos is enabled.
* Xvid, H.264 and Ogg Theora are now directly in the file format menu,
but still using FFMPEG. Unfortunately Ogg is broken at the moment
(also in 2.4x), so that's disabled. And Xvid crashes on 64bit linux,
maybe solvable by upgrading extern/xvidcore/, using ubuntu libs makes
it work.
* Organized file format menu by image/movie types.
Added:
* Render layers RNA wrapped, operatorized, layouted.
* FFMPEG format/codec options are now working.
Defaults changed:
* Compositing & Sequencer enabled.
* Tiles set to 8x8.
* Time/Date/Frame/Scene/Camera/Filename enabled for stamp.
2009-07-13 19:09:13 +00:00
|
|
|
}
|
2012-03-24 06:18:31 +00:00
|
|
|
else if (imf->imtype == R_IMF_IMTYPE_THEORA) {
|
2014-01-16 15:40:37 +01:00
|
|
|
if (rd->ffcodecdata.codec != AV_CODEC_ID_THEORA) {
|
2012-05-07 09:30:15 +00:00
|
|
|
BKE_ffmpeg_preset_set(rd, FFMPEG_PRESET_THEORA);
|
2012-05-12 16:11:34 +00:00
|
|
|
audio = 1;
|
2.5: Render
* UI layout for scene buttons has quite some changes, I tried to
better organize things according to the pipeline, and also showing
important properties by default, and collapsing less important ones.
Some changes compared to 2.4x:
* Panorama is now a Camera property.
* Sequence and Compositing are now enabled by default, but will only
do something when there is a node tree using nodes, or a strip in the
sequence editor.
* Enabling Full Sample now automatically enables Save Buffers too.
* Stamp option to include info in file is removed, it now simply always
does this if one of the stamp infos is enabled.
* Xvid, H.264 and Ogg Theora are now directly in the file format menu,
but still using FFMPEG. Unfortunately Ogg is broken at the moment
(also in 2.4x), so that's disabled. And Xvid crashes on 64bit linux,
maybe solvable by upgrading extern/xvidcore/, using ubuntu libs makes
it work.
* Organized file format menu by image/movie types.
Added:
* Render layers RNA wrapped, operatorized, layouted.
* FFMPEG format/codec options are now working.
Defaults changed:
* Compositing & Sequencer enabled.
* Tiles set to 8x8.
* Time/Date/Frame/Scene/Camera/Filename enabled for stamp.
2009-07-13 19:09:13 +00:00
|
|
|
}
|
|
|
|
|
}
|
Video rendering: FFMpeg AV1 codec encoding support
Previously, the Blender video renderer did not have support for
encoding video to AV1 (not to be confused with the container AVI).
The proposed solution is to leverage the existing FFMpeg renderer
to encode to AV1.
Note that avcodec_find_encoder(AV_CODEC_ID_AV1) usually returns
"libaom-av1" which is the "reference implementation" for AV1 encoding
(the default for FFMpeg, and is slow). "libsvtav1" is faster and
preferred so there is extra handling when fetching the AV1 codec for
encoding such that "libsvtav1" is used when possible.
This commit should only affect the options available for video
rendering, which includes the additional AV1 codec to choose from, and
setting "-crf".
Also note that the current release of FFMpeg for ArchLinux does not
support "-crf" for "libsvtav1", but the equivalent option "-qp" is
supported and used as a fallback when "libsvtav1" is used (as
mentioned here: https://trac.ffmpeg.org/wiki/Encode/AV1#SVT-AV1 ).
(Actually, both "-crf" and "-qp" is specified with the same value in
the code. When a release of FFMpeg obtains support for "-crf" for
"libsvtav1" is released, the code shouldn't be needed to change.)
The usage of the AV1 codec should be very similar to the usage of the
H264 codec, but is limited to the "mp4" and "mkv" containers.
This patch pertains to the "VFX & Video" module, as its main purpose
is to supplement the Video Sequencer tool with the additional AV1
codec for encoded video output.
Differential Revision: https://developer.blender.org/D14920
Reviewed By: sergey , ISS, zeddb
2022-10-21 20:10:17 -06:00
|
|
|
else if (imf->imtype == R_IMF_IMTYPE_AV1) {
|
|
|
|
|
if (rd->ffcodecdata.codec != AV_CODEC_ID_AV1) {
|
|
|
|
|
BKE_ffmpeg_preset_set(rd, FFMPEG_PRESET_AV1);
|
|
|
|
|
audio = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:18:31 +00:00
|
|
|
if (audio && rd->ffcodecdata.audio_codec < 0) {
|
2014-01-16 15:40:37 +01:00
|
|
|
rd->ffcodecdata.audio_codec = AV_CODEC_ID_NONE;
|
2.5: Render
* UI layout for scene buttons has quite some changes, I tried to
better organize things according to the pipeline, and also showing
important properties by default, and collapsing less important ones.
Some changes compared to 2.4x:
* Panorama is now a Camera property.
* Sequence and Compositing are now enabled by default, but will only
do something when there is a node tree using nodes, or a strip in the
sequence editor.
* Enabling Full Sample now automatically enables Save Buffers too.
* Stamp option to include info in file is removed, it now simply always
does this if one of the stamp infos is enabled.
* Xvid, H.264 and Ogg Theora are now directly in the file format menu,
but still using FFMPEG. Unfortunately Ogg is broken at the moment
(also in 2.4x), so that's disabled. And Xvid crashes on 64bit linux,
maybe solvable by upgrading extern/xvidcore/, using ubuntu libs makes
it work.
* Organized file format menu by image/movie types.
Added:
* Render layers RNA wrapped, operatorized, layouted.
* FFMPEG format/codec options are now working.
Defaults changed:
* Compositing & Sequencer enabled.
* Tiles set to 8x8.
* Time/Date/Frame/Scene/Camera/Filename enabled for stamp.
2009-07-13 19:09:13 +00:00
|
|
|
rd->ffcodecdata.audio_bitrate = 128;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-13 17:27:11 +11:00
|
|
|
bool BKE_ffmpeg_alpha_channel_is_supported(const RenderData *rd)
|
2012-02-24 09:49:44 +00:00
|
|
|
{
|
|
|
|
|
int codec = rd->ffcodecdata.codec;
|
2019-07-31 15:26:25 +02:00
|
|
|
|
2021-05-07 17:10:03 +02:00
|
|
|
return ELEM(codec,
|
|
|
|
|
AV_CODEC_ID_FFV1,
|
|
|
|
|
AV_CODEC_ID_QTRLE,
|
|
|
|
|
AV_CODEC_ID_PNG,
|
|
|
|
|
AV_CODEC_ID_VP9,
|
|
|
|
|
AV_CODEC_ID_HUFFYUV);
|
2012-02-24 09:49:44 +00:00
|
|
|
}
|
|
|
|
|
|
2023-11-30 16:42:39 +11:00
|
|
|
void *BKE_ffmpeg_context_create()
|
2015-04-06 10:40:12 -03:00
|
|
|
{
|
2023-12-07 12:15:45 +11:00
|
|
|
/* New FFMPEG data struct. */
|
2023-11-30 06:03:18 +01:00
|
|
|
FFMpegContext *context = static_cast<FFMpegContext *>(
|
2023-12-07 12:15:45 +11:00
|
|
|
MEM_callocN(sizeof(FFMpegContext), "new FFMPEG context"));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
context->ffmpeg_codec = AV_CODEC_ID_MPEG4;
|
|
|
|
|
context->ffmpeg_audio_codec = AV_CODEC_ID_NONE;
|
|
|
|
|
context->ffmpeg_video_bitrate = 1150;
|
|
|
|
|
context->ffmpeg_audio_bitrate = 128;
|
|
|
|
|
context->ffmpeg_gop_size = 12;
|
|
|
|
|
context->ffmpeg_autosplit = 0;
|
|
|
|
|
context->ffmpeg_autosplit_count = 0;
|
|
|
|
|
context->ffmpeg_preview = false;
|
2023-11-30 16:42:39 +11:00
|
|
|
context->stamp_data = nullptr;
|
2021-12-14 01:16:24 +01:00
|
|
|
context->audio_time_total = 0.0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
return context;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BKE_ffmpeg_context_free(void *context_v)
|
|
|
|
|
{
|
2023-11-30 06:03:18 +01:00
|
|
|
FFMpegContext *context = static_cast<FFMpegContext *>(context_v);
|
2023-11-30 16:42:39 +11:00
|
|
|
if (context == nullptr) {
|
2018-04-05 16:31:59 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (context->stamp_data) {
|
|
|
|
|
MEM_freeN(context->stamp_data);
|
2015-04-06 10:40:12 -03:00
|
|
|
}
|
2018-04-05 16:31:59 +02:00
|
|
|
MEM_freeN(context);
|
2015-04-06 10:40:12 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif /* WITH_FFMPEG */
|