[vlc-devel] [PATCH 03/24] [codec/dirac] Gather Dirac Data Units into Encapsulation units of block_t
davidf+nntp at woaf.net
davidf+nntp at woaf.net
Thu Oct 30 12:29:32 CET 2008
From: David Flynn <davidf at rd.bbc.co.uk>
- Some versions of the dirac-research encoder output in dirac data units,
which must be coallesed into encapsulation units.
- Timestamp the encapsulation units correctly
DTS values are offset and queued up at the input to the encoder
When an encapsulation unit is formed, the first DTS is dequeued
NB, doesn't handle interlaced yet
- Stamp random access points
Signed-off-by: David Flynn <davidf at rd.bbc.co.uk>
---
modules/codec/dirac.c | 64 ++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 55 insertions(+), 9 deletions(-)
diff --git a/modules/codec/dirac.c b/modules/codec/dirac.c
index 2d7bca7..f238279 100644
--- a/modules/codec/dirac.c
+++ b/modules/codec/dirac.c
@@ -320,8 +320,10 @@ struct encoder_sys_t
uint8_t *p_buffer_in;
int i_buffer_in;
uint32_t i_input_picnum;
+ block_fifo_t *p_dts_fifo;
uint8_t p_buffer_out[ENC_BUFSIZE];
+ block_t *p_chain;
struct picture_pts_t pts_tlb[PTS_TLB_SIZE];
mtime_t i_lastdts;
@@ -428,6 +430,8 @@ static int OpenEncoder( vlc_object_t *p_this )
return VLC_ENOMEM;
memset( p_sys, 0, sizeof(encoder_sys_t) );
+ p_sys->p_dts_fifo = block_FifoNew();
+
p_enc->p_sys = p_sys;
p_enc->pf_encode_video = Encode;
p_enc->fmt_out.i_codec = VLC_FOURCC('d','r','a','c');
@@ -615,14 +619,15 @@ static int OpenEncoder( vlc_object_t *p_this )
}
/* Attempt to find dirac picture number in an encapsulation unit */
-static uint32_t ReadDiracPictureNumber( block_t *p_block )
+static int ReadDiracPictureNumber( uint32_t *p_picnum, block_t *p_block )
{
uint32_t u_pos = 4;
/* protect against falling off the edge */
while ( u_pos + 13 < p_block->i_buffer ) {
/* find the picture startcode */
if ( p_block->p_buffer[u_pos] & 0x08 ) {
- return GetDWBE( p_block->p_buffer + u_pos + 9 );
+ *p_picnum = GetDWBE( p_block->p_buffer + u_pos + 9 );
+ return 1;
}
/* skip to the next dirac data unit */
uint32_t u_npo = GetDWBE( p_block->p_buffer + u_pos + 1 );
@@ -630,7 +635,7 @@ static uint32_t ReadDiracPictureNumber( block_t *p_block )
u_npo = 13;
u_pos += u_npo;
}
- return -1;
+ return 0;
}
@@ -642,7 +647,7 @@ static uint32_t ReadDiracPictureNumber( block_t *p_block )
static block_t *Encode( encoder_t *p_enc, picture_t *p_pic )
{
encoder_sys_t *p_sys = p_enc->p_sys;
- block_t *p_block, *p_chain = NULL;
+ block_t *p_block, *p_output_chain = NULL;
int i_plane, i_line, i_width, i_src_stride;
uint8_t *p_dst;
@@ -689,9 +694,18 @@ static block_t *Encode( encoder_t *p_enc, picture_t *p_pic )
return NULL;
}
+ /* store pts in a lookaside buffer, so that the same pts may
+ * be used for the picture in coded order */
StorePicturePTS( p_enc, p_sys->i_input_picnum, p_pic->date );
p_sys->i_input_picnum++;
+ /* store dts in a queue, so that they appear in order in
+ * coded order */
+ p_block = block_New( p_enc, 1 );
+ p_block->i_dts = p_pic->date;
+ block_FifoPut( p_sys->p_dts_fifo, p_block );
+ p_block = NULL;
+
dirac_encoder_state_t state;
/* Retrieve encoded frames from encoder */
do
@@ -701,14 +715,42 @@ static block_t *Encode( encoder_t *p_enc, picture_t *p_pic )
state = dirac_encoder_output( p_sys->p_dirac );
switch( state )
{
- case ENC_STATE_AVAIL:
+ case ENC_STATE_AVAIL: {
+ uint32_t pic_num;
+
+ /* extract data from encoder temporary buffer. */
p_block = block_New( p_enc, p_sys->p_dirac->enc_buf.size );
memcpy( p_block->p_buffer, p_sys->p_dirac->enc_buf.buffer,
p_sys->p_dirac->enc_buf.size );
- /* todo dts */
- p_block->i_pts = GetPicturePTS( p_enc, ReadDiracPictureNumber( p_block ));
- block_ChainAppend( &p_chain, p_block );
+
+ /* if some flags were set for a previous block, prevent
+ * them from getting lost */
+ if( p_sys->p_chain )
+ p_block->i_flags |= p_sys->p_chain->i_flags;
+
+ /* store all extracted blocks in a chain and gather up when an
+ * entire encapsulation unit is avaliable (ends with a picture) */
+ block_ChainAppend( &p_sys->p_chain, p_block );
+
+ /* Presence of a Sequence header indicates a seek point */
+ if( 0 == p_block->p_buffer[4] )
+ p_block->i_flags |= BLOCK_FLAG_TYPE_I;
+
+ if( ReadDiracPictureNumber( &pic_num, p_block ) ) {
+ /* Finding a picture terminates an ecapsulation unit, gather
+ * all data and output; use the next dts value queued up
+ * and find correct pts in the tlb */
+ p_block = block_FifoGet( p_sys->p_dts_fifo );
+ p_sys->p_chain->i_dts = p_block->i_dts;
+ p_sys->p_chain->i_pts = GetPicturePTS( p_enc, pic_num );
+ block_Release( p_block );
+ block_ChainAppend( &p_output_chain, block_ChainGather( p_sys->p_chain ) );
+ p_sys->p_chain = NULL;
+ } else {
+ p_block = NULL;
+ }
break;
+ }
case ENC_STATE_BUFFER:
break;
@@ -718,7 +760,7 @@ static block_t *Encode( encoder_t *p_enc, picture_t *p_pic )
}
} while( state == ENC_STATE_AVAIL );
- return p_chain;
+ return p_output_chain;
}
/*****************************************************************************
@@ -735,5 +777,9 @@ static void CloseEncoder( vlc_object_t *p_this )
if( p_sys->p_buffer_in )
free( p_sys->p_buffer_in );
+
+ block_FifoRelease( p_sys->p_dts_fifo );
+ block_ChainRelease( p_sys->p_chain );
+
free( p_sys );
}
--
1.5.6.5
More information about the vlc-devel
mailing list