Previously i successfully opened, decoded and saved frames from .mp4
file. Raw frames were in YUV420P
format which i converted to RGB24
using sws_scale()
function and saved them into a .ppm
file. What i'm trying to do now is to keep raw decoded frames in YUV420P
, or convert frames that i get to YUV420P
just to make sure they are in YUV420P
. But the problem is that i don't know which type of file should i use, i'm guessing .yuv
? And another problem is that i also don't know how to save YUV420P
data.
I used to save RGB24
in .ppm
like this:
for (y = 0; y < height; y++)
{
fwrite(frame->data[0] + y*frame->linesize[0], 1, width * 3, pf);
}
which worked fine since i was using only 1 plane. But YUV420P
uses 3 planes (Y,Cb,Cr). What i tried to do is to save Y component first, and Cb/Cr after that.
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);
}
But as you can guess that is not working at all. Actually it does, but it saves only Y component. Could anyone guide me to right direction please?
EDIT
I've changed mine saveFrame()
function like you said, but instead of interleaved chroma writing i used planar. But, i'm still getting only Y component picture (black-white).
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);
}
Your chroma code is wrong:
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);
}
I'd also claim that height / 2
or width / 2
is wrong, since you should round up, not down, but that's relatively minor.