Merge with trunk up to r38584.
[blender-staging.git] / source / blender / blenkernel / intern / writeffmpeg.c
index 27ae8ec2aba4065f2277123fcc9530efbb02bdac..ae4387c12f98e3795351d56522100f3caf2adf79 100644 (file)
@@ -49,7 +49,9 @@
 
 #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"
 #include "IMB_imbuf_types.h"
 #include "IMB_imbuf.h"
 
-#if (LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 105)
-#define FFMPEG_HAVE_AVIO 1
-#endif
-
-#if (LIBAVFORMAT_VERSION_MAJOR >= 53) && (LIBAVFORMAT_VERSION_MINOR >= 3)
-#define FFMPEG_HAVE_DEFAULT_VAL_UNION 1
-#endif
-
-#ifndef FFMPEG_HAVE_AVIO
-#define AVIO_FLAG_WRITE URL_WRONLY
-#define avio_open url_fopen
-#define avio_tell url_ftell
-#define avio_close url_fclose
-#endif
-
-/* make OpenSuSe special "in-between" ffmpeg 0.6.2 version(tm) happy... 
-   Arrrrgh */
-#ifndef AVIO_FLAG_WRITE
-#define AVIO_FLAG_WRITE URL_WRONLY
-#endif
+#include "ffmpeg_compat.h"
 
 extern void do_init_ffmpeg(void);
 
@@ -108,7 +91,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
 
@@ -122,6 +107,7 @@ static void delete_picture(AVFrame* f)
        }
 }
 
+#ifdef WITH_AUDASPACE
 static int write_audio_frame(void) 
 {
        AVCodecContext* c = NULL;
@@ -164,6 +150,7 @@ static int write_audio_frame(void)
        }
        return 0;
 }
+#endif // #ifdef WITH_AUDASPACE
 
 /* Allocate a temporary frame */
 static AVFrame* alloc_picture(int pix_fmt, int width, int height) 
@@ -568,7 +555,7 @@ static AVStream* alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
        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");
@@ -593,12 +580,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;
 
@@ -720,7 +706,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;
                }
@@ -870,7 +856,7 @@ 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 = audio_stream->codec;
@@ -879,13 +865,18 @@ int start_ffmpeg(struct Scene *scene, RenderData *rd, int rectx, int recty, Repo
                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;
@@ -897,6 +888,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) 
 {
@@ -924,8 +916,9 @@ 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;
 }
 
@@ -939,12 +932,14 @@ void end_ffmpeg(void)
                write_audio_frames();
        }*/
 
+#ifdef WITH_AUDASPACE
        if(audio_mixdown_device)
        {
                AUD_closeReadDevice(audio_mixdown_device);
                audio_mixdown_device = 0;
        }
-       
+#endif
+
        if (video_stream && video_stream->codec) {
                fprintf(stderr, "Flushing delayed frames...\n");
                flush_ffmpeg ();                
@@ -990,11 +985,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;
        }
 
@@ -1072,20 +1067,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:
-#ifdef FFMPEG_HAVE_DEFAULT_VAL_UNION
-               val.i = o->default_val.i64;
-#else
-               val.i = o->default_val;
-#endif
+               val.i = FFMPEG_DEF_OPT_VAL_INT(o);
                idp_type = IDP_INT;
                break;
        case FF_OPT_TYPE_DOUBLE:
        case FF_OPT_TYPE_FLOAT:
-#ifdef FFMPEG_HAVE_DEFAULT_VAL_UNION
-               val.f = o->default_val.dbl;
-#else
-               val.f = o->default_val;
-#endif
+               val.f = FFMPEG_DEF_OPT_VAL_DOUBLE(o);
                idp_type = IDP_FLOAT;
                break;
        case FF_OPT_TYPE_STRING: