commit 71efebdaaef112efb97ad6ea84c3045bf61c5ea9
Author: phantomjinx <p.g.richard...@phantomjinx.co.uk>
Date:   Sat Aug 7 00:41:22 2010 +0100

    Media Player plugin enable video
    
    * Use the playbin factory to create the high-level gstreamer player.
      All that is required. Throws up a dialog with the video in.
    
    * Problematic to put the video into the gui as closing other gdkwindows
      causes instability and crashes. Simple implementation for now that just
      works.
    
    * Removed all the commented code and extra stuff so tidied up a bit.

 plugins/media_player/media_player.c     |  308 +++++++++++++------------------
 plugins/media_player/media_player.glade |   10 +-
 plugins/media_player/media_player.h     |   12 +-
 3 files changed, 131 insertions(+), 199 deletions(-)
---
diff --git a/plugins/media_player/media_player.c 
b/plugins/media_player/media_player.c
index 74c0f03..d99522a 100644
--- a/plugins/media_player/media_player.c
+++ b/plugins/media_player/media_player.c
@@ -31,7 +31,6 @@
 
 #include <math.h>
 #include <gst/interfaces/xoverlay.h>
-//#include <gdk/gdkx.h>
 #include "libgtkpod/itdb.h"
 #include "libgtkpod/file.h"
 #include "libgtkpod/directories.h"
@@ -39,39 +38,13 @@
 #include "plugin.h"
 #include "media_player.h"
 
-static MediaPlayer *player;
-
-//GstElement *video, *videosink, *videoconv;
-//GstPad *videopad;
-
-GstBus *bus;
-
-static int my_bus_callback(GstBus *bus, GstMessage *msg, gpointer data) {
-    switch (GST_MESSAGE_TYPE (msg)) {
-    case GST_MESSAGE_EOS:
-        gtk_range_set_range(GTK_RANGE(player->song_scale), 0, 1);
-        gtk_range_set_value(GTK_RANGE(player->song_scale), 0);
-        g_main_loop_quit(data);
-        break;
-    case GST_MESSAGE_ERROR: {
-        gchar *debug;
-        GError *err;
-
-        gst_message_parse_error(msg, &err, &debug);
-        g_free(debug);
-
-        g_print("Error: %s\n", err->message);
-        g_error_free(err);
+#ifndef M_LN10
+#define M_LN10 (log(10.0))
+#endif
 
-        g_main_loop_quit(data);
-        break;
-    }
-    default:
-        break;
-    }
+static MediaPlayer *player;
 
-    return TRUE;
-}
+static int pipeline_bus_watch_cb(GstBus *bus, GstMessage *msg, gpointer data);
 
 static gboolean set_scale_range(GstElement *pipeline) {
     GstFormat fmt = GST_FORMAT_TIME;
@@ -96,6 +69,7 @@ static gboolean set_scale_range(GstElement *pipeline) {
 
     return TRUE;
 }
+
 static gboolean set_scale_position(GstElement *pipeline) {
     GstFormat fmt = GST_FORMAT_TIME;
     gint64 pos;
@@ -127,16 +101,13 @@ static gboolean set_scale_position(GstElement *pipeline) {
 
     return FALSE;
 }
-#ifndef M_LN10
-#define M_LN10 (log(10.0))
-#endif
 
 static void update_volume(gboolean value) {
     if (!player)
         return;
 
     player->volume_level = exp(value / 20.0 * M_LN10);
-    g_object_set(player->volume_element, "volume", player->volume_level, NULL);
+    //    g_object_set(player->volume_element, "volume", player->volume_level, 
NULL);
 }
 
 static gboolean volume_changed_cb(GtkRange *range, GtkScrollType scroll, 
gdouble value, gpointer user_data) {
@@ -144,50 +115,50 @@ static gboolean volume_changed_cb(GtkRange *range, 
GtkScrollType scroll, gdouble
     return FALSE;
 }
 
-static void new_decoded_pad_cb(GstElement *decodebin, GstPad *pad, gboolean 
last, gpointer data) {
-    GstCaps *caps;
-    GstStructure *str;
-    GstPad *audiopad2;
-    //    , *videopad2;
-
-    if (!player)
-        return;
-
-    /* check media type */
-    caps = gst_pad_get_caps(pad);
-    str = gst_caps_get_structure(caps, 0);
-    const gchar *name = gst_structure_get_name(str);
-    if (g_strrstr(name, "audio")) {
-        /* only link once */
-        audiopad2 = gst_element_get_pad(player->audio, "sink");
-        if (GST_PAD_IS_LINKED (audiopad2)) {
-            g_object_unref(audiopad2);
-            return;
-        }
-
-        /* link'n'play */
-        gst_pad_link(pad, audiopad2); // Link audiopad to pad or other way 
around, dunno
-        //gst_element_link (volume, dec); //Doesn't seem to work...
-        //volume_changed_callback (vol_scale, volume); //Change volume to 
default
-    }
-
-    if (g_strrstr(name, "video")) {
-        // only link once
-
-        //        videopad2 = gst_element_get_pad(videoconv, "sink");
-        //        if (GST_PAD_IS_LINKED (videopad2)) {
-        //            printf("video pad is linked!unreffing\n");
-        //            g_object_unref(videopad2);
-        //            return;
-        //        }
-        // link'n'play
-        //        gst_pad_link(pad, videopad2);
-        //set_video_mode (TRUE);//Not needed since We can't actually SEE the 
video
-    }
-
-    gst_caps_unref(caps);
-
-}
+//static void new_decoded_pad_cb(GstElement *decodebin, GstPad *pad, gboolean 
last, gpointer data) {
+//    GstCaps *caps;
+//    GstStructure *str;
+//    GstPad *audiopad2;
+//    //    , *videopad2;
+//
+//    if (!player)
+//        return;
+//
+//    /* check media type */
+//    caps = gst_pad_get_caps(pad);
+//    str = gst_caps_get_structure(caps, 0);
+//    const gchar *name = gst_structure_get_name(str);
+//    if (g_strrstr(name, "audio")) {
+//        /* only link once */
+//        audiopad2 = gst_element_get_pad(player->audio, "sink");
+//        if (GST_PAD_IS_LINKED (audiopad2)) {
+//            g_object_unref(audiopad2);
+//            return;
+//        }
+//
+//        /* link'n'play */
+//        gst_pad_link(pad, audiopad2); // Link audiopad to pad or other way 
around, dunno
+//        //gst_element_link (volume, dec); //Doesn't seem to work...
+//        //volume_changed_callback (vol_scale, volume); //Change volume to 
default
+//    }
+//
+//    if (g_strrstr(name, "video")) {
+//        // only link once
+//
+//        //        videopad2 = gst_element_get_pad(videoconv, "sink");
+//        //        if (GST_PAD_IS_LINKED (videopad2)) {
+//        //            printf("video pad is linked!unreffing\n");
+//        //            g_object_unref(videopad2);
+//        //            return;
+//        //        }
+//        // link'n'play
+//        //        gst_pad_link(pad, videopad2);
+//        //set_video_mode (TRUE);//Not needed since We can't actually SEE the 
video
+//    }
+//
+//    gst_caps_unref(caps);
+//
+//}
 
 static void set_song_label(Track *track) {
     if (!track)
@@ -196,11 +167,17 @@ static void set_song_label(Track *track) {
     gchar *label;
 
     // title by artist from album
-    if (!track->title)
+    if (track->title)
+        label = g_strdup(track->title);
+    else
         label = _("No Track Title");
-    else {
-        label = g_strdup_printf("%s by %s from %s", track->title, 
track->artist, track->album);
-    }
+
+    if (track->artist && strlen(track->artist) > 0 )
+        label = g_strconcat(label, " by ", track->artist, NULL);
+
+    if (track->album && strlen(track->album) > 0)
+        label = g_strconcat(label, " from ", track->album, NULL);
+
     gtk_label_set_text(GTK_LABEL(player->song_label), label);
     g_object_set_data(G_OBJECT (player->song_label), "tr_title", track->title);
     g_object_set_data(G_OBJECT (player->song_label), "tr_artist", 
track->artist);
@@ -210,7 +187,9 @@ static void set_song_label(Track *track) {
 static void thread_play_song() {
     GstStateChangeReturn sret;
     GstState state;
-    gchar *str;
+    gchar *track_name;
+    gchar *uri;
+    GstBus *bus;
 
     if (!player || !player->tracks)
         return;
@@ -218,80 +197,43 @@ static void thread_play_song() {
     while (player->tracks) {
         Track *tr = player->tracks->data;
         g_return_if_fail(tr);
-        str = get_file_name_from_source(tr, SOURCE_PREFER_LOCAL);
-        if (str) {
-            set_song_label(tr);
-
-            /* init GStreamer */
-            player->loop = g_main_loop_new(NULL, FALSE); // make new loop
-            /* setup */
-            player->pipeline = gst_pipeline_new("pipeline"); //Create our 
pipeline
-
-            bus = gst_pipeline_get_bus(GST_PIPELINE (player->pipeline)); // 
get pipeline's bus
-            gst_bus_add_watch(bus, my_bus_callback, player->loop); //Add a 
watch to the bus
-            gst_object_unref(bus); //unref the bus
-
-            player->src = gst_element_factory_make("filesrc", "source"); 
//create the file source
-            g_object_set(G_OBJECT (player->src), "location", str, NULL); //set 
location to the file location
-
-            player->dec = gst_element_factory_make("decodebin", "decoder"); 
//create our decodebin
-            g_signal_connect (player->dec, "new-decoded-pad", G_CALLBACK 
(new_decoded_pad_cb), NULL); //signal to the new-decoded-pad(same as new-pad)
-
-            gst_bin_add_many(GST_BIN (player->pipeline), player->src, 
player->dec, NULL); //add src and dec to pipeline
-            gst_element_link(player->src, player->dec); //link src and dec 
together
-
-            /* create audio output */
-            player->audio = gst_bin_new("audiobin"); //create our audio bin
-            player->conv = gst_element_factory_make("audioconvert", "aconv"); 
//Create audioconvert element
-            player->audiopad = gst_element_get_pad(player->conv, "sink"); 
//get the audioconvert pad
-            player->sink = gst_element_factory_make("alsasink", "sink"); 
//create our alsasink
-
-            gst_bin_add_many(GST_BIN (player->audio), player->conv, 
player->sink, player->volume, NULL); //add volume, conv, and sink to audio
-            gst_element_link(player->conv, player->sink); // link sink and conv
-            gst_element_add_pad(player->audio, gst_ghost_pad_new("sink", 
player->audiopad)); // add pad to audio...?
-            gst_object_unref(player->audiopad); //unref audiopad
-            gst_bin_add(GST_BIN (player->pipeline), player->audio); //add 
audio to pipeline
-
-            /*create video output*/
-
-            //            video = gst_bin_new("videobin"); //create videobin
-            //            videoconv = 
gst_element_factory_make("ffmpegcolorspace", "vconv"); //make ffmpegcolorspace
-            //videopad = gst_element_get_pad (videoconv, "sink"); //get 
videoconv pad, why the hell am I getting
-            //videosink = gst_element_factory_make ("ximagesink", "sink"); 
//create video sink
-            //g_object_set (G_OBJECT (videosink), "force-aspect-ratio", TRUE, 
NULL); //force aspect ratio
-            // gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (videosink), 
gdk_x11_drawable_get_xid (drawing_area->window)); //set the overlay to our 
drawing area
-            //gst_element_link (videoconv, videosink); //link videoconv and 
videosink
-            //gst_bin_add_many (GST_BIN (video),videoconv, videosink, NULL); 
//add videoconv and videosink to video
-            //            gst_bin_add(GST_BIN (video), videoconv);
-            //gst_object_unref (videopad); //unref videopad
-            //            gst_bin_add(GST_BIN (pipeline), video);
-            //[NOTE] If file doesn't contain video, it crashes the program, so 
commented out
-
-            /* Volume Control */
-
-            //volume_changed_callback (vol_scale, volume);
-            //g_signal_connect (vol_scale, "value-changed", G_CALLBACK 
(volume_changed_callback), volume); //connect volume-changed signal
-
-            /* run */
-            gst_element_set_state(player->pipeline, GST_STATE_PLAYING);// set 
state
-            g_timeout_add(250, (GSourceFunc) set_scale_range, GST_PIPELINE 
(player->pipeline));
-            g_timeout_add(1000, (GSourceFunc) set_scale_position, GST_PIPELINE 
(player->pipeline));
-            //g_timeout_add (500, (GSourceFunc) checkinfo, 
gst_pipeline_get_bus (GST_PIPELINE (pipeline)));
-            g_main_loop_run(player->loop);
-
-            /* cleanup */
-            sret = gst_element_set_state(player->pipeline, GST_STATE_NULL);
+        track_name = get_file_name_from_source(tr, SOURCE_PREFER_LOCAL);
+        if (!track_name)
+            continue;
+
+        set_song_label(tr);
+
+        /* init GStreamer */
+        player->loop = g_main_loop_new(NULL, FALSE); // make new loop
+
+        uri = g_strconcat("file://", track_name, NULL);
+        player->play_element = gst_element_factory_make("playbin2", "play");
+        g_object_set(G_OBJECT (player->play_element), "uri", uri, NULL);
+
+        bus = gst_pipeline_get_bus(GST_PIPELINE (player->play_element));
+        gst_bus_add_watch(bus, pipeline_bus_watch_cb, player->loop); //Add a 
watch to the bus
+        gst_object_unref(bus); //unref the bus
+
+        /* run */
+        gst_element_set_state(player->play_element, GST_STATE_PLAYING);// set 
state
+        g_timeout_add(250, (GSourceFunc) set_scale_range, GST_PIPELINE 
(player->play_element));
+        g_timeout_add(1000, (GSourceFunc) set_scale_position, GST_PIPELINE 
(player->play_element));
+        g_main_loop_run(player->loop);
+
+        /* cleanup */
+        sret = gst_element_set_state(player->play_element, GST_STATE_NULL);
 #ifndef NEW_PIPE_PER_FILE
-            if (GST_STATE_CHANGE_ASYNC == sret) {
-                if (gst_element_get_state(GST_ELEMENT (player->pipeline), 
&state, NULL, GST_CLOCK_TIME_NONE)
-                        == GST_STATE_CHANGE_FAILURE) {
-                    break;
-                }
+        if (GST_STATE_CHANGE_ASYNC == sret) {
+            if (gst_element_get_state(GST_ELEMENT (player->play_element), 
&state, NULL, GST_CLOCK_TIME_NONE)
+                    == GST_STATE_CHANGE_FAILURE) {
+                break;
             }
-#endif
-            gst_element_set_state(player->pipeline, GST_STATE_NULL);
-            g_free(str);//Free it since it is no longer needed.
         }
+#endif
+        gst_element_set_state(player->play_element, GST_STATE_NULL);
+        g_free(uri);
+        g_free(track_name);//Free it since it is no longer needed.
+
 
         if (player->stopButtonPressed)
             break;
@@ -315,15 +257,15 @@ static void waitforpipeline(int state) {
         return;
 
     GstState istate, ipending;
-    gst_element_get_state(player->pipeline, &istate, &ipending, 
GST_CLOCK_TIME_NONE);
+    gst_element_get_state(player->play_element, &istate, &ipending, 
GST_CLOCK_TIME_NONE);
 
     if (istate == GST_STATE_VOID_PENDING) {
         return;
     }
-    gst_element_set_state(player->pipeline, state);
+    gst_element_set_state(player->play_element, state);
 
     do {
-        gst_element_get_state(player->pipeline, &istate, &ipending, 
GST_CLOCK_TIME_NONE);
+        gst_element_get_state(player->play_element, &istate, &ipending, 
GST_CLOCK_TIME_NONE);
 
         if (istate == GST_STATE_VOID_PENDING) {
             return;
@@ -392,21 +334,21 @@ static void pause_or_play_song() {
     if (!player)
         return;
 
-    if (!player->loop || !player->pipeline || !player->thread || 
!g_main_loop_is_running(player->loop)) {
+    if (!player->loop || !player->play_element || !player->thread || 
!g_main_loop_is_running(player->loop)) {
         play_song();
         return;
     }
 
     GstState state, pending;
-    gst_element_get_state(player->pipeline, &state, &pending, 
GST_CLOCK_TIME_NONE);
+    gst_element_get_state(player->play_element, &state, &pending, 
GST_CLOCK_TIME_NONE);
 
     if (state == GST_STATE_PLAYING) {
-        gst_element_set_state(player->pipeline, GST_STATE_PAUSED);
         gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(player->play_button), 
GTK_STOCK_MEDIA_PLAY);
+        gst_element_set_state(player->play_element, GST_STATE_PAUSED);
     }
     else if (state == GST_STATE_PAUSED) {
-        gst_element_set_state(player->pipeline, GST_STATE_PLAYING);
         gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(player->play_button), 
GTK_STOCK_MEDIA_PAUSE);
+        gst_element_set_state(player->play_element, GST_STATE_PLAYING);
     }
 }
 
@@ -414,17 +356,33 @@ void seek_to_time(gint64 time_seconds) {
     if (!player)
         return;
 
-    if (!player->loop || !player->pipeline || !player->thread)
+    if (!player->loop || !player->play_element || !player->thread)
         return;
 
     if (!g_main_loop_is_running(player->loop))
         return;
 
-    if (!gst_element_seek(player->pipeline, 1.0, GST_FORMAT_TIME, 
GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, time_seconds
+    if (!gst_element_seek(player->play_element, 1.0, GST_FORMAT_TIME, 
GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, time_seconds
             * 1000000000, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE))
         g_print("Seek failed!\n");
 }
 
+static int pipeline_bus_watch_cb(GstBus *bus, GstMessage *msg, gpointer data) {
+    switch (GST_MESSAGE_TYPE (msg)) {
+    case GST_MESSAGE_EOS:
+        stop_song(FALSE);
+        break;
+    case GST_MESSAGE_ERROR: {
+        stop_song(TRUE);
+        break;
+    }
+    default:
+        break;
+    }
+
+    return TRUE;
+}
+
 void set_selected_tracks(GList *tracks) {
     if (!player)
         return;
@@ -467,7 +425,6 @@ void init_media_player(GtkWidget *parent) {
     xml = glade_xml_new(player->glade_path, "media_window", NULL);
 
     window = gtkpod_xml_get_widget(xml, "media_window");
-    player->video_widget = gtkpod_xml_get_widget(xml, "video_widget");
     player->media_panel = gtkpod_xml_get_widget(xml, "media_panel");
     player->song_label = gtkpod_xml_get_widget(xml, "song_label");
     player->song_time_label = gtkpod_xml_get_widget(xml, "song_time_label");
@@ -495,20 +452,11 @@ void init_media_player(GtkWidget *parent) {
     player->previousButtonPressed = FALSE;
     player->stopButtonPressed = FALSE;
     player->shuffle = FALSE;
-    player->volume_element = gst_element_factory_make("volume", "volume"); // 
Create volume element
-    player->volume_level = 50;
-    player->pipeline = NULL;
-    player->audio = NULL;
-    player->audiomixer = NULL;
-    player->volume = NULL;
-    player->src = NULL;
-    player->dec = NULL;
-    player->conv = NULL;
-    player->sink = NULL;
-    player->audiopad = NULL;
-
-    gtk_widget_show(player->song_label);
-    gtk_widget_show_all(player->media_toolbar);
+    player->play_element = NULL;
+
+    //    gtk_widget_show(player->song_label);
+    gtk_widget_show_all(player->media_panel);
+//    gtk_widget_realize(player->video_widget);
 
     g_object_unref(xml);
 }
diff --git a/plugins/media_player/media_player.glade 
b/plugins/media_player/media_player.glade
index c19d065..ea2309b 100644
--- a/plugins/media_player/media_player.glade
+++ b/plugins/media_player/media_player.glade
@@ -9,12 +9,6 @@
         <property name="visible">True</property>
         <property name="orientation">vertical</property>
         <child>
-          <widget class="GtkDrawingArea" id="video_widget"/>
-          <packing>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
           <widget class="GtkHBox" id="song_label_box">
             <property name="visible">True</property>
             <property name="spacing">10</property>
@@ -45,7 +39,7 @@
           <packing>
             <property name="expand">False</property>
             <property name="padding">5</property>
-            <property name="position">1</property>
+            <property name="position">0</property>
           </packing>
         </child>
         <child>
@@ -153,7 +147,7 @@
           <packing>
             <property name="expand">False</property>
             <property name="fill">False</property>
-            <property name="position">2</property>
+            <property name="position">1</property>
           </packing>
         </child>
       </widget>
diff --git a/plugins/media_player/media_player.h 
b/plugins/media_player/media_player.h
index b7d3e55..8d4237c 100644
--- a/plugins/media_player/media_player.h
+++ b/plugins/media_player/media_player.h
@@ -35,7 +35,6 @@
 
 typedef struct {
     GtkWidget *media_panel;
-    GtkWidget *video_widget;
     GtkWidget *song_label;
     GtkWidget *song_time_label;
     GtkWidget *media_toolbar;
@@ -57,16 +56,7 @@ typedef struct {
     gboolean shuffle;
 
     gdouble volume_level;
-    GstElement *volume_element;
-    GstElement *pipeline;
-    GstElement *audio;
-    GstElement *audiomixer;
-    GstElement *volume;
-    GstElement *src;
-    GstElement *dec;
-    GstElement *conv;
-    GstElement *sink;
-    GstPad *audiopad;
+    GstElement *play_element;
 
 } MediaPlayer;
 

------------------------------------------------------------------------------
This SF.net email is sponsored by 

Make an app they can't live without
Enter the BlackBerry Developer Challenge
http://p.sf.net/sfu/RIM-dev2dev 
_______________________________________________
gtkpod-cvs2 mailing list
gtkpod-cvs2@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/gtkpod-cvs2

Reply via email to