From 8dcb1f4d12b809c46bccfc9e6e828447cd0d58d8 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 13 Jan 2012 12:34:23 +0000 Subject: Added Lossless Output option for h264 codec. This will fix #26943: render image to video problem --- source/blender/blenkernel/BKE_writeffmpeg.h | 1 + source/blender/blenkernel/intern/writeffmpeg.c | 99 +++++++++++++++----------- source/blender/makesdna/DNA_scene_types.h | 1 + source/blender/makesrna/intern/rna_scene.c | 21 +++++- 4 files changed, 80 insertions(+), 42 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/BKE_writeffmpeg.h b/source/blender/blenkernel/BKE_writeffmpeg.h index d1babc7ac9a..e99dece0f7c 100644 --- a/source/blender/blenkernel/BKE_writeffmpeg.h +++ b/source/blender/blenkernel/BKE_writeffmpeg.h @@ -74,6 +74,7 @@ void filepath_ffmpeg(char* string, struct RenderData* rd); extern void ffmpeg_set_preset(struct RenderData *rd, int preset); extern void ffmpeg_verify_image_type(struct RenderData *rd, struct ImageFormatData *imf); +extern void ffmpeg_verify_lossless_format(struct RenderData *rd, struct ImageFormatData *imf); extern struct IDProperty *ffmpeg_property_add(struct RenderData *Rd, const char *type, int opt_index, int parent_index); extern int ffmpeg_property_add_string(struct RenderData *rd, const char *type, const char *str); diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index 25b6a3faf0b..0b043e26ab7 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -1200,6 +1200,56 @@ int ffmpeg_property_add_string(RenderData *rd, const char * type, const char * s return 1; } +static void ffmpeg_set_expert_options(RenderData *rd, int preset) +{ + if(rd->ffcodecdata.properties) + IDP_FreeProperty(rd->ffcodecdata.properties); + + if(preset == FFMPEG_PRESET_H264) { + /* + * All options here are for x264, but must be set via ffmpeg. + * The names are therefore different - Search for "x264 to FFmpeg option mapping" + * to get a list. + */ + + /* + * Use CABAC coder. Using "coder:1", which should be equivalent, + * crashes Blender for some reason. Either way - this is no big deal. + */ + ffmpeg_property_add_string(rd, "video", "coder:vlc"); + + /* + * The other options were taken from the libx264-default.preset + * included in the ffmpeg distribution. + */ + ffmpeg_property_add_string(rd, "video", "flags:loop"); + ffmpeg_property_add_string(rd, "video", "cmp:chroma"); + ffmpeg_property_add_string(rd, "video", "partitions:parti4x4"); + ffmpeg_property_add_string(rd, "video", "partitions:partp8x8"); + ffmpeg_property_add_string(rd, "video", "partitions:partb8x8"); + ffmpeg_property_add_string(rd, "video", "me:hex"); + ffmpeg_property_add_string(rd, "video", "subq:6"); + ffmpeg_property_add_string(rd, "video", "me_range:16"); + ffmpeg_property_add_string(rd, "video", "qdiff:4"); + ffmpeg_property_add_string(rd, "video", "keyint_min:25"); + ffmpeg_property_add_string(rd, "video", "sc_threshold:40"); + ffmpeg_property_add_string(rd, "video", "i_qfactor:0.71"); + ffmpeg_property_add_string(rd, "video", "b_strategy:1"); + ffmpeg_property_add_string(rd, "video", "bf:3"); + ffmpeg_property_add_string(rd, "video", "refs:2"); + ffmpeg_property_add_string(rd, "video", "qcomp:0.6"); + ffmpeg_property_add_string(rd, "video", "directpred:3"); + ffmpeg_property_add_string(rd, "video", "trellis:0"); + ffmpeg_property_add_string(rd, "video", "flags2:wpred"); + ffmpeg_property_add_string(rd, "video", "flags2:dct8x8"); + ffmpeg_property_add_string(rd, "video", "flags2:fastpskip"); + ffmpeg_property_add_string(rd, "video", "wpredp:2"); + + if(rd->ffcodecdata.flags & FFMPEG_LOSSLESS_OUTPUT) + ffmpeg_property_add_string(rd, "video", "cqp:0"); + } +} + void ffmpeg_set_preset(RenderData *rd, int preset) { int isntsc = (rd->frs_sec != 25); @@ -1267,47 +1317,7 @@ void ffmpeg_set_preset(RenderData *rd, int preset) rd->ffcodecdata.mux_packet_size = 2048; rd->ffcodecdata.mux_rate = 10080000; - /* - * All options here are for x264, but must be set via ffmpeg. - * The names are therefore different - Search for "x264 to FFmpeg option mapping" - * to get a list. - */ - - /* - * Use CABAC coder. Using "coder:1", which should be equivalent, - * crashes Blender for some reason. Either way - this is no big deal. - */ - ffmpeg_property_add_string(rd, "video", "coder:vlc"); - - /* - * The other options were taken from the libx264-default.preset - * included in the ffmpeg distribution. - */ - ffmpeg_property_add_string(rd, "video", "flags:loop"); - ffmpeg_property_add_string(rd, "video", "cmp:chroma"); - ffmpeg_property_add_string(rd, "video", "partitions:parti4x4"); - ffmpeg_property_add_string(rd, "video", "partitions:partp8x8"); - ffmpeg_property_add_string(rd, "video", "partitions:partb8x8"); - ffmpeg_property_add_string(rd, "video", "me:hex"); - ffmpeg_property_add_string(rd, "video", "subq:6"); - ffmpeg_property_add_string(rd, "video", "me_range:16"); - ffmpeg_property_add_string(rd, "video", "qdiff:4"); - ffmpeg_property_add_string(rd, "video", "keyint_min:25"); - ffmpeg_property_add_string(rd, "video", "sc_threshold:40"); - ffmpeg_property_add_string(rd, "video", "i_qfactor:0.71"); - ffmpeg_property_add_string(rd, "video", "b_strategy:1"); - ffmpeg_property_add_string(rd, "video", "bf:3"); - ffmpeg_property_add_string(rd, "video", "refs:2"); - ffmpeg_property_add_string(rd, "video", "qcomp:0.6"); - ffmpeg_property_add_string(rd, "video", "directpred:3"); - ffmpeg_property_add_string(rd, "video", "trellis:0"); - ffmpeg_property_add_string(rd, "video", "flags2:wpred"); - ffmpeg_property_add_string(rd, "video", "flags2:dct8x8"); - ffmpeg_property_add_string(rd, "video", "flags2:fastpskip"); - ffmpeg_property_add_string(rd, "video", "wpredp:2"); - - // This makes x264 output lossless. Will be a separate option later. - //ffmpeg_property_add_string(rd, "video", "cqp:0"); + ffmpeg_set_expert_options(rd, preset); break; case FFMPEG_PRESET_THEORA: @@ -1378,4 +1388,11 @@ void ffmpeg_verify_image_type(RenderData *rd, ImageFormatData *imf) } } +void ffmpeg_verify_lossless_format(RenderData *rd, ImageFormatData *imf) +{ + if(imf->imtype == R_IMF_IMTYPE_H264) { + ffmpeg_set_expert_options(rd, FFMPEG_PRESET_H264); + } +} + #endif diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 505a9ee30ab..a2dfea11cdb 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1380,6 +1380,7 @@ typedef struct Scene { #define FFMPEG_MULTIPLEX_AUDIO 1 /* deprecated, you can choose none as audiocodec now */ #define FFMPEG_AUTOSPLIT_OUTPUT 2 +#define FFMPEG_LOSSLESS_OUTPUT 4 /* Paint.flags */ typedef enum { diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index ace4999e814..7ea0083d193 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -869,6 +869,19 @@ static EnumPropertyItem *rna_RenderSettings_qtcodecsettings_audiocodecType_itemf #endif #endif +static void rna_RenderSettings_ffmpegsettings_lossless_output_set(PointerRNA *ptr, int value) +{ + RenderData *rd = (RenderData*)ptr->data; + + if (value) + rd->ffcodecdata.flags |= FFMPEG_LOSSLESS_OUTPUT; + else + rd->ffcodecdata.flags &= ~FFMPEG_LOSSLESS_OUTPUT; +#ifdef WITH_FFMPEG + ffmpeg_verify_lossless_format(rd, &rd->im_format); +#endif +} + static int rna_RenderSettings_active_layer_index_get(PointerRNA *ptr) { RenderData *rd= (RenderData*)ptr->data; @@ -2996,7 +3009,13 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "ffcodecdata.flags", FFMPEG_AUTOSPLIT_OUTPUT); RNA_def_property_ui_text(prop, "Autosplit Output", "Autosplit output at 2GB boundary"); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - + + prop= RNA_def_property(srna, "ffmpeg_lossless_output", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "ffcodecdata.flags", FFMPEG_LOSSLESS_OUTPUT); + RNA_def_property_boolean_funcs(prop, NULL, "rna_RenderSettings_ffmpegsettings_lossless_output_set"); + RNA_def_property_ui_text(prop, "Lossless Output", "Use losslecc output for video streams"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + /* FFMPEG Audio*/ prop= RNA_def_property(srna, "ffmpeg_audio_codec", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "ffcodecdata.audio_codec"); -- cgit v1.2.3