Evince
Evince is a document viewer capable of displaying multiple and single page document formats like PDF and Postscript.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ev-media-player.c File Reference
#include "config.h"
#include "ev-media-player.h"
#include <gst/video/videooverlay.h>
+ Include dependency graph for ev-media-player.c:

Go to the source code of this file.

Data Structures

struct  _EvMediaPlayer
 
struct  _EvMediaPlayerClass
 

Enumerations

enum  { PROP_0, PROP_MEDIA }
 

Functions

static void ev_media_player_update_position (EvMediaPlayer *player)
 
static gboolean query_position_cb (EvMediaPlayer *player)
 
static void ev_media_player_query_position_start (EvMediaPlayer *player)
 
static void ev_media_player_query_position_stop (EvMediaPlayer *player)
 
static void ev_media_player_query_position (EvMediaPlayer *player)
 
static void ev_media_player_update_play_button (EvMediaPlayer *player)
 
static void ev_media_player_update_state (EvMediaPlayer *player, GstState *new_state)
 
static void ev_media_player_toggle_state (EvMediaPlayer *player)
 
static void ev_media_player_seek (EvMediaPlayer *player, GtkScrollType scroll, gdouble position)
 
static void ev_media_player_notify_eos (EvMediaPlayer *player)
 
static GstBusSyncReply bus_sync_handle (GstBus *bus, GstMessage *message, EvMediaPlayer *player)
 
static void bus_message_handle (GstBus *bus, GstMessage *message, EvMediaPlayer *player)
 
static void drawing_area_realize_cb (GtkWidget *widget, EvMediaPlayer *player)
 
static void ev_media_player_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
 
static void ev_media_player_dispose (GObject *object)
 
static void ev_media_player_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
 
static void ev_media_player_init (EvMediaPlayer *player)
 
static void ev_media_player_setup_media_controls (EvMediaPlayer *player)
 
static void ev_media_player_constructed (GObject *object)
 
static void ev_media_player_class_init (EvMediaPlayerClass *klass)
 
GtkWidget * ev_media_player_new (EvMedia *media)
 
EvMediaev_media_player_get_media (EvMediaPlayer *player)
 

Enumeration Type Documentation

anonymous enum
Enumerator
PROP_0 
PROP_MEDIA 

Definition at line 33 of file ev-media-player.c.

33  {
34  PROP_0,
35  PROP_MEDIA,
36 };

Function Documentation

static void bus_message_handle ( GstBus *  bus,
GstMessage *  message,
EvMediaPlayer player 
)
static

Definition at line 229 of file ev-media-player.c.

232 {
233  switch (GST_MESSAGE_TYPE (message)) {
234  case GST_MESSAGE_ERROR: {
235  GError *error = NULL;
236  gchar *dbg;
237 
238  gst_message_parse_error (message, &error, &dbg);
239  g_warning ("Error: %s (%s)\n", error->message, dbg);
240  g_error_free (error);
241  g_free (dbg);
242  }
243  break;
244  case GST_MESSAGE_STATE_CHANGED:
245  if (GST_MESSAGE_SRC (message) != (GstObject *)player->pipeline)
246  return;
247 
248  if (!player->is_seeking)
249  ev_media_player_update_state (player, NULL);
250 
251  break;
252  case GST_MESSAGE_ASYNC_DONE: {
253  GstState state;
254 
255  if (GST_MESSAGE_SRC (message) != (GstObject *)player->pipeline)
256  return;
257 
258  if (!ev_media_get_show_controls (player->media))
259  return;
260 
261  if (player->is_seeking) {
262  player->is_seeking = FALSE;
263  if (player->is_playing)
265  } else {
266  ev_media_player_update_state (player, &state);
267 
268  if (player->duration == 0 && (state == GST_STATE_PAUSED || state == GST_STATE_PLAYING)) {
269  gint64 duration;
270 
271  gst_element_query_duration (player->pipeline, GST_FORMAT_TIME, &duration);
272  player->duration = (gdouble)duration / GST_SECOND;
273  gtk_range_set_range (GTK_RANGE (player->slider), 0, player->duration);
274  }
275  }
276 
277  }
278  break;
279  case GST_MESSAGE_EOS:
280  player->is_playing = FALSE;
282 
283  break;
284  default:
285  break;
286  }
287 }

+ Here is the caller graph for this function:

static GstBusSyncReply bus_sync_handle ( GstBus *  bus,
GstMessage *  message,
EvMediaPlayer player 
)
static

Definition at line 208 of file ev-media-player.c.

211 {
212  GstVideoOverlay *overlay;
213 
214  if (!gst_is_video_overlay_prepare_window_handle_message (message))
215  return GST_BUS_PASS;
216 
217  overlay = GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message));
218  gst_video_overlay_set_window_handle (overlay, (guintptr)player->window_handle);
219  gst_video_overlay_expose (overlay);
220 
221  player->overlay = overlay;
222 
223  gst_message_unref (message);
224 
225  return GST_BUS_DROP;
226 }

+ Here is the caller graph for this function:

static void drawing_area_realize_cb ( GtkWidget *  widget,
EvMediaPlayer player 
)
static

Definition at line 290 of file ev-media-player.c.

292 {
293 #if defined (GDK_WINDOWING_X11)
294  player->window_handle = (guint64)GDK_WINDOW_XID (gtk_widget_get_window (widget));
295 #elif defined (GDK_WINDOWING_WIN32)
296  player->window_handle = (guint64)GDK_WINDOW_HWND (gtk_widget_get_window (widget));
297 #else
298  g_assert_not_reached ();
299 #endif
300 }

+ Here is the caller graph for this function:

static void ev_media_player_class_init ( EvMediaPlayerClass klass)
static

Definition at line 461 of file ev-media-player.c.

462 {
463  GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
464  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
465 
466  if (!gst_is_initialized ()) {
467  GError *error = NULL;
468 
469  if (!gst_init_check (NULL, NULL, &error)) {
470  g_warning ("Failed to initialize GStreamer: %s\n", error->message);
471  g_error_free (error);
472  }
473  }
474 
475  g_object_class->constructed = ev_media_player_constructed;
476  g_object_class->dispose = ev_media_player_dispose;
477  g_object_class->set_property = ev_media_player_set_property;
478  widget_class->size_allocate = ev_media_player_size_allocate;
479 
480  g_object_class_install_property (g_object_class,
481  PROP_MEDIA,
482  g_param_spec_object ("media",
483  "Media",
484  "The media played by the player",
486  G_PARAM_WRITABLE |
487  G_PARAM_CONSTRUCT_ONLY |
488  G_PARAM_STATIC_STRINGS));
489 }
static void ev_media_player_constructed ( GObject *  object)
static

Definition at line 444 of file ev-media-player.c.

445 {
446  EvMediaPlayer *player = EV_MEDIA_PLAYER (object);
447 
448  G_OBJECT_CLASS (ev_media_player_parent_class)->constructed (object);
449 
450  if (ev_media_get_show_controls (player->media))
452 
453  if (!player->pipeline)
454  return;
455 
456  g_object_set (player->pipeline, "uri", ev_media_get_uri (player->media), NULL);
457  gst_element_set_state (player->pipeline, GST_STATE_PLAYING);
458 }

+ Here is the caller graph for this function:

static void ev_media_player_dispose ( GObject *  object)
static

Definition at line 330 of file ev-media-player.c.

331 {
332  EvMediaPlayer *player = EV_MEDIA_PLAYER (object);
333 
335 
336  if (player->bus) {
337  gst_bus_remove_signal_watch (player->bus);
338  gst_object_unref (player->bus);
339  player->bus = NULL;
340  }
341 
342  if (player->pipeline) {
343  gst_element_set_state (player->pipeline, GST_STATE_NULL);
344  gst_object_unref (player->pipeline);
345  player->pipeline = NULL;
346  }
347 
348  g_clear_object (&player->media);
349 
350  G_OBJECT_CLASS (ev_media_player_parent_class)->dispose (object);
351 }

+ Here is the caller graph for this function:

EvMedia* ev_media_player_get_media ( EvMediaPlayer player)

Definition at line 500 of file ev-media-player.c.

501 {
502  g_return_val_if_fail (EV_IS_MEDIA_PLAYER (player), NULL);
503 
504  return player->media;
505 }

+ Here is the caller graph for this function:

static void ev_media_player_init ( EvMediaPlayer player)
static

Definition at line 371 of file ev-media-player.c.

372 {
373  gtk_orientable_set_orientation (GTK_ORIENTABLE (player), GTK_ORIENTATION_VERTICAL);
374 
375  player->pipeline = gst_element_factory_make ("playbin", NULL);
376  if (!player->pipeline) {
377  g_warning ("Failed to create playbin\n");
378  return;
379  }
380 
381  player->drawing_area = gtk_drawing_area_new ();
382  g_signal_connect (player->drawing_area, "realize",
383  G_CALLBACK (drawing_area_realize_cb),
384  player);
385  gtk_box_pack_start (GTK_BOX (player), player->drawing_area, TRUE, TRUE, 0);
386  gtk_widget_show (player->drawing_area);
387 
388  player->bus = gst_pipeline_get_bus (GST_PIPELINE (player->pipeline));
389  gst_bus_set_sync_handler (player->bus, (GstBusSyncHandler)bus_sync_handle, player, NULL);
390  gst_bus_add_signal_watch (player->bus);
391  g_signal_connect_object (player->bus, "message",
392  G_CALLBACK (bus_message_handle),
393  player, 0);
394 }
GtkWidget* ev_media_player_new ( EvMedia media)

Definition at line 492 of file ev-media-player.c.

493 {
494  g_return_val_if_fail (EV_IS_MEDIA (media), NULL);
495 
496  return GTK_WIDGET (g_object_new (EV_TYPE_MEDIA_PLAYER, "media", media, NULL));
497 }

+ Here is the caller graph for this function:

static void ev_media_player_notify_eos ( EvMediaPlayer player)
static

Definition at line 192 of file ev-media-player.c.

193 {
194  if (!ev_media_get_show_controls (player->media)) {
195  /* A media without controls can't be played again */
196  gtk_widget_destroy (GTK_WIDGET (player));
197  return;
198  }
199 
202  player->position = 0;
204  gst_element_set_state (player->pipeline, GST_STATE_READY);
205 }

+ Here is the caller graph for this function:

static void ev_media_player_query_position ( EvMediaPlayer player)
static

Definition at line 110 of file ev-media-player.c.

111 {
112  if (!ev_media_get_show_controls (player->media))
113  return;
114 
115  if (player->duration <= 0)
116  return;
117 
118  if (player->is_playing)
120  else
122  query_position_cb (player);
123 }

+ Here is the caller graph for this function:

static void ev_media_player_query_position_start ( EvMediaPlayer player)
static

Definition at line 87 of file ev-media-player.c.

88 {
89  if (player->position_timeout_id > 0)
90  return;
91 
92  if (!ev_media_get_show_controls (player->media))
93  return;
94 
95  player->position_timeout_id = g_timeout_add (1000 / 15,
96  (GSourceFunc)query_position_cb,
97  player);
98 }

+ Here is the caller graph for this function:

static void ev_media_player_query_position_stop ( EvMediaPlayer player)
static

Definition at line 101 of file ev-media-player.c.

102 {
103  if (player->position_timeout_id > 0) {
104  g_source_remove (player->position_timeout_id);
105  player->position_timeout_id = 0;
106  }
107 }

+ Here is the caller graph for this function:

static void ev_media_player_seek ( EvMediaPlayer player,
GtkScrollType  scroll,
gdouble  position 
)
static

Definition at line 171 of file ev-media-player.c.

174 {
175  if (!player->pipeline)
176  return;
177 
178  position = CLAMP (position, 0, player->duration);
179  if (gst_element_seek_simple (player->pipeline,
180  GST_FORMAT_TIME,
181  GST_SEEK_FLAG_FLUSH,
182  (gint64)(position * GST_SECOND))) {
183  player->is_seeking = TRUE;
185  player->position = position;
187  }
188 }

+ Here is the caller graph for this function:

static void ev_media_player_set_property ( GObject *  object,
guint  prop_id,
const GValue *  value,
GParamSpec *  pspec 
)
static

Definition at line 354 of file ev-media-player.c.

358 {
359  EvMediaPlayer *player = EV_MEDIA_PLAYER (object);
360 
361  switch (prop_id) {
362  case PROP_MEDIA:
363  player->media = EV_MEDIA (g_value_dup_object (value));
364  break;
365  default:
366  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
367  }
368 }

+ Here is the caller graph for this function:

static void ev_media_player_setup_media_controls ( EvMediaPlayer player)
static

Definition at line 397 of file ev-media-player.c.

398 {
399  GtkAdjustment *adjustment;
400  GtkCssProvider *provider;
401 
402  player->controls = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
403 
404  gtk_style_context_add_class (gtk_widget_get_style_context (player->controls), GTK_STYLE_CLASS_OSD);
405 
406  player->play_button = gtk_button_new ();
407  g_signal_connect_swapped (player->play_button, "clicked",
408  G_CALLBACK (ev_media_player_toggle_state),
409  player);
410  gtk_widget_set_name (player->play_button, "ev-media-player-play-button");
411  gtk_widget_set_valign (player->play_button, GTK_ALIGN_CENTER);
412  gtk_button_set_relief (GTK_BUTTON (player->play_button), GTK_RELIEF_NONE);
413  gtk_button_set_image (GTK_BUTTON (player->play_button),
414  gtk_image_new_from_icon_name ("media-playback-start-symbolic",
415  GTK_ICON_SIZE_MENU));
416  gtk_button_set_label(GTK_BUTTON (player->play_button), NULL);
417  gtk_button_set_focus_on_click (GTK_BUTTON (player->play_button), FALSE);
418 
419  provider = gtk_css_provider_new ();
420  gtk_css_provider_load_from_data (provider, "#ev-media-player-play-button { padding: 0px 8px 0px 8px; }", -1, NULL);
421  gtk_style_context_add_provider (gtk_widget_get_style_context (player->play_button),
422  GTK_STYLE_PROVIDER (provider),
423  GTK_STYLE_PROVIDER_PRIORITY_USER);
424  g_object_unref (provider);
425 
426  gtk_box_pack_start (GTK_BOX (player->controls), player->play_button, FALSE, TRUE, 0);
427  gtk_widget_show (player->play_button);
428 
429  adjustment = gtk_adjustment_new (0, 0, 1, 0.1, 0.10, 0);
430  player->slider = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, adjustment);
431  g_signal_connect_swapped (player->slider, "change-value",
432  G_CALLBACK (ev_media_player_seek),
433  player);
434  gtk_widget_set_hexpand (player->slider, TRUE);
435  gtk_scale_set_draw_value (GTK_SCALE (player->slider), FALSE);
436  gtk_box_pack_start (GTK_BOX (player->controls), player->slider, FALSE, TRUE, 0);
437  gtk_widget_show (player->slider);
438 
439  gtk_box_pack_start (GTK_BOX (player), player->controls, FALSE, FALSE, 0);
440  gtk_widget_show (player->controls);
441 }

+ Here is the caller graph for this function:

static void ev_media_player_size_allocate ( GtkWidget *  widget,
GtkAllocation *  allocation 
)
static

Definition at line 303 of file ev-media-player.c.

305 {
306  EvMediaPlayer *player = EV_MEDIA_PLAYER (widget);
307  GdkRectangle controls_allocation;
308 
309  GTK_WIDGET_CLASS (ev_media_player_parent_class)->size_allocate (widget, allocation);
310 
311  if (!ev_media_get_show_controls (player->media))
312  return;
313 
314  /* Give all the allocated size to the drawing area */
315  gtk_widget_size_allocate (player->drawing_area, allocation);
316 
317  /* And give space for the controls below */
318  controls_allocation.x = allocation->x;
319  controls_allocation.y = allocation->y + allocation->height;
320  controls_allocation.width = allocation->width;
321  controls_allocation.height = gtk_widget_get_allocated_height (player->controls);
322  gtk_widget_size_allocate (player->controls, &controls_allocation);
323 
324  allocation->height += controls_allocation.height;
325 
326  gtk_widget_set_allocation (widget, allocation);
327 }

+ Here is the caller graph for this function:

static void ev_media_player_toggle_state ( EvMediaPlayer player)
static

Definition at line 157 of file ev-media-player.c.

158 {
159  GstState current, pending, new_state;
160 
161  if (!player->pipeline)
162  return;
163 
164  gst_element_get_state (player->pipeline, &current, &pending, 0);
165  new_state = current == GST_STATE_PLAYING ? GST_STATE_PAUSED : GST_STATE_PLAYING;
166  if (pending != new_state)
167  gst_element_set_state (player->pipeline, new_state);
168 }

+ Here is the caller graph for this function:

static void ev_media_player_update_play_button ( EvMediaPlayer player)
static

Definition at line 126 of file ev-media-player.c.

127 {
128  if (!ev_media_get_show_controls (player->media))
129  return;
130 
131  gtk_image_set_from_icon_name (GTK_IMAGE (gtk_button_get_image (GTK_BUTTON (player->play_button))),
132  player->is_playing ? "media-playback-pause-symbolic" : "media-playback-start-symbolic",
133  GTK_ICON_SIZE_MENU);
134 }

+ Here is the caller graph for this function:

static void ev_media_player_update_position ( EvMediaPlayer player)
static

Definition at line 66 of file ev-media-player.c.

67 {
68  if (!ev_media_get_show_controls (player->media))
69  return;
70 
71  gtk_range_set_value (GTK_RANGE (player->slider), player->position);
72 }

+ Here is the caller graph for this function:

static void ev_media_player_update_state ( EvMediaPlayer player,
GstState *  new_state 
)
static

Definition at line 137 of file ev-media-player.c.

139 {
140  GstState state, pending;
141  gboolean is_playing;
142 
143  gst_element_get_state (player->pipeline, &state, &pending, 250 * GST_NSECOND);
144 
145  is_playing = state == GST_STATE_PLAYING;
146  if (is_playing != player->is_playing) {
147  player->is_playing = is_playing;
150  }
151 
152  if (new_state)
153  *new_state = state;
154 }

+ Here is the caller graph for this function:

static gboolean query_position_cb ( EvMediaPlayer player)
static

Definition at line 75 of file ev-media-player.c.

76 {
77  gint64 position;
78 
79  gst_element_query_position (player->pipeline, GST_FORMAT_TIME, &position);
80  player->position = (gdouble)position / GST_SECOND;
82 
83  return G_SOURCE_CONTINUE;
84 }

+ Here is the caller graph for this function: