RTSP stream frames from OpenCV in H264

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

RTSP stream frames from OpenCV in H264

macarons
Hello! I'm trying to stream frames from OpenCV using an RTSP server and H264 encoding and then view it from VLC but I can't seem to get the stream to work. Does anyone know how to get this working? Thank you!

I'm using OpenCV's VideoWriter to put the frames into a GStreamer pipeline as follows:
void *read_write_frame(void *args){
    opencv_thread_args *opencv_args = (opencv_thread_args *)args;

    opencv_args->out = cv::VideoWriter ("appsrc ! videoconvert ! video/x-raw,format=I420,width=" + to_string(opencv_args->width) + ",height=" + to_string(opencv_args->height) + ",framerate=30/1 ! x264enc ! udpsink host=127.0.0.1 port=5050",cv::CAP_GSTREAMER,0,30,cv::Size(opencv_args->width,opencv_args->height),true);

    while (true){
        mtx.lock();
        opencv_args->out.write(opencv_args->frame);
        mtx.unlock();
    }
}


I think the important part of the RTSP server is this line:
gst_rtsp_media_factory_set_launch (factory, "udpsrc port=5050 ! rtph264pay name=pay0 pt=96");

The rest of the RTSP server is as follows (the g main loop is created in main):
void *rtsp_server_start(void *args){
    server_thread_args *server_args = (server_thread_args *)args;
   
    GstRTSPMountPoints *mounts;
    GstRTSPMediaFactory *factory;

    // Initialize GStreamer
    gst_init(0, NULL);

    // RTSP server
    server_args->server = gst_rtsp_server_new (); // default listens on 0.0.0.0
    g_object_set (server_args->server, "service", server_args->port.c_str(), NULL);
    mounts = gst_rtsp_server_get_mount_points (server_args->server);

    factory = gst_rtsp_media_factory_new();

    // Set configurations and start stream
    gst_rtsp_media_factory_set_launch (factory, "udpsrc port=5050 ! rtph264pay name=pay0 pt=96");
    gst_rtsp_media_factory_set_shared (factory, TRUE);

    string temp = "/" + server_args->endpoint;
    gst_rtsp_mount_points_add_factory (mounts, temp.c_str(), factory);
    g_object_unref (mounts);

    // Attach server to main(default) context
    int gst_server_id;
    if ((gst_server_id = gst_rtsp_server_attach (server_args->server, NULL)) == 0){
        cout << "RTSP server creation failed" << endl;
    }
    // Run GStreamer main loop
    g_main_loop_run (server_args->loop);
}


I'm running the functions in pthreads and the thread arguments are as follows:
struct server_thread_args{
    GstRTSPServer *server;
    GMainLoop *loop;
    string endpoint = "test";
    string port = "8554";
};

struct opencv_thread_args{
    cv::VideoWriter out;
    cv::Mat frame;
    video_format format;
    int width;
    int height;
};

Any insight would be appreciated!