GStreamer文档中RU4含义及RGB格式参数与Buffer大小疑问
GStreamer RGB格式相关问题解答
背景信息
RGB格式定义
- "RGB" RGB
+--+--+--+ +--+--+--+ |R0|G0|B0| |R1|G1|B1| ... +--+--+--+ +--+--+--+ Component 0: R depth: 8 pstride: 3 offset: 0 Component 1: G depth: 8 pstride: 3 offset: 1 Component 2: B depth 8 pstride: 3 offset: 2 Image default rstride: RU4 (width * 3) default size: rstride (image) * height
调试代码(C++)
auto caps = gst_sample_get_caps(sample); GstVideoFrame cuda_frame; GstVideoInfo info; gst_video_info_from_caps(&info, caps); gst_video_frame_map(&cuda_frame, &info, buffer, (GstMapFlags) (GST_MAP_READ | GST_MAP_CUDA)); spdlog::debug("n components: {}, n plane: {}, frame size: {}, frame width: {}, frame height: {}", GST_VIDEO_FRAME_N_COMPONENTS(&cuda_frame), GST_VIDEO_FRAME_N_PLANES(&cuda_frame), GST_VIDEO_FRAME_SIZE(&cuda_frame), GST_VIDEO_FRAME_WIDTH(&cuda_frame), GST_VIDEO_FRAME_HEIGHT(&cuda_frame) ); for (size_t i = 0; i < GST_VIDEO_FRAME_N_COMPONENTS(&cuda_frame); i++) { spdlog::debug("[component {}] depth: {}, width: {}, height: {}, offset: {}, stride: {}, plane: {}, poffset: {}, pstride: {}", i, GST_VIDEO_FRAME_COMP_DEPTH(&cuda_frame, i), GST_VIDEO_FRAME_COMP_WIDTH(&cuda_frame, i), GST_VIDEO_FRAME_COMP_HEIGHT(&cuda_frame, i), GST_VIDEO_FRAME_COMP_OFFSET(&cuda_frame, i), GST_VIDEO_FRAME_COMP_STRIDE(&cuda_frame, i), GST_VIDEO_FRAME_COMP_PLANE(&cuda_frame, i), GST_VIDEO_FRAME_COMP_POFFSET(&cuda_frame, i), GST_VIDEO_FRAME_COMP_PSTRIDE(&cuda_frame, i) ); } for (size_t i = 0; i < GST_VIDEO_FRAME_N_PLANES(&cuda_frame); i++) { spdlog::debug("[plane {}] offset: {}, stride: {}", i, GST_VIDEO_FRAME_PLANE_OFFSET(&cuda_frame, i), GST_VIDEO_FRAME_PLANE_STRIDE(&cuda_frame, i) ); }
调试输出
n components: 3, n plane: 1, frame size: 150528, frame width: 224, frame height: 224 [component 0] depth: 8, width: 224, height: 224, offset: 0, stride: 1024, plane: 0, poffset: 0, pstride: 3 [component 1] depth: 8, width: 224, height: 224, offset: 1, stride: 1024, plane: 0, poffset: 1, pstride: 3 [component 2] depth: 8, width: 224, height: 224, offset: 2, stride: 1024, plane: 0, poffset: 2, pstride: 3
问题解答
1. 文档中的RU4代表什么含义?
RU4是Round Up to 4的缩写,指将计算值向上取整到最接近的4的整数倍。这是GStreamer中为满足内存对齐要求常用的处理方式,这里会把width * 3的结果调整为大于等于它的4的倍数。
2. pstride和rstride分别指什么?
- pstride(组件步长):同一组件中,相邻两个像素数据之间的字节间隔。对于RGB打包格式,每个像素占3字节,所以R/G/B组件的pstride都是3,即下一个同组件像素在当前像素的3字节之后。
- rstride(行步长):视频帧中同一列相邻两行像素数据的字节间隔,也就是一行像素占用的总字节数(包含对齐填充的无效字节)。文档里的默认rstride是
RU4(width*3),就是一行有效像素数据向上对齐到4的倍数后的结果。
3. Component的offset、stride、plane、poffset、pstride分别代表什么?
针对单平面RGB打包格式,各参数含义如下:
- offset:该组件数据在整个视频帧缓冲区中的起始字节偏移量。R是0,G是1,B是2,对应每个像素的三个通道位置。
- stride:该组件的行步长,即同一列相邻两行的组件数据之间的字节间隔,和所属平面的行步长一致(此处为1024)。
- plane:该组件所属的平面索引。因为是打包格式,R/G/B都在同一个平面,所以索引为0。
- poffset:该组件在所属平面内的起始字节偏移量,单平面场景下和offset数值一致。
- pstride:同pstride定义,即同一组件相邻像素的字节间隔,此处为3。
4. 计算的Buffer大小应为2242243=150528,与调试的frame size一致,但实际Buffer大小为2242244=229376,这是为什么?
这是内存对齐导致的:
GST_VIDEO_FRAME_SIZE返回的是视频帧的有效像素数据大小,即2242243=150528。- 实际缓冲区大小是按行步长(rstride)乘以高度计算的,你的调试输出中stride为1024,所以实际缓冲区大小是1024224=229376,刚好等于224224*4。
- 额外的填充字节是为了满足硬件(如CUDA、GPU)或系统内存的对齐要求,提升数据读写效率,这些填充字节属于缓冲区的一部分,但不属于有效像素数据。
内容的提问来源于stack exchange,提问作者vipcxj
相关产品推荐
相关产品推荐

