我试着做一个程序,合并两个帧。我在Windows 7 64和Visual Studio 2013下使用LibAV(LibAV-win32-20140428)。
但结果很奇怪。
使用的过滤器是Overlay。当我把图表改成只使用一个流并添加淡入效果的图表时,一切都像一个符咒一样工作。但套印和抽框给了我奇怪的失真(一个三帧,黑白效果)。代码如下:

static int init_filter_graph(AVFilterGraph **pGraph, AVFilterContext **pSrc1, AVFilterContext **pSink)
{
    AVFilterGraph* tFilterGraph;
    AVFilterContext* tBufferContext1;
    AVFilter* tBuffer1;
    AVFilterContext* tColorContext;
    AVFilter* tColor;
    AVFilterContext* tOverlayContext;
    AVFilter* tOverlay;
    AVFilterContext* tBufferSinkContext;
    AVFilter* tBufferSink;

    int tError;

    /* Create a new filtergraph, which will contain all the filters. */
    tFilterGraph = avfilter_graph_alloc();

    if (!tFilterGraph) {
        return -1;
    }

    { // BUFFER FILTER 1
        tBuffer1 = avfilter_get_by_name("buffer");
        if (!tBuffer1) {
            return -1;
        }
        tBufferContext1 = avfilter_graph_alloc_filter(tFilterGraph, tBuffer1, "src1");
        if (!tBufferContext1) {
            return -1;
        }

        av_dict_set(&tOptionsDict, "width", "320", 0);
        av_dict_set(&tOptionsDict, "height", "240", 0);
        av_dict_set(&tOptionsDict, "pix_fmt", "bgr24", 0);
        av_dict_set(&tOptionsDict, "time_base", "1/25", 0);
        av_dict_set(&tOptionsDict, "sar", "1", 0);
        tError = avfilter_init_dict(tBufferContext1, &tOptionsDict);
        av_dict_free(&tOptionsDict);
        if (tError < 0) {
            return tError;
        }
    }

    { // COLOR FILTER
        tColor = avfilter_get_by_name("color");
        if (!tColor) {
            return -1;
        }
        tColorContext = avfilter_graph_alloc_filter(tFilterGraph, tColor, "color");
        if (!tColorContext) {
            return -1;
        }

        av_dict_set(&tOptionsDict, "color", "white", 0);
        av_dict_set(&tOptionsDict, "size", "20x120", 0);
        av_dict_set(&tOptionsDict, "framerate", "1/25", 0);
        tError = avfilter_init_dict(tColorContext, &tOptionsDict);
        av_dict_free(&tOptionsDict);
        if (tError < 0) {
            return tError;
        }
    }

    { // OVERLAY FILTER
        tOverlay = avfilter_get_by_name("overlay");
        if (!tOverlay) {
            return -1;
        }
        tOverlayContext = avfilter_graph_alloc_filter(tFilterGraph, tOverlay, "overlay");
        if (!tOverlayContext) {
            return -1;
        }

        av_dict_set(&tOptionsDict, "x", "0", 0);
        av_dict_set(&tOptionsDict, "y", "0", 0);
        av_dict_set(&tOptionsDict, "main_w", "120", 0);
        av_dict_set(&tOptionsDict, "main_h", "140", 0);
        av_dict_set(&tOptionsDict, "overlay_w", "320", 0);
        av_dict_set(&tOptionsDict, "overlay_h", "240", 0);
        tError = avfilter_init_dict(tOverlayContext, &tOptionsDict);
        av_dict_free(&tOptionsDict);
        if (tError < 0) {
            return tError;
        }
    }

    { // BUFFERSINK FILTER
        tBufferSink = avfilter_get_by_name("buffersink");
        if (!tBufferSink) {
            return -1;
        }

        tBufferSinkContext = avfilter_graph_alloc_filter(tFilterGraph, tBufferSink, "sink");
        if (!tBufferSinkContext) {
            return -1;
        }

        tError = avfilter_init_str(tBufferSinkContext, NULL);
        if (tError < 0) {
            return tError;
        }
    }

    // Linking graph
    tError = avfilter_link(tBufferContext1, 0, tOverlayContext, 0);
    if (tError >= 0) {
        tError = avfilter_link(tColorContext, 0, tOverlayContext, 1);
    }
    if (tError >= 0) {
        tError = avfilter_link(tOverlayContext, 0, tBufferSinkContext, 0);
    }
    if (tError < 0) {
        return tError;
    }

    tError = avfilter_graph_config(tFilterGraph, NULL);
    if (tError < 0) {
        return tError;
    }

    *pGraph = tFilterGraph;
    *pSrc1 = tBufferContext1;
    *pSink = tBufferSinkContext;

    return 0;
}

你认为原因是什么?

最佳答案

我从卢卡·巴巴托那里得到了一个提示:
你能试着用avconv复制吗?从图像上看像你
得到的像素格式不是你所期望的。

我发现,我需要使用LibAV's mailing list,以保持像素的格式相同。
所以我补充道:

{ // FORMAT FILTER
    tFormat = avfilter_get_by_name("format");
    if (!tFormat) {
        // Could not find the tFormat filter.
        return -1;
    }

    tFormatContext = avfilter_graph_alloc_filter(tFilterGraph, tFormat, "format");
    if (!tFormatContext) {
        // Could not allocate the tFormat instance.
        return -1;
    }

    av_dict_set(&tOptionsDict, "pix_fmts", "bgr24", 0);
    tError = avfilter_init_dict(tFormatContext, &tOptionsDict);
    av_dict_free(&tOptionsDict);
    if (tError < 0) {
        // Could not initialize the tFormat filter.
        return tError;
    }
}

在init_filter_graph函数中。
现在我的过滤图是这样的:
tError = avfilter_link(tBufferContext1, 0, tOverlayContext, 0);
if (tError >= 0)
{
    tError = avfilter_link(tColorContext, 0, tOverlayContext, 1);
}
if (tError >= 0)
{
    tError = avfilter_link(tOverlayContext, 0, tFormatContext, 0);
}
if (tError >= 0)
{
    tError = avfilter_link(tFormatContext, 0, tBufferSinkContext, 0);
}
if (tError < 0) { // Error connecting filters.
    return tError;
}

失真消失了,颜色又回来了!

08-17 00:16