http://blog.csdn.net/huahuahailang/article/details/9040847
- * 主要功能:兩路 YUV4:2:0拼接一路左右半寬格式YUV視頻
- 參考資料:http://www.pudn.com/downloads271/sourcecode/multimedia/vfw/detail1237363.html
- U_size=V_size=Y_size/2
- *************************************************/
- #include<stdio.h>
- #include<stdlib.h>
- #include<string.h>
- #define PREWEIGHT 1920
- #define PREHEIGHT 1080
- #define RESWEIGHT 3840
- #define RESHEIGHT 1080
- #define PREYSIZE ((PREWEIGHT)*(PREHEIGHT))
- #define PREUSIZE ((PREWEIGHT/2)*(PREHEIGHT/2))
- #define PREVSIZE ((PREWEIGHT/2)*(PREHEIGHT/2))
- #define RESYSIZE ((RESWEIGHT)*(RESHEIGHT))
- #define RESUSIZE ((RESWEIGHT/2)*(RESHEIGHT/2))
- #define RESVSIZE ((RESWEIGHT/2)*(RESHEIGHT/2))
- #define PRESIZE ((PREYSIZE)+(PREUSIZE)+(PREVSIZE))
- #define RESSIZE ((RESYSIZE)+(RESUSIZE)+(RESVSIZE))
- int GetFrameNum(const char *File)
- {
- FILE *fp;
- int size=0;
- if (!(fp=fopen(File,"rb")))
- {
- printf("Open %s error !",File);
- exit(1);
- }
- else
- {
- fseek(fp,0,SEEK_END);/*將文件指針移到YUV文件的末尾*/
- size=ftell(fp);/*計算文件的總大小*/
- }
- return (size/PRESIZE);
- }
- void ReadYUV(char *ResBuf,char *PreBuf,int resstart,int prestart,int resoffset,int preoffset,int size,int height)
- {
- int k;
- for (k=0;k<height;k++)
- {
- memmove(ResBuf+resstart+k*(resoffset),PreBuf+prestart+k*(preoffset),size);//注意這裏用memmov不用strncpy
- }
- }
- int main(int argc,char *argv[])
- {
- const char *FileName[]={"e:\BMX_L_1920x1080_240frms.yuv","e:\BMX_R_1920x1080_240frms.yuv"};/*兩路YUV文件名*/
- FILE *FileResult;/*輸出文件名*/
- FILE** fp_combine=(FILE**)malloc(sizeof(FILE *)*3);/*申請文件指針*/
- int *FileFrameNum=(int *)malloc(sizeof(int)*3);/*每個YUV的幀數*/
- char *PreBuf=(char *)malloc(sizeof(char)*(PRESIZE+1));/*處理前每一幀圖像的大小*/
- char *ResBuf=(char*)malloc(sizeof(char)*(RESSIZE+1));/*處理後每一幀圖像的大小*/
- int Y_start_section=0;/*預處理圖片Y分量存入目標區域的起始區域*/
- int U_start_section = 0;/*預處理圖片U分量存入目標區域的起始區域*/
- int V_start_section = 0;/*預處理圖片V分量存入目標區域的起始區域*/
- int File_offset = 0;/*預處理文件偏移值*/
- int i_combine=0,j_combine=0,k_combine=0;/*控制循環*/
- /*判斷申請內存是否成功*/
- if (!((fp_combine)&&(FileFrameNum)&&(PreBuf)&&(ResBuf)))
- {
- printf("Allocate memeroy Faile !");
- exit(1);
- }
- /*初始化申請空間*/
- memset(fp_combine,0,sizeof(FILE *)*2);
- memset(FileFrameNum,0,sizeof(int)*2);
- memset(PreBuf,0,sizeof(char)*PRESIZE);
- memset(ResBuf,0,sizeof(char)*RESSIZE);
- if (!(FileResult=fopen("hua_result.YUV","wb")))/*創建輸出文件*/
- {
- printf("Creat File faile !");
- exit(1);
- }
- for (i_combine=0;i_combine<2;i_combine++)
- {
- if(!(fp_combine[i_combine]=fopen(FileName[i_combine],"rb")))/*打開輸入文件*/
- {
- printf("Open File %s Faile !",FileName[i_combine]);
- exit(1);
- }
- else
- {
- FileFrameNum[i_combine]=GetFrameNum(FileName[i_combine]);/*存儲每一個視頻的幀數*/
- }
- }
- i_combine=0;
- k_combine=FileFrameNum[i_combine];
- while (i_combine<k_combine)
- {
- File_offset = i_combine*PRESIZE;
- j_combine=0;
- while (j_combine<2)
- {
- fseek(fp_combine[j_combine],File_offset,SEEK_SET);/*移動文件指針至需要處理的數據的位置*/
- fread(PreBuf,1,PRESIZE,fp_combine[j_combine]);/*讀取一幅圖像*/
- if (j_combine==0)
- {
- /*把讀取預處理圖片Y/U/V分量的起始位置放置目標對應位置*/
- Y_start_section=0;
- U_start_section=RESYSIZE;
- V_start_section=RESYSIZE+RESUSIZE;
- }
- else
- {
- /*把讀取預處理圖片Y/U/V分量的起始位置放置目標對應位置*/
- Y_start_section=PREWEIGHT;
- U_start_section=RESYSIZE+PREWEIGHT/2;
- V_start_section=RESYSIZE+RESUSIZE+PREWEIGHT/2;
- }
- /*分別讀Y、U、V*/
- ReadYUV(ResBuf,PreBuf,Y_start_section,0, RESWEIGHT,PREWEIGHT,PREWEIGHT,PREHEIGHT);
- ReadYUV(ResBuf,PreBuf,U_start_section,PREYSIZE, RESWEIGHT/2,PREWEIGHT/2,PREWEIGHT/2,PREHEIGHT/2);
- ReadYUV(ResBuf,PreBuf,V_start_section,PREYSIZE+PREUSIZE, RESWEIGHT/2,PREWEIGHT/2,PREWEIGHT/2,PREHEIGHT/2);
- j_combine++;
- }
- fwrite(ResBuf,1,RESSIZE,FileResult);
- fflush(FileResult);
- i_combine++;
- }
- fclose(fp_combine[0]);
- fclose(fp_combine[1]);
- fclose(FileResult);
- return 0;
- }
一行一行地讀圖片。
PRE RES
Y W * H Y 2W * H
U W/2 * H/2 U W * H/2
V W/2 * H/2 V W * H/2