FFmpeg中AVFrame中data与linesize的联系

论坛 期权论坛 脚本     
匿名网站用户   2020-12-21 08:15   77   0

问题描述:

通过以下代码获取到pFrame帧数据(即AVFrame结构体),将pFrame内的帧数据通过memcpy函数复制给已经分配好内存的Buffer中,发现总是报错,错误现象由两种首先是访问越界,其次是图像数据不对,其图像如下所示。

//AVFrame用于存储解码后的像素数据(YUV)
 //内存分配
 AVFrame *pFrame = av_frame_alloc();

 int ret = -1;
 int frame_count = 0;

 //6.一帧一帧的读取压缩数据
 while (av_read_frame(pFormatCtx, packet) >= 0)
 {
  //只要视频压缩数据(根据流的索引位置判断)
  if (packet->stream_index == v_stream_idx)
  {
   //7.解码一帧视频压缩数据,得到视频像素数据
   ret = avcodec_send_packet(pEnc, packet);
   //ret = avcodec_decode_video2(pEnc, pFrame, &got_picture, packet);
   if (ret < 0)
   {
    printf("%s", "解码错误");
    return -1;
   }

   ret = avcodec_receive_frame(pEnc, pFrame);

原因分析:

linesize[0] 指定了每行的字节数,而不是图像的大小。原始视频分辨率为720*576,而linesize[0] 为768,因为linesize是指每一行占多少字节,可能比宽度nwidth要大,它是根据cpu来对齐的,可能是16或32的整数倍,不同的cpu有不同的对齐方式导致的。

解决方法:

通过以下代码进行转换,最终访问越界错误消失,图像数据正常。

for (int j = 0, cont = 0; j < TL_NUM_DATA_POINTERS && cont < src_buf_len; j++ )
{
    int size = pFrame->linesize[j];

 if (size <= 0) break;
 int radio = pFrame->linesize[0] / size;
 for (int i = 0; i < pFrame->height / radio; i++)
 {
  memcpy(src_frame.m_pBuf + cont, pFrame->data[j] + i * size, pFrame->width / radio);
  cont += pFrame->width / radio;
 }
}

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1136255
帖子:227251
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP