本文共 4507 字,大约阅读时间需要 15 分钟。
利用ffmpeg进行图像数据格式的转换以及图片的缩放应用中,主要用到了swscale.h文件中的三个函数,分别是:
struct SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat, int dstW, int dstH, enum AVPixelFormat dstFormat, int flags, SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param);
int sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[]);
void sws_freeContext(struct SwsContext *swsContext);
sws_getContext函数可以看做是初始化函数,它的参数定义分别为:
int srcW,int srcH 为原始图像数据的高和宽; int dstW,int dstH 为输出图像数据的高和宽; enum AVPixelFormat srcFormat 为输入和输出图片数据的类型;eg:AV_PIX_FMT_YUV420、PAV_PIX_FMT_RGB24; int flags 为scale算法种类;eg:SWS_FAST_BILINEAR,SWS_BICUBIC、SWS_BICUBLIN、SWS_POINT、SWS_SINC; SwsFilter *srcFilter ,SwsFilter *dstFilter,const double *param 可以不用管,全为NULL即可;
sws_scale函数则为执行函数,它的参数定义分别为:
struct SwsContext *c 为sws_getContext函数返回的值; const uint8_t *const srcSlice[],uint8_t *const dst[] 为输入输出图像数据各颜色通道的buffer指针数组; const int srcStride[],const int dstStride[] 为输入输出图像数据各颜色通道每行存储的字节数数组; int srcSliceY 为从输入图像数据的第多少列开始逐行扫描,通常设为0; int srcSliceH 为需要扫描多少行,通常为输入图像数据的高度;
sws_freeContext函数为结束函数,它的参数即为sws_getContext函数返回的值;
做一个实际缩放YUV420函数打包实例如下:
int ScaleImg(AVCodecContext *pCodecCtx,AVFrame *src_picture,AVFrame *dst_picture,int nDstH ,int nDstW ){int i ;int nSrcStride[3];int nDstStride[3];int nSrcH = pCodecCtx->height;int nSrcW = pCodecCtx->width;struct SwsContext* m_pSwsContext;uint8_t *pSrcBuff[3] = {src_picture->data[0],src_picture->data[1], src_picture->data[2]};nSrcStride[0] = nSrcW ;nSrcStride[1] = nSrcW/2 ;nSrcStride[2] = nSrcW/2 ;dst_picture->linesize[0] = nDstW;dst_picture->linesize[1] = nDstW / 2;dst_picture->linesize[2] = nDstW / 2;printf("nSrcW%d\n",nSrcW);m_pSwsContext = sws_getContext(nSrcW, nSrcH, PIX_FMT_YUV420P,nDstW, nDstH, PIX_FMT_YUV420P,SWS_BICUBIC,NULL, NULL, NULL);if (NULL == m_pSwsContext){printf("ffmpeg get context error!\n");exit (-1);}sws_scale(m_pSwsContext, src_picture->data,src_picture->linesize, 0, pCodecCtx->height,dst_picture->data,dst_picture->linesize);printf("line0:%d line1:%d line2:%d\n",dst_picture->linesize[0] ,dst_picture->linesize[1] ,dst_picture->linesize[2]);sws_freeContext(m_pSwsContext);return 1 ;}
函数很简单,申请环境初始指针,后缩放即可。读到此文的朋友,这个函数可以直接拷贝使用哟。
RGB的缩放可以参考下面:
int ScaleYUVImgToRGB(int nSrcW,int nSrcH ,uint8_t* src_data,int *linesize,int nDstW ,int nDstH ) { int i ; int ret ; FILE *nRGB_file ; AVFrame *nDst_picture ; struct SwsContext* m_pSwsContext; nDst_picture = avcodec_alloc_frame(); if (!nDst_picture){ printf("nDst_picture avcodec_alloc_frame failed\n"); exit(1); } if(avpicture_alloc((AVPicture *)nDst_picture,PIX_FMT_RGB24,nDstW, nDstH)<0){ printf("dst_picture avpicture_alloc failed\n"); exit(1); } m_pSwsContext = sws_getContext(nSrcW, nSrcH, PIX_FMT_YUV420P, nDstW, nDstH, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL); if (NULL == m_pSwsContext) { printf("ffmpeg get context error!\n"); exit (-1); } ret = sws_scale(m_pSwsContext, src_data,linesize, 0,nSrcH,nDst_picture->data,nDst_picture->linesize); nRGB_file = fopen("..\\YUV_STREAM\\RGBFile.rgb","ab+"); fwrite(nDst_picture->data[0],nDstW*nDstH*3,1,nRGB_file); fclose(nRGB_file); sws_freeContext(m_pSwsContext); avpicture_free((AVPicture *)nDst_picture); return 0; }
参数data 和 linesize 参考yuv平面指针即可。
同时如果不想使用AVPicture结构的话,可以参考下面的:(注意不同图像类型,linesize一定要写对)
char* H264Decoder_c::ScaleYUVImgToRGB(int nSrcW,int nSrcH ,uint8_t** src_data,int *linesize,int nDstW ,int nDstH ){ int i ; int ret ; FILE *nRGB_file ; struct SwsContext* m_pSwsContext; char* out_Img[3]; int out_linesize[3]; out_linesize[0] = 2*nDstW ; //out_linesize[1] = nDstW ;out_linesize[2] = nDstW ; out_Img[0] = g_RGBImg ; m_pSwsContext = sws_getContext(nSrcW, nSrcH, PIX_FMT_YUV420P, nDstW, nDstH, PIX_FMT_RGB565, SWS_BICUBIC, NULL, NULL, NULL); if (NULL == m_pSwsContext) { printf("ffmpeg get context error!\n"); exit (-1); } ret = sws_scale(m_pSwsContext, src_data,linesize, 0,nSrcH,(uint8_t**)out_Img,out_linesize);#if 0 nRGB_file = fopen("./RGBFile.rgb","ab+"); fwrite(out_Img[0],nDstW*nDstH*2,1,nRGB_file); fclose(nRGB_file);#endif sws_freeContext(m_pSwsContext); return out_Img[0];
转载地址:http://vqnvb.baihongyu.com/