mirror of
https://github.com/morgan9e/UxPlay
synced 2026-04-14 00:04:13 +09:00
add message handler for audio pipeline bus
This commit is contained in:
@@ -45,6 +45,7 @@ typedef struct audio_renderer_s {
|
||||
GstElement *appsrc;
|
||||
GstElement *pipeline;
|
||||
GstElement *volume;
|
||||
GstBus *bus;
|
||||
unsigned char ct;
|
||||
} audio_renderer_t ;
|
||||
static audio_renderer_t *renderer_type[NFORMATS];
|
||||
@@ -186,7 +187,7 @@ void audio_renderer_init(logger_t *render_logger, const char* audiosink, const b
|
||||
|
||||
g_assert (renderer_type[i]->pipeline);
|
||||
gst_pipeline_use_clock(GST_PIPELINE_CAST(renderer_type[i]->pipeline), clock);
|
||||
|
||||
renderer_type[i]->bus = gst_element_get_bus(renderer_type[i]->pipeline);
|
||||
renderer_type[i]->appsrc = gst_bin_get_by_name (GST_BIN (renderer_type[i]->pipeline), "audio_source");
|
||||
renderer_type[i]->volume = gst_bin_get_by_name (GST_BIN (renderer_type[i]->pipeline), "volume");
|
||||
switch (i) {
|
||||
@@ -367,6 +368,8 @@ void audio_renderer_flush() {
|
||||
void audio_renderer_destroy() {
|
||||
audio_renderer_stop();
|
||||
for (int i = 0; i < NFORMATS ; i++ ) {
|
||||
gst_object_unref (renderer_type[i]->bus);
|
||||
renderer_type[i]->bus = NULL;
|
||||
gst_object_unref (renderer_type[i]->volume);
|
||||
renderer_type[i]->volume = NULL;
|
||||
gst_object_unref (renderer_type[i]->appsrc);
|
||||
@@ -376,3 +379,41 @@ void audio_renderer_destroy() {
|
||||
free(renderer_type[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean gstreamer_audio_pipeline_bus_callback(GstBus *bus, GstMessage *message, void *loop) {
|
||||
switch (GST_MESSAGE_TYPE(message)) {
|
||||
case GST_MESSAGE_ERROR: {
|
||||
GError *err;
|
||||
gchar *debug;
|
||||
gst_message_parse_error (message, &err, &debug);
|
||||
logger_log(logger, LOGGER_INFO, "GStreamer error (audio): %s %s", GST_MESSAGE_SRC_NAME(message),err->message);
|
||||
g_error_free(err);
|
||||
g_free(debug);
|
||||
if (renderer->appsrc) {
|
||||
gst_app_src_end_of_stream (GST_APP_SRC(renderer->appsrc));
|
||||
}
|
||||
gst_bus_set_flushing(bus, TRUE);
|
||||
gst_element_set_state (renderer->pipeline, GST_STATE_READY);
|
||||
g_main_loop_quit( (GMainLoop *) loop);
|
||||
break;
|
||||
}
|
||||
case GST_MESSAGE_EOS:
|
||||
logger_log(logger, LOGGER_INFO, "GStreamer: End-Of-Stream (audio)");
|
||||
break;
|
||||
case GST_MESSAGE_ELEMENT:
|
||||
// many "level" messages may be sent
|
||||
break;
|
||||
default:
|
||||
/* unhandled message */
|
||||
logger_log(logger, LOGGER_DEBUG,"GStreamer unhandled audio bus message: src = %s type = %s",
|
||||
GST_MESSAGE_SRC_NAME(message), GST_MESSAGE_TYPE_NAME(message));
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
unsigned int audio_renderer_listen(void *loop, int id) {
|
||||
g_assert(id >= 0 && id < NFORMATS);
|
||||
return (unsigned int) gst_bus_add_watch(renderer_type[id]->bus,(GstBusFunc)
|
||||
gstreamer_audio_pipeline_bus_callback, (gpointer) loop);
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ void audio_renderer_render_buffer(unsigned char* data, int *data_len, unsigned s
|
||||
void audio_renderer_set_volume(double volume);
|
||||
void audio_renderer_flush();
|
||||
void audio_renderer_destroy();
|
||||
|
||||
unsigned int audio_renderer_listen(void *loop, int id);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -647,7 +647,7 @@ static void get_stream_status_name(GstStreamStatusType type, char *name, size_t
|
||||
}
|
||||
}
|
||||
|
||||
gboolean gstreamer_pipeline_bus_callback(GstBus *bus, GstMessage *message, void *loop) {
|
||||
static gboolean gstreamer_video_pipeline_bus_callback(GstBus *bus, GstMessage *message, void *loop) {
|
||||
GstState old_state, new_state;
|
||||
const gchar no_state[] = "";
|
||||
const gchar *old_state_name = no_state, *new_state_name = no_state;
|
||||
@@ -756,7 +756,7 @@ gboolean gstreamer_pipeline_bus_callback(GstBus *bus, GstMessage *message, void
|
||||
gchar *debug;
|
||||
gboolean flushing;
|
||||
gst_message_parse_error (message, &err, &debug);
|
||||
logger_log(logger, LOGGER_INFO, "GStreamer error: %s %s", GST_MESSAGE_SRC_NAME(message),err->message);
|
||||
logger_log(logger, LOGGER_INFO, "GStreamer error (video): %s %s", GST_MESSAGE_SRC_NAME(message),err->message);
|
||||
if (!hls_video && strstr(err->message,"Internal data stream error")) {
|
||||
logger_log(logger, LOGGER_INFO,
|
||||
"*** This is a generic GStreamer error that usually means that GStreamer\n"
|
||||
@@ -780,7 +780,7 @@ gboolean gstreamer_pipeline_bus_callback(GstBus *bus, GstMessage *message, void
|
||||
}
|
||||
case GST_MESSAGE_EOS:
|
||||
/* end-of-stream */
|
||||
logger_log(logger, LOGGER_INFO, "GStreamer: End-Of-Stream");
|
||||
logger_log(logger, LOGGER_INFO, "GStreamer: End-Of-Stream (video)");
|
||||
if (hls_video) {
|
||||
gst_bus_set_flushing(bus, TRUE);
|
||||
gst_element_set_state (renderer_type[type]->pipeline, GST_STATE_READY);
|
||||
@@ -1007,5 +1007,5 @@ void video_renderer_seek(float position) {
|
||||
unsigned int video_renderer_listen(void *loop, int id) {
|
||||
g_assert(id >= 0 && id < n_renderers);
|
||||
return (unsigned int) gst_bus_add_watch(renderer_type[id]->bus,(GstBusFunc)
|
||||
gstreamer_pipeline_bus_callback, (gpointer) loop);
|
||||
gstreamer_video_pipeline_bus_callback, (gpointer) loop);
|
||||
}
|
||||
|
||||
31
uxplay.cpp
31
uxplay.cpp
@@ -164,7 +164,8 @@ static double db_high = 0.0;
|
||||
static bool taper_volume = false;
|
||||
static double initial_volume = 0.0;
|
||||
static bool h265_support = false;
|
||||
static int n_renderers = 0;
|
||||
static int n_video_renderers = 0;
|
||||
static int n_audio_renderers = 0;
|
||||
static bool hls_support = false;
|
||||
static std::string url = "";
|
||||
static guint gst_x11_window_id = 0;
|
||||
@@ -464,8 +465,10 @@ static guint g_unix_signal_add(gint signum, GSourceFunc handler, gpointer user_d
|
||||
#endif
|
||||
|
||||
static void main_loop() {
|
||||
guint gst_bus_watch_id[3] = { 0 };
|
||||
g_assert(n_renderers <= 3);
|
||||
guint gst_video_bus_watch_id[3] = { 0 };
|
||||
g_assert(n_video_renderers <= 3);
|
||||
guint gst_audio_bus_watch_id[2] = { 0 };
|
||||
g_assert(n_audio_renderers <= 2);
|
||||
GMainLoop *loop = g_main_loop_new(NULL,FALSE);
|
||||
relaunch_video = false;
|
||||
reset_loop = false;
|
||||
@@ -475,18 +478,25 @@ static void main_loop() {
|
||||
relaunch_video = true;
|
||||
if (url.empty()) {
|
||||
/* renderer[0] : jpeg coverart; renderer[1] h264 video; renderer[2] h265 video (optional) */
|
||||
n_renderers = h265_support ? 3 : 2;
|
||||
n_video_renderers = h265_support ? 3 : 2;
|
||||
gst_x11_window_id = 0;
|
||||
} else {
|
||||
/* hls video will be rendered: renderer[0] : hls */
|
||||
n_renderers = 1;
|
||||
n_video_renderers = 1;
|
||||
url.erase();
|
||||
gst_x11_window_id = g_timeout_add(100, (GSourceFunc) x11_window_callback, (gpointer) loop);
|
||||
}
|
||||
for (int i = 0; i < n_renderers; i++) {
|
||||
gst_bus_watch_id[i] = (guint) video_renderer_listen((void *)loop, i);
|
||||
for (int i = 0; i < n_video_renderers; i++) {
|
||||
gst_video_bus_watch_id[i] = (guint) video_renderer_listen((void *)loop, i);
|
||||
}
|
||||
}
|
||||
if (use_audio) {
|
||||
n_audio_renderers = 2;
|
||||
for (int i = 0; i < n_audio_renderers; i++) {
|
||||
gst_audio_bus_watch_id[i] = (guint) audio_renderer_listen((void *)loop, i);
|
||||
}
|
||||
}
|
||||
|
||||
missed_feedback = 0;
|
||||
guint feedback_watch_id = g_timeout_add_seconds(1, (GSourceFunc) feedback_callback, (gpointer) loop);
|
||||
guint reset_watch_id = g_timeout_add(100, (GSourceFunc) reset_callback, (gpointer) loop);
|
||||
@@ -495,8 +505,11 @@ static void main_loop() {
|
||||
guint sigint_watch_id = g_unix_signal_add(SIGINT, (GSourceFunc) sigint_callback, (gpointer) loop);
|
||||
g_main_loop_run(loop);
|
||||
|
||||
for (int i = 0; i < n_renderers; i++) {
|
||||
if (gst_bus_watch_id[i] > 0) g_source_remove(gst_bus_watch_id[i]);
|
||||
for (int i = 0; i < n_video_renderers; i++) {
|
||||
if (gst_video_bus_watch_id[i] > 0) g_source_remove(gst_video_bus_watch_id[i]);
|
||||
}
|
||||
for (int i = 0; i < n_audio_renderers; i++) {
|
||||
if (gst_audio_bus_watch_id[i] > 0) g_source_remove(gst_audio_bus_watch_id[i]);
|
||||
}
|
||||
if (gst_x11_window_id > 0) g_source_remove(gst_x11_window_id);
|
||||
if (sigint_watch_id > 0) g_source_remove(sigint_watch_id);
|
||||
|
||||
Reference in New Issue
Block a user