本文來自:http://blog.csdn.net/jinhaijian/archive/2010/09/02/5859649.aspx
軟件縮放庫libswscale
近來ffmpeg添加了新的接口:libswscale來處理圖像縮放。
但是在前面我們使用img_convert來把RGB轉換成YUV12,我們現在使用新的接口。新接口更加標準和快速,而且我相信裏面有了MMX優化代碼。換句話說,它是做縮放更好的方式。
我們將用來縮放的基本函數是sws_scale。但一開始,我們必需建立一個SwsContext的概念。這將讓我們進行想要的轉換,然後把它傳遞給 sws_scale函數。類似於在SQL中的預備階段或者是在Python中編譯的規則表達式regexp。要準備這個上下文,我們使用 sws_getContext函數,它需要我們源的寬度和高度,我們想要的寬度和高度,源的格式和想要轉換成的格式,同時還有一些其它的參數和標誌。然後我們像使用img_convert一樣來使用sws_scale函數,唯一不同的是我們傳遞給的是SwsContext:
#include <ffmpeg/swscale.h> // include the header!
int queue_picture(VideoState *is, AVFrame *pFrame, double pts) {
static struct SwsContext *img_convert_ctx;
...
if(vp->bmp) {
SDL_LockYUVOverlay(vp->bmp);
dst_pix_fmt = PIX_FMT_YUV420P;
pict.data[0] = vp->bmp->pixels[0];
pict.data[1] = vp->bmp->pixels[2];
pict.data[2] = vp->bmp->pixels[1];
pict.linesize[0] = vp->bmp->pitches[0];
pict.linesize[1] = vp->bmp->pitches[2];
pict.linesize[2] = vp->bmp->pitches[1];
// Convert the image into YUV format that SDL uses
if(img_convert_ctx == NULL) {
int w = is->video_st->codec->width;
int h = is->video_st->codec->height;
img_convert_ctx = sws_getContext(w, h,
is->video_st->codec->pix_fmt,
w, h, dst_pix_fmt, SWS_BICUBIC,
NULL, NULL, NULL);
if(img_convert_ctx == NULL) {
fprintf(stderr, "Cannot initialize the conversion context!/n");
exit(1);
}
}
sws_scale(img_convert_ctx, pFrame->data,
pFrame->linesize, 0,
is->video_st->codec->height,
pict.data, pict.linesize);
我們把新的縮放器放到了合適的位置。希望這會讓你知道libswscale能做什麼。
就這樣,我們做完了!編譯我們的播放器:
gcc -o tutorial08 tutorial08.c -lavutil -lavformat -lavcodec -lz -lm `sdl-config --cflags --libs`
享受我們用C寫的少於1000行的電影播放器吧。
當然,還有很多事情要做。
現在還要做什麼?
我們已經有了一個可以工作的播放器,但是它肯定還不夠好。我們做了很多,但是還有很多要添加的性能:
•錯誤處理。我們代碼中的錯誤處理是無窮的,多處理一些會更好。
•暫停。我們不能暫停電影,這是一個很有用的功能。我們可以在大結構體中使用一個內部
暫停變量,當用戶暫停的時候就設置它。然後我們的音頻,視頻和解碼線程檢測到它後就不再輸出任何東西。我們也使用av_read_play來支持網絡。這很容易解釋,但是你卻不能明顯的計算出,所以把這個作爲一個家庭作業,如果你想嘗試的話。提示,可以參考ffplay.c。
•支持視頻硬件特性。一個參考的例子,請參考Frame Grabbing在Martin的舊的指導中的相關部分。http://www.inb.uni-luebeck.de/~boehme/libavcodec_update.html
•按字節跳轉。如果你可以按照字節而不是秒的方式來計算出跳轉位置,那麼對於像VOB文件一樣的有不連續時間戳的視頻文件來說,定位會更加精確。
•丟棄幀。如果視頻落後的太多,我們應當把下一幀丟棄掉而不是設置一個短的刷新時間。
•支持網絡。現在的電影播放器還不能播放網絡流媒體。
•支持像YUV文件一樣的原始視頻流。如果我們的播放器支持的話,因爲我們不能猜測出時基和大小,我們應該加入一些參數來進行相應的設置。
•全屏。
•多種參數,例如:不同圖像格式;參考ffplay.c中的命令開關。
•其它事情,例如:在結構體中的音頻緩衝區應該對齊。