0

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

因此,我将其替换AV_PIX_FMT_MONOWHITE为根据http://libav.org/doxygen/master/pixfmt_8h.htmlAV_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);
  }
}

HEIGHTx WIDTH= 80x60 时,这个版本产生 红到蓝条纹的截图,当我期望一个蓝色到红色的水平渐变时。

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

640x640、160x160 等,产生列,青色/洋红色/黄色,具有相同的水平条纹。

垂直渐变的表现更加怪异。

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

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

访问 AVFrame的每个像素都会以较少的细节提出相同的问题,目前尚未得到解答。

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

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

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

4

2 回答 2

2

avpicture_fill()如使用FFMPEG 将屏幕截图编码为视频中所述使用

不要data直接传递给sws_scale(),而是这样做:

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

然后将第二个和第三个参数替换sws_scale()

pic->data, pic->linesize,

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

于 2013-05-14T19:32:20.567 回答
1

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

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

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

于 2013-05-15T06:39:23.253 回答