Added support for video via a GDK fallback

This commit is contained in:
Joel Holdsworth 2008-05-12 13:02:14 +01:00
parent 67413c7c17
commit f72dab3257
9 changed files with 198 additions and 29 deletions

View file

@ -41,6 +41,8 @@ gtk_lumiera_SOURCES = \
model/project.hpp \
output/displayer.cpp \
output/displayer.hpp \
output/gdkdisplayer.cpp \
output/gdkdisplayer.hpp \
output/xvdisplayer.cpp \
output/xvdisplayer.hpp

View file

@ -23,6 +23,8 @@
* *****************************************************/
#include "displayer.hpp"
#include "xvdisplayer.hpp"
#include "gdkdisplayer.hpp"
namespace lumiera {
namespace gui {
@ -31,7 +33,7 @@ namespace output {
bool
Displayer::usable()
{
return false;
return false;
}
DisplayerInput
@ -53,19 +55,19 @@ Displayer::preferredHeight()
}
void
Displayer::CalculateVideoLayout(
Displayer::calculateVideoLayout(
int widget_width, int widget_height,
int image_width, int image_height,
int &video_x, int &video_y, int &video_width, int &video_height )
{
double ratio_width = ( double ) widget_width / ( double ) image_width;
double ratio_height = ( double ) widget_height / ( double ) image_height;
double ratio_constant = ratio_height < ratio_width ?
ratio_height : ratio_width;
video_width = ( int ) ( image_width * ratio_constant + 0.5 );
video_height = ( int ) ( image_height * ratio_constant + 0.5 );
video_x = ( widget_width - video_width ) / 2;
video_y = ( widget_height - video_height ) / 2;
double ratio_width = ( double ) widget_width / ( double ) image_width;
double ratio_height = ( double ) widget_height / ( double ) image_height;
double ratio_constant = ratio_height < ratio_width ?
ratio_height : ratio_width;
video_width = ( int ) ( image_width * ratio_constant + 0.5 );
video_height = ( int ) ( image_height * ratio_constant + 0.5 );
video_x = ( widget_width - video_width ) / 2;
video_y = ( widget_height - video_height ) / 2;
}
} // namespace output

View file

@ -99,7 +99,7 @@ namespace output {
protected:
static void CalculateVideoLayout(
static void calculateVideoLayout(
int widget_width, int widget_height,
int image_width, int image_height,
int &video_x, int &video_y, int &video_width, int &video_height );

View file

@ -0,0 +1,76 @@
/*
gdkdisplayer.cpp - Implements the class for displaying video via GDK
Copyright (C) Lumiera.org
2000, Arne Schirmacher <arne@schirmacher.de>
2001-2007, Dan Dennedy <dan@dennedy.org>
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <gtkmm.h>
#include <gdk/gdkx.h>
#include <iostream>
using std::cerr;
using std::endl;
#include "gdkdisplayer.hpp"
namespace lumiera {
namespace gui {
namespace output {
GdkDisplayer::GdkDisplayer( Gtk::Widget *drawing_area, int width, int height ) :
drawingArea( drawing_area )
{
imageWidth = width, imageHeight = height;
}
bool
GdkDisplayer::usable()
{
return true;
}
void
GdkDisplayer::put( void *image )
{
int video_x = 0, video_y = 0, video_width = 0, video_height = 0;
calculateVideoLayout(
drawingArea->get_width(),
drawingArea->get_height(),
preferredWidth(), preferredHeight(),
video_x, video_y, video_width, video_height );
GdkWindow *window = drawingArea->get_window()->gobj();
GdkGC *gc = gdk_gc_new( window );
GdkPixbuf *pix = gdk_pixbuf_new_from_data( (const guchar*)image, GDK_COLORSPACE_RGB, FALSE, 8,
preferredWidth(), preferredHeight(), preferredWidth() * 3, NULL, NULL );
GdkPixbuf *im = gdk_pixbuf_scale_simple( pix, video_width, video_height, GDK_INTERP_NEAREST );
gdk_draw_pixbuf( window, gc, im, 0, 0, video_x, video_y, -1, -1, GDK_RGB_DITHER_NORMAL, 0, 0 );
g_object_unref( im );
g_object_unref( pix );
g_object_unref( gc );
}
} // namespace output
} // namespace gui
} // namespace lumiera

View file

@ -0,0 +1,62 @@
/*
gdkdisplayer.hpp - Defines the class for displaying video via GDK
Copyright (C) Lumiera.org
2000, Arne Schirmacher <arne@schirmacher.de>
2001-2007, Dan Dennedy <dan@dennedy.org>
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file gdkdisplayer.hpp
** This file contains the definition of XvDisplayer, the XVideo
** video output implementation
** @see gdkdisplayer.cpp
** @see displayer.hpp
*/
#include "displayer.hpp"
#ifndef GDKDISPLAYER_HPP
#define GDKDISPLAYER_HPP
namespace Gtk {
class Widget;
}
namespace lumiera {
namespace gui {
namespace output {
class GdkDisplayer : public Displayer
{
public:
GdkDisplayer( Gtk::Widget *drawing_area, int width, int height );
void put( void *image );
protected:
bool usable();
private:
Gtk::Widget *drawingArea;
};
} // namespace output
} // namespace gui
} // namespace lumiera
#endif // GDKDISPLAYER_HPP

View file

@ -1,5 +1,5 @@
/*
displayer.cpp - Implements the base class for displaying video
xvdisplayer.cpp - Implements the base class for XVideo display
Copyright (C) Lumiera.org
2000, Arne Schirmacher <arne@schirmacher.de>
@ -39,16 +39,15 @@ namespace gui {
namespace output {
XvDisplayer::XvDisplayer( Gtk::Widget *drawing_area, int width, int height ) :
xvImage( NULL )
xvImage( NULL ),
drawingArea( drawing_area ),
gotPort( false )
{
cerr << ">> Trying XVideo at " << width << "x" << height << endl;
this->drawingArea = drawing_area;
imageWidth = width;
imageHeight = height;
imageWidth = width, imageHeight = height;
shmInfo.shmaddr = NULL;
gotPort = false;
Glib::RefPtr<Gdk::Window> area_window = drawing_area->get_window();
@ -215,7 +214,7 @@ XvDisplayer::put( void *image )
if(xvImage != NULL)
{
int video_x = 0, video_y = 0, video_width = 0, video_height = 0;
CalculateVideoLayout(
calculateVideoLayout(
drawingArea->get_width(),
drawingArea->get_height(),
preferredWidth(), preferredHeight(),

View file

@ -1,5 +1,5 @@
/*
xcdisplayer.hpp - Defines the base class for XVideo display
xvdisplayer.hpp - Defines the base class for XVideo display
Copyright (C) Lumiera.org
2000, Arne Schirmacher <arne@schirmacher.de>
@ -25,6 +25,7 @@
** This file contains the definition of XvDisplayer, the XVideo
** video output implementation
** @see xvdisplayer.cpp
** @see displayer.hpp
*/
#include <X11/Xlib.h>

View file

@ -24,6 +24,9 @@
#include <gdkmm/general.h>
#include <cairomm-1.0/cairomm/cairomm.h>
#include "../output/xvdisplayer.hpp"
#include "../output/gdkdisplayer.hpp"
#include "video-display-widget.hpp"
namespace lumiera {
@ -32,15 +35,15 @@ namespace widgets {
VideoDisplayWidget::VideoDisplayWidget() :
gdkWindow(NULL),
xvDisplayer(NULL)
displayer(NULL)
{
set_flags(Gtk::NO_WINDOW);
}
VideoDisplayWidget::~VideoDisplayWidget()
{
if(xvDisplayer != NULL)
delete xvDisplayer;
if(displayer != NULL)
delete displayer;
}
void
@ -78,9 +81,9 @@ VideoDisplayWidget::on_realize()
//make the widget receive expose events
gdkWindow->set_user_data(gobj());
if(xvDisplayer != NULL)
delete xvDisplayer;
xvDisplayer = new XvDisplayer(this, 320, 240 );
if(displayer != NULL)
delete displayer;
displayer = createDisplayer(this, 320, 240);
add_events(Gdk::ALL_EVENTS_MASK);
}
@ -102,7 +105,7 @@ VideoDisplayWidget::on_button_press_event (GdkEventButton* event)
for(int i = 0; i < 320*240*4; i++)
buffer[i] = rand();
xvDisplayer->put((void*)buffer);
displayer->put((void*)buffer);
return true;
}
@ -131,6 +134,26 @@ VideoDisplayWidget::on_expose_event(GdkEventExpose* event)
return true;
}
Displayer*
VideoDisplayWidget::createDisplayer( Gtk::Widget *drawingArea, int width, int height )
{
Displayer *displayer = NULL;
displayer = new XvDisplayer( drawingArea, width, height );
if ( !displayer->usable() )
{
delete displayer;
displayer = NULL;
}
if ( displayer == NULL )
{
displayer = new GdkDisplayer( drawingArea, width, height );
}
return displayer;
}
} // namespace widgets
} // namespace gui
} // namespace lumiera

View file

@ -28,7 +28,7 @@
#include <gtkmm.h>
#include "../output/xvdisplayer.hpp"
#include "../output/displayer.hpp"
using namespace lumiera::gui::output;
@ -51,13 +51,17 @@ namespace widgets {
virtual bool on_expose_event(GdkEventExpose* event);
virtual bool on_button_press_event (GdkEventButton* event);
virtual bool on_button_press_event (GdkEventButton* event);
/* ===== Internals ===== */
private:
static Displayer*
createDisplayer( Gtk::Widget *drawingArea, int width, int height );
private:
Glib::RefPtr<Gdk::Window> gdkWindow;
XvDisplayer *xvDisplayer;
Displayer *displayer;
};
} // namespace widgets