我正在尝试将ffmpeg流媒体Trouble syncing libavformat/ffmpeg with x264 and RTP的测试模式更改为熟悉的RGB格式。我更广泛的目标是即时计算流视频的帧。
所以我根据http://libav.org/doxygen/master/pixfmt_8h.html将AV_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,此版本产生
,当我期待一个蓝色到红色的水平渐变时。
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值?
答案 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。