AVFrame有一个负线条

时间:2016-04-08 15:49:40

标签: c++ libavcodec libavformat ffdshow swscale

我使用libav(2.7为MSVC构建)使用dshow打开相机:

input_format = av_find_input_format("dshow");
avformat_open_input(format_context, "video=Integrated Camera", input_format, 0);

当我打开视频流时,它是"原始视频" (根据其long_name)格式为AV_PIX_FMT_BGR24。我需要在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->linsize[0] == -1920(对于BGR24,预期1和2为0)。由于我的帧的宽度是640,我预计1920年,但负号似乎很奇怪。我试过翻转标志,但没有帮助。我应该注意它每次都不会崩溃(有些运行它首先通过几帧)。

为什么线条化为负数?它是什么意思还是只是搞砸了?

1 个答案:

答案 0 :(得分:2)

Windows中用于位图和视频的标准RGB线路排序是自下而上的(AFAIR它只是相对新鲜的API,如WIC和Direct2D,其中线路以自然方式重新排序)。线的从上到下的顺序由负高度表示,基本上很少见。这个行顺序没有任何问题,指向“第一个像素”的指针指向最后一行的最左边的像素,然后通过负偏移在行之间前进。 libswscale处理这件事。

  

负的线条大小不会与负的biWidth(他们没有讨论)相对应,而不是负的biHeight(他们这样做)吗?

不,惯例是这样的:如果biHeight为负,则它减去行数并且行的顺序相反。 biWidth始终为正(biWidth负责携带另一个扩展:如果从有效负载图像右侧有填充,则可能会扩大到指示非标准扩展步幅。)