姚伟示微博:YUV420SP to YUV420P

来源:百度文库 编辑:中财网 时间:2024/05/05 09:05:23

最近做TI DM365的solution, 发现出来的画面有抖动,于是就想抓RAW data出来看看是sensor有问题还是encode出了问题,sensor出来的数据是RGB的,通过Previewer后就变成了YUV420SP, 抓了RAW data出来之后用YUVtools一看,整个画面都是灰色的,感觉只有Y值work了,UV都没了,于是又去网上download其他的YUV tools, 结果还是一样,后来发现一般的YUV tools只支持普通的YUV420格式,即YUV420P, 于是去找解析YUV420SP的tool, 发现还不太好找,于是就自己写了一个转换工具,将YUV420SP的转成YUV420P的格式,转了之后用YUV tools 一看,颜色全对了。

 

下面就是源码:


/*
YYYYYYYYYYYYY                                YYYYYYYYYYYYY
YYYYYYYYYYYYY       -->                      YYYYYYYYYYYYY
YYYYYYYYYYYYY                                YYYYYYYYYYYYY
YYYYYYYYYYYYY                                YYYYYYYYYYYYY
CbCrCbCr                                     CbCbCbCb
CbCrCbCr                                     CrCrCrCr

YYYYYYYY...      -->   YYYYYYYY...
CbCrCbCr....     -->   CbCb.....  CrCr......
*/

#include
#include
#include
#include

int main(int argc, char* argv[])
{
 int i;
 int idx;
 int width;
 int height;
 int pixels;
 int frame_no;
 FILE *inputfp = NULL;
 FILE *outputfp = NULL;
 unsigned char *pBuffer;
 struct stat state;

 if (argc != 5)
 {
  fprintf(stderr, "Usage : %s /n",argv[0]);
  return -1;
 }

 width = atoi(argv[3]);
 height = atoi(argv[4]);

 if(width <= 0 || height <= 0)
 {
  fprintf(stderr, "parameter error [width = %d, height=%d]/n",width, height);
  return -1;
 }

 if (stat(argv[1], &state) < 0)
 {
  fprintf(stderr, "Faile to stat %s/n",argv[1]);
  return -1;
 }
 frame_no = (state.st_size/((width*height/2)*3));

 inputfp = fopen(argv[1], "rb");
 if (!inputfp)
 {
  fprintf(stderr, "fopen failed for input file[%s]/n",argv[1]);
  return -1;
 }

 outputfp = fopen(argv[2], "wb");
 if (!outputfp)
 {
  fprintf(stderr, "fopen failed for output file[%s]/n",argv[2]);
  return -1;
 }

 pixels = width * height;
 pBuffer = (unsigned char *)malloc(pixels);

 for (i=0; i {
  // Read Y
  fread (pBuffer, pixels, sizeof(unsigned char), inputfp);

  // Write Y
  fwrite(pBuffer, pixels, sizeof(unsigned char), outputfp);

  // Read Cb Cr
  fread (pBuffer, (pixels/2), sizeof(unsigned char), inputfp);

  // Write Cb
  for(idx = 0; idx <  (pixels/2); idx+=2)
  {
   fwrite((pBuffer + idx), 1, sizeof(unsigned char), outputfp);
  }

  // Write Cr
  for(idx = 1; idx <  (pixels/2); idx+=2)
  {
   fwrite((pBuffer + idx), 1, sizeof(unsigned char), outputfp);
  }
 }
 
 free(pBuffer);
 fclose(inputfp);
 fclose(outputfp);
 return 0;
}