In gstreamer adding and removing queue of a tee dy

2020-06-23 06:48发布

问题:

I have written gstreamer code for camera live-streaming and recording at the same time.

My pipeline looks like that:

                 /  [ queue1 | videosink ]           
v4l2src | tee         
                 \  [ queue2 | filesink ]        

Currently both live streaming and file recording is working together.

Now I need to start the pipeline with only one queue i.e. queue1 (live streaming queue), After a while I need to add the recording queue and remove it dynamically too.

My working code are given below :

    pipeline = gst_pipeline_new ("rv_camera");

    /*Create source element. We use mfw_v4lsrc from Freescale as source */

    source= gst_element_factory_make (GSTREAMER_SOURCE,"camera-source");
    g_object_set(G_OBJECT(source),"device",camDeviceName, (char *)0);

    /*Set default properties of mfw_v4lsrc */
    g_object_set(G_OBJECT(source),"capture-width", CAMERA_CAPTURE_WIDTH,
                                  "capture-height", CAMERA_CAPTURE_HEIGHT,
                                  "sensor-width", CAMERA_SENSOR_WIDTH,
                                  "sensor-height", CAMERA_SENSOR_HEIGHT,
                                  "preview", CAMERA_PREVIEW_DISPLAY,
                                  "preview-width",CAMERA_PREVIEW_WIDTH,
                                  "preview-height",CAMERA_PREVIEW_HEIGHT,
                                  "fps-n",CAMERA_FRAMERATE,
                                  "rotate",mirror_effect,
                                  (char *)0);


    /* Tee that copies the stream to multiple outputs */
        tee = gst_element_factory_make("tee", "tee");

        /* Queue creates new thread for the stream */
        screen_queue = gst_element_factory_make("queue", "screen_queue");

    /*Create sink element. We use mfw_v4lsink from Freescale as sink. fbdevsink is not used as
      it directly writes into framebuffer which is not desired*/
    sink= gst_element_factory_make (GSTREAMER_SINK,"video-output");

    capture_queue = gst_element_factory_make("queue", "capture_queue");

    encoder = gst_element_factory_make("mfw_vpuencoder", "encoder");
    g_object_set(G_OBJECT(encoder),"codec-type",0,
                                   "mirror-direction",0,
                                    (char *)0);

    clockoverlay = gst_element_factory_make("clockoverlay", "Timestamp");
    g_object_set(G_OBJECT(clockoverlay),"time-format","%R %d-%b-%Y", (char *)0);

    avimux = gst_element_factory_make("avimux", "avimux");

    filesink = gst_element_factory_make("filesink", "file-output");
    g_object_set(G_OBJECT(filesink),"location","/KPIT/OBITS/Blackbox/OBITS-SCNLog.avi", (char *)0);



    /* Check if all elements are created or not*/
    if (!pipeline || !source || !tee || !screen_queue || !sink || !capture_queue || !clockoverlay || !encoder || !avimux || !filesink) {
        LOGERR((TEXT("GstreamerStream :: camInit: 1 One or more element(s) could not be created .... logerr\n")));
        return CAM_STATUS_INIT_FAIL;
    }

    /* we add all elements into the pipeline */
    gst_bin_add_many (GST_BIN (pipeline),source,tee,screen_queue, sink, capture_queue,clockoverlay,encoder,avimux,filesink, (char *)0);

    /* we link the elements together */
   if( gst_element_link_many( source, tee, NULL ) &&  gst_element_link_many( tee,screen_queue,sink, NULL ) &&
           gst_element_link_many( tee,capture_queue,clockoverlay,encoder,avimux,filesink, NULL ))
   {
         bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));

        /*Add watch to look for error events */
        gst_bus_add_watch(bus, process_events, this);

        gst_object_unref(bus);

        }
        gst_element_set_state (pipeline, GST_STATE_PLAYING);

Kindly let me know the way, I can add or remove any queue dynamically.

I'd appreciate your help if someone can provide sample code related to this.

回答1:

Keep the tee in the pipeline and you can request/release pads from the tee at any time during playback. Request the pad and add your new elements to the pipeline, link them, and set them to playing, too. When you are done, unlink this branch and remember to send EOS to it to have the recording properly finished. After you receive the EOS message from the filesink you can shutdown, remove and unref the branch you unlinked.

If you are using 0.10 (don't use it, move to 1.0), then you might need to send a segment event to the new branch once you add it.



标签: gstreamer