Gstreamer 面临错误:无法将多路分配器视频板链接到视频队列板。退出

问题描述 投票:0回答:1

我一直在研究 gstreamer,我不明白我在哪里出错,但我尝试转换代码的每个管道都会给我“元素无法链接”,并且我正在 ubuntu 上运行此代码。我不想使用 gst-launch 的直接命令行,因为稍后我必须更改时钟属性,所以请帮助处理 c 程序本身。

#include <gst/gst.h>

GstElement *pipeline, *source, *demux, *audio_queue, *audio_decode, *audio_convert, *video_queue, *video_decode, *video_convert, *video_overlay, *audio_sink, *video_sink;
    GstPad *audio_pad, *video_pad, *demux_audio_pad, *demux_video_pad, *demux_pad_template;

static int temp = 0;
static void pad_added_callback(GstElement *src, GstPad *new_pad, gpointer data) {
GstPad *sink_pad;
GstElement *queue = (GstElement *) data;
GstCaps *new_pad_caps = NULL;
GstStructure *new_pad_struct = NULL;
const gchar *new_pad_type = NULL;

g_print("Received new pad '%s' from '%s':\n", GST_PAD_NAME(new_pad), GST_ELEMENT_NAME(src));

// Check the new pad's type 
//
new_pad_caps = gst_pad_get_current_caps(new_pad);
new_pad_struct = gst_caps_get_structure(new_pad_caps, 0);
new_pad_type = gst_structure_get_name(new_pad_struct);

// If it's audio, link it to the audio_queue 
//
if (temp == 1) {

g_print("audio pad added");

sink_pad = gst_element_get_static_pad(audio_queue, "sink");
if (gst_pad_link(new_pad, audio_pad) != GST_PAD_LINK_OK) {

        g_error("Failed to link demux audio pad to audio queue pad. Exiting.");
        return;
    }
    temp++;
} else if (temp == 0) {
// If it's video, link it to the video_queue 

g_print("Entered the vid pad");
sink_pad = gst_element_get_static_pad(video_queue, "sink");
if (gst_pad_link(new_pad, video_pad) != GST_PAD_LINK_OK) {
        g_error("Failed to link demux video pad to video queue pad. Exiting.");
        return;
    }
    temp++;
} else {
// It is neither audio nor video so we do nothing 
g_print("ajjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
if (new_pad_caps != NULL)
gst_caps_unref(new_pad_caps);
return;
}
}

 
int main(int argc, char *argv[]) {
    
    GstBus *bus;
    GstMessage *msg;

    // Initialize GStreamer
    gst_init(&argc, &argv);

    // Create the pipeline
    pipeline = gst_pipeline_new("pipeline");

    // Create elements
    source = gst_element_factory_make("filesrc", "source");
    demux = gst_element_factory_make("matroskademux", "demux");
    audio_queue = gst_element_factory_make("queue", "audio_queue");
    audio_decode = gst_element_factory_make("decodebin", "audio_decode");
    audio_convert = gst_element_factory_make("audioconvert", "audio_convert");
    audio_sink = gst_element_factory_make("autoaudiosink", "audio_sink");
    video_queue = gst_element_factory_make("queue", "video_queue");
    video_decode = gst_element_factory_make("decodebin", "video_decode");
    video_convert = gst_element_factory_make("videoconvert", "video_convert");
    video_overlay = gst_element_factory_make("clockoverlay", "video_overlay");
    video_sink = gst_element_factory_make("autovideosink", "video_sink");

    // Check elements creation
    if (!pipeline || !source || !demux || !audio_queue || !audio_decode || !audio_convert || !audio_sink || !video_queue || !video_decode || !video_convert || !video_overlay || !video_sink)  {
        g_error("Failed to create elements. Exiting.");
        return -1;
    }

    // Set the location of the file to play
    g_object_set(source, "location", "/home/lg/ml/sintel_video.mkv", NULL);

    // Add elements to the pipeline
    gst_bin_add_many(GST_BIN(pipeline), source, demux, audio_queue, audio_decode, audio_convert, audio_sink, video_queue, video_decode, video_convert, video_overlay, video_sink, NULL);

    // Link elements
    gst_element_link(source, demux);
    gst_element_link_many(audio_queue, audio_decode, audio_convert, audio_sink, NULL);
    gst_element_link_many(video_queue, video_decode, video_convert, video_overlay, video_sink, NULL);


    g_signal_connect(demux, "pad-added", G_CALLBACK(pad_added_callback), NULL);

    // Start playing
    gst_element_set_state(pipeline, GST_STATE_PLAYING);

    // Listen for messages on the pipeline's bus
    bus = gst_element_get_bus(pipeline);
    msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);

    // Free resources
    gst_message_unref(msg);
    gst_object_unref(bus);
    gst_element_set_state(pipeline, GST_STATE_NULL);
    gst_object_unref(pipeline);

    return 1;
}

这是用于解复用音频视频并在本地目录位置流式传输文件的代码:/home/lg/ml/sintel_video.mkv 编译时我没有收到任何错误,但 ./filepgm 给出:

muthu:~/ml$ ./clock1 0:00:00.031117832 17158 0x616a13c34100 警告basesrc gstbasesrc.c:3688:gst_base_src_start_complete: 垫尚未激活 从“demux”收到新的 pad“video_0”: 已进入视频板 (时钟1:17158):GStreamer-CRITICAL **:01:52:14.180:gst_pad_link_full:断言“GST_IS_PAD(水槽)”失败

**(时钟1:17158):错误**:01:52:14.181:无法将多路分配器视频板链接到视频队列板。退出。 跟踪/断点陷阱(核心转储)

gstreamer gstreamer-1.0
1个回答
0
投票

Matroska demuxer 生成已解码的流(x-raw),因此在audio_queue 和video_queue 之后不需要decodebin。另外,您也可以使用decodebin,而不是使用matroska demuxer。 Decodebin 应该自动(使用 typefind)检测输入的类型,如果 filesrc 正在推送 webm 输入,那么decodebin 将透明地为您使用 matroska demuxer。 现在,您可能想从管道中删除 audio_decode 和 video_decode 元素。

© www.soinside.com 2019 - 2024. All rights reserved.