4

情况:

当我尝试将 jpeg 多路复用到 mkv 文件时,我会得到一个零大小的文件。我必须在解析器和复用器之间放置编码和解码元素以获得正确的输出。当我用相同的代码混合 h264 视频时,我会得到正确的视频文件,这意味着缓冲区的时间设置应该是好的(持续时间和 pts 参数)。无论如何,在缓冲区设置错误之后,文件的大小不为零。Matroskamux 只需要接收器上的“image/jpeg”“宽度”和“高度”功能,但看起来这还不够。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;
    }

问题:

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

4

1 回答 1

0

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

于 2014-07-07T21:29:09.740 回答