YUV数据的复制
2024-07-03
21
0
YUV数据的复制,详见:https://www.pnpon.com/article/detail-712.html
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->trc = src->trc;
dst->full_range = src->full_range;
dst->max_luminance = src->max_luminance;
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:
case VIDEO_FORMAT_I010: {
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:
case VIDEO_FORMAT_P010: {
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:
case VIDEO_FORMAT_I210:
case VIDEO_FORMAT_I412:
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:
case VIDEO_FORMAT_V210:
case VIDEO_FORMAT_R10L:
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:
case VIDEO_FORMAT_YA2L:
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;
case VIDEO_FORMAT_P216:
case VIDEO_FORMAT_P416:
/* Unimplemented */
break;
}
}
关于数据的复制copy_frame_data_plane
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];//src起始位置
uint32_t pos_dst = y * dst->linesize[plane];//dest起始位置
uint32_t minbytes = dst->linesize[plane] < src->linesize[plane] //最小复制字节数
? dst->linesize[plane]
: src->linesize[plane];
memcpy(dst->data[plane] + pos_dst, src->data[plane] + pos_src, minbytes);
}
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);
}
}