From 9049645d0fbb34fb00f283f7983f5151ecbbe245 Mon Sep 17 00:00:00 2001 From: Martin-Vignali Date: Thu, 8 May 2025 02:34:56 +0200 Subject: [PATCH] FFmpeg: Add support for 10/12 bits FFV1 output FFV1 supports more than 8 bits by pixel. Add support for 10 and 12 bit depth (FFV1 encoder uses planar pixel format for these bitdepths). Fix pixel format for 8 bit output. Previously it was always RGBA. Co-authored-by: mvji <33432858+mvji@users.noreply.github.com> Pull Request: https://projects.blender.org/blender/blender/pulls/138192 --- scripts/startup/bl_ui/properties_output.py | 2 +- .../blender/imbuf/movie/intern/movie_util.cc | 10 +++++-- .../blender/imbuf/movie/intern/movie_write.cc | 28 ++++++++++++++++++- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/scripts/startup/bl_ui/properties_output.py b/scripts/startup/bl_ui/properties_output.py index e2dfad2f6b3..adc5b4bde2f 100644 --- a/scripts/startup/bl_ui/properties_output.py +++ b/scripts/startup/bl_ui/properties_output.py @@ -531,7 +531,7 @@ class RENDER_PT_encoding_video(RenderOutputButtonsPanel, Panel): # Color depth. List of codecs needs to be in sync with # `IMB_ffmpeg_valid_bit_depths` in source code. - use_bpp = needs_codec and ffmpeg.codec in {'H264', 'H265', 'AV1', 'PRORES'} + use_bpp = needs_codec and ffmpeg.codec in {'H264', 'H265', 'AV1', 'PRORES', 'FFV1'} if use_bpp: image_settings = context.scene.render.image_settings layout.prop(image_settings, "color_depth", expand=True) diff --git a/source/blender/imbuf/movie/intern/movie_util.cc b/source/blender/imbuf/movie/intern/movie_util.cc index 05445502746..d4655d4beff 100644 --- a/source/blender/imbuf/movie/intern/movie_util.cc +++ b/source/blender/imbuf/movie/intern/movie_util.cc @@ -380,10 +380,16 @@ int MOV_codec_valid_bit_depths(int av_codec_id) int bit_depths = R_IMF_CHAN_DEPTH_8; #ifdef WITH_FFMPEG /* Note: update properties_output.py `use_bpp` when changing this function. */ - if (ELEM(av_codec_id, AV_CODEC_ID_H264, AV_CODEC_ID_H265, AV_CODEC_ID_AV1, AV_CODEC_ID_PRORES)) { + if (ELEM(av_codec_id, + AV_CODEC_ID_H264, + AV_CODEC_ID_H265, + AV_CODEC_ID_AV1, + AV_CODEC_ID_PRORES, + AV_CODEC_ID_FFV1)) + { bit_depths |= R_IMF_CHAN_DEPTH_10; } - if (ELEM(av_codec_id, AV_CODEC_ID_H265, AV_CODEC_ID_AV1)) { + if (ELEM(av_codec_id, AV_CODEC_ID_H265, AV_CODEC_ID_AV1, AV_CODEC_ID_FFV1)) { bit_depths |= R_IMF_CHAN_DEPTH_12; } #else diff --git a/source/blender/imbuf/movie/intern/movie_write.cc b/source/blender/imbuf/movie/intern/movie_write.cc index 0b010e91fe6..bede84ccc75 100644 --- a/source/blender/imbuf/movie/intern/movie_write.cc +++ b/source/blender/imbuf/movie/intern/movie_write.cc @@ -803,7 +803,33 @@ static AVStream *alloc_video_stream(MovieWriter *context, } if (codec_id == AV_CODEC_ID_FFV1) { - c->pix_fmt = AV_PIX_FMT_RGB32; + if (rd->im_format.planes == R_IMF_PLANES_BW) { + c->pix_fmt = AV_PIX_FMT_GRAY8; + if (is_10_bpp) { + c->pix_fmt = AV_PIX_FMT_GRAY10; + } + else if (is_12_bpp) { + c->pix_fmt = AV_PIX_FMT_GRAY12; + } + } + else if (rd->im_format.planes == R_IMF_PLANES_RGBA) { + c->pix_fmt = AV_PIX_FMT_RGB32; + if (is_10_bpp) { + c->pix_fmt = AV_PIX_FMT_GBRAP10; + } + else if (is_12_bpp) { + c->pix_fmt = AV_PIX_FMT_GBRAP12; + } + } + else { /* RGB */ + c->pix_fmt = AV_PIX_FMT_0RGB32; + if (is_10_bpp) { + c->pix_fmt = AV_PIX_FMT_GBRP10; + } + else if (is_12_bpp) { + c->pix_fmt = AV_PIX_FMT_GBRP12; + } + } } if (codec_id == AV_CODEC_ID_QTRLE) {