⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gtv.c

📁 This code is based on mpeg_play, available from: http://bmrc.berkeley.edu/frame/research/mpeg/
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * gtv - a Gtk+ based SMPEG player * (c) Michael Vance, 1999 *     briareos@lokigames.com * * TODO * - SMPEG returns an incorrect current_frame after a * call to SMPEG_renderFinal(). * - SMPEG loops audio incorrectly when audio stream is * shorter than a video stream, etc. */#include "gtv.h"#include "SDL_syswm.h"#define TIMER_TIMEOUT 100static GtkWidget* create_gtv_window( void );static void gtv_connect( gpointer, gchar*, gchar*, GtkSignalFunc );static void gtv_set_frame( gpointer, int );static void gtv_set_fps( gpointer, float );static void gtv_set_trackbar( gpointer, int );static void gtv_set_sensitive( gpointer, gchar*, gboolean );static void gtv_clear_screen( gpointer );static void gtv_fix_toggle_state( gpointer );static void gtv_double( GtkWidget*, gpointer );static void gtv_loop( GtkWidget*, gpointer );static void gtv_audio( GtkWidget*, gpointer );static void gtv_filter( GtkWidget*, gpointer );static void gtv_open( GtkWidget*, gpointer );static void gtv_open_file( gchar*, gpointer );static void gtv_close( GtkWidget*, gpointer );static void gtv_info( GtkWidget*, gpointer );static void gtv_quit( GtkWidget*, gpointer );static void gtv_about( GtkWidget*, gpointer );static void gtv_play( GtkWidget*, gpointer );static void gtv_pause( GtkWidget*, gpointer );static void gtv_stop( GtkWidget*, gpointer );static void gtv_step( GtkWidget*, gpointer );static void gtv_to_end( GtkWidget*, gpointer );static void gtv_seek( GtkAdjustment*, gpointer );static void gtv_drag_data_received(GtkWidget * widget,                                   GdkDragContext * context,                                   gint x, gint y,                                   GtkSelectionData * selection_data,                                   guint info, guint time);static int gtv_trackbar_dragging;static gchar * gtv_default_directory = 0;static void gtv_fix_toggle_state( gpointer raw ){    SMPEG* mpeg = NULL;    assert( raw );    mpeg = (SMPEG*) gtk_object_get_data( GTK_OBJECT( raw ), "mpeg" );    /* If no mpeg is loaded, pop all the buttons. */    if( !mpeg ) {	GtkWidget* twotimes = NULL;	GtkWidget* loop = NULL;	GtkWidget* audio = NULL;	GtkWidget* filter = NULL;	twotimes = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( raw ), "twotimes" ) );	loop = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( raw ), "loop" ) );	audio = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( raw ), "audio" ) );	filter = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( raw ), "filter" ) );#if 1 /* Sam 5/31/2000 - Default to doubled video and audio on */	gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( twotimes ), FALSE );	gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( loop ), FALSE );	gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( audio ), TRUE );	gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( filter ), FALSE );#else	gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( twotimes ), FALSE );	gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( loop ), FALSE );	gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( audio ), FALSE );	gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( filter ), FALSE );#endif    }}static void gtv_set_sensitive( gpointer raw, gchar* name, gboolean sensitive ){    GtkWidget* item = NULL;    assert( raw );    assert( name );    item = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( raw ), name ) );    assert( item );    gtk_widget_set_sensitive( item, sensitive );}static void gtv_set_buttons_sensitive( gpointer raw, gboolean sensitive ){    SMPEG_Info* info = NULL;    /* HACK If no MPEG is loaded, info has been memset()'ed to 0. */    info = (SMPEG_Info*) gtk_object_get_data( GTK_OBJECT( raw ), "info" );    gtv_set_sensitive( raw, "play", sensitive );    gtv_set_sensitive( raw, "pause", sensitive );    gtv_set_sensitive( raw, "stop", sensitive );    gtv_set_sensitive( raw, "step", sensitive && info->has_video );    gtv_set_sensitive( raw, "to_end", sensitive && info->has_video );    gtv_set_sensitive( raw, "loop", sensitive );    gtv_set_sensitive( raw, "close", sensitive );    gtv_set_sensitive( raw, "file_info", sensitive );    gtv_set_sensitive( raw, "twotimes", sensitive && info->has_video );    gtv_set_sensitive( raw, "audio", sensitive && info->has_audio && info->has_video);    gtv_set_sensitive( raw, "filter", sensitive && info->has_video );    gtv_fix_toggle_state( raw );}static void gtv_dialog_cleanup( gpointer raw ){    GtkWidget* dialog = NULL;    dialog = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( raw ), "dialog" ) );    gtk_grab_remove( dialog );    gtk_widget_destroy( dialog );    gtk_object_set_data( GTK_OBJECT( raw ), "dialog", NULL );}static void gtv_dialog_cancel( GtkWidget* item, gpointer raw ){    gtv_dialog_cleanup( raw );}static void gtv_open_ok( GtkWidget* item, gpointer raw ){    GtkWidget* file_sel = NULL;    gchar* filename = NULL;    /* HACK HACK HACK */    file_sel = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( raw ), "dialog" ) );    filename = gtk_file_selection_get_filename( GTK_FILE_SELECTION( file_sel ) );    if( filename ) {	gtv_open_file( filename, raw );	if( strrchr( filename, '/') )	{	  if( gtv_default_directory ) free( gtv_default_directory );	  gtv_default_directory = (gchar *) malloc( (strlen(filename) + 1) * sizeof(gchar) );	  strcpy( gtv_default_directory, filename);	  *(strrchr( gtv_default_directory, '/' ) + 1) = 0;	}    }    gtv_dialog_cleanup( raw );}static void gtv_open( GtkWidget* item, gpointer raw ){    GtkWidget* file_sel = NULL;    file_sel = gtk_file_selection_new( "Select an MPEG" );    gtk_signal_connect( GTK_OBJECT( GTK_FILE_SELECTION( file_sel )->ok_button ), "clicked",			GTK_SIGNAL_FUNC( gtv_open_ok ), raw );    gtk_signal_connect( GTK_OBJECT( GTK_FILE_SELECTION( file_sel )->cancel_button ), "clicked",			GTK_SIGNAL_FUNC( gtv_dialog_cancel ), raw );    if( gtv_default_directory )      gtk_file_selection_complete( GTK_FILE_SELECTION( file_sel ), gtv_default_directory );    gtk_file_selection_hide_fileop_buttons( GTK_FILE_SELECTION( file_sel ) );    /* HACK HACK HACK */    gtk_object_set_data( GTK_OBJECT( raw ), "dialog", file_sel );    gtk_grab_add( file_sel );    gtk_widget_show( file_sel );}static void gtv_center_window(SDL_Surface *screen){    SDL_SysWMinfo info;    SDL_VERSION(&info.version);    if ( SDL_GetWMInfo(&info) > 0 ) {        int x, y;        int w, h;#ifdef unix        if ( info.subsystem == SDL_SYSWM_X11 ) {            info.info.x11.lock_func();            w = DisplayWidth(info.info.x11.display,                             DefaultScreen(info.info.x11.display));            h = DisplayHeight(info.info.x11.display,                             DefaultScreen(info.info.x11.display));            x = (w - screen->w)/2;            y = (h - screen->h)/2;            XMoveWindow(info.info.x11.display, info.info.x11.wmwindow, x, y);            info.info.x11.unlock_func();        }#else#ifdef WIN32	/* FIXME: implement centering code for Windows */#else#warning Need to implement these functions for other systems#endif // WIN32#endif // unix    }}static void gtv_open_file( gchar* name, gpointer raw ){    SMPEG_Info* info = NULL;    SMPEG* mpeg = NULL;    gchar buffer[FILENAME_BUFFER_SIZE];    assert( name );    assert( raw );    gtv_close( NULL, raw );    if( SDL_Init( SDL_INIT_AUDIO | SDL_INIT_VIDEO ) < 0 ) {	fprintf( stderr, "gtv: couldn't initialize SDL: %s\n", SDL_GetError( ) );	exit( 1 );    }    info = (SMPEG_Info*) gtk_object_get_data( GTK_OBJECT( raw ), "info" );    assert( info );    mpeg = SMPEG_new( name, info, 1 );    if( SMPEG_error( mpeg ) ) {	fprintf( stderr, "gtv: %s\n", SMPEG_error( mpeg ) );	SMPEG_delete( mpeg );	gtk_object_set_data( GTK_OBJECT( raw ), "mpeg", NULL );	return;    }    gtk_object_set_data( GTK_OBJECT( raw ), "mpeg", mpeg );    strncpy( (char*) gtk_object_get_data( GTK_OBJECT( raw ), "filename_buffer" ),	     name,	     FILENAME_BUFFER_SIZE );    gtv_set_frame( raw, 0 );    gtv_set_fps( raw, 0.0 );    g_snprintf( buffer, FILENAME_BUFFER_SIZE, "gtv - %s", name );    gtk_window_set_title( GTK_WINDOW( raw ), buffer );    if( info->has_video ) {	SDL_Surface* sdl_screen = NULL;        const SDL_VideoInfo *video_info;        int video_bpp;        /* Get the "native" video mode */        video_info = SDL_GetVideoInfo();        switch (video_info->vfmt->BitsPerPixel) {            case 16:            case 32:                video_bpp = video_info->vfmt->BitsPerPixel;                break;            default:                video_bpp = 16;                break;        }#ifdef linux	putenv("SDL_VIDEO_CENTERED=1");#endif	sdl_screen = SDL_SetVideoMode( info->width , info->height , video_bpp, SDL_ASYNCBLIT);        SDL_WM_SetCaption(name, "gtv movie");        gtv_center_window(sdl_screen);	SMPEG_setdisplay( mpeg, sdl_screen, NULL, NULL );	gtk_object_set_data( GTK_OBJECT( raw ), "sdl_screen", sdl_screen );	gtv_double( NULL, raw );    }    gtv_loop( NULL, raw );    gtv_audio( NULL, raw );    gtv_filter( NULL, raw );    gtv_set_buttons_sensitive( raw, TRUE );}static void gtv_close( GtkWidget* item, gpointer raw ){    SMPEG* mpeg = NULL;    SMPEG_Info* info = NULL;    assert( raw != NULL );    gtv_stop( NULL, raw );    mpeg = (SMPEG*) gtk_object_get_data( GTK_OBJECT( raw ), "mpeg" );    if( mpeg ) {	SDL_Surface* sdl_screen = NULL;	SMPEG_delete( mpeg );	gtk_object_set_data( GTK_OBJECT( raw ), "mpeg", NULL );	info = (SMPEG_Info*) gtk_object_get_data( GTK_OBJECT( raw ), "info" );	memset( info, 0, sizeof( SMPEG_Info ) );	sdl_screen = (SDL_Surface*) gtk_object_get_data( GTK_OBJECT( raw ), "sdl_screen" );	SDL_FreeSurface( sdl_screen );	gtk_object_set_data( GTK_OBJECT( raw ), "sdl_screen", NULL );	SDL_Quit( );    }    /* Reset title. */    gtk_window_set_title( GTK_WINDOW( raw ), "gtv" );    gtv_set_frame( raw, 0 );    gtv_set_fps( raw, 0.0 );    gtv_set_buttons_sensitive( raw, FALSE );}static GtkWidget* create_file_info_dialog( void ){  GtkWidget *file_info_dialog;  GtkWidget *dialog_vbox1;  GtkWidget *vbox2;  GtkWidget *label5;  GtkWidget *scrolledwindow1;  GtkWidget *viewport1;  GtkWidget *text;  GtkWidget *dialog_action_area1;  GtkWidget *ok;  file_info_dialog = gtk_dialog_new ();  gtk_object_set_data (GTK_OBJECT (file_info_dialog), "file_info_dialog", file_info_dialog);  gtk_window_set_title (GTK_WINDOW (file_info_dialog), "File Info");  gtk_window_set_default_size (GTK_WINDOW (file_info_dialog), 256, 192);  dialog_vbox1 = GTK_DIALOG (file_info_dialog)->vbox;  gtk_object_set_data (GTK_OBJECT (file_info_dialog), "dialog_vbox1", dialog_vbox1);  gtk_widget_show (dialog_vbox1);  vbox2 = gtk_vbox_new (FALSE, 5);  gtk_widget_ref (vbox2);  gtk_object_set_data_full (GTK_OBJECT (file_info_dialog), "vbox2", vbox2,                            (GtkDestroyNotify) gtk_widget_unref);  gtk_widget_show (vbox2);  gtk_box_pack_start (GTK_BOX (dialog_vbox1), vbox2, TRUE, TRUE, 0);  gtk_container_set_border_width (GTK_CONTAINER (vbox2), 5);  label5 = gtk_label_new ("File info:");  gtk_widget_ref (label5);  gtk_object_set_data_full (GTK_OBJECT (file_info_dialog), "label5", label5,                            (GtkDestroyNotify) gtk_widget_unref);  gtk_widget_show (label5);  gtk_box_pack_start (GTK_BOX (vbox2), label5, FALSE, FALSE, 0);  gtk_misc_set_alignment (GTK_MISC (label5), 0, 0.5);  scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);  gtk_widget_ref (scrolledwindow1);  gtk_object_set_data_full (GTK_OBJECT (file_info_dialog), "scrolledwindow1", scrolledwindow1,                            (GtkDestroyNotify) gtk_widget_unref);  gtk_widget_show (scrolledwindow1);  gtk_box_pack_start (GTK_BOX (vbox2), scrolledwindow1, TRUE, TRUE, 0);  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);  viewport1 = gtk_viewport_new (NULL, NULL);  gtk_widget_ref (viewport1);  gtk_object_set_data_full (GTK_OBJECT (file_info_dialog), "viewport1", viewport1,                            (GtkDestroyNotify) gtk_widget_unref);  gtk_widget_show (viewport1);  gtk_container_add (GTK_CONTAINER (scrolledwindow1), viewport1);  text = gtk_text_new (NULL, NULL);  gtk_widget_ref (text);  gtk_object_set_data_full (GTK_OBJECT (file_info_dialog), "text", text,                            (GtkDestroyNotify) gtk_widget_unref);  gtk_widget_show (text);  gtk_container_add (GTK_CONTAINER (viewport1), text);  dialog_action_area1 = GTK_DIALOG (file_info_dialog)->action_area;  gtk_object_set_data (GTK_OBJECT (file_info_dialog), "dialog_action_area1", dialog_action_area1);  gtk_widget_show (dialog_action_area1);  gtk_container_set_border_width (GTK_CONTAINER (dialog_action_area1), 10);  ok = gtk_button_new_with_label ("  OK  ");  gtk_widget_ref (ok);  gtk_object_set_data_full (GTK_OBJECT (file_info_dialog), "ok", ok,                            (GtkDestroyNotify) gtk_widget_unref);  gtk_widget_show (ok);  gtk_box_pack_start (GTK_BOX (dialog_action_area1), ok, FALSE, FALSE, 0);  return file_info_dialog;}static void gtv_info( GtkWidget* item, gpointer raw ){    GtkWidget* dialog = NULL;    GtkWidget* ok = NULL;    gchar buffer[1024];    gint ignored = 0;    GtkWidget* text = NULL;    SMPEG_Info* info = NULL;    int hh,mm,ss;    dialog = create_file_info_dialog( );    ok = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( dialog ), "ok" ) );    gtk_signal_connect( GTK_OBJECT( ok ), "clicked",			GTK_SIGNAL_FUNC( gtv_dialog_cancel ), raw );    /* HACK HACK HACK */    gtk_object_set_data( GTK_OBJECT( raw ), "dialog", dialog );    /* Actually stuff some data in there. */    info = (SMPEG_Info*) gtk_object_get_data( GTK_OBJECT( raw ), "info" );    hh = info->total_time / 3600;    mm = (info->total_time - hh * 3600)/60;    ss = ((int)info->total_time % 60);    g_snprintf( buffer, 1024, "Filename: %s\nStream: %s\nVideo: %dx%d resolution\nAudio: %s\nSize: %d\nTime %d:%02d:%02d\n",		(gchar*) gtk_object_get_data( GTK_OBJECT( raw ), "filename_buffer" ),		( info->has_audio && info->has_video ) ? "system" :		( info->has_video ? "video" :		( info->has_audio ? "audio" : "not MPEG" ) ),		info->width, info->height,		( info->has_audio ? info->audio_string : "none" ),		info->total_size , hh,mm,ss);    text = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( dialog ), "text" ) );    gtk_editable_insert_text( GTK_EDITABLE( text ), buffer, strlen( buffer ), &ignored );    gtk_grab_add( dialog );    gtk_widget_show( dialog );}static GtkWidget* create_about_dialog( void ){  GtkWidget *about_dialog;  GtkWidget *dialog_vbox2;  GtkWidget *scrolledwindow2;  GtkWidget *viewport2;  GtkWidget *text;  GtkWidget *dialog_action_area2;  GtkWidget *ok;  about_dialog = gtk_dialog_new ();  gtk_object_set_data (GTK_OBJECT (about_dialog), "about_dialog", about_dialog);  gtk_window_set_title (GTK_WINDOW (about_dialog), "About gtv");  gtk_window_set_default_size (GTK_WINDOW (about_dialog), 384, 256);  gtk_window_set_policy (GTK_WINDOW (about_dialog), TRUE, TRUE, FALSE);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -