[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