ffmpeg pipe example

這邊從 stdout stderr 流輸入給 ffmpeg 做壓縮,主要就是利用 pipe IPC

寫個小程式順便比較 javascript (nodejs) 和 C 語言的速度差異,最佳化的結果是 javascript 輸出到 stderr 幾乎等速於 C 語言,令人有點意外XD;反而直出到 stdout 的速度比 C 語言慢了 30%,這不太科學 。

題外話是 stderr 通常不會有 buffer 的問題,大多數時候都不用擔心沒有 flush 乾淨

Github code

 

最後我們會在 command line 把 stderr 流灌到 stdout 中,給 ffmpeg 接收,其實速度超快的,極限大概是 full HD 80FPS,若不考慮產生影像,已經足以 realtime 計算了

#include <stdio.h>
#include <stdlib.h>
// includes for setmode
#include <fcntl.h>
#include <io.h>

int imgSizeX = 1920;
int imgSizeY = 1080;
int imgNum   = 0;

int mvX      = 5;
int mvY      = -2;

int main(int argc, char *argv[]) {
    imgNum = atoi(argv[1]);
    
    // change to binary stdout mode (avoid 0x0A be changed into 0x0D 0x0A)
    setmode(2, _O_BINARY);
    
    char *img = new char[imgSizeX*imgSizeY*3];
    
    for (int i = 0; i < imgNum; ++i) {
        for (int y = 0; y < imgSizeY; ++y) {
            for (int x = 0; x < imgSizeX; ++x) {
                int offset = y*imgSizeX*3 + x*3;
                img[offset+0] = (y+i*mvY) & 0xFF;
                img[offset+1] = (x+i*mvX) & 0xFF;
                img[offset+2] = 0x00;
            }
        }
        fwrite(img, 1, imgSizeX*imgSizeY*3, stderr);
    }
    
    fflush(stderr);
    delete [] img;
    return 0;
}
set inputSettings=-f rawvideo -pix_fmt rgb24 -video_size 1920x1080 -r 60
set outputSettings=-vcodec libx264 -qp 18 -x264opts opencl -pix_fmt yuv420p -r 60
set outputFile=output.mp4

del %outputFile%
a.exe 1000 2>&1 | ffmpeg %inputSettings% -i - %outputSettings% %outputFile%
pause
let imgSizeX = 1920;
let imgSizeY = 1080;
let imgNum   = 1000;

let data = Buffer.alloc(imgSizeX*imgSizeY*3);

for (var i = 0; i < imgNum; i+=1) {
    var offset = 0;
    for (var y = 0; y < imgSizeY; ++y) {
        for (var x = 0; x < imgSizeX; ++x) {
            offset += 3;
            data[offset+0] = (x+i*5) & 0xFF;
            data[offset+1] = (y+i*(-2)) & 0xFF;
            data[offset+2] = 0x00;
        }
    }
    process.stderr.write( data );
}
set inputSettings=-f rawvideo -pix_fmt rgb24 -video_size 1920x1080 -r 60
set outputSettings=-vcodec libx264 -qp 18 -x264opts opencl -pix_fmt yuv420p -r 60
set outputFile=output.mp4

del %outputFile%
node main.js 2>&1 | ffmpeg %inputSettings% -i - %outputSettings% %outputFile%
pause

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *