]> git.sesse.net Git - vlc/blobdiff - modules/video_filter/deinterlace.c
Qt: reindent
[vlc] / modules / video_filter / deinterlace.c
index 70d9b2ce4500ea35f2fd99728cc76fe08d3884ee..66ce1953226034436cc431271bb8dc7105d6d8d6 100644 (file)
@@ -98,7 +98,7 @@ static void RenderMean   ( filter_t *, picture_t *, picture_t * );
 static void RenderBlend  ( filter_t *, picture_t *, picture_t * );
 static void RenderLinear ( filter_t *, picture_t *, picture_t *, int );
 static void RenderX      ( picture_t *, picture_t * );
-static void RenderYadif  ( filter_t *, picture_t *, picture_t *, int, int );
+static int  RenderYadif  ( filter_t *, picture_t *, picture_t *, int, int );
 
 static void MergeGeneric ( void *, const void *, const void *, size_t );
 #if defined(CAN_COMPILE_C_ALTIVEC)
@@ -137,6 +137,8 @@ struct filter_sys_t
     void (*pf_merge) ( void *, const void *, const void *, size_t );
     void (*pf_end_merge) ( void );
 
+    mtime_t i_last_date;
+
     /* Yadif */
     picture_t *pp_history[HISTORY_SIZE];
 };
@@ -829,7 +831,8 @@ static void MergeNEON (void *restrict out, const void *in1,
                 "vst1.u8  {q10-q11}, [%[out],:128]!\n"
                 : [out] "+r" (outp), [in1] "+r" (in1p), [in2] "+r" (in2p)
                 :
-                : "q0", "q1", "q2", "memory");
+                : "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
+                  "q8", "q9", "q10", "q11", "memory");
     else
          while (outp < end)
             asm volatile (
@@ -845,7 +848,8 @@ static void MergeNEON (void *restrict out, const void *in1,
                 "vst1.u8  {q10-q11}, [%[out],:128]!\n"
                 : [out] "+r" (outp), [in1] "+r" (in1p), [in2] "+r" (in2p)
                 :
-                : "q0", "q1", "q2", "memory");
+                : "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
+                  "q8", "q9", "q10", "q11", "memory");
     n &= 15;
     if (n)
         MergeGeneric (outp, in1p, in2p, n);
@@ -1432,7 +1436,7 @@ typedef intptr_t x86_reg;
 /* yadif.h comes from vf_yadif.c of mplayer project */
 #include "yadif.h"
 
-static void RenderYadif( filter_t *p_filter, picture_t *p_dst, picture_t *p_src, int i_order, int i_field )
+static int RenderYadif( filter_t *p_filter, picture_t *p_dst, picture_t *p_src, int i_order, int i_field )
 {
     filter_sys_t *p_sys = p_filter->p_sys;
 
@@ -1515,12 +1519,17 @@ static void RenderYadif( filter_t *p_filter, picture_t *p_dst, picture_t *p_src,
 
         /* */
         p_dst->date = (p_next->date - p_cur->date) * i_order / 2 + p_cur->date;
+        return VLC_SUCCESS;
+    }
+    else if( !p_prev && !p_cur && p_next )
+    {
+        /* FIXME not good as it does not use i_order/i_field */
+        RenderX( p_dst, p_next );
+        return VLC_SUCCESS;
     }
     else
     {
-        /* Fallback to something simple
-         * XXX it is wrong when we have 2 pictures, we should not output a picture */
-        RenderX( p_dst, p_src );
+        return VLC_EGENERIC;
     }
 }
 
@@ -1530,72 +1539,105 @@ static void RenderYadif( filter_t *p_filter, picture_t *p_dst, picture_t *p_src,
 static picture_t *Deinterlace( filter_t *p_filter, picture_t *p_pic )
 {
     filter_sys_t *p_sys = p_filter->p_sys;
-    picture_t *p_pic_dst;
+    picture_t *p_dst[2];
 
     /* Request output picture */
-    p_pic_dst = filter_NewPicture( p_filter );
-    if( p_pic_dst == NULL )
+    p_dst[0] = filter_NewPicture( p_filter );
+    if( p_dst[0] == NULL )
     {
         picture_Release( p_pic );
         return NULL;
     }
+    picture_CopyProperties( p_dst[0], p_pic );
+
+    if( p_sys->b_double_rate )
+    {
+        p_dst[0]->p_next =
+        p_dst[1]         = filter_NewPicture( p_filter );
+        if( p_dst[1] )
+        {
+            picture_CopyProperties( p_dst[1], p_pic );
+            /* XXX it's not really good especially for the first picture, but
+             * I don't think that delaying by one frame is worth it */
+            if( p_sys->i_last_date > VLC_TS_INVALID && p_pic->date > VLC_TS_INVALID )
+                p_dst[1]->date = p_pic->date + (p_pic->date - p_sys->i_last_date) / 2;
+        }
+        p_sys->i_last_date = p_pic->date;
+    }
+    else
+    {
+        p_dst[1] = NULL;
+    }
 
     switch( p_sys->i_mode )
     {
         case DEINTERLACE_DISCARD:
-            RenderDiscard( p_filter, p_pic_dst, p_pic, 0 );
+            RenderDiscard( p_filter, p_dst[0], p_pic, 0 );
             break;
 
         case DEINTERLACE_BOB:
-#if 0
-            RenderBob( p_filter, pp_outpic[0], p_pic, !p_pic->b_top_field_first );
-            RenderBob( p_filter, pp_outpic[1], p_pic, p_pic->b_top_field_first );
-            break;
-#endif
+            RenderBob( p_filter, p_dst[0], p_pic, !p_pic->b_top_field_first );
+            if( p_dst[1] )
+                RenderBob( p_filter, p_dst[1], p_pic, p_pic->b_top_field_first );
+            break;;
 
         case DEINTERLACE_LINEAR:
-#if 0
-            RenderLinear( p_filter, pp_outpic[0], p_pic, !p_pic->b_top_field_first );
-            RenderLinear( p_filter, pp_outpic[1], p_pic, p_pic->b_top_field_first );
-#endif
-            msg_Err( p_filter, "doubling the frame rate is not supported yet" );
-            picture_Release( p_pic_dst );
-            picture_Release( p_pic );
-            return NULL;
+            RenderLinear( p_filter, p_dst[0], p_pic, !p_pic->b_top_field_first );
+            if( p_dst[1] )
+                RenderLinear( p_filter, p_dst[1], p_pic, p_pic->b_top_field_first );
+            break;
 
         case DEINTERLACE_MEAN:
-            RenderMean( p_filter, p_pic_dst, p_pic );
+            RenderMean( p_filter, p_dst[0], p_pic );
             break;
 
         case DEINTERLACE_BLEND:
-            RenderBlend( p_filter, p_pic_dst, p_pic );
+            RenderBlend( p_filter, p_dst[0], p_pic );
             break;
 
         case DEINTERLACE_X:
-            RenderX( p_pic_dst, p_pic );
+            RenderX( p_dst[0], p_pic );
             break;
 
         case DEINTERLACE_YADIF:
-            msg_Err( p_filter, "delaying frames is not supported yet" );
-            //RenderYadif( p_vout, pp_outpic[0], p_pic, 0, 0 );
-            picture_Release( p_pic_dst );
-            picture_Release( p_pic );
-            return NULL;
+            if( RenderYadif( p_filter, p_dst[0], p_pic, 0, 0 ) )
+                goto drop;
+            break;
 
         case DEINTERLACE_YADIF2X:
-            msg_Err( p_filter, "doubling the frame rate is not supported yet" );
-            //RenderYadif( p_vout, pp_outpic[0], p_pic, 0, !p_pic->b_top_field_first );
-            //RenderYadif( p_vout, pp_outpic[1], p_pic, 1, p_pic->b_top_field_first );
-            picture_Release( p_pic_dst );
-            picture_Release( p_pic );
-            return NULL;
+            if( RenderYadif( p_filter, p_dst[0], p_pic, 0, !p_pic->b_top_field_first ) )
+                goto drop;
+            if( p_dst[1] )
+                RenderYadif( p_filter, p_dst[1], p_pic, 1, p_pic->b_top_field_first );
+            break;
     }
 
-    picture_CopyProperties( p_pic_dst, p_pic );
-    p_pic_dst->b_progressive = true;
+    p_dst[0]->b_progressive = true;
+    if( p_dst[1] )
+        p_dst[1]->b_progressive = true;
 
     picture_Release( p_pic );
-    return p_pic_dst;
+    return p_dst[0];
+
+drop:
+    picture_Release( p_dst[0] );
+    if( p_dst[1] )
+        picture_Release( p_dst[1] );
+    picture_Release( p_pic );
+    return NULL;
+}
+
+static void Flush( filter_t *p_filter )
+{
+    filter_sys_t *p_sys = p_filter->p_sys;
+
+    p_sys->i_last_date = VLC_TS_INVALID;
+    for( int i = 0; i < HISTORY_SIZE; i++ )
+    {
+        if( p_sys->pp_history[i] )
+            picture_Release( p_sys->pp_history[i] );
+        p_sys->pp_history[i] = NULL;
+    }
 }
 
 static int Mouse( filter_t *p_filter,
@@ -1627,6 +1669,9 @@ static int Open( vlc_object_t *p_this )
     p_sys->i_mode = DEINTERLACE_BLEND;
     p_sys->b_double_rate = false;
     p_sys->b_half_height = true;
+    p_sys->i_last_date = VLC_TS_INVALID;
+    for( int i = 0; i < HISTORY_SIZE; i++ )
+        p_sys->pp_history[i] = NULL;
 
 #if defined(CAN_COMPILE_C_ALTIVEC)
     if( vlc_CPU() & CPU_CAPABILITY_ALTIVEC )
@@ -1694,6 +1739,7 @@ static int Open( vlc_object_t *p_this )
     p_filter->fmt_out.video = fmt;
     p_filter->fmt_out.i_codec = fmt.i_chroma;
     p_filter->pf_video_filter = Deinterlace;
+    p_filter->pf_video_flush  = Flush;
     p_filter->pf_video_mouse  = Mouse;
 
     msg_Dbg( p_filter, "deinterlacing" );
@@ -1708,6 +1754,7 @@ static void Close( vlc_object_t *p_this )
 {
     filter_t *p_filter = (filter_t*)p_this;
 
+    Flush( p_filter );
     free( p_filter->p_sys );
 }