g_main_loop_quit выдает КРИТИЧЕСКУЮ ошибку GLib. Как с этим справиться на C ?

#c #runtime-error #gstreamer #glib #gobject

#c #время выполнения-ошибка #gstreamer #glib #gobject

Вопрос:

Я использую gstreamer 1.14.4 библиотеку для прослушивания локального порта и выгрузки содержимого в файл. Я написал код на C .

Когда я выполняю конвейер, он работает успешно (но не всегда). Иногда случайно программа выдает

КРИТИЧЕСКАЯ ОШИБКА GLib **: g_main_loop_quit: утверждение ‘g_atomic_int_get (amp;loop-> ref_count) > 0’ не удалось
завершить конвейер Gstreamer

Теперь я добавил try-catch к нему, но я не думаю, что это a 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, amp;err, amp;debug);
            g_print("Error: %sn", 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;
    }
}
        
  

Любые предложения / опыт работы с такими ошибками?

Ответ №1:

Критическое предупреждение от GLib означает, что вы каким-то образом неправильно используете API. Это не должно быть перехвачено и обработано / проигнорировано: исправление заключается в том, чтобы исправить ваш код, чтобы не вызывать API неправильно.

Однако я не могу сказать вам, что вы делаете неправильно с API, без полного сообщения об ошибке и минимального рабочего примера воспроизводителя.

Комментарии:

1. Я обновил код и сообщение об ошибке для вашей справки. Не могли бы вы предложить изменения?

2. Где печатается критическое предупреждение? Вы можете отладить это, запустив свою программу в gdb with G_DEBUG=fatal-warnings set .

3. На консоли Eclipse. Мне нужно будет увидеть это предложение (я еще этого не сделал)

4. Я дал контрольные точки для управления потоком G-объектов, и, как вы сказали, ошибка была вызвана неправильными вызовами Api. Конвейер дважды прерывался из-за некоторых проблем с таймером, которые я сейчас исправил. Спасибо