opencv and g_main_loop_run(loop) render problem

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

opencv and g_main_loop_run(loop) render problem

Erickson.LU
I tried to use appsink get frame and convert it cv::mat and use imshow show
the mat on screen.
The program some part is from opensource code.
I have 2 question :
(1)I think gst_buffer_ref(buffer);  used for releasing the Buffer. But why i
can't use gst_buffer_unref(buffer); ???

(2) The program use appsink pull frame Buffer from v4l2src and convert it to
cv::mat, at last use imshow show the mat.
But when i comment out  *g_main_loop_thread_ = boost::thread(RunMainLoop); *
Everything is ok . The mat will continuously show the mat, and the log
"frame count = ..."  will scroll .


The log is :
*main thread lwpid = 20051
main thread tid = 1807194688
Process_frame thread lwpid = 20055
Process_frame thread tid = 1377380096
frame count = 1
Element APP_SINK0 changed state from NULL to READY.
Element capsfilter1 changed state from NULL to READY.
Element videoconvert0 changed state from NULL to READY.
Element capsfilter0 changed state from NULL to READY.
Element v4l2src0 changed state from NULL to READY.
Element pipeline0 changed state from NULL to READY.
Element capsfilter1 changed state from READY to PAUSED.
Element videoconvert0 changed state from READY to PAUSED.
Element capsfilter0 changed state from READY to PAUSED.
STREAM STATUS received from element v4l2src0: CREATE
Element v4l2src0 changed state from READY to PAUSED.
Element pipeline0 changed state from READY to PAUSED.
Unparsed message received of type: new-clock
Element capsfilter1 changed state from PAUSED to PLAYING.
Element videoconvert0 changed state from PAUSED to PLAYING.
Element capsfilter0 changed state from PAUSED to PLAYING.
Element v4l2src0 changed state from PAUSED to PLAYING.
STREAM STATUS received from element v4l2src0: ENTER
Unparsed message received of type: stream-start
Element APP_SINK0 changed state from READY to PAUSED.
Unparsed message received of type: async-done
Element APP_SINK0 changed state from PAUSED to PLAYING.
Element pipeline0 changed state from PAUSED to PLAYING.
frame count = 2
frame count = 3
frame count = 4
frame count = 5
frame count = 6
frame count = 7
frame count = 8
frame count = 9
frame count = 10
...*







But when I don't comment out  *g_main_loop_thread_ =
boost::thread(RunMainLoop); *
The mat just show only one frame on my screen and pause at there. And the
log is:


*main thread lwpid = 18025
main thread tid = 4097198656
RunningMainLoop thread lwpid = 18027
RunningMainLoop thread tid = 3675776768
Element APP_SINK0 changed state from NULL to READY.
Element capsfilter1 changed state from NULL to READY.
Element videoconvert0 changed state from NULL to READY.
Element capsfilter0 changed state from NULL to READY.
Element v4l2src0 changed state from NULL to READY.
Element pipeline0 changed state from NULL to READY.
Element capsfilter1 changed state from READY to PAUSED.
Element videoconvert0 changed state from READY to PAUSED.
Element capsfilter0 changed state from READY to PAUSED.
STREAM STATUS received from element v4l2src0: CREATE
Element v4l2src0 changed state from READY to PAUSED.
Element pipeline0 changed state from READY to PAUSED.
STREAM STATUS received from element v4l2src0: ENTER
Unparsed message received of type: new-clock
Process_frame thread lwpid = 18029
Element capsfilter1 changed state from PAUSED to PLAYING.
Process_frame thread tid = 3658991360
Unparsed message received of type: stream-start
Element videoconvert0 changed state from PAUSED to PLAYING.
Element capsfilter0 changed state from PAUSED to PLAYING.
Element v4l2src0 changed state from PAUSED to PLAYING.
Element APP_SINK0 changed state from READY to PAUSED.Unparsed message
received of type: async-done

Element APP_SINK0 changed state from PAUSED to PLAYING.
frame count = 1
Element pipeline0 changed state from PAUSED to PLAYING.
test_now: Fatal IO error 11 (Resource temporarily unavailable) on X server
:0.*



If i use *RunMainLoop(); instead of g_main_loop_thread_ =
boost::thread(RunMainLoop);* on the main thread .
It will block at *g_main_loop_run(loop);*. I can understand at blocking at
there. But why i run it at a new thread it will block the Process_frame
method at cv::waitKey(30); ? Does it the function  *g_main_loop_run* will
occupy the X Windows server or something, make opencv can't use that ?






The whole program is bleow:

GstElement* pipeline;
GstBus* bus;
boost::thread g_main_loop_thread_;
GstElement* appsink;
boost::mutex mutex;
GstSample* retrievedBuffer;
GstSample* currentBuffer;

#define SINK0 "v4l2src device=/dev/video0 ! video/x-raw,format=(string)I420,
width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1 !
videoconvert ! video/x-raw,format=(string)BGR, width=(int)640,
height=(int)480, pixel-aspect-ratio=(fraction)1/1 ! appsink name=APP_SINK0
caps=video/x-raw,format=BGR,width=640,height=480,pixel-aspect-ratio=1/1"
const cv::Scalar RED(0,0,255), GREEN(0,255,0);
void DoNewSample()
{
    GstSample* sample = gst_app_sink_pull_sample(GST_APP_SINK(appsink));

    if (sample) {
        boost::lock_guard<boost::mutex> guard(mutex);
        if (currentBuffer != 0)
        {
            gst_sample_unref(currentBuffer);
        }
        currentBuffer = sample;
    }
}
bool IsNewFrameAvailable()
{
    boost::lock_guard<boost::mutex> guard(mutex);
    return ((retrievedBuffer == 0) && (currentBuffer != 0));
}
bool GetSample(GstSample** sample)
{
    boost::lock_guard<boost::mutex> guard(mutex);
    if (retrievedBuffer == 0) {
        if (currentBuffer != 0) {
            retrievedBuffer = currentBuffer;
            currentBuffer = 0;
            (*sample) = retrievedBuffer;
            retrievedBuffer=0;
        }
    } else {
        (*sample) = NULL;
        return false;
    }

    return true;
}

void ReleaseSample()
{
    boost::lock_guard<boost::mutex> guard(mutex);

    if (retrievedBuffer)
        gst_sample_unref(retrievedBuffer);
    retrievedBuffer = 0;

}

void Process_frame(){
    GstSample* sample;
    GstMapInfo map;
    GstStructure* s;
    GstBuffer* buffer;
    GstCaps* caps;
    GstMemory* mem;
    int height, width, size;
    int count=0;
    void* map_data;
    g_print("Process_frame thread lwpid = %u\n", syscall(SYS_gettid));
    g_print("Process_frame thread tid = %u\n", pthread_self());
    while(true){
        if(IsNewFrameAvailable()){
            GetSample(&sample);
            caps = gst_sample_get_caps(sample);
            buffer = gst_sample_get_buffer(sample);
            s = gst_caps_get_structure(caps, 0);
            gst_structure_get_int(s, "height", &height);
            gst_structure_get_int(s, "width", &width);
            size = gst_buffer_get_size(buffer);
            if (gst_buffer_map (buffer, &map, GST_MAP_READ)) {
                cv::Mat frame(height, width, CV_8UC3,map.data,
cv::Mat::AUTO_STEP);
                std::string msg ="Copy Right";
                cv::Point origin(0,0+13);
                cv::putText( frame, msg, origin, 1, 1, RED);
                count++;
                g_print("frame count = %d\n",count);
                cv::imshow("View_CV",frame);
                cv::waitKey(30);

                gst_buffer_unmap (buffer, &map);
                gst_buffer_ref(buffer);
            }
            gst_sample_unref (sample);
            ReleaseSample();
        } else {
        }
    }
}


void EndOfStreamCallback(GstAppSink* appsink, gpointer user_data)
{

}

GstFlowReturn PrerollCallback(GstAppSink* appsink, gpointer user_data)
{
    GstSample* sample = gst_app_sink_pull_preroll(appsink);
    gst_sample_unref(sample);
    return GST_FLOW_OK;
}
GstFlowReturn SampleCallback(GstAppSink* appsink, gpointer user_data)
{
    DoNewSample();
    return GST_FLOW_OK;
}

bool GstMessageParser(GstBus* bus, GstMessage* msg, pipelinewrapper*
pipeline)
{


    if (msg != NULL) {
        GError* err = 0;
        gchar* debug_info = 0;

        switch (GST_MESSAGE_TYPE(msg)) {
            case GST_MESSAGE_ERROR:
                gst_message_parse_error(msg, &err, &debug_info);
                g_printerr("Error received from element %s: %s\n",
GST_OBJECT_NAME(msg->src), err->message);
                g_printerr("Debugging information: %s\n", debug_info ?
debug_info : "none");
                g_clear_error(&err);
                g_free(debug_info);
                break;

            case GST_MESSAGE_WARNING:
                gst_message_parse_warning(msg, &err, &debug_info);
                g_printerr("Warning received from element %s: %s\n",
GST_OBJECT_NAME(msg->src), err->message);
                g_printerr("Debugging information: %s\n", debug_info ?
debug_info : "none");
                g_clear_error(&err);
                g_free(debug_info);
                break;

            case GST_MESSAGE_INFO:
                gst_message_parse_info(msg, &err, &debug_info);
                g_printerr("Info received from element %s: %s\n",
GST_OBJECT_NAME(msg->src), err->message);
                g_printerr("Debugging information: %s\n", debug_info ?
debug_info : "none");
                g_clear_error(&err);
                g_free(debug_info);
                break;

            case GST_MESSAGE_EOS:
                g_print("End-Of-Stream reached.\n");
                break;

            case GST_MESSAGE_STATE_CHANGED:
                GstState old_state, new_state;
                gst_message_parse_state_changed(msg, &old_state, &new_state,
0);
                g_print("Element %s changed state from %s to %s.\n",
GST_OBJECT_NAME(msg->src), gst_element_state_get_name(old_state),
gst_element_state_get_name(new_state));
                break;

            case GST_MESSAGE_QOS:
                break;

            case GST_MESSAGE_STREAM_STATUS:

                GstStreamStatusType stream_status_type;
                GstElement* owner;
                const gchar* stream_status_type_string;
                gst_message_parse_stream_status(msg, &stream_status_type,
&owner);

                switch (stream_status_type) {
                    case GST_STREAM_STATUS_TYPE_CREATE:
                        stream_status_type_string = "CREATE";
                        break;
                    case GST_STREAM_STATUS_TYPE_ENTER:
                        stream_status_type_string = "ENTER";
                        break;
                    case GST_STREAM_STATUS_TYPE_LEAVE:
                        stream_status_type_string = "LEAVE";
                        break;
                    case GST_STREAM_STATUS_TYPE_DESTROY:
                        stream_status_type_string = "DESTROY";
                        break;

                    case GST_STREAM_STATUS_TYPE_START:
                        stream_status_type_string = "START";
                        break;
                    case GST_STREAM_STATUS_TYPE_PAUSE:
                        stream_status_type_string = "PAUSE";
                        break;
                    case GST_STREAM_STATUS_TYPE_STOP:
                        stream_status_type_string = "STOP";
                        break;
                }

                g_printerr("STREAM STATUS received from element %s: %s\n",
GST_OBJECT_NAME(owner), stream_status_type_string);
                //g_free (stream_status_type_string);
                break;

            default:
                g_printerr("Unparsed message received of type: %s\n",
gst_message_type_get_name(GST_MESSAGE_TYPE(msg)));
                break;
        }
    }
    return true;
}

void RunMainLoop()
{
    GMainLoop* loop = g_main_loop_new(NULL, FALSE);
    g_print("RunningMainLoop thread lwpid = %u\n", syscall(SYS_gettid));
    g_print("RunningMainLoop thread tid = %u\n", pthread_self());
    g_main_loop_run(loop);
}

int
main (int argc, char *argv[])
{

    gst_init(&argc, &argv);
//    XInitThreads();
    boost::thread g_main_loop_thread0;

    GstAppSinkCallbacks appsinkCallbacks;
    std::string pipelineString = SINK0;
    std::string appsink_name="APP_SINK0";
    GError* err = 0;
    pipeline = gst_parse_launch(pipelineString.c_str(), &err);

    bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
    gst_bus_add_watch(bus, (GstBusFunc)GstMessageParser, NULL);

    g_main_loop_thread_ = boost::thread(RunMainLoop);
//    RunMainLoop();
    appsink = gst_bin_get_by_name(GST_BIN(pipeline), appsink_name.c_str());

    g_print("main thread lwpid = %u\n", syscall(SYS_gettid));
    g_print("main thread tid = %u\n", pthread_self());


    appsinkCallbacks.new_preroll = &PrerollCallback;
    appsinkCallbacks.new_sample = &SampleCallback;
//    appsinkCallbacks.eos = &EndOfStreamCallback;
    gst_app_sink_set_drop(GST_APP_SINK(appsink), true);
    gst_app_sink_set_max_buffers(GST_APP_SINK(appsink), 1);
    gst_app_sink_set_callbacks(GST_APP_SINK(appsink), &appsinkCallbacks,
NULL, NULL);


    GstStateChangeReturn ret = gst_element_set_state(pipeline,
GST_STATE_PLAYING);

    if (ret == GST_STATE_CHANGE_FAILURE) {
        g_printerr("Unable to set the pipeline to the playing state");
        gst_object_unref(pipeline);
        return false;
    }


//    Process_frame();
    g_main_loop_thread0 = boost::thread(&Process_frame);
    g_main_loop_thread0.join();

    /* cleanup and exit */

    gst_element_set_state(pipeline,GST_STATE_NULL);
    gst_object_unref (pipeline);

    exit (0);
}




--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: opencv and g_main_loop_run(loop) render problem

Nicolas Dufresne-5


Le sam. 21 avr. 2018 12:12, Erickson.LU <[hidden email]> a écrit :
I tried to use appsink get frame and convert it cv::mat and use imshow show
the mat on screen.
The program some part is from opensource code.
I have 2 question :
(1)I think gst_buffer_ref(buffer);  used for releasing the Buffer. But why i
can't use gst_buffer_unref(buffer); ???

(2) The program use appsink pull frame Buffer from v4l2src and convert it to
cv::mat, at last use imshow show the mat.
But when i comment out  *g_main_loop_thread_ = boost::thread(RunMainLoop); *
Everything is ok . The mat will continuously show the mat, and the log
"frame count = ..."  will scroll .


The log is :
*main thread lwpid = 20051
main thread tid = 1807194688
Process_frame thread lwpid = 20055
Process_frame thread tid = 1377380096
frame count = 1
Element APP_SINK0 changed state from NULL to READY.
Element capsfilter1 changed state from NULL to READY.
Element videoconvert0 changed state from NULL to READY.
Element capsfilter0 changed state from NULL to READY.
Element v4l2src0 changed state from NULL to READY.
Element pipeline0 changed state from NULL to READY.
Element capsfilter1 changed state from READY to PAUSED.
Element videoconvert0 changed state from READY to PAUSED.
Element capsfilter0 changed state from READY to PAUSED.
STREAM STATUS received from element v4l2src0: CREATE
Element v4l2src0 changed state from READY to PAUSED.
Element pipeline0 changed state from READY to PAUSED.
Unparsed message received of type: new-clock
Element capsfilter1 changed state from PAUSED to PLAYING.
Element videoconvert0 changed state from PAUSED to PLAYING.
Element capsfilter0 changed state from PAUSED to PLAYING.
Element v4l2src0 changed state from PAUSED to PLAYING.
STREAM STATUS received from element v4l2src0: ENTER
Unparsed message received of type: stream-start
Element APP_SINK0 changed state from READY to PAUSED.
Unparsed message received of type: async-done
Element APP_SINK0 changed state from PAUSED to PLAYING.
Element pipeline0 changed state from PAUSED to PLAYING.
frame count = 2
frame count = 3
frame count = 4
frame count = 5
frame count = 6
frame count = 7
frame count = 8
frame count = 9
frame count = 10
...*







But when I don't comment out  *g_main_loop_thread_ =
boost::thread(RunMainLoop); *
The mat just show only one frame on my screen and pause at there. And the
log is:


*main thread lwpid = 18025
main thread tid = 4097198656
RunningMainLoop thread lwpid = 18027
RunningMainLoop thread tid = 3675776768
Element APP_SINK0 changed state from NULL to READY.
Element capsfilter1 changed state from NULL to READY.
Element videoconvert0 changed state from NULL to READY.
Element capsfilter0 changed state from NULL to READY.
Element v4l2src0 changed state from NULL to READY.
Element pipeline0 changed state from NULL to READY.
Element capsfilter1 changed state from READY to PAUSED.
Element videoconvert0 changed state from READY to PAUSED.
Element capsfilter0 changed state from READY to PAUSED.
STREAM STATUS received from element v4l2src0: CREATE
Element v4l2src0 changed state from READY to PAUSED.
Element pipeline0 changed state from READY to PAUSED.
STREAM STATUS received from element v4l2src0: ENTER
Unparsed message received of type: new-clock
Process_frame thread lwpid = 18029
Element capsfilter1 changed state from PAUSED to PLAYING.
Process_frame thread tid = 3658991360
Unparsed message received of type: stream-start
Element videoconvert0 changed state from PAUSED to PLAYING.
Element capsfilter0 changed state from PAUSED to PLAYING.
Element v4l2src0 changed state from PAUSED to PLAYING.
Element APP_SINK0 changed state from READY to PAUSED.Unparsed message
received of type: async-done

Element APP_SINK0 changed state from PAUSED to PLAYING.
frame count = 1
Element pipeline0 changed state from PAUSED to PLAYING.
test_now: Fatal IO error 11 (Resource temporarily unavailable) on X server
:0.*



If i use *RunMainLoop(); instead of g_main_loop_thread_ =
boost::thread(RunMainLoop);* on the main thread .
It will block at *g_main_loop_run(loop);*. I can understand at blocking at
there. But why i run it at a new thread it will block the Process_frame
method at cv::waitKey(30); ? Does it the function  *g_main_loop_run* will
occupy the X Windows server or something, make opencv can't use that ?






The whole program is bleow:

GstElement* pipeline;
GstBus* bus;
boost::thread g_main_loop_thread_;
GstElement* appsink;
boost::mutex mutex;
GstSample* retrievedBuffer;
GstSample* currentBuffer;

#define SINK0 "v4l2src device=/dev/video0 ! video/x-raw,format=(string)I420,
width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1 !
videoconvert ! video/x-raw,format=(string)BGR, width=(int)640,
height=(int)480, pixel-aspect-ratio=(fraction)1/1 ! appsink name=APP_SINK0
caps=video/x-raw,format=BGR,width=640,height=480,pixel-aspect-ratio=1/1"
const cv::Scalar RED(0,0,255), GREEN(0,255,0);
void DoNewSample()
{
    GstSample* sample = gst_app_sink_pull_sample(GST_APP_SINK(appsink));

    if (sample) {
        boost::lock_guard<boost::mutex> guard(mutex);
        if (currentBuffer != 0)
        {
            gst_sample_unref(currentBuffer);
        }
        currentBuffer = sample;
    }
}
bool IsNewFrameAvailable()
{
    boost::lock_guard<boost::mutex> guard(mutex);
    return ((retrievedBuffer == 0) && (currentBuffer != 0));
}
bool GetSample(GstSample** sample)
{
    boost::lock_guard<boost::mutex> guard(mutex);
    if (retrievedBuffer == 0) {
        if (currentBuffer != 0) {
            retrievedBuffer = currentBuffer;
            currentBuffer = 0;
            (*sample) = retrievedBuffer;
            retrievedBuffer=0;
        }
    } else {
        (*sample) = NULL;
        return false;
    }

    return true;
}

void ReleaseSample()
{
    boost::lock_guard<boost::mutex> guard(mutex);

    if (retrievedBuffer)
        gst_sample_unref(retrievedBuffer);
    retrievedBuffer = 0;

}

void Process_frame(){
    GstSample* sample;
    GstMapInfo map;
    GstStructure* s;
    GstBuffer* buffer;
    GstCaps* caps;
    GstMemory* mem;
    int height, width, size;
    int count=0;
    void* map_data;
    g_print("Process_frame thread lwpid = %u\n", syscall(SYS_gettid));
    g_print("Process_frame thread tid = %u\n", pthread_self());
    while(true){
        if(IsNewFrameAvailable()){
            GetSample(&sample);
            caps = gst_sample_get_caps(sample);
            buffer = gst_sample_get_buffer(sample);
            s = gst_caps_get_structure(caps, 0);
            gst_structure_get_int(s, "height", &height);
            gst_structure_get_int(s, "width", &width);
            size = gst_buffer_get_size(buffer);
            if (gst_buffer_map (buffer, &map, GST_MAP_READ)) {
                cv::Mat frame(height, width, CV_8UC3,map.data,
cv::Mat::AUTO_STEP);
                std::string msg ="Copy Right";
                cv::Point origin(0,0+13);
                cv::putText( frame, msg, origin, 1, 1, RED);
                count++;
                g_print("frame count = %d\n",count);
                cv::imshow("View_CV",frame);
                cv::waitKey(30);

                gst_buffer_unmap (buffer, &map);
                gst_buffer_ref(buffer);
            }
            gst_sample_unref (sample);
            ReleaseSample();
        } else {
        }
    }
}


void EndOfStreamCallback(GstAppSink* appsink, gpointer user_data)
{

}

GstFlowReturn PrerollCallback(GstAppSink* appsink, gpointer user_data)
{
    GstSample* sample = gst_app_sink_pull_preroll(appsink);
    gst_sample_unref(sample);
    return GST_FLOW_OK;
}
GstFlowReturn SampleCallback(GstAppSink* appsink, gpointer user_data)
{
    DoNewSample();
    return GST_FLOW_OK;
}

bool GstMessageParser(GstBus* bus, GstMessage* msg, pipelinewrapper*
pipeline)
{


    if (msg != NULL) {
        GError* err = 0;
        gchar* debug_info = 0;

        switch (GST_MESSAGE_TYPE(msg)) {
            case GST_MESSAGE_ERROR:
                gst_message_parse_error(msg, &err, &debug_info);
                g_printerr("Error received from element %s: %s\n",
GST_OBJECT_NAME(msg->src), err->message);
                g_printerr("Debugging information: %s\n", debug_info ?
debug_info : "none");
                g_clear_error(&err);
                g_free(debug_info);
                break;

            case GST_MESSAGE_WARNING:
                gst_message_parse_warning(msg, &err, &debug_info);
                g_printerr("Warning received from element %s: %s\n",
GST_OBJECT_NAME(msg->src), err->message);
                g_printerr("Debugging information: %s\n", debug_info ?
debug_info : "none");
                g_clear_error(&err);
                g_free(debug_info);
                break;

            case GST_MESSAGE_INFO:
                gst_message_parse_info(msg, &err, &debug_info);
                g_printerr("Info received from element %s: %s\n",
GST_OBJECT_NAME(msg->src), err->message);
                g_printerr("Debugging information: %s\n", debug_info ?
debug_info : "none");
                g_clear_error(&err);
                g_free(debug_info);
                break;

            case GST_MESSAGE_EOS:
                g_print("End-Of-Stream reached.\n");
                break;

            case GST_MESSAGE_STATE_CHANGED:
                GstState old_state, new_state;
                gst_message_parse_state_changed(msg, &old_state, &new_state,
0);
                g_print("Element %s changed state from %s to %s.\n",
GST_OBJECT_NAME(msg->src), gst_element_state_get_name(old_state),
gst_element_state_get_name(new_state));
                break;

            case GST_MESSAGE_QOS:
                break;

            case GST_MESSAGE_STREAM_STATUS:

                GstStreamStatusType stream_status_type;
                GstElement* owner;
                const gchar* stream_status_type_string;
                gst_message_parse_stream_status(msg, &stream_status_type,
&owner);

                switch (stream_status_type) {
                    case GST_STREAM_STATUS_TYPE_CREATE:
                        stream_status_type_string = "CREATE";
                        break;
                    case GST_STREAM_STATUS_TYPE_ENTER:
                        stream_status_type_string = "ENTER";
                        break;
                    case GST_STREAM_STATUS_TYPE_LEAVE:
                        stream_status_type_string = "LEAVE";
                        break;
                    case GST_STREAM_STATUS_TYPE_DESTROY:
                        stream_status_type_string = "DESTROY";
                        break;

                    case GST_STREAM_STATUS_TYPE_START:
                        stream_status_type_string = "START";
                        break;
                    case GST_STREAM_STATUS_TYPE_PAUSE:
                        stream_status_type_string = "PAUSE";
                        break;
                    case GST_STREAM_STATUS_TYPE_STOP:
                        stream_status_type_string = "STOP";
                        break;
                }

                g_printerr("STREAM STATUS received from element %s: %s\n",
GST_OBJECT_NAME(owner), stream_status_type_string);
                //g_free (stream_status_type_string);
                break;

            default:
                g_printerr("Unparsed message received of type: %s\n",
gst_message_type_get_name(GST_MESSAGE_TYPE(msg)));
                break;
        }
    }
    return true;
}

void RunMainLoop()
{
    GMainLoop* loop = g_main_loop_new(NULL, FALSE);

This is wrong, Null mean default main context, which must be created on the same thread. It's really hard to control in which thread the one will be created. In your case, it probably get created in your main function, when you do gst_bus_add_watch(). You could try to create it here, but in general, it's more robust to create a new one. Nd then make everything explicit. Using push_thread_default, and also gst_bus_create_watch and g_source_attach

    g_print("RunningMainLoop thread lwpid = %u\n", syscall(SYS_gettid));
    g_print("RunningMainLoop thread tid = %u\n", pthread_self());
    g_main_loop_run(loop);
}

int
main (int argc, char *argv[])
{

    gst_init(&argc, &argv);
//    XInitThreads();
    boost::thread g_main_loop_thread0;

    GstAppSinkCallbacks appsinkCallbacks;
    std::string pipelineString = SINK0;
    std::string appsink_name="APP_SINK0";
    GError* err = 0;
    pipeline = gst_parse_launch(pipelineString.c_str(), &err);

    bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
    gst_bus_add_watch(bus, (GstBusFunc)GstMessageParser, NULL);

    g_main_loop_thread_ = boost::thread(RunMainLoop);
//    RunMainLoop();
    appsink = gst_bin_get_by_name(GST_BIN(pipeline), appsink_name.c_str());

    g_print("main thread lwpid = %u\n", syscall(SYS_gettid));
    g_print("main thread tid = %u\n", pthread_self());


    appsinkCallbacks.new_preroll = &PrerollCallback;
    appsinkCallbacks.new_sample = &SampleCallback;
//    appsinkCallbacks.eos = &EndOfStreamCallback;
    gst_app_sink_set_drop(GST_APP_SINK(appsink), true);
    gst_app_sink_set_max_buffers(GST_APP_SINK(appsink), 1);
    gst_app_sink_set_callbacks(GST_APP_SINK(appsink), &appsinkCallbacks,
NULL, NULL);


    GstStateChangeReturn ret = gst_element_set_state(pipeline,
GST_STATE_PLAYING);

    if (ret == GST_STATE_CHANGE_FAILURE) {
        g_printerr("Unable to set the pipeline to the playing state");
        gst_object_unref(pipeline);
        return false;
    }


//    Process_frame();
    g_main_loop_thread0 = boost::thread(&Process_frame);
    g_main_loop_thread0.join();

    /* cleanup and exit */

    gst_element_set_state(pipeline,GST_STATE_NULL);
    gst_object_unref (pipeline);

    exit (0);
}




--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel

_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: opencv and g_main_loop_run(loop) render problem

Erickson.LU
I'm sorry, i'm a little confused. I think you said i use gst_bus_add_watch
wrong, cause give it NULL at the third parameter.
How can i chage to that?

static GMainLoop* loop;

void RunMainLoop()
{
    loop = g_main_loop_new(NULL, FALSE);
    g_print("RunningMainLoop thread lwpid = %u\n", syscall(SYS_gettid));
    g_print("RunningMainLoop thread tid = %u\n", pthread_self());
    g_main_loop_run(loop);
}
int
main (int argc, char *argv[])
{...
    bus=gst_pipeline_get_bus(GST_PIPELINE(pipeline));
    gst_bus_add_watch(bus, (GstBusFunc)GstMessageParser, loop);
    g_main_loop_thread_ = boost::thread(RunMainLoop);
...
}

I still get only one frame and it block there.
I think i use the loop at wrong way, it conflict with opencv.

The log is
*main thread lwpid = 24974
main thread tid = 2439948864
RunningMainLoop thread lwpid = 24976
RunningMainLoop thread tid = 2018526976
Element APP_SINK0 changed state from NULL to READY.
Element capsfilter1 changed state from NULL to READY.
Element videoconvert0 changed state from NULL to READY.
Element capsfilter0 changed state from NULL to READY.
Element v4l2src0 changed state from NULL to READY.
Element pipeline0 changed state from NULL to READY.
Element capsfilter1 changed state from READY to PAUSED.
Element videoconvert0 changed state from READY to PAUSED.
Element capsfilter0 changed state from READY to PAUSED.
STREAM STATUS received from element v4l2src0: CREATE
Element v4l2src0 changed state from READY to PAUSED.
Element pipeline0 changed state from READY to PAUSED.
Unparsed message received of type: new-clock
Element capsfilter1 changed state from PAUSED to PLAYING.
Element videoconvert0 changed state from PAUSED to PLAYING.
Element capsfilter0 changed state from PAUSED to PLAYING.
Element v4l2src0 changed state from PAUSED to PLAYING.
Process_frame thread lwpid = 24978
Process_frame thread tid = 2001741568
STREAM STATUS received from element v4l2src0: ENTER
Unparsed message received of type: stream-start
Element APP_SINK0 changed state from READY to PAUSED.
Unparsed message received of type: async-done
frame count = 1
Element APP_SINK0 changed state from PAUSED to PLAYING.
Element pipeline0 changed state from PAUSED to PLAYING.
[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi-threaded client and XInitThreads has not
been called
[xcb] Aborting, sorry about that.
test_now: ../../src/xcb_io.c:274: poll_for_event: Assertion
`!xcb_xlib_threads_sequence_lost' failed.*





--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel