Cycles: svn merge -r41225:41232 ^/trunk/blender
[blender.git] / source / blender / blenkernel / intern / writeffmpeg.c
index ec998e68e00bf16f9ecfa08457f7b3e9808bb8b5..ed0a351716c417c5fd72ff775733016af57cd030 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ *
  * ffmpeg-write support
  *
  * Partial Copyright (c) 2006 Peter Schlaile
  *
  */
 
+/** \file blender/blenkernel/intern/writeffmpeg.c
+ *  \ingroup bke
+ */
+
 #ifdef WITH_FFMPEG
 #include <string.h>
 #include <stdio.h>
 
-#if defined(_WIN32) && defined(_DEBUG) && !defined(__MINGW32__) && !defined(__CYGWIN__)
+#if defined(_WIN32) && defined(DEBUG) && !defined(__MINGW32__) && !defined(__CYGWIN__)
 /* This does not seem necessary or present on MSVC 8, but may be needed in earlier versions? */
 #if _MSC_VER < 1400
 #include <stdint.h>
 #include <libswscale/swscale.h>
 #include <libavcodec/opt.h>
 
-#if LIBAVFORMAT_VERSION_INT < (49 << 16)
-#define FFMPEG_OLD_FRAME_RATE 1
-#else
-#define FFMPEG_CODEC_IS_POINTER 1
-#define FFMPEG_CODEC_TIME_BASE  1
-#endif
-
-#if LIBAVFORMAT_VERSION_INT >= (52 << 16)
-#define OUTFILE_PB (outfile->pb)
-#else
-#define OUTFILE_PB (&outfile->pb)
-#endif
-
-#if defined(WIN32) && (!(defined snprintf))
-#define snprintf _snprintf
-#endif
-
 #include "MEM_guardedalloc.h"
 
 #include "DNA_scene_types.h"
 
 #include "BLI_blenlib.h"
 
-#include "AUD_C-API.h" /* must be before BKE_sound.h for define */
+#ifdef WITH_AUDASPACE
+#  include "AUD_C-API.h"
+#endif
 
 #include "BKE_global.h"
 #include "BKE_idprop.h"
@@ -69,7 +59,9 @@
 #include "IMB_imbuf_types.h"
 #include "IMB_imbuf.h"
 
-extern void do_init_ffmpeg();
+#include "ffmpeg_compat.h"
+
+extern void do_init_ffmpeg(void);
 
 static int ffmpeg_type = 0;
 static int ffmpeg_codec = CODEC_ID_MPEG4;
@@ -95,7 +87,9 @@ static uint8_t* audio_output_buffer = 0;
 static int audio_outbuf_size = 0;
 static double audio_time = 0.0f;
 
+#ifdef WITH_AUDASPACE
 static AUD_Device* audio_mixdown_device = 0;
+#endif
 
 #define FFMPEG_AUTOSPLIT_SIZE 2000000000
 
@@ -109,24 +103,13 @@ static void delete_picture(AVFrame* f)
        }
 }
 
-#ifdef FFMPEG_CODEC_IS_POINTER
-static AVCodecContext* get_codec_from_stream(AVStream* stream)
-{
-       return stream->codec;
-}
-#else
-static AVCodecContext* get_codec_from_stream(AVStream* stream)
-{
-       return &stream->codec;
-}
-#endif
-
+#ifdef WITH_AUDASPACE
 static int write_audio_frame(void) 
 {
        AVCodecContext* c = NULL;
        AVPacket pkt;
 
-       c = get_codec_from_stream(audio_stream);
+       c = audio_stream->codec;
 
        av_init_packet(&pkt);
        pkt.size = 0;
@@ -148,23 +131,22 @@ static int write_audio_frame(void)
 
        if(c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE)
        {
-#ifdef FFMPEG_CODEC_TIME_BASE
                pkt.pts = av_rescale_q(c->coded_frame->pts,
-                                          c->time_base, audio_stream->time_base);
-#else
-               pkt.pts = c->coded_frame->pts;
-#endif
+                                      c->time_base, audio_stream->time_base);
                fprintf(stderr, "Audio Frame PTS: %d\n", (int)pkt.pts);
        }
 
        pkt.stream_index = audio_stream->index;
-       pkt.flags |= PKT_FLAG_KEY;
+
+       pkt.flags |= AV_PKT_FLAG_KEY;
+
        if (av_interleaved_write_frame(outfile, &pkt) != 0) {
                fprintf(stderr, "Error writing audio packet!\n");
                return -1;
        }
        return 0;
 }
+#endif // #ifdef WITH_AUDASPACE
 
 /* Allocate a temporary frame */
 static AVFrame* alloc_picture(int pix_fmt, int width, int height) 
@@ -258,10 +240,10 @@ static int write_video_frame(RenderData *rd, AVFrame* frame, ReportList *reports
 {
        int outsize = 0;
        int ret, success= 1;
-       AVCodecContext* c = get_codec_from_stream(video_stream);
-#ifdef FFMPEG_CODEC_TIME_BASE
+       AVCodecContext* c = video_stream->codec;
+
        frame->pts = rd->cfra - rd->sfra;
-#endif
+
        if (rd->mode & R_FIELDS) {
                frame->top_field_first = ((rd->mode & R_ODDFIELD) != 0);
        }
@@ -273,19 +255,15 @@ static int write_video_frame(RenderData *rd, AVFrame* frame, ReportList *reports
                av_init_packet(&packet);
 
                if (c->coded_frame->pts != AV_NOPTS_VALUE) {
-#ifdef FFMPEG_CODEC_TIME_BASE
                        packet.pts = av_rescale_q(c->coded_frame->pts,
                                                  c->time_base,
                                                  video_stream->time_base);
-#else
-                       packet.pts = c->coded_frame->pts;
-#endif
                        fprintf(stderr, "Video Frame PTS: %d\n", (int)packet.pts);
                } else {
                        fprintf(stderr, "Video Frame PTS: not set\n");
                }
                if (c->coded_frame->key_frame)
-                       packet.flags |= PKT_FLAG_KEY;
+                       packet.flags |= AV_PKT_FLAG_KEY;
                packet.stream_index = video_stream->index;
                packet.data = video_buffer;
                packet.size = outsize;
@@ -307,7 +285,7 @@ static AVFrame* generate_video_frame(uint8_t* pixels, ReportList *reports)
 {
        uint8_t* rendered_frame;
 
-       AVCodecContext* c = get_codec_from_stream(video_stream);
+       AVCodecContext* c = video_stream->codec;
        int width = c->width;
        int height = c->height;
        AVFrame* rgb_frame;
@@ -391,7 +369,7 @@ static void set_ffmpeg_property_option(AVCodecContext* c, IDProperty * prop)
        switch(prop->type) {
        case IDP_STRING:
                fprintf(stderr, "%s.\n", IDP_String(prop));
-               rv = av_set_string(c, prop->name, IDP_String(prop));
+               av_set_string3(c, prop->name, IDP_String(prop), 1, &rv);
                break;
        case IDP_FLOAT:
                fprintf(stderr, "%g.\n", IDP_Float(prop));
@@ -402,7 +380,7 @@ static void set_ffmpeg_property_option(AVCodecContext* c, IDProperty * prop)
                
                if (param) {
                        if (IDP_Int(prop)) {
-                               rv = av_set_string(c, name, param);
+                               av_set_string3(c, name, param, 1, &rv);
                        } else {
                                return;
                        }
@@ -428,8 +406,7 @@ static void set_ffmpeg_properties(RenderData *rd, AVCodecContext *c, const char
                return;
        }
        
-       prop = IDP_GetPropertyFromGroup(
-               rd->ffcodecdata.properties, (char*) prop_name);
+       prop = IDP_GetPropertyFromGroup(rd->ffcodecdata.properties, prop_name);
        if (!prop) {
                return;
        }
@@ -454,9 +431,9 @@ static AVStream* alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
 
        /* Set up the codec context */
        
-       c = get_codec_from_stream(st);
+       c = st->codec;
        c->codec_id = codec_id;
-       c->codec_type = CODEC_TYPE_VIDEO;
+       c->codec_type = AVMEDIA_TYPE_VIDEO;
 
 
        /* Get some values from the current render settings */
@@ -464,7 +441,6 @@ static AVStream* alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
        c->width = rectx;
        c->height = recty;
 
-#ifdef FFMPEG_CODEC_TIME_BASE
        /* FIXME: Really bad hack (tm) for NTSC support */
        if (ffmpeg_type == FFMPEG_DV && rd->frs_sec != 25) {
                c->time_base.den = 2997;
@@ -477,20 +453,6 @@ static AVStream* alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
                c->time_base.den = rd->frs_sec * 100000;
                c->time_base.num = ((double) rd->frs_sec_base) * 100000;
        }
-#else
-       /* FIXME: Really bad hack (tm) for NTSC support */
-       if (ffmpeg_type == FFMPEG_DV && rd->frs_sec != 25) {
-               c->frame_rate = 2997;
-               c->frame_rate_base = 100;
-       } else if ((double) ((int) rd->frs_sec_base) == 
-                  rd->frs_sec_base) {
-               c->frame_rate = rd->frs_sec;
-               c->frame_rate_base = rd->frs_sec_base;
-       } else {
-               c->frame_rate = rd->frs_sec * 100000;
-               c->frame_rate_base = ((double) rd->frs_sec_base)*100000;
-       }
-#endif
        
        c->gop_size = ffmpeg_gop_size;
        c->bit_rate = ffmpeg_video_bitrate*1000;
@@ -514,7 +476,7 @@ static AVStream* alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
                c->pix_fmt = PIX_FMT_YUV422P;
        }
 
-       if (codec_id == CODEC_ID_XVID) {
+       if (ffmpeg_type == FFMPEG_XVID) {
                /* arghhhh ... */
                c->pix_fmt = PIX_FMT_YUV420P;
                c->codec_tag = (('D'<<24) + ('I'<<16) + ('V'<<8) + 'X');
@@ -526,6 +488,12 @@ static AVStream* alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
                c->qmax=51;
        }
        
+       // Keep lossless encodes in the RGB domain.
+       if (codec_id == CODEC_ID_HUFFYUV || codec_id == CODEC_ID_FFV1) {
+               /* HUFFYUV was PIX_FMT_YUV422P before */
+               c->pix_fmt = PIX_FMT_RGB32;
+       }
+
        if ((of->oformat->flags & AVFMT_GLOBALHEADER)
 //             || !strcmp(of->oformat->name, "mp4")
 //         || !strcmp(of->oformat->name, "mov")
@@ -555,8 +523,8 @@ static AVStream* alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
                return NULL;
        }
 
-       video_buffersize = 2000000;
-       video_buffer = (uint8_t*)MEM_mallocN(video_buffersize
+       video_buffersize = avpicture_get_size(c->pix_fmt, c->width, c->height);
+       video_buffer = (uint8_t*)MEM_mallocN(video_buffersize*sizeof(uint8_t),
                                                 "FFMPEG video buffer");
        
        current_frame = alloc_picture(c->pix_fmt, c->width, c->height);
@@ -581,14 +549,14 @@ static AVStream* alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
        st = av_new_stream(of, 1);
        if (!st) return NULL;
 
-       c = get_codec_from_stream(st);
+       c = st->codec;
        c->codec_id = codec_id;
-       c->codec_type = CODEC_TYPE_AUDIO;
+       c->codec_type = AVMEDIA_TYPE_AUDIO;
 
        c->sample_rate = rd->ffcodecdata.audio_mixrate;
        c->bit_rate = ffmpeg_audio_bitrate*1000;
        c->sample_fmt = SAMPLE_FMT_S16;
-       c->channels = 2;
+       c->channels = rd->ffcodecdata.audio_channels;
        codec = avcodec_find_encoder(c->codec_id);
        if (!codec) {
                //XXX error("Couldn't find a valid audio codec");
@@ -602,6 +570,11 @@ static AVStream* alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
                return NULL;
        }
 
+       /* need to prevent floating point exception when using vorbis audio codec,
+          initialize this value in the same way as it's done in FFmpeg iteslf (sergey) */
+       st->codec->time_base.num= 1;
+       st->codec->time_base.den= st->codec->sample_rate;
+
        audio_outbuf_size = FF_MIN_BUFFER_SIZE;
 
        if((c->codec_id >= CODEC_ID_PCM_S16LE) && (c->codec_id <= CODEC_ID_PCM_DVD))
@@ -613,12 +586,11 @@ static AVStream* alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
                        audio_outbuf_size = c->frame_size * c->channels * sizeof(int16_t) * 4;
        }
 
-       audio_output_buffer = (uint8_t*)MEM_mallocN(
-               audio_outbuf_size, "FFMPEG audio encoder input buffer");
+       audio_output_buffer = (uint8_t*)av_malloc(
+               audio_outbuf_size);
 
-       audio_input_buffer = (uint8_t*)MEM_mallocN(
-               audio_input_samples * c->channels * sizeof(int16_t),
-               "FFMPEG audio encoder output buffer");
+       audio_input_buffer = (uint8_t*)av_malloc(
+               audio_input_samples * c->channels * sizeof(int16_t));
 
        audio_time = 0.0f;
 
@@ -661,13 +633,13 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
                BKE_report(reports, RPT_ERROR, "No valid formats found.");
                return 0;
        }
-       fmt = guess_format(NULL, exts[0], NULL);
+       fmt = av_guess_format(NULL, exts[0], NULL);
        if (!fmt) {
                BKE_report(reports, RPT_ERROR, "No valid formats found.");
                return 0;
        }
 
-       of = av_alloc_format_context();
+       of = avformat_alloc_context();
        if (!of) {
                BKE_report(reports, RPT_ERROR, "Error opening output file");
                return 0;
@@ -686,15 +658,17 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
 
        fmt->audio_codec = ffmpeg_audio_codec;
 
-       snprintf(of->filename, sizeof(of->filename), "%s", name);
+       BLI_snprintf(of->filename, sizeof(of->filename), "%s", name);
        /* set the codec to the user's selection */
        switch(ffmpeg_type) {
        case FFMPEG_AVI:
        case FFMPEG_MOV:
-       case FFMPEG_OGG:
        case FFMPEG_MKV:
                fmt->video_codec = ffmpeg_codec;
                break;
+       case FFMPEG_OGG:
+               fmt->video_codec = CODEC_ID_THEORA;
+               break;
        case FFMPEG_DV:
                fmt->video_codec = CODEC_ID_DVVIDEO;
                break;
@@ -708,7 +682,7 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
                fmt->video_codec = CODEC_ID_H264;
                break;
        case FFMPEG_XVID:
-               fmt->video_codec = CODEC_ID_XVID;
+               fmt->video_codec = CODEC_ID_MPEG4;
                break;
        case FFMPEG_FLV:
                fmt->video_codec = CODEC_ID_FLV1;
@@ -740,7 +714,7 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
        
        if (ffmpeg_type == FFMPEG_DV) {
                fmt->audio_codec = CODEC_ID_PCM_S16LE;
-               if (ffmpeg_audio_codec != CODEC_ID_NONE && rd->ffcodecdata.audio_mixrate != 48000) {
+               if (ffmpeg_audio_codec != CODEC_ID_NONE && rd->ffcodecdata.audio_mixrate != 48000 && rd->ffcodecdata.audio_channels != 2) {
                        BKE_report(reports, RPT_ERROR, "FFMPEG only supports 48khz / stereo audio for DV!");
                        return 0;
                }
@@ -767,15 +741,19 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
                return 0;
        }
        if (!(fmt->flags & AVFMT_NOFILE)) {
-               if (url_fopen(&of->pb, name, URL_WRONLY) < 0) {
+               if (avio_open(&of->pb, name, AVIO_FLAG_WRITE) < 0) {
                        BKE_report(reports, RPT_ERROR, "Could not open file for writing.");
                        return 0;
                }
        }
 
-       av_write_header(of);
+       if (av_write_header(of) < 0) {
+               BKE_report(reports, RPT_ERROR, "Could not initialize streams. Probably unsupported codec combination.");
+               return 0;
+       }
+
        outfile = of;
-       dump_format(of, 0, name, 1);
+       av_dump_format(of, 0, name, 1);
 
        return 1;
 }
@@ -802,7 +780,7 @@ void flush_ffmpeg(void)
        int outsize = 0;
        int ret = 0;
        
-       AVCodecContext* c = get_codec_from_stream(video_stream);
+       AVCodecContext* c = video_stream->codec;
        /* get the delayed frames */
        while (1) {
                AVPacket packet;
@@ -817,19 +795,15 @@ void flush_ffmpeg(void)
                        break;
                }
                if (c->coded_frame->pts != AV_NOPTS_VALUE) {
-#ifdef FFMPEG_CODEC_TIME_BASE
                        packet.pts = av_rescale_q(c->coded_frame->pts,
                                                  c->time_base,
                                                  video_stream->time_base);
-#else
-                       packet.pts = c->coded_frame->pts;
-#endif
                        fprintf(stderr, "Video Frame PTS: %d\n", (int)packet.pts);
                } else {
                        fprintf(stderr, "Video Frame PTS: not set\n");
                }
                if (c->coded_frame->key_frame) {
-                       packet.flags |= PKT_FLAG_KEY;
+                       packet.flags |= AV_PKT_FLAG_KEY;
                }
                packet.stream_index = video_stream->index;
                packet.data = video_buffer;
@@ -840,7 +814,7 @@ void flush_ffmpeg(void)
                        break;
                }
        }
-       avcodec_flush_buffers(get_codec_from_stream(video_stream));
+       avcodec_flush_buffers(video_stream->codec);
 }
 
 /* **********************************************************************
@@ -848,7 +822,8 @@ void flush_ffmpeg(void)
    ********************************************************************** */
 
 /* Get the output filename-- similar to the other output formats */
-void filepath_ffmpeg(char* string, RenderData* rd) {
+void filepath_ffmpeg(char* string, RenderData* rd)
+{
        char autosplit[20];
 
        const char ** exts = get_file_extensions(rd->ffcodecdata.type);
@@ -894,22 +869,27 @@ int start_ffmpeg(struct Scene *scene, RenderData *rd, int rectx, int recty, Repo
        ffmpeg_autosplit_count = 0;
 
        success = start_ffmpeg_impl(rd, rectx, recty, reports);
-
+#ifdef WITH_AUDASPACE
        if(audio_stream)
        {
-               AVCodecContext* c = get_codec_from_stream(audio_stream);
+               AVCodecContext* c = audio_stream->codec;
                AUD_DeviceSpecs specs;
                specs.channels = c->channels;
                specs.format = AUD_FORMAT_S16;
                specs.rate = rd->ffcodecdata.audio_mixrate;
                audio_mixdown_device = sound_mixdown(scene, specs, rd->sfra, rd->ffcodecdata.audio_volume);
+#ifdef FFMPEG_CODEC_TIME_BASE
+               c->time_base.den = specs.rate;
+               c->time_base.num = 1;
+#endif
        }
-
+#endif
        return success;
 }
 
 void end_ffmpeg(void);
 
+#ifdef WITH_AUDASPACE
 static void write_audio_frames(double to_pts)
 {
        int finished = 0;
@@ -921,6 +901,7 @@ static void write_audio_frames(double to_pts)
                }
        }
 }
+#endif
 
 int append_ffmpeg(RenderData *rd, int frame, int *pixels, int rectx, int recty, ReportList *reports) 
 {
@@ -940,7 +921,7 @@ int append_ffmpeg(RenderData *rd, int frame, int *pixels, int rectx, int recty,
                success= (avframe && write_video_frame(rd, avframe, reports));
 
                if (ffmpeg_autosplit) {
-                       if (url_ftell(OUTFILE_PB) > FFMPEG_AUTOSPLIT_SIZE) {
+                       if (avio_tell(outfile->pb) > FFMPEG_AUTOSPLIT_SIZE) {
                                end_ffmpeg();
                                ffmpeg_autosplit_count++;
                                success &= start_ffmpeg_impl(rd, rectx, recty, reports);
@@ -948,14 +929,15 @@ int append_ffmpeg(RenderData *rd, int frame, int *pixels, int rectx, int recty,
                }
        }
 
+#ifdef WITH_AUDASPACE
        write_audio_frames((frame - rd->sfra) / (((double)rd->frs_sec) / rd->frs_sec_base));
-
+#endif
        return success;
 }
 
 void end_ffmpeg(void)
 {
-       int i;
+       unsigned int i;
        
        fprintf(stderr, "Closing ffmpeg...\n");
 
@@ -963,13 +945,15 @@ void end_ffmpeg(void)
                write_audio_frames();
        }*/
 
+#ifdef WITH_AUDASPACE
        if(audio_mixdown_device)
        {
                AUD_closeReadDevice(audio_mixdown_device);
                audio_mixdown_device = 0;
        }
-       
-       if (video_stream && get_codec_from_stream(video_stream)) {
+#endif
+
+       if (video_stream && video_stream->codec) {
                fprintf(stderr, "Flushing delayed frames...\n");
                flush_ffmpeg ();                
        }
@@ -980,8 +964,8 @@ void end_ffmpeg(void)
        
        /* Close the video codec */
 
-       if (video_stream && get_codec_from_stream(video_stream)) {
-               avcodec_close(get_codec_from_stream(video_stream));
+       if (video_stream && video_stream->codec) {
+               avcodec_close(video_stream->codec);
                printf("zero video stream %p\n", video_stream);
                video_stream = 0;
        }
@@ -1002,7 +986,7 @@ void end_ffmpeg(void)
        }
        if (outfile && outfile->oformat) {
                if (!(outfile->oformat->flags & AVFMT_NOFILE)) {
-                       url_fclose(OUTFILE_PB);
+                       avio_close(outfile->pb);
                }
        }
        if (outfile) {
@@ -1014,11 +998,11 @@ void end_ffmpeg(void)
                video_buffer = 0;
        }
        if (audio_output_buffer) {
-               MEM_freeN(audio_output_buffer);
+               av_free(audio_output_buffer);
                audio_output_buffer = 0;
        }
        if (audio_input_buffer) {
-               MEM_freeN(audio_input_buffer);
+               av_free(audio_input_buffer);
                audio_input_buffer = 0;
        }
 
@@ -1039,8 +1023,7 @@ void ffmpeg_property_del(RenderData *rd, void *type, void *prop_)
                return;
        }
 
-       group = IDP_GetPropertyFromGroup(
-               rd->ffcodecdata.properties, (char*) type);
+       group = IDP_GetPropertyFromGroup(rd->ffcodecdata.properties, type);
        if (group && prop) {
                IDP_RemFromGroup(group, prop);
                IDP_FreeProperty(prop);
@@ -1058,6 +1041,8 @@ IDProperty *ffmpeg_property_add(RenderData *rd, char * type, int opt_index, int
        IDPropertyTemplate val;
        int idp_type;
        char name[256];
+       
+       val.i = 0;
 
        avcodec_get_context_defaults(&c);
 
@@ -1065,19 +1050,14 @@ IDProperty *ffmpeg_property_add(RenderData *rd, char * type, int opt_index, int
        parent = c.av_class->option + parent_index;
 
        if (!rd->ffcodecdata.properties) {
-               IDPropertyTemplate val;
-
                rd->ffcodecdata.properties 
                        = IDP_New(IDP_GROUP, val, "ffmpeg"); 
        }
 
-       group = IDP_GetPropertyFromGroup(
-               rd->ffcodecdata.properties, (char*) type);
+       group = IDP_GetPropertyFromGroup(rd->ffcodecdata.properties, type);
        
        if (!group) {
-               IDPropertyTemplate val;
-               
-               group = IDP_New(IDP_GROUP, val, (char*) type); 
+               group = IDP_New(IDP_GROUP, val, type);
                IDP_AddToGroup(rd->ffcodecdata.properties, group);
        }
 
@@ -1098,12 +1078,12 @@ IDProperty *ffmpeg_property_add(RenderData *rd, char * type, int opt_index, int
        switch (o->type) {
        case FF_OPT_TYPE_INT:
        case FF_OPT_TYPE_INT64:
-               val.i = o->default_val;
+               val.i = FFMPEG_DEF_OPT_VAL_INT(o);
                idp_type = IDP_INT;
                break;
        case FF_OPT_TYPE_DOUBLE:
        case FF_OPT_TYPE_FLOAT:
-               val.f = o->default_val;
+               val.f = FFMPEG_DEF_OPT_VAL_DOUBLE(o);
                idp_type = IDP_FLOAT;
                break;
        case FF_OPT_TYPE_STRING:
@@ -1311,7 +1291,7 @@ void ffmpeg_set_preset(RenderData *rd, int preset)
        case FFMPEG_PRESET_XVID:
                if(preset == FFMPEG_PRESET_XVID) {
                        rd->ffcodecdata.type = FFMPEG_AVI;
-                       rd->ffcodecdata.codec = CODEC_ID_XVID;
+                       rd->ffcodecdata.codec = CODEC_ID_MPEG4;
                }
                else if(preset == FFMPEG_PRESET_THEORA) {
                        rd->ffcodecdata.type = FFMPEG_OGG; // XXX broken
@@ -1344,6 +1324,9 @@ void ffmpeg_verify_image_type(RenderData *rd)
                        /* Don't set preset, disturbs render resolution.
                         * ffmpeg_set_preset(rd, FFMPEG_PRESET_DVD); */
                }
+               if(rd->ffcodecdata.type == FFMPEG_OGG) {
+                       rd->ffcodecdata.type = FFMPEG_MPEG2;
+               }
 
                audio= 1;
        }
@@ -1354,7 +1337,7 @@ void ffmpeg_verify_image_type(RenderData *rd)
                }
        }
        else if(rd->imtype == R_XVID) {
-               if(rd->ffcodecdata.codec != CODEC_ID_XVID) {
+               if(rd->ffcodecdata.codec != CODEC_ID_MPEG4) {
                        ffmpeg_set_preset(rd, FFMPEG_PRESET_XVID);
                        audio= 1;
                }