diff options
author | Peter Schlaile <peter@schlaile.de> | 2008-05-12 00:40:55 +0400 |
---|---|---|
committer | Peter Schlaile <peter@schlaile.de> | 2008-05-12 00:40:55 +0400 |
commit | c8673be3d6382bd49994c78347d17f8ef64744f5 (patch) | |
tree | aaf598f5d1178af83245f3cbac54913f80c5c4c8 /source/blender/blenkernel | |
parent | e459d5518ec2ac19e22e480e685ca8c1fbd318f8 (diff) |
== FFMPEG ==
Add ffmpeg expert option (meaning _all_ ffmpeg option) to render dialog
using properties.
Also adds: H264 preset, that doesn't screw up output.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_idprop.h | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_writeffmpeg.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/scene.c | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/writeffmpeg.c | 87 |
4 files changed, 95 insertions, 4 deletions
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h index 46252b310ae..2d7d0e9286f 100644 --- a/source/blender/blenkernel/BKE_idprop.h +++ b/source/blender/blenkernel/BKE_idprop.h @@ -171,4 +171,9 @@ void IDP_FreeProperty(struct IDProperty *prop); /*Unlinks any struct IDProperty<->ID linkage that might be going on.*/ void IDP_UnlinkProperty(struct IDProperty *prop); +#define IDP_Int(prop) (prop->data.val) +#define IDP_Float(prop) (*(float*)&prop->data.val) +#define IDP_String(prop) ((char*)prop->data.pointer) +#define IDP_Array(prop) (prop->data.pointer) + #endif /* _BKE_IDPROP_H */ diff --git a/source/blender/blenkernel/BKE_writeffmpeg.h b/source/blender/blenkernel/BKE_writeffmpeg.h index 844f25d51dc..86ad67f76b0 100644 --- a/source/blender/blenkernel/BKE_writeffmpeg.h +++ b/source/blender/blenkernel/BKE_writeffmpeg.h @@ -58,6 +58,7 @@ extern "C" { #define FFMPEG_PRESET_SVCD 2 #define FFMPEG_PRESET_VCD 3 #define FFMPEG_PRESET_DV 4 +#define FFMPEG_PRESET_H264 5 struct RenderData; diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 6798c3c47b7..2898dca767c 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -67,6 +67,7 @@ #include "BKE_global.h" #include "BKE_group.h" #include "BKE_ipo.h" +#include "BKE_idprop.h" #include "BKE_image.h" #include "BKE_key.h" #include "BKE_library.h" @@ -149,6 +150,11 @@ void free_scene(Scene *sce) MEM_freeN(sce->r.qtcodecdata); sce->r.qtcodecdata = NULL; } + if (sce->r.ffcodecdata.properties) { + IDP_FreeProperty(sce->r.ffcodecdata.properties); + MEM_freeN(sce->r.ffcodecdata.properties); + sce->r.ffcodecdata.properties = NULL; + } BLI_freelistN(&sce->markers); BLI_freelistN(&sce->transform_spaces); diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index e79e36a1498..61d598ba868 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -33,6 +33,7 @@ #include <ffmpeg/avcodec.h> #include <ffmpeg/rational.h> #include <ffmpeg/swscale.h> +#include <ffmpeg/opt.h> #if LIBAVFORMAT_VERSION_INT < (49 << 16) #define FFMPEG_OLD_FRAME_RATE 1 @@ -58,6 +59,7 @@ #include "BKE_bad_level_calls.h" #include "BKE_global.h" +#include "BKE_idprop.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -337,6 +339,75 @@ static AVFrame* generate_video_frame(uint8_t* pixels) return current_frame; } +static void set_ffmpeg_property_option(AVCodecContext* c, IDProperty * prop) +{ + char name[128]; + char * param; + + fprintf(stderr, "FFMPEG expert option: %s: ", prop->name); + + strncpy(name, prop->name, 128); + + param = strchr(name, ':'); + + if (param) { + *param++ = 0; + } + + const AVOption * rv = NULL; + switch(prop->type) { + case IDP_STRING: + fprintf(stderr, "%s.\n", IDP_String(prop)); + rv = av_set_string(c, prop->name, IDP_String(prop)); + break; + case IDP_FLOAT: + fprintf(stderr, "%g.\n", IDP_Float(prop)); + rv = av_set_double(c, prop->name, IDP_Float(prop)); + break; + case IDP_INT: + fprintf(stderr, "%d.\n", IDP_Int(prop)); + + if (param) { + if (IDP_Int(prop)) { + rv = av_set_string(c, name, param); + } else { + return; + } + } else { + rv = av_set_int(c, prop->name, IDP_Int(prop)); + } + break; + } + + if (!rv) { + fprintf(stderr, "ffmpeg-option not supported: %s! Skipping.\n", + prop->name); + } +} + +static void set_ffmpeg_properties(AVCodecContext* c, const char * prop_name) +{ + IDProperty * prop; + void * iter; + IDProperty * curr; + + if (!G.scene->r.ffcodecdata.properties) { + return; + } + + prop = IDP_GetPropertyFromGroup( + G.scene->r.ffcodecdata.properties, (char*) prop_name); + if (!prop) { + return; + } + + iter = IDP_GetGroupIterator(prop); + + while ((curr = IDP_GroupIterNext(iter)) != NULL) { + set_ffmpeg_property_option(c, curr); + } +} + /* prepare a video stream for the output file */ static AVStream* alloc_video_stream(int codec_id, AVFormatContext* of, @@ -423,13 +494,18 @@ static AVStream* alloc_video_stream(int codec_id, AVFormatContext* of, } /* Determine whether we are encoding interlaced material or not */ - if (G.scene->r.mode & (1 << 6)) { + if (G.scene->r.mode & R_FIELDS) { fprintf(stderr, "Encoding interlaced video\n"); c->flags |= CODEC_FLAG_INTERLACED_DCT; c->flags |= CODEC_FLAG_INTERLACED_ME; - } - c->sample_aspect_ratio.num = G.scene->r.xasp; - c->sample_aspect_ratio.den = G.scene->r.yasp; + } + + /* xasp & yasp got float lately... */ + + c->sample_aspect_ratio = av_d2q( + ((double) G.scene->r.xasp / (double) G.scene->r.yasp), 255); + + set_ffmpeg_properties(c, "video"); if (avcodec_open(c, codec) < 0) { error("Couldn't initialize codec"); @@ -474,6 +550,9 @@ static AVStream* alloc_audio_stream(int codec_id, AVFormatContext* of) error("Couldn't find a valid audio codec"); return NULL; } + + set_ffmpeg_properties(c, "audio"); + if (avcodec_open(c, codec) < 0) { error("Couldn't initialize audio codec"); return NULL; |