可伸缩视频编码程序.docx
《可伸缩视频编码程序.docx》由会员分享,可在线阅读,更多相关《可伸缩视频编码程序.docx(25页珍藏版)》请在冰豆网上搜索。
可伸缩视频编码程序
#include
#include
#include
#include
#defineMAXSIZE352*288
#defineWIDTH352
#defineLENGTH288
#defineGOP16
#defineBLOCKTYPE4//BLOCKTYPE为块的大小4,实质是把视频分成4*4的方块
FILE*p_in=NULL;
FILE*p_out=NULL;
FILE*text=NULL;
//charfilename0="crew.yuv";
//charfilename1="crew_left.yuv";
//charfilename2="flower.yuv";
//charfilename3="flower_lift.yuv";
intABANDONED,GOPNUM;
structqualevy
{
doubleframeY[MAXSIZE];
doubleframeU[MAXSIZE/4];
doubleframeV[MAXSIZE/4];
}yuan[GOP];//Y:
U:
V=4:
1:
1表示4:
1的水平取样,没有垂直下采样。
structqua
{
doubleframeY[MAXSIZE];
doubleframeU[MAXSIZE/4];
doubleframeV[MAXSIZE/4];
}yuan1[GOP];//Y:
U:
V=4:
1:
1表示4:
1的水平取样,没有垂直下采样。
intMVX[GOP-1][MAXSIZE/(BLOCKTYPE*BLOCKTYPE)]={0};
intMVY[GOP-1][MAXSIZE/(BLOCKTYPE*BLOCKTYPE)]={0};
unsignedcharbitvecY[LENGTH][WIDTH];
unsignedcharbitvecUV[LENGTH/2][WIDTH/2];
voidreadoneframe(inti);
voidreadoneGOP();
voidmotionestimate(double*s,double*p,intsrc);
voidgetLH(intsrc,double*sy,double*su,double*sv,double*py,double*pu,double*pv);
voidsearch(intsrc);
voiddecode(intsrc,double*sy,double*su,double*sv,double*py,double*pu,double*pv);
voidprosessOneGOP();
voidfind_snr(float*a,float*b,float*c,intsrc,double*y,double*u,double*v);
intmain(void)
{
registerinti;
doubletotal_time=0.0f;
doubletotal_cost=0.0f;
charletter;
printf("#####################################\n");
printf("##\n");
printf("#此程序为基于哈尔小波的提升实现方案#\n");
printf("#ZZIA_WXJ#\n");
printf("#####################################\n");
printf("请输入您要丢弃的帧数:
\n");
scanf("%d",&ABANDONED);
GOPNUM=8;
printf("您确定要舍弃%d帧?
\n",ABANDONED);
printf("确认请按:
Y,否则请按其它键.\n");
getchar();
scanf("%c",&letter);
if((letter=='y')||(letter=='Y'))
{
printf("系统运行中,请稍等……\n");
if((p_in=fopen("crew.yuv","rb"))==NULL)
{
printf("Inputfile%sdoesnotexist\n","crew.yuv");
exit
(1);
}
//新建输出文件
if((p_out=fopen("crew_lift.yuv","wb"))==NULL)
{
printf("can'tcreatfile%s","crew_lift.yuv");
}
if((text=fopen("stat.txt","wb"))==NULL)
{
printf("can'tcreatfile%s","stat.txt");
}
for(i=0;i{
registerclock_tbegin=0;
registerclock_tend=0;
registerdoublecost=0;
begin=clock();
/*程序代码*/
prosessOneGOP();
//printf("完成第%d个GOP的处理!
\n",i+1);
end=clock();
cost=(double)(end-begin)/CLOCKS_PER_SEC;
printf("完成第%d个GOP的处理,所使用的时间:
%lfseconds.\n\n",i+1,cost);
total_cost+=cost;
//printf("总共用时:
%lfseconds\n",total_cost);
}
printf("总共耗时:
%.4fseconds\n",total_cost);
printf("程序运行结束!
\n");
}
else
exit(0);
return0;
}
/*************************************
编解码一组数据
******************************************/
voidprosessOneGOP()
{
double*fmy[GOP];
double*fmu[GOP];
double*fmv[GOP];
floatpsnr[GOP][3];
registerinti,j,y,a;
readoneGOP();//读入一组数据
for(i=0;i{
fmy[i]=yuan[i].frameY;
fmu[i]=yuan[i].frameU;
fmv[i]=yuan[i].frameV;
}
for(i=1;i{
motionestimate(fmy[i],fmy[i-1],i);
getLH(i,fmy[i],fmu[i],fmv[i],fmy[i-1],fmu[i-1],fmv[i-1]);
}//一级提升
j=GOP/2;
if(j>1)
{
j=j/2;
for(i=2;i{
motionestimate(fmy[i],fmy[i-2],i);
getLH(i,fmy[i],fmu[i],fmv[i],fmy[i-2],fmu[i-2],fmv[i-2]);
}
}//二级提升
if(j>1)
{
j=j/2;
for(i=4;i{
motionestimate(fmy[i],fmy[i-4],i);
getLH(i,fmy[i],fmu[i],fmv[i],fmy[i-4],fmu[i-4],fmv[i-4]);
}
}//三级提升
if(j>1)
{
j=j/2;
for(i=8;i{
motionestimate(fmy[i],fmy[i-8],i);
getLH(i,fmy[i],fmu[i],fmv[i],fmy[i-8],fmu[i-8],fmv[i-8]);
}
}//四级提升
if(j>1)
{
j=j/2;
for(i=16;i{
motionestimate(fmy[i],fmy[i-16],i);
getLH(i,fmy[i],fmu[i],fmv[i],fmy[i-16],fmu[i-16],fmv[i-16]);
}
}//五级提升
if(j>1)
printf("ThebiggestnumberofGOPis32!
");
a=1;
j=ABANDONED;
while((a<16)&&(j>0))
{
for(y=0;y*(fmy[a]+y)=0;
for(y=0;y{
*(fmu[a]+y)=0;
*(fmv[a]+y)=0;
}
a=a+2;
--j;
}
a=2;
while((a<16)&&(j>0))
{
for(y=0;y*(fmy[a]+y)=0;
for(y=0;y{
*(fmu[a]+y)=0;
*(fmv[a]+y)=0;
}
a=a+4;
--j;
}
a=4;
while((a<16)&&(j>0))
{
for(y=0;y*(fmy[a]+y)=0;
for(y=0;y{
*(fmu[a]+y)=0;
*(fmv[a]+y)=0;
}
a=a+8;
--j;
}
a=8;
if(j>0)
{
for(y=0;y*(fmy[a]+y)=0;
for(y=0;y{
*(fmu[a]+y)=0;
*(fmv[a]+y)=0;
}
--j;
}
if(j>0)
printf("最多可以丢弃15帧!
");
//解码
decode(8,fmy[8],fmu[8],fmv[8],fmy[0],fmu[0],fmv[0]);
decode(4,fmy[4],fmu[4],fmv[4],fmy[0],fmu[0],fmv[0]);
decode(12,fmy[12],fmu[12],fmv[12],fmy[8],fmu[8],fmv[8]);
decode(2,fmy[2],fmu[2],fmv[2],fmy[0],fmu[0],fmv[0]);
decode(6,fmy[6],fmu[6],fmv[6],fmy[4],fmu[4],fmv[4]);
decode(10,fmy[10],fmu[10],fmv[10],fmy[8],fmu[8],fmv[8]);
decode(14,fmy[14],fmu[14],fmv[14],fmy[12],fmu[12],fmv[12]);
decode(1,fmy[1],fmu[1],fmv[1],fmy[0],fmu[0],fmv[0]);
decode(3,fmy[3],fmu[3],fmv[3],fmy[2],fmu[2],fmv[2]);
decode(5,fmy[5],fmu[5],fmv[5],fmy[4],fmu[4],fmv[4]);
decode(7,fmy[7],fmu[7],fmv[7],fmy[6],fmu[6],fmv[6]);
decode(9,fmy[9],fmu[9],fmv[9],fmy[8],fmu[8],fmv[8]);
decode(11,fmy[11],fmu[11],fmv[11],fmy[10],fmu[10],fmv[10]);
decode(13,fmy[13],fmu[13],fmv[13],fmy[12],fmu[12],fmv[12]);
decode(15,fmy[15],fmu[15],fmv[15],fmy[14],fmu[14],fmv[14]);
for(i=0;ifind_snr(&psnr[i][0],&psnr[i][1],&psnr[i][2],i,fmy[i],fmu[i],fmv[i]);
for(i=0;i{
fprintf(text,"\n%f",psnr[i][0]);
fprintf(text,"%f",psnr[i][1]);
fprintf(text,"%f",psnr[i][2]);
}
for(i=0;i{
for(y=0;yfprintf(p_out,"%c",(unsignedchar)(*(fmy[i]+y)));
for(y=0;yfprintf(p_out,"%c",(unsignedchar)(*(fmu[i]+y)));
for(y=0;yfprintf(p_out,"%c",(unsignedchar)(*(fmv[i]+y)));
}
}
/********************************************
读取一组数据到数组中
*********************************************/
voidreadoneGOP()
{
inti=0;
for(i=0;ireadoneframe(i);
}
/************************************************
读入一帧图像到charframeY[i][WIDTH][LENGTH];
charframeU[i][WIDTH/2][LENGTH/2];
charframeV[i][WIDTH/2][LENGTH/2];
*************************************************/
voidreadoneframe(inti)
{
registerinty;
unsignedcharfry[MAXSIZE]={0};
unsignedcharfru[MAXSIZE/4]={0};
unsignedcharfrv[MAXSIZE/4]={0};
if(fread(fry,1,MAXSIZE,p_in)!
=MAXSIZE)
printf("ReadOneFrame:
cannotread%dbytesfrominputfile,unexpectedEOF?
exiting",MAXSIZE);
if(fread(fru,1,MAXSIZE/4,p_in)!
=MAXSIZE/4)
printf("ReadOneFrame:
cannotread%dbytesfrominputfile,unexpectedEOF?
exiting",MAXSIZE/4);
if(fread(frv,1,MAXSIZE/4,p_in)!
=MAXSIZE/4)
printf("ReadOneFrame:
cannotread%dbytesfrominputfile,unexpectedEOF?
exiting",MAXSIZE/4);
for(y=0;y{
yuan[i].frameY[y]=fry[y];
yuan1[i].frameY[y]=fry[y];
}
for(y=0;y{
yuan[i].frameU[y]=fru[y];
yuan1[i].frameU[y]=fru[y];
yuan[i].frameV[y]=frv[y];
yuan1[i].frameV[y]=frv[y];
}
}
/******************************************
brife:
motionestimate
in:
sourceframe,refrenceframe,searchrange
out:
MV[src-1]
*******************************************/
voidmotionestimate(double*s,double*p,intsrc)
{
//全搜索
registerintpic_x=0;
registerintpic_y=0;
registerintpic_xref=0;
registerintpic_yref=0;
registerinta,i,j,x,y;
for(a=0;a{
unsignedsad=~0U;
unsignedcharacc=0;
for(x=-4;x<=4;x++)
{
pic_xref=pic_x+x;
if(pic_xref<0)
continue;
if(pic_xref>(WIDTH-BLOCKTYPE))
continue;
for(y=-4;y<=4;y++)
{
pic_yref=pic_y+y;
if(pic_yref<0)
continue;
if(pic_yref>(LENGTH-BLOCKTYPE))
continue;
for(j=0;jfor(i=0;iacc+=abs(*(s+(pic_y+j)*WIDTH+pic_x+i)-*(p+(pic_yref+j)*WIDTH+pic_xref+i));
if(acc{
sad=acc;
MVX[src-1][a]=x;
MVY[src-1][a]=y;
}
}
}
pic_x+=BLOCKTYPE;
if(((a+1)*BLOCKTYPE)%WIDTH==0)
{pic_x=0;
pic_y+=BLOCKTYPE;
}
}
}
/**************************************************
brief:
getlowandhighfrequencyframe
in:
sourceframe,refrenceframe
out:
lowandhighfrequencyframe,bitvecY,bitvecuv
**************************************************/
voidgetLH(intsrc,double*sy,double*su,double*sv,double*py,double*pu,double*pv)
{
registerintpic_x=0;
registerintpic_y=0;
registerintpic_xref=0;
registerintpic_yref=0;
registerintpic_xuvref=0;
registerintpic_yuvref=0;
registerintpic_uvx=0;
registerintpic_uvy=0;
registerinta,i,j,x,y;
unsignedcharbitvecY[LENGTH][WIDTH];
unsignedcharbitvecUV[LENGTH/2][WIDTH/2];
for(y=0;yfor(x=0;xbitvecY[y][x]=0;
for(a=0;a{
//获得高频子带
pic_xref=pic_x+MVX[src-1][a];
pic_yref=pic_y+MVY[src-1][a];
for(j=0;jfor(i=0;i*(sy+(pic_y+j)*WIDTH+pic_x+i)=(*(sy+(pic_y+j)*WIDTH+pic_x+i)-*(py+(pic_yref+j)*WIDTH+pic_xref+i))/2;
pic_xuvref=pic_uvx+(MVX[src-1][a])/2;
pic_yuvref=pic_uvy+(MVY[src-1][a])/2;
for(j=0;j<(BLOCKTYPE/2);j++)
for(i=0;i<(BLOCKTYPE/2);i++)
{
*(su+(pic_uvy+j)*WIDTH/2+pic_uvx+i)=(*(su+(pic_uvy+j)*WIDTH/2+pic_uvx+i)-*(pu+(pic_yuvref+j)*WIDTH/2+pic_xuvref+i))/2;
*(sv+(pic_uvy+j)*WIDTH/2+pic_uvx+i)=(*(sv+(pic_uvy+j)*WIDTH/2+pic_uvx+i)-*(pv+(pic_yuvref+j)*WIDTH/2+pic_xuvref+i))/2;
}
////参考中心更新
pic_x+=BLOCKTYPE;
if(((a+1)*BLOCKTYPE)%WIDTH==0)
{pic_x=0;
pic_y+=BLOCKTYPE;
}
pic_uvx+=BLOCKTYPE/2;
if(((a+1)*BLOCKTYPE)%WIDTH==0)
{pic_uvx=0;