# HG changeset patch # User rtogni # Date 1160424002 0 # Node ID 1ef90de62efa51868c5b642ef4716aa595d7b098 # Parent f753fbd5ae6673dc990cfdd13c1431f501c88c7a Fix problems on live streams with huge timestamps, causing overflows and negative pts values. It also changes pts to double, since there is no enough precision in float to represent 32bit uint timestamps. diff -r f753fbd5ae66 -r 1ef90de62efa libmpdemux/demux_real.c --- a/libmpdemux/demux_real.c Mon Oct 09 19:57:56 2006 +0000 +++ b/libmpdemux/demux_real.c Mon Oct 09 20:00:02 2006 +0000 @@ -55,7 +55,7 @@ {77,80} }; typedef struct { - int timestamp; + unsigned int timestamp; int offset; // int packetno; // int len; /* only filled by our index generator */ @@ -82,10 +82,10 @@ int current_vpacket; // timestamp correction: - int kf_base;// timestamp of the prev. video keyframe - int kf_pts; // timestamp of next video keyframe - int a_pts; // previous audio timestamp - float v_pts; // previous video timestamp + unsigned int kf_base;// timestamp of the prev. video keyframe + unsigned int kf_pts; // timestamp of next video keyframe + unsigned int a_pts; // previous audio timestamp + double v_pts; // previous video timestamp unsigned long duration; /* stream id table */ @@ -117,7 +117,7 @@ int coded_framesize[MAX_STREAMS]; ///< coded frame size, per stream int audiopk_size[MAX_STREAMS]; ///< audio packet size unsigned char *audio_buf; ///< place to store reordered audio data - float *audio_timestamp; ///< timestamp for each audio packet + double *audio_timestamp; ///< timestamp for each audio packet int sub_packet_cnt; ///< number of subpacket already received int audio_filepos; ///< file position of first audio packet in block } real_priv_t; @@ -175,7 +175,7 @@ for (i = 0; i < entries; i++) { #if 1 - mp_msg(MSGT_DEMUX, MSGL_V,"i: %d, pos: %d, timestamp: %d\n", i, index[i].offset, index[i].timestamp); + mp_msg(MSGT_DEMUX, MSGL_V,"i: %d, pos: %d, timestamp: %u\n", i, index[i].offset, index[i].timestamp); #else mp_msg(MSGT_DEMUX, MSGL_V,"packetno: %x pos: %x len: %x timestamp: %x flags: %x\n", index[i].packetno, index[i].offset, index[i].len, index[i].timestamp, @@ -264,7 +264,7 @@ #if 1 -static void add_index_item(demuxer_t *demuxer, int stream_id, int timestamp, int offset) +static void add_index_item(demuxer_t *demuxer, int stream_id, unsigned int timestamp, int offset) { if ((unsigned)stream_id < MAX_STREAMS) { @@ -299,9 +299,10 @@ } } -static void add_index_segment(demuxer_t *demuxer, int seek_stream_id, int seek_timestamp) +static void add_index_segment(demuxer_t *demuxer, int seek_stream_id, int64_t seek_timestamp) { - int tag, len, stream_id, timestamp, flags; + int tag, len, stream_id, flags; + unsigned int timestamp; if (seek_timestamp != -1 && (unsigned)seek_stream_id >= MAX_STREAMS) return; while (1) @@ -336,7 +337,7 @@ return; } } - // printf("Index: stream=%d packet=%d timestamp=%d len=%d flags=0x%x datapos=0x%x\n", stream_id, entries, timestamp, len, flags, index->offset); + // printf("Index: stream=%d packet=%d timestamp=%u len=%d flags=0x%x datapos=0x%x\n", stream_id, entries, timestamp, len, flags, index->offset); /* skip data */ stream_skip(demuxer->stream, len-12); } @@ -382,7 +383,8 @@ int data_pos = priv->data_chunk_offset-10; int num_of_packets = 0; int i, entries = 0; - int len, stream_id = 0, timestamp, flags; + int len, stream_id = 0, flags; + unsigned int timestamp; int tab_pos = 0; read_index: @@ -493,12 +495,12 @@ #define SKIP_BITS(n) buffer<<=n #define SHOW_BITS(n) ((buffer)>>(32-(n))) -static float real_fix_timestamp(real_priv_t* priv, unsigned char* s, int timestamp, float frametime, unsigned int format){ - float v_pts; +static double real_fix_timestamp(real_priv_t* priv, unsigned char* s, unsigned int timestamp, double frametime, unsigned int format){ + double v_pts; uint32_t buffer= (s[0]<<24) + (s[1]<<16) + (s[2]<<8) + s[3]; - int kf=timestamp; + unsigned int kf=timestamp; int pict_type; - int orig_kf; + unsigned int orig_kf; #if 1 if(format==mmioFOURCC('R','V','3','0') || format==mmioFOURCC('R','V','4','0')){ @@ -521,19 +523,19 @@ kf=timestamp; } else { // P/B frame, merge timestamps: - int tmp=timestamp-priv->kf_base; + int64_t tmp=(int64_t)timestamp-priv->kf_base; kf|=tmp&(~0x1fff); // combine with packet timestamp if(kftmp+4096) kf-=8192; kf+=priv->kf_base; } if(pict_type != 3){ // P || I frame -> swap timestamps - int tmp=kf; + unsigned int tmp=kf; kf=priv->kf_pts; priv->kf_pts=tmp; // if(kf<=tmp) kf=0; } - mp_msg(MSGT_DEMUX, MSGL_DBG2,"\nTS: %08X -> %08X (%04X) %d %02X %02X %02X %02X %5d\n",timestamp,kf,orig_kf,pict_type,s[0],s[1],s[2],s[3],kf-(int)(1000.0*priv->v_pts)); + mp_msg(MSGT_DEMUX, MSGL_DBG2,"\nTS: %08X -> %08X (%04X) %d %02X %02X %02X %02X %5u\n",timestamp,kf,orig_kf,pict_type,s[0],s[1],s[2],s[3],kf-(unsigned int)(1000.0*priv->v_pts)); } #endif v_pts=kf*0.001f; @@ -557,7 +559,7 @@ real_priv_t *priv = demuxer->priv; demux_stream_t *ds = NULL; int len; - int timestamp; + unsigned int timestamp; int stream_id; #ifdef CRACK_MATRIX int i; @@ -642,7 +644,7 @@ // (int)demuxer->filepos,(int)version,(int)len, stream_id, // (int) timestamp, reserved, flags); - mp_dbg(MSGT_DEMUX,MSGL_DBG2, "\npacket#%d: pos: 0x%0x, len: %d, id: %d, pts: %d, flags: %x rvd:%d\n", + mp_dbg(MSGT_DEMUX,MSGL_DBG2, "\npacket#%d: pos: 0x%0x, len: %d, id: %d, pts: %u, flags: %x rvd:%d\n", priv->current_packet, (int)demuxer->filepos, len, stream_id, timestamp, flags, reserved); priv->current_packet++; @@ -1055,7 +1057,7 @@ sh->ds=demuxer->audio; demuxer->audio->sh=sh; priv->audio_buf = calloc(priv->sub_packet_h[demuxer->audio->id], priv->audiopk_size[demuxer->audio->id]); - priv->audio_timestamp = calloc(priv->sub_packet_h[demuxer->audio->id], sizeof(float)); + priv->audio_timestamp = calloc(priv->sub_packet_h[demuxer->audio->id], sizeof(double)); mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected RM audio ID = %d\n",stream_id); goto got_audio; } @@ -1477,7 +1479,7 @@ sh->ds=demuxer->audio; demuxer->audio->sh=sh; priv->audio_buf = calloc(priv->sub_packet_h[demuxer->audio->id], priv->audiopk_size[demuxer->audio->id]); - priv->audio_timestamp = calloc(priv->sub_packet_h[demuxer->audio->id], sizeof(float)); + priv->audio_timestamp = calloc(priv->sub_packet_h[demuxer->audio->id], sizeof(double)); } ++a_streams; @@ -1847,7 +1849,7 @@ sh_video_t *sh_video = d_video->sh; int vid = d_video->id, aid = d_audio->id; int next_offset = 0; - int cur_timestamp = 0; + int64_t cur_timestamp = 0; int streams = 0; int retried = 0; @@ -1932,7 +1934,7 @@ static int demux_real_control(demuxer_t *demuxer, int cmd, void *arg) { real_priv_t *priv = demuxer->priv; - int lastpts = priv->v_pts ? priv->v_pts : priv->a_pts; + unsigned int lastpts = priv->v_pts ? priv->v_pts : priv->a_pts; switch (cmd) { case DEMUXER_CTRL_GET_TIME_LENGTH: