阶梯型横线:
条纹状画面:
出现阶梯型横线的原因是:对FFmpeg中AVFrame中width与linesize的关系不明确
因为存在字节对齐,所以linesize和width的大小可能会不同
假如按照64字节对齐,width=720。那么linesize=768。其中48位多余的用0x00补齐。这48位就是阶梯型横线出现的原因。
下边的方法写就可能会出现阶梯型横线。为什么是可能呢。因为如果width正好是64的倍数,那么width=linesize,就不会出现补齐的0x00。
y_size = pInCodecCtx->width * pInCodecCtx->height;
fwrite(pFrame->data[0], 1, y_size, fp);
fwrite(pFrame->data[1], 1, y_size/4, fp);
fwrite(pFrame->data[2], 1, y_size/4, fp);
下边两种写法都可以:
写法一(有时候也不行):
fwrite(frame->data[0], 1, frame->linesize[0] * frame->height, out_yuv);
fwrite(frame->data[1], 1, frame->linesize[1] * frame->height / 2, out_yuv);
fwrite(frame->data[2], 1, frame->linesize[2] * frame->height / 2, out_yuv);
正确写法二:
FILE* out_yuv = fopen("C:/Users/zhou/Desktop/Mpeg2decoder/1.yuv","wb+");
AVFrame* frame = frameYUV;//假设frameYUV为FFmpeg解码输出的AVFrame
frame->height = frameYUV->height;
frame->width = frameYUV->width;
int picSize = frame->height *frame->width;
int newSize = picSize * 1.5;
//申请内存
unsigned char *buf = new unsigned char[newSize];
int a=0,i;
for (i=0; i<frame->height; i++)
{
memcpy(buf+a,frame->data[0] + i * frame->linesize[0], frame->width);
a+=frame->width;
}
for (i=0; i<frame->height/2; i++)
{
memcpy(buf+a,frame->data[1] + i * frame->linesize[1], frame->width/2);
a+=frame->width/2;
}
for (i=0; i<frame->height/2; i++)
{
memcpy(buf+a,frame->data[2] + i * frame->linesize[2], frame->width/2);
a+=frame->width/2;
}
fwrite(buf, 1, newSize, out_yuv);
delete buf;
buf = nullptr;