简体   繁体   English

Gstreamer Appsink 无法从管道中获取数据

[英]Gstreamer Appsink not getting Data from the Pipeline

I am designing a pipeline to Encode a video frame from a opencv application (got from a web cam) to video/x-h264 format, send it via network and decode it on another device of different type (probably a raspberry pi ) to a proper RGB stream for my project.我正在设计一个管道来将来自 opencv 应用程序(从网络摄像头获取)的视频帧编码为 video/x-h264 格式,通过网络发送它并在另一个不同类型的设备(可能是树莓派)上将其解码到适合我的项目的 RGB 流。

For this I am supposed to use a hardware accelerated Encoder and Decoder.为此,我应该使用硬件加速的编码器和解码器。 Since , the whole scenario is huge , the current development is performed on a Intel machine using the gstreamer VAAPI plugins(vaapiencode_h264 & vaapidecode ) .因为,整个场景是巨大的,当前的开发是在使用 gstreamer VAAPI 插件(vaapiencode_h264 & vaapidecode)的 Intel 机器上执行的。 Ánd also, the fact that we need to NOT use any of the networking plugins like TCPServer or UDPServer此外,我们不需要使用任何网络插件,如 TCPServer 或 UDPServer

For this I have used the below pipeline for my purpose : On the Encoder End:为此,我出于我的目的使用了以下管道:在编码器端:

appsrc name=applicationSource ! videoconvert ! video/x-raw, format=I420, width=640, height=480,framerate=30/1, pixel-aspect-ratio=1/1,interlace-mode=progressive ! vaapiencode_h264 bitrate=600 tune=high-compression ! h264parse config-interval=1 ! appsink name=applicationSink sync=false

The Appsrc part works perfectly well while the appsink part is having some issue with it. Appsrc 部分运行良好,而 appsink 部分有一些问题。

The appsink part of this pipeline has been set with the below caps:此管道的 appsink 部分已设置为以下上限:

"video/x-h264, format=(string){avc,avc3,byte-stream },alignment=(string){au,nal};video/mpeg, mpegversion=(int)2, profile=(string)simple" "video/x-h264, format=(string){avc,avc3,byte-stream },alignment=(string){au,nal};video/mpeg, mpegversion=(int)2, profile=(string)simple ”

The code for the data extraction of my appsink is我的appsink数据提取的代码是

    bool HWEncoder::grabData()
{

    // initial checks..

    if (!cameraPipeline)
    {

        GST_ERROR("ERROR AS TO NO PIPE FOUND ... Stopping FRAME GRAB HERE !! ");
        return false;
    }


    if (gst_app_sink_is_eos (GST_APP_SINK(applicationSink)))
    {

        GST_WARNING("APP SINK GAVE US AN EOS! BAILING OUT ");
        return false;
    }

    if (sample)
    {
        cout << "sample available ... unrefing it ! "<< endl;
        gst_sample_unref(sample);
    }


    sample = gst_app_sink_pull_sample (GST_APP_SINK(applicationSink));

    if (!sample)
    {
        GST_WARNING("No valid sample");
        return false; // no valid sample pulled !
    }

    sink_buffer = gst_sample_get_buffer(sample);

    if (!sink_buffer)
    {
        GST_ERROR("No Valid Buffer ");return false;
    }

    return true;
}

After bringing up the pipeline and checking for the buffer filling up in my appsink, I am getting stuck at the below said lines ofmy code indefinitely:在启动管道并检查在我的应用程序接收器中填充的缓冲区后,我无限期地陷入了以下代码行:

sample = gst_app_sink_pull_sample (GST_APP_SINK(applicationSink));

I have the following questions : 1) Is my Caps for appsink correct ?我有以下问题: 1) 我的 Appsink Caps 是否正确? If not How can I determine the caps for them ?如果不是,我如何确定它们的上限? 2) Is there something wrong in my pipeline above ? 2)我上面的管道有问题吗?

How can I fix this issue with Appsink ??如何使用 Appsink 解决此问题?

Any kind of help would be useful!任何形式的帮助都会很有用!

Thanks !!谢谢 !!

Just a guess (I had similar problems) the problem having appsink and appsrc in same pipeline may be that when you fill/empty one of them it will block the other(more on that below).只是猜测(我有类似的问题)在同一管道中存在 appsink 和 appsrc 的问题可能是当您填充/清空其中一个时,它会阻止另一个(更多内容见下文)。

appsink and appsrc would block when they are full/empty - this is normal desired behaviour. appsink 和 appsrc 在满/空时会阻塞 - 这是正常的期望行为。 There is option drop for appsink or for appsrc there is option block - but using these it may be just workaround and you will get glitches in your stream. appsink 有选项drop或 appsrc 有选项block - 但使用这些可能只是解决方法,你会在你的流中出现故障。 Proper solution is to handle the synchronisation between appsrc and appsink in a better way.正确的解决方案是更好地处理 appsrc 和 appsink 之间的同步。

You can react on appsrc signals enough-data and need-data - this is our way.您可以对 appsrc 信号做出enough-dataneed-data - 这是我们的方式。 Also we fiddled with properties of appsrc: is-live , do-timestamp and buffer size (this may or may not help you):我们还摆弄了 appsrc 的属性: is-livedo-timestamp和缓冲区大小(这可能对您有帮助,也可能无济于事):

g_object_set(src->appsrc,
    "stream-type", GST_APP_STREAM_TYPE_STREAM,
    "format", GST_FORMAT_TIME,
    "do-timestamp", TRUE,
    "is-live", TRUE,
    "block", TRUE,
    NULL);

Why do they block each other?他们为什么互相屏蔽? Because (I guess) you process appsink and at the same time appsrc in main application thread.因为(我猜)你在主应用程序线程中同时处理 appsink 和 appsrc 。 When one of the appsink/appsrc block the thread there is no one that would handle the processing for the other one.当一个 appsink/appsrc 阻塞线程时,没有人会处理另一个线程的处理。 So when appsink is blocked because it does not have any data there is noone that can feed appsrc with new data - thus endless deadlock.因此,当 appsink 因为没有任何数据而被阻止时,没有人可以为 appsrc 提供新数据 - 因此会陷入无休止的僵局。

We also implemented noblock version of appsink *pull_sample method but it was just a workaround and resulted in more problems than solutions.我们还实现了 appsink *pull_sample 方法的 noblock 版本,但这只是一种解决方法,导致的问题多于解决方案。

If you want to debug what is happening you can add GST_DEBUG entry for appsrc/appsink (I do not remember what they were), you can add callback on mentioned enough-data and need-data signals or you may add queues and enable GST_DEBUG=queue_dataflow:5 to see which queue is filled first etc.. this is always helpful when debugging the "data-deadlock".如果您想调试正在发生的事情,您可以为 appsrc/appsink 添加 GST_DEBUG 条目(我不记得它们是什么),您可以在提到的enough-dataneed-data信号上添加回调,或者您可以添加队列并启用 GST_DEBUG= queue_dataflow:5 查看哪个队列先被填满等等。这在调试“数据死锁”时总是有帮助的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM