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);