You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

141 lines
4.5 KiB

/*****************************************************************************
* pes.h: PES Packet helpers
*****************************************************************************
* Copyright (C) 2004-2015 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef VLC_MPEG_PES_H
#define VLC_MPEG_PES_H
static inline mtime_t ExtractPESTimestamp( const uint8_t *p_data )
{
return ((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);
}
static inline mtime_t ExtractMPEG1PESTimestamp( const uint8_t *p_data )
{
return ((mtime_t)(p_data[ 0]&0x38 ) << 27)|
((mtime_t)(p_data[0]&0x03 ) << 28)|
(mtime_t)(p_data[1] << 20)|
((mtime_t)(p_data[2]&0xf8 ) << 12)|
((mtime_t)(p_data[2]&0x03 ) << 13)|
(mtime_t)(p_data[3] << 5) |
(mtime_t)(p_data[4] >> 3);
}
inline
static int ParsePESHeader( vlc_object_t *p_object, const uint8_t *p_header, size_t i_header,
unsigned *pi_skip, mtime_t *pi_dts, mtime_t *pi_pts,
uint8_t *pi_stream_id )
{
unsigned i_skip;
if ( i_header < 9 )
return VLC_EGENERIC;
*pi_stream_id = p_header[3];
switch( p_header[3] )
{
case 0xBC: /* Program stream map */
case 0xBE: /* Padding */
case 0xBF: /* Private stream 2 */
case 0xF0: /* ECM */
case 0xF1: /* EMM */
case 0xFF: /* Program stream directory */
case 0xF2: /* DSMCC stream */
case 0xF8: /* ITU-T H.222.1 type E stream */
i_skip = 6;
break;
default:
if( ( p_header[6]&0xC0 ) == 0x80 )
{
/* mpeg2 PES */
i_skip = p_header[8] + 9;
if( p_header[7]&0x80 ) /* has pts */
{
if( i_header < 9 + 5 )
return VLC_EGENERIC;
*pi_pts = ExtractPESTimestamp( &p_header[9] );
if( p_header[7]&0x40 ) /* has dts */
{
if( i_header < 14 + 5 )
return VLC_EGENERIC;
*pi_dts = ExtractPESTimestamp( &p_header[14] );
}
}
}
else
{
i_skip = 6;
if( i_header < i_skip + 1 )
return VLC_EGENERIC;
while( i_skip < 23 && p_header[i_skip] == 0xff )
{
i_skip++;
if( i_header < i_skip + 1 )
return VLC_EGENERIC;
}
if( i_skip == 23 )
{
msg_Err( p_object, "too much MPEG-1 stuffing" );
return VLC_EGENERIC;
}
if( ( p_header[i_skip] & 0xC0 ) == 0x40 )
{
i_skip += 2;
}
if( i_header < i_skip + 1 )
return VLC_EGENERIC;
if( p_header[i_skip]&0x20 )
{
if( i_header < i_skip + 5 )
return VLC_EGENERIC;
*pi_pts = ExtractPESTimestamp( &p_header[i_skip] );
if( p_header[i_skip]&0x10 ) /* has dts */
{
if( i_header < i_skip + 10 )
return VLC_EGENERIC;
*pi_dts = ExtractPESTimestamp( &p_header[i_skip+5] );
i_skip += 10;
}
else
{
i_skip += 5;
}
}
else
{
i_skip += 1;
}
}
break;
}
*pi_skip = i_skip;
return VLC_SUCCESS;
}
#endif