FFMPEG:通过二进制ffmpeg和代码C ++将RGB转换为YUV会得到不同的结果 [英] FFMPEG: RGB to YUV conversion by binary ffmpeg and by code C++ give different results

查看:196
本文介绍了FFMPEG:通过二进制ffmpeg和代码C ++将RGB转换为YUV会得到不同的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用ffmpeg将RGB帧(ppm格式)转换为YUV420P格式.为了确保我的代码C ++良好,我将输出与该命令创建的输出(同一文件管理器BILINEAR)进行了比较: ffmpeg -start_number 1 -i data/test512x512%d.ppm -sws_flags'bilinear'-pix_fmt yuv420p data/test-yuv420p.yuv

I am trying to convert RGB frames (ppm format) to YUV420P format using ffmpeg. To make sure that my code C++ is good , I compared the output with the one created by this command (the same filer BILINEAR): ffmpeg -start_number 1 -i data/test512x512%d.ppm -sws_flags 'bilinear' -pix_fmt yuv420p data/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;
}

比较结果不好. Y和V略有不同,但在U中有很多差异.我无法发布图像,但是Y的一部分在U图像中.而且它会使颜色稍微改变.

The comparison result is not good. The are slight differences in Y and V but a lot in U. I cannot post my images but there is a part of Y is in U image. And it makes color change a little bit.

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

Can you tell me where is my error? Thanks you

推荐答案

我对ffmpeg的默认设置并不满意,但是使用SWS_BILINEAR | SWS_ACCURATE_RND应该会产生更好的结果.

I'm not positive about the ffmpeg defaults, but using SWS_BILINEAR | SWS_ACCURATE_RND should produce better results.

这篇关于FFMPEG:通过二进制ffmpeg和代码C ++将RGB转换为YUV会得到不同的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆