[vlc-commits] demux: ts/ps: check marked bits and fixed headers
Francois Cartegnie
git at videolan.org
Mon Dec 12 15:00:47 CET 2016
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Mon Dec 12 14:39:03 2016 +0100| [e9938d680f006a023871cb4cb89f0a58e180bc14] | committer: Francois Cartegnie
demux: ts/ps: check marked bits and fixed headers
refs #17773
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=e9938d680f006a023871cb4cb89f0a58e180bc14
---
modules/demux/mpeg/pes.h | 32 ++++++++++++++++++++++----------
modules/demux/mpeg/ps.h | 6 ++++--
modules/demux/mpeg/ts_hotfixes.c | 8 ++++----
3 files changed, 30 insertions(+), 16 deletions(-)
diff --git a/modules/demux/mpeg/pes.h b/modules/demux/mpeg/pes.h
index 9a2cc34..7ad420a 100644
--- a/modules/demux/mpeg/pes.h
+++ b/modules/demux/mpeg/pes.h
@@ -20,13 +20,21 @@
#ifndef VLC_MPEG_PES_H
#define VLC_MPEG_PES_H
-static inline mtime_t ExtractPESTimestamp( const uint8_t *p_data )
+static inline bool ExtractPESTimestamp( const uint8_t *p_data, uint8_t i_flags, mtime_t *ret )
{
- return ((mtime_t)(p_data[ 0]&0x0e ) << 29)|
+ i_flags = (i_flags << 4) | 0x01; /* check marker bits, and i_flags = b 0010, 0011 or 0001 */
+ if((p_data[0] & 0xF1) != i_flags ||
+ (p_data[2] & 0x01) != 0x01 ||
+ (p_data[4] & 0x01) != 0x01)
+ return false;
+
+
+ *ret = ((mtime_t)(p_data[ 0]&0x0e ) << 29)|
(mtime_t)(p_data[1] << 22)|
((mtime_t)(p_data[2]&0xfe) << 14)|
(mtime_t)(p_data[3] << 7)|
(mtime_t)(p_data[4] >> 1);
+ return true;
}
/* PS SCR timestamp as defined in H222 2.5.3.2 */
@@ -78,20 +86,24 @@ static int ParsePESHeader( vlc_object_t *p_object, const uint8_t *p_header, size
if( p_header[7]&0x80 ) /* has pts */
{
- if( i_header < 9 + 5 )
+ if( i_header < 9 + 5 ||
+ !ExtractPESTimestamp( &p_header[9], p_header[7] >> 6, pi_pts ) )
return VLC_EGENERIC;
- *pi_pts = ExtractPESTimestamp( &p_header[9] );
if( p_header[7]&0x40 ) /* has dts */
{
- if( i_header < 14 + 5 )
+ if( i_header < 14 + 5 ||
+ !ExtractPESTimestamp( &p_header[14], 0x01, pi_dts ) )
return VLC_EGENERIC;
- *pi_dts = ExtractPESTimestamp( &p_header[14] );
}
}
}
else
{
+ /* FIXME?: WTH do we have undocumented MPEG1 packet stuff here ?
+ This code path should not be valid, but seems some ppl did
+ put MPEG1 packets into PS or TS.
+ Non spec reference for packet format on http://andrewduncan.net/mpeg/mpeg-1.html */
i_skip = 6;
if( pb_pes_scambling )
@@ -120,15 +132,15 @@ static int ParsePESHeader( vlc_object_t *p_object, const uint8_t *p_header, size
if( p_header[i_skip]&0x20 )
{
- if( i_header < i_skip + 5 )
+ if( i_header < i_skip + 5 ||
+ !ExtractPESTimestamp( &p_header[i_skip], p_header[i_skip] >> 4, pi_pts ) )
return VLC_EGENERIC;
- *pi_pts = ExtractPESTimestamp( &p_header[i_skip] );
if( p_header[i_skip]&0x10 ) /* has dts */
{
- if( i_header < i_skip + 10 )
+ if( i_header < i_skip + 10 ||
+ !ExtractPESTimestamp( &p_header[i_skip+5], 0x01, pi_dts ) )
return VLC_EGENERIC;
- *pi_dts = ExtractPESTimestamp( &p_header[i_skip+5] );
i_skip += 10;
}
else
diff --git a/modules/demux/mpeg/ps.h b/modules/demux/mpeg/ps.h
index 4b43230..6eee287 100644
--- a/modules/demux/mpeg/ps.h
+++ b/modules/demux/mpeg/ps.h
@@ -372,9 +372,11 @@ static inline int ps_pkt_parse_pack( block_t *p_pkt, int64_t *pi_scr,
*pi_scr = FROM_SCALE_NZ( ExtractPackHeaderTimestamp( &p[4] ) );
*pi_mux_rate = ( p[10] << 14 )|( p[11] << 6 )|( p[12] >> 2);
}
- else if( p_pkt->i_buffer >= 12 && (p[4] >> 4) == 0x02 )
+ else if( p_pkt->i_buffer >= 12 && (p[4] >> 4) == 0x02 ) /* MPEG-1 Pack SCR, same bits as PES/PTS */
{
- *pi_scr = FROM_SCALE_NZ( ExtractPESTimestamp( &p[4] ) );
+ if(!ExtractPESTimestamp( &p[4], 0x02, pi_scr ))
+ return VLC_EGENERIC;
+ *pi_scr = FROM_SCALE_NZ( *pi_scr );
*pi_mux_rate = ( ( p[9]&0x7f )<< 15 )|( p[10] << 7 )|( p[11] >> 1);
}
else
diff --git a/modules/demux/mpeg/ts_hotfixes.c b/modules/demux/mpeg/ts_hotfixes.c
index c485b1b..3cdec5f 100644
--- a/modules/demux/mpeg/ts_hotfixes.c
+++ b/modules/demux/mpeg/ts_hotfixes.c
@@ -87,16 +87,16 @@ void ProbePES( demux_t *p_demux, ts_pid_t *pid, const uint8_t *p_pesstart, size_
if( p_pes[7] & 0x80 ) // PTS
{
i_pesextoffset += 5;
- if ( i_data < i_pesextoffset )
+ if ( i_data < i_pesextoffset ||
+ !ExtractPESTimestamp( &p_pes[9], p_pes[7] >> 6, &i_dts ) )
return;
- i_dts = ExtractPESTimestamp( &p_pes[9] );
}
if( p_pes[7] & 0x40 ) // DTS
{
i_pesextoffset += 5;
- if ( i_data < i_pesextoffset )
+ if ( i_data < i_pesextoffset ||
+ !ExtractPESTimestamp( &p_pes[14], 0x01, &i_dts ) )
return;
- i_dts = ExtractPESTimestamp( &p_pes[14] );
}
if( p_pes[7] & 0x20 ) // ESCR
i_pesextoffset += 6;
More information about the vlc-commits
mailing list