[vlc-devel] Re: New Patch for RTSP offset feature.

mert at cliqtv.com mert at cliqtv.com
Thu Oct 5 19:26:44 CEST 2006


Here is the attached patch (diff) as text file. and also in the email body.



diff -urN ./modules/demux/live555.cpp ../vlc-0.8.6-changed/modules/demux/live555.cpp
--- ./modules/demux/live555.cpp	2006-08-18 05:27:00.000000000 +0400
+++ ../vlc-0.8.6-changed/modules/demux/live555.cpp	2006-09-20 19:44:31.734375000 +0400
@@ -183,6 +183,7 @@
     /* */
     int64_t          i_length;
     int64_t          i_start;
+    int64_t          i_position;
 
     /* timeout thread information */
     int              i_timeout;     /* session timeout value in seconds */
@@ -228,6 +229,7 @@
     
     MediaSubsessionIterator *iter   = NULL;
     MediaSubsession         *sub    = NULL;
+    char * tmp_url = NULL;
     int i_return;
 
     if( p_demux->s )
@@ -268,6 +270,7 @@
     p_sys->i_pcr_repeats = 0;
     p_sys->i_length = 0;
     p_sys->i_start = 0;
+    p_sys->i_position = 0;
     p_sys->p_out_asf = NULL;
     p_sys->b_no_data = VLC_TRUE;
     p_sys->i_no_data_ti = 0;
@@ -275,7 +278,20 @@
     p_sys->i_timeout = 0;
     p_sys->b_timeout_call = VLC_FALSE;
     p_sys->b_multicast = VLC_FALSE;
-    p_sys->psz_path = strdup( p_demux->psz_path );
+    tmp_url = strstr ( p_demux->psz_path , ";offset=" );
+    if ( tmp_url == NULL )
+    {
+    	p_sys->psz_path = strdup( p_demux->psz_path );
+    }
+    else
+    {
+        size_t psz_path_length = (size_t)(tmp_url - p_demux->psz_path) + 1;
+        p_sys->psz_path = (char*)malloc( psz_path_length );
+        memset (p_sys->psz_path , 0 , psz_path_length );
+        strncpy ( p_sys->psz_path , p_demux->psz_path , psz_path_length - 1 );
+        tmp_url += strlen (";offset=");
+        p_sys->i_position = atoi(tmp_url);
+    }    
 
     if( ( p_sys->scheduler = BasicTaskScheduler::createNew() ) == NULL )
     {
@@ -359,9 +375,17 @@
 
     /* Retrieve the duration if possible */
     p_sys->i_length = (int64_t)( p_sys->ms->playEndTime() * 1000000.0 );
+    p_sys->i_start = (int64_t)(p_sys->i_position * 1000000.0);
     if( p_sys->i_length < 0 )
         p_sys->i_length = -1;
-
+        
+    if ( p_sys->i_start < 0 &&
+         p_sys->i_start > p_sys->i_length )
+    {
+    	p_sys->i_start = 0;
+    	p_sys->i_position = 0;
+    }
+        
     if( ( i_return = Play( p_demux ) ) != VLC_SUCCESS )
         goto error;
     
@@ -894,7 +918,8 @@
     if( p_sys->rtsp )
     {
         /* The PLAY */
-        if( !p_sys->rtsp->playMediaSession( *p_sys->ms ) )
+        float position = 1.0 * p_sys->i_position;
+        if( !p_sys->rtsp->playMediaSession( *p_sys->ms , position ) )
         {
             msg_Err( p_demux, "RTSP PLAY failed %s", p_sys->env->getResultMsg() );
             return VLC_EGENERIC;
@@ -1252,8 +1277,16 @@
 
     /* Retrieve the duration if possible */
     p_sys->i_length = (int64_t)( p_sys->ms->playEndTime() * 1000000.0 );
+    p_sys->i_start = (int64_t)(p_sys->i_position * 1000000.0);
     if( p_sys->i_length < 0 )
         p_sys->i_length = -1;
+        
+    if ( p_sys->i_start < 0 &&
+         p_sys->i_start > p_sys->i_length )
+    {
+    	p_sys->i_start = 0;
+    	p_sys->i_position = 0;
+    }
 
     if( ( i_return = Play( p_demux ) ) != VLC_SUCCESS )
         goto error;
diff -urN ./modules/demux/ts.c ../vlc-0.8.6-changed/modules/demux/ts.c
--- ./modules/demux/ts.c	2006-09-12 23:15:20.000000000 +0400
+++ ../vlc-0.8.6-changed/modules/demux/ts.c	2006-09-20 19:46:27.046875000 +0400
@@ -336,6 +336,9 @@
     uint64_t    i_write;    /* bytes written */
     vlc_bool_t  b_file_out; /* dump mode enabled */
 
+    float       f_bitrate;
+    float       f_length;
+
     /* */
     vlc_bool_t  b_meta;
 };
@@ -366,6 +369,7 @@
 
 static iod_descriptor_t *IODNew( int , uint8_t * );
 static void              IODFree( iod_descriptor_t * );
+static void CalculateBitrate (demux_t *p_demux);
 
 #define TS_PACKET_SIZE_188 188
 #define TS_PACKET_SIZE_192 192
@@ -813,10 +817,109 @@
     var_Create( p_demux, "ts-silent", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
     var_Get( p_demux, "ts-silent", &val );
     p_sys->b_silent = val.b_bool;
+    
+    CalculateBitrate ( p_demux );
 
     return VLC_SUCCESS;
 }
 
+#define PCR_COUNT 1000
+#define TS_MAX_COUNT 200000
+
+static void CalculateBitrate (demux_t *p_demux)
+{
+    uint64_t stream_position = stream_Tell ( p_demux->s );
+    uint16_t pcr_count;
+    uint16_t ts_packet_count = 0;
+    uint64_t stream_length = 0;
+    uint32_t bitrate = 0;
+    block_t     *p_pkt;
+    demux_sys_t *p_sys = p_demux->p_sys;
+    float   stream_time;
+    msg_Err ( p_demux , "####################Calculate bitrate of MPEG TS begin");
+    for ( pcr_count = 0 ; pcr_count <= PCR_COUNT && ts_packet_count < TS_MAX_COUNT ;
ts_packet_count ++ )
+    {
+        /* Get a new TS packet */
+        if( !( p_pkt = stream_Block( p_demux->s, p_sys->i_packet_size ) ) )
+        {
+            msg_Err( p_demux, "Calculate bitrate: file exceed" );
+            break;
+        }
+        /* Check sync byte and re-sync if needed */
+        if( p_pkt->p_buffer[0] != 0x47 )
+        {
+            int break_while = 0;
+            msg_Warn( p_demux, "lost synchro" );
+            block_Release( p_pkt );
+
+            while( !p_demux->b_die && break_while != 0 )
+            {
+                uint8_t *p_peek;
+                int i_peek, i_skip = 0;
+
+                i_peek = stream_Peek( p_demux->s, &p_peek,
+                                      p_sys->i_packet_size * 10 );
+                if( i_peek < p_sys->i_packet_size + 1 )
+                {
+                    msg_Err( p_demux, "Calculate bitrate: file exceed" );
+                    break_while = 1;
+                    break;
+                }
+
+                while( i_skip < i_peek - p_sys->i_packet_size )
+                {
+                    if( p_peek[i_skip] == 0x47 &&
+                        p_peek[i_skip + p_sys->i_packet_size] == 0x47 )
+                    {
+                        break;
+                    }
+                    i_skip++;
+                }
+
+                msg_Dbg( p_demux, "skipping %d bytes of garbage", i_skip );
+                stream_Read( p_demux->s, NULL, i_skip );
+
+                if( i_skip < i_peek - p_sys->i_packet_size )
+                {
+                    break;
+                }
+            }
+
+            if( !( p_pkt = stream_Block( p_demux->s, p_sys->i_packet_size ) ) )
+            {
+                msg_Dbg( p_demux, "Calculate bitrate: file exceed" );
+                break;
+                
+            }
+        }
+        else
+        {
+            const uint8_t *p = p_pkt->p_buffer;
+            if( ( p[3]&0x20 ) && /* adaptation */
+                ( p[5]&0x10 ) &&
+                ( p[4] >= 7 ) )
+            {
+                // TS Packet has PCR marker
+                pcr_count ++;
+            }
+            block_Release( p_pkt );
+        }
+        
+    }
+    stream_length = stream_Tell ( p_demux->s ) - stream_position;
+    msg_Err ( p_demux , "We have readed %d PCR markers" , pcr_count );
+    msg_Err ( p_demux , "Bytes read %d" , stream_length );
+    bitrate = (stream_length / ( pcr_count / 14 ))/100;
+    p_sys->f_bitrate = (float) bitrate;
+    msg_Err ( p_demux , "Bitrate %d" , bitrate );
+    stream_time = ((float)(stream_Size(p_demux->s)) / (float)(bitrate))/100.0;
+    p_sys->f_length = stream_time;
+    msg_Err ( p_demux , "Stream time %f" , stream_time );
+    stream_Seek ( p_demux->s , stream_position );
+    
+    msg_Err ( p_demux , "####################Calculate bitrate of MPEG TS end");
+}
+
 /*****************************************************************************
  * Close
  *****************************************************************************/
@@ -1191,35 +1294,16 @@
                 return VLC_EGENERIC;
             }
             return VLC_SUCCESS;
-#if 0
-
         case DEMUX_GET_TIME:
             pi64 = (int64_t*)va_arg( args, int64_t * );
-            if( p_sys->i_time < 0 )
-            {
-                *pi64 = 0;
-                return VLC_EGENERIC;
-            }
-            *pi64 = p_sys->i_time;
+            i64 = stream_Tell ( p_demux->s );
+            *pi64 = I64C(1000000) * ((uint64_t)(((float)(i64) / (float)(p_sys->f_bitrate))/100.0));
             return VLC_SUCCESS;
-
+       
         case DEMUX_GET_LENGTH:
             pi64 = (int64_t*)va_arg( args, int64_t * );
-            if( p_sys->i_mux_rate > 0 )
-            {
-                *pi64 = I64C(1000000) * ( stream_Size( p_demux->s ) / 50 ) /
-                        p_sys->i_mux_rate;
-                return VLC_SUCCESS;
-            }
-            *pi64 = 0;
-            return VLC_EGENERIC;
-#else
-        case DEMUX_GET_TIME:
-        case DEMUX_GET_LENGTH:
-            pi64 = (int64_t*)va_arg( args, int64_t * );
-            *pi64 = 0;
+            *pi64 = I64C(1000000) * ((uint64_t)p_sys->f_length);
             return VLC_SUCCESS;
-#endif
         case DEMUX_SET_GROUP:
         {
             uint16_t i_vpid = 0, i_apid1 = 0, i_apid2 = 0, i_apid3 = 0;
diff -urN ./modules/misc/rtsp.c ../vlc-0.8.6-changed/modules/misc/rtsp.c
--- ./modules/misc/rtsp.c	2006-09-09 11:48:56.000000000 +0400
+++ ../vlc-0.8.6-changed/modules/misc/rtsp.c	2006-09-20 19:49:18.265625000 +0400
@@ -671,6 +671,7 @@
     char *psz_playnow = NULL; /* support option: x-playNow */
     char *psz_session = NULL;
     char *psz_cseq = NULL;
+    char *psz_position = NULL;
     rtsp_client_t *p_rtsp;
     int i_port = 0;
     int i_cseq = 0;
@@ -902,6 +903,25 @@
 
             vod_MediaControl( p_vod, p_media, psz_session, VOD_MEDIA_PLAY,
                               psz_output );
+            psz_position = httpd_MsgGet( query, "Range" );
+            if( psz_position ) psz_position = strstr( psz_position, "npt=" );
+            if( psz_position )
+            {
+                double f_pos;
+                char *end;
+
+                msg_Dbg( p_vod, "seeking request: %s", psz_position );
+
+                psz_position += 4;
+                    /* FIXME: npt= is not necessarily formatted as a float */
+                f_pos = us_strtod( psz_position, &end );
+                if( end > psz_position )
+                {
+                    f_pos /= ((double)(p_media->i_length))/1000 /1000 / 100;
+                    vod_MediaControl( p_vod, p_media, psz_session,
+                                  VOD_MEDIA_SEEK, f_pos );
+                }
+            }            
             free( psz_output );
             break;
         }
diff -urN ./modules/packetizer/h264.c ../vlc-0.8.6-changed/modules/packetizer/h264.c
--- ./modules/packetizer/h264.c	2006-08-24 05:17:58.000000000 +0400
+++ ../vlc-0.8.6-changed/modules/packetizer/h264.c	2006-09-20 19:49:47.890625000 +0400
@@ -2,7 +2,7 @@
  * h264.c: h264/avc video packetizer
  *****************************************************************************
  * Copyright (C) 2001, 2002, 2006 the VideoLAN team
- * $Id: h264.c 16332 2006-08-24 01:17:58Z hartman $
+ * $Id: h264.c 14918 2006-03-25 12:54:27Z fkuehne $
  *
  * Authors: Laurent Aimar <fenrir at via.ecp.fr>
  *          Eric Petit <titer at videolan.org>
@@ -84,7 +84,6 @@
     int i_nal_ref_idc;
     int i_idr_pic_id;
     int i_frame_num;
-    int i_frame_type;
 };
 
 enum
@@ -122,8 +121,6 @@
 
 /*****************************************************************************
  * Open: probe the packetizer and return score
- * When opening after demux, the packetizer is only loaded AFTER the decoder
- * That means that what you set in fmt_out is ignored by the decoder in this special case
  *****************************************************************************/
 static int Open( vlc_object_t *p_this )
 {
@@ -134,7 +131,6 @@
         p_dec->fmt_in.i_codec != VLC_FOURCC( 'H', '2', '6', '4') &&
         p_dec->fmt_in.i_codec != VLC_FOURCC( 'V', 'S', 'S', 'H') &&
         p_dec->fmt_in.i_codec != VLC_FOURCC( 'v', 's', 's', 'h') &&
-        p_dec->fmt_in.i_codec != VLC_FOURCC( 'D', 'A', 'V', 'C') &&
         ( p_dec->fmt_in.i_codec != VLC_FOURCC( 'a', 'v', 'c', '1') ||
           p_dec->fmt_in.i_extra < 7 ) )
     {
@@ -165,18 +161,16 @@
     p_sys->i_nal_ref_idc = -1;
     p_sys->i_idr_pic_id = -1;
     p_sys->i_frame_num = -1;
-    p_sys->i_frame_type = 0;
 
     /* Setup properties */
     es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in );
     p_dec->fmt_out.i_codec = VLC_FOURCC( 'h', '2', '6', '4' );
+    /* FIXME: FFMPEG isn't happy at all if you leave this */
+    if( p_dec->fmt_out.i_extra ) free( p_dec->fmt_out.p_extra );
+    p_dec->fmt_out.i_extra = 0; p_dec->fmt_out.p_extra = 0;
 
     if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'v', 'c', '1' ) )
     {
-        /* This type of stream is produced by mp4 and matroska
-         * when we want to store it in another streamformat, you need to convert
-         * The fmt_in.p_extra should ALWAYS contain the avcC
-         * The fmt_out.p_extra should contain all the SPS and PPS with 4 byte startcodes */
         uint8_t *p = &((uint8_t*)p_dec->fmt_in.p_extra)[4];
         int i_sps, i_pps;
         int i;
@@ -186,6 +180,7 @@
 
         /* Read SPS */
         i_sps = (*p++)&0x1f;
+
         for( i = 0; i < i_sps; i++ )
         {
             int i_length = GetWBE( p );
@@ -211,25 +206,11 @@
         msg_Dbg( p_dec, "avcC length size=%d, sps=%d, pps=%d",
                  p_sys->i_avcC_length_size, i_sps, i_pps );
 
-        /* FIXME: FFMPEG isn't happy at all if you leave this */
-        if( p_dec->fmt_out.i_extra ) free( p_dec->fmt_out.p_extra );
-        p_dec->fmt_out.i_extra = 0; p_dec->fmt_out.p_extra = NULL;
-        
-        /* Set the new extradata */
-        p_dec->fmt_out.i_extra = p_sys->p_pps->i_buffer + p_sys->p_sps->i_buffer;
-        p_dec->fmt_out.p_extra = (uint8_t*)malloc( p_dec->fmt_out.i_extra );
-        memcpy( p_dec->fmt_out.p_extra, p_sys->p_sps->p_buffer, p_sys->p_sps->i_buffer);
-        memcpy( p_dec->fmt_out.p_extra+p_sys->p_sps->i_buffer, p_sys->p_pps->p_buffer, p_sys->
p_pps->i_buffer);
-
         /* Set callback */
         p_dec->pf_packetize = PacketizeAVC1;
     }
     else
     {
-        /* This type of stream contains data with 3 of 4 byte startcodes 
-         * The fmt_in.p_extra MAY contain SPS/PPS with 4 byte startcodes
-         * The fmt_out.p_extra should be the same */
-         
         /* Set callback */
         p_dec->pf_packetize = Packetize;
 
@@ -270,8 +251,6 @@
 
 /****************************************************************************
  * Packetize: the whole thing
- * Search for the startcodes 3 or more bytes
- * Feed ParseNALBlock ALWAYS with 4 byte startcode prepended NALs
  ****************************************************************************/
 static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
 {
@@ -287,7 +266,6 @@
         switch( p_sys->i_state )
         {
             case STATE_NOSYNC:
-                /* Skip until 3 byte startcode 0 0 1 */
                 if( block_FindStartcodeFromOffset( &p_sys->bytestream,
                       &p_sys->i_offset, p_sys->startcode+1, 3 ) == VLC_SUCCESS)
                 {
@@ -296,7 +274,6 @@
 
                 if( p_sys->i_offset )
                 {
-                    /* skip the data */
                     block_SkipBytes( &p_sys->bytestream, p_sys->i_offset );
                     p_sys->i_offset = 0;
                     block_BytestreamFlush( &p_sys->bytestream );
@@ -311,7 +288,7 @@
                 p_sys->i_offset = 1; /* To find next startcode */
 
             case STATE_NEXT_SYNC:
-                /* Find the next 3 byte startcode 0 0 1*/
+                /* Find the next startcode */
                 if( block_FindStartcodeFromOffset( &p_sys->bytestream,
                       &p_sys->i_offset, p_sys->startcode+1, 3 ) != VLC_SUCCESS)
                 {
@@ -320,17 +297,14 @@
                 }
 
                 /* Get the new fragment and set the pts/dts */
-                p_pic = block_New( p_dec, p_sys->i_offset +1 );
+                p_pic = block_New( p_dec, p_sys->i_offset );
                 p_pic->i_pts = p_sys->bytestream.p_block->i_pts;
                 p_pic->i_dts = p_sys->bytestream.p_block->i_dts;
-                /* Force 4 byte startcode 0 0 0 1 */
-                p_pic->p_buffer[0] = 0;
 
-                block_GetBytes( &p_sys->bytestream, &p_pic->p_buffer[1],
-                                p_pic->i_buffer-1 );
+                block_GetBytes( &p_sys->bytestream, p_pic->p_buffer,
+                                p_pic->i_buffer );
 
-                /* Remove trailing 0 bytes */
-                while( p_pic->i_buffer && (!p_pic->p_buffer[p_pic->i_buffer-1] ) ) p_pic->
i_buffer--;
+                if( !p_pic->p_buffer[p_pic->i_buffer-1] ) p_pic->i_buffer--;
                 p_sys->i_offset = 0;
 
                 /* Parse the NAL */
@@ -355,9 +329,7 @@
 }
 
 /****************************************************************************
- * PacketizeAVC1: Takes VCL blocks of data and creates annexe B type NAL stream
- * Will always use 4 byte 0 0 0 1 startcodes
- * Will prepend a SPS and PPS before each keyframe
+ * PacketizeAVC1: the whole thing
  ****************************************************************************/
 static block_t *PacketizeAVC1( decoder_t *p_dec, block_t **pp_block )
 {
@@ -371,6 +343,22 @@
     p_block = *pp_block;
     *pp_block = NULL;
 
+#if 0
+    if( //(p_block->i_flags & BLOCK_FLAG_TYPE_I) &&
+        p_sys->p_sps && p_sys->p_pps )
+    {
+        block_t *p_pic;
+        block_t *p_sps = block_Duplicate( p_sys->p_sps );
+        block_t *p_pps = block_Duplicate( p_sys->p_pps );
+        p_sps->i_dts = p_pps->i_dts = p_block->i_dts;
+        p_sps->i_pts = p_pps->i_pts = p_block->i_pts;
+        p_pic = ParseNALBlock( p_dec, p_sps );
+        if( p_pic ) block_ChainAppend( &p_ret, p_pic );
+        p_pic = ParseNALBlock( p_dec, p_pps );
+        if( p_pic ) block_ChainAppend( &p_ret, p_pic );
+    }
+#endif
+
     for( p = p_block->p_buffer; p < &p_block->p_buffer[p_block->i_buffer]; )
     {
         block_t *p_pic;
@@ -406,16 +394,15 @@
 {
     block_t *p_nal;
 
-    p_nal = block_New( p_dec, 4 + i_size );
+    p_nal = block_New( p_dec, 3 + i_size );
 
     /* Add start code */
     p_nal->p_buffer[0] = 0x00;
     p_nal->p_buffer[1] = 0x00;
-    p_nal->p_buffer[2] = 0x00;
-    p_nal->p_buffer[3] = 0x01;
+    p_nal->p_buffer[2] = 0x01;
 
     /* Copy nalu */
-    memcpy( &p_nal->p_buffer[4], p, i_size );
+    memcpy( &p_nal->p_buffer[3], p, i_size );
 
     return p_nal;
 }
@@ -464,39 +451,21 @@
 }
 
 
-/*****************************************************************************
- * ParseNALBlock: parses annexB type NALs
- * All p_frag blocks are required to start with 0 0 0 1 4-byte startcode 
- *****************************************************************************/
 static block_t *ParseNALBlock( decoder_t *p_dec, block_t *p_frag )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
     block_t *p_pic = NULL;
 
-    const int i_nal_ref_idc = (p_frag->p_buffer[4] >> 5)&0x03;
-    const int i_nal_type = p_frag->p_buffer[4]&0x1f;
+    const int i_nal_ref_idc = (p_frag->p_buffer[3] >> 5)&0x03;
+    const int i_nal_type = p_frag->p_buffer[3]&0x1f;
 
 #define OUTPUT \
-    do {                                                      \
-        p_pic = block_ChainGather( p_sys->p_frame );          \
-        p_pic->i_length = 0;    /* FIXME */                   \
-        p_pic->i_flags |= p_sys->i_frame_type;                \
-                                                              \
-        p_sys->i_frame_type = 0;                              \
-        p_sys->p_frame = NULL;                                \
-        p_sys->b_slice = VLC_FALSE;                           \
-                                                              \
-        if( ( p_pic->i_flags & BLOCK_FLAG_TYPE_I ) &&         \
-              p_sys->p_sps && p_sys->p_pps )                  \
-        {                                                     \
-            block_t *p_sps = block_Duplicate( p_sys->p_sps ); \
-            block_t *p_pps = block_Duplicate( p_sys->p_pps ); \
-            p_sps->i_dts = p_pps->i_dts = p_pic->i_dts;       \
-            p_sps->i_pts = p_pps->i_pts = p_pic->i_pts;       \
-            block_ChainAppend( &p_sps, p_pps );               \
-            block_ChainAppend( &p_sps, p_pic );               \
-            p_pic = block_ChainGather( p_sps );               \
-        }                                                     \
+    do {                                                \
+        p_pic = block_ChainGather( p_sys->p_frame );    \
+        p_pic->i_length = 0;    /* FIXME */             \
+                                                        \
+        p_sys->p_frame = NULL;                          \
+        p_sys->b_slice = VLC_FALSE;                     \
     } while(0)
 
 
@@ -519,13 +488,13 @@
     else if( i_nal_type >= NAL_SLICE && i_nal_type <= NAL_SLICE_IDR )
     {
         uint8_t *dec;
-        int i_dec, i_first_mb, i_slice_type, i_frame_num;
+        int i_dec, i_first_mb, i_slice_type, i_frame_num, i_pic_flags = 0;
         vlc_bool_t b_pic = VLC_FALSE;
         bs_t s;
 
         /* do not convert the whole frame */
-        nal_get_decoded( &dec, &i_dec, &p_frag->p_buffer[5],
-                         __MIN( p_frag->i_buffer - 5, 60 ) );
+        nal_get_decoded( &dec, &i_dec, &p_frag->p_buffer[4],
+                         __MIN( p_frag->i_buffer - 4, 60 ) );
         bs_init( &s, dec, i_dec );
 
         /* first_mb_in_slice */
@@ -534,21 +503,21 @@
         /* slice_type */
         switch( (i_slice_type = bs_read_ue( &s )) )
         {
-        case 0: case 5:
-            p_sys->i_frame_type = BLOCK_FLAG_TYPE_P;
-            break;
-        case 1: case 6:
-            p_sys->i_frame_type = BLOCK_FLAG_TYPE_B;
-            break;
-        case 2: case 7:
-            p_sys->i_frame_type = BLOCK_FLAG_TYPE_I;
-            break;
-        case 3: case 8: /* SP */
-            p_sys->i_frame_type = BLOCK_FLAG_TYPE_P;
-            break;
-        case 4: case 9:
-            p_sys->i_frame_type = BLOCK_FLAG_TYPE_I;
-            break;
+            case 0: case 5:
+                i_pic_flags = BLOCK_FLAG_TYPE_P;
+                break;
+            case 1: case 6:
+                i_pic_flags = BLOCK_FLAG_TYPE_B;
+                break;
+            case 2: case 7:
+                i_pic_flags = BLOCK_FLAG_TYPE_I;
+                break;
+            case 3: case 8: /* SP */
+                i_pic_flags = BLOCK_FLAG_TYPE_P;
+                break;
+            case 4: case 9:
+                i_pic_flags = BLOCK_FLAG_TYPE_I;
+                break;
         }
 
         /* pic_parameter_set_id */
@@ -604,8 +573,8 @@
 
         p_sys->b_sps = VLC_TRUE;
 
-        nal_get_decoded( &dec, &i_dec, &p_frag->p_buffer[5],
-                         p_frag->i_buffer - 5 );
+        nal_get_decoded( &dec, &i_dec, &p_frag->p_buffer[4],
+                         p_frag->i_buffer - 4 );
 
         bs_init( &s, dec, i_dec );
         /* Skip profile(8), constraint_set012, reserver(5), level(8) */
@@ -710,19 +679,13 @@
 
         free( dec );
 
-        if( p_sys->b_slice ) OUTPUT;
-
-        /* We have a new SPS */
-        if( p_sys->p_sps ) block_Release( p_sys->p_sps );
-        p_sys->p_sps = p_frag;
 
-        /* Do not append the SPS because we will insert it on keyframes */
-        return p_pic;
+        if( p_sys->b_slice ) OUTPUT;
     }
     else if( i_nal_type == NAL_PPS )
     {
         bs_t s;
-        bs_init( &s, &p_frag->p_buffer[5], p_frag->i_buffer - 5 );
+        bs_init( &s, &p_frag->p_buffer[4], p_frag->i_buffer - 4 );
 
         if( !p_sys->b_pps ) msg_Dbg( p_dec, "found NAL_PPS" );
         p_sys->b_pps = VLC_TRUE;
@@ -730,13 +693,6 @@
         /* TODO */
 
         if( p_sys->b_slice ) OUTPUT;
-
-        /* We have a new PPS */
-        if( p_sys->p_pps ) block_Release( p_sys->p_pps );
-        p_sys->p_pps = p_frag;
-
-        /* Do not append the PPS because we will insert it on keyframes */
-        return p_pic;
     }
     else if( i_nal_type == NAL_AU_DELIMITER ||
              i_nal_type == NAL_SEI ||
diff -urN ./vlc_rtsp_time_offset.patch ../vlc-0.8.6-changed/vlc_rtsp_time_offset.patch
--- ./vlc_rtsp_time_offset.patch	2006-09-20 20:08:34.375000000 +0400
+++ ../vlc-0.8.6-changed/vlc_rtsp_time_offset.patch	1970-01-01 03:00:00.000000000 +0300
@@ -1,655 +0,0 @@
-diff -urN ./modules/demux/live555.cpp ../vlc-0.8.6-changed/modules/demux/live555.cpp
---- ./modules/demux/live555.cpp	2006-08-18 05:27:00.000000000 +0400
-+++ ../vlc-0.8.6-changed/modules/demux/live555.cpp	2006-09-20 19:44:31.734375000 +0400
-@@ -183,6 +183,7 @@
-     /* */
-     int64_t          i_length;
-     int64_t          i_start;
-+    int64_t          i_position;
- 
-     /* timeout thread information */
-     int              i_timeout;     /* session timeout value in seconds */
-@@ -228,6 +229,7 @@
-     
-     MediaSubsessionIterator *iter   = NULL;
-     MediaSubsession         *sub    = NULL;
-+    char * tmp_url = NULL;
-     int i_return;
- 
-     if( p_demux->s )
-@@ -268,6 +270,7 @@
-     p_sys->i_pcr_repeats = 0;
-     p_sys->i_length = 0;
-     p_sys->i_start = 0;
-+    p_sys->i_position = 0;
-     p_sys->p_out_asf = NULL;
-     p_sys->b_no_data = VLC_TRUE;
-     p_sys->i_no_data_ti = 0;
-@@ -275,7 +278,20 @@
-     p_sys->i_timeout = 0;
-     p_sys->b_timeout_call = VLC_FALSE;
-     p_sys->b_multicast = VLC_FALSE;
--    p_sys->psz_path = strdup( p_demux->psz_path );
-+    tmp_url = strstr ( p_demux->psz_path , ";offset=" );
-+    if ( tmp_url == NULL )
-+    {
-+    	p_sys->psz_path = strdup( p_demux->psz_path );
-+    }
-+    else
-+    {
-+        size_t psz_path_length = (size_t)(tmp_url - p_demux->psz_path) + 1;
-+        p_sys->psz_path = (char*)malloc( psz_path_length );
-+        memset (p_sys->psz_path , 0 , psz_path_length );
-+        strncpy ( p_sys->psz_path , p_demux->psz_path , psz_path_length - 1 );
-+        tmp_url += strlen (";offset=");
-+        p_sys->i_position = atoi(tmp_url);
-+    }    
- 
-     if( ( p_sys->scheduler = BasicTaskScheduler::createNew() ) == NULL )
-     {
-@@ -359,9 +375,17 @@
- 
-     /* Retrieve the duration if possible */
-     p_sys->i_length = (int64_t)( p_sys->ms->playEndTime() * 1000000.0 );
-+    p_sys->i_start = (int64_t)(p_sys->i_position * 1000000.0);
-     if( p_sys->i_length < 0 )
-         p_sys->i_length = -1;
--
-+        
-+    if ( p_sys->i_start < 0 &&
-+         p_sys->i_start > p_sys->i_length )
-+    {
-+    	p_sys->i_start = 0;
-+    	p_sys->i_position = 0;
-+    }
-+        
-     if( ( i_return = Play( p_demux ) ) != VLC_SUCCESS )
-         goto error;
-     
-@@ -894,7 +918,8 @@
-     if( p_sys->rtsp )
-     {
-         /* The PLAY */
--        if( !p_sys->rtsp->playMediaSession( *p_sys->ms ) )
-+        float position = 1.0 * p_sys->i_position;
-+        if( !p_sys->rtsp->playMediaSession( *p_sys->ms , position ) )
-         {
-             msg_Err( p_demux, "RTSP PLAY failed %s", p_sys->env->getResultMsg() );
-             return VLC_EGENERIC;
-@@ -1252,8 +1277,16 @@
- 
-     /* Retrieve the duration if possible */
-     p_sys->i_length = (int64_t)( p_sys->ms->playEndTime() * 1000000.0 );
-+    p_sys->i_start = (int64_t)(p_sys->i_position * 1000000.0);
-     if( p_sys->i_length < 0 )
-         p_sys->i_length = -1;
-+        
-+    if ( p_sys->i_start < 0 &&
-+         p_sys->i_start > p_sys->i_length )
-+    {
-+    	p_sys->i_start = 0;
-+    	p_sys->i_position = 0;
-+    }
- 
-     if( ( i_return = Play( p_demux ) ) != VLC_SUCCESS )
-         goto error;
-diff -urN ./modules/demux/ts.c ../vlc-0.8.6-changed/modules/demux/ts.c
---- ./modules/demux/ts.c	2006-09-12 23:15:20.000000000 +0400
-+++ ../vlc-0.8.6-changed/modules/demux/ts.c	2006-09-20 19:46:27.046875000 +0400
-@@ -336,6 +336,9 @@
-     uint64_t    i_write;    /* bytes written */
-     vlc_bool_t  b_file_out; /* dump mode enabled */
- 
-+    float       f_bitrate;
-+    float       f_length;
-+
-     /* */
-     vlc_bool_t  b_meta;
- };
-@@ -366,6 +369,7 @@
- 
- static iod_descriptor_t *IODNew( int , uint8_t * );
- static void              IODFree( iod_descriptor_t * );
-+static void CalculateBitrate (demux_t *p_demux);
- 
- #define TS_PACKET_SIZE_188 188
- #define TS_PACKET_SIZE_192 192
-@@ -813,10 +817,109 @@
-     var_Create( p_demux, "ts-silent", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
-     var_Get( p_demux, "ts-silent", &val );
-     p_sys->b_silent = val.b_bool;
-+    
-+    CalculateBitrate ( p_demux );
- 
-     return VLC_SUCCESS;
- }
- 
-+#define PCR_COUNT 1000
-+#define TS_MAX_COUNT 200000
-+
-+static void CalculateBitrate (demux_t *p_demux)
-+{
-+    uint64_t stream_position = stream_Tell ( p_demux->s );
-+    uint16_t pcr_count;
-+    uint16_t ts_packet_count = 0;
-+    uint64_t stream_length = 0;
-+    uint32_t bitrate = 0;
-+    block_t     *p_pkt;
-+    demux_sys_t *p_sys = p_demux->p_sys;
-+    float   stream_time;
-+    msg_Err ( p_demux , "####################Calculate bitrate of MPEG TS begin");
-+    for ( pcr_count = 0 ; pcr_count <= PCR_COUNT && ts_packet_count < TS_MAX_COUNT ;
ts_packet_count ++ )
-+    {
-+        /* Get a new TS packet */
-+        if( !( p_pkt = stream_Block( p_demux->s, p_sys->i_packet_size ) ) )
-+        {
-+            msg_Err( p_demux, "Calculate bitrate: file exceed" );
-+            break;
-+        }
-+        /* Check sync byte and re-sync if needed */
-+        if( p_pkt->p_buffer[0] != 0x47 )
-+        {
-+            int break_while = 0;
-+            msg_Warn( p_demux, "lost synchro" );
-+            block_Release( p_pkt );
-+
-+            while( !p_demux->b_die && break_while != 0 )
-+            {
-+                uint8_t *p_peek;
-+                int i_peek, i_skip = 0;
-+
-+                i_peek = stream_Peek( p_demux->s, &p_peek,
-+                                      p_sys->i_packet_size * 10 );
-+                if( i_peek < p_sys->i_packet_size + 1 )
-+                {
-+                    msg_Err( p_demux, "Calculate bitrate: file exceed" );
-+                    break_while = 1;
-+                    break;
-+                }
-+
-+                while( i_skip < i_peek - p_sys->i_packet_size )
-+                {
-+                    if( p_peek[i_skip] == 0x47 &&
-+                        p_peek[i_skip + p_sys->i_packet_size] == 0x47 )
-+                    {
-+                        break;
-+                    }
-+                    i_skip++;
-+                }
-+
-+                msg_Dbg( p_demux, "skipping %d bytes of garbage", i_skip );
-+                stream_Read( p_demux->s, NULL, i_skip );
-+
-+                if( i_skip < i_peek - p_sys->i_packet_size )
-+                {
-+                    break;
-+                }
-+            }
-+
-+            if( !( p_pkt = stream_Block( p_demux->s, p_sys->i_packet_size ) ) )
-+            {
-+                msg_Dbg( p_demux, "Calculate bitrate: file exceed" );
-+                break;
-+                
-+            }
-+        }
-+        else
-+        {
-+            const uint8_t *p = p_pkt->p_buffer;
-+            if( ( p[3]&0x20 ) && /* adaptation */
-+                ( p[5]&0x10 ) &&
-+                ( p[4] >= 7 ) )
-+            {
-+                // TS Packet has PCR marker
-+                pcr_count ++;
-+            }
-+            block_Release( p_pkt );
-+        }
-+        
-+    }
-+    stream_length = stream_Tell ( p_demux->s ) - stream_position;
-+    msg_Err ( p_demux , "We have readed %d PCR markers" , pcr_count );
-+    msg_Err ( p_demux , "Bytes read %d" , stream_length );
-+    bitrate = (stream_length / ( pcr_count / 14 ))/100;
-+    p_sys->f_bitrate = (float) bitrate;
-+    msg_Err ( p_demux , "Bitrate %d" , bitrate );
-+    stream_time = ((float)(stream_Size(p_demux->s)) / (float)(bitrate))/100.0;
-+    p_sys->f_length = stream_time;
-+    msg_Err ( p_demux , "Stream time %f" , stream_time );
-+    stream_Seek ( p_demux->s , stream_position );
-+    
-+    msg_Err ( p_demux , "####################Calculate bitrate of MPEG TS end");
-+}
-+
- /*****************************************************************************
-  * Close
-  *****************************************************************************/
-@@ -1191,35 +1294,16 @@
-                 return VLC_EGENERIC;
-             }
-             return VLC_SUCCESS;
--#if 0
--
-         case DEMUX_GET_TIME:
-             pi64 = (int64_t*)va_arg( args, int64_t * );
--            if( p_sys->i_time < 0 )
--            {
--                *pi64 = 0;
--                return VLC_EGENERIC;
--            }
--            *pi64 = p_sys->i_time;
-+            i64 = stream_Tell ( p_demux->s );
-+            *pi64 = I64C(1000000) * ((uint64_t)(((float)(i64) / (float)(p_sys->
f_bitrate))/100.0));
-             return VLC_SUCCESS;
--
-+       
-         case DEMUX_GET_LENGTH:
-             pi64 = (int64_t*)va_arg( args, int64_t * );
--            if( p_sys->i_mux_rate > 0 )
--            {
--                *pi64 = I64C(1000000) * ( stream_Size( p_demux->s ) / 50 ) /
--                        p_sys->i_mux_rate;
--                return VLC_SUCCESS;
--            }
--            *pi64 = 0;
--            return VLC_EGENERIC;
--#else
--        case DEMUX_GET_TIME:
--        case DEMUX_GET_LENGTH:
--            pi64 = (int64_t*)va_arg( args, int64_t * );
--            *pi64 = 0;
-+            *pi64 = I64C(1000000) * ((uint64_t)p_sys->f_length);
-             return VLC_SUCCESS;
--#endif
-         case DEMUX_SET_GROUP:
-         {
-             uint16_t i_vpid = 0, i_apid1 = 0, i_apid2 = 0, i_apid3 = 0;
-diff -urN ./modules/misc/rtsp.c ../vlc-0.8.6-changed/modules/misc/rtsp.c
---- ./modules/misc/rtsp.c	2006-09-09 11:48:56.000000000 +0400
-+++ ../vlc-0.8.6-changed/modules/misc/rtsp.c	2006-09-20 19:49:18.265625000 +0400
-@@ -671,6 +671,7 @@
-     char *psz_playnow = NULL; /* support option: x-playNow */
-     char *psz_session = NULL;
-     char *psz_cseq = NULL;
-+    char *psz_position = NULL;
-     rtsp_client_t *p_rtsp;
-     int i_port = 0;
-     int i_cseq = 0;
-@@ -902,6 +903,25 @@
- 
-             vod_MediaControl( p_vod, p_media, psz_session, VOD_MEDIA_PLAY,
-                               psz_output );
-+            psz_position = httpd_MsgGet( query, "Range" );
-+            if( psz_position ) psz_position = strstr( psz_position, "npt=" );
-+            if( psz_position )
-+            {
-+                double f_pos;
-+                char *end;
-+
-+                msg_Dbg( p_vod, "seeking request: %s", psz_position );
-+
-+                psz_position += 4;
-+                    /* FIXME: npt= is not necessarily formatted as a float */
-+                f_pos = us_strtod( psz_position, &end );
-+                if( end > psz_position )
-+                {
-+                    f_pos /= ((double)(p_media->i_length))/1000 /1000 / 100;
-+                    vod_MediaControl( p_vod, p_media, psz_session,
-+                                  VOD_MEDIA_SEEK, f_pos );
-+                }
-+            }            
-             free( psz_output );
-             break;
-         }
-diff -urN ./modules/packetizer/h264.c ../vlc-0.8.6-changed/modules/packetizer/h264.c
---- ./modules/packetizer/h264.c	2006-08-24 05:17:58.000000000 +0400
-+++ ../vlc-0.8.6-changed/modules/packetizer/h264.c	2006-09-20 19:49:47.890625000 +0400
-@@ -2,7 +2,7 @@
-  * h264.c: h264/avc video packetizer
-  *****************************************************************************
-  * Copyright (C) 2001, 2002, 2006 the VideoLAN team
-- * $Id: h264.c 16332 2006-08-24 01:17:58Z hartman $
-+ * $Id: h264.c 14918 2006-03-25 12:54:27Z fkuehne $
-  *
-  * Authors: Laurent Aimar <fenrir at via.ecp.fr>
-  *          Eric Petit <titer at videolan.org>
-@@ -84,7 +84,6 @@
-     int i_nal_ref_idc;
-     int i_idr_pic_id;
-     int i_frame_num;
--    int i_frame_type;
- };
- 
- enum
-@@ -122,8 +121,6 @@
- 
- /*****************************************************************************
-  * Open: probe the packetizer and return score
-- * When opening after demux, the packetizer is only loaded AFTER the decoder
-- * That means that what you set in fmt_out is ignored by the decoder in this special case
-  *****************************************************************************/
- static int Open( vlc_object_t *p_this )
- {
-@@ -134,7 +131,6 @@
-         p_dec->fmt_in.i_codec != VLC_FOURCC( 'H', '2', '6', '4') &&
-         p_dec->fmt_in.i_codec != VLC_FOURCC( 'V', 'S', 'S', 'H') &&
-         p_dec->fmt_in.i_codec != VLC_FOURCC( 'v', 's', 's', 'h') &&
--        p_dec->fmt_in.i_codec != VLC_FOURCC( 'D', 'A', 'V', 'C') &&
-         ( p_dec->fmt_in.i_codec != VLC_FOURCC( 'a', 'v', 'c', '1') ||
-           p_dec->fmt_in.i_extra < 7 ) )
-     {
-@@ -165,18 +161,16 @@
-     p_sys->i_nal_ref_idc = -1;
-     p_sys->i_idr_pic_id = -1;
-     p_sys->i_frame_num = -1;
--    p_sys->i_frame_type = 0;
- 
-     /* Setup properties */
-     es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in );
-     p_dec->fmt_out.i_codec = VLC_FOURCC( 'h', '2', '6', '4' );
-+    /* FIXME: FFMPEG isn't happy at all if you leave this */
-+    if( p_dec->fmt_out.i_extra ) free( p_dec->fmt_out.p_extra );
-+    p_dec->fmt_out.i_extra = 0; p_dec->fmt_out.p_extra = 0;
- 
-     if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'v', 'c', '1' ) )
-     {
--        /* This type of stream is produced by mp4 and matroska
--         * when we want to store it in another streamformat, you need to convert
--         * The fmt_in.p_extra should ALWAYS contain the avcC
--         * The fmt_out.p_extra should contain all the SPS and PPS with 4 byte startcodes */
-         uint8_t *p = &((uint8_t*)p_dec->fmt_in.p_extra)[4];
-         int i_sps, i_pps;
-         int i;
-@@ -186,6 +180,7 @@
- 
-         /* Read SPS */
-         i_sps = (*p++)&0x1f;
-+
-         for( i = 0; i < i_sps; i++ )
-         {
-             int i_length = GetWBE( p );
-@@ -211,25 +206,11 @@
-         msg_Dbg( p_dec, "avcC length size=%d, sps=%d, pps=%d",
-                  p_sys->i_avcC_length_size, i_sps, i_pps );
- 
--        /* FIXME: FFMPEG isn't happy at all if you leave this */
--        if( p_dec->fmt_out.i_extra ) free( p_dec->fmt_out.p_extra );
--        p_dec->fmt_out.i_extra = 0; p_dec->fmt_out.p_extra = NULL;
--        
--        /* Set the new extradata */
--        p_dec->fmt_out.i_extra = p_sys->p_pps->i_buffer + p_sys->p_sps->i_buffer;
--        p_dec->fmt_out.p_extra = (uint8_t*)malloc( p_dec->fmt_out.i_extra );
--        memcpy( p_dec->fmt_out.p_extra, p_sys->p_sps->p_buffer, p_sys->p_sps->i_buffer);
--        memcpy( p_dec->fmt_out.p_extra+p_sys->p_sps->i_buffer, p_sys->p_pps->p_buffer, p_sys->
p_pps->i_buffer);
--
-         /* Set callback */
-         p_dec->pf_packetize = PacketizeAVC1;
-     }
-     else
-     {
--        /* This type of stream contains data with 3 of 4 byte startcodes 
--         * The fmt_in.p_extra MAY contain SPS/PPS with 4 byte startcodes
--         * The fmt_out.p_extra should be the same */
--         
-         /* Set callback */
-         p_dec->pf_packetize = Packetize;
- 
-@@ -270,8 +251,6 @@
- 
- /****************************************************************************
-  * Packetize: the whole thing
-- * Search for the startcodes 3 or more bytes
-- * Feed ParseNALBlock ALWAYS with 4 byte startcode prepended NALs
-  ****************************************************************************/
- static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
- {
-@@ -287,7 +266,6 @@
-         switch( p_sys->i_state )
-         {
-             case STATE_NOSYNC:
--                /* Skip until 3 byte startcode 0 0 1 */
-                 if( block_FindStartcodeFromOffset( &p_sys->bytestream,
-                       &p_sys->i_offset, p_sys->startcode+1, 3 ) == VLC_SUCCESS)
-                 {
-@@ -296,7 +274,6 @@
- 
-                 if( p_sys->i_offset )
-                 {
--                    /* skip the data */
-                     block_SkipBytes( &p_sys->bytestream, p_sys->i_offset );
-                     p_sys->i_offset = 0;
-                     block_BytestreamFlush( &p_sys->bytestream );
-@@ -311,7 +288,7 @@
-                 p_sys->i_offset = 1; /* To find next startcode */
- 
-             case STATE_NEXT_SYNC:
--                /* Find the next 3 byte startcode 0 0 1*/
-+                /* Find the next startcode */
-                 if( block_FindStartcodeFromOffset( &p_sys->bytestream,
-                       &p_sys->i_offset, p_sys->startcode+1, 3 ) != VLC_SUCCESS)
-                 {
-@@ -320,17 +297,14 @@
-                 }
- 
-                 /* Get the new fragment and set the pts/dts */
--                p_pic = block_New( p_dec, p_sys->i_offset +1 );
-+                p_pic = block_New( p_dec, p_sys->i_offset );
-                 p_pic->i_pts = p_sys->bytestream.p_block->i_pts;
-                 p_pic->i_dts = p_sys->bytestream.p_block->i_dts;
--                /* Force 4 byte startcode 0 0 0 1 */
--                p_pic->p_buffer[0] = 0;
- 
--                block_GetBytes( &p_sys->bytestream, &p_pic->p_buffer[1],
--                                p_pic->i_buffer-1 );
-+                block_GetBytes( &p_sys->bytestream, p_pic->p_buffer,
-+                                p_pic->i_buffer );
- 
--                /* Remove trailing 0 bytes */
--                while( p_pic->i_buffer && (!p_pic->p_buffer[p_pic->i_buffer-1] ) ) p_pic->
i_buffer--;
-+                if( !p_pic->p_buffer[p_pic->i_buffer-1] ) p_pic->i_buffer--;
-                 p_sys->i_offset = 0;
- 
-                 /* Parse the NAL */
-@@ -355,9 +329,7 @@
- }
- 
- /****************************************************************************
-- * PacketizeAVC1: Takes VCL blocks of data and creates annexe B type NAL stream
-- * Will always use 4 byte 0 0 0 1 startcodes
-- * Will prepend a SPS and PPS before each keyframe
-+ * PacketizeAVC1: the whole thing
-  ****************************************************************************/
- static block_t *PacketizeAVC1( decoder_t *p_dec, block_t **pp_block )
- {
-@@ -371,6 +343,22 @@
-     p_block = *pp_block;
-     *pp_block = NULL;
- 
-+#if 0
-+    if( //(p_block->i_flags & BLOCK_FLAG_TYPE_I) &&
-+        p_sys->p_sps && p_sys->p_pps )
-+    {
-+        block_t *p_pic;
-+        block_t *p_sps = block_Duplicate( p_sys->p_sps );
-+        block_t *p_pps = block_Duplicate( p_sys->p_pps );
-+        p_sps->i_dts = p_pps->i_dts = p_block->i_dts;
-+        p_sps->i_pts = p_pps->i_pts = p_block->i_pts;
-+        p_pic = ParseNALBlock( p_dec, p_sps );
-+        if( p_pic ) block_ChainAppend( &p_ret, p_pic );
-+        p_pic = ParseNALBlock( p_dec, p_pps );
-+        if( p_pic ) block_ChainAppend( &p_ret, p_pic );
-+    }
-+#endif
-+
-     for( p = p_block->p_buffer; p < &p_block->p_buffer[p_block->i_buffer]; )
-     {
-         block_t *p_pic;
-@@ -406,16 +394,15 @@
- {
-     block_t *p_nal;
- 
--    p_nal = block_New( p_dec, 4 + i_size );
-+    p_nal = block_New( p_dec, 3 + i_size );
- 
-     /* Add start code */
-     p_nal->p_buffer[0] = 0x00;
-     p_nal->p_buffer[1] = 0x00;
--    p_nal->p_buffer[2] = 0x00;
--    p_nal->p_buffer[3] = 0x01;
-+    p_nal->p_buffer[2] = 0x01;
- 
-     /* Copy nalu */
--    memcpy( &p_nal->p_buffer[4], p, i_size );
-+    memcpy( &p_nal->p_buffer[3], p, i_size );
- 
-     return p_nal;
- }
-@@ -464,39 +451,21 @@
- }
- 
- 
--/*****************************************************************************
-- * ParseNALBlock: parses annexB type NALs
-- * All p_frag blocks are required to start with 0 0 0 1 4-byte startcode 
-- *****************************************************************************/
- static block_t *ParseNALBlock( decoder_t *p_dec, block_t *p_frag )
- {
-     decoder_sys_t *p_sys = p_dec->p_sys;
-     block_t *p_pic = NULL;
- 
--    const int i_nal_ref_idc = (p_frag->p_buffer[4] >> 5)&0x03;
--    const int i_nal_type = p_frag->p_buffer[4]&0x1f;
-+    const int i_nal_ref_idc = (p_frag->p_buffer[3] >> 5)&0x03;
-+    const int i_nal_type = p_frag->p_buffer[3]&0x1f;
- 
- #define OUTPUT \
--    do {                                                      \
--        p_pic = block_ChainGather( p_sys->p_frame );          \
--        p_pic->i_length = 0;    /* FIXME */                   \
--        p_pic->i_flags |= p_sys->i_frame_type;                \
--                                                              \
--        p_sys->i_frame_type = 0;                              \
--        p_sys->p_frame = NULL;                                \
--        p_sys->b_slice = VLC_FALSE;                           \
--                                                              \
--        if( ( p_pic->i_flags & BLOCK_FLAG_TYPE_I ) &&         \
--              p_sys->p_sps && p_sys->p_pps )                  \
--        {                                                     \
--            block_t *p_sps = block_Duplicate( p_sys->p_sps ); \
--            block_t *p_pps = block_Duplicate( p_sys->p_pps ); \
--            p_sps->i_dts = p_pps->i_dts = p_pic->i_dts;       \
--            p_sps->i_pts = p_pps->i_pts = p_pic->i_pts;       \
--            block_ChainAppend( &p_sps, p_pps );               \
--            block_ChainAppend( &p_sps, p_pic );               \
--            p_pic = block_ChainGather( p_sps );               \
--        }                                                     \
-+    do {                                                \
-+        p_pic = block_ChainGather( p_sys->p_frame );    \
-+        p_pic->i_length = 0;    /* FIXME */             \
-+                                                        \
-+        p_sys->p_frame = NULL;                          \
-+        p_sys->b_slice = VLC_FALSE;                     \
-     } while(0)
- 
- 
-@@ -519,13 +488,13 @@
-     else if( i_nal_type >= NAL_SLICE && i_nal_type <= NAL_SLICE_IDR )
-     {
-         uint8_t *dec;
--        int i_dec, i_first_mb, i_slice_type, i_frame_num;
-+        int i_dec, i_first_mb, i_slice_type, i_frame_num, i_pic_flags = 0;
-         vlc_bool_t b_pic = VLC_FALSE;
-         bs_t s;
- 
-         /* do not convert the whole frame */
--        nal_get_decoded( &dec, &i_dec, &p_frag->p_buffer[5],
--                         __MIN( p_frag->i_buffer - 5, 60 ) );
-+        nal_get_decoded( &dec, &i_dec, &p_frag->p_buffer[4],
-+                         __MIN( p_frag->i_buffer - 4, 60 ) );
-         bs_init( &s, dec, i_dec );
- 
-         /* first_mb_in_slice */
-@@ -534,21 +503,21 @@
-         /* slice_type */
-         switch( (i_slice_type = bs_read_ue( &s )) )
-         {
--        case 0: case 5:
--            p_sys->i_frame_type = BLOCK_FLAG_TYPE_P;
--            break;
--        case 1: case 6:
--            p_sys->i_frame_type = BLOCK_FLAG_TYPE_B;
--            break;
--        case 2: case 7:
--            p_sys->i_frame_type = BLOCK_FLAG_TYPE_I;
--            break;
--        case 3: case 8: /* SP */
--            p_sys->i_frame_type = BLOCK_FLAG_TYPE_P;
--            break;
--        case 4: case 9:
--            p_sys->i_frame_type = BLOCK_FLAG_TYPE_I;
--            break;
-+            case 0: case 5:
-+                i_pic_flags = BLOCK_FLAG_TYPE_P;
-+                break;
-+            case 1: case 6:
-+                i_pic_flags = BLOCK_FLAG_TYPE_B;
-+                break;
-+            case 2: case 7:
-+                i_pic_flags = BLOCK_FLAG_TYPE_I;
-+                break;
-+            case 3: case 8: /* SP */
-+                i_pic_flags = BLOCK_FLAG_TYPE_P;
-+                break;
-+            case 4: case 9:
-+                i_pic_flags = BLOCK_FLAG_TYPE_I;
-+                break;
-         }
- 
-         /* pic_parameter_set_id */
-@@ -604,8 +573,8 @@
- 
-         p_sys->b_sps = VLC_TRUE;
- 
--        nal_get_decoded( &dec, &i_dec, &p_frag->p_buffer[5],
--                         p_frag->i_buffer - 5 );
-+        nal_get_decoded( &dec, &i_dec, &p_frag->p_buffer[4],
-+                         p_frag->i_buffer - 4 );
- 
-         bs_init( &s, dec, i_dec );
-         /* Skip profile(8), constraint_set012, reserver(5), level(8) */
-@@ -710,19 +679,13 @@
- 
-         free( dec );
- 
--        if( p_sys->b_slice ) OUTPUT;
--
--        /* We have a new SPS */
--        if( p_sys->p_sps ) block_Release( p_sys->p_sps );
--        p_sys->p_sps = p_frag;
- 
--        /* Do not append the SPS because we will insert it on keyframes */
--        return p_pic;
-+        if( p_sys->b_slice ) OUTPUT;
-     }
-     else if( i_nal_type == NAL_PPS )
-     {
-         bs_t s;
--        bs_init( &s, &p_frag->p_buffer[5], p_frag->i_buffer - 5 );
-+        bs_init( &s, &p_frag->p_buffer[4], p_frag->i_buffer - 4 );
- 
-         if( !p_sys->b_pps ) msg_Dbg( p_dec, "found NAL_PPS" );
-         p_sys->b_pps = VLC_TRUE;
-@@ -730,13 +693,6 @@
-         /* TODO */
- 
-         if( p_sys->b_slice ) OUTPUT;
--
--        /* We have a new PPS */
--        if( p_sys->p_pps ) block_Release( p_sys->p_pps );
--        p_sys->p_pps = p_frag;
--
--        /* Do not append the PPS because we will insert it on keyframes */
--        return p_pic;
-     }
-     else if( i_nal_type == NAL_AU_DELIMITER ||
-              i_nal_type == NAL_SEI ||


----- Original Message -----
From: mert at cliqtv.com
To:  <vlc-devel at videolan.org>
Sent:  Thu, 5 Oct 2006 09:48:14 -0700
Subject: New Patch for RTSP offset feature.

This patch allows VLC to accept url in the following format;
rtsp://servername/path/stream;offset=nnn

Offset variable in seconds and allows to start the stream from nnn seconds. for example 300 seconds
starts the stream from 5th minute.

Could you also let me know when this takes its place in nightly builds, so we can use that instead
of ours.

Thanks,
Mert Cubukcuoglu


-------------- next part --------------
A non-text attachment was scrubbed...
Name: vlc_rtsp_time_offset_h264.txt
Type: application/binary
Size: 49289 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20061005/b76482e1/attachment.bin>


More information about the vlc-devel mailing list