[vlc-commits] Added partial support for > 8 bits YUV video in the deinterlace filter.

Laurent Aimar git at videolan.org
Fri May 25 21:20:30 CEST 2012


vlc | branch: master | Laurent Aimar <fenrir at videolan.org> | Fri May 25 20:09:26 2012 +0200| [4f93b728e8c007edf9e4af462ac4dc8eb28895ba] | committer: Laurent Aimar

Added partial support for > 8 bits YUV video in the deinterlace filter.

Only the basic modes are supported, blend is used as a fallback.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=4f93b728e8c007edf9e4af462ac4dc8eb28895ba
---

 modules/video_filter/deinterlace/deinterlace.c |   26 ++++++------
 modules/video_filter/deinterlace/merge.c       |   33 ++++++++++++++--
 modules/video_filter/deinterlace/merge.h       |   50 ++++++++++++++++--------
 3 files changed, 75 insertions(+), 34 deletions(-)

diff --git a/modules/video_filter/deinterlace/deinterlace.c b/modules/video_filter/deinterlace/deinterlace.c
index 37062f8..414f87b 100644
--- a/modules/video_filter/deinterlace/deinterlace.c
+++ b/modules/video_filter/deinterlace/deinterlace.c
@@ -164,35 +164,35 @@ void SetFilterMethod( filter_t *p_filter, const char *psz_method )
         p_sys->b_half_height = false;
         p_sys->b_use_frame_history = false;
     }
-    else if( !strcmp( psz_method, "x" ) )
+    else if( !strcmp( psz_method, "x" ) && p_sys->chroma->pixel_size == 1 )
     {
         p_sys->i_mode = DEINTERLACE_X;
         p_sys->b_double_rate = false;
         p_sys->b_half_height = false;
         p_sys->b_use_frame_history = false;
     }
-    else if( !strcmp( psz_method, "yadif" ) )
+    else if( !strcmp( psz_method, "yadif" ) && p_sys->chroma->pixel_size == 1 )
     {
         p_sys->i_mode = DEINTERLACE_YADIF;
         p_sys->b_double_rate = false;
         p_sys->b_half_height = false;
         p_sys->b_use_frame_history = true;
     }
-    else if( !strcmp( psz_method, "yadif2x" ) )
+    else if( !strcmp( psz_method, "yadif2x" ) && p_sys->chroma->pixel_size == 1 )
     {
         p_sys->i_mode = DEINTERLACE_YADIF2X;
         p_sys->b_double_rate = true;
         p_sys->b_half_height = false;
         p_sys->b_use_frame_history = true;
     }
-    else if( !strcmp( psz_method, "phosphor" ) )
+    else if( !strcmp( psz_method, "phosphor" ) && p_sys->chroma->pixel_size == 1 )
     {
         p_sys->i_mode = DEINTERLACE_PHOSPHOR;
         p_sys->b_double_rate = true;
         p_sys->b_half_height = false;
         p_sys->b_use_frame_history = true;
     }
-    else if( !strcmp( psz_method, "ivtc" ) )
+    else if( !strcmp( psz_method, "ivtc" ) && p_sys->chroma->pixel_size == 1 )
     {
         p_sys->i_mode = DEINTERLACE_IVTC;
         p_sys->b_double_rate = false;
@@ -210,7 +210,7 @@ void SetFilterMethod( filter_t *p_filter, const char *psz_method )
     {
         if( strcmp( psz_method, "blend" ) )
             msg_Err( p_filter,
-                     "no valid deinterlace mode provided, using \"blend\"" );
+                     "no valid/compatible deinterlace mode provided, using \"blend\"" );
 
         p_sys->i_mode = DEINTERLACE_BLEND;
         p_sys->b_double_rate = false;
@@ -598,7 +598,7 @@ int Open( vlc_object_t *p_this )
     const vlc_fourcc_t fourcc = p_filter->fmt_in.video.i_chroma;
     const vlc_chroma_description_t *chroma = vlc_fourcc_GetChromaDescription( fourcc );
     if( !vlc_fourcc_IsYUV( fourcc ) ||
-        !chroma || chroma->plane_count != 3 || chroma->pixel_size != 1 )
+        !chroma || chroma->plane_count != 3 || chroma->pixel_size > 2 )
     {
         msg_Err( p_filter, "Unsupported chroma (%4.4s)", (char*)&fourcc );
         return VLC_EGENERIC;
@@ -628,7 +628,7 @@ int Open( vlc_object_t *p_this )
     IVTCClearState( p_filter );
 
 #if defined(CAN_COMPILE_C_ALTIVEC)
-    if( vlc_CPU() & CPU_CAPABILITY_ALTIVEC )
+    if( chroma->pixel_size == 1 && (vlc_CPU() & CPU_CAPABILITY_ALTIVEC) )
     {
         p_sys->pf_merge = MergeAltivec;
         p_sys->pf_end_merge = NULL;
@@ -636,7 +636,7 @@ int Open( vlc_object_t *p_this )
     else
 #endif
 #if defined(CAN_COMPILE_SSE)
-    if( vlc_CPU() & CPU_CAPABILITY_SSE2 )
+    if( chroma->pixel_size == 1 && (vlc_CPU() & CPU_CAPABILITY_SSE2) )
     {
         p_sys->pf_merge = MergeSSE2;
         p_sys->pf_end_merge = EndMMX;
@@ -644,7 +644,7 @@ int Open( vlc_object_t *p_this )
     else
 #endif
 #if defined(CAN_COMPILE_MMXEXT)
-    if( vlc_CPU() & CPU_CAPABILITY_MMXEXT )
+    if( chroma->pixel_size == 1 && (vlc_CPU() & CPU_CAPABILITY_MMXEXT) )
     {
         p_sys->pf_merge = MergeMMXEXT;
         p_sys->pf_end_merge = EndMMX;
@@ -652,7 +652,7 @@ int Open( vlc_object_t *p_this )
     else
 #endif
 #if defined(CAN_COMPILE_3DNOW)
-    if( vlc_CPU() & CPU_CAPABILITY_3DNOW )
+    if( chroma->pixel_size == 1 && (vlc_CPU() & CPU_CAPABILITY_3DNOW) )
     {
         p_sys->pf_merge = Merge3DNow;
         p_sys->pf_end_merge = End3DNow;
@@ -660,7 +660,7 @@ int Open( vlc_object_t *p_this )
     else
 #endif
 #if defined __ARM_NEON__ // FIXME: runtime detect support
-    if( vlc_CPU() & CPU_CAPABILITY_NEON )
+    if( chroma->pixel_size == 1 && (vlc_CPU() & CPU_CAPABILITY_NEON) )
     {
         p_sys->pf_merge = MergeNEON;
         p_sys->pf_end_merge = NULL;
@@ -668,7 +668,7 @@ int Open( vlc_object_t *p_this )
     else
 #endif
     {
-        p_sys->pf_merge = MergeGeneric;
+        p_sys->pf_merge = chroma->pixel_size == 1 ? Merge8BitGeneric : Merge16BitGeneric;
         p_sys->pf_end_merge = NULL;
     }
 
diff --git a/modules/video_filter/deinterlace/merge.c b/modules/video_filter/deinterlace/merge.c
index 0a037b0..b3e6e59 100644
--- a/modules/video_filter/deinterlace/merge.c
+++ b/modules/video_filter/deinterlace/merge.c
@@ -45,8 +45,8 @@
  * Merge (line blending) routines
  *****************************************************************************/
 
-void MergeGeneric( void *_p_dest, const void *_p_s1,
-                   const void *_p_s2, size_t i_bytes )
+void Merge8BitGeneric( void *_p_dest, const void *_p_s1,
+                       const void *_p_s2, size_t i_bytes )
 {
     uint8_t* p_dest = (uint8_t*)_p_dest;
     const uint8_t *p_s1 = (const uint8_t *)_p_s1;
@@ -73,6 +73,31 @@ void MergeGeneric( void *_p_dest, const void *_p_s1,
     }
 }
 
+void Merge16BitGeneric( void *_p_dest, const void *_p_s1,
+                        const void *_p_s2, size_t i_bytes )
+{
+    uint16_t* p_dest = (uint16_t*)_p_dest;
+    const uint16_t *p_s1 = (const uint16_t *)_p_s1;
+    const uint16_t *p_s2 = (const uint16_t *)_p_s2;
+    uint16_t* p_end = p_dest + (i_bytes/2) - 4;
+
+    while( p_dest < p_end )
+    {
+        *p_dest++ = ( (uint32_t)(*p_s1++) + (uint32_t)(*p_s2++) ) >> 1;
+        *p_dest++ = ( (uint32_t)(*p_s1++) + (uint32_t)(*p_s2++) ) >> 1;
+        *p_dest++ = ( (uint32_t)(*p_s1++) + (uint32_t)(*p_s2++) ) >> 1;
+        *p_dest++ = ( (uint32_t)(*p_s1++) + (uint32_t)(*p_s2++) ) >> 1;
+    }
+
+    p_end += 4;
+
+    while( p_dest < p_end )
+    {
+        *p_dest++ = ( (uint32_t)(*p_s1++) + (uint32_t)(*p_s2++) ) >> 1;
+    }
+
+}
+
 #if defined(CAN_COMPILE_MMXEXT)
 void MergeMMXEXT( void *_p_dest, const void *_p_s1, const void *_p_s2,
                   size_t i_bytes )
@@ -246,7 +271,7 @@ void MergeNEON (void *restrict out, const void *in1,
 
     if (mis)
     {
-        MergeGeneric (outp, in1p, in2p, mis);
+        Merge8BitGeneric (outp, in1p, in2p, mis);
         outp += mis;
         in1p += mis;
         in2p += mis;
@@ -291,7 +316,7 @@ void MergeNEON (void *restrict out, const void *in1,
                   "q8", "q9", "q10", "q11", "memory");
     n &= 15;
     if (n)
-        MergeGeneric (outp, in1p, in2p, n);
+        Merge8BitGeneric (outp, in1p, in2p, n);
 }
 #endif
 
diff --git a/modules/video_filter/deinterlace/merge.h b/modules/video_filter/deinterlace/merge.h
index 999d842..7f4af07 100644
--- a/modules/video_filter/deinterlace/merge.h
+++ b/modules/video_filter/deinterlace/merge.h
@@ -41,18 +41,7 @@
 
    Note that you'll need to include vlc_filter.h and deinterlace.h
    to use these.
-*/
-#define Merge p_filter->p_sys->pf_merge
-#define EndMerge if(p_filter->p_sys->pf_end_merge) p_filter->p_sys->pf_end_merge
 
-/*****************************************************************************
- * Merge routines
- *****************************************************************************/
-
-/**
- * Generic routine to blend pixels from two picture lines.
- * No inline assembler acceleration.
- *
  * Note that the Open() call of the deinterlace filter automatically selects
  * the most appropriate merge routine based on the CPU capabilities.
  * You can call the most appropriate version automatically, from a function
@@ -65,20 +54,47 @@
  * Macro syntax:
  *   Merge( _p_dest, _p_s1, _p_s2, i_bytes );
  *
- * See also the EndMerge() macro, which must be called after the merge is
- * finished, if the Merge() macro was used to perform the merge.
- *
- * i_bytes > 0; no other restrictions. This holds for all versions of the
+  * i_bytes > 0; no other restrictions. This holds for all versions of the
  * merge routine.
  *
+ */
+#define Merge p_filter->p_sys->pf_merge
+
+/*
+ * EndMerge() macro, which must be called after the merge is
+ * finished, if the Merge() macro was used to perform the merge.
+ */
+#define EndMerge if(p_filter->p_sys->pf_end_merge) p_filter->p_sys->pf_end_merge
+
+/*****************************************************************************
+ * Merge routines
+ *****************************************************************************/
+
+/**
+ * Generic routine to blend 8 bit pixels from two picture lines.
+ * No inline assembler acceleration.
+ *
  * @param _p_dest Target line. Blend result = (A + B)/2.
  * @param _p_s1 Source line A.
  * @param _p_s2 Source line B.
  * @param i_bytes Number of bytes to merge.
  * @see Open()
  */
-void MergeGeneric( void *_p_dest, const void *_p_s1, const void *_p_s2,
-                   size_t i_bytes );
+void Merge8BitGeneric( void *_p_dest, const void *_p_s1, const void *_p_s2,
+                       size_t i_bytes );
+
+/**
+ * Generic routine to blend 16 bit pixels from two picture lines.
+ * No inline assembler acceleration.
+ *
+ * @param _p_dest Target line. Blend result = (A + B)/2.
+ * @param _p_s1 Source line A.
+ * @param _p_s2 Source line B.
+ * @param i_bytes Number of *bytes* to merge.
+ * @see Open()
+ */
+void Merge16BitGeneric( void *_p_dest, const void *_p_s1, const void *_p_s2,
+                        size_t i_bytes );
 
 #if defined(CAN_COMPILE_C_ALTIVEC)
 /**



More information about the vlc-commits mailing list