指導8:軟件縮放

軟件縮放庫libswscalehtml

 

近來ffmpeg添加了新的接口:libswscale來處理圖像縮放。網絡

可是在前面咱們使用img_convert來把RGB轉換成YUV12,咱們如今使用新的接口。新接口更加標準和快速,並且我相信裏面有了MMX優化代碼。換句話說,它是作縮放更好的方式。ide

咱們將用來縮放的基本函數是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) {spa

 

    SDL_LockYUVOverlay(vp->bmp);code

 

    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文件。我能夠爲它寫另一個指導,可是我沒有足夠的時間來作。

好,我但願這個指導是有益和有趣的。若是你有任何建議,問題,抱怨和讚美等。

相關文章
相關標籤/搜索