[讀書心得] ffmpeg tutorial (二) Drawing images to screen
這集介紹透過 ffmpeg 將 stream 轉為 Images 輸出, 採用的是 SDL (Simple Direct Layer).
SDL 的簡單說明:
(1) Simple DirectMedia Layer
(2) written by c, but C++ compatible.
(3) cross-platform (Linux, Windows, Windows CE, BeOS, MacOS, Mac OS X, FreeBSD, OpenBSD, BSD/OS, Solaris and QNX)
(4) low level access to hardware device, ex. keyboard, audio, mose, joystick, 3D hardware(via OpenGL), 2D video framebuffer.
(5) GNU LGPL v2 (表示只要透過dynamic library, 即可作為商業用途; 只有再修改SDL源碼才要公布修改的部分跟使用的代碼)
(6) Language biding (ex. C#, Java, Lisp, Lua, Object-C, PHP, Python, Ruby and smalltalk)
(7) DirectX之於Windows, 等同SDL之於nonWindows
(8) Current Version 1.2.15 (Jan. 20, 2012) resource click here.
SDL 對於呈現 image 很多方法, 這裡介紹一種 YUV overlay.(這以前在學校有接觸過, 可當時根本不知道在幹嘛... )
YUV(technically, YCbrCr) 是一種儲存 raw image 的格式, 其他的格式像是 RGB.
Y: brightness/luma component, U and V: color compoents.
SDL接受4種不同的 YUV format, 而 處理速度YV12 是最快的. 另外有個 format YUV420P, 指的是 subsampling rate 4:2:0, 每 4 luma samples 伴隨 1 color sample, 即 color information 只剩 1/4, 通常較省頻寬. P 指的是 planar (Y,U,V 存在不同的Arrays).
ffmpeg 可以將 images 轉為 YUV420P, 這好處是大部分 video stream 已經是這種格式.
所以接下來要做的, 是將 ffmpeg tutorial (一) 原先存成 file 改為傳到 screen.
Initialize SDL
Creating a Display
SDL_SetVideoMode(): 設置一個 大小為 pCodecCtx->width, pCodecCtx->height 的 screen.
(Q1) SDL_SetVideoMode() 第三個參數是 depth. 可 Image 要 depth 幹嘛?
(Q2) 所以 surface (term in SDL) = screen (general term) = window (visible) ?
SDL_Overlap *bmp
bmp = SDL_CreateYUVOverlay(pCodecCtx->width, pCodecCtx->height, SDL_YV12_OVERLAY, screen);
將 Picture 轉為 format YV12.
Displaying the Image
* AVPicture 為一個 array of 4 pointers. 因為 YUV420P 只有三個 channels, 所以只有 3 sets.
* pitches 指的是 SDL 上指定的 line data 長度.
Drawing the Image
參考來源
SDL 的簡單說明:
(1) Simple DirectMedia Layer
(2) written by c, but C++ compatible.
(3) cross-platform (Linux, Windows, Windows CE, BeOS, MacOS, Mac OS X, FreeBSD, OpenBSD, BSD/OS, Solaris and QNX)
(4) low level access to hardware device, ex. keyboard, audio, mose, joystick, 3D hardware(via OpenGL), 2D video framebuffer.
(5) GNU LGPL v2 (表示只要透過dynamic library, 即可作為商業用途; 只有再修改SDL源碼才要公布修改的部分跟使用的代碼)
(6) Language biding (ex. C#, Java, Lisp, Lua, Object-C, PHP, Python, Ruby and smalltalk)
(7) DirectX之於Windows, 等同SDL之於nonWindows
(8) Current Version 1.2.15 (Jan. 20, 2012) resource click here.
SDL 對於呈現 image 很多方法, 這裡介紹一種 YUV overlay.(這以前在學校有接觸過, 可當時根本不知道在幹嘛... )
YUV(technically, YCbrCr) 是一種儲存 raw image 的格式, 其他的格式像是 RGB.
Y: brightness/luma component, U and V: color compoents.
SDL接受4種不同的 YUV format, 而 處理速度YV12 是最快的. 另外有個 format YUV420P, 指的是 subsampling rate 4:2:0, 每 4 luma samples 伴隨 1 color sample, 即 color information 只剩 1/4, 通常較省頻寬. P 指的是 planar (Y,U,V 存在不同的Arrays).
ffmpeg 可以將 images 轉為 YUV420P, 這好處是大部分 video stream 已經是這種格式.
所以接下來要做的, 是將 ffmpeg tutorial (一) 原先存成 file 改為傳到 screen.
Initialize SDL
#include#include if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) { fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError()); exit(1); }
Creating a Display
SDL_Surface *screen; screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 0, 0); if (!screen){ fprintf(stderr, "SDL: Could not set video mode - existing.\n"); exit(1); }SDL_Surface: SDL 中定義 screen 為 surface.
SDL_SetVideoMode(): 設置一個 大小為 pCodecCtx->width, pCodecCtx->height 的 screen.
(Q1) SDL_SetVideoMode() 第三個參數是 depth. 可 Image 要 depth 幹嘛?
(Q2) 所以 surface (term in SDL) = screen (general term) = window (visible) ?
SDL_Overlap *bmp
bmp = SDL_CreateYUVOverlay(pCodecCtx->width, pCodecCtx->height, SDL_YV12_OVERLAY, screen);
將 Picture 轉為 format YV12.
Displaying the Image
if (frameFinished) { SDL_LockYUVOverlay(bmp); AVPicture pic; pic.data[0] = bmp->pixels[0]; pic.data[1] = bmp->pixels[2]; pic.data[2] = bmp->pixels[1]; pic.linesize[0] = bmp->pitches[0]; pic.linesize[1] = bmp->pitches[2]; pic.linesize[2] = bmp->pitches[1]; img_convert(&pic, PIX_FMT_YUV420P, (AVFrame *) pFrame, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height); SDL_UnlockYUVOverlay(bmp); ... }這裡主要是將 pFrame 轉為 format PIX_FMT_YUV420P.
* AVPicture 為一個 array of 4 pointers. 因為 YUV420P 只有三個 channels, 所以只有 3 sets.
* pitches 指的是 SDL 上指定的 line data 長度.
Drawing the Image
SDL_Rect rect; if (frameFinished) { ... SDL_UnlockYUVOverlay(bmp); rect.x = 0; rect.y = 0; rect.w = pCodecCtx->width; rect.h = pCodecCtx->height; SDL_DisplayYUVOverlay(bmp, &rect); }
WARNING: This tutorial is slightly out of date.
參考來源
Comments
Post a Comment