⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gstreamer_player.cpp

📁 彩信浏览器
💻 CPP
字号:
// This file is part of Ambulant Player, www.ambulantplayer.org.//// Copyright (C) 2003-2007 Stichting CWI, // Kruislaan 413, 1098 SJ Amsterdam, The Netherlands.//// Ambulant Player is free software; you can redistribute it and/or modify// it under the terms of the GNU Lesser General Public License as published by// the Free Software Foundation; either version 2.1 of the License, or// (at your option) any later version.//// Ambulant Player 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 Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public License// along with Ambulant Player; if not, write to the Free Software// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA//#define AM_DBG#ifndef AM_DBG#define AM_DBG if(0)#endif#include "ambulant/gui/gstreamer/gstreamer_audio_renderer.h"#include "ambulant/gui/gstreamer/gstreamer_player.h"#include "ambulant/net/posix_datasource.h"#include "ambulant/common/region_info.h"#include <stdlib.h>using namespace ambulant;using namespace gui::gstreamer;extern "C" {static gbooleangst_bus_callback (GstBus* bus, GstMessage *msg, gpointer data){	GMainLoop* main_loop = (GMainLoop*)data;		switch (GST_MESSAGE_TYPE (msg)) {	case GST_MESSAGE_EOS:		AM_DBG g_print ("End-of-stream\n");		g_main_loop_quit (main_loop);		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 (main_loop);		break;	}	default:		AM_DBG g_print("Unhandled Message type=%s received\n",GST_MESSAGE_TYPE_NAME(msg));		break;	}	return TRUE;}} /* extern "C" *///************************* gstreamer_player ***************************// Global initialize/finilize, to be called from main threadvoidgstreamer_player_initialize(int* argcp, char*** argvp) {	gst_init(argcp, argvp);}voidgstreamer_player_finalize() {	gst_deinit(); // not avail in gstreamer 0.8}gstreamer_player::gstreamer_player(const char* uri, gstreamer_audio_renderer* rend)  : 	m_gst_player(NULL),	m_gst_mainloop(NULL),	m_audio_renderer(NULL),	m_uri(NULL){	pthread_mutex_init(&m_gst_player_mutex, NULL);	// mutex will be unlocked by gst_player after pipeline initialize is complete	pthread_mutex_lock(&m_gst_player_mutex); 	m_uri = strdup(uri);	m_audio_renderer = rend;	AM_DBG lib::logger::get_logger()->debug("gstreamer_player(0x%x) uri=%s", (void*)this, uri);	start();  //  lib::unix::thread::start() starts run() in separate thread}gstreamer_player::~gstreamer_player() {	AM_DBG lib::logger::get_logger()->debug("gstreamer_player::~gstreamer_player()(0x%x) m_uri=%s", (void*)this, m_uri);	pthread_mutex_lock(&m_gst_player_mutex); 	m_audio_renderer = NULL;	if (m_uri) free(m_uri);	m_uri = NULL;	pthread_mutex_unlock(&m_gst_player_mutex); 	pthread_mutex_destroy(&m_gst_player_mutex);}unsigned longgstreamer_player::run() {  GstElement *source=NULL,*sink=NULL;	GstStateChangeReturn gst_state_changed;	const char* id = "gsteamer_player::run()";	AM_DBG lib::logger::get_logger()->debug("gstreamer_player::run(0x%x)m_uri=%s", (void*)this, m_uri);	m_gst_mainloop = g_main_loop_new (NULL, FALSE);	AM_DBG g_print ("%s: %s=0x%x, %s=0x%x\n", id, "starting, m_gst_player", (void*) m_gst_player,"m_gst_mainloop=", (void*) m_gst_mainloop);#ifdef  WITH_NOKIA770	/* On Nokia770 we use a dedicated gstreamer module "dspmp3sink" which most	   efficiently playes mp3 clips using the DSP signal co-processor	   It only plays one clip at any time.	*/	if (pthread_mutex_lock(&s_main_nokia770_mutex) < 0) {		lib::logger::get_logger()->fatal("gst_mp3_player:: pthread_mutex_lock(s_main_nokia770_mutex) failed: %s", strerror(errno));		abort();	}	m_gst_player = (GstElement*)gst_pipeline_new ("mp3-player");	/* create elements */	AM_DBG g_print ("%s: %s\n", id, "gst_element_factory_make()");	source   = gst_element_factory_make ("gnomevfssrc", "source"); 	sink     = gst_element_factory_make ("dspmp3sink", "sink"); 	if ( !( m_gst_player && source && sink)) {		g_print ("%s:", "gst_mp3_player");		if ( ! m_gst_player) g_print (" %s() failed", "get_pipeline_new");		if ( ! source) g_print (" %s=%s(%s) failed", "source", 					  "gst_element_factory_make", "gnomevfssrc");		if ( ! sink) g_print (" %s=%s(%s) failed", "sink", "gst_element_factory_make", "dspmp3sink");		g_print ("\n");		abort();	} 	AM_DBG g_print ("%s: %s\n", id, "set the source audio file");	g_object_set (G_OBJECT(source), "location", m_uri, NULL);	/* put all elements  to the main pipeline */	gst_bin_add_many (GST_BIN(m_gst_player), source, sink, NULL);	/* link the elements */	if ( ! gst_element_link (source, sink)) {	  g_print ("gst_element_link (source=%s, sink%s) failed\n", (void*) source, (void*) sink);		abort();	}#else //WITH_NOKIA770	m_gst_player = (GstElement*)gst_pipeline_new ("mp3-player");	/* create elements */	AM_DBG g_print ("%s: %s\n", id, "gst_element_factory_make()");	source   = gst_element_factory_make ("playbin", "playbin"); 	if ( !( m_gst_player && source)) {		g_print ("%s:", "gstreamer_player::run()");		if ( ! m_gst_player) g_print (" %s() failed", "get_pipeline_new");		if ( ! source) g_print (" %s=%s(%s) failed", "source", "gst_element_factory_make", "playbin");		g_print ("\n");		abort();	} 	AM_DBG g_print ("%s: %s\n", id, "set the source audio file");	g_object_set (G_OBJECT(source), "uri", m_uri, NULL);	/* put all elements  to the main pipeline */	gst_bin_add_many (GST_BIN(m_gst_player), source, sink, NULL);#endif//WITH_NOKIA770	/* wait for start */	gst_state_changed = gst_element_set_state (m_gst_player, GST_STATE_READY);	if (gst_state_changed != GST_STATE_CHANGE_SUCCESS) {	  //g_print("gst_element_set_state(..%s) returned %d\n", "GST_STATE_READY", gst_state_changed);	}	AM_DBG g_print ("%s: %s\n", id, "add call-back message handler for eos");	/* add call-back message handler to check for eos and errors */	gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (m_gst_player)),			   gst_bus_callback, m_gst_mainloop);	gst_state_changed = gst_element_set_state (m_gst_player, GST_STATE_PAUSED);	if (gst_state_changed == GST_STATE_CHANGE_ASYNC) {		gst_state_changed = gst_element_get_state (m_gst_player, NULL, NULL, GST_CLOCK_TIME_NONE);	}	if (m_audio_renderer) m_audio_renderer->m_pipeline = m_gst_player;	/* allow start playback*/	pthread_mutex_unlock(&m_gst_player_mutex);	AM_DBG g_print ("%s: %s\n", id, "iterate");	/* iterate */	AM_DBG g_print("Now playing %s ...", m_uri);	g_main_loop_run (m_gst_mainloop);	AM_DBG g_print ("done !\n");	/* lock for cleanup */	pthread_mutex_lock(&m_gst_player_mutex);	m_gst_mainloop = NULL;	/* stop the pipeline */	if (gst_state_changed != GST_STATE_CHANGE_SUCCESS) {		if (gst_state_changed == GST_STATE_CHANGE_ASYNC) {			gst_state_changed = gst_element_get_state (GST_ELEMENT(m_gst_player), NULL, NULL, GST_CLOCK_TIME_NONE);		}		// g_print("gst_element_set_state(..%s) returned %d\n", "GST_STATE_PAUSED", gst_state_changed);	}	gst_state_changed = gst_element_set_state (m_gst_player, GST_STATE_READY);	if (gst_state_changed != GST_STATE_CHANGE_SUCCESS) {	  //g_print("gst_element_set_state(..%s) returned %d\n", "GST_STATE_REA", gst_state_changed);	}	gst_state_changed = gst_element_set_state (m_gst_player, GST_STATE_NULL);	if (gst_state_changed != GST_STATE_CHANGE_SUCCESS) {	  //g_print("gst_element_set_state(..%s) returned %d\n", "GST_STATE_NULL", gst_state_changed);	}	// inform the scheduler that the gstreamer player has terminated	if (m_audio_renderer) {		m_audio_renderer->stopped();		m_audio_renderer = NULL;	}	/* cleanup */	gst_object_unref (GST_OBJECT(m_gst_player));	m_gst_player = NULL;	pthread_mutex_unlock(&m_gst_player_mutex);  #ifdef  WITH_NOKIA770	if (pthread_mutex_unlock(&s_main_nokia770_mutex) < 0) {		lib::logger::get_logger()->fatal("gstreamer_player::run():: pthread_mutex_unlock(s_main_nokia770_mutex) failed: %s", strerror(errno));		abort();	}#endif//WITH_NOKIA770	return 0;}voidgstreamer_player::stop_player() {	AM_DBG lib::logger::get_logger()->debug("gstreamer_player::stop_player(0x%x)m_uri=%s, m_gst_mainloop=0x%x", (void*)this, m_uri, m_gst_mainloop);	pthread_mutex_lock(&m_gst_player_mutex);	if (m_gst_mainloop) {		g_main_loop_quit (m_gst_mainloop);		m_gst_mainloop = NULL;	}	m_audio_renderer = NULL;	pthread_mutex_unlock(&m_gst_player_mutex);}voidgstreamer_player::pause() {	GstStateChangeReturn gst_state_changed;	AM_DBG lib::logger::get_logger()->debug("gstreamer_player::pause(0x%x)m_uri=%s", (void*)this, m_uri);	pthread_mutex_lock(&m_gst_player_mutex);	if (m_gst_player) {		gst_state_changed = gst_element_set_state (m_gst_player, GST_STATE_PAUSED);		if (gst_state_changed == GST_STATE_CHANGE_ASYNC) {			gst_state_changed = gst_element_get_state (m_gst_player, NULL, NULL, GST_CLOCK_TIME_NONE);		}	}	pthread_mutex_unlock(&m_gst_player_mutex);}voidgstreamer_player::play() {	GstStateChangeReturn gst_state_changed;	pthread_mutex_lock(&m_gst_player_mutex);	AM_DBG lib::logger::get_logger()->debug("gstreamer_player::play(0x%x)m_uri=%s", (void*)this, m_uri);	if (m_gst_player) {		gst_state_changed = gst_element_set_state (m_gst_player, GST_STATE_PLAYING);		if (gst_state_changed == GST_STATE_CHANGE_ASYNC) {			gst_state_changed = gst_element_get_state (m_gst_player, NULL, NULL, GST_CLOCK_TIME_NONE);		}	}	pthread_mutex_unlock(&m_gst_player_mutex);}voidgstreamer_player::seek(double where) {	guint64 where_guint64;	where_guint64 = llrint(where)* GST_SECOND;	// gst_element_seek hangs inside gstmp3sink, therefore it is disabled.	if (1) return;	pthread_mutex_lock(&m_gst_player_mutex);	lib::logger::get_logger()->trace("gstreamer_player: seek() where=%f, where_guint64=%lu", where, where_guint64);	if (m_gst_player) {		if ( ! gst_element_seek(m_gst_player, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, where_guint64, GST_SEEK_TYPE_NONE, 0)) {		        lib::logger::get_logger()->trace("gstreamer_player: seek() failed.");		}	}	pthread_mutex_unlock(&m_gst_player_mutex);}doublegstreamer_player::get_dur() {	gint64 length = -1;	GstFormat fmtTime = GST_FORMAT_TIME;	double dur = 0.0, nanosec = 1e9;	pthread_mutex_lock(&m_gst_player_mutex);	if (m_gst_player)		gst_element_query_duration(m_gst_player, &fmtTime, &length);		pthread_mutex_unlock(&m_gst_player_mutex);	if (length != -1)		dur  = double(length) / nanosec;	return dur;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -