]> granicus.if.org Git - handbrake/commitdiff
Add mpeg-2 encoding support to libhb, cli, and lingui
authorjstebbins <jstebbins.hb@gmail.com>
Sat, 19 Mar 2011 20:58:01 +0000 (20:58 +0000)
committerjstebbins <jstebbins.hb@gmail.com>
Sat, 19 Mar 2011 20:58:01 +0000 (20:58 +0000)
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@3853 b64f7644-9d1e-0410-96f1-a4d463321fa5

12 files changed:
contrib/ffmpeg/module.defs
gtk/src/callbacks.c
gtk/src/ghb.ui
gtk/src/hb-backend.c
gtk/src/makedeps.py
libhb/common.h
libhb/encavcodec.c
libhb/muxmkv.c
libhb/muxmp4.c
libhb/scan.c
libhb/work.c
test/test.c

index 40c32003e5667f7c441660b54ab572ebd2e6b680..b524e27a7635a7f1d13d8431010d563ef5402272 100644 (file)
@@ -20,9 +20,9 @@ FFMPEG.CONFIGURE.extra = \
     --enable-bzlib \
     --enable-encoder=ac3 \
     --enable-encoder=mpeg4 \
+    --enable-encoder=mpeg2video \
     --enable-encoder=snow \
     --enable-gpl \
-    --enable-muxer=ipod \
     --enable-zlib \
     --cc="$(FFMPEG.GCC.gcc)" \
     --extra-cflags="$(call fn.ARGS,FFMPEG.GCC,*archs *sysroot *minver ?extra) -I$(call fn.ABSOLUTE,$(CONTRIB.build/)include)" \
index 4ba8cdd8b37a96181f91f48da138047f7e5db624..a2854dcad01df883fcf5ccbf532352cd7b26f28e 100644 (file)
@@ -4618,7 +4618,8 @@ format_vquality_cb(GtkScale *scale, gdouble val, signal_user_data_t *ud)
                        }
                } break;
 
-               case HB_VCODEC_FFMPEG:
+               case HB_VCODEC_FFMPEG_MPEG4:
+               case HB_VCODEC_FFMPEG_MPEG2:
                {
                        return g_strdup_printf("QP: %d", (int)val);
                } break;
index 98675dd05520fd8ad1d53e706a40164bac4f1ffc..6284e52fdc349ffa360b7043fd9c0f41a8889e6a 100644 (file)
@@ -3545,7 +3545,7 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property>
                               <object class="GtkLabel" id="label75">
                                 <property name="visible">True</property>
                                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                <property name="label" translatable="yes">&lt;small&gt;&lt;b&gt;Current FFMpeg MPEG-4 Advanced Option String&lt;/b&gt;&lt;/small&gt;</property>
+                                <property name="label" translatable="yes">&lt;small&gt;&lt;b&gt;Current FFMpeg Advanced Option String&lt;/b&gt;&lt;/small&gt;</property>
                                 <property name="use_markup">True</property>
                               </object>
                             </child>
index fbcd4a679ca3d9bda73a205e6c137bc31beecec9..b4ff3e8d278c7209ef014b21ed8ed2b0aae04d60 100644 (file)
@@ -239,7 +239,8 @@ combo_opts_t denoise_opts =
 static options_map_t d_vcodec_opts[] =
 {
        {"H.264 (x264)",    "x264",   HB_VCODEC_X264, ""},
-       {"MPEG-4 (FFmpeg)", "ffmpeg", HB_VCODEC_FFMPEG, ""},
+       {"MPEG-4 (FFmpeg)", "ffmpeg", HB_VCODEC_FFMPEG_MPEG4, ""},
+       {"MPEG-2 (FFmpeg)", "ffmpeg2",HB_VCODEC_FFMPEG_MPEG2, ""},
        {"VP3 (Theora)",    "theora", HB_VCODEC_THEORA, ""},
 };
 combo_opts_t vcodec_opts =
@@ -736,7 +737,8 @@ ghb_vquality_range(
                        *inverted = TRUE;
                } break;
 
-               case HB_VCODEC_FFMPEG:
+               case HB_VCODEC_FFMPEG_MPEG2:
+               case HB_VCODEC_FFMPEG_MPEG4:
                {
                        *min = 1;
                        *max = 31;
@@ -2854,7 +2856,8 @@ ghb_build_advanced_opts_string(GValue *settings)
                        }
                } break;
 
-               case HB_VCODEC_FFMPEG:
+               case HB_VCODEC_FFMPEG_MPEG2:
+               case HB_VCODEC_FFMPEG_MPEG4:
                {
                        gchar *opts = ghb_settings_get_string(settings, "lavcOption");
                        if (opts != NULL)
@@ -4014,7 +4017,7 @@ ghb_validate_video(signal_user_data_t *ud)
                        return FALSE;
                }
                g_free(message);
-               vcodec = HB_VCODEC_FFMPEG;
+               vcodec = HB_VCODEC_FFMPEG_MPEG4;
                ghb_ui_update(ud, "VideoEncoder", ghb_int64_value(vcodec));
        }
        return TRUE;
@@ -4339,7 +4342,8 @@ ghb_validate_vquality(GValue *settings)
                                max = 30;
                        } break;
 
-                       case HB_VCODEC_FFMPEG:
+                       case HB_VCODEC_FFMPEG_MPEG2:
+                       case HB_VCODEC_FFMPEG_MPEG4:
                        {
                                min = 1;
                                max = 8;
@@ -4620,7 +4624,7 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex)
        if ((job->mux == HB_MUX_MP4 ) && (job->vcodec == HB_VCODEC_THEORA))
        {
                // mp4/theora combination is not supported.
-               job->vcodec = HB_VCODEC_FFMPEG;
+               job->vcodec = HB_VCODEC_FFMPEG_MPEG4;
        }
        if ((job->vcodec == HB_VCODEC_X264) && (job->mux == HB_MUX_MP4))
        {
@@ -4880,7 +4884,7 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex)
                                        extra_opts = g_strdup_printf("%s:weightb=0", turbo_x264_opts);
                                }
                        }
-                       else if (job->vcodec == HB_VCODEC_FFMPEG)
+                       else if (job->vcodec == HB_VCODEC_FFMPEG_MPEG4)
                        {
                                extra_opts = g_strdup_printf("%s", turbo_lavc_opts);
                        }
index fd8db094abaac880429e2cf8401fe05401220414..2164ab4e7a2c8faee6f0fcf1bd47b3c3e14b9a74 100644 (file)
@@ -47,7 +47,7 @@ dep_map = (
        DepEntry("PictureAutoCrop", "PictureLeftCrop", "FALSE", False, False),
        DepEntry("PictureAutoCrop", "PictureRightCrop", "FALSE", False, False),
        DepEntry("VideoEncoder", "x264_tab", "x264", False, True),
-       DepEntry("VideoEncoder", "lavc_mpeg4_tab", "ffmpeg", False, True),
+       DepEntry("VideoEncoder", "lavc_mpeg4_tab", "ffmpeg|ffmpeg2", False, True),
        DepEntry("VideoEncoder", "Mp4iPodCompatible", "x264", False, False),
        DepEntry("AudioEncoderActual", "AudioBitrate", "ac3pass|dtspass", True, False),
        DepEntry("AudioEncoderActual", "AudioSamplerate", "ac3pass|dtspass", True, False),
index fc7b13916b594f78857a5d2493e6324e6dbe5951..b8045234c42d6d324b7e0e750c4837a77631d872 100644 (file)
@@ -223,9 +223,12 @@ struct hb_job_s
          advanced_opts:     string of extra advanced encoder options
          areBframes:        boolean to note if b-frames are included in advanced_opts */
 #define HB_VCODEC_MASK   0x0000FF
-#define HB_VCODEC_FFMPEG 0x000001
-#define HB_VCODEC_X264   0x000002
-#define HB_VCODEC_THEORA 0x000004
+#define HB_VCODEC_X264   0x000001
+#define HB_VCODEC_THEORA 0x000002
+#define HB_VCODEC_FFMPEG_MPEG4 0x000010
+#define HB_VCODEC_FFMPEG       HB_VCODEC_FFMPEG_MPEG4
+#define HB_VCODEC_FFMPEG_MPEG2 0x000020
+#define HB_VCODEC_FFMPEG_MASK  0x0000F0
 
     int             vcodec;
     float           vquality;
index e70d9279b153fcfd0b144bac21b85d001a759778..b2cebee6429f7f4717b043f42ce5334fbe2f2611 100644 (file)
@@ -47,7 +47,7 @@ void encavcodecClose( hb_work_object_t * );
 hb_work_object_t hb_encavcodec =
 {
     WORK_ENCAVCODEC,
-    "MPEG-4 encoder (libavcodec)",
+    "FFMPEG encoder (libavcodec)",
     encavcodecInit,
     encavcodecWork,
     encavcodecClose
@@ -57,17 +57,34 @@ int encavcodecInit( hb_work_object_t * w, hb_job_t * job )
 {
     AVCodec * codec;
     AVCodecContext * context;
-    int rate_num, rate_den;
+    AVRational fps;
 
     hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
     w->private_data = pv;
 
     pv->job = job;
 
-    codec = avcodec_find_encoder( CODEC_ID_MPEG4 );
+    switch ( w->codec_param )
+    {
+        case CODEC_ID_MPEG4:
+        {
+            hb_log("encavcodecInit: MPEG-4 ASP encoder");
+        } break;
+        case CODEC_ID_MPEG2VIDEO:
+        {
+            hb_log("encavcodecInit: MPEG-2 encoder");
+        } break;
+        default:
+        {
+            hb_error("encavcodecInit: unsupported encoder!");
+            return 1;
+        }
+    }
+
+    codec = avcodec_find_encoder( w->codec_param  );
     if( !codec )
     {
-        hb_log( "hb_work_encavcodec_init: avcodec_find_encoder "
+        hb_log( "encavcodecInit: avcodec_find_encoder "
                 "failed" );
     }
     context = avcodec_alloc_context3( codec );
@@ -79,45 +96,64 @@ int encavcodecInit( hb_work_object_t * w, hb_job_t * job )
     if( job->pass == 2 )
     {
         hb_interjob_t * interjob = hb_interjob_get( job->h );
-        rate_num = interjob->vrate_base;
-        rate_den = interjob->vrate;
+        fps.den = interjob->vrate_base;
+        fps.num = interjob->vrate;
     }
     else
     {
-        rate_num = job->vrate_base;
-        rate_den = job->vrate;
+        fps.den = job->vrate_base;
+        fps.num = job->vrate;
     }
 
-    // If the rate_den is 27000000, there's a good chance this is
+    // If the fps.num is 27000000, there's a good chance this is
     // a standard rate that we have in our hb_video_rates table.
     // Because of rounding errors and approximations made while 
     // measuring framerate, the actual value may not be exact.  So
     // we look for rates that are "close" and make an adjustment
-    // to rate_num.
-    if (rate_den == 27000000)
+    // to fps.den.
+    if (fps.num == 27000000)
     {
         int ii;
         for (ii = 0; ii < hb_video_rates_count; ii++)
         {
-            if (abs(rate_num - hb_video_rates[ii].rate) < 10)
+            if (abs(fps.den - hb_video_rates[ii].rate) < 10)
             {
-                rate_num = hb_video_rates[ii].rate;
+                fps.den = hb_video_rates[ii].rate;
                 break;
             }
         }
     }
-    hb_reduce(&rate_num, &rate_den, rate_num, rate_den);
-    if ((rate_num & ~0xFFFF) || (rate_den & ~0xFFFF))
+    hb_reduce(&fps.den, &fps.num, fps.den, fps.num);
+
+    // Check that the framerate is supported.  If not, pick the closest.
+    // The mpeg2 codec only supports a specific list of frame rates.
+    if (codec->supported_framerates)
     {
-        hb_log( "encavcodec: truncating framerate %d / %d", 
-                rate_num, rate_den );
+        AVRational supported_fps;
+        supported_fps = codec->supported_framerates[av_find_nearest_q_idx(fps, codec->supported_framerates)];
+        if (supported_fps.num != fps.num || supported_fps.den != fps.den)
+        {
+            hb_log( "encavcodec: framerate %d / %d is not supported. Using %d / %d.", 
+                    fps.num, fps.den, supported_fps.num, supported_fps.den );
+            fps = supported_fps;
+        }
     }
-    while ((rate_num & ~0xFFFF) || (rate_den & ~0xFFFF))
+    else if ((fps.num & ~0xFFFF) || (fps.den & ~0xFFFF))
     {
-        rate_num >>= 1;
-        rate_den >>= 1;
+        // This may only be required for mpeg4 video. But since
+        // our only supported options are mpeg2 and mpeg4, there is
+        // no need to check codec type.
+        hb_log( "encavcodec: truncating framerate %d / %d", 
+                fps.num, fps.den );
+        while ((fps.num & ~0xFFFF) || (fps.den & ~0xFFFF))
+        {
+            fps.num >>= 1;
+            fps.den >>= 1;
+        }
     }
-    context->time_base = (AVRational) { rate_num, rate_den };
+
+    context->time_base.den = fps.num;
+    context->time_base.num = fps.den;
     context->gop_size  = 10 * (int)( (double)job->vrate / (double)job->vrate_base + 0.5 );
 
     /*
@@ -178,7 +214,9 @@ int encavcodecInit( hb_work_object_t * w, hb_job_t * job )
     {
         /* Rate control */
         context->bit_rate = 1000 * job->vbitrate;
-        context->bit_rate_tolerance = 10 * context->bit_rate;
+        // ffmpeg's mpeg2 encoder requires that the bit_rate_tolerance be >=
+        // bitrate * fps
+        context->bit_rate_tolerance = context->bit_rate * av_q2d(fps) + 1;
     }
     else
     {
@@ -257,10 +295,11 @@ int encavcodecInit( hb_work_object_t * w, hb_job_t * job )
 
     if( hb_avcodec_open( context, codec ) )
     {
-        hb_log( "hb_work_encavcodec_init: avcodec_open failed" );
+        hb_log( "encavcodecInit: avcodec_open failed" );
     }
     pv->context = context;
 
+    job->areBframes = 0;
     if ( context->has_b_frames )
     {
         job->areBframes = 1;
@@ -284,7 +323,7 @@ void encavcodecClose( hb_work_object_t * w )
 {
     hb_work_private_t * pv = w->private_data;
 
-    if( pv->context )
+    if( pv->context && pv->context->codec )
     {
         hb_deep_log( 2, "encavcodec: closing libavcodec" );
         avcodec_flush_buffers( pv->context );
@@ -506,6 +545,12 @@ int encavcodecWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
             }
             buf = process_delay_list( pv, buf );
         }
+
+        if( job->pass == 1 )
+        {
+            /* Write stats */
+            fprintf( pv->file, "%s", pv->context->stats_out );
+        }
     }
     else
     {
@@ -516,12 +561,6 @@ int encavcodecWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
 
     av_free( frame );
 
-    if( job->pass == 1 )
-    {
-        /* Write stats */
-        fprintf( pv->file, "%s", pv->context->stats_out );
-    }
-
     *buf_out = buf;
 
     return HB_WORK_OK;
index 63f3e94cd3882b023acca4b528b024f89c89d9cf..287f677fa19706f4851a086977c614bc102ec3cc 100644 (file)
@@ -103,13 +103,20 @@ static int MKVInit( hb_mux_object_t * m )
             if (job->areBframes)
                 track->minCache = 1;
             break;
-        case HB_VCODEC_FFMPEG:
+        case HB_VCODEC_FFMPEG_MPEG4:
             track->codecID = MK_VCODEC_MP4ASP;
             track->codecPrivate = job->config.mpeg4.bytes;
             track->codecPrivateSize = job->config.mpeg4.length;
             if (job->areBframes)
                 track->minCache = 1;
             break;
+        case HB_VCODEC_FFMPEG_MPEG2:
+            track->codecID = MK_VCODEC_MPEG2;
+            track->codecPrivate = job->config.mpeg4.bytes;
+            track->codecPrivateSize = job->config.mpeg4.length;
+            if (job->areBframes)
+                track->minCache = 1;
+            break;
         case HB_VCODEC_THEORA:
             {
                 int i;
@@ -451,7 +458,7 @@ static int MKVMux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
     mk_addFrameData(m->file, mux_data->track, buf->data, buf->size);
     mk_setFrameFlags(m->file, mux_data->track, timecode,
                      (((job->vcodec == HB_VCODEC_X264 || 
-                        job->vcodec == HB_VCODEC_FFMPEG) && 
+                        (job->vcodec & HB_VCODEC_FFMPEG_MASK)) && 
                        mux_data == job->mux_data) ? 
                             (buf->frametype == HB_FRAME_IDR) : 
                             ((buf->frametype & HB_FRAME_KEY) != 0)), 0 );
index 9387d64994c72fe84893ffc22ba0e549af88272d..19a14a0b1c21e1e7128c90e22b4f4c6dc2469970 100644 (file)
@@ -154,7 +154,7 @@ static int MP4Init( hb_mux_object_t * m )
                        MP4AddIPodUUID(m->file, mux_data->track);
                }
     }
-    else /* FFmpeg or XviD */
+    else if ( job->vcodec == HB_VCODEC_FFMPEG_MPEG4 ) /* FFmpeg MPEG-4 */
     {
         MP4SetVideoProfileLevel( m->file, MPEG4_SP_L3 );
         mux_data->track = MP4AddVideoTrack( m->file, 90000,
@@ -182,6 +182,37 @@ static int MP4Init( hb_mux_object_t * m )
             return 0;
         }
     }
+    else if ( job->vcodec == HB_VCODEC_FFMPEG_MPEG2 ) /* FFmpeg MPEG-2 */
+    {
+        mux_data->track = MP4AddVideoTrack( m->file, 90000,
+                MP4_INVALID_DURATION, job->width, job->height,
+                MP4_MPEG2_VIDEO_TYPE );
+        if (mux_data->track == MP4_INVALID_TRACK_ID)
+        {
+            hb_error("muxmp4.c: MP4AddVideoTrack failed!");
+            *job->die = 1;
+            return 0;
+        }
+
+        /* Tune track chunk duration */
+        if( !MP4TuneTrackDurationPerChunk( m, mux_data->track ))
+        {
+            return 0;
+        }
+
+        /* VOL from FFmpeg */
+        if (!(MP4SetTrackESConfiguration( m->file, mux_data->track,
+                job->config.mpeg4.bytes, job->config.mpeg4.length )))
+        {
+            hb_error("muxmp4.c: MP4SetTrackESConfiguration failed!");
+            *job->die = 1;
+            return 0;
+        }
+    }
+    else
+    {
+        hb_error("muxmp4.c: Unsupported video encoder!");
+    }
 
     // COLR atom for color and gamma correction.
     // Per the notes at:
@@ -887,7 +918,7 @@ static int MP4Mux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
         /* Video */
 
         if( job->vcodec == HB_VCODEC_X264 ||
-            job->vcodec == HB_VCODEC_FFMPEG )
+            ( job->vcodec & HB_VCODEC_FFMPEG_MASK ) )
         {
             if ( buf && buf->start < buf->renderOffset )
             {
@@ -907,7 +938,7 @@ static int MP4Mux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
             return 0;
 
         if( job->vcodec == HB_VCODEC_X264 ||
-            job->vcodec == HB_VCODEC_FFMPEG )
+            ( job->vcodec & HB_VCODEC_FFMPEG_MASK ) )
         {
             // x264 supplies us with DTS, so offset is PTS - DTS
             offset = buf->start - buf->renderOffset;
@@ -945,7 +976,7 @@ static int MP4Mux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
         }
 
         if( job->vcodec == HB_VCODEC_X264 ||
-            job->vcodec == HB_VCODEC_FFMPEG )
+            ( job->vcodec & HB_VCODEC_FFMPEG_MASK ) )
         {
             // x264 supplies us with DTS
             if ( m->delay_buf )
@@ -1017,7 +1048,8 @@ static int MP4Mux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
     }
 
     /* Here's where the sample actually gets muxed. */
-    if( ( job->vcodec == HB_VCODEC_X264 || job->vcodec == HB_VCODEC_FFMPEG )
+    if( ( job->vcodec == HB_VCODEC_X264 ||
+        ( job->vcodec & HB_VCODEC_FFMPEG_MASK ) )
         && mux_data == job->mux_data )
     {
         /* Compute dependency flags.
index 901551f55e3d43e2885ab2aa22aec7b702f5fc39..89fd90b978e652441fa51b82785a47bb5068d4ae 100644 (file)
@@ -275,7 +275,7 @@ static void ScanFunc( void * _data )
 
         job->keep_ratio = 1;
 
-        job->vcodec     = HB_VCODEC_FFMPEG;
+        job->vcodec     = HB_VCODEC_FFMPEG_MPEG4;
         job->vquality   = -1.0;
         job->vbitrate   = 1000;
         job->pass       = 0;
index c8caff7b87773138e83e405de0174cc2ab1fcd79..e8c2a4e1e75e3d49a782e458616f9dc9f93795a3 100644 (file)
@@ -264,8 +264,12 @@ void hb_display_job_info( hb_job_t * job )
         /* Video encoder */
         switch( job->vcodec )
         {
-            case HB_VCODEC_FFMPEG:
-                hb_log( "   + encoder: FFmpeg" );
+            case HB_VCODEC_FFMPEG_MPEG4:
+                hb_log( "   + encoder: FFmpeg MPEG-4" );
+                break;
+
+            case HB_VCODEC_FFMPEG_MPEG2:
+                hb_log( "   + encoder: FFmpeg MPEG-2" );
                 break;
 
             case HB_VCODEC_X264:
@@ -452,7 +456,7 @@ static void do_job( hb_job_t * job )
     {
         hb_set_anamorphic_size(job, &job->width, &job->height, &job->anamorphic.par_width, &job->anamorphic.par_height);
 
-        if( job->vcodec == HB_VCODEC_FFMPEG )
+        if( job->vcodec & HB_VCODEC_FFMPEG_MASK )
         {
             /* Just to make working with ffmpeg even more fun,
                lavc's MPEG-4 encoder can't handle PAR values >= 255,
@@ -722,8 +726,13 @@ static void do_job( hb_job_t * job )
         /* Video encoder */
         switch( job->vcodec )
         {
-        case HB_VCODEC_FFMPEG:
+        case HB_VCODEC_FFMPEG_MPEG4:
             w = hb_get_work( WORK_ENCAVCODEC );
+            w->codec_param = CODEC_ID_MPEG4;
+            break;
+        case HB_VCODEC_FFMPEG_MPEG2:
+            w = hb_get_work( WORK_ENCAVCODEC );
+            w->codec_param = CODEC_ID_MPEG2VIDEO;
             break;
         case HB_VCODEC_X264:
             w = hb_get_work( WORK_ENCX264 );
@@ -993,7 +1002,7 @@ static void do_job( hb_job_t * job )
         w = muxer;
     }
 
-    hb_buffer_t      * buf_in, * buf_out;
+    hb_buffer_t      * buf_in, * buf_out = NULL;
 
     while ( !*job->die && !*w->done && w->status != HB_WORK_DONE )
     {
index e957c7cd70adba83c9f810845af1af753b58f2f8..c6363a036cb1b454440e38233cbcfb65312e5c76 100644 (file)
@@ -61,7 +61,7 @@ static char * decomb_opt            = 0;
 static int    rotate                = 0;
 static char * rotate_opt            = 0;
 static int    grayscale   = 0;
-static int    vcodec      = HB_VCODEC_FFMPEG;
+static int    vcodec      = HB_VCODEC_FFMPEG_MPEG4;
 static hb_list_t * audios = NULL;
 static hb_audio_config_t * audio = NULL;
 static int    num_audio_tracks = 0;
@@ -3169,7 +3169,15 @@ static int ParseOptions( int argc, char ** argv )
             case 'e':
                 if( !strcasecmp( optarg, "ffmpeg" ) )
                 {
-                    vcodec = HB_VCODEC_FFMPEG;
+                    vcodec = HB_VCODEC_FFMPEG_MPEG4;
+                }
+                else if( !strcasecmp( optarg, "ffmpeg4" ) )
+                {
+                    vcodec = HB_VCODEC_FFMPEG_MPEG4;
+                }
+                else if( !strcasecmp( optarg, "ffmpeg2" ) )
+                {
+                    vcodec = HB_VCODEC_FFMPEG_MPEG2;
                 }
                 else if( !strcasecmp( optarg, "x264" ) )
                 {