AVFrame与mat互转代码
AVFrame转mat:
```cpp
AVFrame *frame;
Mat mat(frame->height, frame->width, CV_8UC3);
for (int i = 0; i < frame->height; ++i) {
memcpy(mat.data + i * frame->linesize[0], frame->data[0] + i * frame->linesize[0], frame->width * 3);
}
```
Mat转AVFrame:
```cpp
Mat mat;
AVFrame* out_frame = av_frame_alloc(); //申请一个AVFrame结构体,里面有data等信息
int numBytes = avpicture_get_size(AV_PIX_FMT_BGR24, mat.cols, mat.rows); //申请内存大小,根据像素格式、宽、高来获得。这里的内存分配是一次性分配好的。
uint8_t* buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t)); //numBytes为图像数据的大小;将buffer作为AVFrame中的数据部分。
//其他参数赋值 如 像素格式 等 AVFormatContext...... 省略....
//将Mat中的图片复制到buffer中去 注意必须是连续存储在buffer中去 不能出现断裂情况 这里使用opencv函数来实现复制功能 也可以使用memcpy函数来实现复制功能。 注意此时效果是BGR格式而不是RGB格式了。 opencv2.4版本之后Mat对象可以直接copyTo()出来了 opencv2.4之前要使用IplImage对象来copyTo()出来所以我这里就直接使用IplImage了 IplImage img=mat; img.imageData=buffer; cvCopy(&img,&img); //将图片复制过去吧~ 这里注意opencv2.4之前要使用IplImage对象所以上面我先声明了一个IplImage对象然后将其数据部分imageData都处理成buffer地址然后再copyTo()就行了。 注意此时效果是BGR格式而不是RGB格式了。 如有必要可以在上面修正一下代码即可实现RGB-->BGR的功能。 这里注意opencv2.4之前要使用IplImage对象所以上面我先声明了一个IplImage对象然后将其数据部分imageData都处理成buffer地址然后再copyTo()就行了。 outbuf=outbuf+imgSize; //outbuf也要往前++ 因为FFMPEG库会依此得出YUV420P三通道图片 YUV420P三通道图片会占3/2倒數佔原始图片大小 所令outbuf+=imgSize/2也行 outbuf+=numBytes; //outbuf也要往前++ 因为FFMPEG库会依此得出YUV420P三通道图片 YUV420P三通道图片会占3/2倒數佔原始图片大小 所令outbuf+=imgSize/2也行 avpicture_fill((AVPicture *)outframe, buffer, AVCodecContext::pixfmt , mat.cols , mat .rows );//avpicture——fill将rgb24格式帧data 首地址传递进去 AVPicture:ffmpeg中包装帧信息的struct pixfmt:帧的pixel format cols:帧宽 rows:帧高 } else{ free(outBuff); break ; } free(inBuff); } while (1) ; return outframe ; ```
创作工场
免责声明:
以上内容除特别注明外均来源于网友提问,创作工场回答,未经许可,严谨转载。
点击这里>>使用🔥专业版,更聪明、更完整、更原创!