如果想將某個PixelFormat轉換至另一個PixelFormat,例如,將YUV420P轉換成YUYV422,或是想變換圖的大小,都可以使用swscale達成。
其中,PixelFormat 的列表在 libavutil/pixfmt.h 內定義。
swscale的用法可以參考libswscale/swscale-example.c的sample code。主要function有三個
sws_getContext()
sws_scale()
sws_freeContext()
其中,我們可以把sws_getContext() 看成初始化函數,把sws_freeContext()看成結束函數。這兩個函數分別在起始及結束各執行一次即可。
真正主要的函數,是sws_scale()。
sws_getContext() 的宣告如下
SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat, int dstW, int dstH, enum PixelFormat dstFormat, int flags, SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param)
總共有十個參數,其中,較重要的是前七個;
前三個參數分別代表 source 的寬、高及PixelFormat;
四到六個參數分別代表 destination 的寬、高及PixelFormat;
第七個參數則代表要使用哪種scale的方法;此參數可用的方法可在 libswscale/swscale.h 內找到。
最後三個參數,如無使用,可以都填上NULL。
sws_getContext會回傳一個 SwsContext struct,我們可以把這個 struct 看成是個 handler,之後的sws_scale和sws_freeContext皆會用到。
以下是一個sws_getContext的簡單例子:
struct SwsContext *img_convert_ctx;
img_convert_ctx = sws_getContext(in_width, in_height, PIX_FMT_YUV420P,
out_width, out_height, PIX_FMT_YUV420P, SWS_POINT,
NULL, NULL, NULL);
一開始,我們宣告img_convert_ctx 為指向 SwsContext 的一個 pointer;接著,我們將 sws_getContext 的回傳值賦予給img_convert_ctx。
注意sws_getContext的參數;in_width及in_height分別代表 source 的寬及高,out_width及out_height分別代表轉換後的寬與高;input 和 output 的 PixelFormat 皆為 YUV420P;使用SWS_POINT的scale方法。
初始化完成後,接著就要進行主要的 scale 動作;我們透過 sws_scale() 完成。sws_scale() 的宣告如下
int sws_scale(SwsContext c, uint8_t src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[])
總共有七個參數;
第一個參數即是由 sws_getContext 所取得的參數。
第二個 src 及第六個 dst 分別指向input 和 output 的 buffer。
第三個 srcStride 及第七個 dstStride 分別指向 input 及 output 的 stride;如果不知道什麼是 stride,姑且可以先把它看成是每一列的 byte 數。
第四個 srcSliceY,就註解的意思來看,是指第一列要處理的位置;這裡我是從頭處理,所以直接填0。想知道更詳細說明的人,可以參考 swscale.h 的註解。
第五個srcSliceH指的是 source slice 的高度。
舉一個例子如下
sws_scale(img_convert_ctx, inbuf, inlinesize, 0, in_height, outbuf, outlinesize);
這裡應該比較好懂,可以參考上面的參數說明。
最後,全部處理完後,需呼叫sws_freeContext() 結束。用法很簡單,把sws_getContext 取得的參數填入即可。如下
sws_freeContext(img_convert_ctx);
最後再整理一次,要使用swscale,只要使用 sws_getContext() 進行初始化、sws_scale() 進行主要轉換、sws_freeContext() 結束,即可完成全部動作。
以下為一個簡單的範例程式,可從foreman.yuv內取出第一張圖,轉換大小後存成另一張圖。
====