ffmpeg pipe example

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

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

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

Github code

 

閱讀全文〈ffmpeg pipe example〉

Difference between CRF and QP in x264

壓縮時該選哪個? 看目的是要做什麼,基本上一句話: 開發用 QP ,觀賞用CRF

  • CRF: 根據場景移動的速度動態選擇 QP (畫質) ,傾向在快速變化場景提高壓縮率 ( B frames ),目的是只要維持視覺上的 QP 就可以,快速變化的地方可以模糊一點沒關係。(實驗中在同樣的 QP 設定下,CRF在 I 和 P frame 的 QP 值反而比較高!@@ )
  • QP: 均化所有 frame 的QP,不論場景內容

CRF 或 QP=0 都是 loseless 這邊就不討論了,也沒有什麼實用價值。基本上在相同的設定值下,CRF 的檔案大小會比較小,但這是在於 CRF > 25 (平均畫質) 以上才比較有價值,否則差異不大。

就 MEMC (Frame Rate Conversion) 演算法開發我還是習慣用QP=18,因為同樣用 CRF=18,可能在快速移動物體邊緣出現些許 blocky ,但這是 CRF 壓縮造成的,不是演算法瑕疵,尤其我們在斤斤計較的就是這些快速移動的區域。

C/C++ stdout without CRLF

#include <fcntl.h>
#include <io.h>

setmode(1, _O_BINARY);

 

example use in ffmpeg pipe encoding mode

a.exe | ffmpeg -f rawvideo -pixel_format rgb24 -video_size 1920x1080 -i - -pix_fmt yuv420p output.mp4
#include <stdio.h>

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

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

int main() {
    // change to binary stdout mode (avoid 0x0A be changed into 0x0D 0x0A)
    setmode(1, _O_BINARY);
    
    for (int i = 0; i < imgNum; ++i) {
        for (int y = 0; y < imgSizeY; ++y) {
            for (int x = 0; x < imgSizeX; ++x) {
                unsigned char color[3] = {0x00, (x+i*5) & 0xFF, 0x00};
                fwrite(color, 1, 3, stdout);
            }
        }
    }
    
    fflush(stdout);
    
    return 0;
}

 

GitHub Codes