为ffmpeg编码设置RGB帧的各个像素

时间:2013-05-14 19:04:24

标签: c++ ffmpeg libav libavformat

我正在尝试将ffmpeg流媒体Trouble syncing libavformat/ffmpeg with x264 and RTP的测试模式更改为熟悉的RGB格式。我更广泛的目标是即时计算流视频的帧。

所以我根据http://libav.org/doxygen/master/pixfmt_8h.htmlAV_PIX_FMT_MONOWHITE替换为AV_PIX_FMT_RGB24,即“打包RGB 8:8:8,24bpp,RGBRGB ......”。

要填充名为data的像素数组,我在

上尝试了很多变体
for (int y=0; y<HEIGHT; ++y) {
  for (int x=0; x<WIDTH; ++x) {
    uint8_t* rgb = data + ((y*WIDTH + x) *3);
    const double i = x/double(WIDTH);
//  const double j = y/double(HEIGHT);
    rgb[0] = 255*i;
    rgb[1] = 0;
    rgb[2] = 255*(1-i);
  }
}

HEIGHT x WIDTH = 80x60,此版本产生 screenshot of red-to-blue stripes,当我期待一个蓝色到红色的水平渐变时。

640x480产生相同的4列模式,但具有更多的水平条纹。

640x640,160x160等,产生三个列,cyan-ish / magenta-ish / yellow-ish,具有相同类型的水平条纹。

垂直渐变表现得更奇怪。

外观不受AV_PIX_FMT_RGBA尝试的影响(每个像素4个不是3个字节,alpha = 255)。也不受从C到C ++的端口的影响。

传递给srcStrides的参数sws_scale()是一个长度为1的数组,包含单个int HEIGHT

Access each Pixel of AVFrame更详细地询问同一个问题,到目前为止还没有答案。

流光发出一个警告,我怀疑它会影响外观:

[rtp @ 0x269c0a0] Encoder did not produce proper pts, making some up.

因此。如何设置要发送到sws_scale()(然后再发送到x264_encoder_encode()和av_interleaved_write_frame())的帧中像素的RGB值?

2 个答案:

答案 0 :(得分:2)

Encoding a screenshot into a video using FFMPEG

中所述使用avpicture_fill()

不要将 data 直接传递给sws_scale(),而是执行此操作:

AVFrame* pic = avcodec_alloc_frame();
avpicture_fill((AVPicture *)pic, data, AV_PIX_FMT_RGB24, WIDTH, HEIGHT);

然后用

替换sws_scale()的第2和第3个参数
pic->data, pic->linesize,

然后,上面的渐变在很多分辨率下都能正常工作。

答案 1 :(得分:1)

  

传递给sws_scale()的参数srcStrides是一个长度为1的数组,包含单个int HEIGHT。

Stride(AKA linesize)是两行之间的字节距离。由于各种原因主要与优化有关,它通常大于简单的宽度(以字节为单位),因此每行的末尾都有填充。

在您的情况下,没有任何填充,步幅应为宽* 3。