音视频代码模块
+ -

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);
    }
}

0 篇笔记 写笔记

I420/YU12/YUV420P/IYUV格式详解
I420介绍I420也叫YU12,也叫 IYUV,属于 YUV420P 格式。三个平面,分别存储 Y U V 分量。每四个 Y 分量共享一组 UV 分量。U、V 平面的 strides, width 和 height 都是 Y 平面的一半,因此一个像素 12 bits。I420字节大小4:2:0......
YUV格式简介
在计算机图形学中,使用最常见的就是RGB颜色。RGB 颜色使用三个值进行编码:红色、绿色和蓝色。 这些值直接对应于可见光谱的部分。 这三个 RGB 值构成数学坐标系,称为 颜色空间。 红色分量定义此坐标系的一个轴,蓝色定义第二个轴,绿色定义第三个轴。 任何有效的 RGB 颜色都位于此颜色空间中的某个......
YUV数据格式采样
经常说YUV422,YUV420等,前面的YUV我们知道是什么,后面的数字代表的是什么呢?其实后面的数字每一个代表Y的采样因子,后面2个表示UV在横坐标和竖坐标的采样因子。如以下图:X表示Y,圈代表UV。YUV的采样方式主要包括以下:YUV444 4:4:4:表示4:4:4的采样,表示完全取......
YUV格式分类
前面我们说的是按YUV比例因子分为YUV444,YUV422,YUV420和YUV411这些是按YUV数据的比例做了一个粗的分类,其决字一幅图其数据量的大小。但是这些YUV数据的组成顺序也就是内存排布顺序不同,又衍生了很多不同的格式。YUV按数据组织方式可分为2大类:YUV 的存储格式YUV 的存......
YV12格式详解
YV12(属于 YUV 420 Plannar)YV12 是 YUV 420 Planar 的一种,YUV 分量分别存放.先是 w * h 长度的 Y,后面跟 w/2 * h/2 长度的 V, 最后是 w/2 * h/2 长度的 U,总长度为 w * h * 1.5。与 I420 不同的是,YV......
NV12格式详解
NV12(属于 YUV 420 Semi-Planar) NV12 是 YUV 420 Semi-Planar 的一种,Y 分量单独存放,UV 分量交错存放,UV 在排列的时候,从 U 开始。总长度为 w * h * 1.5。NV12中的12代表每像素平均12位,即1.5个字节。先Y,再UV交替存......
NV21格式详解
NV21(属于 YUV 420 Semi-Planar).NV21 是 YUV 420 Semi-Planar 的一种,Y 分量单独存放,UV 分量交错存放,与 NV12 不同的是,UV 在排列的时候,从 V 开始。总长度为 w * h * 1.5。同样,对于一个6*4的图像,这四种像素格式的存......
I422/YUV422P格式详解
I422(属于 YUV 422 Plannar),又叫YUV422P 格式 I422 是 YUV 422 Planar 的一种,YUV 分量分别存放,先是 w * h 长度的 Y,后面跟 w * h * 0.5 长度的 U, 最后是 w* h * 0.5 长度的 V,总长度为 w * h * 2。......
YV16格式详解
YV16(属于 YUV 422 Plannar)YV16 是 YUV 422 Planar 的一种,YUV 分量分别存放,先是 w * h 长度的 Y,后面跟 w * h * 0.5 长度的 V, 最后是 w * h * 0.5 长度的 U,总长度为 w * h * 2。与 I422 不同的是,YV......
NV16格式详解
NV16(属于 YUV 422 Semi-Planar)NV16 是 YUV 422 Semi-Planar 的一种,Y 分量单独存放,UV 分量交错存放,UV 在排列的时候,从 U 开始。总长度为 w * h * 2。Y Y Y Y Y YY Y Y Y Y YY Y Y Y Y YY Y......
NV61格式详解
NV61(属于 YUV 422 Semi-Planar)NV61 是 YUV 422 Semi-Planar 的一种,Y 分量单独存放,UV 分量交错存放,UV 在排列的时候,从 V 开始。总长度为 w * h * 2。Y Y Y Y Y YY Y Y Y Y YY Y Y Y Y YY ......
YUVY格式详解
UVY(属于 YUV 422 Interleaved) YUVY 属于 YUV 422 Interleaved 的一种。事实上,Interleaved 是属于 Packed 的,但是在 422 中,用 Interleaved 更加形象一些。在 Packed 内部,YUV 的排列顺序是 Y U V Y......
VYUY格式详解
VYUY(属于 YUV 422 Interleaved) VYUY 属于 YUV 422 Interleaved 的一种。在 Packed 内部,YUV 的排列顺序是 VYUY,两个 Y 共用一组 UV。V Y U Y V Y U Y V Y U YV Y U Y V Y U Y ......
UYVY格式详解
UYVY(属于 YUV 422 Interleaved) UYVY 属于 YUV 422 Interleaved 的一种。在 Packed 内部,YUV 的排列顺序是 UYVY,两个 Y 共用一组 UV。U Y V Y U Y V Y U Y V YU Y V Y U Y V Y ......
I444格式详解
I444(属于 YUV 444 Plannar) I444 属于 YUV 444 Plannar 的一种。YUV 分量分别存放,先是 w * h 长度的 Y,后面跟 w * h 长度的 U, 最后是 w * h 长度的 V,总长度为 w * h * 3。Y Y Y Y Y YY Y Y Y Y ......
作者信息
站长漫谈
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!