Mercurial > mplayer.hg
changeset 2567:ea6158be8103
video frame reading cleanup
author | arpi |
---|---|
date | Tue, 30 Oct 2001 20:36:20 +0000 |
parents | a350d8bed636 |
children | e96d8e8f0c8f |
files | dec_video.c libmpdemux/Makefile libmpdemux/stheader.h libmpdemux/video.c mplayer.c |
diffstat | 5 files changed, 271 insertions(+), 222 deletions(-) [+] |
line wrap: on
line diff
--- a/dec_video.c Tue Oct 30 20:30:24 2001 +0000 +++ b/dec_video.c Tue Oct 30 20:36:20 2001 +0000 @@ -408,11 +408,14 @@ case VFM_MPEG: { // init libmpeg2: + mpeg2_init(); #ifdef MPEG12_POSTPROC picture->pp_options=divx_quality; #else if(divx_quality) mp_msg(MSGT_DECVIDEO,MSGL_HINT,MSGTR_MpegPPhint); #endif + // send seq header to the decoder: + mpeg2_decode_data(NULL,videobuffer,videobuffer+videobuf_len,0); mpeg2_allocate_image_buffers (picture); break; } @@ -708,118 +711,3 @@ return blit_frame; } - -int video_read_properties(sh_video_t *sh_video){ -demux_stream_t *d_video=sh_video->ds; - -// Determine image properties: -switch(d_video->demuxer->file_format){ - case DEMUXER_TYPE_AVI: - case DEMUXER_TYPE_ASF: { - // display info: - sh_video->format=sh_video->bih->biCompression; - sh_video->disp_w=sh_video->bih->biWidth; - sh_video->disp_h=abs(sh_video->bih->biHeight); - break; - } - case DEMUXER_TYPE_MPEG_ES: - case DEMUXER_TYPE_MPEG_PS: { - // Find sequence_header first: - videobuf_len=0; videobuf_code_len=0; - mp_msg(MSGT_DECVIDEO,MSGL_V,"Searching for sequence header... ");fflush(stdout); - while(1){ - int i=sync_video_packet(d_video); - if(i==0x1B3) break; // found it! - if(!i || !skip_video_packet(d_video)){ - if(verbose) mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n"); - mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_MpegNoSequHdr); - return 0; - } - } - mp_msg(MSGT_DECVIDEO,MSGL_V,"OK!\n"); -// sh_video=d_video->sh;sh_video->ds=d_video; - mpeg2_init(); - // ========= Read & process sequence header & extension ============ - if(!videobuffer) videobuffer=(char*)memalign(8,VIDEOBUFFER_SIZE); - if(!videobuffer){ - mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_ShMemAllocFail); - return 0; - } - - if(!read_video_packet(d_video)){ - mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_CannotReadMpegSequHdr); - return 0; - } - if(header_process_sequence_header (picture, &videobuffer[4])) { - mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_BadMpegSequHdr); - return 0; - } - if(sync_video_packet(d_video)==0x1B5){ // next packet is seq. ext. -// videobuf_len=0; - int pos=videobuf_len; - if(!read_video_packet(d_video)){ - mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_CannotReadMpegSequHdrEx); - return 0; - } - if(header_process_extension (picture, &videobuffer[pos+4])) { - mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_BadMpegSequHdrEx); - return 0; - } - } - // fill aspect info: - switch(picture->aspect_ratio_information){ - case 2: // PAL/NTSC SVCD/DVD 4:3 - case 8: // PAL VCD 4:3 - case 12: // NTSC VCD 4:3 - sh_video->aspect=4.0/3.0; - break; - case 3: // PAL/NTSC Widescreen SVCD/DVD 16:9 - sh_video->aspect=16.0/9.0; - break; - default: - fprintf(stderr,"Detected unknown aspect_ratio_information in mpeg sequence header.\n" - "Please report the aspect value (%i) along with the movie type (VGA,PAL,NTSC," - "SECAM) and the movie resolution (720x576,352x240,480x480,...) to the MPlayer" - " developers, so that we can add support for it!\nAssuming 1:1 aspect for now.\n", - picture->aspect_ratio_information); - case 1: // VGA 1:1 - do not prescale - sh_video->aspect=0.0; - break; - } - // display info: - sh_video->format=picture->mpeg1?0x10000001:0x10000002; // mpeg video - sh_video->fps=frameratecode2framerate[picture->frame_rate_code]*0.0001f; - if(!sh_video->fps){ -// if(!force_fps){ -// fprintf(stderr,"FPS not specified (or invalid) in the header! Use the -fps option!\n"); -// return 0; -// } - sh_video->frametime=0; - } else { - sh_video->frametime=10000.0f/(float)frameratecode2framerate[picture->frame_rate_code]; - } - sh_video->disp_w=picture->display_picture_width; - sh_video->disp_h=picture->display_picture_height; - // bitrate: - if(picture->bitrate!=0x3FFFF) // unspecified/VBR ? - sh_video->i_bps=1000*picture->bitrate/16; - // info: - mp_dbg(MSGT_DECVIDEO,MSGL_DBG2,"mpeg bitrate: %d (%X)\n",picture->bitrate,picture->bitrate); - mp_msg(MSGT_DECVIDEO,MSGL_INFO,"VIDEO: %s %dx%d (aspect %d) %4.2f fps %5.1f kbps (%4.1f kbyte/s)\n", - picture->mpeg1?"MPEG1":"MPEG2", - sh_video->disp_w,sh_video->disp_h, - picture->aspect_ratio_information, - sh_video->fps, - picture->bitrate*0.5f, - picture->bitrate/16.0f ); - break; - } -} // switch(file_format) - -return 1; -} - - - - -
--- a/libmpdemux/Makefile Tue Oct 30 20:30:24 2001 +0000 +++ b/libmpdemux/Makefile Tue Oct 30 20:36:20 2001 +0000 @@ -3,7 +3,7 @@ include ../config.mak -SRCS = mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c aviwrite.c demux_asf.c demux_avi.c demux_mov.c demux_mpg.c demuxer.c dvdauth.c open.c parse_es.c stream.c +SRCS = video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c aviwrite.c demux_asf.c demux_avi.c demux_mov.c demux_mpg.c demuxer.c dvdauth.c open.c parse_es.c stream.c ifeq ($(STREAMING),yes) SRCS += asf_streaming.c url.c http.c network.c endif
--- a/libmpdemux/stheader.h Tue Oct 30 20:30:24 2001 +0000 +++ b/libmpdemux/stheader.h Tue Oct 30 20:36:20 2001 +0000 @@ -71,3 +71,5 @@ sh_audio_t* new_sh_audio(demuxer_t *demuxer,int id); sh_video_t* new_sh_video(demuxer_t *demuxer,int id); +int video_read_properties(sh_video_t *sh_video); +int video_read_frame(sh_video_t* sh_video,float* frame_time_ptr,unsigned char** start,int force_fps);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmpdemux/video.c Tue Oct 30 20:36:20 2001 +0000 @@ -0,0 +1,244 @@ +// read video frame + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include "config.h" +#include "mp_msg.h" +#include "help_mp.h" + +#include "stream.h" +#include "demuxer.h" +#include "stheader.h" +#include "parse_es.h" +#include "mpeg_hdr.h" + +static mp_mpeg_header_t picture; + +int video_read_properties(sh_video_t *sh_video){ +demux_stream_t *d_video=sh_video->ds; + +// Determine image properties: +switch(d_video->demuxer->file_format){ + case DEMUXER_TYPE_AVI: + case DEMUXER_TYPE_ASF: { + // display info: + sh_video->format=sh_video->bih->biCompression; + sh_video->disp_w=sh_video->bih->biWidth; + sh_video->disp_h=abs(sh_video->bih->biHeight); + break; + } + case DEMUXER_TYPE_MPEG_ES: + case DEMUXER_TYPE_MPEG_PS: { + // Find sequence_header first: + videobuf_len=0; videobuf_code_len=0; + mp_msg(MSGT_DECVIDEO,MSGL_V,"Searching for sequence header... ");fflush(stdout); + while(1){ + int i=sync_video_packet(d_video); + if(i==0x1B3) break; // found it! + if(!i || !skip_video_packet(d_video)){ + if(verbose) mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n"); + mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_MpegNoSequHdr); + return 0; + } + } + mp_msg(MSGT_DECVIDEO,MSGL_V,"OK!\n"); +// sh_video=d_video->sh;sh_video->ds=d_video; +// mpeg2_init(); + // ========= Read & process sequence header & extension ============ + if(!videobuffer) videobuffer=(char*)memalign(8,VIDEOBUFFER_SIZE); + if(!videobuffer){ + mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_ShMemAllocFail); + return 0; + } + + if(!read_video_packet(d_video)){ + mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_CannotReadMpegSequHdr); + return 0; + } + if(mp_header_process_sequence_header (&picture, &videobuffer[4])) { + mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_BadMpegSequHdr); + return 0; + } + if(sync_video_packet(d_video)==0x1B5){ // next packet is seq. ext. +// videobuf_len=0; + int pos=videobuf_len; + if(!read_video_packet(d_video)){ + mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_CannotReadMpegSequHdrEx); + return 0; + } + if(mp_header_process_extension (&picture, &videobuffer[pos+4])) { + mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_BadMpegSequHdrEx); + return 0; + } + } + +// printf("picture.fps=%d\n",picture.fps); + + // fill aspect info: + switch(picture.aspect_ratio_information){ + case 2: // PAL/NTSC SVCD/DVD 4:3 + case 8: // PAL VCD 4:3 + case 12: // NTSC VCD 4:3 + sh_video->aspect=4.0/3.0; + break; + case 3: // PAL/NTSC Widescreen SVCD/DVD 16:9 + sh_video->aspect=16.0/9.0; + break; + default: + fprintf(stderr,"Detected unknown aspect_ratio_information in mpeg sequence header.\n" + "Please report the aspect value (%i) along with the movie type (VGA,PAL,NTSC," + "SECAM) and the movie resolution (720x576,352x240,480x480,...) to the MPlayer" + " developers, so that we can add support for it!\nAssuming 1:1 aspect for now.\n", + picture.aspect_ratio_information); + case 1: // VGA 1:1 - do not prescale + sh_video->aspect=0.0; + break; + } + // display info: + sh_video->format=picture.mpeg1?0x10000001:0x10000002; // mpeg video + sh_video->fps=picture.fps*0.0001f; + if(!sh_video->fps){ +// if(!force_fps){ +// fprintf(stderr,"FPS not specified (or invalid) in the header! Use the -fps option!\n"); +// return 0; +// } + sh_video->frametime=0; + } else { + sh_video->frametime=10000.0f/(float)picture.fps; + } + sh_video->disp_w=picture.display_picture_width; + sh_video->disp_h=picture.display_picture_height; + // bitrate: + if(picture.bitrate!=0x3FFFF) // unspecified/VBR ? + sh_video->i_bps=1000*picture.bitrate/16; + // info: + mp_dbg(MSGT_DECVIDEO,MSGL_DBG2,"mpeg bitrate: %d (%X)\n",picture.bitrate,picture.bitrate); + mp_msg(MSGT_DECVIDEO,MSGL_INFO,"VIDEO: %s %dx%d (aspect %d) %4.2f fps %5.1f kbps (%4.1f kbyte/s)\n", + picture.mpeg1?"MPEG1":"MPEG2", + sh_video->disp_w,sh_video->disp_h, + picture.aspect_ratio_information, + sh_video->fps, + picture.bitrate*0.5f, + picture.bitrate/16.0f ); + break; + } +} // switch(file_format) + +return 1; +} + +int video_read_frame(sh_video_t* sh_video,float* frame_time_ptr,unsigned char** start,int force_fps){ + demux_stream_t *d_video=sh_video->ds; + demuxer_t *demuxer=d_video->demuxer; + float frame_time=1; + float pts1=d_video->pts; +// unsigned char* start=NULL; + int in_size=0; + + *start=NULL; + + if(demuxer->file_format==DEMUXER_TYPE_MPEG_ES || demuxer->file_format==DEMUXER_TYPE_MPEG_PS){ + int in_frame=0; + //float newfps; + //videobuf_len=0; + while(videobuf_len<VIDEOBUFFER_SIZE-MAX_VIDEO_PACKET_SIZE){ + int i=sync_video_packet(d_video); + void* buffer=&videobuffer[videobuf_len+4]; + if(in_frame){ + if(i<0x101 || i>=0x1B0){ // not slice code -> end of frame +#if 1 + // send END OF FRAME code: + videobuffer[videobuf_len+0]=0; + videobuffer[videobuf_len+1]=0; + videobuffer[videobuf_len+2]=1; + videobuffer[videobuf_len+3]=0xFF; + videobuf_len+=4; +#endif + if(!i) return -1; // EOF + break; + } + } else { + //if(i==0x100) in_frame=1; // picture startcode + if(i>=0x101 && i<0x1B0) in_frame=1; // picture startcode + else if(!i) return -1; // EOF + } + //if(grab_frames==2 && (i==0x1B3 || i==0x1B8)) grab_frames=1; + if(!read_video_packet(d_video)) return -1; // EOF + //printf("read packet 0x%X, len=%d\n",i,videobuf_len); + // process headers: + switch(i){ + case 0x1B3: mp_header_process_sequence_header (&picture, buffer);break; + case 0x1B5: mp_header_process_extension (&picture, buffer);break; + } + } + + // if(videobuf_len>max_framesize) max_framesize=videobuf_len; // debug + //printf("--- SEND %d bytes\n",videobuf_len); +// if(grab_frames==1){ +// FILE *f=fopen("grab.mpg","ab"); +// fwrite(videobuffer,videobuf_len-4,1,f); +// fclose(f); +// } + + *start=videobuffer; in_size=videobuf_len; + //blit_frame=decode_video(video_out,sh_video,videobuffer,videobuf_len,drop_frame); + +#if 1 + // get mpeg fps: + //newfps=frameratecode2framerate[picture->frame_rate_code]*0.0001f; + if((int)(sh_video->fps*10000+0.5)!=picture.fps) if(!force_fps){ + mp_msg(MSGT_CPLAYER,MSGL_WARN,"Warning! FPS changed %5.3f -> %5.3f (%f) [%d] \n",sh_video->fps,picture.fps*0.0001,sh_video->fps-picture.fps*0.0001,picture.frame_rate_code); + sh_video->fps=picture.fps*0.0001; + sh_video->frametime=10000.0f/(float)picture.fps; + } +#endif + + // fix mpeg2 frametime: + frame_time=(picture.display_time)*0.01f; + picture.display_time=100; + videobuf_len=0; + + } else { + // frame-based file formats: (AVI,ASF,MOV) + in_size=ds_get_packet(d_video,start); + if(in_size<0) return -1; // EOF +// if(in_size>max_framesize) max_framesize=in_size; +// blit_frame=decode_video(video_out,sh_video,start,in_size,drop_frame); + } + +// vdecode_time=video_time_usage-vdecode_time; + +//------------------------ frame decoded. -------------------- + + // Increase video timers: + sh_video->num_frames+=frame_time; + ++sh_video->num_frames_decoded; + + frame_time*=sh_video->frametime; + if(demuxer->file_format==DEMUXER_TYPE_ASF && !force_fps){ + // .ASF files has no fixed FPS - just frame durations! + float d=d_video->pts-pts1; + if(d>=0 && d<5) frame_time=d; + if(d>0){ + if(verbose) + if((int)sh_video->fps==1000) + mp_msg(MSGT_CPLAYER,MSGL_STATUS,"\rASF framerate: %d fps \n",(int)(1.0f/d)); + sh_video->frametime=d; // 1ms + sh_video->fps=1.0f/d; + } + } else + if(demuxer->file_format==DEMUXER_TYPE_MOV && !force_fps){ + // .MOV files has no fixed FPS - just frame durations! + frame_time=d_video->pts-pts1; + } + + if(demuxer->file_format==DEMUXER_TYPE_MPEG_PS) d_video->pts+=frame_time; + + if(frame_time_ptr) *frame_time_ptr=frame_time; + return in_size; + +} + +
--- a/mplayer.c Tue Oct 30 20:30:24 2001 +0000 +++ b/mplayer.c Tue Oct 30 20:36:20 2001 +0000 @@ -100,6 +100,7 @@ #include "dec_audio.h" #include "dec_video.h" +#if 0 extern picture_t *picture; // exported from libmpeg2/decode.c int frameratecode2framerate[16] = { @@ -109,6 +110,7 @@ // libmpeg3's "Unofficial economy rates": 1*10000,5*10000,10*10000,12*10000,15*10000,0,0 }; +#endif //**************************************************************************// //**************************************************************************// @@ -1097,7 +1099,7 @@ total_time_usage_start=GetTimer(); while(!eof){ - unsigned int aq_total_time=GetTimer(); +// unsigned int aq_total_time=GetTimer(); float aq_sleep_time=0; if(play_n_frames>=0){ @@ -1167,88 +1169,26 @@ if(1) while(1){ - float frame_time=1; - float pts1=d_video->pts; + float frame_time=0; int blit_frame=0; - - current_module="decode_video"; - //-------------------- Decode a frame: ----------------------- - - vdecode_time=video_time_usage; - - if(demuxer->file_format==DEMUXER_TYPE_MPEG_ES || demuxer->file_format==DEMUXER_TYPE_MPEG_PS){ - int in_frame=0; - float newfps; - //videobuf_len=0; - while(videobuf_len<VIDEOBUFFER_SIZE-MAX_VIDEO_PACKET_SIZE){ - int i=sync_video_packet(d_video); - void* buffer=&videobuffer[videobuf_len+4]; - if(in_frame){ - if(i<0x101 || i>=0x1B0){ // not slice code -> end of frame -#if 1 - // send END OF FRAME code: - videobuffer[videobuf_len+0]=0; - videobuffer[videobuf_len+1]=0; - videobuffer[videobuf_len+2]=1; - videobuffer[videobuf_len+3]=0xFF; - videobuf_len+=4; -#endif - if(!i) eof=2; // EOF - break; - } - } else { - //if(i==0x100) in_frame=1; // picture startcode - if(i>=0x101 && i<0x1B0) in_frame=1; // picture startcode - else if(!i){ eof=3; break;} // EOF - } - if(grab_frames==2 && (i==0x1B3 || i==0x1B8)) grab_frames=1; - if(!read_video_packet(d_video)){ eof=4; break;} // EOF - //printf("read packet 0x%X, len=%d\n",i,videobuf_len); - if(sh_video->codec->driver!=VFM_MPEG){ - // if not libmpeg2: - switch(i){ - case 0x1B3: header_process_sequence_header (picture, buffer);break; - case 0x1B5: header_process_extension (picture, buffer);break; - } - } - } - - if(videobuf_len>max_framesize) max_framesize=videobuf_len; // debug - //printf("--- SEND %d bytes\n",videobuf_len); - if(grab_frames==1){ - FILE *f=fopen("grab.mpg","ab"); - fwrite(videobuffer,videobuf_len-4,1,f); - fclose(f); - } - - blit_frame=decode_video(video_out,sh_video,videobuffer,videobuf_len,drop_frame); - - // get mpeg fps: - newfps=frameratecode2framerate[picture->frame_rate_code]*0.0001f; - if(ABS(sh_video->fps-newfps)>0.01f) if(!force_fps){ - mp_msg(MSGT_CPLAYER,MSGL_WARN,"Warning! FPS changed %5.3f -> %5.3f (%f) [%d] \n",sh_video->fps,newfps,sh_video->fps-newfps,picture->frame_rate_code); - sh_video->fps=newfps; - sh_video->frametime=10000.0f/(float)frameratecode2framerate[picture->frame_rate_code]; + //-------------------- Decode a frame: ----------------------- + vdecode_time=video_time_usage; + { unsigned char* start=NULL; + int in_size; + // get it! + current_module="video_read_frame"; + in_size=video_read_frame(sh_video,&frame_time,&start,force_fps); + if(in_size<0){ eof=1; break; } + if(in_size>max_framesize) max_framesize=in_size; // stats + // decode: + current_module="decode_video"; +// printf("Decode! %p %d \n",start,in_size); + blit_frame=decode_video(video_out,sh_video,start,in_size,drop_frame); } - - // fix mpeg2 frametime: - frame_time=(picture->display_time)*0.01f; - picture->display_time=100; - videobuf_len=0; - - } else { - // frame-based file formats: (AVI,ASF,MOV) - unsigned char* start=NULL; - int in_size=ds_get_packet(d_video,&start); - if(in_size<0){ eof=5;break;} - if(in_size>max_framesize) max_framesize=in_size; - blit_frame=decode_video(video_out,sh_video,start,in_size,drop_frame); - } - - vdecode_time=video_time_usage-vdecode_time; - -//------------------------ frame decoded. -------------------- + vdecode_time=video_time_usage-vdecode_time; + //------------------------ frame decoded. -------------------- + //------------------------ add OSD to frame contents --------- #ifndef USE_LIBVO2 current_module="draw_osd"; @@ -1257,32 +1197,9 @@ current_module="av_sync"; - // Increase video timers: - sh_video->num_frames+=frame_time; - ++sh_video->num_frames_decoded; - frame_time*=sh_video->frametime; - if(demuxer->file_format==DEMUXER_TYPE_ASF && !force_fps){ - // .ASF files has no fixed FPS - just frame durations! - float d=d_video->pts-pts1; - if(d>=0 && d<5) frame_time=d; - if(d>0){ - if(verbose) - if((int)sh_video->fps==1000) - mp_msg(MSGT_CPLAYER,MSGL_STATUS,"\rASF framerate: %d fps \n",(int)(1.0f/d)); - sh_video->frametime=d; // 1ms - sh_video->fps=1.0f/d; - } - } else - if(demuxer->file_format==DEMUXER_TYPE_MOV && !force_fps){ - // .MOV files has no fixed FPS - just frame durations! - float d=d_video->pts-pts1; - frame_time=d; - } sh_video->timer+=frame_time; time_frame+=frame_time; // for nosound - if(demuxer->file_format==DEMUXER_TYPE_MPEG_PS) d_video->pts+=frame_time; - mp_dbg(MSGT_AVSYNC,MSGL_DBG2,"*** ftime=%5.3f ***\n",frame_time); if(drop_frame){ @@ -1302,9 +1219,7 @@ } } #ifdef HAVE_NEW_GUI - if(use_gui){ - EventHandling(); - } + if(use_gui) EventHandling(); #endif video_out->check_events(); // check events AST } else {