All pastes #896048 Raw Edit

Sonicadvance1

public cpp v1 · immutable
·published 2008-02-08 08:40 UTC
rendered paste body
/* Time-stamp: <2008-01-07 07:07:33 Sonic1>||  Copyright (C) 2002-2003 Ryan Houdek <Sonicadvance1 at users.sourceforge.net>|  Part of the gtkpod project.||  URL: http://gtkpod.sourceforge.net/||  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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA||  iTunes and iPod are trademarks of Apple||  This product is not supported/written/published by Apple!*/#ifdef HAVE_CONFIG_H#  include <config.h>#endif#ifdef HAVE_GSTREAMER#include <math.h>#include <gst/gst.h>#include <gst/interfaces/xoverlay.h>#include <gdk/gdkx.h> #include "info.h"#include "misc.h"#include "misc_track.h"#include "mp3file.h"#include "prefs.h"#include "tools.h"#include "string.h"	GMainLoop *loop;	GstElement *pipeline, *audio, *audiomixer,  *video, *volume;	GstElement *src, *dec, *conv, *sink, *videosink, *videoconv;	GstPad *audiopad, *videopad;	GstBus *bus;GtkWidget *drawing_area;GtkWidget *vol_scale;static gboolean prevbut = FALSE;static gboolean stopall = FALSE;static GThread *thread = NULL;static GtkWidget *play_button;static GtkWidget *song_scale;static GtkWidget *song_label;static GList *l;gboolean hasvideo = FALSE;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 (song_scale), 0, 1);        gtk_range_set_value (GTK_RANGE (song_scale), 0);        gtk_label_set_text(GTK_LABEL (song_label),"");        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);            g_main_loop_quit (data);            break;        }    default:        break;    }    return TRUE;}int init_audio(int argc, char *argv[]){	gst_init (&argc, &argv);    play_button = gtkpod_xml_get_widget (main_window_xml, "Play_button");    song_scale = gtkpod_xml_get_widget (main_window_xml, "song_scale");	song_label = gtkpod_xml_get_widget (main_window_xml, "song_label");	drawing_area = gtkpod_xml_get_widget (main_window_xml, "video_widget");	vol_scale = gtkpod_xml_get_widget (main_window_xml, "vol_scale");	gtk_widget_realize(gtkpod_xml_get_widget (main_window_xml, "video_widget"));	return 0;}static gboolean set_scale_range (GstElement *pipeline){	GstFormat fmt = GST_FORMAT_TIME;	gint64 len;    	if (loop == NULL || GST_OBJECT_IS_DISPOSING(pipeline))		return FALSE;    	if (loop != NULL || g_main_loop_is_running (loop))    {		if(gst_element_query_duration (pipeline, &fmt, &len))		{			gtk_range_set_range (GTK_RANGE (song_scale), 0, (((GstClockTime)(len)) / GST_SECOND));			return FALSE;		}    }	else		return FALSE;    	return TRUE;}static gboolean set_scale_position (GstElement *pipeline){	GstFormat fmt = GST_FORMAT_TIME;	gint64 pos;    gint64 len;    	if(loop == NULL || thread == NULL || !g_main_loop_is_running(loop))		return FALSE;    	if (loop != NULL || g_main_loop_is_running(loop))    {		if (gst_element_query_position (pipeline, &fmt, &pos)) 		{            gint seconds = ((GstClockTime) pos) / GST_SECOND;            gint length;            gchar *label;                        gst_element_query_duration (pipeline, &fmt, &len);            length = ((GstClockTime) len) / GST_SECOND;                        label = g_strdup_printf (_("%s (%d:%02d of %d:%02d)"),                                     (gchar *) g_object_get_data (G_OBJECT (song_label), "tr_title"),                                     seconds / 60,                                     seconds % 60,                                     length / 60,                                     length % 60);                        gtk_range_set_value (GTK_RANGE (song_scale), seconds);            gtk_label_set_text (GTK_LABEL (song_label), label);                        g_free (label);			return TRUE;		}    }	return FALSE;}#ifndef M_LN10#define M_LN10 (log(10.0))#endifstatic void volume_changed_callback (GtkWidget *widget, GstElement* volume){  gdouble value;  gdouble level;  value = gtk_range_get_value (GTK_RANGE (widget));  level = exp (value / 20.0 * M_LN10);  g_object_set (volume, "volume", level, NULL);}static voidcb_newpad (GstElement *decodebin,	   GstPad     *pad,	   gboolean    last,	   gpointer    data){  GstCaps *caps;  GstStructure *str;  GstPad *audiopad, *videopad;  /* check media type */  caps = gst_pad_get_caps (pad);  str = gst_caps_get_structure (caps, 0);  printf("string = %s\n",gst_structure_get_name (str));  const gchar *name = gst_structure_get_name (str);  if (g_strrstr (name, "audio")) {  	/* only link once */  	audiopad = gst_element_get_pad (audio, "sink");  	if (GST_PAD_IS_LINKED (audiopad))   	{    	g_object_unref (audiopad);    	return;  	}  	    /* link'n'play */  	gst_pad_link (pad, audiopad); // 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   	videopad = gst_element_get_pad (video, "sink");  	if (GST_PAD_IS_LINKED (videopad))   	{    	g_object_unref (videopad);    	return;  	}    // link'n'play   	gst_pad_link (pad, videopad);  	set_video_mode (TRUE);  }  gst_caps_unref (caps);}static void *playsong_real (void *ptr){	gchar *str;	l = ptr;    	while (l)	{		Track *tr = l->data;		g_return_val_if_fail(tr, (void*)-1);//printf("%d\n",a++);		str = get_file_name_from_source(tr, SOURCE_PREFER_LOCAL);//printf("%d\n",a++);		if (str)		{            gtk_label_set_text(GTK_LABEL (song_label), tr->title); // set label to title            g_object_set_data (G_OBJECT (song_label), "tr_title", tr->title); // set label to title...again?wtf?            gtk_widget_set_sensitive (vol_scale, TRUE); //set volume scale sensitivity to true            			/* init GStreamer */			loop = g_main_loop_new (NULL, FALSE); // make new loop			/* setup */			pipeline = gst_pipeline_new ("pipeline"); //Create our pipeline			volume = gst_element_factory_make ("volume", "volume"); // Create volume element			bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); // get pipeline's bus			gst_bus_add_watch (bus, my_bus_callback, loop); //Add a watch to the bus			gst_object_unref (bus); //unref the bus			src = gst_element_factory_make ("filesrc", "source"); //create the file source			g_object_set (G_OBJECT (src), "location", str, NULL); //set location to the file location			dec = gst_element_factory_make ("decodebin", "decoder"); //create our decodebin			g_signal_connect (dec, "new-decoded-pad", G_CALLBACK (cb_newpad), NULL); //signal to the new-decoded-pad(same as new-pad)			gst_bin_add_many (GST_BIN (pipeline), src,  dec, NULL); //add src and dec to pipeline			gst_element_link (src, dec); //link src and dec together						/* create audio output */			audio = gst_bin_new ("audiobin"); //create our audio bin			conv = gst_element_factory_make ("audioconvert", "aconv"); //Create audioconvert element			audiopad = gst_element_get_pad (conv, "sink"); //get the audioconvert pad			sink = gst_element_factory_make ("alsasink", "sink"); //create our alsasink						gst_bin_add_many (GST_BIN (audio), conv, sink, volume, NULL); //add volume, conv, and sink to audio			gst_element_link (conv, sink); // link sink and conv			gst_element_add_pad (audio,			  gst_ghost_pad_new ("sink", audiopad)); // add pad to audio...?			gst_object_unref (audiopad); //unref audiopad			gst_bin_add (GST_BIN (pipeline), 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			videosink = gst_element_factory_make ("xvimagesink", "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_bin_add_many (GST_BIN (video),videoconv, videosink, NULL); //add videoconv and videosink to video			gst_element_link (videoconv, videosink); //link videoconv and videosink			gst_element_add_pad (video, gst_ghost_pad_new ("sink", videopad)); //add pad to video...?			gst_object_unref (videopad); //unref videopad			//gst_bin_add(GST_BIN (pipeline), video); //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           // gst_bin_add_many (GST_BIN (pipeline), src, dec, volume, audio,  NULL);            			/* run */			gst_element_set_state (pipeline, GST_STATE_PLAYING);// set state			g_timeout_add (250, (GSourceFunc) set_scale_range, GST_PIPELINE (pipeline));			g_timeout_add (1000, (GSourceFunc) set_scale_position, GST_PIPELINE (pipeline));			//g_timeout_add (500, (GSourceFunc) checkinfo, gst_pipeline_get_bus (GST_PIPELINE (pipeline)));			g_main_loop_run (loop);			/* cleanup */			gst_element_set_state (pipeline, GST_STATE_NULL);			gst_object_unref (GST_OBJECT (pipeline));			#ifndef NEW_PIPE_PER_FILE		        /*if (GST_STATE_CHANGE_ASYNC == sret)		        {		            if (gst_element_get_state (GST_ELEMENT (pipeline),		                                       &state,		                                       NULL,		                                       GST_CLOCK_TIME_NONE) == GST_STATE_CHANGE_FAILURE)		            {		                g_print ("State change failed. Aborting");		                break;		            }		        }*/			#endif			if(pipeline != NULL)				gst_object_unref (GST_OBJECT (pipeline));			g_main_loop_unref (loop);			//START OLD! D:<		}        		if (stopall)			break;        		if (!prevbut)			l = g_list_next(l);		else			prevbut = FALSE;	}    	thread = NULL;	stopall = FALSE;	g_thread_exit (0);	return (void*)-1;}void seek_to_time (gint64 time_seconds){	if(loop == NULL || pipeline == NULL || thread == NULL || !g_main_loop_is_running(loop))		return;	if (!gst_element_seek (pipeline, 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");}void pause_song(){	if(loop == NULL || pipeline == NULL || thread == NULL || !g_main_loop_is_running(loop))    {        play_song (tm_get_selected_tracks());    }    	GstState state, pending;	gst_element_get_state(pipeline, &state, &pending, GST_CLOCK_TIME_NONE);    	if(state == GST_STATE_PLAYING)    {		gst_element_set_state (pipeline, GST_STATE_PAUSED);        gtk_tool_button_set_stock_id (GTK_TOOL_BUTTON (play_button), GTK_STOCK_MEDIA_PLAY);    }    else if(state == GST_STATE_PAUSED)    {		gst_element_set_state (pipeline, GST_STATE_PLAYING);        gtk_tool_button_set_stock_id (GTK_TOOL_BUTTON (play_button), GTK_STOCK_MEDIA_PAUSE);    }}static void waitforpipeline(int state){	if(pipeline == NULL || thread == NULL)		return;    	GstState istate, ipending;	gst_element_get_state(pipeline, &istate, &ipending, GST_CLOCK_TIME_NONE);    	if(istate == GST_STATE_VOID_PENDING)		return;    	gst_element_set_state (pipeline, state);    	do	{		gst_element_get_state(pipeline, &istate, &ipending, GST_CLOCK_TIME_NONE);        		if(istate == GST_STATE_VOID_PENDING)			return;	}    while(istate != state);	    return;}static void stop_song (){	if(loop != NULL && g_main_loop_is_running(loop))		g_main_loop_quit(loop);    	gtk_range_set_range(GTK_RANGE (song_scale), 0, 1);	gtk_range_set_value (GTK_RANGE (song_scale), 0);	gtk_label_set_text(GTK_LABEL (song_label), "");}void stop_all_songs (){	stopall = TRUE;	//stop_song ();	waitforpipeline (1);	thread = NULL;	set_video_mode (FALSE);    gtk_tool_button_set_stock_id (GTK_TOOL_BUTTON (play_button), GTK_STOCK_MEDIA_PLAY);    stopall = FALSE;    gtk_widget_set_sensitive (gtkpod_xml_get_widget (main_window_xml, "song_scale"), FALSE);}void previous_song(){	prevbut = TRUE;	l = g_list_previous (l);	stop_song();	waitforpipeline (1);}void next_song(){	stop_song();	waitforpipeline (1);}int play_song(GList *songs){	stop_all_songs();	GError *err1 = NULL ;	if (!g_thread_supported ())	{		g_thread_init (NULL);		gdk_threads_init ();	}    thread = g_thread_create ((GThreadFunc)playsong_real, (void *)songs, TRUE, &err1);    if (!thread)	{		printf ("GStreamer thread creation failed: %s\n", err1->message);		g_error_free (err1);	}    gtk_tool_button_set_stock_id (GTK_TOOL_BUTTON (play_button), GTK_STOCK_MEDIA_PAUSE);	return 0;}#endif