FFMPEG:通过二进制FFMPEG和代码C+将RGB转换为YUV+;给出不同的结果

FFMPEG:通过二进制FFMPEG和代码C+将RGB转换为YUV+;给出不同的结果,ffmpeg,rgb,yuv,ppm,Ffmpeg,Rgb,Yuv,Ppm,我正在尝试使用ffmpeg将RGB帧(ppm格式)转换为YUV420P格式。为了确保我的代码C++是好的,我将输出与这个命令创建的输出进行了比较(相同的文件双线性): ffmpeg-开始编号1-i数据/test512x512%d.ppm-sws_标志“双线性”-pix_fmt yuv420p数据/test-yuv420p.yuv 我的代码: static unsigned char *readPPM(int i) { FILE *pF; unsigned char *imgRGB;

我正在尝试使用ffmpeg将RGB帧(ppm格式)转换为YUV420P格式。为了确保我的代码C++是好的,我将输出与这个命令创建的输出进行了比较(相同的文件双线性): ffmpeg-开始编号1-i数据/test512x512%d.ppm-sws_标志“双线性”-pix_fmt yuv420p数据/test-yuv420p.yuv

我的代码:

static unsigned char *readPPM(int i)
{
  FILE *pF;
  unsigned char *imgRGB;
  unsigned char *imgBGR;
  int w,h;
  int c;
  int bit;
  char buff[16];

  char *filename;
  asprintf(&filename,"test512x512%d.ppm",i);
  pF = fopen(filename,"rb");
  free(filename);

  if (pF) {
    if (!fgets(buff, sizeof(buff), pF)) {
      return nullptr;
    }
    if (buff[0] != 'P' || buff[1] != '6') {
      fprintf(stderr, "Invalid image format (must be 'P6')\n");
    return nullptr;
  }
  c = getc(pF);
  while (c == '#') {
    while (getc(pF) != '\n') ;
      c = getc(pF);
  }
  ungetc(c, pF);
  // read size
  if (fscanf(pF, "%d %d", &w, &h) != 2) {
    fprintf(stderr, "Invalid image size (error loading '%s')\n", filename);
    return nullptr;

  }
  //read bit
  if (fscanf(pF, "%d", &bit) != 1) {
    fprintf(stderr, "Invalid rgb component (error loading '%s')\n", filename);
    exit(1);
  }

  imgRGB =(unsigned char*) malloc(3*h*w);
  imgBGR =(unsigned char*) malloc(3*h*w);
  //read pixel data from file
  int length = fread(imgBGR, sizeof(unsigned char)*3, w*h, pF) ;
  if (length != w*h) {
    fprintf(stderr, "Error loading image '%s'\n", filename);
    return nullptr;
  }


  int start=0;
  for (i=0; i < HEIGHT*WIDTH;i++) {
   imgRGB[start] = imgBGR[start];
   imgRGB[start+2]= imgBGR[start+2];
   imgRGB[start+1]= imgBGR[start+1];
   start+=3;
  }

  fclose(pF);
  free(imgBGR);
  return imgRGB;
}
else {
  return nullptr;
}
}

void Test_FFMPEG::FillFrame (uint8_t* pic, int index)
{

 avpicture_fill((AVPicture*)RGBFrame, pic, AV_PIX_FMT_RGB24, encodeContext->width, encodeContext->height);

  struct SwsContext* fooContext = sws_getContext(encodeContext->width, encodeContext->height,
  PIX_FMT_RGB24,
  encodeContext->width, encodeContext->height,
  PIX_FMT_YUV420P,
  SWS_BILINEAR  , nullptr, nullptr, nullptr);
  sws_scale(fooContext, RGBFrame->data, RGBFrame->linesize, 0, encodeContext->height, OrgFrame->data, OrgFrame->linesize);

  OrgFrame->pts = index;
}
静态无符号字符*readPPM(int i)
{
文件*pF;
无符号字符*imgRGB;
无符号字符*imgBGR;
int w,h;
INTC;
整数位;
字符buff[16];
字符*文件名;
asprintf(&filename,“test512x512%d.ppm”,i);
pF=fopen(文件名,“rb”);
免费(文件名);
if(pF){
如果(!fgets(buff,sizeof(buff,pF)){
返回空ptr;
}
如果(buff[0]!=“P”| buff[1]!=“6”){
fprintf(stderr,“无效图像格式(必须为'P6'))\n”);
返回空ptr;
}
c=getc(pF);
而(c='#'){
while(getc(pF)!='\n');
c=getc(pF);
}
ungetc(c,pF);
//读取大小
如果(fscanf(pF,%d%d,&w,&h)!=2){
fprintf(stderr,“无效图像大小(加载“%s”时出错)”\n,“文件名”;
返回空ptr;
}
//读取位
如果(fscanf(pF、%d、&bit)!=1){
fprintf(stderr,“无效的rgb组件(加载“%s”时出错)”\n,“文件名”;
出口(1);
}
imgRGB=(无符号字符*)malloc(3*h*w);
imgBGR=(无符号字符*)malloc(3*h*w);
//从文件中读取像素数据
int length=fread(imgBGR,sizeof(无符号字符)*3,w*h,pF);
如果(长度!=w*h){
fprintf(stderr,“加载映像“%s”时出错,\n”,文件名);
返回空ptr;
}
int start=0;
对于(i=0;i<高度*宽度;i++){
imgRGB[start]=imgBGR[start];
imgRGB[start+2]=imgBGR[start+2];
imgRGB[start+1]=imgBGR[start+1];
启动+=3;
}
fclose(pF);
免费(imgBGR);
返回imgRGB;
}
否则{
返回空ptr;
}
}
void Test\u FFMPEG::FillFrame(uint8\u t*pic,int索引)
{
avpicture_fill((avpicture*)RGB帧,图片,AV_PIX_FMT_RGB24,编码上下文->宽度,编码上下文->高度);
struct SwsContext*fooContext=sws_getContext(encodeContext->width,encodeContext->height,
PIX_FMT_RGB24,
编码上下文->宽度,编码上下文->高度,
PIX_FMT_YUV420P,
SWS_双线性、nullptr、nullptr、nullptr);
sws_比例(fooContext,RGBFrame->data,RGBFrame->linesize,0,encodeContext->height,OrgFrame->data,OrgFrame->linesize);
OrgFrame->pts=索引;
}
比较结果不好。在Y和V上有细微的差别,但在U上有很多差别。我不能发布我的图片,但Y的一部分在U图片中。它会使颜色有一点变化


你能告诉我我的错误在哪里吗?谢谢你

我对ffmpeg默认值不是很肯定,但是使用
SWS_双线性| SWS_精确_RND
应该会产生更好的结果。

你可以添加一些printf语句来检查它们是否使用与你对SwsContext完全相同的参数。。。