gpt4 book ai didi

c++ - 使用 gstreamer 将 jpeg 混合到 mkv

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:23:21 25 4
gpt4 key购买 nike

情况:

当我尝试将 jpeg 多路复用到 mkv 文件时,我会得到一个大小为零的文件。我必须将编码和解码元素放在解析器和多路复用器之间以获得正确的输出。当我使用相同的代码混合 h264 视频时,我会得到正确的视频文件,这意味着缓冲区的时间设置应该没问题(duration 和 pts 参数)。无论如何,在错误的缓冲区设置之后文件大小不为零。Matroskamux 只需要“image/jpeg”sink pad 的“width”和“heigth”功能,但看起来这还不够。 Jpegparse 给出了正确的值,并且在手动设置此功能后程序也无法运行。

管道示例:

这条管道不起作用

appsrc ! "image/jpeg" ! jpegparse ! matroskamux ! filesink location=mjpeg.mkv

但这行得通

appsrc ! "image/jpeg" ! jpegparse ! avdec_mjpeg ! x264enc ! matroskamux ! filesink location=mjpeg.mkv

代码示例:

工作代码,但重新编码

    app = new _App();

app->src = (GstAppSrc*)gst_element_factory_make ("appsrc", "source");

if(IsH264Frame(codecType))
app->parser = gst_element_factory_make("h264parse", "parser");
else if(codecType == IMAGE_MJPEG_FRAME)
app->parser = gst_element_factory_make("jpegparse", "parser");

//additional code
app->decoder = gst_element_factory_make("avdec_mjpeg", "decoder");
app->encoder = gst_element_factory_make("x264enc", "encoder");

app->muxer = gst_element_factory_make("matroskamux", "muxer");
app->sink = (GstAppSink*)gst_element_factory_make ("filesink", "sink");


if (!app->pipeline || !app->src || !app->decoder || !app->encoder || !app->muxer || !app->sink || !app->parser)
return;



app->bus = gst_pipeline_get_bus (GST_PIPELINE (app->pipeline));
g_assert(app->bus);
gst_bus_add_watch (app->bus, (GstBusFunc) BusMessage, this);


gst_bin_add_many (GST_BIN (app->pipeline), (GstElement*)app->src, app->decoder, app->encoder, app->muxer, app->sink, app->parser
,NULL);


/* SETUP ELEMENTS */


g_object_set(app->src,
"stream-type", 0,
"format", GST_FORMAT_BUFFERS,
"is-live", true,
"block", true,
NULL);

if(IsH264Frame(codecType)){

g_object_set(app->src, "caps", gst_caps_new_simple("video/x-h264",
NULL), NULL);

} else if(codecType == IMAGE_MJPEG_FRAME) {

g_object_set(app->src, "caps", gst_caps_new_simple("image/jpeg",
"framerate",GST_TYPE_FRACTION,(int)framerate,1,
NULL), NULL);

//additional code

g_object_set(app->decoder, "caps", gst_caps_new_simple("video/x-raw",
NULL), NULL);

g_object_set(app->encoder, "caps", gst_caps_new_simple("video/x-h264",
NULL), NULL);

}


g_signal_connect(app->src, "need-data", G_CALLBACK(StartFeed), this);
g_signal_connect(app->src, "enough-data", G_CALLBACK(StopFeed), this);


g_object_set (app->sink,
"location", GenerateFileName().c_str(),
"buffer-mode", 0,
NULL);


/* LINKING */


GstPad *padDecSrc, *padMuxSink, *parserSrc,
GstPadTemplate *mux_sink_pad_template;

mux_sink_pad_template = gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (app->muxer), "video_%u");
padMuxSink = gst_element_request_pad (app->muxer, mux_sink_pad_template, NULL, NULL);

parserSrc = gst_element_get_static_pad (app->parser, "src");
padEncSrc = gst_element_get_static_pad (app->encoder, "src");


if(!gst_element_link( (GstElement*)app->src, app->parser))
return;

if(IsH264Frame(codecType)){

if(gst_pad_link (parserSrc, padMuxSink) != GST_PAD_LINK_OK)
return;

} else if(codecType == IMAGE_MJPEG_FRAME){

//additional code
if(!gst_element_link( app->parser, app->decoder))
return;

if(!gst_element_link( app->decoder, app->encoder))
return;

if(gst_pad_link (padDecSrc, padMuxSink) != GST_PAD_LINK_OK)
return;

}

if(!gst_element_link( app->muxer, (GstElement*)app->sink))
return;


/* PLAY */


GstStateChangeReturn ret = gst_element_set_state (app->pipeline, GST_STATE_PLAYING);

if (ret == GST_STATE_CHANGE_FAILURE)
{
gst_object_unref (app->pipeline);
return;
}

问题:

我做错了什么?有解决这个问题的想法吗?

最佳答案

我通过将 appsrc 属性“格式”从 GST_FORMAT_BUFFERS 更改为 GST_FORMAT_TIME 解决了这个问题。正确的缓冲区时间戳是不够的。

关于c++ - 使用 gstreamer 将 jpeg 混合到 mkv,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20207687/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com