Commit: a7e74791221e2ef9b44ee1b3eb9ece37785aa62a Author: Sybren A. Stüvel Date: Wed Sep 21 15:01:51 2016 +0200 Branches: master https://developer.blender.org/rBa7e74791221e2ef9b44ee1b3eb9ece37785aa62a
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 =================================================================== D release/scripts/presets/ffmpeg/DV.py R100 release/scripts/presets/ffmpeg/DVD.py release/scripts/presets/ffmpeg/DVD (note_colon_ this changes render resolution).py D release/scripts/presets/ffmpeg/SVCD.py D release/scripts/presets/ffmpeg/VCD.py A release/scripts/presets/ffmpeg/h264 in MP4.py A release/scripts/presets/ffmpeg/h264 in Matroska for scrubbing.py R091 release/scripts/presets/ffmpeg/h264.py release/scripts/presets/ffmpeg/h264 in Matroska.py R090 release/scripts/presets/ffmpeg/theora.py release/scripts/presets/ffmpeg/ogg_theora.py M release/scripts/presets/ffmpeg/xvid.py M release/scripts/startup/bl_ui/properties_render.py M source/blender/blenkernel/intern/image.c M source/blender/blenkernel/intern/writeffmpeg.c M source/blender/blenloader/intern/versioning_270.c M source/blender/makesdna/DNA_scene_types.h M source/blender/makesrna/intern/rna_scene.c =================================================================== diff --git a/release/scripts/presets/ffmpeg/DV.py b/release/scripts/presets/ffmpeg/DV.py deleted file mode 100644 index a95d861..0000000 --- a/release/scripts/presets/ffmpeg/DV.py +++ /dev/null @@ -1,14 +0,0 @@ -import bpy -is_ntsc = (bpy.context.scene.render.fps != 25) - -bpy.context.scene.render.ffmpeg.format = "DV" -bpy.context.scene.render.resolution_x = 720 - -if is_ntsc: - bpy.context.scene.render.resolution_y = 480 -else: - bpy.context.scene.render.resolution_y = 576 - -bpy.context.scene.render.ffmpeg.audio_mixrate = 48000 -bpy.context.scene.render.ffmpeg.audio_codec = "PCM" -bpy.context.scene.render.ffmpeg.audio_channels = "STEREO" diff --git a/release/scripts/presets/ffmpeg/DVD.py b/release/scripts/presets/ffmpeg/DVD (note_colon_ this changes render resolution).py similarity index 100% rename from release/scripts/presets/ffmpeg/DVD.py rename to release/scripts/presets/ffmpeg/DVD (note_colon_ this changes render resolution).py diff --git a/release/scripts/presets/ffmpeg/SVCD.py b/release/scripts/presets/ffmpeg/SVCD.py deleted file mode 100644 index deaf969..0000000 --- a/release/scripts/presets/ffmpeg/SVCD.py +++ /dev/null @@ -1,24 +0,0 @@ -import bpy -is_ntsc = (bpy.context.scene.render.fps != 25) - -bpy.context.scene.render.ffmpeg.format = "MPEG2" -bpy.context.scene.render.resolution_x = 480 - -if is_ntsc: - bpy.context.scene.render.resolution_y = 480 - bpy.context.scene.render.ffmpeg.gopsize = 18 -else: - bpy.context.scene.render.resolution_y = 576 - bpy.context.scene.render.ffmpeg.gopsize = 15 - -bpy.context.scene.render.ffmpeg.video_bitrate = 2040 -bpy.context.scene.render.ffmpeg.maxrate = 2516 -bpy.context.scene.render.ffmpeg.minrate = 0 -bpy.context.scene.render.ffmpeg.buffersize = 224 * 8 -bpy.context.scene.render.ffmpeg.packetsize = 2324 -bpy.context.scene.render.ffmpeg.muxrate = 0 - -bpy.context.scene.render.ffmpeg.audio_bitrate = 224 -bpy.context.scene.render.ffmpeg.audio_mixrate = 44100 -bpy.context.scene.render.ffmpeg.audio_codec = "MP2" -bpy.context.scene.render.ffmpeg.audio_channels = "STEREO" diff --git a/release/scripts/presets/ffmpeg/VCD.py b/release/scripts/presets/ffmpeg/VCD.py deleted file mode 100644 index 3e57be7..0000000 --- a/release/scripts/presets/ffmpeg/VCD.py +++ /dev/null @@ -1,24 +0,0 @@ -import bpy -is_ntsc = (bpy.context.scene.render.fps != 25) - -bpy.context.scene.render.ffmpeg.format = "MPEG1" -bpy.context.scene.render.resolution_x = 352 - -if is_ntsc: - bpy.context.scene.render.resolution_y = 240 - bpy.context.scene.render.ffmpeg.gopsize = 18 -else: - bpy.context.scene.render.resolution_y = 288 - bpy.context.scene.render.ffmpeg.gopsize = 15 - -bpy.context.scene.render.ffmpeg.video_bitrate = 1150 -bpy.context.scene.render.ffmpeg.maxrate = 1150 -bpy.context.scene.render.ffmpeg.minrate = 1150 -bpy.context.scene.render.ffmpeg.buffersize = 40 * 8 -bpy.context.scene.render.ffmpeg.packetsize = 2324 -bpy.context.scene.render.ffmpeg.muxrate = 2352 * 75 * 8 - -bpy.context.scene.render.ffmpeg.audio_bitrate = 224 -bpy.context.scene.render.ffmpeg.audio_mixrate = 44100 -bpy.context.scene.render.ffmpeg.audio_codec = "MP2" -bpy.context.scene.render.ffmpeg.audio_channels = "STEREO" diff --git a/release/scripts/presets/ffmpeg/h264.py b/release/scripts/presets/ffmpeg/h264 in MP4.py similarity index 83% copy from release/scripts/presets/ffmpeg/h264.py copy to release/scripts/presets/ffmpeg/h264 in MP4.py index e1dbdc1..0e9c32c 100644 --- a/release/scripts/presets/ffmpeg/h264.py +++ b/release/scripts/presets/ffmpeg/h264 in MP4.py @@ -1,13 +1,14 @@ import bpy is_ntsc = (bpy.context.scene.render.fps != 25) -bpy.context.scene.render.ffmpeg.format = "H264" +bpy.context.scene.render.ffmpeg.format = "MPEG4" bpy.context.scene.render.ffmpeg.codec = "H264" if is_ntsc: bpy.context.scene.render.ffmpeg.gopsize = 18 else: bpy.context.scene.render.ffmpeg.gopsize = 15 +bpy.context.scene.render.ffmpeg.use_max_b_frames = False bpy.context.scene.render.ffmpeg.video_bitrate = 6000 bpy.context.scene.render.ffmpeg.maxrate = 9000 diff --git a/release/scripts/presets/ffmpeg/h264 in Matroska for scrubbing.py b/release/scripts/presets/ffmpeg/h264 in Matroska for scrubbing.py new file mode 100644 index 0000000..eb1889d --- /dev/null +++ b/release/scripts/presets/ffmpeg/h264 in Matroska for scrubbing.py @@ -0,0 +1,14 @@ +"""Sets up FFmpeg to output files that can easily be scrubbed through. + +Information was taken from https://trac.ffmpeg.org/wiki/Encode/VFX#H.264 +""" + +import bpy + +bpy.context.scene.render.ffmpeg.format = "MKV" +bpy.context.scene.render.ffmpeg.codec = "H264" + +bpy.context.scene.render.ffmpeg.gopsize = 1 +bpy.context.scene.render.ffmpeg.constant_rate_factor = 'PERC_LOSSLESS' +bpy.context.scene.render.ffmpeg.use_max_b_frames = True +bpy.context.scene.render.ffmpeg.max_b_frames = 0 diff --git a/release/scripts/presets/ffmpeg/h264.py b/release/scripts/presets/ffmpeg/h264 in Matroska.py similarity index 91% rename from release/scripts/presets/ffmpeg/h264.py rename to release/scripts/presets/ffmpeg/h264 in Matroska.py index e1dbdc1..1fe066d 100644 --- a/release/scripts/presets/ffmpeg/h264.py +++ b/release/scripts/presets/ffmpeg/h264 in Matroska.py @@ -1,7 +1,7 @@ import bpy is_ntsc = (bpy.context.scene.render.fps != 25) -bpy.context.scene.render.ffmpeg.format = "H264" +bpy.context.scene.render.ffmpeg.format = "MKV" bpy.context.scene.render.ffmpeg.codec = "H264" if is_ntsc: diff --git a/release/scripts/presets/ffmpeg/theora.py b/release/scripts/presets/ffmpeg/ogg_theora.py similarity index 90% rename from release/scripts/presets/ffmpeg/theora.py rename to release/scripts/presets/ffmpeg/ogg_theora.py index 88f1ac9..b450b67 100644 --- a/release/scripts/presets/ffmpeg/theora.py +++ b/release/scripts/presets/ffmpeg/ogg_theora.py @@ -8,6 +8,7 @@ if is_ntsc: bpy.context.scene.render.ffmpeg.gopsize = 18 else: bpy.context.scene.render.ffmpeg.gopsize = 15 +bpy.context.scene.render.ffmpeg.use_max_b_frames = False bpy.context.scene.render.ffmpeg.video_bitrate = 6000 bpy.context.scene.render.ffmpeg.maxrate = 9000 diff --git a/release/scripts/presets/ffmpeg/xvid.py b/release/scripts/presets/ffmpeg/xvid.py index e69ab66..dba0f71 100644 --- a/release/scripts/presets/ffmpeg/xvid.py +++ b/release/scripts/presets/ffmpeg/xvid.py @@ -1,12 +1,14 @@ import bpy is_ntsc = (bpy.context.scene.render.fps != 25) -bpy.context.scene.render.ffmpeg.format = "XVID" +bpy.context.scene.render.ffmpeg.format = "AVI" +bpy.context.scene.render.ffmpeg.codec = "MPEG4" if is_ntsc: bpy.context.scene.render.ffmpeg.gopsize = 18 else: bpy.context.scene.render.ffmpeg.gopsize = 15 +bpy.context.scene.render.ffmpeg.use_max_b_frames = False bpy.context.scene.render.ffmpeg.video_bitrate = 6000 bpy.context.scene.render.ffmpeg.maxrate = 9000 diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index 152d4e9..850606e 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -461,31 +461,42 @@ class RENDER_PT_encoding(RenderButtonsPanel, Panel): split = layout.split() split.prop(rd.ffmpeg, "format") - if ffmpeg.format in {'AVI', 'QUICKTIME', 'MKV', 'OGG', 'MPEG4'}: - split.prop(ffmpeg, "codec") - if ffmpeg.codec == 'H264': - row = layout.row() - row.label() - row.prop(ffmpeg, "use_lossless_output") - elif rd.ffmpeg.format == 'H264': - split.prop(ffmpeg, "use_lossless_output") - else: - split.label() + split.prop(ffmpeg, "use_autosplit") + + layout.separator() + + needs_codec = ffmpeg.format in {'AVI', 'QUICKTIME', 'MKV', 'OGG', 'MPEG4'} + if needs_codec: + layout.prop(ffmpeg, "codec") + if ffmpeg.codec in {'DNXHD'}: + layout.prop(ffmpeg, "use_lossless_output") + + # Output quality + if needs_codec and ffmpeg.codec in {'H264', 'MPEG4'}: + layout.prop(ffmpeg, "constant_rate_factor") + + # Encoding speed + layout.prop(ffmpeg, "ffmpeg_preset") + # I-frames + layout.prop(ffmpeg, "gopsize") + # B-Frames row = layout.row() - row.prop(ffmpeg, "video_bitrate") - row.prop(ffmpeg, "gopsize") + row.prop(ffmpeg, "use_max_b_frames", text='Max B-frames') + pbox = row.split() + pbox.prop(ffmpeg, "max_b_frames", text='') + pbox.enabled = ffmpeg.use_max_b_frames split = layout.split() - + split.enabled = ffmpeg.constant_rate_factor == 'NONE' col = split.column() col.label(text="Rate:") + col.prop(ffmpeg, "video_bitrate") col.prop(ffmpeg, "minrate", text="Minimum") col.prop(ffmpeg, "maxrate", text="Maximum") col.prop(ffmpeg, "buffersize", text="Buffer") col = split.column() - col.prop(ffmpeg, "use_autosplit") col.label(text="Mux:") col.prop(ffmpeg, "muxrate", text="Rate") col.prop(ffmpeg, "packetsize", text="Packet Size") @@ -497,6 +508,7 @@ class RENDER_PT_encoding(RenderButtonsPanel, Panel): layout.prop(ffmpeg, "audio_codec", text="Audio Codec") row = layout.row() + row.enabled = ffmpeg.audio_codec != 'NONE' row.prop(ffmpeg, "audio_bitrate") row.prop(ffmpeg, "audio_volume", slider=True) diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 8a9cb73..a4eef2f 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -1325,7 +1325,7 @@ char BKE_imtype_from_arg(const char *imtype_arg) else if (STREQ(imtype_arg, "EXR")) return R_IMF_IMTYPE_OPENEXR; else if (STREQ(imtype_arg, "MULTILAYER")) return R_IMF_IMTYPE_MULTILAYER; #endif - else if (STREQ(imtype_arg, "MPEG")) return R_IMF_IMTYPE_FFMPEG; + else if (STREQ(imtype_arg, "FFMPEG")) return R_IMF_IMTYPE_FFMPEG; else if (STREQ(imtype_arg, "FRAMESERVER")) return R_IMF_IMTYPE_FRAMESERVER; #ifdef WITH_CINEON else if (STREQ(imtype_arg, "CINEON")) return R_IMF_IMTYPE_CINEON; diff - @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs