ffmpeg入門學習——文檔8:軟件縮放

指導8:軟件縮放

軟件縮放庫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中的命令開關。

·其它事情,例如:在結構體中的音頻緩衝區應該對齊。

如果你想了解關於ffmpeg更多的事情,我們已經包含了其中的一部分。下一步應該學習的就是如何來編碼多媒體。一個好的入手點是在ffmpeg中的output_example.c文件。我可以爲它寫另外一個指導,但是我沒有足夠的時間來做。

好,我希望這個指導是有益和有趣的。如果你有任何建議,問題,抱怨和讚美等,請給發郵件到[email protected]

發佈了48 篇原創文章 · 獲贊 30 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章