我试着做一个程序,合并两个帧。我在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;
}
失真消失了,颜色又回来了!