g_main_loop_quit 抛出 GLib-CRITICAL 错误。如何在 C++ 中处理它?
g_main_loop_quit throws GLib-CRITICAL error. How to handle it in C++?
我正在使用 gstreamer 1.14.4
库来侦听本地端口并将内容转储到文件中。我用C++写了代码。
当我执行管道时,它成功运行(但并非总是如此)。有时,程序会随机抛出
GLib-CRITICAL **: g_main_loop_quit: assertion 'g_atomic_int_get (&loop->ref_count) > 0' failed
Terminating the Gstreamer pipeline
现在,我添加了 try-catch
,但我认为它不是 std::exception
。
gboolean GstRtpDepayloader::CallBackBus(GstBus *bus, GstMessage *message, gpointer my_gst_instance) {
/*******************************************************
* Recover your class instance
*******************************************************/
GstRtpDepayloader *pGstptr = (GstRtpDepayloader *) my_gst_instance;
if (pGstptr) {
/*******************************************************
* Check the message type and perform actions accordingly
*******************************************************/
switch (GST_MESSAGE_TYPE(message)) {
case GST_MESSAGE_ERROR: { //Error occured in gstreamer pipeline
GError *err;
gchar *debug;
gst_message_parse_error(message, &err, &debug);
g_print("Error: %s\n", err->message);
g_error_free(err);
g_free(debug);
pGstptr->QuitLoop(pGstptr);
break;
}
case GST_MESSAGE_EOS: { //End of stream reached
pGstptr->QuitLoop(pGstptr);
break;
}
case GST_MESSAGE_ELEMENT: { //UDPSRC throws element message upon set timeout (1sec)
//store and increment the timeout count every this block is executed
if (//timeout is thrown 5 times) {
pGstptr->QuitLoop(pGstptr);
}
break;
default: {
/* unhandled message */
break;
}
}
return (TRUE);
}
return (FALSE);
}
void GstRtpDepayloader::QuitLoop(GstRtpDepayloader *pGstptr){
/*******************************************************
* Quit the main loop
*******************************************************/
try{
g_main_loop_quit(msLoop);
}catch (exception *e) {
/*******************************************************
* Catch any standard exception type failures
*******************************************************/
cerr << "Error: " << e->what() << endl;
}
}
void GstRtpDepayloader::GstPipelineCreation() {
try {
GstBus *bus;
guint bus_watch_id;
auto msLoop = g_main_loop_new(NULL, FALSE);
if (NULL==msLoop){
throw ("Null Loop pointer received @ ");
}
GstElement *pPipeline = gst_pipeline_new("PIPELINE");
/**
* Create the pipeline elements
* udpsrc
* rtppcmudepay
* filesink
*/
/**
* Add elements in pipeline and link them
*/
/*****************************************************************
* adds a watch for new message on our pipeline's message bus to
* the default GLib main context, which is the main context that
* our GLib main loop is attached to below
*****************************************************************/
bus = gst_pipeline_get_bus(GST_PIPELINE(pPipeline));
bus_watch_id = gst_bus_add_watch(bus, CallBackBus, this);
gst_object_unref(bus);
/**********************************************************************
* Pipeline state - PLAYING
**********************************************************************/
gst_element_set_state(pPipeline, GST_STATE_PLAYING);
/**********************************************************************
* Start the loop
**********************************************************************/
g_main_loop_run(msLoop);
/**********************************************************************
* Clean up after GMainLoop ends
**********************************************************************/
gst_element_set_state(pPipeline, GST_STATE_NULL);
gst_object_unref(GST_OBJECT(pPipeline));
g_source_remove(bus_watch_id);
g_main_loop_unref(msLoop);
} catch (exception *e) {
/*******************************************************
* Catch any standard exception type failures
*******************************************************/
cerr << "Error: " << e->what() << endl;
} catch (const char *msg) {
/*******************************************************
* Catch user defined type failures
*******************************************************/
cerr << "Error: " << msg << __FUNCTION__ << __LINE__ << endl;
}
}
关于如何处理此类错误的任何suggestions/experience?
来自 GLib 的严重警告意味着您在某种程度上滥用了 API。它不应该被捕获并且 handled/ignored:修复是修复您的代码以不正确地调用 API。
不过,如果没有完整的错误消息和最小的工作重现器示例,我无法告诉您 API 做错了什么。
我正在使用 gstreamer 1.14.4
库来侦听本地端口并将内容转储到文件中。我用C++写了代码。
当我执行管道时,它成功运行(但并非总是如此)。有时,程序会随机抛出
GLib-CRITICAL **: g_main_loop_quit: assertion 'g_atomic_int_get (&loop->ref_count) > 0' failed
Terminating the Gstreamer pipeline
现在,我添加了 try-catch
,但我认为它不是 std::exception
。
gboolean GstRtpDepayloader::CallBackBus(GstBus *bus, GstMessage *message, gpointer my_gst_instance) {
/*******************************************************
* Recover your class instance
*******************************************************/
GstRtpDepayloader *pGstptr = (GstRtpDepayloader *) my_gst_instance;
if (pGstptr) {
/*******************************************************
* Check the message type and perform actions accordingly
*******************************************************/
switch (GST_MESSAGE_TYPE(message)) {
case GST_MESSAGE_ERROR: { //Error occured in gstreamer pipeline
GError *err;
gchar *debug;
gst_message_parse_error(message, &err, &debug);
g_print("Error: %s\n", err->message);
g_error_free(err);
g_free(debug);
pGstptr->QuitLoop(pGstptr);
break;
}
case GST_MESSAGE_EOS: { //End of stream reached
pGstptr->QuitLoop(pGstptr);
break;
}
case GST_MESSAGE_ELEMENT: { //UDPSRC throws element message upon set timeout (1sec)
//store and increment the timeout count every this block is executed
if (//timeout is thrown 5 times) {
pGstptr->QuitLoop(pGstptr);
}
break;
default: {
/* unhandled message */
break;
}
}
return (TRUE);
}
return (FALSE);
}
void GstRtpDepayloader::QuitLoop(GstRtpDepayloader *pGstptr){
/*******************************************************
* Quit the main loop
*******************************************************/
try{
g_main_loop_quit(msLoop);
}catch (exception *e) {
/*******************************************************
* Catch any standard exception type failures
*******************************************************/
cerr << "Error: " << e->what() << endl;
}
}
void GstRtpDepayloader::GstPipelineCreation() {
try {
GstBus *bus;
guint bus_watch_id;
auto msLoop = g_main_loop_new(NULL, FALSE);
if (NULL==msLoop){
throw ("Null Loop pointer received @ ");
}
GstElement *pPipeline = gst_pipeline_new("PIPELINE");
/**
* Create the pipeline elements
* udpsrc
* rtppcmudepay
* filesink
*/
/**
* Add elements in pipeline and link them
*/
/*****************************************************************
* adds a watch for new message on our pipeline's message bus to
* the default GLib main context, which is the main context that
* our GLib main loop is attached to below
*****************************************************************/
bus = gst_pipeline_get_bus(GST_PIPELINE(pPipeline));
bus_watch_id = gst_bus_add_watch(bus, CallBackBus, this);
gst_object_unref(bus);
/**********************************************************************
* Pipeline state - PLAYING
**********************************************************************/
gst_element_set_state(pPipeline, GST_STATE_PLAYING);
/**********************************************************************
* Start the loop
**********************************************************************/
g_main_loop_run(msLoop);
/**********************************************************************
* Clean up after GMainLoop ends
**********************************************************************/
gst_element_set_state(pPipeline, GST_STATE_NULL);
gst_object_unref(GST_OBJECT(pPipeline));
g_source_remove(bus_watch_id);
g_main_loop_unref(msLoop);
} catch (exception *e) {
/*******************************************************
* Catch any standard exception type failures
*******************************************************/
cerr << "Error: " << e->what() << endl;
} catch (const char *msg) {
/*******************************************************
* Catch user defined type failures
*******************************************************/
cerr << "Error: " << msg << __FUNCTION__ << __LINE__ << endl;
}
}
关于如何处理此类错误的任何suggestions/experience?
来自 GLib 的严重警告意味着您在某种程度上滥用了 API。它不应该被捕获并且 handled/ignored:修复是修复您的代码以不正确地调用 API。
不过,如果没有完整的错误消息和最小的工作重现器示例,我无法告诉您 API 做错了什么。