2016-03-11 6 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); 
} 

, который работал хорошо, так как я использовал только один самолет. Но 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-компонент. Может ли кто-нибудь направлять меня в правильном направлении, пожалуйста?

EDIT Я изменила мою 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); 
} 

Я бы также утверждать, что height/2 или width/2 является неправильным, так как вы должны округлить вверх, а не вниз, но это относительно небольшие.

+0

Отредактируйте раздел редактирования, пожалуйста. –

+0

в PPM, аргумент «высота» должен быть h * 3/2 для yuv420p, так что общий размер двух чисел - это количество элементов на изображении, а не только плоскость Y. См. Https://www.ffmpeg.org/doxygen/trunk/pnmenc_8c_source.html –

+0

О, боже, большое вам спасибо, это так полезно, я наконец понял, как выполняется YUV420P. Но что-то щекочет мой разум, в этом файле, в частности 'ptr1 + = p-> lineize [1]; ptr2 + = p-> lineize [2]; '. Если мы сохраним такие данные цветности, это не будет сохранено как полуплоскостное и не полностью-плоскостное, учитывая это изображение: [YUV420 Planar/Interleaved/SemiPlanar] (http://3.bp.blogspot.com/-wQp0uFzDOC4 /T3Rp9PU04sI/AAAAAAAABOw/u24jEPKzLCY/s1600/YUV420P&YUV420SP.png) –