📄 mpeg2dec.cpp
字号:
pMPG2->cur_position=_telli64(ld->Infile);
break;
}
}
else //连续解码
{
if(CurFrame<=frameno+framenum)
{
char str[100];
sprintf( str, "CurFrame=%d", CurFrame);
// ::MessageBox(NULL,str,"okMPG2GetHeader",MB_OK);
Decode_Picture(frameno,frameno,Framedst1);
//转换并存储
SaveFrame(Framedst1,dst,Mode,&offset,stride);
//存储帧累加
decode_Framenum++;
pMPG2->frameno++;
pMPG2->hour=hour;
pMPG2->minute=minute;
pMPG2->sec=sec;
pMPG2->frame=frame;
pMPG2->lframe=lframe;
pMPG2->cur_bitno=frameno;
if(pMPG2->mode==0)
pMPG2->cur_position=_telli64(pMPG2->infile);
break;
}
}
}
///////////////////////////////
//若首帧序号超过实际帧数,则存储帧数为0
//释放缓存
for(i=0;i<3;i++)
{
pMPG2->backward_reference_frame[i]=backward_reference_frame[i];
pMPG2->forward_reference_frame[i]=forward_reference_frame[i];
pMPG2->auxframe[i]=auxframe[i];
}
memcpy(pMPG2->ld,&base,sizeof(layer_data));
remain=base.length;
free(Framedst1);
GlobalUnlock(hMPG2);
return remain; //返回实际解码帧数
}
HANDLE okMPG2BeginDecodeEx(LPSTR infile,LPBYTE lpData,LPARAM lpParam)
{
// ::MessageBox(NULL,NULL,"okMPG2BeginDecodeEx",MB_OK);
HANDLE hMPG2;
environment_data *pMPG2;
hMPG2=GlobalAlloc(GHND,sizeof(environment_data));
if(!hMPG2)
Error("alloc hDecode mem fail");
pMPG2=(environment_data *)GlobalLock(hMPG2);
pMPG2->hFilesize=sizeof(environment_data);
// pMPG2->ld=(layer_data*)malloc(sizeof(layer_data));
pMPG2->ld=(layer_data*)GlobalAlloc(GPTR,sizeof(layer_data));
ld=&base;
if(infile)
{
pMPG2->mode=0;
pMPG2->ld->Infile=_open(infile,O_RDONLY|O_BINARY);
pMPG2->ld->mode=0;
pMPG2->frameno=1;
}
else
{
pMPG2->mode=1;
pMPG2->ld->mode=1;
pMPG2->frameno=1;
}
init_dither_tab();
Initialize_Decoder();
long total;
char temp[16];
mpg2_header_info *head;
head=(mpg2_header_info*)lpParam;
total=head->totalframe;
pMPG2=(environment_data *)GlobalLock(hMPG2);
memcpy(&base,pMPG2->ld,sizeof(layer_data));
hour=pMPG2->hour;
minute=pMPG2->minute;
sec=pMPG2->sec;
frame=pMPG2->frame;
thour=pMPG2->thour;
tminute=pMPG2->tminute;
tsec=pMPG2->tsec;
tframe=pMPG2->tframe;
check_stream(pMPG2,lpData);
GetParam(pMPG2,lpData);
if(pMPG2->mode==0)
{
GetTotalFrame(hMPG2,&total);
}
TotalFrame=total;
head->headsize=sizeof(header_data);
head->totalframe=total;
head->bit_rate=bit_rate;
head->frame_rate=frame_rate;
head->color=24;
pMPG2->width=horizontal_size;
pMPG2->height=vertical_size;
pMPG2->OK_ID=OK_ID;
if(fabs(factor-1.000)>0.001)
head->horizontal_size=WIDTHBYTES((int)((double)horizontal_size*factor))*8;
else
head->horizontal_size=horizontal_size;
head->vertical_size=vertical_size;
pMPG2->factor=factor;
pMPG2->mb_height=mb_height;
pMPG2->mb_width=mb_width;
pMPG2->Chroma_Width =Chroma_Width ;
pMPG2->Chroma_Height=Chroma_Height ;
pMPG2->block_count=block_count;
pMPG2->FileSize=FileSize;
pMPG2->frame_rate=frame_rate;
for (int cc=0; cc<3; cc++)
{
long size=0;
if (cc==0)
size = Coded_Picture_Width*Coded_Picture_Height;
else
size = Chroma_Width*Chroma_Height;
pMPG2->backward_reference_frame[cc] = (unsigned char *)malloc(size);
pMPG2->forward_reference_frame[cc] = (unsigned char *)malloc(size);
pMPG2->auxframe[cc] = (unsigned char *)malloc(size);
}
if(pMPG2->mode==0)
pMPG2->total=total;
else
pMPG2->total=100;
memcpy(pMPG2->ld,&base,sizeof(layer_data));
GlobalUnlock(hMPG2);
return hMPG2;
}
void okMPG2EndDecodeEx(HANDLE hMPG2)
{
// ::MessageBox(NULL,NULL,"okMPG2EndDecodeEx",MB_OK);
environment_data *pMPG2;
pMPG2=(environment_data *)GlobalLock(hMPG2);
memcpy(&base,pMPG2->ld,sizeof(layer_data));
for(int i=0;i<3;i++)
{
backward_reference_frame[i]=pMPG2->backward_reference_frame[i];
forward_reference_frame[i]=pMPG2->forward_reference_frame[i];
auxframe[i]=pMPG2->auxframe[i];
}
AUDIO=false;
SEQEND=false;
ClearGlobal();
Initialize_Buffer();
Deinitialize_Sequence();
if(pMPG2->mode==0)
_close(pMPG2->ld->Infile);
//free(pMPG2->ld);
GlobalFree(pMPG2->ld);
GlobalUnlock(hMPG2);
GlobalFree(hMPG2);
}
long okMPG2ReadFrameEx(HANDLE hMPG2,LPBYTE lpBuf, long lParam, LPBYTE dst,long stride,LPARAM lpParam)
{
// ::MessageBox(NULL,NULL,"okMPG2ReadFrameEx",MB_OK);
//分配存储空间
long offset=0; //存储偏移量
unsigned char *Framedst1; //解码缓存指针
environment_data *pMPG2; //文件指针
short decode_Framenum; //实际解码帧数
short N,M; //N,M变量
short cal; //跳跃解码间隔
long CurFrame=0; //当前帧号
long lframe=0; //图像组内序号
BOOL SKIP; //跳跃解码标记
_int64 filecur; //粗略文件位置
_int64 interval; //文件位置跨度
BOOL BACK; //文件位置后向查找标记
BOOL FirstI; //图像组位置标记
long frameno;
long framenum=1;
long Mode=2;
long TotalFrame;
long remain=0;
long tlframe=0;
long b,e;
mpg2_frame_info *info;
info=(mpg2_frame_info *)lpParam;
long skip;
if(info)
skip=info->skip;
else
skip=0;
pMPG2=(environment_data *)GlobalLock(hMPG2); //分配环境变量
if(pMPG2->mode==0)
frameno=lParam+1;
else
frameno=pMPG2->frameno;
for(int i=0;i<3;i++)
{
backward_reference_frame[i]=pMPG2->backward_reference_frame[i];
forward_reference_frame[i]=pMPG2->forward_reference_frame[i];
auxframe[i]=pMPG2->auxframe[i];
}
b=tell(pMPG2->ld->Infile);
horizontal_size=pMPG2->width;
vertical_size=pMPG2->height;
memcpy(&base,pMPG2->ld,sizeof(layer_data));
mb_height=pMPG2->mb_height;
mb_width=pMPG2->mb_width;
System_Stream_Flag=pMPG2->System_Stream_Flag;
factor=pMPG2->factor;
TotalFrame=pMPG2->total;
Coded_Picture_Height=pMPG2->height;
Coded_Picture_Width=pMPG2->width;
Chroma_Width = pMPG2->Chroma_Width;
Chroma_Height = pMPG2->Chroma_Height;
block_count=pMPG2->block_count;
OK_ID=pMPG2->OK_ID;
FileSize=pMPG2->FileSize;
TotalFrame=pMPG2->total;
frame_rate=pMPG2->frame_rate;
//分配存储空间
Framedst1=(unsigned char*)malloc(Coded_Picture_Height*Coded_Picture_Width*3);
if(!Framedst1)
Error("alloc frame mem fail");
if(frameno-1>=pMPG2->total) //若帧号大于总帧数则返回0
{
memset(Framedst1,0,Coded_Picture_Height*Coded_Picture_Width*3);
SaveFrame(Framedst1,dst,Mode,&offset,stride);
return 0;
}
//初始化
N=pMPG2->N;
M=pMPG2->M;
decode_Framenum=0;
cal=N+M+1;
interval=4*(N+M+1);
AUDIO=false;
SEQEND=false;
FirstI=false;
SKIP=true;
if(frameno==pMPG2->cur_bitno+1)
{
if(pMPG2->mode==0)
{
//连续解码
SKIP=false;
//初始化播放时间
base.length=0;
//指向当前帧位置
_lseeki64(ld->Infile,pMPG2->cur_position,SEEK_SET);
}
else
{
//连续解码
if(frameno==1)
base.lpData=lpBuf;
base.length=0;
base.size=lParam;
SKIP=false;
//初始化播放时间
}
hour=pMPG2->hour;
minute=pMPG2->minute;
sec=pMPG2->sec;
lframe=pMPG2->lframe;
frame=pMPG2->frame;
thour=pMPG2->thour;
tminute=pMPG2->tminute;
tsec=pMPG2->tsec;
tlframe=pMPG2->tlframe;
tframe=pMPG2->tframe;
}
else
{
for (int cc=0; cc<3; cc++)
{
long size;
if (cc==0)
size = Coded_Picture_Width*Coded_Picture_Height;
else
size = Chroma_Width*Chroma_Height;
memset(backward_reference_frame[cc],0,size);
memset(forward_reference_frame[cc],0,size);
memset(auxframe[cc],0,size);
}
thour=pMPG2->thour;
tminute=pMPG2->tminute;
tsec=pMPG2->tsec;
tlframe=pMPG2->tlframe;
tframe=pMPG2->tframe;
//跳跃解码
//计算粗略文件位置
filecur=FileSize*(_int64)(frameno-interval)/(_int64)(TotalFrame);
filecur=filecur/2048*2048;
if(filecur>=0)
_lseeki64(ld->Infile,filecur,SEEK_SET);
else
lseek(ld->Infile,0l,SEEK_SET);
Initialize_Buffer();
//精确定位
if(frameno>4*cal)
{
BACK=false;
_int64 Ioffset;
while(1)
{
Ioffset=_telli64(ld->Infile);
if(!Headers())
{
lseek(ld->Infile,0l,SEEK_SET);
SEQEND=false;
break;
}
if(picture_coding_type==I_TYPE)
{
CurFrame=((hour-thour)*3600+(minute-tminute)*60+(sec-tsec))*(int)(frame_rate+0.5)+(frame-tframe+1);
//粗略位置超过实际位置
if(CurFrame>frameno-cal)
{
BACK=true;
//跨度增加一个间隔
interval+=4*(N+M+1);
filecur=FileSize*(_int64)(frameno-interval)/(_int64)(TotalFrame);
filecur=filecur/2048*2048;
if(filecur>=0)
_lseeki64(ld->Infile,filecur,SEEK_SET);
else
lseek(ld->Infile,0l,SEEK_SET);
}
else if(!BACK&&frameno-cal-CurFrame>4*(N+M+1))
{
//粗略位置小于实际位置超过一个跨度
//减少一个跨度
interval-=4*(N+M+1);
filecur=FileSize*(_int64)(frameno-interval)/(_int64)(TotalFrame);
filecur=filecur/2048*2048;
if(filecur>=0)
_lseeki64(ld->Infile,filecur,SEEK_SET);
else
lseek(ld->Infile,0l,SEEK_SET);
}
else
{
lseek(ld->Infile,Ioffset,SEEK_SET);
break;
}
}
}
Initialize_Buffer();
}
}
//开始解码
SEQEND=false; //文件末尾标记
while(1)
{
if(!Headers())
{
pMPG2->hour=hour;
pMPG2->minute=minute;
pMPG2->sec=sec;
pMPG2->frame=frame;
pMPG2->lframe=lframe;
pMPG2->cur_bitno=frameno;
pMPG2->cur_position=_telli64(ld->Infile);
//读文件尾
if(frameno==TotalFrame)
{
//存储最后一帧
Output_Last_Frame_of_Sequence(CurFrame,Framedst1);
SaveFrame(Framedst1,dst,Mode,&offset,stride);
decode_Framenum++;
}
break;
}
if(picture_coding_type==I_TYPE)
{
//寻找图像组首位置
FirstI=true;
lframe=0; //组内序号归零
}
else
{
//若不是图像组首且为非连续解码,则继续寻找。
if(!FirstI&&SKIP)
continue;
lframe++; //组内序号加1
}
//计算当前帧号
CurFrame=((hour-thour)*3600+(minute-tminute)*60+(sec-tsec))*(int)(frame_rate+0.5)+(frame-tframe+1+lframe);
//若当前帧号大于解码帧号,则结束循环
if(CurFrame>frameno+framenum)
{
memset(Framedst1,0,Coded_Picture_Height*Coded_Picture_Width*3);
SaveFrame(Framedst1,dst,Mode,&offset,stride);
break;
}
//跳跃解码
if(SKIP)
{
if(FirstI)
{
Decode_Picture(CurFrame, CurFrame,Framedst1);
//若等于解码帧号转换并存储
SaveFrame(Framedst1,dst,Mode,&offset,stride);
//存储帧累加
decode_Framenum++;
pMPG2->hour=hour;
pMPG2->minute=minute;
pMPG2->sec=sec;
pMPG2->frame=frame;
pMPG2->lframe=lframe;
pMPG2->cur_bitno=frameno;
pMPG2->cur_position=_telli64(ld->Infile);
break;
}
/* //若当前帧号大于等于解码间隔
if(CurFrame>=frameno-cal&&CurFrame<=frameno+framenum)
{
//解码
if(!skip)
Decode_Picture(CurFrame, CurFrame,Framedst1);
if(CurFrame==frameno)
{
if(info)
info->frame_type=picture_coding_type;
}
//若等于解码帧号转换并存储
if(CurFrame==frameno+1)
{
SaveFrame(Framedst1,dst,Mode,&offset,stride);
//存储帧累加
decode_Framenum++;
}
}
//若等于解码帧号,结束循环,并存储相关信息
if(CurFrame==frameno+framenum)
{
pMPG2->hour=hour;
pMPG2->minute=minute;
pMPG2->sec=sec;
pMPG2->frame=frame;
pMPG2->lframe=lframe;
pMPG2->cur_bitno=frameno;
pMPG2->cur_position=_telli64(ld->Infile);
break;
}*/
}
else //连续解码
{
if(CurFrame<=frameno+framenum)
{
if(!skip)
Decode_Picture(CurFrame,CurFrame,Framedst1);
if(CurFrame==frameno)
{
if(info)
info->frame_type=picture_coding_type;
}
//转换并存储
if(CurFrame==frameno+1)
{
SaveFra
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -