2016-03-11 70 views
0

我以前成功打開,解碼並從.mp4文件保存幀。原始幀均YUV420P格式我轉換爲RGB24使用sws_scale()功能,並將它們保存到.ppm文件。我想要現在要做的就是保持YUV420P原料解碼幀,或轉換,我去YUV420P幀只是爲了確保他們在YUV420P。但問題是,我不知道我應該使用哪種類型的文件,我猜.yuv?另一個問題是我也不知道如何保存YUV420P數據。保存原始YUV420P幀的FFmpeg/Libav

我用來保存RGB24.ppm這樣的:

for (y = 0; y < height; y++) 
{ 
fwrite(frame->data[0] + y*frame->linesize[0], 1, width * 3, pf); 
} 

,因爲我只使用1個平面,工作得很好。但是YUV420P使用3個平面(Y,Cb,Cr)。我試圖做的是先保存Y分量,然後再保存Cb/Cr。

for (y = 0; y < height; y++) 
{ 
    fwrite(frame->data[0] + y*frame->linesize[0], 1, width, pf); 
} 

for (y = 0; y < height/2; y++) 
{ 
    fwrite(frame->data[1] + y*frame->linesize[1], 1, width, pf); 
    fwrite(frame->data[2] + y*frame->linesize[2], 1, width, pf); 
} 

但是,正如你所猜測的那樣根本不起作用。實際上它確實存在,但它只保存了Y分量。任何人都可以指導我正確的方向嗎?

編輯 我已經改變了我的saveFrame()功能就像你說的,但不是交錯色度寫作我使用的平面。但是,我仍然只能得到Y分量圖片(黑白)。

fprintf(pf, "P5\n%d %d\n255\n", width, height); 

for (y = 0; y < height; y++) 
{ 
    fwrite(frame->data[0] + y*frame->linesize[0], 1, width, pf); 
} 

for (y = 0; y < height/2; y++) 
{ 
    fwrite(frame->data[1] + y*frame->linesize[1], 1, width/2, pf); 
} 

for (y = 0; y < height/2; y++) 
{ 
    fwrite(frame->data[2] + y*frame->linesize[2], 1, width/2, pf); 
} 

回答

1

你色度代碼是錯誤的:

for (y = 0; y < height/2; y++) 
{ 
    fwrite(frame->data[1] + y*frame->linesize[1], 1, width/2, pf); 
    fwrite(frame->data[2] + y*frame->linesize[2], 1, width/2, pf); 
} 

我還聲稱​​或width/2是錯誤的,因爲你要圓了,而不是下降,但這是相對較小的。

+0

請檢查編輯部分。 –

+0

在PPM中,對於yuv420p,「height」參數應該是h * 3/2,這樣兩個數字的總大小就是圖像中元素的數量,而不僅僅是Y平面。見https://www.ffmpeg.org/doxygen/trunk/pnmenc_8c_source.html –

+0

哦,上帝,非常感謝你,這是非常有用的,我終於明白如何儲蓄YUV420P完成。但是,在那個文件中,有些東西在我的腦海裏撓癢癢,特別是'ptr1 + = p-> linesize [1]; ptr2 + = p-> linesize [2];'。如果我們保存這樣的色度數據,考慮到這張圖片,將不會保存爲半平面和不完全平面:[YUV420 Planar/Interleaved/SemiPlanar](http://3.bp.blogspot.com/-wQp0uFzDOC4 /T3Rp9PU04sI/AAAAAAAABOw/u24jEPKzLCY/s1600/YUV420P&YUV420SP.png) –