C语言 Gstreamer删除队列分支导致其他分支暂停

ycl3bljg  于 2023-02-11  发布在  其他
关注(0)|答案(1)|浏览(128)

我通过连接和断开分支来控制录像,但小概率appsrc会拒绝数据,无法继续工作,不知道是什么原因造成的,请问有没有解决方案或者其他控制方法?这是管道:

"appsrc name=mysource caps=\"video/x-raw, format=RGB, width=1920, height=1200\" ! "
"videoconvert ! video/x-raw, format=BGRx ! "
"nvvidconv  ! video/x-raw(memory:NVMM), width=1920, height=1080, format=NV12 ! "
"nvv4l2h264enc  insert-sps-pps=1 insert-vui=1 idrinterval=10 disable-cabac=1 profile=2! tee name=t !" "queue ! appsink drop=true name=mysink emit-signals=TRUE caps=\"video/x-h264\""
"queue ! h264parse ! qtmux ! filesink location=xxxxxx"

这是控制视频的功能:

void GstHandle::startRecord(QString path)
{
    if(mIsRecording){
        log_info("%s : GST current record is already open", __func__);
        return;
    }
    record_start = QDateTime::currentMSecsSinceEpoch();
    mRecordQueue = gst_element_factory_make("queue", "record_queue");
    mH264Parse = gst_element_factory_make("h264parse", "myparse");
    mQtMux = gst_element_factory_make("qtmux", "qtmux");
    mFileSink = gst_element_factory_make("filesink", "filesink");

    if(!mFileSink || !mRecordQueue || !mQtMux || !mH264Parse){
        log_error("%s : GST create elements error", __func__);
        return;
    }

    g_object_set (mFileSink, "location", path.toLocal8Bit().data(), NULL);

    gst_bin_add_many(GST_BIN(mPipeline), mRecordQueue, mH264Parse, mQtMux, mFileSink, NULL);
    gst_element_sync_state_with_parent(mFileSink);
    gst_element_sync_state_with_parent(mQtMux);
    gst_element_sync_state_with_parent(mH264Parse);
    gst_element_sync_state_with_parent(mRecordQueue);
    if(gst_element_link_many(mRecordQueue, mH264Parse, mQtMux, mFileSink, NULL) != TRUE)
    {
        log_error("%s : GST video queue link error", __func__);
    }

    gst_element_sync_state_with_parent(mRecordQueue);

    //set pads
    tee_record_pad = gst_element_get_request_pad(mTee, "src_2");
    record_sink_pad = gst_element_get_static_pad(mRecordQueue, "sink");
    if(!tee_record_pad || !record_sink_pad){
        log_error("%s : GST get pads error", __func__);
        return;
    }
    GstPadLinkReturn ret = GST_PAD_LINK_OK;
    if(!gst_pad_is_linked(record_sink_pad)){
        ret = gst_pad_link(tee_record_pad, record_sink_pad);
        if(ret != GST_PAD_LINK_OK)
        {
            log_error("%s : GST pad link error", __func__);
            gst_object_unref(record_sink_pad);
            return;
        }
    }
    gst_object_unref(record_sink_pad);

    if(gst_element_set_state(mPipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE)
    {
        log_error("%s : GST Unable to set the pipeline to playing state!", __func__);
    }
    mIsRecording = true;
    log_info("%s : GST start record, save %s", __func__, path.toLocal8Bit().data());
}

void GstHandle::stopRecord()
{
    if(!mIsRecording){
        return;
    }

    if(gst_element_send_event(mQtMux, gst_event_new_eos()) != TRUE){
        log_error("%s : GST send eos to qtmux error, may mp4 cannot play", __func__);
    }

    gst_element_set_state(mRecordQueue, GST_STATE_NULL);
    gst_element_set_state(mH264Parse, GST_STATE_NULL);
    gst_element_set_state(mQtMux, GST_STATE_NULL);
    gst_element_set_state(mFileSink, GST_STATE_NULL);

    record_sink_pad = gst_element_get_static_pad(mRecordQueue, "sink");

    if(gst_pad_is_linked(record_sink_pad))
        gst_pad_unlink(tee_record_pad, record_sink_pad);
    gst_bin_remove(GST_BIN(mPipeline), mFileSink);
    gst_bin_remove(GST_BIN(mPipeline), mQtMux);
    gst_bin_remove(GST_BIN(mPipeline), mH264Parse);
    gst_bin_remove(GST_BIN(mPipeline), mRecordQueue);
    gst_object_unref(record_sink_pad);
    gst_element_release_request_pad(mTee, tee_record_pad);
    gst_object_unref(tee_record_pad);

    mIsRecording = false;
    log_info("%s : GST stop record", __func__);
}

我不能稳定的重现,我想问一下可能的情况是什么或者如何优化这个功能。非常感谢!

ki1q1bka

ki1q1bka1#

是否可以从多线程访问停止/启动记录?如果可以,则它似乎不是线程安全的。代码段中没有“mIsRecording”定义。

相关问题