aboutsummaryrefslogtreecommitdiffhomepage
path: root/libmpdemux
diff options
context:
space:
mode:
authorGravatar arpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-06-14 00:49:56 +0000
committerGravatar arpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-06-14 00:49:56 +0000
commit6e021a815f2542546990c3837edf39577a3778a7 (patch)
treeac68f281d26dd47637d843dc75527669d5b86121 /libmpdemux
parent5d3ed7324cff456e1bc543cf0c6548b422105baf (diff)
fixed playback speed and a-v sync issues
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@6424 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpdemux')
-rw-r--r--libmpdemux/demux_real.c44
-rw-r--r--libmpdemux/video.c17
2 files changed, 50 insertions, 11 deletions
diff --git a/libmpdemux/demux_real.c b/libmpdemux/demux_real.c
index d65f772535..f5094fab6f 100644
--- a/libmpdemux/demux_real.c
+++ b/libmpdemux/demux_real.c
@@ -8,6 +8,9 @@
TODO: fix the whole syncing mechanism
$Log$
+ Revision 1.18 2002/06/14 00:49:56 arpi
+ fixed playback speed and a-v sync issues
+
Revision 1.17 2002/06/13 13:31:45 arpi
fix fps/frametime parsing - patch by Florian Schneider <flo-mplayer-dev@gmx.net>
@@ -108,6 +111,11 @@ typedef struct {
int current_apacket;
int current_vpacket;
+ // timestamp correction:
+ int kf_pts; // timestamp of next video keyframe
+ int a_pts; // previous audio timestamp
+ float v_pts; // previous video timestamp
+
/* stream id table */
int last_a_stream;
int a_streams[MAX_STREAMS];
@@ -357,6 +365,25 @@ int real_check_file(demuxer_t* demuxer)
void hexdump(char *, unsigned long);
+static float real_fix_timestamp(real_priv_t* priv, unsigned char* s, int timestamp, float frametime){
+ int kf=2*(((s[1]&15)<<8)+s[2]); // 12-bit timestamp from frame header
+ float v_pts;
+ kf|=timestamp&(~0x1fff); // combine with packet timestamp
+ if(kf<timestamp-4096) kf+=8192; else // workaround wrap-around problems
+ if(kf>timestamp+4096) kf-=8192;
+ if(!(s[0]&0x8) || !(s[0]&0x10)){ // P || I frame -> swap timestamps
+ int tmp=kf;
+ kf=priv->kf_pts;
+ priv->kf_pts=tmp;
+// if(kf<=tmp) kf=0;
+ }
+ v_pts=kf*0.001f;
+ if(v_pts<priv->v_pts || !kf) v_pts=priv->v_pts+frametime;
+ priv->v_pts=v_pts;
+// printf("\n#T# %5d/%5d (%5.3f) %5.3f \n",kf,timestamp,frametime,v_pts);
+ return v_pts;
+}
+
// return value:
// 0 = EOF or no stream found
// 1 = successfully read a packet
@@ -469,7 +496,8 @@ loop:
ptr += 2;
}
}
- dp->pts = timestamp/1000.0f;
+ dp->pts = (priv->a_pts==timestamp) ? 0 : (timestamp/1000.0f);
+ priv->a_pts=timestamp;
dp->pos = demuxer->filepos;
dp->flags = (flags & 0x2) ? 0x10 : 0;
ds_add_packet(ds, dp);
@@ -545,16 +573,18 @@ loop:
vpkg_header, vpkg_length, vpkg_offset, vpkg_seqnum);
if(ds->asf_packet){
+ demux_packet_t* dp=ds->asf_packet;
mp_dbg(MSGT_DEMUX,MSGL_DBG2, "we have an incomplete packet (oldseq=%d new=%d)\n",ds->asf_seq,vpkg_seqnum);
// we have an incomplete packet:
if(ds->asf_seq!=vpkg_seqnum){
// this fragment is for new packet, close the old one
- mp_msg(MSGT_DEMUX,MSGL_DBG2, "closing probably incomplete packet, len: %d \n",ds->asf_packet->len);
- ds_add_packet(ds,ds->asf_packet);
+ mp_msg(MSGT_DEMUX,MSGL_DBG2, "closing probably incomplete packet, len: %d \n",dp->len);
+ dp->pts=(dp->len<3)?0:
+ real_fix_timestamp(priv,dp->buffer,timestamp,sh_video->frametime);
+ ds_add_packet(ds,dp);
ds->asf_packet=NULL;
} else {
// append data to it!
- demux_packet_t* dp=ds->asf_packet;
extra=(unsigned int*)(dp->buffer+vpkg_length);
++extra[0];
if((extra[0]&3)==0){ // increase buffer size, if more than 4 subpackets
@@ -573,6 +603,8 @@ loop:
len-=vpkg_offset;
mp_dbg(MSGT_DEMUX,MSGL_DBG2, "fragment (%d bytes) appended, %d bytes left\n",vpkg_offset,len);
// we know that this is the last fragment -> we can close the packet!
+ dp->pts=(dp->len<3)?0:
+ real_fix_timestamp(priv,dp->buffer,extra[1],sh_video->frametime);
ds_add_packet(ds,dp);
ds->asf_packet=NULL;
// continue parsing
@@ -589,7 +621,7 @@ loop:
// create new packet!
dp = new_demux_packet(vpkg_length+8*5);
// the timestamp seems to be in milliseconds
- dp->pts = timestamp/1000.0f; timestamp=0;
+ dp->pts = 0; // timestamp/1000.0f; //timestamp=0;
dp->pos = demuxer->filepos;
dp->flags = (flags & 0x2) ? 0x10 : 0;
ds->asf_seq = vpkg_seqnum;
@@ -608,6 +640,8 @@ loop:
// whole packet (not fragmented):
dp->len=vpkg_length; len-=vpkg_length;
stream_read(demuxer->stream, dp->buffer, dp->len);
+ dp->pts=(dp->len<3)?0:
+ real_fix_timestamp(priv,dp->buffer,extra[1],sh_video->frametime);
ds_add_packet(ds,dp);
} // while(len>0)
diff --git a/libmpdemux/video.c b/libmpdemux/video.c
index 6d05cdf947..2a781c43a9 100644
--- a/libmpdemux/video.c
+++ b/libmpdemux/video.c
@@ -284,6 +284,10 @@ int video_read_frame(sh_video_t* sh_video,float* frame_time_ptr,unsigned char**
// override frame_time for variable/unknown FPS formats:
if(!force_fps) switch(demuxer->file_format){
+ case DEMUXER_TYPE_REAL:
+ if(d_video->pts>0 && pts1>0 && d_video->pts>pts1)
+ frame_time=d_video->pts-pts1;
+ break;
#ifdef HAVE_TV_BSDBT848
case DEMUXER_TYPE_TV:
#endif
@@ -294,15 +298,16 @@ int video_read_frame(sh_video_t* sh_video,float* frame_time_ptr,unsigned char**
float next_pts = ds_get_next_pts(d_video);
float d= next_pts > 0 ? next_pts - d_video->pts : d_video->pts-pts1;
if(d>=0){
- if(verbose)
+ if(d>0){
if((int)sh_video->fps==1000)
- mp_msg(MSGT_CPLAYER,MSGL_STATUS,"\navg. framerate: %d fps \n",(int)(1.0f/d));
- sh_video->frametime=d; // 1ms
- sh_video->fps=1.0f/d;
+ mp_msg(MSGT_CPLAYER,MSGL_V,"\navg. framerate: %d fps \n",(int)(1.0f/d));
+ sh_video->frametime=d; // 1ms
+ sh_video->fps=1.0f/d;
+ }
frame_time = d;
} else {
- mp_msg(MSGT_CPLAYER,MSGL_WARN,"\nInvalid frame duration value (%2.5f/%2.5f => %2.5f). Defaulting to 1/25 sec.\n",d_video->pts,next_pts,d);
- frame_time = 1/25.0;
+ mp_msg(MSGT_CPLAYER,MSGL_WARN,"\nInvalid frame duration value (%5.3f/%5.3f => %5.3f). Defaulting to %5.3f sec.\n",d_video->pts,next_pts,d,frame_time);
+ // frame_time = 1/25.0;
}
}
}