[vlc-devel] [PATCH 13/24] [packetizer/dirac] Fix handling for input-slave.
davidf+nntp at woaf.net
davidf+nntp at woaf.net
Thu Oct 30 12:29:42 CET 2008
From: David Flynn <davidf at rd.bbc.co.uk>
- Note that the packetizer may be used multiple times.
- VLC adds an offset to the PTS/DTS
- If PTS/DTS have been set on way into packetizer, don't overwrite
Rework packetizer to always try and extract a whole encapsulation
unit each time it is called rather than needing an input block
each time
Signed-off-by: David Flynn <davidf at rd.bbc.co.uk>
---
modules/packetizer/dirac.c | 190 +++++++++++++++++++++++--------------------
1 files changed, 102 insertions(+), 88 deletions(-)
diff --git a/modules/packetizer/dirac.c b/modules/packetizer/dirac.c
index c759503..39f0ee8 100644
--- a/modules/packetizer/dirac.c
+++ b/modules/packetizer/dirac.c
@@ -93,6 +93,7 @@ enum {
SYNCED_INCOMPLETEDU,
};
+static block_t *dirac_DoSync( decoder_t *p_dec );
bool dirac_UnpackParseInfo( parse_info_t *p_pi, block_bytestream_t *p_bs, int i_offset );
static void dirac_UnpackSeqHdr( struct seq_hdr_t *p_sh, block_t *p_block );
static block_t *Packetize( decoder_t *p_dec, block_t **pp_block );
@@ -190,103 +191,50 @@ static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
block_BytestreamPush( &p_sys->bytestream, *pp_block );
*pp_block = NULL;
- parse_info_t pu;
-
- static const uint8_t p_parsecode[4] = {'B','B','C','D'};
- do {
- switch( p_sys->i_state )
- {
- case NOT_SYNCED:
- /* shouldn't try sync if there isn't a whole PI avaliable */
- /* or, rather, if we found a sync, ignore it if it is close to the end */
- if( block_FindStartcodeFromOffset( &p_sys->bytestream, &p_sys->i_offset, p_parsecode, 4 ) != VLC_SUCCESS ) {
- return NULL; /* goto cleanup */
- }
- case TRY_SYNC: { /* -> SYNCED | NOT_SYNCED */
- parse_info_t pu1;
- bool a = dirac_UnpackParseInfo(&pu1, &p_sys->bytestream, p_sys->i_offset);
- bool b = dirac_UnpackParseInfo(&pu, &p_sys->bytestream, p_sys->i_offset - pu1.u_prev_offset);
- if( !a || !b || (pu1.u_prev_offset != pu.u_next_offset) ) {
- p_sys->i_state = NOT_SYNCED;
- p_sys->i_offset++;
- break; /* find somewhere else to try again */
- }
- p_sys->u_last_npo = pu.u_next_offset;
- p_sys->i_offset -= pu.u_next_offset;
- p_sys->i_state = SYNCED;
- break;
- }
- case SYNCED: { /* -> SYNCED | NOT_SYNCED */
- bool a = dirac_UnpackParseInfo(&pu, &p_sys->bytestream, p_sys->i_offset);
- if (!a || (p_sys->u_last_npo != pu.u_prev_offset)) {
- p_sys->i_state = NOT_SYNCED;
- break;
- }
- //p_sys->i_offset += pu.u_next_offset;
- p_sys->u_last_npo = pu.u_next_offset;
- p_sys->i_state = SYNCED;
- break;
- }
- case SYNCED_INCOMPLETEDU: /* -> SYNCED */
- dirac_UnpackParseInfo(&pu, &p_sys->bytestream, p_sys->i_offset );
- p_sys->i_state = SYNCED; /* try again */
- }
- } while( NOT_SYNCED == p_sys->i_state );
-
- /* synced, attempt to extract a data unit */
- /* if we can't peek at the last byte, we don't yet have the entire DU */
- if( VLC_SUCCESS != block_PeekOffsetBytes( &p_sys->bytestream, p_sys->i_offset + pu.u_next_offset, NULL, 0) ) {
- p_sys->i_state = SYNCED_INCOMPLETEDU;
- return NULL;
- }
-
- /* flush everything upto the start of the DU */
- block_SkipBytes( &p_sys->bytestream, p_sys->i_offset );
- block_BytestreamFlush( &p_sys->bytestream );
- p_sys->i_offset = 0;
- /* copy the DU and insert into the output chain */
- p_pic = block_New( p_dec, pu.u_next_offset );
- block_GetBytes( &p_sys->bytestream, p_pic->p_buffer, p_pic->i_buffer );
- block_ChainLastAppend( &p_sys->pp_last, p_pic );
+ /* loop until we either finish the encapsulation unit
+ * or dry up the input buffer */
+ while( (p_pic = dirac_DoSync( p_dec )) )
+ {
+ block_ChainLastAppend( &p_sys->pp_last, p_pic );
- if( 0x08 & p_pic->p_buffer[4] ) {
- /* p_pic is a picture -- it ends the 'mux unit' */
- /* this isn't possible if no seq hdr has been found yet */
- uint32_t u_picnum = GetDWBE( p_pic->p_buffer + 13 );
- date_t pts;
- date_Init( &pts, p_sys->m_seq_hdr.u_fps_num, p_sys->m_seq_hdr.u_fps_den );
- //p_pic->i_flags = BLOCK_FLAG_TYPE_I
+ if( 0x08 & p_pic->p_buffer[4] ) {
+ /* p_pic is a picture -- it ends the 'encapsulation unit' */
+ uint32_t u_picnum = GetDWBE( p_pic->p_buffer + 13 );
+ //p_pic->i_flags |= BLOCK_FLAG_TYPE_I
- p_pic = block_ChainGather( p_sys->p_frame );
- p_sys->p_frame = NULL;
- p_sys->pp_last = &p_sys->p_frame;
+ p_pic = block_ChainGather( p_sys->p_frame );
+ p_sys->p_frame = NULL;
+ p_sys->pp_last = &p_sys->p_frame;
- p_pic->i_pts = date_Increment( &pts, u_picnum ) + 1;
- p_pic->i_dts = date_Get( &p_sys->m_dts ) + 1;
- date_Increment( &p_sys->m_dts, 1);
+ if( !p_pic->i_pts || !p_pic->i_dts )
+ {
+ /* this isn't possible if no seq hdr has been found yet */
+ date_t pts;
+ date_Init( &pts, p_sys->m_seq_hdr.u_fps_num, p_sys->m_seq_hdr.u_fps_den );
+ p_pic->i_pts = date_Increment( &pts, u_picnum+3 ) + 1;
+ p_pic->i_pts = 1 + (3+u_picnum) * INT64_C(1000000) / ((float) p_sys->m_seq_hdr.u_fps_num / p_sys->m_seq_hdr.u_fps_den);
+ p_pic->i_dts = date_Get( &p_sys->m_dts ) + 1;
+ }
+ date_Increment( &p_sys->m_dts, 1);
- p_pic->i_pts = 1 + u_picnum * INT64_C(1000000) / ((float) p_sys->m_seq_hdr.u_fps_num / p_sys->m_seq_hdr.u_fps_den);
- }
- else if( 0 == p_pic->p_buffer[4] ) {
- /* we should stash a copy of this -- it isn't allowed to change ever */
- dirac_UnpackSeqHdr(&p_sys->m_seq_hdr, p_pic);
+ return p_pic;
+ }
+ else if( 0 == p_pic->p_buffer[4] ) {
+ /* we should stash a copy of this -- it isn't allowed to change ever */
+ dirac_UnpackSeqHdr(&p_sys->m_seq_hdr, p_pic);
- es_format_t *p_es = &p_dec->fmt_out;
+ es_format_t *p_es = &p_dec->fmt_out;
#if 0
- p_es->video.i_width = p_sys->m_seq_hdr.u_width;
- p_es->video.i_height = p_sys->m_seq_hdr.u_height;
+ p_es->video.i_width = p_sys->m_seq_hdr.u_width;
+ p_es->video.i_height = p_sys->m_seq_hdr.u_height;
#endif
- vlc_ureduce( &p_es->video.i_frame_rate, &p_es->video.i_frame_rate_base
- , p_sys->m_seq_hdr.u_fps_num, p_sys->m_seq_hdr.u_fps_den, 0 );
+ vlc_ureduce( &p_es->video.i_frame_rate, &p_es->video.i_frame_rate_base
+ , p_sys->m_seq_hdr.u_fps_num, p_sys->m_seq_hdr.u_fps_den, 0 );
- date_Change( &p_sys->m_dts, p_sys->m_seq_hdr.u_fps_num, p_sys->m_seq_hdr.u_fps_den );
-
- p_pic = NULL;
- }
- else {
- p_pic = NULL;
+ date_Change( &p_sys->m_dts, p_sys->m_seq_hdr.u_fps_num, p_sys->m_seq_hdr.u_fps_den );
+ }
}
- return p_pic;
+ return NULL;
}
@@ -377,3 +325,69 @@ static void dirac_UnpackSeqHdr( struct seq_hdr_t *p_sh, block_t *p_block )
}
}
}
+
+static block_t *dirac_DoSync( decoder_t *p_dec )
+{
+ decoder_sys_t *p_sys = p_dec->p_sys;
+ parse_info_t pu;
+
+ static const uint8_t p_parsecode[4] = {'B','B','C','D'};
+ do {
+ switch( p_sys->i_state )
+ {
+ case NOT_SYNCED:
+ /* shouldn't try sync if there isn't a whole PI avaliable */
+ /* or, rather, if we found a sync, ignore it if it is close to the end */
+ if( block_FindStartcodeFromOffset( &p_sys->bytestream, &p_sys->i_offset, p_parsecode, 4 ) != VLC_SUCCESS ) {
+ return NULL; /* goto cleanup */
+ }
+ case TRY_SYNC: { /* -> SYNCED | NOT_SYNCED */
+ parse_info_t pu1;
+ bool a = dirac_UnpackParseInfo(&pu1, &p_sys->bytestream, p_sys->i_offset);
+ bool b = dirac_UnpackParseInfo(&pu, &p_sys->bytestream, p_sys->i_offset - pu1.u_prev_offset);
+ if( !a || !b || (pu1.u_prev_offset != pu.u_next_offset) ) {
+ p_sys->i_state = NOT_SYNCED;
+ p_sys->i_offset++;
+ break; /* find somewhere else to try again */
+ }
+ p_sys->u_last_npo = pu.u_next_offset;
+ p_sys->i_offset -= pu.u_next_offset;
+ p_sys->i_state = SYNCED;
+ break;
+ }
+ case SYNCED: { /* -> SYNCED | NOT_SYNCED */
+ bool a = dirac_UnpackParseInfo(&pu, &p_sys->bytestream, p_sys->i_offset);
+ if (!a || (p_sys->u_last_npo != pu.u_prev_offset)) {
+ p_sys->i_state = NOT_SYNCED;
+ break;
+ }
+ //p_sys->i_offset += pu.u_next_offset;
+ p_sys->u_last_npo = pu.u_next_offset;
+ p_sys->i_state = SYNCED;
+ break;
+ }
+ case SYNCED_INCOMPLETEDU: /* -> SYNCED */
+ dirac_UnpackParseInfo(&pu, &p_sys->bytestream, p_sys->i_offset );
+ p_sys->i_state = SYNCED; /* try again */
+ }
+ } while( NOT_SYNCED == p_sys->i_state );
+
+ /* synced, attempt to extract a data unit */
+ /* if we can't peek at the last byte, we don't yet have the entire DU */
+ if( VLC_SUCCESS != block_PeekOffsetBytes( &p_sys->bytestream, p_sys->i_offset + pu.u_next_offset, NULL, 0) ) {
+ p_sys->i_state = SYNCED_INCOMPLETEDU;
+ return NULL;
+ }
+
+ /* flush everything upto the start of the DU */
+ block_SkipBytes( &p_sys->bytestream, p_sys->i_offset );
+ block_BytestreamFlush( &p_sys->bytestream );
+ p_sys->i_offset = 0;
+ /* copy the DU and insert into the output chain */
+ block_t *p_pic = block_New( p_dec, pu.u_next_offset );
+ p_pic->i_pts = p_sys->bytestream.p_block->i_pts;
+ p_pic->i_dts = p_sys->bytestream.p_block->i_dts;
+ block_GetBytes( &p_sys->bytestream, p_pic->p_buffer, p_pic->i_buffer );
+
+ return p_pic;
+}
--
1.5.6.5
More information about the vlc-devel
mailing list