美文网首页
ffmpeg播放视频的部分方法解析

ffmpeg播放视频的部分方法解析

作者: YocnZhao | 来源:发表于2021-08-24 19:38 被阅读0次

ffmpeg播放视频的部分方法解析

  • ANativeWindow_Buffer->stride

The number of *pixels* that a line in the buffer takes in memory. This may be >= width.
图像的一行在内存里占的空间,做了对齐,可能比宽度大一些。比如宽高为544 * 960的视频下stride可能为576,所以在向m_NativeWindowBuffer.bits中拷贝图像数据的时候需要考虑此步长数据,每次向m_NativeWindowBuffer.bits中拷贝544个bytes,需要占据576个bytes空间。

也就是:

memcpy(dstBuffer + i * 576 * x, srcBuffer + i * 544 * x, 544 * x);

x:如果是RGBA_8888格式,x=4,如果是RGB_565,则x=2.

  • AVFrame->linesize的赋值

linesize存储的是图像的尺寸,不是一个固定值,是根据格式来的。
一个宽高为544 * 960的视频,在常见的格式下:

\ linesize[0] linesize[1] linesize[2] linesize[3]
YUV420P 544 272 272 0
RGB_565 1088 0 0 0
RGBA_8888 2176 0 0 0
  • av_image_fill_arrays的作用

在使用的时候一般是这样:

    int bufferSize = av_image_get_buffer_size(AV_PIX_FMT_RGB565LE, m_VideoWidth, m_VideoHeight, 1);
    auto *m_FrameBuffer = (uint8_t *) av_malloc(bufferSize * sizeof(uint8_t));
    av_image_fill_arrays(m_RGBAFrame->data, m_RGBAFrame->linesize, m_FrameBuffer,
                         AV_PIX_FMT_RGB565LE, m_VideoWidth, m_VideoHeight, 1);

根据需要的显示类型和视频的宽高计算出需要的缓冲区bufferSize的大小,申请一块bufferSize大小的内存,然后使用av_image_fill_arrays,然后传入了我们拿来接收配置的的m_RGBAFrame和新申请的m_FrameBuffer
这个函数的作用其实是将AVFramem_FrameBuffer绑定在了一起,然后设置了对应的data和linesize数据。
我们可以查看这个函数的源码:

int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4],
                         const uint8_t *src, enum AVPixelFormat pix_fmt,
                         int width, int height, int align)
{
    int ret, i;

    ret = av_image_check_size(width, height, 0, NULL);
    if (ret < 0)
        return ret;

    ret = av_image_fill_linesizes(dst_linesize, pix_fmt, width);
    if (ret < 0)
        return ret;

    for (i = 0; i < 4; i++)
        dst_linesize[i] = FFALIGN(dst_linesize[i], align);

    return av_image_fill_pointers(dst_data, pix_fmt, height, (uint8_t *)src, dst_linesize);
}

int av_image_fill_pointers(uint8_t *data[4], enum AVPixelFormat pix_fmt, int height,
                           uint8_t *ptr, const int linesizes[4])
{
    int i, ret;
    ptrdiff_t linesizes1[4];
    size_t sizes[4];

    memset(data     , 0, sizeof(data[0])*4);

    for (i = 0; i < 4; i++)
        linesizes1[i] = linesizes[i];

    ret = av_image_fill_plane_sizes(sizes, pix_fmt, height, linesizes1);
    if (ret < 0)
        return ret;

    ret = 0;
    for (i = 0; i < 4; i++) {
        if (sizes[i] > INT_MAX - ret)
            return AVERROR(EINVAL);
        ret += sizes[i];
    }

    data[0] = ptr;
    for (i = 1; i < 4 && sizes[i]; i++)
        data[i] = data[i - 1] + sizes[i - 1];

    return ret;
}

发现其实把ptr也就是src赋值给了data[0],其实m_FrameBuffer传进来之后就打酱油坐了个赋值。

AVFrame中data与linesize关系

相关文章

网友评论

      本文标题:ffmpeg播放视频的部分方法解析

      本文链接:https://www.haomeiwen.com/subject/bseeiltx.html