]> git.sesse.net Git - vlc/blobdiff - modules/video_filter/panoramix.c
Remove imgresample
[vlc] / modules / video_filter / panoramix.c
index c0cb19d4529b55e9904d350f95ffb426cc51694c..73c92814fbbafb454b33f6cafdfe91fd6845aa51 100644 (file)
@@ -33,6 +33,7 @@
 #include <vlc_common.h>
 #include <vlc_plugin.h>
 #include <vlc_vout.h>
+#include <assert.h>
 
 #include "filter_common.h"
 
@@ -72,8 +73,12 @@ static void RenderPackedRGB   ( vout_thread_t *, picture_t * );
 
 static void RemoveAllVout  ( vout_thread_t *p_vout );
 
-static int  SendEvents( vlc_object_t *, char const *,
+static int  MouseEvent( vlc_object_t *, char const *,
                         vlc_value_t, vlc_value_t, void * );
+static int  FullscreenEventUp( vlc_object_t *, char const *,
+                               vlc_value_t, vlc_value_t, void * );
+static int  FullscreenEventDown( vlc_object_t *, char const *,
+                                 vlc_value_t, vlc_value_t, void * );
 
 /*****************************************************************************
  * Module descriptor
@@ -100,9 +105,9 @@ vlc_module_begin ()
     set_subcategory( SUBCAT_VIDEO_VFILTER )
 
     add_integer( CFG_PREFIX "cols", -1, NULL,
-                 COLS_TEXT, COLS_LONGTEXT, true );
+                 COLS_TEXT, COLS_LONGTEXT, true )
     add_integer( CFG_PREFIX "rows", -1, NULL,
-                 ROWS_TEXT, ROWS_LONGTEXT, true );
+                 ROWS_TEXT, ROWS_LONGTEXT, true )
 
 #ifdef OVERLAP
 #define OFFSET_X_TEXT N_("Offset X offset (automatic compensation)")
@@ -558,7 +563,10 @@ static int AdjustHeight( vout_thread_t *p_vout )
         i_window_width  = GetSystemMetrics(SM_CXSCREEN);
         i_window_height = GetSystemMetrics(SM_CYSCREEN);
 #else
-        Display *p_display = XOpenDisplay( "" );
+        char *psz_display = var_CreateGetNonEmptyString( p_vout,
+                                                        "x11-display" );
+        Display *p_display = XOpenDisplay( psz_display );
+        free( psz_display );
         if (p_vout->p_sys->b_xinerama)
         {
             i_window_width = DisplayWidth(p_display, 0) / p_vout->p_sys->i_col;
@@ -643,7 +651,6 @@ static int AdjustHeight( vout_thread_t *p_vout )
 static int Init( vout_thread_t *p_vout )
 {
     int i_index, i_row, i_col;
-    picture_t *p_pic;
 
     I_OUTPUTPICTURES = 0;
 
@@ -836,7 +843,9 @@ static int Init( vout_thread_t *p_vout )
                 RemoveAllVout( p_vout );
                 return VLC_EGENERIC;
             }
-            ADD_CALLBACKS( p_entry->p_vout, SendEvents );
+            vout_filter_SetupChild( p_vout, p_entry->p_vout,
+                                    MouseEvent, FullscreenEventUp, FullscreenEventDown, true );
+
 #ifdef OVERLAP
             p_entry->p_vout->i_alignment = 0;
             if (i_col == 0)
@@ -850,7 +859,7 @@ static int Init( vout_thread_t *p_vout )
                 else if (i_row == p_vout->p_sys->i_row -1)
                     p_entry->p_vout->i_alignment |= VOUT_ALIGN_TOP;
             }
-            // i_n : number of active pp_vout
+            // i_active : number of active pp_vout
             int i_active = 0;
             for( int i = 0; i <= p_vout->p_sys->i_vout; i++ )
             {
@@ -858,15 +867,13 @@ static int Init( vout_thread_t *p_vout )
                     i_active++;
             }
             var_SetInteger( p_vout, "align", p_entry->p_vout->i_alignment );
-            var_SetInteger( p_vout, "video-x", i_video_x + p_vout->p_sys->i_offset_x + ((i_active + 1) % p_vout->p_sys->i_col) * p_vout->i_window_width);
-            var_SetInteger( p_vout, "video-y", i_video_y +                             ((i_active + 1) / p_vout->p_sys->i_col) * p_vout->i_window_height);
+            var_SetInteger( p_vout, "video-x", i_video_x + p_vout->p_sys->i_offset_x + (i_active % p_vout->p_sys->i_col) * p_vout->i_window_width);
+            var_SetInteger( p_vout, "video-y", i_video_y +                             (i_active / p_vout->p_sys->i_col) * p_vout->i_window_height);
 #endif
         }
     }
 
-    ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES );
-
-    ADD_PARENT_CALLBACKS( SendEventsToChild );
+    vout_filter_AllocateDirectBuffers( p_vout, VOUT_MAX_PICTURES );
 
     return VLC_SUCCESS;
 }
@@ -876,19 +883,10 @@ static int Init( vout_thread_t *p_vout )
  *****************************************************************************/
 static void End( vout_thread_t *p_vout )
 {
-    int i_index;
-
-    DEL_PARENT_CALLBACKS( SendEventsToChild );
-
-    /* Free the fake output buffers we allocated */
-    for( i_index = I_OUTPUTPICTURES ; i_index ; )
-    {
-        i_index--;
-        free( PP_OUTPUTPICTURE[ i_index ]->p_data_orig );
-    }
-
     RemoveAllVout( p_vout );
 
+    vout_filter_ReleaseDirectBuffers( p_vout );
+
 #ifdef OVERLAP
     var_SetInteger( p_vout, "bz-length", p_vout->p_sys->bz_length);
 #endif
@@ -1040,7 +1038,7 @@ static void RenderPlanarYUV( vout_thread_t *p_vout, picture_t *p_pic )
                     if( p_vout->p_sys->i_col > 2 )
                     {
                         const int halfl = length / 2;
-                        if( b_col_first == 0)
+                        if( b_col_first)
                             vlc_memcpy( &p_out[halfl], &p_in[0], i_copy_pitch - halfl );
                         else if( b_col_last )
                             vlc_memcpy( &p_out[    0], &p_in[-halfl], i_copy_pitch - halfl );
@@ -1085,10 +1083,7 @@ static void RenderPlanarYUV( vout_thread_t *p_vout, picture_t *p_pic )
                                 p_dst[i_index] = (p_vout->p_sys->lambda[0][i_plane][i_index] * p_dst[i_index]) / ACCURACY +
                                                         p_vout->p_sys->cstYUV[0][i_plane][i_index];
 #else
-                                fprintf( stderr, "r=%d c=%d, i_plane=%d i_index=%d | %d %d\n", i_row, i_col, i_plane, i_index,
-                                         i_copy_pitch, length );
-                                fprintf( stderr, "# %d\n", p_dst[i_index] );
-                                p_dst[i_index] = p_vout->p_sys->LUT[i_plane][p_vout->p_sys->lambda[0][i_plane][i_index]][p_dst[i_index]];
+                               p_dst[i_index] = p_vout->p_sys->LUT[i_plane][p_vout->p_sys->lambda[0][i_plane][i_index]][p_dst[i_index]];
 #endif
                             }
                         }
@@ -1099,36 +1094,46 @@ static void RenderPlanarYUV( vout_thread_t *p_vout, picture_t *p_pic )
                     p_out += i_out_pitch;
                 }
 #ifdef OVERLAP
-                // horizontal blend
-                if( p_vout->p_sys->i_row > 2 )
+       // horizontal blend
+        if ( p_vout->p_sys->i_row >= 2 )
+        {
+           // black bar
+           if (( p_vout->p_sys->i_row > 2 ) && (( b_row_first ) || ( b_row_last )))
+           {
+
+               int height = 2 * p_vout->p_sys->i_halfHeight / i_div;
+               if ( b_row_first )
+               {
+                    TopOffset = i_lines + (2 * p_vout->p_sys->i_halfHeight) / i_div;
+               }
+               else
                 {
-                    length = 2 * p_vout->p_sys->i_halfHeight / i_div;
-                    if (p_vout->p_sys->b_has_changed)
-                    {
-                        Denom = F2(length);
-                        a_2 = p_vout->p_sys->a_2 * (ACCURACY / 100);
-                        a_1 = p_vout->p_sys->a_1 * length * (ACCURACY / 100);
-                        a_0 = p_vout->p_sys->a_0 * Denom * (ACCURACY / 100);
-                       for(i_col_mod = 0; i_col_mod < 2; i_col_mod++)
-                        for (i_index = 0; i_index < length; i_index++)
-                        {
-                            p_vout->p_sys->lambda2[i_col_mod][i_plane][i_index] = CLIP_0A(!i_col_mod ? ACCURACY - (F4(a_2, a_1, i_index) + a_0) / Denom : ACCURACY - (F4(a_2, a_1,length - i_index) + a_0) / Denom);
-                            p_vout->p_sys->cstYUV2[i_col_mod][i_plane][i_index] = ((ACCURACY - p_vout->p_sys->lambda2[i_col_mod][i_plane][i_index]) * constantYUV[i_plane]) / ACCURACY;
-                        }
-                    }
-
-                    if( b_row_first )
-                    {
-                        // black bar
-                        TopOffset = i_lines + (2 * p_vout->p_sys->i_halfHeight) / i_div;
-                        uint8_t *p_dst = p_out - TopOffset * i_out_pitch;
-
-                        for (i_index = 0; i_index < length; i_index++)
-                            memset( &p_dst[i_index * i_out_pitch], constantYUV[i_plane], i_copy_pitch );
-                    }
-                    else if( p_vout->p_sys->b_attenuate )
-                    {
-                        // first blended zone
+                   TopOffset = height - (2 * p_vout->p_sys->i_halfHeight) / i_div;
+                }
+                uint8_t *p_dst = p_out - TopOffset * i_out_pitch;
+                for (i_index = 0; i_index < height; i_index++)
+                   for (i_index2 = 0; i_index2 < i_copy_pitch; i_index2++)
+                       p_dst[i_index * i_out_pitch + i_index2] = constantYUV[i_plane];
+           }
+           if( p_vout->p_sys->b_attenuate )
+           {
+               length = 2 * p_vout->p_sys->i_halfHeight / (p_vout->p_sys->pp_vout[i_vout].i_width / i_copy_pitch);
+               if (p_vout->p_sys->b_has_changed)
+               {
+                   Denom = F2(length);
+                   a_2 = p_vout->p_sys->a_2 * (ACCURACY / 100);
+                   a_1 = p_vout->p_sys->a_1 * length * (ACCURACY / 100);
+                   a_0 = p_vout->p_sys->a_0 * Denom * (ACCURACY / 100);
+                   for(i_col_mod = 0; i_col_mod < 2; i_col_mod++)
+                       for (i_index = 0; i_index < length; i_index++)
+                       {
+                           p_vout->p_sys->lambda2[i_col_mod][i_plane][i_index] = CLIP_0A(!i_col_mod ? ACCURACY - (F4(a_2, a_1, i_index) + a_0) / Denom : ACCURACY - (F4(a_2, a_1,length - i_index) + a_0) / Denom);
+                           p_vout->p_sys->cstYUV2[i_col_mod][i_plane][i_index] = ((ACCURACY - p_vout->p_sys->lambda2[i_col_mod][i_plane][i_index]) * constantYUV[i_plane]) / ACCURACY;
+                       }
+               }
+               // first blended zone
+               if ( !b_row_first )
+               {
                         TopOffset = i_lines;
                         uint8_t *p_dst = p_out - TopOffset * i_out_pitch;
 
@@ -1145,20 +1150,10 @@ static void RenderPlanarYUV( vout_thread_t *p_vout, picture_t *p_pic )
 #endif
                             }
                         }
-                    }
-
-                    if( b_row_last )
-                    {
-                        // black bar
-                        TopOffset = length - (2 * p_vout->p_sys->i_halfHeight) / i_div;
-                        uint8_t *p_dst = p_out - TopOffset * p_outpic->p[i_plane].i_pitch;
-
-                        for (i_index = 0; i_index < length; i_index++)
-                            memset( &p_dst[i_index * i_out_pitch], constantYUV[i_plane], i_copy_pitch );
-                    }
-                    else if( p_vout->p_sys->b_attenuate )
-                    {
-                    // second blended zone
+               }
+               // second blended zone
+               if ( !b_row_last )
+               {
                         TopOffset = length;
                         uint8_t *p_dst = p_out - TopOffset * p_outpic->p[i_plane].i_pitch;
 
@@ -1176,9 +1171,10 @@ static void RenderPlanarYUV( vout_thread_t *p_vout, picture_t *p_pic )
 #endif
                             }
                         }
-                    }
-                    // end blended zone
-                }
+               }
+           }
+        }
+       // end blended zone
 #endif
                 // bug for wall filter : fix by CC
                 //            pi_left_skip[i_plane] += i_out_pitch;
@@ -1840,13 +1836,16 @@ static void RenderPackedYUV( vout_thread_t *p_vout, picture_t *p_pic )
  *****************************************************************************/
 static void RemoveAllVout( vout_thread_t *p_vout )
 {
+    vout_sys_t *p_sys = p_vout->p_sys;
+
     for( int i = 0; i < p_vout->p_sys->i_vout; i++ )
     {
-        if( p_vout->p_sys->pp_vout[i].b_active )
+        if( p_sys->pp_vout[i].b_active )
         {
-            DEL_CALLBACKS( p_vout->p_sys->pp_vout[i].p_vout, SendEvents );
-            vout_CloseAndRelease( p_vout->p_sys->pp_vout[i].p_vout );
-            p_vout->p_sys->pp_vout[i].p_vout = NULL;
+            vout_filter_SetupChild( p_vout, p_sys->pp_vout[i].p_vout,
+                                    MouseEvent, FullscreenEventUp, FullscreenEventDown, true );
+            vout_CloseAndRelease( p_sys->pp_vout[i].p_vout );
+            p_sys->pp_vout[i].p_vout = NULL;
         }
     }
 }
@@ -1854,78 +1853,102 @@ static void RemoveAllVout( vout_thread_t *p_vout )
 /*****************************************************************************
  * SendEvents: forward mouse and keyboard events to the parent p_vout
  *****************************************************************************/
-static int SendEvents( vlc_object_t *p_this, char const *psz_var,
-                       vlc_value_t oldval, vlc_value_t newval, void *_p_vout )
+static int MouseEvent( vlc_object_t *p_this, char const *psz_var,
+                       vlc_value_t oldval, vlc_value_t newval, void *p_data )
 {
+    vout_thread_t *p_vout = p_data;
+    vout_sys_t *p_sys = p_vout->p_sys;
     VLC_UNUSED(oldval);
-    vout_thread_t *p_vout = (vout_thread_t *)_p_vout;
     int i_vout;
-    vlc_value_t sentval = newval;
 
     /* Find the video output index */
-    for( i_vout = 0; i_vout < p_vout->p_sys->i_vout; i_vout++ )
+    for( i_vout = 0; i_vout < p_sys->i_vout; i_vout++ )
     {
-        if( p_this == (vlc_object_t *)p_vout->p_sys->pp_vout[ i_vout ].p_vout )
-        {
+        if( p_sys->pp_vout[i_vout].b_active &&
+            p_this == VLC_OBJECT(p_sys->pp_vout[i_vout].p_vout) )
             break;
-        }
-    }
-
-    if( i_vout == p_vout->p_sys->i_vout )
-    {
-        return VLC_EGENERIC;
     }
+    assert( i_vout < p_vout->p_sys->i_vout );
 
     /* Translate the mouse coordinates */
     if( !strcmp( psz_var, "mouse-x" ) )
     {
 #ifdef OVERLAP
-        int i_overlap = ((p_vout->p_sys->i_col > 2) ? 0 : 2 * p_vout->p_sys->i_halfLength);
-           sentval.i_int += (p_vout->output.i_width - i_overlap)
+        int i_overlap = ((p_sys->i_col > 2) ? 0 : 2 * p_sys->i_halfLength);
+           newval.i_int += (p_vout->output.i_width - i_overlap)
 #else
-           sentval.i_int += p_vout->output.i_width
+           newval.i_int += p_vout->output.i_width
 #endif
-                         * (i_vout % p_vout->p_sys->i_col)
-                          / p_vout->p_sys->i_col;
+                         * (i_vout % p_sys->i_col)
+                          / p_sys->i_col;
     }
     else if( !strcmp( psz_var, "mouse-y" ) )
     {
 #ifdef OVERLAP
-        int i_overlap = ((p_vout->p_sys->i_row > 2) ? 0 : 2 * p_vout->p_sys->i_halfHeight);
-           sentval.i_int += (p_vout->output.i_height - i_overlap)
+        int i_overlap = ((p_sys->i_row > 2) ? 0 : 2 * p_sys->i_halfHeight);
+           newval.i_int += (p_vout->output.i_height - i_overlap)
 #else
-           sentval.i_int += p_vout->output.i_height
+           newval.i_int += p_vout->output.i_height
 #endif
 //bug fix in Wall plug-in
 //                         * (i_vout / p_vout->p_sys->i_row)
-                         * (i_vout / p_vout->p_sys->i_col)
-                          / p_vout->p_sys->i_row;
+                         * (i_vout / p_sys->i_col)
+                          / p_sys->i_row;
     }
 
-    var_Set( p_vout, psz_var, sentval );
+    return var_Set( p_vout, psz_var, newval );
+}
 
-    return VLC_SUCCESS;
+/**
+ * Forward fullscreen event to/from the childrens.
+ * FIXME pretty much duplicated from wall.c
+ */
+static bool IsFullscreenActive( vout_thread_t *p_vout )
+{
+    vout_sys_t *p_sys = p_vout->p_sys;
+    for( int i = 0; i < p_sys->i_vout; i++ )
+    {
+        if( p_sys->pp_vout[i].b_active &&
+            var_GetBool( p_sys->pp_vout[i].p_vout, "fullscreen" ) )
+            return true;
+    }
+    return false;
 }
+static int FullscreenEventUp( vlc_object_t *p_this, char const *psz_var,
+                              vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+    vout_thread_t *p_vout = p_data;
+    VLC_UNUSED(oldval); VLC_UNUSED(p_this); VLC_UNUSED(psz_var); VLC_UNUSED(newval);
 
-/*****************************************************************************
- * SendEventsToChild: forward events to the child/children vout
- *****************************************************************************/
-static int SendEventsToChild( vlc_object_t *p_this, char const *psz_var,
-                       vlc_value_t oldval, vlc_value_t newval, void *p_data )
+    const bool b_fullscreen = IsFullscreenActive( p_vout );
+    if( !var_GetBool( p_vout, "fullscreen" ) != !b_fullscreen )
+        return var_SetBool( p_vout, "fullscreen", b_fullscreen );
+    return VLC_SUCCESS;
+}
+static int FullscreenEventDown( vlc_object_t *p_this, char const *psz_var,
+                                vlc_value_t oldval, vlc_value_t newval, void *p_data )
 {
-    VLC_UNUSED(oldval); VLC_UNUSED(p_data);
-    vout_thread_t *p_vout = (vout_thread_t *)p_this;
-    int i_row, i_col, i_vout = 0;
+    vout_thread_t *p_vout = (vout_thread_t*)p_this;
+    vout_sys_t *p_sys = p_vout->p_sys;
+    VLC_UNUSED(oldval); VLC_UNUSED(p_data); VLC_UNUSED(psz_var);
 
-    for( i_row = 0; i_row < p_vout->p_sys->i_row; i_row++ )
+    const bool b_fullscreen = IsFullscreenActive( p_vout );
+    if( !b_fullscreen != !newval.b_bool )
     {
-        for( i_col = 0; i_col < p_vout->p_sys->i_col; i_col++ )
+        for( int i = 0; i < p_sys->i_vout; i++ )
         {
-            var_Set( p_vout->p_sys->pp_vout[ i_vout ].p_vout, psz_var, newval);
-            if( !strcmp( psz_var, "fullscreen" ) ) break;
-            i_vout++;
+            if( !p_sys->pp_vout[i].b_active )
+                continue;
+
+            vout_thread_t *p_child = p_sys->pp_vout[i].p_vout;
+            if( !var_GetBool( p_child, "fullscreen" ) != !newval.b_bool )
+            {
+                var_SetBool( p_child, "fullscreen", newval.b_bool );
+                if( newval.b_bool )
+                    return VLC_SUCCESS;
+            }
         }
     }
-
     return VLC_SUCCESS;
 }
+