rendered paste body#include <unistd.h>#include "audio.h"#include "gst_driver.h"#include <gst/pbutils/pbutils.h>static GstElement *pipeline;static GstElement *playbin;static GstDiscoverer *discoverer;static char *audio_output;const char *AUDIO_get_driver(AUDIO_SESSION *s){ return audio_output;}int AUDIO_get_drivers(AUDIO_SESSION *s,char *buffer){ GstElement *element; int i,length; char *sinks[] = { "artsdsink", "esdsink", "pulsesink", "alsasink", "jackaudiosink", "gconfaudiosink", NULL}; length = 0; for(i=0;sinks[i];i++){ element = gst_element_factory_make(sinks[i],NULL); if(element){ length += sprintf(buffer+length,"%s,",sinks[i]); g_object_unref(G_OBJECT(element)); } } return 0;}int AUDIO_is_audio(AUDIO_SESSION *s,const char *url){ GstDiscovererInfo *info; int result; GError *err; char *uri = NULL; if(url == NULL) return 1; uri = g_filename_to_uri (url, NULL, NULL); info = gst_discoverer_discover_uri(discoverer,uri,&err); free(uri); result = gst_discoverer_info_get_result(info); gst_discoverer_info_unref(info); return (result != GST_DISCOVERER_OK);}int AUDIO_get_metadata(AUDIO_SESSION *s, const char *url, AUDIO_metadata *mdata){ GstDiscovererInfo *info; GError *err; const GstTagList *tags; char *cptr; int result; unsigned uvalue=0; char *uri = NULL; /* Clear out the meta struct */ mdata->title [0]=0; mdata->artist[0]=0; mdata->album [0]=0; mdata->year =0; mdata->track=0; mdata->disc =0; if(url == NULL) return 1; uri = g_filename_to_uri (url, NULL, NULL); info = gst_discoverer_discover_uri(discoverer,uri,&err); free(uri); result = gst_discoverer_info_get_result(info); if(result !=GST_DISCOVERER_OK){ printf("GSTREAMER_driver: %s\n",err->message); gst_discoverer_info_unref(info); return 1; } tags = gst_discoverer_info_get_tags(info); if(gst_tag_list_get_string(tags,GST_TAG_TITLE,&cptr) == TRUE){ strcpy(mdata->title,cptr); free(cptr); } if(gst_tag_list_get_string(tags,GST_TAG_ALBUM,&cptr) == TRUE){ strcpy(mdata->album,cptr); free(cptr); } if(gst_tag_list_get_string(tags,GST_TAG_ARTIST,&cptr) == TRUE){ strcpy(mdata->artist,cptr); free(cptr); } gst_tag_list_get_uint(tags,GST_TAG_TRACK_NUMBER,&uvalue); mdata->track = (short) uvalue; gst_tag_list_get_uint(tags,GST_TAG_ALBUM_VOLUME_NUMBER,&uvalue); mdata->disc = (short) uvalue; gst_discoverer_info_unref(info); mdata->title [LONG_FIELD-1]=0; mdata->artist[LONG_FIELD-1]=0; mdata->album [LONG_FIELD-1]=0; return 0;}int AUDIO_driver_init(AUDIO_SESSION *s, const char *audiodriver){ GstBus *bus; GstElement *audiosink; printf("GSTREAMER_driver - init\n"); audio_output = NULL; gst_init(NULL,NULL); discoverer = gst_discoverer_new(GST_SECOND,NULL); pipeline = NULL; pipeline = gst_pipeline_new("Amatory-playpipe"); if(pipeline == NULL){ printf("ERROR: Could not create pipeline\n"); return 1; } playbin = NULL; playbin = gst_element_factory_make("playbin2","bin"); if(playbin == NULL){ printf("ERROR: Could not create bin\n"); return 1; } gst_bin_add(GST_BIN(pipeline),playbin); if(strstr(audiodriver,"auto")){ audiosink = gst_element_factory_make("gconfaudiosink",NULL); audio_output = strdup("gconfaudiosink"); }else { audiosink = gst_element_factory_make(audiodriver,NULL); audio_output = strdup(audiodriver); } if(audiosink == NULL){ printf("ERROR: Could not audio sink\n"); gst_object_unref(pipeline); return 1; } g_object_set(G_OBJECT(playbin),"audio-sink",audiosink,NULL); bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); gst_bus_add_watch(bus,GST_DRIVER_bus_cb,s); gst_object_unref(bus); return 0;}int AUDIO_play(AUDIO_SESSION *s,char *url, int seek){ gint64 nanolength; char *uri=NULL; GstFormat format = GST_FORMAT_TIME; if(url == NULL){ gst_element_seek_simple (pipeline, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT, seek * GST_SECOND); return 0; } if(gst_element_set_state(pipeline,GST_STATE_READY)==GST_STATE_CHANGE_FAILURE){ printf("AUDIO_play: STATE_READY failed\n"); return 1; } uri = g_filename_to_uri (url, NULL, NULL); g_object_set (G_OBJECT (playbin), "uri", uri, NULL); free(uri); if(gst_element_set_state (pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE){ printf("AUDIO_play: STATE_PLAYING failed\n"); return 1; } // Wait a maximum of 1s for the state to change GstStateChangeReturn return_state; GstState state; return_state = gst_element_get_state(pipeline,&state,NULL,1000*1000*1000); if(return_state != GST_STATE_CHANGE_SUCCESS){ printf("AUDIO_play: Pipeline did not change state in allocated time\n"); return 1; } if(s->url){ free(s->url); } s->url = strdup(url); // Get the stream length for our audio session if(gst_element_query_duration(pipeline, &format, &nanolength) == TRUE){ //GST returns in nanosecs s->length = (nanolength+(GST_SECOND/2))/GST_SECOND; }else{ printf("AUDIO_play: gst_element_query_duration failed\n"); } s->playing = 1; time(&s->start_time); if(s->AUDIO_UI_caller){ s->AUDIO_UI_caller(AUDIO_START,s->cdata); } return 0;}int AUDIO_pause(AUDIO_SESSION *s){ GstState state; gst_element_get_state(pipeline,&state, NULL, 0); if(state == GST_STATE_PAUSED){ gst_element_set_state (pipeline, GST_STATE_PLAYING); return 0; }else if (state == GST_STATE_PLAYING){ gst_element_set_state (pipeline, GST_STATE_PAUSED); return 0; } return 1;}int AUDIO_stop(AUDIO_SESSION *s){ gst_element_set_state(pipeline,GST_STATE_READY); s->playing = 0; if(s->AUDIO_UI_caller)s->AUDIO_UI_caller(AUDIO_STOP,s->cdata); return 0;} int AUDIO_seek(AUDIO_SESSION *s, int time){ gst_element_seek (pipeline, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT, GST_SEEK_TYPE_CUR, time * GST_SECOND, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); return 0;}int AUDIO_driver_dinit(AUDIO_SESSION *s){ printf("audi dinit\n"); if(s==NULL)return 0; gst_element_set_state (pipeline, GST_STATE_NULL); gst_object_unref (GST_OBJECT (pipeline)); if(audio_output) { free(audio_output); audio_output = NULL; } pipeline = NULL; return 0;}int AUDIO_get_position(AUDIO_SESSION *s,int *pos_time){ gint64 nanolength; GstFormat format = GST_FORMAT_TIME; gst_element_query_position(pipeline, &format, &nanolength); *pos_time = (nanolength+(GST_SECOND/2))/GST_SECOND; return 0;}static int GST_DRIVER_bus_cb(GstBus *bus, GstMessage *msg, void *data){ AUDIO_SESSION *s; char *debug=NULL; GError *err=NULL; GstStateChangeReturn state_return; GstState state; s = (AUDIO_SESSION*)data; printf("GST_DRIVER: Message Type = %s\n",GST_MESSAGE_TYPE_NAME (msg)); switch(GST_MESSAGE_TYPE(msg)) { case GST_MESSAGE_EOS: s->playing = 0; if(s->AUDIO_UI_caller) s->AUDIO_UI_caller(AUDIO_END,s->cdata); break; case GST_MESSAGE_STATE_CHANGED: default: printf("GST_DRIVER: Unhandled Message\n"); } return 0;}