void SrcToDest(char* pSrc, char* pDest,unsigned int nSrcWidth, unsigned int nSrcHeight, AVPixelFormat srcFormat, unsigned int nDestWidth, unsigned int nDestHeight, AVPixelFormat destFormat) { SwsContext* pConvert_ctx = NULL; AVFrame* pFrameIn = NULL; AVFrame* pFrameOut = NULL; // 分配一个AVFrame,注意必须使用avcodec_free_frame()释放 pFrameIn = avcodec_alloc_frame(); // 使用原始图片数据填充一个AVFrame avpicture_fill((AVPicture*)pFrameIn, (uint8_t*)pSrc, srcFormat, nSrcWidth, nSrcHeight); pFrameOut = avcodec_alloc_frame(); avpicture_fill((AVPicture*)pFrameOut, (uint8_t*)pDest, destFormat, nDestWidth, nDestHeight); // linesize[0]是每行的字节数,需根据具体格式调整 pFrameOut->linesize[0] = nDestWidth * 4; // 依据输入参数获取格式转换信息的结构体 pConvert_ctx = sws_getContext(nSrcWidth, nSrcHeight, srcFormat, \ nDestWidth, nDestHeight, destFormat, \ SWS_FAST_BILINEAR, NULL, NULL, NULL); // 依据格式转换结构体,转换一帧数据 sws_scale(pConvert_ctx, pFrameIn->data, pFrameIn->linesize, 0, nSrcHeight, pFrameOut->data, pFrameOut->linesize); // 释放内存 avcodec_free_frame(&pFrameIn); avcodec_free_frame(&pFrameOut); sws_freeContext(pConvert_ctx); }
注意转换的宽高不能搞错,否则非但不能转换正确,还有可能crash。附调试用的保存图片函数DumpImage,可以使用该函数查看原始数据是否正确或者格式转换是否成功:
BOOL DumpBmp(const char *filename, uint8_t *pRGBBuffer, int width, int height, int bpp) { BITMAPFILEHEADER bmpheader; BITMAPINFOHEADER bmpinfo; FILE *fp = NULL; fp = fopen(filename,"wb"); if( fp == NULL ) { return FALSE; } bmpheader.bfType = ('M' <<8)|'B'; bmpheader.bfReserved1 = 0; bmpheader.bfReserved2 = 0; bmpheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); bmpheader.bfSize = bmpheader.bfOffBits + width*height*bpp/8; bmpinfo.biSize = sizeof(BITMAPINFOHEADER); bmpinfo.biWidth = width; bmpinfo.biHeight = 0 - height; bmpinfo.biPlanes = 1; bmpinfo.biBitCount = bpp; bmpinfo.biCompression = BI_RGB; bmpinfo.biSizeImage = 0; bmpinfo.biXPelsPerMeter = 100; bmpinfo.biYPelsPerMeter = 100; bmpinfo.biClrUsed = 0; bmpinfo.biClrImportant = 0; fwrite(&bmpheader,sizeof(BITMAPFILEHEADER),1,fp); fwrite(&bmpinfo,sizeof(BITMAPINFOHEADER),1,fp); fwrite(pRGBBuffer,width*height*bpp/8,1,fp); fclose(fp); fp = NULL; return TRUE; }
char *pBmpFile = "DumpTest.bmp";
DumpBmp(pBmpFile, (uint8_t*)&bufferVector[0],
DEST_WIDTH_DEFAULT, DEST_HEIGHT_DEFAULT, 32);