GStreamer 1.0用C将原始数据编码为H.264

GStreamer 1.0用C将原始数据编码为H.264,c,h.264,gstreamer-1.0,C,H.264,Gstreamer 1.0,我正在使用GStreamer-1.0版本:1.10.4 我有一个原始视频文件,我想用C中的GStreamer用h.264编码 我的管道如下所示: GstElement* pipeline; GstElement* src; GstElement* videoparse; GstElement* decodebin; GstElement* videoconvert; GstElement* x264enc; GstElement* queue; GstElement* mp4mux; GstE

我正在使用GStreamer-1.0版本:1.10.4

我有一个原始视频文件,我想用C中的GStreamer用h.264编码

我的管道如下所示:

GstElement* pipeline;

GstElement* src;
GstElement* videoparse;
GstElement* decodebin;
GstElement* videoconvert;
GstElement* x264enc;
GstElement* queue;
GstElement* mp4mux;
GstElement* filesink;

pipeline = gst_pipeline_new("pipeline");

src = gst_element_factory_make("filesrc", NULL);
if(!src) {
    GST_WARNING("Error in: src");
}

g_object_set(G_OBJECT(src),"location","myVideo.yuv",NULL);
g_object_set(G_OBJECT(src),2073600,NULL);

videoparse = gst_element_factory_make("videoparse", NULL);
if(!videoparse) {
    GST_WARNING("Error in: videoparse");
}

g_object_set(G_OBJECT(videoparse),"width",1920,NULL);
g_object_set(G_OBJECT(videoparse),"height",1080,NULL);

decodebin = gst_element_factory_make("decodebin", NULL);
if(!decodebin) {
    GST_WARNING("Error in: decodebin");
}

videoconvert = gst_element_factory_make("videoconvert", NULL);
if(!videoconvert) {
    GST_WARNING("Error in: videoconvert");
}   

x264enc = gst_element_factory_make("x264enc", NULL);
if(!x264enc) {
    GST_WARNING("Error in: x264enc");
}    

queue = gst_element_factory_make("queue", NULL);
if(!queue) {
    GST_WARNING("Error in: queue");
}     

mp4mux = gst_element_factory_make("mp4mux", NULL);
if(!mp4mux) {
    GST_WARNING("Error in: mp4mux");
}     

g_object_set(G_OBJECT(mp4mux),"name","mux",NULL);

filesink = gst_element_factory_make("filesink", NULL);
if(!filesink) {
    GST_WARNING("Error in: filesink");
}     

g_object_set(G_OBJECT(filesink),"location","myFile.mp4",NULL);

gst_bin_add_many(GST_BIN(pipeline),src,videoparse,decodebin,videoconvert,x264enc,queue,mp4mux,filesink, NULL);

gst_element_link(src, videoparse);
gst_element_link(videoparse, decodebin);
gst_element_link(decodebin, videoconvert);
gst_element_link(videoconvert, x264enc);
gst_element_link(x264enc, queue);
gst_element_link(queue, mp4mux);
gst_element_link(mp4mux, filesink);

gst_element_set_state(pipeline, GST_STATE_PLAYING);

sleep(40);
gst-launch-1.0 filesrc location=myVideo.yuv blocksize=2073600!视频解析宽度=1920高度=1080!德克宾!视频转换!x264enc!队列mp4mux name=mux!filesink location=myFile.mp4

当我在终端中执行此管道时,它工作正常。但我想用C-API实现这一点,因此我的源代码如下所示:

GstElement* pipeline;

GstElement* src;
GstElement* videoparse;
GstElement* decodebin;
GstElement* videoconvert;
GstElement* x264enc;
GstElement* queue;
GstElement* mp4mux;
GstElement* filesink;

pipeline = gst_pipeline_new("pipeline");

src = gst_element_factory_make("filesrc", NULL);
if(!src) {
    GST_WARNING("Error in: src");
}

g_object_set(G_OBJECT(src),"location","myVideo.yuv",NULL);
g_object_set(G_OBJECT(src),2073600,NULL);

videoparse = gst_element_factory_make("videoparse", NULL);
if(!videoparse) {
    GST_WARNING("Error in: videoparse");
}

g_object_set(G_OBJECT(videoparse),"width",1920,NULL);
g_object_set(G_OBJECT(videoparse),"height",1080,NULL);

decodebin = gst_element_factory_make("decodebin", NULL);
if(!decodebin) {
    GST_WARNING("Error in: decodebin");
}

videoconvert = gst_element_factory_make("videoconvert", NULL);
if(!videoconvert) {
    GST_WARNING("Error in: videoconvert");
}   

x264enc = gst_element_factory_make("x264enc", NULL);
if(!x264enc) {
    GST_WARNING("Error in: x264enc");
}    

queue = gst_element_factory_make("queue", NULL);
if(!queue) {
    GST_WARNING("Error in: queue");
}     

mp4mux = gst_element_factory_make("mp4mux", NULL);
if(!mp4mux) {
    GST_WARNING("Error in: mp4mux");
}     

g_object_set(G_OBJECT(mp4mux),"name","mux",NULL);

filesink = gst_element_factory_make("filesink", NULL);
if(!filesink) {
    GST_WARNING("Error in: filesink");
}     

g_object_set(G_OBJECT(filesink),"location","myFile.mp4",NULL);

gst_bin_add_many(GST_BIN(pipeline),src,videoparse,decodebin,videoconvert,x264enc,queue,mp4mux,filesink, NULL);

gst_element_link(src, videoparse);
gst_element_link(videoparse, decodebin);
gst_element_link(decodebin, videoconvert);
gst_element_link(videoconvert, x264enc);
gst_element_link(x264enc, queue);
gst_element_link(queue, mp4mux);
gst_element_link(mp4mux, filesink);

gst_element_set_state(pipeline, GST_STATE_PLAYING);

sleep(40);
正如我所说,终端中的管道工作正常,但C实现只创建一个空mp4文件。我不明白为什么

如果可能有帮助的话:原始视频文件的录制也已使用GStreamer完成。用于此目的的管道是:

gst-launch-1.0-e v4l2src设备=/dev/video0 num buffers=300!队列图像/jpeg,宽度=1920,高度=1080,帧速率=30/1!jpegdec!视频/x-raw,格式=I420,宽度=1920,高度=1080,帧速率=30/1!filesink location=myVideo.yuv


我想知道是否有人能看到我犯的错误,或者是否有人面临类似的问题。

您没有检查任何函数的返回值。链接元素可能会失败,例如,设置状态

在您的情况下,问题是a)将decodebin链接到videoconvert(它有时有pad,您需要连接到“pad added”信号并从那里链接,检查GStreamer文档),b)将队列链接到mp4mux(它有请求pad,您必须使用gst_元素\u get_request_pad()来获得正确的pad)


或者,您可以使用C中的gst_parse_launch()并传入管道字符串。它将为您提供一个与gst-launch-1.0工具创建的管道等效的管道,它将在内部完成我上面提到的两件事,而您无需担心这一点。

g_对象集(g_对象(src),“location”,myVideo.yuv,NULL);你能解释一下myVideo.yuv的价值吗?应该是字符串。对不起,这是我这边的错误。我用静态名称和数字替换了所有变量,以保持论坛的可读性。在这一点上,我还应该提到gst_init(NULL,NULL);也已经叫了。无论如何,这不是问题所在。我发现视频解析似乎是麻烦制造者。我试图用rawvideoparse来代替它,但没有成功。我不知道我的实现会出什么问题。