最近做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 <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>
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 <input file name> <output file name> <width> <height>/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<frame_no; 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;
}