AVFrame 的线宽为负
AVFrame has a negative linesize
我正在使用 libav(为 MSVC 构建的 2.7)使用 dshow 打开相机:
input_format = av_find_input_format("dshow");
avformat_open_input(format_context, "video=Integrated Camera", input_format, 0);
当我打开视频流时,它是格式 AV_PIX_FMT_BGR24
的“原始视频”(根据其 long_name
)。我需要在 AV_PIX_FMT_RGB24
中有框架,所以我制作了一个 SwsContext 如下:
sws_context = sws_getContext(codec_context->width, codec_context->height, codec_context->pix_fmt,
codec_context->width, codec_context->height, AV_PIX_FMT_RGB24,
SWS_BICUBIC, 0, 0, 0);
av_picture = new AVPicture();
avpicture_alloc(av_picture, AV_PIX_FMT_RGB24, codec_context->width, codec_context->height);
然后我有一个循环计时器来读取帧并解码成一个 AVFrame,然后将其传递给 sws_scale。
while(av_read_frame(format_context, &packet) >= 0)
{
if(packet.stream_index == stream_index)
{
av_frame = 0;
av_frame = av_frame_alloc();
avcodec_decode_video2(codec_context, av_frame, &frame_finished, &packet);
if(frame_finished)
{
sws_scale(sws_context, (const uint8_t * const *)av_frame->data, av_frame->linesize,
0, codec_context->height, av_picture->data, av_picture->linesize);
av_free_packet(&packet);
return;
}
}
av_free_packet(&packet);
}
此后我将在我的应用程序中使用 av_picture
,但是 sws_scale
挂起并崩溃。查看我进入 sws_scale
的所有数据,除了 av_frame
的 linesize 之外,我觉得没有什么奇怪的。 av_frame->linesize[0] == -1920
(linesize[1]
和 linesize[2]
为 0,正如 BGR24
预期的那样)。由于我的框架宽度是 640,我希望是 1920,但负号看起来很奇怪。我试过翻转标志,但没有用。我应该注意到它不会每次都崩溃(有些运行它会先通过几帧)。
为什么linesize会是负数?这意味着什么还是只是搞砸了?
Windows 中用于位图和视频的标准 RGB 行顺序是从下到上(AFAIR 只有相对较新的 API,如 WIC 和 Direct2D,其中行以自然方式重新排序)。线条从上到下的顺序由负高度表示,基本上很少见。这个行顺序没有错,指向 "first pixel" 的指针指向最后一行最左边的像素,然后你在行之间前进负偏移量。 libswscale
处理得很好。
Wouldn't a negative linesize correspond with a negative biWidth (which they do not discuss) as opposed to a negative biHeight (which they do)?
不,惯例是这样的:如果biHeight
是负数,那么它减去行数并且行的顺序是相反的。 biWidth
始终为正(biWidth
负责携带另一个扩展:它可能会被放大为指示的非标准扩展步幅,以防有效载荷图像右侧有填充)。
我正在使用 libav(为 MSVC 构建的 2.7)使用 dshow 打开相机:
input_format = av_find_input_format("dshow");
avformat_open_input(format_context, "video=Integrated Camera", input_format, 0);
当我打开视频流时,它是格式 AV_PIX_FMT_BGR24
的“原始视频”(根据其 long_name
)。我需要在 AV_PIX_FMT_RGB24
中有框架,所以我制作了一个 SwsContext 如下:
sws_context = sws_getContext(codec_context->width, codec_context->height, codec_context->pix_fmt,
codec_context->width, codec_context->height, AV_PIX_FMT_RGB24,
SWS_BICUBIC, 0, 0, 0);
av_picture = new AVPicture();
avpicture_alloc(av_picture, AV_PIX_FMT_RGB24, codec_context->width, codec_context->height);
然后我有一个循环计时器来读取帧并解码成一个 AVFrame,然后将其传递给 sws_scale。
while(av_read_frame(format_context, &packet) >= 0)
{
if(packet.stream_index == stream_index)
{
av_frame = 0;
av_frame = av_frame_alloc();
avcodec_decode_video2(codec_context, av_frame, &frame_finished, &packet);
if(frame_finished)
{
sws_scale(sws_context, (const uint8_t * const *)av_frame->data, av_frame->linesize,
0, codec_context->height, av_picture->data, av_picture->linesize);
av_free_packet(&packet);
return;
}
}
av_free_packet(&packet);
}
此后我将在我的应用程序中使用 av_picture
,但是 sws_scale
挂起并崩溃。查看我进入 sws_scale
的所有数据,除了 av_frame
的 linesize 之外,我觉得没有什么奇怪的。 av_frame->linesize[0] == -1920
(linesize[1]
和 linesize[2]
为 0,正如 BGR24
预期的那样)。由于我的框架宽度是 640,我希望是 1920,但负号看起来很奇怪。我试过翻转标志,但没有用。我应该注意到它不会每次都崩溃(有些运行它会先通过几帧)。
为什么linesize会是负数?这意味着什么还是只是搞砸了?
Windows 中用于位图和视频的标准 RGB 行顺序是从下到上(AFAIR 只有相对较新的 API,如 WIC 和 Direct2D,其中行以自然方式重新排序)。线条从上到下的顺序由负高度表示,基本上很少见。这个行顺序没有错,指向 "first pixel" 的指针指向最后一行最左边的像素,然后你在行之间前进负偏移量。 libswscale
处理得很好。
Wouldn't a negative linesize correspond with a negative biWidth (which they do not discuss) as opposed to a negative biHeight (which they do)?
不,惯例是这样的:如果biHeight
是负数,那么它减去行数并且行的顺序是相反的。 biWidth
始终为正(biWidth
负责携带另一个扩展:它可能会被放大为指示的非标准扩展步幅,以防有效载荷图像右侧有填充)。