obs_source_frame数据拷贝
2025-05-30
0
0
static inline void copy_frame_data_line(struct obs_source_frame *dst,
const struct obs_source_frame *src,
uint32_t plane, uint32_t y)
{
uint32_t pos_src = y * src->linesize[plane];
uint32_t pos_dst = y * dst->linesize[plane];
uint32_t bytes = dst->linesize[plane] < src->linesize[plane]
? dst->linesize[plane]
: src->linesize[plane];
//uint32_t bytes = min(dst->linesize[plane], src->linesize[plane]);
memcpy(dst->data[plane] + pos_dst, src->data[plane] + pos_src, bytes);
}
static inline void copy_frame_data_plane(struct obs_source_frame *dst,
const struct obs_source_frame *src,
uint32_t plane, uint32_t lines)
{
if (dst->linesize[plane] != src->linesize[plane]) {
for (uint32_t y = 0; y < lines; y++)
copy_frame_data_line(dst, src, plane, y);
} else {
memcpy(dst->data[plane], src->data[plane],
(size_t)dst->linesize[plane] * (size_t)lines);
}
}
使用方法:
static void copy_frame_data(struct obs_source_frame *dst,
const struct obs_source_frame *src)
{
dst->flip = src->flip;
dst->flags = src->flags;
dst->full_range = src->full_range;
dst->timestamp = src->timestamp;
memcpy(dst->color_matrix, src->color_matrix, sizeof(float) * 16);
if (!dst->full_range) {
size_t const size = sizeof(float) * 3;
memcpy(dst->color_range_min, src->color_range_min, size);
memcpy(dst->color_range_max, src->color_range_max, size);
}
switch (src->format) {
case VIDEO_FORMAT_I420: {
const uint32_t height = dst->height;
const uint32_t half_height = (height + 1) / 2;
copy_frame_data_plane(dst, src, 0, height);
copy_frame_data_plane(dst, src, 1, half_height);
copy_frame_data_plane(dst, src, 2, half_height);
break;
}
case VIDEO_FORMAT_NV12: {
const uint32_t height = dst->height;
const uint32_t half_height = (height + 1) / 2;
copy_frame_data_plane(dst, src, 0, height);
copy_frame_data_plane(dst, src, 1, half_height);
break;
}
case VIDEO_FORMAT_I444:
case VIDEO_FORMAT_I422:
copy_frame_data_plane(dst, src, 0, dst->height);
copy_frame_data_plane(dst, src, 1, dst->height);
copy_frame_data_plane(dst, src, 2, dst->height);
break;
case VIDEO_FORMAT_YVYU:
case VIDEO_FORMAT_YUY2:
case VIDEO_FORMAT_UYVY:
case VIDEO_FORMAT_NONE:
case VIDEO_FORMAT_RGBA:
case VIDEO_FORMAT_BGRA:
case VIDEO_FORMAT_BGRX:
case VIDEO_FORMAT_Y800:
case VIDEO_FORMAT_BGR3:
case VIDEO_FORMAT_AYUV:
copy_frame_data_plane(dst, src, 0, dst->height);
break;
case VIDEO_FORMAT_I40A: {
const uint32_t height = dst->height;
const uint32_t half_height = (height + 1) / 2;
copy_frame_data_plane(dst, src, 0, height);
copy_frame_data_plane(dst, src, 1, half_height);
copy_frame_data_plane(dst, src, 2, half_height);
copy_frame_data_plane(dst, src, 3, height);
break;
}
case VIDEO_FORMAT_I42A:
case VIDEO_FORMAT_YUVA:
copy_frame_data_plane(dst, src, 0, dst->height);
copy_frame_data_plane(dst, src, 1, dst->height);
copy_frame_data_plane(dst, src, 2, dst->height);
copy_frame_data_plane(dst, src, 3, dst->height);
break;
}
}