我使用FFmpeg库已经使用RGB->YUV420转换了一段时间。已经尝试过sws_scale
功能,但效果不佳。现在,我决定使用颜色空间转换公式分别转换每个像素。所以,下面的代码可以让我获得一些帧,并允许我访问每个像素的单个R、G、B值:
// Read frames and save first five frames to disk
i=0;
while((av_read_frame(pFormatCtx, &packet)>=0) && (i<5))
{
// Is this a packet from the video stream?
if(packet.stream_index==videoStreamIdx)
{
/// Decode video frame
avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
// Did we get a video frame?
if(frameFinished)
{
i++;
sws_scale(img_convert_ctx, (const uint8_t * const *)pFrame->data,
pFrame->linesize, 0, pCodecCtx->height,
pFrameRGB->data, pFrameRGB->linesize);
int x, y, R, G, B;
uint8_t *p = pFrameRGB->data[0];
for(y = 0; y < h; y++)
{
for(x = 0; x < w; x++)
{
R = *p++;
G = *p++;
B = *p++;
printf(" %d-%d-%d ",R,G,B);
}
}
SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i);
}
}
// Free the packet that was allocated by av_read_frame
av_free_packet(&packet);
}
我读到online要转换RGB->YUV420或反之亦然,首先应该转换成YUV444格式。所以,它类似于:RGB->YUV444->YUV420。如何在C++中实现这一点?
此外,这里还有上面使用的
SaveFrame()
函数。我想这也会有所改变,因为YUV420存储数据的方式不同。怎么处理?void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame)
{
FILE *pFile;
char szFilename[32];
int y;
// Open file
sprintf(szFilename, "frame%d.ppm", iFrame);
pFile=fopen(szFilename, "wb");
if(pFile==NULL)
return;
// Write header
fprintf(pFile, "P6\n%d %d\n255\n", width, height);
// Write pixel data
for(y=0; y<height; y++)
fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile);
// Close file
fclose(pFile);
}
有人能推荐一下吗?非常感谢!!!
最佳答案
void SaveFrameYUV420P(AVFrame *pFrame, int width, int height, int iFrame)
{
FILE *pFile;
char szFilename[32];
int y;
// Open file
sprintf(szFilename, "frame%d.yuv", iFrame);
pFile=fopen(szFilename, "wb");
if(pFile==NULL)
return;
// Write pixel data
fwrite(pFrame->data[0], 1, width*height, pFile);
fwrite(pFrame->data[1], 1, width*height/4, pFile);
fwrite(pFrame->data[2], 1, width*height/4, pFile);
// Close file
fclose(pFile);
}
在Windows上,可以使用irfanview查看以这种方式保存的帧。您可以以原始的24bpp格式打开框架,提供宽度和高度,并选中“yuv420”复选框。
关于c++ - 将单个像素值从RGB转换为YUV420并保存帧-C++,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22616387/