smallapp.c
Upload User: shyika
Upload Date: 2017-11-25
Package Size: 1227k
Code Size: 9k
Category:

Video Capture

Development Platform:

Unix_Linux

  1. #include <stdlib.h>
  2. #include <gtk/gtk.h>
  3. #include <unicap.h>
  4. #include <unicapgtk.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. static void save_image( UnicapgtkVideoDisplay *ugtk );
  8. static void show_property_dialog( UnicapgtkVideoDisplay *ugtk );
  9. static GtkItemFactoryEntry menu_entries[] = 
  10. {
  11.    { "/_File", NULL, NULL, 0, "<Branch>" }, 
  12.    { "/_File/_Save Image", "<CTRL>Q", save_image, 1, "<Item>" },
  13.    { "/_File/_Quit", "<CTRL>Q", gtk_main_quit, 0 , "<StockItem>",GTK_STOCK_QUIT },
  14.    { "/_Device", NULL, NULL, 0, "<Branch>" },
  15.    { "/_Device/_Parameters", "<CTRL>P", show_property_dialog, 1, "<Item>"},
  16. };
  17. static gint nmenu_entries = sizeof (menu_entries) / sizeof (menu_entries[0]);
  18. /*
  19.   format_change_cb: 
  20.   Callback called when the user selected a new video format
  21. */
  22. static 
  23. void format_change_cb( GtkWidget *ugtk, unicap_format_t *format, GtkWidget *ugtk_display )
  24. {
  25.    GtkWidget *property_dialog;
  26.    property_dialog = g_object_get_data( G_OBJECT( ugtk_display ), "property_dialog" );
  27.    g_assert( property_dialog );
  28.    unicapgtk_video_display_stop( UNICAPGTK_VIDEO_DISPLAY( ugtk_display ) );
  29.    unicapgtk_video_display_set_format( UNICAPGTK_VIDEO_DISPLAY( ugtk_display ), format );
  30.    unicapgtk_video_display_start( UNICAPGTK_VIDEO_DISPLAY( ugtk_display ) );
  31.    // reset the property dialog since some properties ( eg. frame rate ) might change when the format changes
  32.    unicapgtk_property_dialog_reset( UNICAPGTK_PROPERTY_DIALOG( property_dialog ) );
  33. }
  34. /*
  35.   pause_toggle_cb: 
  36.   Callback called when the user pressed the pause button
  37. */
  38. static 
  39. void pause_toggle_cb( GtkWidget *toggle_button, GtkWidget *ugtk_display )
  40. {
  41.    unicapgtk_video_display_set_pause( UNICAPGTK_VIDEO_DISPLAY( ugtk_display ), 
  42.       gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( toggle_button ) ) );
  43. }
  44. /*
  45.   device_change_cb: 
  46.   callback called when the user selected a video capture device
  47. */
  48. static 
  49. void device_change_cb( UnicapgtkDeviceSelection *selection, gchar *device_id, GtkWidget *ugtk_display )
  50. {
  51.    unicap_device_t device;
  52.    unicap_handle_t handle;
  53.    GtkWidget *property_dialog;
  54.    GtkWidget *format_selection;
  55.    GtkWidget *window;
  56.    property_dialog = g_object_get_data( G_OBJECT( ugtk_display ), "property_dialog" );
  57.    g_assert( property_dialog );
  58.    format_selection = g_object_get_data( G_OBJECT( ugtk_display ), "format_selection" );
  59.    g_assert( format_selection );
  60.    window = g_object_get_data( G_OBJECT( ugtk_display ), "app-window" );
  61.    g_assert( window );
  62.    unicap_void_device( &device );
  63.    strcpy( device.identifier, device_id );
  64.    
  65.    if( !SUCCESS( unicap_enumerate_devices( &device, &device, 0 ) ) ||
  66.        !SUCCESS( unicap_open( &handle, &device ) ) )
  67.    {
  68.       // device is not available anymore
  69.       g_printerr( "*** TODO: device rescan*** device not available!n" );
  70.       return;
  71.    }
  72.    
  73.    if( unicap_is_stream_locked( &device ) )
  74.    {
  75.       // could not acquire lock
  76.       unicap_close( handle );
  77.       g_printerr( "*** TODO: device rescan*** device is lockedn" );
  78.       return;
  79.    }
  80.    unicapgtk_video_display_set_handle( UNICAPGTK_VIDEO_DISPLAY( ugtk_display ), handle );
  81.    unicapgtk_property_dialog_set_handle( UNICAPGTK_PROPERTY_DIALOG( property_dialog ), handle );
  82.    unicapgtk_video_format_selection_set_handle( UNICAPGTK_VIDEO_FORMAT_SELECTION( format_selection ), handle );
  83.    unicap_close( handle );
  84.    gtk_window_set_title( GTK_WINDOW( window ), device.identifier );
  85. }
  86. static void show_property_dialog( UnicapgtkVideoDisplay *ugtk )
  87. {
  88.    GtkWidget *dialog;
  89.    dialog = g_object_get_data( G_OBJECT( ugtk ), "property_dialog" );
  90.    g_assert( dialog );
  91.    gtk_window_present( GTK_WINDOW( dialog ) );
  92. }
  93. static void save_image( UnicapgtkVideoDisplay *ugtk )
  94. {
  95.    GtkWidget *fsdialog;
  96.    GtkWidget *app_window;
  97.    gint response;
  98.    app_window = g_object_get_data( G_OBJECT( ugtk ), "app-window" );
  99.    g_assert( app_window );
  100.    fsdialog = gtk_file_chooser_dialog_new( "Save Still Image", 
  101.    GTK_WINDOW( app_window ), 
  102.    GTK_FILE_CHOOSER_ACTION_SAVE, 
  103.    GTK_STOCK_SAVE, GTK_RESPONSE_OK, 
  104.    GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL );
  105.    gtk_file_chooser_set_current_name( GTK_FILE_CHOOSER( fsdialog ), "Image.jpg" );
  106.    response = gtk_dialog_run( GTK_DIALOG( fsdialog ) );
  107.    if( response == GTK_RESPONSE_OK )
  108.    {
  109.       GdkPixbuf *pixbuf;
  110.       gchar *filename;
  111.       pixbuf = unicapgtk_video_display_get_still_image( ugtk );
  112.       if( pixbuf )
  113.       {
  114.  filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER( fsdialog ) );
  115.  gdk_pixbuf_save( pixbuf, filename, "jpeg", NULL, NULL );
  116.  g_object_unref( pixbuf );
  117.       }
  118.       else
  119.       {
  120.  g_warning( "Failed to acquire imagen" );
  121.       }
  122.    }
  123.    
  124.    gtk_widget_destroy( fsdialog );
  125. }
  126. /*
  127.   create_application_window - Creates the main application window
  128.   The window consists of a button bar ( containing a video format selector, 
  129.   a pause button, a save still image button and the preferences button ). 
  130.   Below the toolbar, place the video display widget
  131. */
  132. GtkWidget *create_application_window( )
  133. {
  134.    GtkWidget *window;
  135.    GtkWidget *menu_bar;
  136.    GtkWidget *ugtk_display;
  137.    GtkWidget *ugtk_format_selection;
  138.    GtkWidget *widget;
  139.    GtkWidget *vbox;
  140.    GtkWidget *hbox;
  141.    GtkWidget *button_box;
  142.    GtkWidget *device_selection;
  143.    GtkWidget *scrolled_window;
  144.    GtkItemFactory *factory;
  145.    GtkAccelGroup *accel_group;
  146.    window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
  147.    g_signal_connect( G_OBJECT( window ), "destroy", G_CALLBACK( gtk_main_quit ), NULL);
  148.    gtk_window_set_default_size( GTK_WINDOW( window ), 680, 560 );
  149.    vbox = gtk_vbox_new( 0,0 );
  150.    gtk_container_add( GTK_CONTAINER( window ), vbox );
  151.    ugtk_display = unicapgtk_video_display_new( );
  152.    g_object_set( G_OBJECT( ugtk_display ), "scale-to-fit", TRUE, NULL );
  153.    g_object_set_data( G_OBJECT( window ), "ugtk_display", ugtk_display );
  154.    g_object_set_data( G_OBJECT( ugtk_display ), "app-window", window );
  155.    accel_group = gtk_accel_group_new();
  156.    factory = gtk_item_factory_new( GTK_TYPE_MENU_BAR, "<UnicapgtkSmallappMain>", accel_group );
  157.    gtk_item_factory_create_items( factory, nmenu_entries, menu_entries, ugtk_display );
  158.    gtk_window_add_accel_group( GTK_WINDOW( window ), accel_group );
  159.    menu_bar = gtk_item_factory_get_widget( factory, "<UnicapgtkSmallappMain>" );
  160.    gtk_box_pack_start( GTK_BOX( vbox ), menu_bar, FALSE, TRUE, 0 );
  161.    hbox = gtk_hbox_new( 0, 0 );
  162.    gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 2 );
  163.    device_selection = unicapgtk_device_selection_new(TRUE);
  164.    g_signal_connect( G_OBJECT( device_selection ), "unicapgtk_device_selection_changed", 
  165.      (GCallback)device_change_cb, ugtk_display );
  166.    gtk_box_pack_start_defaults( GTK_BOX( hbox ), device_selection );
  167.    ugtk_format_selection = unicapgtk_video_format_selection_new( );
  168.    gtk_box_pack_start_defaults( GTK_BOX( hbox ), ugtk_format_selection );
  169.    g_signal_connect( G_OBJECT( ugtk_format_selection ), "unicapgtk_video_format_changed",
  170.      G_CALLBACK( format_change_cb ), ugtk_display );
  171.    button_box = gtk_hbutton_box_new();
  172.    gtk_box_pack_start( GTK_BOX( hbox ), button_box, 0, 0, 0 );
  173.    widget = gtk_toggle_button_new_with_label( GTK_STOCK_MEDIA_PAUSE );
  174.    gtk_button_set_use_stock( GTK_BUTTON( widget ), TRUE );
  175.    gtk_container_add( GTK_CONTAINER( button_box ), widget );
  176.    g_signal_connect( G_OBJECT( widget ), "toggled", G_CALLBACK( pause_toggle_cb ), ugtk_display );
  177.    scrolled_window = gtk_scrolled_window_new( NULL, NULL );
  178.    gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scrolled_window ), 
  179.    GTK_POLICY_AUTOMATIC, 
  180.    GTK_POLICY_AUTOMATIC );
  181.    gtk_box_pack_start( GTK_BOX( vbox ), scrolled_window, TRUE, TRUE, 2 );
  182.    gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( scrolled_window ), ugtk_display );
  183.    gtk_widget_show_all( window );
  184.    g_object_set_data( G_OBJECT( ugtk_display ), "format_selection", ugtk_format_selection );
  185.    g_object_set_data( G_OBJECT( ugtk_display ), "device_selection", device_selection );
  186.    return window;
  187. }
  188. int main( int argc, char *argv[] )
  189. {
  190.    GtkWidget *display_window;
  191.    GtkWidget *video_display;
  192.    GtkWidget *device_selection;
  193.    GtkWidget *widget;
  194.    gtk_init (&argc, &argv);
  195.    //
  196.    // Create the main application window
  197.    // 
  198.    display_window  = create_application_window( );
  199.    video_display = g_object_get_data( G_OBJECT( display_window ), "ugtk_display" );
  200.    g_assert( video_display );
  201.    device_selection = g_object_get_data( G_OBJECT( video_display ), "device_selection" );
  202.    g_assert( device_selection );
  203.    //
  204.    // Create a window containing the properties for the 
  205.    // video capture device and a device selection menu
  206.    //
  207.    widget = unicapgtk_property_dialog_new( );
  208.    gtk_widget_show_all( widget );
  209.    g_object_set_data( G_OBJECT( video_display ), "property_dialog", widget );
  210.    //
  211.    // Rescan devices and select first device
  212.    //
  213.    if( unicapgtk_device_selection_rescan( UNICAPGTK_DEVICE_SELECTION( device_selection ) ) > 0 )
  214.    {
  215.       gtk_combo_box_set_active (GTK_COMBO_BOX( device_selection ), 0);
  216.    }
  217.    gtk_main ();
  218.    return 0;
  219. }