]> granicus.if.org Git - handbrake/commitdiff
libhb: bob deinterlacing
authorjstebbins <jstebbins.hb@gmail.com>
Tue, 1 May 2012 17:17:55 +0000 (17:17 +0000)
committerjstebbins <jstebbins.hb@gmail.com>
Tue, 1 May 2012 17:17:55 +0000 (17:17 +0000)
This is jbrjake's patch for bob deinterlacing applied to decomb and deinterlace
filters.  Thanks to yeasah's for refinements and testing of this patch.

git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4625 b64f7644-9d1e-0410-96f1-a4d463321fa5

gtk/src/hb-backend.c
libhb/decomb.c
libhb/deinterlace.c
macosx/Controller.m
test/test.c

index af1b890e5ad10e2a84b36ee891e70f2961489bb4..b3ca4afa79cecc57f966cef34724ea4c40227771 100644 (file)
@@ -202,6 +202,7 @@ static options_map_t d_decomb_opts[] =
        {"Custom", "custom", 1, ""},
        {"Default","default",2, NULL},
        {"Fast",   "fast",   3, "7:2:6:9:1:80"},
+       {"Bob",    "bob",    4, "455"},
 };
 combo_opts_t decomb_opts =
 {
@@ -211,11 +212,12 @@ combo_opts_t decomb_opts =
 
 static options_map_t d_deint_opts[] =
 {
-       {"Off",    "off",   0, ""},
-       {"Custom", "custom", 1, ""},
-       {"Fast",   "fast",   2, "-1:-1:-1:0:1"},
-       {"Slow",   "slow",   3, "2:-1:-1:0:1"},
-       {"Slower", "slower", 4, "0:-1:-1:0:1"},
+       {"Off",    "off",    0,  ""},
+       {"Custom", "custom", 1,  ""},
+       {"Fast",   "fast",   2,  "0:-1:-1:0:1"},
+       {"Slow",   "slow",   3,  "1:-1:-1:0:1"},
+       {"Slower", "slower", 4,  "3:-1:-1:0:1"},
+       {"Bob",    "bob",    5, "15:-1:-1:0:1"},
 };
 combo_opts_t deint_opts =
 {
index fae95caea2d03e523436149950c56579c716f20a..74f0a7b35a7bc7671946db3e827b070b4675e267 100644 (file)
@@ -27,13 +27,14 @@ Defaults:
 Original "Faster" settings:
     7:2:6:9:1:80:16:16:10:20:20:4:2:50:24:1:-1
 *****/
-
 #define MODE_YADIF       1 // Use yadif
 #define MODE_BLEND       2 // Use blending interpolation
 #define MODE_CUBIC       4 // Use cubic interpolation
 #define MODE_EEDI2       8 // Use EEDI2 interpolation
 #define MODE_MCDEINT    16 // Post-process with mcdeint
 #define MODE_MASK       32 // Output combing masks instead of pictures
+#define MODE_BOB        64 // Deinterlace each field to a separate frame
+
 #define MODE_GAMMA      128 // Scale gamma when decombing
 #define MODE_FILTER     256 // Filter combing mask
 #define MODE_COMPOSITE  512 // Overlay combing mask onto picture
@@ -216,8 +217,6 @@ struct hb_filter_private_s
     hb_lock_t      ** eedi2_begin_lock;     // Thread has work
     hb_lock_t      ** eedi2_complete_lock;  // Thread has completed work
     eedi2_arguments_t *eedi2_arguments;    // Arguments to thread for work
-
-//    int              alternator;           // for bobbing parity when framedoubling
 };
 
 static int hb_decomb_init( hb_filter_object_t * filter,
@@ -328,7 +327,6 @@ void draw_mask_box( hb_filter_private_t * pv )
     int stride = pv->ref_stride[0];
     uint8_t * mskp = ( pv->mode & MODE_FILTER ) ? pv->mask_filtered[0] : pv->mask[0];
 
-
     int block_x, block_y;
     for( block_x = 0; block_x < box_width; block_x++)
     {
@@ -364,7 +362,6 @@ void apply_mask_line( uint8_t * srcp,
 
 void apply_mask( hb_filter_private_t * pv )
 {
-
     /* draw_boxes */
     draw_mask_box( pv );
 
@@ -681,7 +678,6 @@ void filter_combing_mask( hb_filter_private_t * pv )
 
             for( x = 0; x < pv->width[k]-1; x++ )
             {
-
                 h_count = v_count = 0;
                 if( x == 0 )
                 {
@@ -973,7 +969,6 @@ void detect_gamma_combed_segment( hb_filter_private_t * pv, int segment_start, i
        picked up from neuron2's Decomb plugin for
        AviSynth and tritical's IsCombedT and
        IsCombedTIVTC plugins.                       */
-
     int x, y, k, width, height;
 
     /* Comb scoring algorithm */
@@ -2452,6 +2447,8 @@ static int hb_decomb_work( hb_filter_object_t * filter,
 {
     hb_filter_private_t * pv = filter->private_data;
     hb_buffer_t * in = *buf_in;
+    hb_buffer_t * last = NULL, * out = NULL;
+    uint8_t duplicate = 0;
 
     if ( in->size <= 0 )
     {
@@ -2460,104 +2457,134 @@ static int hb_decomb_work( hb_filter_object_t * filter,
         return HB_FILTER_DONE;
     }
 
-    hb_avpicture_fill( &pv->pic_in, in );
-
-    /* Determine if top-field first layout */
-    int tff;
-    if( pv->parity < 0 )
+    do
     {
-        tff = !!(in->s.flags & PIC_FLAG_TOP_FIELD_FIRST);
-    }
-    else
-    {
-        tff = (pv->parity & 1) ^ 1;
-    }
+        hb_avpicture_fill( &pv->pic_in, in );
 
-    /* Store current frame in yadif cache */
-    store_ref( (const uint8_t**)pv->pic_in.data, pv );
+        /* Determine if top-field first layout */
+        int tff;
+        if( pv->parity < 0 )
+        {
+            tff = !!(in->s.flags & PIC_FLAG_TOP_FIELD_FIRST);
+        }
+        else
+        {
+            tff = (pv->parity & 1) ^ 1;
+        }
 
-    /* If yadif is not ready, store another ref and return FILTER_DELAY */
-    if( pv->yadif_ready == 0 )
-    {
-        store_ref( (const uint8_t**)pv->pic_in.data, pv );
+        /* Store current frame in yadif cache */
+        if( !duplicate )
+        {
+            store_ref( (const uint8_t**)pv->pic_in.data, pv );
+        }
 
-        pv->buf_settings->s = in->s;
-        hb_buffer_move_subs( pv->buf_settings, in );
+        /* If yadif is not ready, store another ref and return FILTER_DELAY */
+        if( pv->yadif_ready == 0 )
+        {
+            store_ref( (const uint8_t**)pv->pic_in.data, pv );
 
-        pv->yadif_ready = 1;
+            pv->buf_settings->s = in->s;
+            hb_buffer_move_subs( pv->buf_settings, in );
 
-        return HB_FILTER_DELAY;
-    }
+            pv->yadif_ready = 1;
 
-    /* Perform yadif filtering */        
-    int frame, out_frame;
-    for( frame = 0; frame <= ( ( pv->mode & MODE_MCDEINT ) ? 1 : 0 ) ; frame++ )
-// This would be what to use for bobbing: for( frame = 0; frame <= 0 ; frame++ )
-    {
+            return HB_FILTER_DELAY;
+        }
 
-#if 0
-        /* Perhaps skip the second run if the frame is uncombed? */
-        if( frame && !pv->yadif_arguments[0].is_combed )
+        /* deinterlace both fields if mcdeint is enabled without bob */
+        int frame, out_frame, num_frames = 1;
+        if( ( pv->mode & (MODE_MCDEINT | MODE_BOB) ) == MODE_MCDEINT )
+            num_frames = 2;
+        
+        /* Perform yadif filtering */        
+        for( frame = 0; frame < num_frames; frame++ )
         {
-            break;
-        }
-#endif
-        int parity = frame ^ tff ^ 1;
 
-// This will be for bobbing
 #if 0
-        if( pv->alternator )
+            /* Perhaps skip the second run if the frame is uncombed? */
+            if( frame && !pv->yadif_arguments[0].is_combed )
+            {
+                break;
+            }
+#endif        
+            int parity = frame ^ tff ^ 1 ^ duplicate;
+            pv->tff = !parity;
+
+            hb_buffer_t *b = pv->buf_out[!(frame^1)];
+            hb_avpicture_fill( &pv->pic_out, b );
+
+            /* XXX
+                Should check here and only bother filtering field 2 when
+               field 1 was detected as combed.
+               And when it's not, it's a progressive frame,
+               so mcdeint should be skipped...
+            */
+            yadif_filter( pv->pic_out.data, parity, tff, pv );
+
+            /* Commented out code in the line below would skip mcdeint
+               on uncombed frames. Possibly a bad idea, since mcdeint
+               maintains the same snow context for the entire video... */
+            if( pv->mcdeint_mode >= 0 /* && pv->yadif_arguments[0].is_combed */)
+            {
+                /* Perform mcdeint filtering */
+                b = pv->buf_out[(frame^1)];
+                hb_avpicture_fill( &pv->pic_in, b );
+
+                mcdeint_filter( pv->pic_in.data, pv->pic_out.data, parity, pv->width, pv->height, &pv->mcdeint );
+
+                out_frame = frame ^ 1;
+            }
+            else
+            {
+                out_frame = !(frame ^ 1);
+            }
+        }
+
+        // Add to list of output buffers (should be at most 2)
+        if ( out == NULL )
         {
-            parity = !parity;
-            pv->alternator = 0;
+            last = out = pv->buf_out[out_frame];
         }
         else
         {
-            pv->alternator = 1;
+            last->next = pv->buf_out[out_frame];
+            last = last->next;
         }
-#endif
-        pv->tff = !parity;
-
-        hb_buffer_t *b = pv->buf_out[!(frame^1)];
-        hb_avpicture_fill( &pv->pic_out, b );
-
-        /* XXX
-            Should check here and only bother filtering field 2 when
-           field 1 was detected as combed.
-           And when it's not, it's a progressive frame,
-           so mcdeint should be skipped...
-        */
-        yadif_filter( pv->pic_out.data, parity, tff, pv );
-
-        /* Commented out code in the line below would skip mcdeint
-           on uncombed frames. Possibly a bad idea, since mcdeint
-           maintains the same snow context for the entire video... */
-        if( pv->mcdeint_mode >= 0 /* && pv->yadif_arguments[0].is_combed */)
-        {
-            /* Perform mcdeint filtering */
-            b = pv->buf_out[(frame^1)];
-            hb_avpicture_fill( &pv->pic_in, b );
 
-            mcdeint_filter( pv->pic_in.data, pv->pic_out.data, parity, pv->width, pv->height, &pv->mcdeint );
+        // Allocate a replacement for the buffer we just consumed
+        pv->buf_out[out_frame] = hb_video_buffer_init( pv->width[0], pv->height[0] );
 
-            out_frame = frame ^ 1;
-        }
-        else
+        /* Copy buffered settings to output buffer settings */
+        last->s = pv->buf_settings->s;
+
+        if ( !duplicate )
         {
-            out_frame = !(frame ^ 1);
+            hb_buffer_move_subs( last, pv->buf_settings );
         }
-    }
-    *buf_out = pv->buf_out[out_frame];
-    // Allocate a replacement for the buffer we just consumed
-    pv->buf_out[out_frame] = hb_video_buffer_init( pv->width[0], pv->height[0] );
 
-    /* Copy buffered settings to output buffer settings */
-    (*buf_out)->s = pv->buf_settings->s;
-    hb_buffer_move_subs( *buf_out, pv->buf_settings );
+        /* if this frame was deinterlaced and bob mode is engaged, halve
+           the duration of the saved timestamp, and request a duplicate. */
+        if( pv->mode & MODE_BOB && pv->yadif_arguments[0].is_combed == 1 )
+        {
+            if ( !duplicate )
+            {
+                last->s.stop -= (last->s.stop - last->s.start) / 2LL;
+                duplicate = 1;
+            }
+            else
+            {
+                last->s.start = out->s.stop;
+                last->s.new_chap = 0;
+                duplicate = 0;
+            }
+        }
+    } while ( duplicate );
 
     /* Replace buffered settings with input buffer settings */
     pv->buf_settings->s = in->s;
     hb_buffer_move_subs( pv->buf_settings, in );
 
+    *buf_out = out;
+
     return HB_FILTER_OK;
 }
index 0292078052c87ecd0e8fec809b46ad8ec49ffe15..4911f4bbca2ca25f851e8410dd163b23d4d56d80 100644 (file)
 #include "mpeg2dec/mpeg2.h"
 #include "mcdeint.h"
 
-#define YADIF_MODE_DEFAULT     -1
+// yadif_mode is a bit vector with the following flags
+// Note that 2PASS should be enabled when using MCDEINT
+#define MODE_YADIF_ENABLE       1
+#define MODE_YADIF_SPATIAL      2
+#define MODE_YADIF_2PASS        4
+#define MODE_YADIF_BOB          8
+
+#define YADIF_MODE_DEFAULT      0
 #define YADIF_PARITY_DEFAULT   -1
 
 #define MCDEINT_MODE_DEFAULT   -1
@@ -155,7 +162,7 @@ static void yadif_filter_line( uint8_t *dst,
         YADIF_CHECK(-1) YADIF_CHECK(-2) }} }}
         YADIF_CHECK( 1) YADIF_CHECK( 2) }} }}
 
-        if( pv->yadif_mode < 2 )
+        if( pv->yadif_mode & MODE_YADIF_SPATIAL )
         {
             int b = (prev2[-2*refs] + next2[-2*refs])>>1;
             int f = (prev2[+2*refs] + next2[+2*refs])>>1;
@@ -420,7 +427,7 @@ static int hb_deinterlace_init( hb_filter_object_t * filter,
     pv->cpu_count = hb_get_cpu_count();
 
     /* Allocate yadif specific buffers */
-    if( pv->yadif_mode >= 0 )
+    if( pv->yadif_mode & MODE_YADIF_ENABLE )
     {
         int i, j;
         for( i = 0; i < 3; i++ )
@@ -507,7 +514,7 @@ static void hb_deinterlace_close( hb_filter_object_t * filter )
     }
 
     /* Cleanup yadif specific buffers */
-    if( pv->yadif_mode >= 0 )
+    if( pv->yadif_mode & MODE_YADIF_ENABLE )
     {
         int i;
         for( i = 0; i<3*3; i++ )
@@ -556,6 +563,8 @@ static int hb_deinterlace_work( hb_filter_object_t * filter,
     AVPicture pic_out;
     hb_filter_private_t * pv = filter->private_data;
     hb_buffer_t * in = *buf_in;
+    hb_buffer_t * last = NULL, * out = NULL;
+    uint8_t duplicate = 0;
 
     if ( in->size <= 0 )
     {
@@ -564,99 +573,144 @@ static int hb_deinterlace_work( hb_filter_object_t * filter,
         return HB_FILTER_DONE;
     }
 
-    hb_avpicture_fill( &pic_in, in );
-
-    /* Use libavcodec deinterlace if yadif_mode < 0 */
-    if( pv->yadif_mode < 0 )
+    do
     {
-        hb_avpicture_fill( &pic_out, pv->buf_out[0] );
+        hb_avpicture_fill( &pic_in, in );
 
-        avpicture_deinterlace( &pic_out, &pic_in, pv->buf_out[0]->f.fmt, 
-                               pv->buf_out[0]->f.width, pv->buf_out[0]->f.height );
+        /* Use libavcodec deinterlace if yadif_mode < 0 */
+        if( !( pv->yadif_mode & MODE_YADIF_ENABLE ) )
+        {
+            hb_avpicture_fill( &pic_out, pv->buf_out[0] );
 
-        pv->buf_out[0]->s = in->s;
-        hb_buffer_move_subs( pv->buf_out[0], in );
+            avpicture_deinterlace( &pic_out, &pic_in, pv->buf_out[0]->f.fmt, 
+                                   pv->buf_out[0]->f.width, pv->buf_out[0]->f.height );
 
-        *buf_out = pv->buf_out[0];
+            pv->buf_out[0]->s = in->s;
+            hb_buffer_move_subs( pv->buf_out[0], in );
 
-        // Allocate a replacement for the buffer we just consumed
-        hb_buffer_t * b = pv->buf_out[0];
-        pv->buf_out[0] = hb_video_buffer_init( b->f.width, b->f.height );
+            *buf_out = pv->buf_out[0];
 
-        return HB_FILTER_OK;
-    }
+            // Allocate a replacement for the buffer we just consumed
+            hb_buffer_t * b = pv->buf_out[0];
+            pv->buf_out[0] = hb_video_buffer_init( b->f.width, b->f.height );
 
-    /* Determine if top-field first layout */
-    int tff;
-    if( pv->yadif_parity < 0 )
-    {
-        tff = !!(in->s.flags & PIC_FLAG_TOP_FIELD_FIRST);
-    }
-    else
-    {
-        tff = (pv->yadif_parity & 1) ^ 1;
-    }
-
-    /* Store current frame in yadif cache */
-    yadif_store_ref( (const uint8_t**)pic_in.data, pv );
+            return HB_FILTER_OK;
+        }
 
-    /* If yadif is not ready, store another ref and return HB_FILTER_DELAY */
-    if( pv->yadif_ready == 0 )
-    {
-        yadif_store_ref( (const uint8_t**)pic_in.data, pv );
+        /* Determine if top-field first layout */
+        int tff;
+        if( pv->yadif_parity < 0 )
+        {
+            tff = !!(in->s.flags & PIC_FLAG_TOP_FIELD_FIRST);
+        }
+        else
+        {
+            tff = (pv->yadif_parity & 1) ^ 1;
+        }
 
-        pv->buf_settings->s = in->s;
-        hb_buffer_move_subs( pv->buf_settings, in );
+        /* Store current frame in yadif cache */
+        if (!duplicate)
+        {
+            yadif_store_ref( (const uint8_t**)pic_in.data, pv );
+        }
 
-        pv->yadif_ready = 1;
+        /* If yadif is not ready, store another ref and return HB_FILTER_DELAY */
+        if( pv->yadif_ready == 0 )
+        {
+            yadif_store_ref( (const uint8_t**)pic_in.data, pv );
 
-        return HB_FILTER_DELAY;
-    }
+            pv->buf_settings->s = in->s;
+            hb_buffer_move_subs( pv->buf_settings, in );
 
-    /* Perform yadif and mcdeint filtering */
-    int frame;
-    int out_frame;
-    hb_buffer_t * b;
-    for( frame = 0; frame <= (pv->yadif_mode & 1); frame++ )
-    {
-        AVPicture pic_yadif_out;
-        int parity = frame ^ tff ^ 1;
+            pv->yadif_ready = 1;
 
-        b = pv->buf_out[!(frame^1)];
-        hb_avpicture_fill( &pic_yadif_out, b );
+            return HB_FILTER_DELAY;
+        }
 
-        yadif_filter( pic_yadif_out.data, parity, tff, pv );
+        /* deinterlace both fields if mcdeint is enabled without bob */
+        int frame, num_frames = 1;
+        if( ( pv->yadif_mode & MODE_YADIF_2PASS ) &&
+           !( pv->yadif_mode & MODE_YADIF_BOB ) )
+        {
+            num_frames = 2;
+        }
 
-        if( pv->mcdeint_mode >= 0 )
+        /* Perform yadif and mcdeint filtering */
+        int out_frame;
+        hb_buffer_t * b;
+        for( frame = 0; frame < num_frames; frame++ )
         {
-            b = pv->buf_out[(frame^1)];
-            hb_avpicture_fill( &pic_out, b );
+            AVPicture pic_yadif_out;
+            int parity = frame ^ tff ^ 1 ^ duplicate;
 
-            mcdeint_filter( pic_out.data, pic_yadif_out.data, parity, 
-                            pv->width, pv->height, &pv->mcdeint );
+            b = pv->buf_out[!(frame^1)];
+            hb_avpicture_fill( &pic_yadif_out, b );
 
-            out_frame = (frame^1);
+            yadif_filter( pic_yadif_out.data, parity, tff, pv );
+
+            if( pv->mcdeint_mode >= 0 )
+            {
+                b = pv->buf_out[(frame^1)];
+                hb_avpicture_fill( &pic_out, b );
+
+                mcdeint_filter( pic_out.data, pic_yadif_out.data, parity, 
+                                pv->width, pv->height, &pv->mcdeint );
+
+                out_frame = (frame^1);
+            }
+            else
+            {
+                out_frame = !(frame^1);
+            }
+        }
+
+        // Add to list of output buffers (should be at most 2)
+        if ( out == NULL )
+        {
+            last = out = pv->buf_out[out_frame];
         }
         else
         {
-            out_frame = !(frame^1);
+            last->next = pv->buf_out[out_frame];
+            last = last->next;
         }
-    }
-    *buf_out = pv->buf_out[out_frame];
 
-    // Allocate a replacement for the buffer we just consumed
-    b = pv->buf_out[out_frame];
-    pv->buf_out[out_frame] = hb_video_buffer_init( b->f.width, b->f.height );
+        // Allocate a replacement for the buffer we just consumed
+        b = pv->buf_out[out_frame];
+        pv->buf_out[out_frame] = hb_video_buffer_init( b->f.width, b->f.height );
+
+        /* Copy buffered settings to output buffer settings */
+        last->s = pv->buf_settings->s;
+
+        if ( !duplicate )
+        {
+            hb_buffer_move_subs( last, pv->buf_settings );
+        }
 
-    /* Copy buffered settings to output buffer settings */
-    (*buf_out)->s = pv->buf_settings->s;
-    hb_buffer_move_subs( *buf_out, pv->buf_settings );
+        /* if bob mode is engaged, halve the duration of the
+         * timestamp, and request a duplicate. */
+        if( pv->yadif_mode & MODE_YADIF_BOB )
+        {
+            if ( !duplicate )
+            {
+                last->s.stop -= (last->s.stop - last->s.start) / 2LL;
+                duplicate = 1;
+            }
+            else
+            {
+                last->s.start = out->s.stop;
+                last->s.new_chap = 0;
+                duplicate = 0;
+            }
+        }
+    } while ( duplicate );
 
     /* Replace buffered settings with input buffer settings */
     pv->buf_settings->s = in->s;
     hb_buffer_move_subs( pv->buf_settings, in );
 
+    *buf_out = out;
+
     return HB_FILTER_OK;
 }
 
-
index 88a146ae05a13eb9bb2d5e616ade32766f1c209a..9029e9b5c11f5d966054f914e8383be73a5e33c7 100644 (file)
@@ -3366,17 +3366,17 @@ bool one_burned = FALSE;
         else if ([fPictureController deinterlace] == 2)
         {
             /* Run old deinterlacer fd by default */
-            hb_add_filter( job, filter, "-1" );
+            hb_add_filter( job, filter, "0" );
         }
         else if ([fPictureController deinterlace] == 3)
         {
             /* Yadif mode 0 (without spatial deinterlacing.) */
-            hb_add_filter( job, filter, "2" );            
+            hb_add_filter( job, filter, "1" );            
         }
         else if ([fPictureController deinterlace] == 4)
         {
             /* Yadif (with spatial deinterlacing) */
-            hb_add_filter( job, filter, "0" );
+            hb_add_filter( job, filter, "3" );
         }
         
        }
@@ -3885,17 +3885,17 @@ bool one_burned = FALSE;
         else if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 2)
         {
             /* Run old deinterlacer fd by default */
-            hb_add_filter( job, filter, "-1" );
+            hb_add_filter( job, filter, "0" );
         }
         else if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 3)
         {
             /* Yadif mode 0 (without spatial deinterlacing.) */
-            hb_add_filter( job, filter, "2" );            
+            hb_add_filter( job, filter, "1" );            
         }
         else if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 4)
         {
             /* Yadif (with spatial deinterlacing) */
-            hb_add_filter( job, filter, "0" );            
+            hb_add_filter( job, filter, "3" );            
         }
         
         
index 113bfe63bf8a344132cdfd036e184a655e97bf70..cb23a6f4a56d35e397ff1ee97e4c9c1409154640 100644 (file)
@@ -3451,15 +3451,19 @@ static int ParseOptions( int argc, char ** argv )
                 {
                     if (!( strcmp( optarg, "fast" ) ))
                     {
-                        deinterlace_opt = "-1";
+                        deinterlace_opt = "0";
                     }
                     else if (!( strcmp( optarg, "slow" ) ))
                     {
-                        deinterlace_opt = "2";
+                        deinterlace_opt = "1";
                     }
                     else if (!( strcmp( optarg, "slower" ) ))
                     {
-                        deinterlace_opt = "0";
+                        deinterlace_opt = "3";
+                    }
+                    else if (!( strcmp( optarg, "bob" ) ))
+                    {
+                        deinterlace_opt = "15";
                     }
                     else
                     {
@@ -3507,7 +3511,18 @@ static int ParseOptions( int argc, char ** argv )
             case '5':
                 if( optarg != NULL )
                 {
-                    decomb_opt = strdup( optarg );
+                    if (!( strcmp( optarg, "fast" ) ))
+                    {
+                        decomb_opt = "7:2:6:9:1:80";
+                    }
+                    else if (!( strcmp( optarg, "bob" ) ))
+                    {
+                        decomb_opt = "455";
+                    }
+                    else
+                    {
+                        decomb_opt = strdup( optarg );
+                    }
                 }
                 decomb = 1;
                 break;