2

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

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

当我打开视频流时,它是格式的“原始视频”(根据其long_nameAV_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,除了linesize之外,我觉得没什么奇怪的av_frameav_frame->linesize[0] == -1920(linesize[1]并且linesize[2]是 0 的预期BGR24)。由于我的框架宽度是 640,我预计是 1920,但负号似乎很奇怪。我试过翻转标志,但没有帮助。我应该注意,它不会每次都崩溃(有些运行它首先会通过几帧)。

为什么 linesize 是负数?这是否意味着什么,或者只是以某种方式搞砸了?

4

1 回答 1

2

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

与负的biHeight(他们做的)相反,负的linesize不会与负的biWidth(他们没有讨论)相对应吗?

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

于 2016-04-08T16:28:57.917 回答