📄 mpeg2dec.cpp
字号:
lseek(pDecode->infile,0l,SEEK_SET);
Initialize_Buffer();
//精确定位
if(frameno>4*cal)
{
BACK=false;
_int64 Ioffset;
while(1)
{
Ioffset=_telli64(pDecode->infile);
if(!Headers())
{
lseek(pDecode->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(pDecode->infile,filecur,SEEK_SET);
else
lseek(pDecode->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(pDecode->infile,filecur,SEEK_SET);
else
lseek(pDecode->infile,0l,SEEK_SET);
}
else
{
lseek(pDecode->infile,Ioffset,SEEK_SET);
break;
}
}
}
Initialize_Buffer();
}
}
//开始解码
ld->Infile=pDecode->infile;
SEQEND=false; //文件末尾标记
while(1)
{
if(!Headers() && SEQEND)
{
pDecode->hour=hour;
pDecode->minute=minute;
pDecode->sec=sec;
pDecode->frame=frame;
pDecode->lframe=lframe;
pDecode->cur_bitno=frameno;
pDecode->cur_position=_telli64(pDecode->infile);
//读文件尾
if(frameno==TotalFrame)
{
//存储最后一帧
// ::MessageBox(NULL,NULL,"frameno==TotalFrame",MB_OK);
Output_Last_Frame_of_Sequence(CurFrame,Framedst1);
pDecode->infile=base.Infile;
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)
{
// ::MessageBox(NULL,NULL,"CurFrame>frameno+framenum",MB_OK);
memset(Framedst1,0,Coded_Picture_Height*Coded_Picture_Width*3);
SaveFrame(Framedst1,dst,Mode,&offset,stride);
break;
}
//跳跃解码
if(SKIP)
{
//若当前帧号大于等于解码间隔
if(CurFrame>=frameno-cal&&CurFrame<=frameno+framenum)
{
//解码
Decode_Picture(CurFrame, CurFrame,Framedst1);
pDecode->infile=ld->Infile;
//若等于解码帧号转换并存储
if(CurFrame==frameno+1)
{
SaveFrame(Framedst1,dst,Mode,&offset,stride);
//存储帧累加
decode_Framenum++;
}
}
//若等于解码帧号,结束循环,并存储相关信息
if(CurFrame==frameno+framenum)
{
pDecode->hour=hour;
pDecode->minute=minute;
pDecode->sec=sec;
pDecode->frame=frame;
pDecode->lframe=lframe;
pDecode->cur_bitno=frameno;
pDecode->cur_position=_telli64(pDecode->infile);
break;
}
}
else //连续解码
{
if(CurFrame<=frameno+framenum)
{
Decode_Picture(CurFrame,CurFrame,Framedst1);
pDecode->infile=ld->Infile;
//转换并存储
if(CurFrame==frameno+1)
{
SaveFrame(Framedst1,dst,Mode,&offset,stride);
//存储帧累加
decode_Framenum++;
}
if(CurFrame==frameno+framenum)
{
pDecode->hour=hour;
pDecode->minute=minute;
pDecode->sec=sec;
pDecode->frame=frame;
pDecode->lframe=lframe;
pDecode->cur_bitno=frameno;
pDecode->cur_position=_telli64(pDecode->infile);
break;
}
}
}
}
///////////////////////////////
//若首帧序号超过实际帧数,则存储帧数为0
base.Infile=pDecode->infile;
//释放缓存
free(Framedst1);
GlobalUnlock(hDecode);
return decode_Framenum; //返回实际解码帧数
}
void ClearGlobal()
{
Coded_Picture_Width=0;
Coded_Picture_Height=0;
Chroma_Width=0;
Chroma_Height=0;
block_count=0;
Second_Field=0;
profile=0;
level=0;
horizontal_size=0;
vertical_size=0;
mb_width=0;
mb_height=0;
bit_rate=0;
frame_rate=0;
aspect_ratio_information=0;
frame_rate_code=0;
bit_rate_value=0;
vbv_buffer_size=0;
constrained_parameters_flag=0;
profile_and_level_indication=0;
progressive_sequence=0;
chroma_format=0;
low_delay=0;
frame_rate_extension_n=0;
frame_rate_extension_d=0;
video_format=0;
color_description=0;
color_primaries=0;
transfer_characteristics=0;
matrix_coefficients=0;
display_horizontal_size=0;
display_vertical_size=0;
temporal_reference=0;
picture_coding_type=0;
vbv_delay=0;
full_pel_forward_vector=0;
forward_f_code=0;
full_pel_backward_vector=0;
backward_f_code=0;
// f_code[2][2]=0;
memset(f_code,0,4);
intra_dc_precision=0;
picture_structure=0;
top_field_first=0;
frame_pred_frame_dct=0;
concealment_motion_vectors=0;
intra_vlc_format=0;
repeat_first_field=0;
chroma_420_type=0;
progressive_frame=0;
composite_display_flag=0;
v_axis=0;
field_sequence=0;
sub_carrier=0;
burst_amplitude=0;
sub_carrier_phase=0;
// frame_center_horizontal_offset[3]=0;
// frame_center_vertical_offset[3]=0;
memset(frame_center_horizontal_offset,0,3);
memset(frame_center_vertical_offset,0,3);
memset(ld,0,sizeof(layer_data));
layer_id=0;
lower_layer_prediction_horizontal_size=0;
lower_layer_prediction_vertical_size=0;
horizontal_subsampling_factor_m=0;
horizontal_subsampling_factor_n=0;
vertical_subsampling_factor_m=0;
vertical_subsampling_factor_n=0;
lower_layer_temporal_reference=0;
lower_layer_horizontal_offset=0;
lower_layer_vertical_offset=0;
spatial_temporal_weight_code_table_index=0;
lower_layer_progressive_frame=0;
lower_layer_deinterlaced_field_select=0;
copyright_flag=0;
copyright_identifier=0;
original_or_copy=0;
copyright_number_1=0;
copyright_number_2=0;
copyright_number_3=0;
drop_flag=0;
hour=0;
minute=0;
sec=0;
frame=0;
closed_gop=0;
broken_link=0;
tframe=0;
tsec=0;
tminute=0;
thour=0;
}
void CloseMpeg2(HANDLE hDecode)
{
environment_data *pDecode;
pDecode=(environment_data *)GlobalLock(hDecode);
base.Infile=pDecode->infile;
AUDIO=false;
SEQEND=false;
ClearGlobal();
Deinitialize_Sequence();
_close(pDecode->infile);
if (Two_Streams)
close(enhan.Infile);
GlobalUnlock(hDecode);
GlobalFree(pDecode);
}
BOOL check_stream(environment_data *pMPG2,LPBYTE lpBuf)
{
long i=0;
long code;
char temp[16];
char str[200];
if(pMPG2->mode==0)
{
sprintf( str,"Infile=%d",ld->Infile);
// ::MessageBox(NULL,str,"check_stream",MB_OK);
pMPG2->mode=0;
System_Stream_Flag = 0;
Clear_Options();
lseek(ld->Infile, 0l, 0);
Initialize_Buffer();
if(SHOW_BITS(8)==0x47)
{
// ::MessageBox(NULL,"非法退出1!!!","check_stream",MB_OK);
return 0;
}
int pos_file;
int continue_loop=1;
_int64 FileSize=_filelengthi64(ld->Infile); //得到文件长度
for (;;)
{
/* look for next_start_code */
next_start_code();
code = Get_Bits32();
pos_file=_tell(base.Infile);
if(pos_file>20480 || pos_file>FileSize/2)
break;
switch (code)
{
case PACK_START_CODE:
continue_loop=0;
System_Stream_Flag = 1;
break;
case VIDEO_ELEMENTARY_STREAM:
continue_loop=0;
System_Stream_Flag = 1;
break;
default:
break;
}
if(!continue_loop)
break;
}
lseek(base.Infile, 0l, 0);
Initialize_Buffer();
pMPG2->System_Stream_Flag=System_Stream_Flag;
_lseek(pMPG2->ld->Infile, 0l, 0);
Initialize_Buffer();
OK_ID=true;
/*
memset(temp,0,16);
_lseek(pMPG2->ld->Infile, 0l, 0);
read(pMPG2->ld->Infile,temp,16);
if(strcmp(temp,"00ok00ok00ok00ok")==0)
OK_ID=true;
else
OK_ID=false;
*/
_lseek(pMPG2->ld->Infile, 0l, 0);
Initialize_Buffer();
}
else
{
SEQEND=false;
base.lpData=lpBuf;
base.size=80000;
base.length=0;
System_Stream_Flag = 0;
Initialize_Buffer();
if(SHOW_BITS(8)==0x47)
{
// ::MessageBox(NULL,"非法退出1!!!","check_stream",MB_OK);
return 0;
}
while(1)
{
i+=32;
next_start_code();
code = Get_Bits32();//Show_Bits(32);
switch(code)
{
case SEQUENCE_HEADER_CODE:
break;
case PACK_START_CODE:
System_Stream_Flag = 1;
break;
case VIDEO_ELEMENTARY_STREAM:
System_Stream_Flag = 1;
break;
}
if(code==SEQUENCE_HEADER_CODE||System_Stream_Flag )
break;
if(i>2048)
{
// ::MessageBox(NULL,"非法退出1!!!","check_stream",MB_OK);
return 0;
}
}
//Initialize_Buffer();
}
return 1;
}
void GetTotalFrame(HANDLE hMPG2,long* total)
{
// ::MessageBox(NULL,NULL,"GetTotalFrame",MB_OK);
long temp=0;
long lframe=0;
environment_data *pMPG2;
pMPG2=(environment_data *)GlobalLock(hMPG2);
SEQEND=false;
//计算总帧数
//定位于文件尾后一定范围内
_lseeki64(pMPG2->ld->Infile,-1*MaxFrame*(pMPG2->N*10),SEEK_END);
BOOL FirstI=false;
/*
while(Headers())
{
if(picture_coding_type==I_TYPE)
{
FirstI=true;
lframe=0; //组内序号归零
}
else if(picture_coding_type==P_TYPE||picture_coding_type==B_TYPE)
{
//若不是图像组首且为非连续解码,则继续寻找。
if(!FirstI)
continue;
lframe++;
}
if(SEQEND)
break;
}
*/
int hour_ok=hour, minute_ok=minute, sec_ok=sec;
while(Headers())
{
if(hour > hour_ok)
{
hour_ok=hour;minute_ok=minute; sec_ok=sec;
}
else if(minute > minute_ok)
{
minute_ok=minute; sec_ok=sec;
}
else if(sec > sec_ok)
{
sec_ok=sec;
}
if(picture_coding_type==I_TYPE)
{
FirstI=true;
lframe=0; //组内序号归零
}
else if(picture_coding_type==P_TYPE||picture_coding_type==B_TYPE)
{
//若不是图像组首且为非连续解码,则继续寻找。
if(!FirstI)
continue;
lframe++;
}
if(SEQEND)
break;
}
SEQEND=false;
if(lframe>pMPG2->N)
lframe=pMPG2->N;
*total=((hour_ok-pMPG2->thour)*3600+(minute_ok-pMPG2->tminute)*60+(sec_ok-pMPG2->tsec))*(int)(frame_rate+0.5)+(frame-pMPG2->tframe+1+lframe);
//若在范围内无播放时间信息,则遍历整个文件得到的总帧数
if(*total<=0)
{
SEQEND=false;
lseek(pMPG2->ld->Infile, 0l, 0);
if(pMPG2->ld->Infile!=0)
{
lseek(pMPG2->ld->Infile, 0l, 0);
}
Initialize_Buffer();
while(1)
{
int code;
next_start_code();
code = Get_Bits32();
pMPG2->ld->Infile=base.Infile;
if(code==PICTURE_START_CODE)
{
temp++;
}
if(SEQEND)
break;
}
*total=temp;
}
lseek(pMPG2->ld->Infile, 0l, 0);
if(pMPG2->ld->Infile!=0)
{
lseek(pMPG2->ld->Infile, 0l, 0);
}
Initialize_Buffer();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -