[vlc-commits] demux: mp4: more insane rtp cleanup
Francois Cartegnie
git at videolan.org
Sat May 21 17:05:35 CEST 2016
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Sat May 21 17:01:37 2016 +0200| [9687196e4db338f71a4452363cc77807efd7056c] | committer: Francois Cartegnie
demux: mp4: more insane rtp cleanup
clueless crap unchecked everywhere,
even demux returning function error codes
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=9687196e4db338f71a4452363cc77807efd7056c
---
modules/demux/mp4/mp4.c | 118 +++++++++++++++++++++++------------------------
1 file changed, 57 insertions(+), 61 deletions(-)
diff --git a/modules/demux/mp4/mp4.c b/modules/demux/mp4/mp4.c
index 0d9d55f..a7d11f1 100644
--- a/modules/demux/mp4/mp4.c
+++ b/modules/demux/mp4/mp4.c
@@ -134,10 +134,6 @@ static void MP4_GetDefaultSizeAndDuration( demux_t *p_demux,
uint32_t *pi_default_size,
uint32_t *pi_default_duration );
-static int MP4_RTPHintToFrame( demux_t *p_demux,
- block_t **pp_block,
- uint32_t packetcount );
-
static bool AddFragment( demux_t *p_demux, MP4_Box_t *p_moox );
static int ProbeFragments( demux_t *p_demux, bool b_force );
static int ProbeIndex( demux_t *p_demux );
@@ -153,6 +149,10 @@ static asf_track_info_t * MP4ASF_GetTrackInfo( asf_packet_sys_t *p_packetsys, ui
static void MP4ASF_Send(asf_packet_sys_t *p_packetsys, uint8_t i_stream_number, block_t **pp_frame);
static void MP4ASF_ResetFrames( demux_sys_t *p_sys );
+/* RTP Hint track */
+static block_t * MP4_RTPHint_Convert( demux_t *p_demux, block_t *p_block, vlc_fourcc_t i_codec );
+static block_t * MP4_RTPHintToFrame( demux_t *p_demux, block_t *p_block, uint32_t packetcount );
+
/* Helpers */
static uint32_t stream_ReadU32( stream_t *s, void *p_read, uint32_t i_toread )
@@ -424,6 +424,10 @@ static block_t * MP4_Block_Read( demux_t *p_demux, const mp4_track_t *p_track, i
break;
}
}
+ else if( p_track->fmt.i_original_fourcc == ATOM_rrtp )
+ {
+ p_block = MP4_RTPHint_Convert( p_demux, p_block, p_track->fmt.i_codec );
+ }
return p_block;
}
@@ -879,9 +883,8 @@ const unsigned int CONSTRUCTORSIZE = 16;
/*******************************************************************************
* MP4_RTPHintToFrame: converts RTP Reception Hint Track sample to H.264 frame
*******************************************************************************/
-static int MP4_RTPHintToFrame( demux_t *p_demux, block_t **pp_block, uint32_t packetcount )
+static block_t * MP4_RTPHintToFrame( demux_t *p_demux, block_t *p_block, uint32_t packetcount )
{
- block_t* p_block = *pp_block;
uint8_t *p_slice = p_block->p_buffer + SAMPLEHEADERSIZE;
block_t *p_newblock = NULL;
size_t i_payload = 0;
@@ -889,17 +892,15 @@ static int MP4_RTPHintToFrame( demux_t *p_demux, block_t **pp_block, uint32_t pa
if( p_block->i_buffer < SAMPLEHEADERSIZE + RTPPACKETSIZE + CONSTRUCTORSIZE )
{
msg_Err( p_demux, "Sample not large enough for necessary structs");
- return VLC_EGENERIC;
+ block_Release( p_block );
+ return NULL;
}
for( uint32_t i = 0; i < packetcount; ++i )
{
- if( (p_slice - p_block->p_buffer) + RTPPACKETSIZE + CONSTRUCTORSIZE > p_block->i_buffer )
- {
- if( p_newblock )
- block_Release( p_newblock );
- return VLC_EGENERIC;
- }
+ if( (size_t)(p_slice - p_block->p_buffer) + RTPPACKETSIZE + CONSTRUCTORSIZE > p_block->i_buffer )
+ goto error;
+
/* skip RTP header in sample. Could be used to detect packet losses */
p_slice += RTPPACKETSIZE;
@@ -921,27 +922,19 @@ static int MP4_RTPHintToFrame( demux_t *p_demux, block_t **pp_block, uint32_t pa
||sample_cons.samplesperblock != 1||sample_cons.bytesperblock != 1 )
{
msg_Err(p_demux, "Unhandled constructor in RTP Reception Hint Track. Type:%u", sample_cons.type);
- if( p_newblock )
- block_Release( p_newblock );
- return VLC_EGENERIC;
+ goto error;
}
/* slice doesn't fit in buffer */
if( sample_cons.sampleoffset + sample_cons.length > p_block->i_buffer)
{
msg_Err(p_demux, "Sample buffer is smaller than sample" );
- if( p_newblock )
- block_Release( p_newblock );
- return VLC_EGENERIC;
+ goto error;
}
block_t *p_realloc = block_Realloc( p_newblock, 0, i_payload + sample_cons.length + 4 );
if( !p_realloc )
- {
- if( p_newblock )
- block_Release( p_newblock );
- return VLC_ENOMEM;
- }
+ goto error;
p_newblock = p_realloc;
uint8_t *p_dst = &p_newblock->p_buffer[i_payload];
@@ -967,14 +960,49 @@ static int MP4_RTPHintToFrame( demux_t *p_demux, block_t **pp_block, uint32_t pa
i_payload += p_dst - p_newblock->p_buffer;
}
- if( p_newblock == NULL )
- return VLC_EGENERIC;
+ block_Release( p_block );
+ if( p_newblock )
+ p_newblock->i_buffer = i_payload;
+ return p_newblock;
+error:
block_Release( p_block );
- p_newblock->i_buffer = i_payload;
- *pp_block = p_newblock;
+ if( p_newblock )
+ block_Release( p_newblock );
+ return NULL;
+}
- return VLC_SUCCESS;
+/* RTP Reception Hint Track */
+static block_t * MP4_RTPHint_Convert( demux_t *p_demux, block_t *p_block, vlc_fourcc_t i_codec )
+{
+ block_t *p_converted = NULL;
+ if( p_block->i_buffer < 2 )
+ {
+ block_Release( p_block );
+ return NULL;
+ }
+
+ /* number of RTP packets contained in this sample */
+ const uint16_t i_packets = GetWBE( p_block->p_buffer );
+ if( i_packets <= 1 || i_codec != VLC_CODEC_H264 )
+ {
+ const size_t i_skip = SAMPLEHEADERSIZE + i_packets * ( RTPPACKETSIZE + CONSTRUCTORSIZE );
+ if( i_packets == 1 && i_skip < p_block->i_buffer )
+ {
+ p_block->p_buffer += i_skip;
+ p_converted = p_block;
+ }
+ else
+ {
+ block_Release( p_block );
+ }
+ }
+ else
+ {
+ p_converted = MP4_RTPHintToFrame( p_demux, p_block, i_packets );
+ }
+
+ return p_converted;
}
/*****************************************************************************
@@ -1134,39 +1162,7 @@ static int Demux( demux_t *p_demux )
MP4_TrackUnselect( p_demux, tk );
goto end;
}
- /* RTP Reception Hint Track */
- if( tk->fmt.i_original_fourcc == VLC_FOURCC( 'r','r','t','p') )
- {
- for( unsigned int i = 0; i < i_nb_samples; ++i )
- {
- /* number of RTP packets contained in this sample */
- uint16_t packetcount = GetWBE( p_block->p_buffer );
- if( packetcount == 1 )
- {
- int skip = SAMPLEHEADERSIZE + RTPPACKETSIZE + CONSTRUCTORSIZE;
- p_block = block_Realloc( p_block, -skip, p_block->i_buffer);
- }
- if( packetcount > 1 )
- {
- if(tk->fmt.i_codec == VLC_CODEC_H264)
- {
- int status = MP4_RTPHintToFrame( p_demux, &p_block, packetcount );
- if( status != VLC_SUCCESS )
- return status;
- }
- else
- {
- msg_Warn( p_demux, "Unsupported rrtp codec" );
- /* this may work with some codecs, skip all unnecessary stuff leaving payloads */
- int skip = SAMPLEHEADERSIZE + (RTPPACKETSIZE + CONSTRUCTORSIZE) * packetcount;
- p_block = block_Realloc( p_block, -skip, p_block->i_buffer);
- }
- }
- if( !p_block )
- return VLC_ENOMEM;
- }
- }
/* dts */
p_block->i_dts = VLC_TS_0 + MP4_TrackGetDTS( p_demux, tk );
/* pts */
More information about the vlc-commits
mailing list