Commit dfedf6f6 authored by Ali Abdallah's avatar Ali Abdallah

* Supports for Aspect ratio views.

	* Remember the size of the main window set.

(Old svn revision: 7868)
parent 5df19f48
2009-07-30: Ali aliov@xfce.org
* Supports for Aspect ratio views.
* Remember the size of the main window set.
2009-07-29: Ali aliov@xfce.org
* Added session code for session interaction.
* Support nice sound fading on exit.
......
=== Media player ===
* Support some aspect ratio view.
* Support scale ratio view.
* Complete the shortcut keys.
* Better support for cdda.
* Handle missing gstreamer plugins.
* Support scale ratio view.
* Better support for cdda.
* Support some playlist title entity.
* Use pixel-aspect-ratio info when calculating the
aspect ratio.
* ...
=== Plugins ===
......
......@@ -89,6 +89,7 @@ XDT_CHECK_PACKAGE([GIO], [gio-2.0], [glib_minimum_version])
XDT_CHECK_PACKAGE([GST], [gstreamer-0.10], [gstreamer_minimum_version])
XDT_CHECK_PACKAGE([GST_BASE], [gstreamer-base-0.10], [gstreamer_minimum_version])
XDT_CHECK_PACKAGE([GST_VIDEO], [gstreamer-video-0.10], [gstreamer_minimum_version])
XDT_CHECK_PACKAGE([GST_INTERFACES], [gstreamer-interfaces-0.10], [gstreamer_minimum_version])
XDT_CHECK_PACKAGE([DBUS], [dbus-1], [dbus_minimum_version])
......
......@@ -9,6 +9,7 @@
<property name="icon_name">parole</property>
<signal name="destroy" handler="parole_player_destroy_cb"/>
<signal name="key_press_event" handler="parole_player_key_press"/>
<signal name="configure_event" handler="parole_player_configure_event_cb"/>
<signal name="delete_event" handler="parole_player_delete_event_cb" after="yes"/>
<child>
<object class="GtkVBox" id="vbox1">
......@@ -119,6 +120,82 @@
<child type="submenu">
<object class="GtkMenu" id="menu2">
<property name="visible">True</property>
<child>
<object class="GtkMenuItem" id="menuitem1">
<property name="visible">True</property>
<property name="label" translatable="yes">Aspect Ratio</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu" id="menu5">
<property name="visible">True</property>
<child>
<object class="GtkRadioMenuItem" id="ratio_none">
<property name="visible">True</property>
<property name="label" translatable="yes">None</property>
<property name="use_underline">True</property>
<property name="draw_as_radio">True</property>
<signal name="toggled" handler="ratio_none_toggled_cb"/>
</object>
</child>
<child>
<object class="GtkRadioMenuItem" id="ratio_auto">
<property name="visible">True</property>
<property name="label" translatable="yes">Auto</property>
<property name="use_underline">True</property>
<property name="draw_as_radio">True</property>
<property name="group">ratio_none</property>
<signal name="toggled" handler="ratio_auto_toggled_cb"/>
</object>
</child>
<child>
<object class="GtkRadioMenuItem" id="ratio_square">
<property name="visible">True</property>
<property name="label" translatable="yes">Square</property>
<property name="use_underline">True</property>
<property name="draw_as_radio">True</property>
<property name="group">ratio_none</property>
<signal name="toggled" handler="ratio_square_toggled_cb"/>
</object>
</child>
<child>
<object class="GtkRadioMenuItem" id="ratio_4_3">
<property name="visible">True</property>
<property name="label" translatable="yes">4:3 (TV)</property>
<property name="use_underline">True</property>
<property name="draw_as_radio">True</property>
<property name="group">ratio_none</property>
<signal name="toggled" handler="ratio_4_3_toggled_cb"/>
</object>
</child>
<child>
<object class="GtkRadioMenuItem" id="ratio_16_9">
<property name="visible">True</property>
<property name="label" translatable="yes">16:9 (Widescreen)</property>
<property name="use_underline">True</property>
<property name="draw_as_radio">True</property>
<property name="group">ratio_none</property>
<signal name="toggled" handler="ratio_16_9_toggled_cb"/>
</object>
</child>
<child>
<object class="GtkRadioMenuItem" id="ratio_20_9">
<property name="visible">True</property>
<property name="label" translatable="yes">20:9 (DVB)</property>
<property name="use_underline">True</property>
<property name="draw_as_radio">True</property>
<property name="group">ratio_none</property>
<signal name="toggled" handler="ratio_20_9_toggled_cb"/>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem" id="separatormenuitem3">
<property name="visible">True</property>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="fullscreen-menu">
<property name="label">gtk-fullscreen</property>
......@@ -227,6 +304,7 @@
<child>
<object class="GtkHBox" id="output">
<property name="visible">True</property>
<property name="app_paintable">True</property>
<child>
<placeholder/>
</child>
......
......@@ -20,6 +20,7 @@ INCLUDES = \
$(LIBXFCE4GUI_CFLAGS) \
$(LIBXFCE4UTIL_CFLAGS) \
$(GST_CFLAGS) \
$(GST_VIDEO_CFLAGS) \
$(GST_BASE_CFLAGS) \
$(GST_INTERFACES_CFLAGS)
......@@ -40,6 +41,7 @@ PAROLE_LIBS = \
$(LIBXFCE4UTIL_LIBS) \
$(GST_LIBS) \
$(GST_BASE_LIBS) \
$(GST_VIDEO_LIBS) \
$(GST_INTERFACES_LIBS)
GENERATED_FILES = \
......@@ -142,7 +144,8 @@ parole_glib_enum_headers = \
parole-gst.h \
parole-plugin.h \
parole-pl-parser.h \
parole-stream.h
parole-stream.h \
parole-conf.h
if MAINTAINER_MODE
......@@ -176,6 +179,7 @@ enum-gtypes.c: $(parole_glib_enum_headers) Makefile
--fhead "#include \"parole-plugin.h\"\n\n" \
--fhead "#include \"parole-pl-parser.h\"\n\n" \
--fhead "#include \"parole-stream.h\"\n\n" \
--fhead "#include \"parole-conf.h\"\n\n" \
--fprod "\n/* enumerations from \"@filename@\" */" \
--vhead "GType\n@enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G@Type@Value values[] = {" \
--vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
......
......@@ -30,6 +30,7 @@
#include "parole-conf.h"
#include "parole-rc-utils.h"
#include "enum-gtypes.h"
#define PAROLE_CONF_GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), PAROLE_TYPE_CONF, ParoleConfPrivate))
......@@ -49,6 +50,9 @@ struct ParoleConfPrivate
gint contrast;
gint hue;
gint saturation;
ParoleAspectRatio aspect_ratio;
gint window_width;
gint window_height;
};
static gpointer parole_conf_object = NULL;
......@@ -68,7 +72,11 @@ enum
PROP_BRIGHTNESS,
PROP_CONTRAST,
PROP_HUE,
PROP_SATURATION
PROP_SATURATION,
PROP_ASPECT_RATIO,
PROP_WINDOW_WIDTH,
PROP_WINDOW_HEIGHT,
N_PROP
};
static void parole_conf_set_property (GObject *object,
......@@ -132,6 +140,18 @@ static void parole_conf_set_property (GObject *object,
conf->priv->brightness = g_value_get_int (value);
parole_rc_write_entry_int ("BRIGHTNESS", PAROLE_RC_GROUP_GENERAL, conf->priv->brightness);
break;
case PROP_ASPECT_RATIO:
conf->priv->aspect_ratio = g_value_get_enum (value);
parole_rc_write_entry_int ("ASPECT_RATIO", PAROLE_RC_GROUP_GENERAL, conf->priv->aspect_ratio);
break;
case PROP_WINDOW_WIDTH:
conf->priv->window_width = g_value_get_int (value);
parole_rc_write_entry_int ("WINDOW_WIDTH", PAROLE_RC_GROUP_GENERAL, conf->priv->window_width);
break;
case PROP_WINDOW_HEIGHT:
conf->priv->window_height = g_value_get_int (value);
parole_rc_write_entry_int ("WINDOW_HEIGHT", PAROLE_RC_GROUP_GENERAL, conf->priv->window_height);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
goto out;
......@@ -185,6 +205,15 @@ static void parole_conf_get_property (GObject *object,
case PROP_BRIGHTNESS:
g_value_set_int (value, conf->priv->brightness);
break;
case PROP_ASPECT_RATIO:
g_value_set_enum (value, conf->priv->aspect_ratio);
break;
case PROP_WINDOW_WIDTH:
g_value_set_int (value, conf->priv->window_width);
break;
case PROP_WINDOW_HEIGHT:
g_value_set_int (value, conf->priv->window_height);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
......@@ -299,6 +328,32 @@ parole_conf_class_init (ParoleConfClass *klass)
0,
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_ASPECT_RATIO,
g_param_spec_enum ("aspect-ratio",
NULL, NULL,
ENUM_GTYPE_ASPECT_RATIO,
PAROLE_ASPECT_RATIO_NONE,
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_WINDOW_WIDTH,
g_param_spec_int ("window-width",
NULL, NULL,
320,
G_MAXINT16,
780,
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_WINDOW_HEIGHT,
g_param_spec_int ("window-height",
NULL, NULL,
220,
G_MAXINT16,
480,
G_PARAM_READWRITE));
g_type_class_add_private (klass, sizeof (ParoleConfPrivate));
}
......@@ -318,6 +373,9 @@ parole_conf_init (ParoleConf *conf)
conf->priv->hue = parole_rc_read_entry_int ("HUE", PAROLE_RC_GROUP_GENERAL, 0);
conf->priv->contrast = parole_rc_read_entry_int ("CONTRAST", PAROLE_RC_GROUP_GENERAL, 0);
conf->priv->brightness = parole_rc_read_entry_int ("BRIGHTNESS", PAROLE_RC_GROUP_GENERAL, 0);
conf->priv->aspect_ratio = parole_rc_read_entry_int ("ASPECT_RATIO", PAROLE_RC_GROUP_GENERAL, PAROLE_ASPECT_RATIO_NONE);
conf->priv->window_width = parole_rc_read_entry_int ("WINDOW_WIDTH", PAROLE_RC_GROUP_GENERAL, 780);
conf->priv->window_height = parole_rc_read_entry_int ("WINDOW_HEIGHT", PAROLE_RC_GROUP_GENERAL, 480);
}
ParoleConf *
......
......@@ -31,10 +31,11 @@ G_BEGIN_DECLS
typedef enum
{
PAROLE_ASPECT_RATIO_AUTO ,
PAROLE_ASPECT_RATIO_NONE,
PAROLE_ASPECT_RATIO_AUTO,
PAROLE_ASPECT_RATIO_SQUARE,
PAROLE_ASPECT_RATIO_4_3,
PAROLE_ASPECT_RATIO_0,
PAROLE_ASPECT_RATIO_16_9,
PAROLE_ASPECT_RATIO_DVB
} ParoleAspectRatio;
......
......@@ -31,6 +31,8 @@
#include <gst/interfaces/xoverlay.h>
#include <gst/interfaces/navigation.h>
#include <gst/video/video.h>
#include <libxfce4util/libxfce4util.h>
#include <libxfcegui4/libxfcegui4.h>
......@@ -75,6 +77,7 @@ struct ParoleGstPrivate
gboolean buffering;
gboolean update_color_balance;
ParoleAspectRatio aspect_ratio;
/*
* xvimage sink has brightness+hue+aturation+contrast.
......@@ -113,7 +116,7 @@ parole_gst_finalize (GObject *object)
g_object_unref (gst->priv->stream);
g_object_unref (gst->priv->playbin);
g_object_unref (gst->priv->bus);
g_object_unref (gst->priv->logo);
g_mutex_free (gst->priv->lock);
......@@ -144,7 +147,22 @@ parole_gst_set_window_cursor (GdkWindow *window, GdkCursor *cursor)
static gboolean
parole_gst_configure_event_cb (GtkWidget *widget, GdkEventConfigure *ev, ParoleGst *gst)
{
return FALSE;
}
static gboolean
parole_gst_parent_expose_event (GtkWidget *w, GdkEventExpose *ev, ParoleGst *gst)
{
cairo_t *cr;
cr = gdk_cairo_create (w->window);
cairo_set_source_rgb (cr, 0.0f, 0.0f, 0.0f);
cairo_rectangle (cr, w->allocation.x, w->allocation.y, w->allocation.width, w->allocation.height);
cairo_fill (cr);
cairo_destroy (cr);
return FALSE;
}
......@@ -190,6 +208,9 @@ parole_gst_realize (GtkWidget *widget)
g_signal_connect (gtk_widget_get_toplevel (widget), "configure_event",
G_CALLBACK (parole_gst_configure_event_cb), gst);
g_signal_connect (gtk_widget_get_parent (widget), "expose_event",
G_CALLBACK (parole_gst_parent_expose_event), gst);
}
static void
......@@ -205,6 +226,85 @@ parole_gst_show (GtkWidget *widget)
GTK_WIDGET_CLASS (parole_gst_parent_class)->show (widget);
}
static void
parole_gst_get_video_output_size (ParoleGst *gst, gint *ret_w, gint *ret_h)
{
/*
* Default values returned if:
* 1) We are not playing.
* 2) Playing audio.
* 3) Playing video but we don't have its correct size yet.
*/
*ret_w = GTK_WIDGET (gst)->allocation.width;
*ret_h = GTK_WIDGET (gst)->allocation.height;
if ( gst->priv->state >= GST_STATE_PAUSED )
{
gboolean has_video;
guint video_w, video_h;
guint video_par_n, video_par_d;
guint dar_n, dar_d;
g_object_get (G_OBJECT (gst->priv->stream),
"has-video", &has_video,
"video-width", &video_w,
"video-height", &video_h,
NULL);
if ( has_video )
{
if ( video_w != 0 && video_h != 0 )
{
switch ( gst->priv->aspect_ratio )
{
case PAROLE_ASPECT_RATIO_NONE:
return;
case PAROLE_ASPECT_RATIO_AUTO:
*ret_w = video_w;
*ret_h = video_h;
return;
case PAROLE_ASPECT_RATIO_SQUARE:
video_par_n = 1;
video_par_d = 1;
break;
case PAROLE_ASPECT_RATIO_16_9:
video_par_n = 16 * video_h;
video_par_d = 9 * video_w;
break;
case PAROLE_ASPECT_RATIO_4_3:
video_par_n = 4 * video_h;
video_par_d = 3 * video_w;
break;
case PAROLE_ASPECT_RATIO_DVB:
video_par_n = 20 * video_h;
video_par_d = 9 * video_w;
break;
default:
return;
}
if ( gst_video_calculate_display_ratio (&dar_n, &dar_d,
video_w, video_h,
video_par_n, video_par_d,
1, 1) )
{
if (video_w % dar_n == 0)
{
*ret_w = video_w;
*ret_h = (guint) gst_util_uint64_scale (video_w, dar_d, dar_n);
}
else
{
*ret_w = (guint) gst_util_uint64_scale (video_h, dar_n, dar_d);
*ret_h = video_w;
}
TRACE ("Got best video size %dx%d\n", *ret_w, *ret_h);
}
}
}
}
}
static void
parole_gst_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
{
......@@ -214,9 +314,30 @@ parole_gst_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
if ( GTK_WIDGET_REALIZED (widget) )
{
gint w, h;
gdouble ratio, width, height;
w = allocation->width;
h = allocation->height;
parole_gst_get_video_output_size (PAROLE_GST (widget), &w, &h);
width = w;
height = h;
if ( (gdouble) allocation->width / width > allocation->height / height)
ratio = (gdouble) allocation->height / height;
else
ratio = (gdouble) allocation->width / width;
width *= ratio;
height *= ratio;
gdk_window_move_resize (widget->window,
allocation->x, allocation->y,
allocation->width, allocation->height);
allocation->x + (allocation->width - width)/2,
allocation->y + (allocation->height - height)/2,
width,
height);
gtk_widget_queue_draw (widget);
}
......@@ -343,7 +464,8 @@ parole_gst_expose_event (GtkWidget *widget, GdkEventExpose *ev)
parole_gst_set_x_overlay (gst);
if ( (gst->priv->state < GST_STATE_PAUSED || !gst->priv->with_vis ) && !playing_video && !gst->priv->buffering)
if ( (gst->priv->state < GST_STATE_PAUSED || !gst->priv->with_vis ) &&
!playing_video && !gst->priv->buffering)
parole_gst_draw_logo (gst);
else
{
......@@ -544,24 +666,6 @@ parole_gst_load_subtitle (ParoleGst *gst)
g_free (uri);
}
static void
parole_gst_set_size (GtkWidget *widget, gint w, gint h)
{
GdkScreen *screen;
GtkWidget *toplevel;
gint monitor;
toplevel = gtk_widget_get_toplevel (widget);
gtk_widget_set_size_request (GTK_WIDGET (widget), w, h);
screen = gtk_window_get_screen (GTK_WINDOW (toplevel));
monitor = gdk_screen_get_monitor_at_window (screen, toplevel->window),
xfce_gtk_window_center_on_monitor (GTK_WINDOW (toplevel), screen, monitor);
}
static void
parole_gst_get_pad_capabilities (GObject *object, GParamSpec *pspec, ParoleGst *gst)
{
......@@ -587,13 +691,17 @@ parole_gst_get_pad_capabilities (GObject *object, GParamSpec *pspec, ParoleGst *
"video-width", width,
"video-height", height,
NULL);
parole_gst_set_size (GTK_WIDGET (gst), width, height);
if ( ( value = gst_structure_get_value (st, "pixel-aspect-ratio")) )
{
num = gst_value_get_fraction_numerator (value),
den = gst_value_get_fraction_denominator (value);
TRACE ("FIXME: Use these value num=%d den=%d \n", num, den);
}
parole_gst_get_video_output_size (gst, &width, &height);
parole_gst_size_allocate (GTK_WIDGET (gst), &GTK_WIDGET (gst)->allocation);
}
}
......@@ -756,6 +864,7 @@ parole_gst_evaluate_state (ParoleGst *gst, GstState old, GstState new, GstState
}
else if ( gst->priv->target == GST_STATE_READY)
{
parole_gst_size_allocate (GTK_WIDGET (gst), &GTK_WIDGET (gst)->allocation);
parole_gst_draw_logo (gst);
}
break;
......@@ -859,9 +968,9 @@ parole_gst_application_message (ParoleGst *gst, GstMessage *msg)
{
parole_gst_update_stream_info (gst);
}
else
else if ( !g_strcmp0 (name, "video-size") )
{
//FIXME: Handle video size message.
parole_gst_size_allocate (GTK_WIDGET (gst), &GTK_WIDGET (gst)->allocation);
}
}
......@@ -1103,6 +1212,7 @@ parole_gst_construct (GObject *object)
parole_gst_load_logo (gst);
parole_gst_set_subtitle_encoding (gst);
parole_gst_set_subtitle_font (gst);
}
static gboolean
......@@ -1222,6 +1332,14 @@ parole_gst_conf_notify_cb (GObject *object, GParamSpec *spec, ParoleGst *gst)
if ( gst->priv->state >= GST_STATE_PAUSED )
parole_gst_set_video_color_balance (gst);
}
else if ( !g_strcmp0 ("aspect-ratio", spec->name) )
{
g_object_get (G_OBJECT (gst->priv->conf),
"aspect-ratio", &gst->priv->aspect_ratio,
NULL);
parole_gst_size_allocate (GTK_WIDGET (gst), &GTK_WIDGET (gst)->allocation);
}
}
static void
......@@ -1313,6 +1431,10 @@ parole_gst_init (ParoleGst *gst)
gst->priv->conf = parole_conf_new ();
g_object_get (G_OBJECT (gst->priv->conf),
"aspect-ratio", &gst->priv->aspect_ratio,
NULL);
g_signal_connect (G_OBJECT (gst->priv->conf), "notify",
G_CALLBACK (parole_gst_conf_notify_cb), gst);
......@@ -1434,7 +1556,7 @@ void parole_gst_terminate (ParoleGst *gst)
step = volume - volume / 10;
parole_gst_set_volume (gst, step < 0.01 ? 0 : step);
volume = parole_gst_get_volume (gst);
g_usleep (30000);
g_usleep (35000);
}
}
}
......
......@@ -54,6 +54,10 @@
/*
* GtkBuilder Callbacks
*/
gboolean parole_player_configure_event_cb (GtkWidget *widget,
GdkEventConfigure *ev,
ParolePlayer *player);
gboolean parole_player_range_button_press (GtkWidget *widget,
GdkEventButton *ev,
ParolePlayer *player);
......@@ -128,6 +132,27 @@ void parole_player_shuffle_toggled_cb (GtkWidget *widget,
void parole_player_repeat_toggled_cb (GtkWidget *widget,
ParolePlayer *player);
/*
* Aspect ratio
*/
void ratio_none_toggled_cb (GtkWidget *widget,
ParolePlayer *player);
void ratio_auto_toggled_cb (GtkWidget *widget,
ParolePlayer *player);
void ratio_square_toggled_cb (GtkWidget *widget,
ParolePlayer *player);
void ratio_4_3_toggled_cb (GtkWidget *widget,
ParolePlayer *player);
void ratio_16_9_toggled_cb (GtkWidget *widget,
ParolePlayer *player);
void ratio_20_9_toggled_cb (GtkWidget *widget,
ParolePlayer *player);
void parole_show_about (GtkWidget *widget);
gboolean parole_player_key_press (GtkWidget *widget,
......@@ -193,6 +218,48 @@ void parole_show_about (GtkWidget *widget)
parole_about (_("Parole Media Player"));
}
void ratio_none_toggled_cb (GtkWidget *widget, ParolePlayer *player)
{
g_object_set (G_OBJECT (player->priv->conf),
"aspect-ratio", PAROLE_ASPECT_RATIO_NONE,
NULL);
}
void ratio_auto_toggled_cb (GtkWidget *widget, ParolePlayer *player)
{
g_object_set (G_OBJECT (player->priv->conf),
"aspect-ratio", PAROLE_ASPECT_RATIO_AUTO,
NULL);
}
void ratio_square_toggled_cb (GtkWidget *widget, ParolePlayer *player)
{
g_object_set (G_OBJECT (player->priv->conf),
"aspect-ratio", PAROLE_ASPECT_RATIO_SQUARE,
NULL);
}
void ratio_4_3_toggled_cb (GtkWidget *widget, ParolePlayer *player)
{
g_object_set (G_OBJECT (player->priv->conf),
"aspect-ratio", PAROLE_ASPECT_RATIO_4_3,
NULL);
}
void ratio_16_9_toggled_cb (GtkWidget *widget, ParolePlayer *player)
{
g_object_set (G_OBJECT (player->priv->conf),
"aspect-ratio", PAROLE_ASPECT_RATIO_16_9,
NULL);
}
void ratio_20_9_toggled_cb (GtkWidget *widget, ParolePlayer *player)
{
g_object_set (G_OBJECT (player->priv->conf),
"aspect-ratio", PAROLE_ASPECT_RATIO_DVB,
NULL);
}