[vlc-devel] [PATCH 3/5] chroma: i420_nv12: handle more conversions using copy helper

Thomas Guillem thomas at gllm.fr
Fri Mar 9 19:15:32 CET 2018


---
 modules/video_chroma/i420_nv12.c | 104 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 91 insertions(+), 13 deletions(-)

diff --git a/modules/video_chroma/i420_nv12.c b/modules/video_chroma/i420_nv12.c
index b779ca8ec1..d2ca769123 100644
--- a/modules/video_chroma/i420_nv12.c
+++ b/modules/video_chroma/i420_nv12.c
@@ -78,9 +78,62 @@ static void YV12_NV12( filter_t *p_filter, picture_t *p_src,
     I420_NV12( p_filter, p_src, p_dst );
 }
 
+static void NV12_I420( filter_t *p_filter, picture_t *p_src,
+                                           picture_t *p_dst )
+{
+    filter_sys_t *p_sys = p_filter->p_sys;
+    p_dst->format.i_x_offset = p_src->format.i_x_offset;
+    p_dst->format.i_y_offset = p_src->format.i_y_offset;
+    const size_t pitches[] = GET_PITCHES( p_src );
+    const uint8_t *planes[] = GET_PLANES( p_src );
+
+    Copy420_SP_to_P( p_dst, planes, pitches,
+                     p_src->format.i_y_offset + p_src->format.i_visible_height,
+                     &p_sys->cache );
+}
+
+static void NV12_YV12( filter_t *p_filter, picture_t *p_src,
+                                           picture_t *p_dst )
+{
+    NV12_I420( p_filter, p_src, p_dst );
+    picture_SwapUV( p_dst );
+}
+
+static void I42010B_P010( filter_t *p_filter, picture_t *p_src,
+                                              picture_t *p_dst )
+{
+    filter_sys_t *p_sys = p_filter->p_sys;
+    p_dst->format.i_x_offset = p_src->format.i_x_offset;
+    p_dst->format.i_y_offset = p_src->format.i_y_offset;
+    const size_t pitches[] = GET_PITCHES( p_src );
+    const uint8_t *planes[] = GET_PLANES( p_src );
+
+    Copy420_16_P_to_SP( p_dst, planes, pitches,
+                        p_src->format.i_y_offset + p_src->format.i_visible_height,
+                        &p_sys->cache );
+}
+
+static void P010_I42010B( filter_t *p_filter, picture_t *p_src,
+                                              picture_t *p_dst )
+{
+    filter_sys_t *p_sys = p_filter->p_sys;
+    p_dst->format.i_x_offset = p_src->format.i_x_offset;
+    p_dst->format.i_y_offset = p_src->format.i_y_offset;
+    const size_t pitches[] = GET_PITCHES( p_src );
+    const uint8_t *planes[] = GET_PLANES( p_src );
+
+    Copy420_16_SP_to_P( p_dst, planes, pitches,
+                        p_src->format.i_y_offset + p_src->format.i_visible_height,
+                        &p_sys->cache );
+}
+
 /* Following functions are local */
 VIDEO_FILTER_WRAPPER( I420_NV12 )
 VIDEO_FILTER_WRAPPER( YV12_NV12 )
+VIDEO_FILTER_WRAPPER( NV12_I420 )
+VIDEO_FILTER_WRAPPER( NV12_YV12 )
+VIDEO_FILTER_WRAPPER( I42010B_P010 )
+VIDEO_FILTER_WRAPPER( P010_I42010B )
 
 /*****************************************************************************
  * Create: allocate a chroma function
@@ -91,16 +144,6 @@ static int Create( vlc_object_t *p_this )
 {
     filter_t *p_filter = (filter_t *)p_this;
 
-    if ( p_filter->fmt_out.video.i_chroma != VLC_CODEC_NV12 )
-        return -1;
-
-    /* video must be even, because 4:2:0 is subsampled by 2 in both ways */
-    if( p_filter->fmt_in.video.i_width  & 1
-     || p_filter->fmt_in.video.i_height & 1 )
-    {
-        return -1;
-    }
-
     /* resizing not supported */
     if( p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width !=
             p_filter->fmt_out.video.i_x_offset + p_filter->fmt_out.video.i_visible_width
@@ -109,16 +152,51 @@ static int Create( vlc_object_t *p_this )
        || p_filter->fmt_in.video.orientation != p_filter->fmt_out.video.orientation )
         return -1;
 
-    switch( p_filter->fmt_in.video.i_chroma )
+    vlc_fourcc_t infcc = p_filter->fmt_in.video.i_chroma;
+    vlc_fourcc_t outfcc = p_filter->fmt_out.video.i_chroma;
+    uint8_t pixel_bytes = 1;
+
+    switch( infcc )
     {
         case VLC_CODEC_I420:
         case VLC_CODEC_J420:
+            if( outfcc != VLC_CODEC_NV12 )
+                return -1;
             p_filter->pf_video_filter = I420_NV12_Filter;
             break;
 
         case VLC_CODEC_YV12:
+            if( outfcc != VLC_CODEC_NV12 )
+                return -1;
             p_filter->pf_video_filter = YV12_NV12_Filter;
             break;
+        case VLC_CODEC_NV12:
+            switch( outfcc )
+            {
+                case VLC_CODEC_I420:
+                case VLC_CODEC_J420:
+                    p_filter->pf_video_filter = NV12_I420_Filter;
+                    break;
+                case VLC_CODEC_YV12:
+                    p_filter->pf_video_filter = NV12_YV12_Filter;
+                default:
+                    return -1;
+            }
+            break;
+
+        case VLC_CODEC_I420_10B:
+            if( outfcc != VLC_CODEC_P010 )
+                return -1;
+            pixel_bytes = 2;
+            p_filter->pf_video_filter = I42010B_P010_Filter;
+            break;
+
+        case VLC_CODEC_P010:
+            if( outfcc != VLC_CODEC_I420_10B )
+                return -1;
+            pixel_bytes = 2;
+            p_filter->pf_video_filter = P010_I42010B_Filter;
+            break;
 
         default:
             return -1;
@@ -129,8 +207,8 @@ static int Create( vlc_object_t *p_this )
     if (!p_sys)
          return VLC_ENOMEM;
 
-    CopyInitCache( &p_sys->cache, p_filter->fmt_in.video.i_x_offset +
-                                  p_filter->fmt_in.video.i_visible_width );
+    CopyInitCache( &p_sys->cache, ( p_filter->fmt_in.video.i_x_offset +
+                                    p_filter->fmt_in.video.i_visible_width ) * pixel_bytes );
     p_filter->p_sys = p_sys;
 
     return 0;
-- 
2.11.0



More information about the vlc-devel mailing list