diff --git a/demux_asf.c b/demux_asf.c index e7550a5695..76373461ab 100644 --- a/demux_asf.c +++ b/demux_asf.c @@ -58,7 +58,7 @@ static void asf_descrambling(unsigned char *src,int len){ } -static int demux_asf_read_packet(demuxer_t *demux,unsigned char *data,int len,int id,int seq,unsigned long time,unsigned short dur,int offs){ +static int demux_asf_read_packet(demuxer_t *demux,unsigned char *data,int len,int id,int seq,unsigned long time,unsigned short dur,int offs,int keyframe){ demux_stream_t *ds=NULL; if(verbose>=4) printf("demux_asf.read_packet: id=%d seq=%d len=%d\n",id,seq,len); @@ -118,6 +118,7 @@ static int demux_asf_read_packet(demuxer_t *demux,unsigned char *data,int len,in dp=new_demux_packet(len); memcpy(dp->buffer,data,len); dp->pts=time*0.001f; + dp->flags=keyframe; // if(ds==demux->video) printf("ASF time: %8d dur: %5d \n",time,dur); dp->pos=demux->filepos; ds->asf_packet=dp; @@ -207,6 +208,7 @@ int demux_asf_fill_buffer(demuxer_t *demux){ unsigned long x; unsigned char type; unsigned long time2; + int keyframe=0; if(p>=p_end) printf("Warning! invalid packet 1, sig11 coming soon...\n"); @@ -218,6 +220,7 @@ int demux_asf_fill_buffer(demuxer_t *demux){ } streamno=p[0]&0x7F; + if(p[0]&0x80) keyframe=1; seq=p[1]; p+=2; @@ -279,7 +282,7 @@ int demux_asf_fill_buffer(demuxer_t *demux){ int len2=p[0]; p++; //printf(" group part: %d bytes\n",len2); - demux_asf_read_packet(demux,p,len2,streamno,seq,x,duration,-1); + demux_asf_read_packet(demux,p,len2,streamno,seq,x,duration,-1,keyframe); p+=len2; len-=len2+1; } @@ -290,7 +293,7 @@ int demux_asf_fill_buffer(demuxer_t *demux){ case 0x08: // NO GROUPING: //printf("fragment offset: %d \n",sh->x); - demux_asf_read_packet(demux,p,len,streamno,seq,time2,duration,x); + demux_asf_read_packet(demux,p,len,streamno,seq,time2,duration,x,keyframe); p+=len; break; } diff --git a/demux_avi.c b/demux_avi.c index 664a3f000f..c3ea043bbc 100644 --- a/demux_avi.c +++ b/demux_avi.c @@ -57,7 +57,7 @@ demux_stream_t* demux_avi_select_stream(demuxer_t *demux,unsigned int id){ return NULL; } -static int demux_avi_read_packet(demuxer_t *demux,unsigned int id,unsigned int len,int idxpos){ +static int demux_avi_read_packet(demuxer_t *demux,unsigned int id,unsigned int len,int idxpos,int flags){ int skip; float pts=0; demux_stream_t *ds=demux_avi_select_stream(demux,id); @@ -92,7 +92,7 @@ static int demux_avi_read_packet(demuxer_t *demux,unsigned int id,unsigned int l if(ds){ if(verbose>=2) printf("DEMUX_AVI: Read %d data bytes from packet %04X\n",len,id); - ds_read_packet(ds,demux->stream,len,pts,idxpos); + ds_read_packet(ds,demux->stream,len,pts,idxpos,flags); skip-=len; } if(skip){ @@ -115,6 +115,7 @@ int max_packs=128; int ret=0; do{ + int flags=0; AVIINDEXENTRY *idx=NULL; demux->filepos=stream_tell(demux->stream); if(demux->filepos>=demux->movi_end){ @@ -166,6 +167,7 @@ do{ printf("ChunkSize mismatch! raw=%d idx=%ld \n",len,idx->dwChunkLength); continue; } + if(idx->dwFlags&AVIIF_KEYFRAME) flags=1; } else { id=stream_read_dword_le(demux->stream); len=stream_read_dword_le(demux->stream); @@ -174,7 +176,7 @@ do{ continue; } } - ret=demux_avi_read_packet(demux,id,len,demux->idx_pos-1); + ret=demux_avi_read_packet(demux,id,len,demux->idx_pos-1,flags); if(!ret && skip_video_frames<=0) if(--max_packs==0){ demux->stream->eof=1; @@ -196,6 +198,7 @@ int max_packs=128; int ret=0; do{ + int flags=0; AVIINDEXENTRY *idx=NULL; int idx_pos=0; demux->filepos=stream_tell(demux->stream); @@ -245,8 +248,9 @@ do{ printf("ChunkSize mismatch! raw=%d idx=%ld \n",len,idx->dwChunkLength); continue; } + if(idx->dwFlags&AVIIF_KEYFRAME) flags=1; } else return 0; - ret=demux_avi_read_packet(demux,id,len,idx_pos); + ret=demux_avi_read_packet(demux,id,len,idx_pos,flags); if(!ret && skip_video_frames<=0) if(--max_packs==0){ demux->stream->eof=1; @@ -291,7 +295,7 @@ do{ if(ds==demux_avi_select_stream(demux,id)){ // read it! - ret=demux_avi_read_packet(demux,id,len,demux->idx_pos-1); + ret=demux_avi_read_packet(demux,id,len,demux->idx_pos-1,0); } else { // skip it! int skip=(len+1)&(~1); // total bytes in this chunk diff --git a/demux_mpg.c b/demux_mpg.c index 6ebebe65ce..f9b8b425c6 100644 --- a/demux_mpg.c +++ b/demux_mpg.c @@ -238,7 +238,7 @@ static int demux_mpg_read_packet(demuxer_t *demux,int id){ printf("Encrypted stream but authentication was not requested by you!!\n"); } #endif - ds_read_packet(ds,demux->stream,len,pts/90000.0f,0); + ds_read_packet(ds,demux->stream,len,pts/90000.0f,0,0); // if(ds==demux->sub) parse_dvdsub(ds->last->buffer,ds->last->len); return 1; } @@ -255,7 +255,7 @@ int demux_mpg_es_fill_buffer(demuxer_t *demux){ // Elementary video stream if(demux->stream->eof) return 0; demux->filepos=stream_tell(demux->stream); - ds_read_packet(demux->video,demux->stream,STREAM_BUFFER_SIZE,0,0); + ds_read_packet(demux->video,demux->stream,STREAM_BUFFER_SIZE,0,0,0); return 1; } diff --git a/demuxer.c b/demuxer.c index 3aba153875..dc41c6d2df 100644 --- a/demuxer.c +++ b/demuxer.c @@ -70,11 +70,12 @@ void ds_add_packet(demux_stream_t *ds,demux_packet_t* dp){ dp->len,dp->pts,dp->pos,ds->demuxer->audio->packs,ds->demuxer->video->packs); } -void ds_read_packet(demux_stream_t *ds,stream_t *stream,int len,float pts,int pos){ +void ds_read_packet(demux_stream_t *ds,stream_t *stream,int len,float pts,int pos,int flags){ demux_packet_t* dp=new_demux_packet(len); stream_read(stream,dp->buffer,len); dp->pts=pts; //(float)pts/90000.0f; dp->pos=pos; + dp->flags=flags; // append packet to DS stream: ds_add_packet(ds,dp); } @@ -128,6 +129,7 @@ int ds_fill_buffer(demux_stream_t *ds){ ds->pts_bytes=0; } ds->pts_bytes+=p->len; // !!! + ds->flags=p->flags; // free packet: ds->bytes-=p->len; ds->first=p->next; diff --git a/demuxer.h b/demuxer.h index 575bffc384..0acf059646 100644 --- a/demuxer.h +++ b/demuxer.h @@ -21,6 +21,7 @@ typedef struct demux_packet_st { float pts; int pos; // pozicio indexben (AVI) ill. fileban (MPG) unsigned char* buffer; + int flags; // keyframe, etc struct demux_packet_st* next; } demux_packet_t; @@ -34,6 +35,7 @@ typedef struct { int pos; // position in the input stream (file) int dpos; // position in the demuxed stream int pack_no; // serial number of packet + int flags; // flags of current packet (keyframe etc) //--------------- int packs; // number of packets in buffer int bytes; // total bytes of packets in buffer @@ -87,6 +89,7 @@ inline static demux_packet_t* new_demux_packet(int len){ dp->next=NULL; dp->pts=0; dp->pos=0; + dp->flags=0; return dp; } @@ -99,7 +102,7 @@ demux_stream_t* new_demuxer_stream(struct demuxer_st *demuxer,int id); demuxer_t* new_demuxer(stream_t *stream,int type,int a_id,int v_id,int s_id); void ds_add_packet(demux_stream_t *ds,demux_packet_t* dp); -void ds_read_packet(demux_stream_t *ds,stream_t *stream,int len,float pts,int pos); +void ds_read_packet(demux_stream_t *ds,stream_t *stream,int len,float pts,int pos,int flags); int demux_fill_buffer(demuxer_t *demux,demux_stream_t *ds); int ds_fill_buffer(demux_stream_t *ds); diff --git a/mplayer.c b/mplayer.c index b561623237..f287902de0 100644 --- a/mplayer.c +++ b/mplayer.c @@ -1611,6 +1611,8 @@ switch(sh_video->codec->driver){ if(in_size<0){ eof=1;break;} if(in_size>max_framesize) max_framesize=in_size; + if(d_video->flags) if(verbose) printf("***keyframe***\n"); + if(drop_frame<2) DS_VideoDecoder_DecodeFrame(start, in_size, 0, !drop_frame); current_module="draw_frame"; @@ -1641,6 +1643,8 @@ switch(sh_video->codec->driver){ if(in_size<0){ eof=1;break;} if(in_size>max_framesize) max_framesize=in_size; + if(d_video->flags) if(verbose) printf("***keyframe***\n"); + if(in_size){ sh_video->bih->biSizeImage = in_size;