从YUV420p数据构造AVFrame

4 篇文章 0 订阅

前言

书接上文,发现 YUV420p各个通道不一致的问题后。就猜测FFmpeg里面应该对这点做了处理了吧

自己构造AVFrame

ffmepg里面的demo,encode_video.c,里面已经有了,我稍微修改了下。
网上很多构造AVFrame视频帧的代码已经过时了。

void ProducerScreenCapture::appendYuvFrame(char *yData,int yPerRowBytes,
                    char *uData,int uPerRowBytes,
                    char *vData,int vPerRowBytes,
                    int frameWidth,int frameHeight)
{
    AVFrame *t_pFrame = av_frame_alloc();//av_frame_free()
    t_pFrame->width = frameWidth;
    t_pFrame->height = frameHeight;
    t_pFrame->format = AV_PIX_FMT_YUV420P;
    int t_ret = av_frame_get_buffer(t_pFrame,32);//申请了AVFrame的内存
    if(t_ret < 0)
    {
        qDebug()<<"robin:av_frame_get_buffer,Could not allocate the video frame data";
        return;
    }
    av_frame_make_writable(t_pFrame);


    av_image_copy_plane(t_pFrame->data[0],t_pFrame->linesize[0],(const uint8_t*)yData,yPerRowBytes,yPerRowBytes,frameHeight);
    av_image_copy_plane(t_pFrame->data[1],t_pFrame->linesize[1],(const uint8_t*)uData,uPerRowBytes,yPerRowBytes / 2,frameHeight);
    av_image_copy_plane(t_pFrame->data[2],t_pFrame->linesize[2],(const uint8_t*)vData,vPerRowBytes,yPerRowBytes / 2,frameHeight);

... 保存起来

发现一个函数av_image_copy_plane,很是不明白。

/**
 * Copy image plane from src to dst.
 * That is, copy "height" number of lines of "bytewidth" bytes each.
 * The first byte of each successive line is separated by *_linesize
 * bytes.
 *
 * bytewidth must be contained by both absolute values of dst_linesize
 * and src_linesize, otherwise the function behavior is undefined.
 *
 * @param dst_linesize linesize for the image plane in dst
 * @param src_linesize linesize for the image plane in src
 */
void av_image_copy_plane(uint8_t       *dst, int dst_linesize,
                         const uint8_t *src, int src_linesize,
                         int bytewidth, int height);

看了函数说明还是不太明白
后来,看了源代码,就知道了

void av_image_copy_plane(uint8_t       *dst, int dst_linesize,
                           const uint8_t *src, int src_linesize,
                           int bytewidth, int height)
  {
      image_copy_plane(dst, dst_linesize, src, src_linesize, bytewidth, height);
  }
******************************************
******************************************
static void image_copy_plane(uint8_t *dst, ptrdiff_t dst_linesize,
const uint8_t *src, ptrdiff_t src_linesize,
ptrdiff_t bytewidth, int height)
{
   if (!dst || !src)
       return;
   av_assert0(abs(src_linesize) >= bytewidth);
   av_assert0(abs(dst_linesize) >= bytewidth);
   for (;height > 0; height--) {
       memcpy(dst, src, bytewidth);
       dst += dst_linesize;
       src += src_linesize;
   }
}

void av_image_copy_plane(uint8_t       *dst, int dst_linesize,
                           const uint8_t *src, int src_linesize,
                           int bytewidth, int height)

其中 bytewidth 才是每次实际要复制的数据长度。
而 dst_linesize 和 src_linesize 则是为了内存对齐数据而存在的。
从这里可以看出,内存数据的循环复制还是免不了啊。^o^

总结

AVFrame 进化了这么些年,现在已经提供了更简洁的方式申请内存空间
av_image_copy_plane,提供了通道数据的复制功能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值