2個YUV視頻 拼接技術

http://blog.csdn.net/huahuahailang/article/details/9040847

  1. * 主要功能:兩路 YUV4:2:0拼接一路左右半寬格式YUV視頻 
  2. 參考資料:http://www.pudn.com/downloads271/sourcecode/multimedia/vfw/detail1237363.html 
  3. U_size=V_size=Y_size/2 
  4. *************************************************/  
  5. #include<stdio.h>  
  6. #include<stdlib.h>  
  7. #include<string.h>  
  8. #define PREWEIGHT 1920  
  9. #define PREHEIGHT 1080  
  10. #define RESWEIGHT 3840  
  11. #define RESHEIGHT 1080  
  12. #define PREYSIZE ((PREWEIGHT)*(PREHEIGHT))  
  13. #define PREUSIZE ((PREWEIGHT/2)*(PREHEIGHT/2))  
  14. #define PREVSIZE ((PREWEIGHT/2)*(PREHEIGHT/2))  
  15. #define RESYSIZE ((RESWEIGHT)*(RESHEIGHT))  
  16. #define RESUSIZE ((RESWEIGHT/2)*(RESHEIGHT/2))  
  17. #define RESVSIZE ((RESWEIGHT/2)*(RESHEIGHT/2))  
  18. #define PRESIZE ((PREYSIZE)+(PREUSIZE)+(PREVSIZE))  
  19. #define RESSIZE ((RESYSIZE)+(RESUSIZE)+(RESVSIZE))  
  20.   
  21. int GetFrameNum(const char *File)  
  22. {  
  23.     FILE *fp;  
  24.     int size=0;  
  25.     if (!(fp=fopen(File,"rb")))  
  26.     {  
  27.         printf("Open %s error !",File);  
  28.         exit(1);  
  29.     }   
  30.     else  
  31.     {  
  32.         fseek(fp,0,SEEK_END);/*將文件指針移到YUV文件的末尾*/    
  33.         size=ftell(fp);/*計算文件的總大小*/  
  34.     }  
  35.     return (size/PRESIZE);  
  36. }  
  37. void ReadYUV(char *ResBuf,char *PreBuf,int resstart,int prestart,int resoffset,int preoffset,int size,int height)  
  38. {  
  39.     int k;  
  40.     for (k=0;k<height;k++)  
  41.     {  
  42.         memmove(ResBuf+resstart+k*(resoffset),PreBuf+prestart+k*(preoffset),size);//注意這裏用memmov不用strncpy  
  43.     }  
  44. }  
  45. int main(int argc,char *argv[])  
  46. {  
  47.     const char *FileName[]={"e:\BMX_L_1920x1080_240frms.yuv","e:\BMX_R_1920x1080_240frms.yuv"};/*兩路YUV文件名*/  
  48.     FILE *FileResult;/*輸出文件名*/  
  49.     FILE** fp_combine=(FILE**)malloc(sizeof(FILE *)*3);/*申請文件指針*/  
  50.     int *FileFrameNum=(int *)malloc(sizeof(int)*3);/*每個YUV的幀數*/  
  51.     char *PreBuf=(char *)malloc(sizeof(char)*(PRESIZE+1));/*處理前每一幀圖像的大小*/  
  52.     char *ResBuf=(char*)malloc(sizeof(char)*(RESSIZE+1));/*處理後每一幀圖像的大小*/  
  53.     int Y_start_section=0;/*預處理圖片Y分量存入目標區域的起始區域*/  
  54.     int U_start_section = 0;/*預處理圖片U分量存入目標區域的起始區域*/  
  55.     int V_start_section = 0;/*預處理圖片V分量存入目標區域的起始區域*/  
  56.     int File_offset = 0;/*預處理文件偏移值*/      
  57.     int i_combine=0,j_combine=0,k_combine=0;/*控制循環*/  
  58.     /*判斷申請內存是否成功*/  
  59.     if (!((fp_combine)&&(FileFrameNum)&&(PreBuf)&&(ResBuf)))  
  60.     {  
  61.         printf("Allocate memeroy Faile !");  
  62.         exit(1);  
  63.     }   
  64.     /*初始化申請空間*/  
  65.     memset(fp_combine,0,sizeof(FILE *)*2);  
  66.     memset(FileFrameNum,0,sizeof(int)*2);  
  67.     memset(PreBuf,0,sizeof(char)*PRESIZE);  
  68.     memset(ResBuf,0,sizeof(char)*RESSIZE);  
  69.     if (!(FileResult=fopen("hua_result.YUV","wb")))/*創建輸出文件*/  
  70.     {  
  71.         printf("Creat File faile !");  
  72.         exit(1);  
  73.     }   
  74.     for (i_combine=0;i_combine<2;i_combine++)  
  75.     {  
  76.         if(!(fp_combine[i_combine]=fopen(FileName[i_combine],"rb")))/*打開輸入文件*/  
  77.         {  
  78.             printf("Open File %s Faile !",FileName[i_combine]);  
  79.             exit(1);  
  80.         }  
  81.         else  
  82.         {  
  83.             FileFrameNum[i_combine]=GetFrameNum(FileName[i_combine]);/*存儲每一個視頻的幀數*/  
  84.         }  
  85.     }  
  86.     i_combine=0;  
  87.     k_combine=FileFrameNum[i_combine];  
  88.     while (i_combine<k_combine)  
  89.     {  
  90.         File_offset = i_combine*PRESIZE;  
  91.         j_combine=0;  
  92.         while (j_combine<2)  
  93.         {  
  94.             fseek(fp_combine[j_combine],File_offset,SEEK_SET);/*移動文件指針至需要處理的數據的位置*/  
  95.             fread(PreBuf,1,PRESIZE,fp_combine[j_combine]);/*讀取一幅圖像*/  
  96.             if (j_combine==0)  
  97.             {  
  98.                 /*把讀取預處理圖片Y/U/V分量的起始位置放置目標對應位置*/  
  99.                 Y_start_section=0;  
  100.                 U_start_section=RESYSIZE;  
  101.                 V_start_section=RESYSIZE+RESUSIZE;  
  102.             }   
  103.             else  
  104.             {  
  105.                 /*把讀取預處理圖片Y/U/V分量的起始位置放置目標對應位置*/  
  106.                 Y_start_section=PREWEIGHT;  
  107.                 U_start_section=RESYSIZE+PREWEIGHT/2;  
  108.                 V_start_section=RESYSIZE+RESUSIZE+PREWEIGHT/2;  
  109.             }  
  110.             /*分別讀Y、U、V*/  
  111.             ReadYUV(ResBuf,PreBuf,Y_start_section,0,                 RESWEIGHT,PREWEIGHT,PREWEIGHT,PREHEIGHT);  
  112.             ReadYUV(ResBuf,PreBuf,U_start_section,PREYSIZE,          RESWEIGHT/2,PREWEIGHT/2,PREWEIGHT/2,PREHEIGHT/2);  
  113.             ReadYUV(ResBuf,PreBuf,V_start_section,PREYSIZE+PREUSIZE, RESWEIGHT/2,PREWEIGHT/2,PREWEIGHT/2,PREHEIGHT/2);  
  114.             j_combine++;  
  115.         }  
  116.         fwrite(ResBuf,1,RESSIZE,FileResult);  
  117.         fflush(FileResult);  
  118.         i_combine++;  
  119.     }  
  120.     fclose(fp_combine[0]);  
  121.     fclose(fp_combine[1]);  
  122.     fclose(FileResult);  
  123.     return 0;  
  124. }  

一行一行地讀圖片。

           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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章