==FFMPEG==
authorPeter Schlaile <peter@schlaile.de>
Fri, 9 Jun 2006 19:48:50 +0000 (19:48 +0000)
committerPeter Schlaile <peter@schlaile.de>
Fri, 9 Jun 2006 19:48:50 +0000 (19:48 +0000)
Added support for XVid and H264-codecs in codec-selection. (only work, if
ffmpeg is compiled with XVid and/or H264-support. Failure in doing so
results in an error message that codec can't be selected.)

Both are written always to AVIs since raw-h264-files created by ffmpeg
can't even be opened by itself...

Video render options are reset to sane defaults (=DVD preset) on startup now.

Don't expect quicktime-support to be very exciting, since ffmpeg can't really
multiplex quicktime files. (Tried several codecs with the ffmpeg-commandline
tool,... sigh)

Timestamp crash on Debian-Sarge version is fixed.

source/blender/blenkernel/BKE_writeffmpeg.h
source/blender/blenkernel/intern/writeffmpeg.c
source/blender/src/buttons_scene.c

index 288955f..13084e9 100644 (file)
@@ -43,12 +43,16 @@ extern "C" {
 #define FFMPEG_AVI     3
 #define FFMPEG_MOV     4
 #define FFMPEG_DV      5
+#define FFMPEG_H264     6
+#define FFMPEG_XVID     7
 
 #define FFMPEG_CODEC_MPEG1 0
 #define FFMPEG_CODEC_MPEG2 1
 #define FFMPEG_CODEC_MPEG4 2
 #define FFMPEG_CODEC_HUFFYUV 3
 #define FFMPEG_CODEC_DV 4
+#define FFMPEG_CODEC_H264 5
+#define FFMPEG_CODEC_XVID 6
 
 #define FFMPEG_PRESET_NONE 0
 #define FFMPEG_PRESET_DVD  1
index 7eae185..aa4cb00 100644 (file)
@@ -181,6 +181,14 @@ AVOutputFormat* ffmpeg_get_format(int format)
                case FFMPEG_MOV:
                        f = guess_format("mov", NULL, NULL);
                        break;
+               case FFMPEG_H264:
+                       /* FIXME: avi for now... */
+                       f = guess_format("avi", NULL, NULL);
+                       break;
+               case FFMPEG_XVID:
+                       /* FIXME: avi for now... */
+                       f = guess_format("avi", NULL, NULL);
+                       break;
                default:
                        f = NULL;
        }
@@ -238,7 +246,9 @@ static void write_video_frame(AVFrame* frame) {
        int outsize = 0;
        int ret;
        AVCodecContext* c = get_codec_from_stream(video_stream);
+#ifdef FFMPEG_CODEC_TIME_BASE
        frame->pts = G.scene->r.cfra - G.scene->r.sfra;
+#endif
 
        outsize = avcodec_encode_video(c, video_buffer, video_buffersize, 
                                       frame);
@@ -400,6 +410,11 @@ static AVStream* alloc_video_stream(int codec_id, AVFormatContext* of,
                /* makes HuffYUV happy ... */
                c->pix_fmt = PIX_FMT_YUV422P;
        }
+
+       if (codec_id == CODEC_ID_XVID) {
+               /* arghhhh ... */
+               c->pix_fmt = PIX_FMT_YUV420P;
+       }
        
        if (!strcmp(of->oformat->name, "mp4") || 
            !strcmp(of->oformat->name, "mov") ||
@@ -549,23 +564,29 @@ void start_ffmpeg_impl(RenderData *rd, int rectx, int recty)
        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:
-                       fmt->video_codec = ffmpeg_codec;
-                       break;
-               case FFMPEG_DV:
-                       fmt->video_codec = CODEC_ID_DVVIDEO;
-                       break;
-               case FFMPEG_MPEG1:
-                       fmt->video_codec = CODEC_ID_MPEG1VIDEO;
-                       break;
-               case FFMPEG_MPEG2:
-                       fmt->video_codec = CODEC_ID_MPEG2VIDEO;
-                       break;
-               case FFMPEG_MPEG4:
-               default:
-                       fmt->video_codec = CODEC_ID_MPEG4;
-                       break;
+       case FFMPEG_AVI:
+       case FFMPEG_MOV:
+               fmt->video_codec = ffmpeg_codec;
+               break;
+       case FFMPEG_DV:
+               fmt->video_codec = CODEC_ID_DVVIDEO;
+               break;
+       case FFMPEG_MPEG1:
+               fmt->video_codec = CODEC_ID_MPEG1VIDEO;
+               break;
+       case FFMPEG_MPEG2:
+               fmt->video_codec = CODEC_ID_MPEG2VIDEO;
+               break;
+       case FFMPEG_H264:
+               fmt->video_codec = CODEC_ID_H264;
+               break;
+       case FFMPEG_XVID:
+               fmt->video_codec = CODEC_ID_XVID;
+               break;
+       case FFMPEG_MPEG4:
+       default:
+               fmt->video_codec = CODEC_ID_MPEG4;
+               break;
        }
        if (fmt->video_codec == CODEC_ID_DVVIDEO) {
                if (rectx != 720) {
index 236e0a5..ca061ac 100644 (file)
@@ -518,6 +518,10 @@ void playback_anim(void)
        }
 }
 
+#ifdef WITH_FFMPEG
+static void set_ffmpeg_preset(int preset);
+#endif
+
 void do_render_panels(unsigned short event)
 {
        ScrArea *sa;
@@ -593,16 +597,21 @@ void do_render_panels(unsigned short event)
                allqueue(REDRAWBUTSSCENE, 0);
 #ifdef WITH_FFMPEG
                 if (G.scene->r.imtype == R_FFMPEG) {
-                       if (G.scene->r.ffcodecdata.codec <= 0) 
-                              G.scene->r.ffcodecdata.codec = CODEC_ID_MPEG4;
-                       if (G.scene->r.ffcodecdata.audio_codec <= 0) 
-                              G.scene->r.ffcodecdata.audio_codec 
-                                      = CODEC_ID_MP2;
-                       if (G.scene->r.ffcodecdata.video_bitrate <= 1) 
-                              G.scene->r.ffcodecdata.video_bitrate = 1152;
-                       if (G.scene->r.ffcodecdata.audio_bitrate <= 0) 
-                              G.scene->r.ffcodecdata.audio_bitrate = 128;
-                       break;
+                       if (G.scene->r.ffcodecdata.type <= 0 ||
+                           G.scene->r.ffcodecdata.codec <= 0 ||
+                           G.scene->r.ffcodecdata.audio_codec <= 0 ||
+                           G.scene->r.ffcodecdata.video_bitrate <= 1) {
+                               G.scene->r.ffcodecdata.codec 
+                                       = CODEC_ID_MPEG2VIDEO;
+                               set_ffmpeg_preset(FFMPEG_PRESET_DVD);
+                       }
+
+                       if (G.scene->r.ffcodecdata.audio_codec <= 0) {
+                               G.scene->r.ffcodecdata.audio_codec 
+                                       = CODEC_ID_MP2;
+                               G.scene->r.ffcodecdata.audio_bitrate = 128;
+                       }
+                       break;
                 }
 #endif
 #if defined (_WIN32) || defined (__APPLE__)
@@ -981,14 +990,16 @@ static char* ffmpeg_format_pup(void)
        }
        return string;
 #endif
-       strcpy(formatstring, "FFMpeg format: %%t|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d");
+       strcpy(formatstring, "FFMpeg format: %%t|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d");
        sprintf(string, formatstring,
                "MPEG-1", FFMPEG_MPEG1,
                "MPEG-2", FFMPEG_MPEG2,
                "MPEG-4", FFMPEG_MPEG4,
                "AVI",    FFMPEG_AVI,
                "Quicktime", FFMPEG_MOV,
-               "DV", FFMPEG_DV);
+               "DV", FFMPEG_DV,
+              "H264", FFMPEG_H264,
+              "XVid", FFMPEG_XVID);
        return string;
 }
 
@@ -1011,13 +1022,15 @@ static char* ffmpeg_preset_pup(void)
 static char* ffmpeg_codec_pup(void) {
        static char string[2048];
        char formatstring[2048];
-       strcpy(formatstring, "FFMpeg format: %%t|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d");
+       strcpy(formatstring, "FFMpeg format: %%t|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d");
        sprintf(string, formatstring,
                "MPEG1", CODEC_ID_MPEG1VIDEO,
                "MPEG2", CODEC_ID_MPEG2VIDEO,
                "MPEG4(divx)", CODEC_ID_MPEG4,
                "HuffYUV", CODEC_ID_HUFFYUV,
-              "DV", CODEC_ID_DVVIDEO);
+              "DV", CODEC_ID_DVVIDEO,
+               "H264", CODEC_ID_H264,
+              "XVid", CODEC_ID_XVID);
        return string;
 
 }
@@ -1321,6 +1334,56 @@ static void render_panel_anim(void)
 }
 
 #ifdef WITH_FFMPEG
+static void set_ffmpeg_preset(int preset)
+{
+       int isntsc = (G.scene->r.frs_sec != 25);
+       switch (preset) {
+       case FFMPEG_PRESET_VCD:
+               G.scene->r.ffcodecdata.type = FFMPEG_MPEG1;
+               G.scene->r.ffcodecdata.video_bitrate = 1150;
+               G.scene->r.xsch = 352;
+               G.scene->r.ysch = isntsc ? 240 : 288;
+               G.scene->r.ffcodecdata.gop_size = isntsc ? 18 : 15;
+               G.scene->r.ffcodecdata.rc_max_rate = 1150;
+               G.scene->r.ffcodecdata.rc_min_rate = 1150;
+               G.scene->r.ffcodecdata.rc_buffer_size = 40*8;
+               G.scene->r.ffcodecdata.mux_packet_size = 2324;
+               G.scene->r.ffcodecdata.mux_rate = 2352 * 75 * 8;
+               break;
+       case FFMPEG_PRESET_SVCD:
+               G.scene->r.ffcodecdata.type = FFMPEG_MPEG2;
+               G.scene->r.ffcodecdata.video_bitrate = 2040;
+               G.scene->r.xsch = 480;
+               G.scene->r.ysch = isntsc ? 480 : 576;
+               G.scene->r.ffcodecdata.gop_size = isntsc ? 18 : 15;
+               G.scene->r.ffcodecdata.rc_max_rate = 2516;
+               G.scene->r.ffcodecdata.rc_min_rate = 0;
+               G.scene->r.ffcodecdata.rc_buffer_size = 224*8;
+               G.scene->r.ffcodecdata.mux_packet_size = 2324;
+               G.scene->r.ffcodecdata.mux_rate = 0;
+               
+               break;
+       case FFMPEG_PRESET_DVD:
+               G.scene->r.ffcodecdata.type = FFMPEG_MPEG2;
+               G.scene->r.ffcodecdata.video_bitrate = 6000;
+               G.scene->r.xsch = 720;
+               G.scene->r.ysch = isntsc ? 480 : 576;
+               G.scene->r.ffcodecdata.gop_size = isntsc ? 18 : 15;
+               G.scene->r.ffcodecdata.rc_max_rate = 9000;
+               G.scene->r.ffcodecdata.rc_min_rate = 0;
+               G.scene->r.ffcodecdata.rc_buffer_size = 224*8;
+               G.scene->r.ffcodecdata.mux_packet_size = 2048;
+               G.scene->r.ffcodecdata.mux_rate = 10080000;
+               
+               break;
+       case FFMPEG_PRESET_DV:
+               G.scene->r.ffcodecdata.type = FFMPEG_DV;
+               G.scene->r.xsch = 720;
+               G.scene->r.ysch = isntsc ? 480 : 576;
+               break;
+       }
+}
+
 static void render_panel_ffmpeg_video(void)
 {
        int yofs;
@@ -1333,52 +1396,7 @@ static void render_panel_ffmpeg_video(void)
           == 0) return;
 
        if (ffmpeg_preset_sel != 0) {
-              int isntsc = (G.scene->r.frs_sec != 25);
-              switch (ffmpeg_preset_sel) {
-              case FFMPEG_PRESET_VCD:
-                      G.scene->r.ffcodecdata.type = FFMPEG_MPEG1;
-                      G.scene->r.ffcodecdata.video_bitrate = 1150;
-                      G.scene->r.xsch = 352;
-                      G.scene->r.ysch = isntsc ? 240 : 288;
-                      G.scene->r.ffcodecdata.gop_size = isntsc ? 18 : 15;
-                      G.scene->r.ffcodecdata.rc_max_rate = 1150;
-                      G.scene->r.ffcodecdata.rc_min_rate = 1150;
-                      G.scene->r.ffcodecdata.rc_buffer_size = 40*8;
-                      G.scene->r.ffcodecdata.mux_packet_size = 2324;
-                      G.scene->r.ffcodecdata.mux_rate = 2352 * 75 * 8;
-                      break;
-              case FFMPEG_PRESET_SVCD:
-                      G.scene->r.ffcodecdata.type = FFMPEG_MPEG2;
-                      G.scene->r.ffcodecdata.video_bitrate = 2040;
-                      G.scene->r.xsch = 480;
-                      G.scene->r.ysch = isntsc ? 480 : 576;
-                      G.scene->r.ffcodecdata.gop_size = isntsc ? 18 : 15;
-                      G.scene->r.ffcodecdata.rc_max_rate = 2516;
-                      G.scene->r.ffcodecdata.rc_min_rate = 0;
-                      G.scene->r.ffcodecdata.rc_buffer_size = 224*8;
-                      G.scene->r.ffcodecdata.mux_packet_size = 2324;
-                      G.scene->r.ffcodecdata.mux_rate = 0;
-              
-                      break;
-              case FFMPEG_PRESET_DVD:
-                      G.scene->r.ffcodecdata.type = FFMPEG_MPEG2;
-                      G.scene->r.ffcodecdata.video_bitrate = 6000;
-                      G.scene->r.xsch = 720;
-                      G.scene->r.ysch = isntsc ? 480 : 576;
-                      G.scene->r.ffcodecdata.gop_size = isntsc ? 18 : 15;
-                      G.scene->r.ffcodecdata.rc_max_rate = 9000;
-                      G.scene->r.ffcodecdata.rc_min_rate = 0;
-                      G.scene->r.ffcodecdata.rc_buffer_size = 224*8;
-                      G.scene->r.ffcodecdata.mux_packet_size = 2048;
-                      G.scene->r.ffcodecdata.mux_rate = 10080000;
-              
-                      break;
-              case FFMPEG_PRESET_DV:
-                      G.scene->r.ffcodecdata.type = FFMPEG_DV;
-                      G.scene->r.xsch = 720;
-                      G.scene->r.ysch = isntsc ? 480 : 576;
-                      break;
-              }
+              set_ffmpeg_preset(ffmpeg_preset_sel);
               ffmpeg_preset_sel = 0;
               allqueue(REDRAWBUTSSCENE, 0);
        }