* src/video_output/vout_intf.c: implemented vout_Control( VOUT_SNAPSHOT ) ... most...
authorGildas Bazin <gbazin@videolan.org>
Tue, 21 Dec 2004 14:51:43 +0000 (14:51 +0000)
committerGildas Bazin <gbazin@videolan.org>
Tue, 21 Dec 2004 14:51:43 +0000 (14:51 +0000)
include/video_output.h
include/vlc_keys.h
src/video_output/video_output.c
src/video_output/vout_intf.c

index 2c23eff..0ddccd9 100644 (file)
@@ -142,6 +142,9 @@ struct vout_thread_t
     /* Filter chain */
     char *psz_filter_chain;
     vlc_bool_t b_filter_change;
+
+    /* Misc */
+    vlc_bool_t       b_snapshot;     /**< take one snapshot on the next loop */
 };
 
 #define I_OUTPUTPICTURES p_vout->output.i_pictures
@@ -243,6 +246,7 @@ enum output_query_e
     VOUT_SET_ZOOM,         /* arg1= double           res=    */
     VOUT_SET_STAY_ON_TOP,  /* arg1= vlc_bool_t       res=    */
     VOUT_REPARENT,
+    VOUT_SNAPSHOT,
     VOUT_CLOSE
 };
 
index f7b6a39..cbaebc5 100644 (file)
@@ -237,4 +237,5 @@ static inline int StringToKey( char *psz_key )
 #define ACTIONID_INTF_SHOW             52
 #define ACTIONID_AUDIODELAY_UP         53
 #define ACTIONID_AUDIODELAY_DOWN       54
+#define ACTIONID_SNAPSHOT              55
 
index d7122d8..a47cb8b 100644 (file)
@@ -65,6 +65,9 @@ static int DeinterlaceCallback( vlc_object_t *, char const *,
 static int FilterCallback( vlc_object_t *, char const *,
                            vlc_value_t, vlc_value_t, void * );
 
+/* From vout_intf.c */
+int vout_Snapshot( vout_thread_t *, picture_t * );
+
 /*****************************************************************************
  * vout_Request: find a video output thread, create one, or destroy one.
  *****************************************************************************
@@ -852,6 +855,12 @@ static void RunThread( vout_thread_t *p_vout)
             i_idle_loops++;
         }
 
+        if( p_picture && p_vout->b_snapshot )
+        {
+            p_vout->b_snapshot = VLC_FALSE;
+            vout_Snapshot( p_vout, p_picture );
+        }
+
         /*
          * Check for subpictures to display
          */
index be3efab..07cc0d3 100644 (file)
@@ -31,6 +31,8 @@
 
 #include "vlc_video.h"
 #include "video_output.h"
+#include "vlc_image.h"
+#include "vlc_spu.h"
 
 /*****************************************************************************
  * Local prototypes
@@ -170,6 +172,7 @@ void vout_IntfInit( vout_thread_t *p_vout )
     vlc_value_t val, text, old_val;
 
     /* Create a few object variables we'll need later on */
+    var_Create( p_vout, "snapshot-path", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
     var_Create( p_vout, "aspect-ratio", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
     var_Create( p_vout, "width", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
     var_Create( p_vout, "height", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
@@ -238,6 +241,89 @@ void vout_IntfInit( vout_thread_t *p_vout )
     var_Set( p_vout, "intf-change", val );
 }
 
+/*****************************************************************************
+ * vout_Snapshot: generates a snapshot.
+ *****************************************************************************/
+int vout_Snapshot( vout_thread_t *p_vout, picture_t *p_pic )
+{
+    image_handler_t *p_image = image_HandlerCreate( p_vout );
+    video_format_t fmt_in = {0}, fmt_out = {0};
+    char *psz_filename;
+    subpicture_t *p_subpic;
+    picture_t *p_pif;
+    vlc_value_t val;
+    int i_ret;
+
+    var_Get( p_vout, "snapshot-path", &val );
+    if( val.psz_string && !*val.psz_string )
+    {
+        free( val.psz_string );
+        val.psz_string = 0;
+    }
+    if( !val.psz_string && p_vout->p_vlc->psz_homedir )
+    {
+        asprintf( &val.psz_string, "%s/" CONFIG_DIR,
+                  p_vout->p_vlc->psz_homedir );
+    }
+    if( !val.psz_string )
+    {
+        msg_Err( p_vout, "no directory specified for snapshots" );
+        return VLC_EGENERIC;
+    }
+
+    asprintf( &psz_filename, "%s/vlcsnap-%u.png", val.psz_string,
+              (unsigned int)(p_pic->date / 100000) & 0xFFFFFF );
+    free( val.psz_string );
+
+    /* Save the snapshot */
+    fmt_in.i_chroma = p_vout->render.i_chroma;
+    fmt_in.i_width = p_vout->render.i_width;
+    fmt_in.i_height = p_vout->render.i_height;
+    i_ret = image_WriteUrl( p_image, p_pic, &fmt_in, &fmt_out, psz_filename );
+    if( i_ret != VLC_SUCCESS )
+    {
+        msg_Err( p_vout, "could not create snapshot %s", psz_filename );
+        free( psz_filename );
+        image_HandlerDelete( p_image );
+        return VLC_EGENERIC;
+    }
+
+    msg_Dbg( p_vout, "snapshot taken (%s)", psz_filename );
+    free( psz_filename );
+
+    /* Inject a subpicture with the snapshot */
+    fmt_out.i_chroma = VLC_FOURCC('Y','U','V','A');
+    fmt_out.i_width = fmt_out.i_visible_width = p_vout->render.i_width;
+    fmt_out.i_height = fmt_out.i_visible_height = p_vout->render.i_height;
+    fmt_out.i_aspect = VOUT_ASPECT_FACTOR;
+    p_pif = image_Convert( p_image, p_pic, &fmt_in, &fmt_out );
+    image_HandlerDelete( p_image );
+    if( !p_pif ) return VLC_EGENERIC;
+
+    p_subpic = spu_CreateSubpicture( p_vout->p_spu );
+    if( p_subpic == NULL )
+    {
+         p_pif->pf_release( p_pif );
+         return VLC_EGENERIC;
+    }
+
+    p_subpic->i_channel = 0;
+    p_subpic->i_start = mdate();
+    p_subpic->i_stop = mdate() + 4000000;
+    p_subpic->b_ephemer = VLC_TRUE;
+    p_subpic->b_fade = VLC_TRUE;
+    p_subpic->i_original_picture_width = p_vout->render.i_width * 4;
+    p_subpic->i_original_picture_height = p_vout->render.i_height * 4;
+
+    p_subpic->p_region = spu_CreateRegion( p_vout->p_spu, &fmt_out );
+    vout_CopyPicture( p_image->p_parent, &p_subpic->p_region->picture, p_pif );
+    p_pif->pf_release( p_pif );
+
+    spu_DisplaySubpicture( p_vout->p_spu, p_subpic );
+
+    return VLC_SUCCESS;
+}
+
 /*****************************************************************************
  * vout_ControlDefault: default methods for video output control.
  *****************************************************************************/
@@ -255,6 +341,11 @@ int vout_vaControlDefault( vout_thread_t *p_vout, int i_query, va_list args )
         return VLC_SUCCESS;
         break;
 
+    case VOUT_SNAPSHOT:
+        p_vout->b_snapshot = VLC_TRUE;
+        return VLC_SUCCESS;
+        break;
+
     default:
         msg_Dbg( p_vout, "control query not supported" );
         return VLC_EGENERIC;