您的位置:首页 > 其它

FFmpeg av_image_fill_arrays填充AVFrame数据缓冲

2019-11-12 16:09 2791 查看

需求

        创建一个BGR24的AVFrame帧,用于YUV420转换BGR24帧


代码

  AVFrame *pBGRFrame = NULL;
  pBGRFrame = av_frame_alloc();
  uint8_t *pszBGRBuffer = NULL;
  int nBGRFrameSize;
  nBGRFrameSize = av_image_get_buffer_size(AV_PIX_FMT_BGR24, pVideoc->m_pAVCodecContext->width, pVideoc->m_pAVCodecContext->height, 1);
  pszBGRBuffer = (uint8_t*)av_malloc(nBGRFrameSize);
  av_image_fill_arrays(pBGRFrame->data, pBGRFrame->linesize, pszBGRBuffer, AV_PIX_FMT_BGR24, pFrame->width, pFrame->height, 1);


旧版本函数
int avpicture_fill(AVPicture *picture, uint8_t *ptr,
                   int pix_fmt, int width, int height);


这个函数的使用本质上是为已经分配的空间的结构体AVPicture挂上一段用于保存数据的空间,这个结构体中有一个指针数组data[4],挂在这个数组里。一般我们这么使用:
1) pFrameRGB=avcodec_alloc_frame();
2) numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,pCodecCtx->height);
    buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
3) avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,pCodecCtx->width, pCodecCtx-         >height);
以上就是为pFrameRGB挂上buffer。这个buffer是用于存缓冲数据的。
好,现在让我们来看一下tutorials里常出现的pFrame为什么不用fill空间。主要是下面这句:
avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,packet.data, packet.size);


1.int avpicture_fill(AVPicture *picture, const uint8_t *ptr,enum AVPixelFormat pix_fmt, int width, int height);
这个函数的作用是给 picture挂上存放数据的代码。在对帧数据进行scale之前,对于接受数据的picture(等同AVFrame)要用av_frame_alloc()初始化,但AVFrame::data需要手动初始化,即挂上内存,在scale的时候是直接在data里写入数据的。但在接收解码数据时,只需要av_frame_alloc(),不用手动挂内存
2.AVFrame的内存释放问题
在用AVFrame循环接受视频的帧数据的时候,或者批量读取图片量比较大的时候,不释放AVFrame会报指针越界错误,在我添加了av_free()并释放了AVFrame指针后,发现报错时间延后了,但任然有指针越界导致的报错,调试后发现,av_free()并没有释放AVFrame中data[x]指向的 数据,仅仅是把data本身指向的数据释放了,但其作为二级指针指向的数据跳过了,需要手动释放,添加 av_free(AVFrame->data[0])后问题解决。
总结       
av_free( AVFrame* )                                              对应    av_frame_alloc()   
av_free( AVFrame->data[0] )  或者av_free( ptr* )  对应   avpicture_fill 函数或者 avcodec_encode_video2()
    


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: