dirac.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:49k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * dirac.c
  3.  *****************************************************************************
  4.  * Copyright (C) 2008 the VideoLAN team
  5.  * $Id: 75f9ce5796c3c6fc74f12cbc2066dc93b31dcc0b $
  6.  *
  7.  * Authors: David Flynn <davidf@rd.bbc.co.uk>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  22.  *****************************************************************************/
  23. /* Dirac packetizer, formed of three parts:
  24.  *  1) Bitstream synchroniser (dirac_DoSync)
  25.  *      - Given an arbitary sequence of bytes, extract whole Dirac Data Units
  26.  *      - Maps timestamps in supplied block_t's to the extracted Data Unit
  27.  *        A time stamp applies to the next Data Unit to commence at, or after
  28.  *        the first byte of the block_t with the timestamp.
  29.  *  2) Encapsulation Unit generation (dirac_BuildEncapsulationUnit)
  30.  *      - Takes multiple well formed Dirac Data Units and forms them into a
  31.  *        single encapsulation unit, suitable for muxing.
  32.  *      - Sorts out any time stamps so that they only apply to pictures.
  33.  *  3) Timestamp generator (dirac_TimeGenPush)
  34.  *      - Many streams will not be correctly timestamped, ie, DTS&PTS for
  35.  *        every encapsulation unit.  Timestamp generator syncs to avaliable
  36.  *        timestamps and produces DTS&PTS for each encapsulation unit.
  37.  *      - For 'Occasional' missing PTS|DTS:
  38.  *          Missing timestamp is generated using interpolation from last
  39.  *          known good values.
  40.  *      - for All PTS missing:
  41.  *          It is assumed that DTS values are fake, and are actually
  42.  *          in the sequence of the PTS values at the output of a decoder.
  43.  *          Fill in PTS by copying from DTS (accounting for reordering,
  44.  *          by simulating reorder buffer); adjust DTS to provide correct
  45.  *          value.  This is how demuxers like AVI work.
  46.  *      - for All DTS missing:
  47.  *          (Ie, PTS is present), reorder buffer is simulated to determine
  48.  *          PTS for each encapsulation unit.
  49.  *      - NB, doesn't handle all pts missing with real dts. (no way to
  50.  *        distinguish from the fake dts case.)
  51.  *
  52.  *  DIRAC_NON_DATED is used to show a block should not have a time stamp
  53.  *  associated (ie, don't interpolate a counter).  At the ouput, these
  54.  *  blocks get dated with the last used timestamp (or are merged with
  55.  *  another encapsulation unit).
  56.  */
  57. /*****************************************************************************
  58.  * Preamble
  59.  *****************************************************************************/
  60. #ifdef HAVE_CONFIG_H
  61. # include "config.h"
  62. #endif
  63. #include <assert.h>
  64. #include <vlc_common.h>
  65. #include <vlc_plugin.h>
  66. #include <vlc_codec.h>
  67. #include <vlc_block.h>
  68. #include "vlc_bits.h"
  69. #include "vlc_block_helper.h"
  70. #define SANITIZE_PREV_PARSE_OFFSET 1
  71. /*****************************************************************************
  72.  * Module descriptor
  73.  *****************************************************************************/
  74. static int  Open ( vlc_object_t * );
  75. static void Close( vlc_object_t * );
  76. vlc_module_begin()
  77.     set_category( CAT_SOUT )
  78.     set_subcategory( SUBCAT_SOUT_PACKETIZER )
  79.     set_description( N_("Dirac packetizer") )
  80.     set_capability( "packetizer", 50 )
  81.     set_callbacks( Open, Close )
  82. vlc_module_end()
  83. /*****************************************************************************
  84.  * Local prototypes
  85.  *****************************************************************************/
  86. struct decoder_sys_t
  87. {
  88.     /* sync state */
  89.     block_bytestream_t bytestream;
  90.     int i_state;
  91.     size_t i_offset;
  92.     uint32_t u_last_npo;
  93.     /* recovered timestamp from bytesteram for use
  94.      * by synchroniser: should only get reset by the
  95.      * synchronizer upon a discontinuity sentinel */
  96.     mtime_t i_sync_pts;
  97.     mtime_t i_sync_dts;
  98.     /* build encapsulation unit state */
  99.     block_t *p_eu; /*< Current encapsulation unit being built */
  100.     block_t **pp_eu_last;
  101.     uint32_t u_eu_last_npo; /* last next_parse_offset at input to encapsulation */
  102.     mtime_t i_eu_pts;
  103.     mtime_t i_eu_dts;
  104.     /* timestamp generator state */
  105.     date_t dts; /*< timegen decode clock, increments at picture rate */
  106.     bool b_dts; /*< timegen decode clock valid */
  107.     bool b_pts; /*< timegen presentation time valid */
  108.     mtime_t i_pts; /*< timegen presentation time of picture u_pts_picnum */
  109.     uint32_t u_pts_picnum; /*< picture number of timegen presentation time */
  110.     mtime_t i_pts_offset; /*< maximum time between pts and dts */
  111.     /* p_outqueue is the list of encapsulation units that have been
  112.      * fed to the timegenerator.  the timegenerator stamps them in
  113.      * the order it solves the time.  the main packetizer loop removes
  114.      * completed encapsulation units from the front */
  115.     block_t *p_outqueue;
  116.     block_t **pp_outqueue_last;
  117.     /* p_out_dts points to an element in p_outqueue.  It is used for VLC's
  118.      * fake pts hidden in DTS hack, as used by AVI */
  119.     block_t *p_out_dts;
  120.     uint32_t u_tg_last_picnum; /*< most recent picturenumber output from RoB */
  121.     bool b_tg_last_picnum; /*< u_tg_last_picnum valid */
  122.     struct dirac_reorder_buffer {
  123.         int u_size_max;
  124.         int u_size;
  125.         struct dirac_reorder_entry {
  126.             struct dirac_reorder_entry *p_next;
  127.             block_t *p_eu;
  128.             uint32_t u_picnum;
  129.         } p_entries[32], *p_head, *p_empty;
  130.     } reorder_buf; /*< reorder buffer, used by timegenerator */
  131.     /* packetizer state */
  132.     mtime_t i_pts_last_out; /*< last output [from packetizer] pts */
  133.     mtime_t i_dts_last_out; /*< last output [from packetizer] dts */
  134.     struct seq_hdr_t {
  135.         uint32_t u_width;
  136.         uint32_t u_height;
  137.         uint32_t u_fps_num;
  138.         uint32_t u_fps_den;
  139.         enum picture_coding_mode_t {
  140.             DIRAC_FRAME_CODING=0,
  141.             DIRAC_FIELD_CODING=1,
  142.         } u_picture_coding_mode;
  143.     } seq_hdr; /*< sequence header */
  144.     bool b_seen_seq_hdr; /* sequence header valid */
  145.     bool b_seen_eos; /* last data unit to be handled was an EOS */
  146. };
  147. typedef struct {
  148.     uint32_t u_next_offset;
  149.     uint32_t u_prev_offset;
  150.     int i_parse_code;
  151. } parse_info_t;
  152. typedef struct {
  153.     block_free_t pf_blk_release;
  154.     /*> next_parse_offset of the final data unit in associated block_t */
  155.     uint32_t u_last_next_offset;
  156.     /*> picture number is invalid if block has flags DIRAC_NON_DATED */
  157.     uint32_t u_picture_number;
  158. } dirac_block_encap_t;
  159. enum {
  160.     NOT_SYNCED=0,
  161.     TRY_SYNC,
  162.     SYNCED,
  163.     SYNCED_INCOMPLETEDU,
  164. };
  165. enum {
  166.     DIRAC_NON_DATED = (1 << BLOCK_FLAG_PRIVATE_SHIFT),
  167.     DIRAC_DISCARD   = (2 << BLOCK_FLAG_PRIVATE_SHIFT),
  168. };
  169. enum {
  170.     DIRAC_DU_IN_EU,
  171.     DIRAC_DU_ENDS_EU,
  172. };
  173. /***
  174.  * Block encapsulation functions.
  175.  * Things are greately simplified by associating some metadata
  176.  * with a block as it passes through the packetizer (saves having
  177.  * to determine it again)
  178.  *
  179.  * unfortunately p_block doesn't have a p_priv, so some fakage
  180.  * needs to happen:
  181.  *   - Create a dummy block that has some extra storage, set up
  182.  *     members to be identical to the actual block
  183.  *   - Store private data there and pointer to orig block
  184.  *   - modify block pointer to point to fake block
  185.  *
  186.  * NB, the add/new functions must not be used to blocks
  187.  * that are referenced in lists, etc., [in this code, this is ok]
  188.  * NB, don't call add on the same block multiple times (will leak)
  189.  *
  190.  * davidf has a patch that reverts this to use a p_priv in block_t.
  191.  */
  192. typedef struct {
  193.     block_t fake;
  194.     block_t *p_orig;
  195.     void *p_priv;
  196. } fake_block_t;
  197. static dirac_block_encap_t *dirac_RemoveBlockEncap( block_t *p_block )
  198. {
  199.     fake_block_t *p_fake = (fake_block_t *)p_block;
  200.     dirac_block_encap_t *p_dbe = p_fake->p_priv;
  201.     if( !p_dbe ) return NULL;
  202.     p_fake->p_priv = NULL;
  203.     p_dbe->pf_blk_release = NULL;
  204.     return p_dbe;
  205. }
  206. static void dirac_ReleaseBlockAndEncap( block_t *p_block )
  207. {
  208.     fake_block_t *p_fake = (fake_block_t *)p_block;
  209.     free( dirac_RemoveBlockEncap( p_block ) );
  210.     p_fake->p_orig->pf_release( p_fake->p_orig );
  211.     free( p_fake );
  212. }
  213. static void dirac_AddBlockEncap( block_t **pp_block, dirac_block_encap_t *p_dbe )
  214. {
  215.     fake_block_t *p_fake = calloc( 1, sizeof( *p_fake ) );
  216.     assert( p_fake ); /* must not fail, fixby: adding a p_priv to block_t */
  217.     p_fake->p_orig = *pp_block;
  218.     memcpy( &p_fake->fake, *pp_block, sizeof( block_t ) );
  219.     *pp_block = &p_fake->fake;
  220.     p_fake->p_priv = p_dbe;
  221.     p_dbe->pf_blk_release = p_fake->p_orig->pf_release;
  222.     p_fake->fake.pf_release = dirac_ReleaseBlockAndEncap;
  223. }
  224. static dirac_block_encap_t *dirac_NewBlockEncap( block_t **pp_block )
  225. {
  226.     dirac_block_encap_t *p_dbe = calloc( 1, sizeof( *p_dbe ) );
  227.     if( p_dbe ) dirac_AddBlockEncap( pp_block, p_dbe );
  228.     return p_dbe;
  229. }
  230. static dirac_block_encap_t *dirac_GetBlockEncap( block_t *p_block )
  231. {
  232.     return (dirac_block_encap_t*) ((fake_block_t *)p_block)->p_priv;
  233. }
  234. /***
  235.  * General utility funcions
  236.  */
  237. /**
  238.  * given a chain of block_t, allocate and return an array containing
  239.  * pointers to all the blocks. (Acts as a replacement for the old p_prev
  240.  * member of block_t) */
  241. static int block_ChainToArray( block_t *p_block, block_t ***ppp_array)
  242. {
  243.     if( !ppp_array )
  244.         return 0;
  245.     int i_num_blocks;
  246.     block_ChainProperties( p_block, &i_num_blocks, NULL, NULL );
  247.     *ppp_array = calloc( i_num_blocks, sizeof( block_t* ) );
  248.     if( !ppp_array ) return 0;
  249.     for( int i = 0; i < i_num_blocks; i++ )
  250.     {
  251.         (*ppp_array)[i] = p_block;
  252.         p_block = p_block->p_next;
  253.     }
  254.     return i_num_blocks;
  255. }
  256. /**
  257.  * Destructively find and recover the earliest timestamp from start of
  258.  * bytestream, upto i_length.
  259.  */
  260. static void dirac_RecoverTimestamps ( decoder_t *p_dec, size_t i_length )
  261. {
  262.     decoder_sys_t *p_sys = p_dec->p_sys;
  263.     block_t *p_block = p_sys->bytestream.p_block;
  264.     /* Find the block with first non-flushed data */
  265.     size_t i_offset = p_sys->bytestream.i_offset;
  266.     for(; p_block != NULL; p_block = p_block->p_next )
  267.     {
  268.         if( i_offset < p_block->i_buffer )
  269.             break;
  270.         i_offset -= p_block->i_buffer;
  271.     }
  272.     i_offset += i_length;
  273.     for(; p_block != NULL; p_block = p_block->p_next )
  274.     {
  275.         if( p_sys->i_sync_pts <= VLC_TS_INVALID && p_sys->i_sync_dts <= VLC_TS_INVALID )
  276.         {
  277.             /* oldest timestamp wins */
  278.             p_sys->i_sync_pts = p_block->i_pts;
  279.             p_sys->i_sync_dts = p_block->i_dts;
  280.         }
  281.         /* clear timestamps -- more than one data unit can come from a block */
  282.         p_block->i_flags = 0;
  283.         p_block->i_pts = p_block->i_dts = VLC_TS_INVALID;
  284.         if( i_offset < p_block->i_buffer )
  285.             break;
  286.         i_offset -= p_block->i_buffer;
  287.     }
  288. }
  289. /* backdate the list [p_block .. p_block->p_next where p_next == p_last] */
  290. static void dirac_BackdateDTS( block_t *p_block, block_t *p_last, date_t *p_dts )
  291. {
  292.     /* Transverse p_last backwards.  (no p_prev anymore) */
  293.     block_t **pp_array = NULL;
  294.     int n = block_ChainToArray( p_block, &pp_array );
  295.     while( n ) if( pp_array[--n] == p_last ) break;
  296.     /* want to start at p_last->p_prev */
  297.     while( n-- )
  298.     {
  299.         if( pp_array[n]->i_flags & DIRAC_NON_DATED )
  300.             continue;
  301.         if( pp_array[n]->i_dts <= VLC_TS_INVALID )
  302.             pp_array[n]->i_dts = date_Decrement( p_dts, 1 );
  303.     }
  304.     free( pp_array );
  305. }
  306. /* backdate the list [p_block .. p_block->p_next where p_next == p_last] */
  307. static void dirac_BackdatePTS( block_t *p_block, block_t *p_last, date_t *p_pts, uint32_t u_pts_picnum )
  308. {
  309.     /* Transverse p_last backwards.  (no p_prev anymore) */
  310.     block_t **pp_array = NULL;
  311.     int n = block_ChainToArray( p_block, &pp_array );
  312.     while( n ) if( pp_array[--n] == p_last ) break;
  313.     /* want to start at p_last->p_prev */
  314.     while( n-- )
  315.     {
  316.         if( pp_array[n]->i_flags & DIRAC_NON_DATED )
  317.             continue;
  318.         if( pp_array[n]->i_dts > VLC_TS_INVALID )
  319.             continue;
  320.         dirac_block_encap_t *dbe = dirac_GetBlockEncap( pp_array[n] );
  321.         int32_t u_pic_num = dbe ? dbe->u_picture_number : 0;
  322.         int32_t i_dist = u_pic_num - u_pts_picnum;
  323.         date_t pts = *p_pts;
  324.         if( i_dist >= 0 )
  325.             pp_array[n]->i_pts = date_Increment( &pts, i_dist );
  326.         else
  327.             pp_array[n]->i_pts = date_Decrement( &pts, -i_dist );
  328.     }
  329.     free( pp_array );
  330. }
  331. /***
  332.  * Dirac spec defined relations
  333.  */
  334. static bool dirac_isEOS( uint8_t u_parse_code ) { return 0x10 == u_parse_code; }
  335. static bool dirac_isSeqHdr( uint8_t u_parse_code ) { return 0 == u_parse_code; }
  336. static bool dirac_isPicture( uint8_t u_parse_code ) { return 0x08 & u_parse_code; }
  337. static int dirac_numRefs( uint8_t u_parse_code ) { return 0x3 & u_parse_code; }
  338. static inline bool dirac_PictureNbeforeM( uint32_t u_n, uint32_t u_m )
  339. {
  340.     /* specified as: u_n occurs before u_m if:
  341.      *   (u_m - u_n) mod (1<<32) < D */
  342.     return (uint32_t)(u_m - u_n) < (1u<<31);
  343. }
  344. /***
  345.  * Reorder buffer model
  346.  */
  347. static void dirac_ReorderInit( struct dirac_reorder_buffer *p_rb )
  348. {
  349.     memset( p_rb, 0, sizeof(*p_rb) );
  350.     p_rb->u_size_max = 2;
  351.     p_rb->p_empty = p_rb->p_entries;
  352.     p_rb->p_entries[31].p_next = NULL;
  353.     for( int i = 0; i < 31; i++ )
  354.         p_rb->p_entries[i].p_next = &p_rb->p_entries[i+1];
  355. }
  356. /* simulate the dirac picture reorder buffer */
  357. static block_t *dirac_Reorder( decoder_t *p_dec, block_t *p_block_in, uint32_t u_picnum )
  358. {
  359.     decoder_sys_t *p_sys = p_dec->p_sys;
  360.     if( !p_sys->reorder_buf.u_size_max )
  361.         /* reorder buffer disabled */
  362.         return p_block_in;
  363.     /* Modeling the reorder buffer:
  364.      * 1. If the reorder buffer is not full, insert picture for reordering.
  365.      *    No picture is output by the system this picture period
  366.      * 2. If the reorder buffer is full:
  367.      *    a. The picture decoded this period (u_picnum) bypasses the reorder
  368.      *       buffer if it has a lower picture number than any entry in the
  369.      *       reorder buffer. This picture is output by the system.
  370.      *    b. Otherwise, the lowest picture number in the reorder buffer is
  371.      *       removed from the buffer and output by the system.  The current
  372.      *       decoded picture (u_picnum) is inserted into the reorder buffer
  373.      */
  374.     block_t *p_block = NULL;
  375.     /* Determine if the picture needs to be inserted */
  376.     if( p_sys->reorder_buf.u_size == p_sys->reorder_buf.u_size_max )
  377.     {
  378.         /* (2) reorder buffer is full */
  379.         if( !p_sys->reorder_buf.u_size_max ||
  380.             dirac_PictureNbeforeM( u_picnum, p_sys->reorder_buf.p_head->u_picnum ) )
  381.         {
  382.             /* (2a) current picture is first in order */
  383.             return p_block_in;
  384.         }
  385.         /* (2b) extract the youngest picture in the buffer */
  386.         p_block = p_sys->reorder_buf.p_head->p_eu;
  387.         struct dirac_reorder_entry *p_tmp = p_sys->reorder_buf.p_head;
  388.         p_sys->reorder_buf.p_head = p_tmp->p_next;
  389.         p_tmp->p_next = p_sys->reorder_buf.p_empty;
  390.         p_sys->reorder_buf.p_empty = p_tmp;
  391.         p_sys->reorder_buf.u_size--;
  392.     }
  393.     /* (1) and (2b) both require u_picnum to be inserted */
  394.     struct dirac_reorder_entry *p_current = p_sys->reorder_buf.p_empty;
  395.     p_sys->reorder_buf.p_empty = p_current->p_next;
  396.     p_sys->reorder_buf.u_size++;
  397.     /* insertion sort to keep p_head always sorted, earliest first */
  398.     struct dirac_reorder_entry **pp_at = &p_sys->reorder_buf.p_head;
  399.     for( ; *pp_at; pp_at = &(*pp_at)->p_next )
  400.         if( dirac_PictureNbeforeM( u_picnum, (*pp_at)->u_picnum ) )
  401.             break;
  402.     p_current->u_picnum = u_picnum;
  403.     p_current->p_eu = p_block_in;
  404.     p_current->p_next = *pp_at;
  405.     *pp_at = p_current;
  406.     return p_block;
  407. }
  408. /***
  409.  * bytestream parsing and unmarshalling functions
  410.  */
  411. static bool dirac_UnpackParseInfo( parse_info_t *p_pi, block_bytestream_t *p_bs,
  412.                                    size_t u_offset )
  413. {
  414.     uint8_t p_d[13];
  415.     if( VLC_SUCCESS != block_PeekOffsetBytes( p_bs, u_offset, p_d, 13 ) )
  416.         return false;
  417.     if( p_d[0] != 'B' || p_d[1] != 'B' || p_d[2] != 'C' || p_d[3] != 'D' )
  418.         return false;
  419.     p_pi->i_parse_code = p_d[4];
  420.     p_pi->u_next_offset = p_d[5] << 24 | p_d[6] << 16 | p_d[7] << 8 | p_d[8];
  421.     p_pi->u_prev_offset = p_d[9] << 24 | p_d[10] << 16 | p_d[11] << 8 | p_d[12];
  422.     return true;
  423. }
  424. static uint32_t dirac_uint( bs_t *p_bs )
  425. {
  426.     uint32_t u_count = 0, u_value = 0;
  427.     while( !bs_eof( p_bs ) && !bs_read( p_bs, 1 ) )
  428.     {
  429.         u_count++;
  430.         u_value <<= 1;
  431.         u_value |= bs_read( p_bs, 1 );
  432.     }
  433.     return (1 << u_count) - 1 + u_value;
  434. }
  435. static int dirac_bool( bs_t *p_bs )
  436. {
  437.     return bs_read( p_bs, 1 );
  438. }
  439. /* read in useful bits from sequence header */
  440. static bool dirac_UnpackSeqHdr( struct seq_hdr_t *p_sh, block_t *p_block )
  441. {
  442.     bs_t bs;
  443.     bs_init( &bs, p_block->p_buffer, p_block->i_buffer );
  444.     bs_skip( &bs, 13*8 ); /* parse_info_header */
  445.     dirac_uint( &bs ); /* major_version */
  446.     dirac_uint( &bs ); /* minor_version */
  447.     dirac_uint( &bs ); /* profile */
  448.     dirac_uint( &bs ); /* level */
  449.     uint32_t u_video_format = dirac_uint( &bs ); /* index */
  450.     if( u_video_format > 20 )
  451.     {
  452.         /* dont know how to parse this header */
  453.         return false;
  454.     }
  455.     static const struct {
  456.         uint32_t u_w, u_h;
  457.     } dirac_size_tbl[] = {
  458.         {640,480}, {176,120}, {176,144}, {352,240}, {352,288}, {704,480},
  459.         {704,576}, {720,480}, {720,576}, {1280,720}, {1280,720}, {1920,1080},
  460.         {1920,1080}, {1920,1080}, {1920,1080}, {2048,1080}, {4096,2160},
  461.         {3840,2160}, {3840,2160}, {7680,4320}, {7680,4320},
  462.     };
  463.     p_sh->u_width = dirac_size_tbl[u_video_format].u_w;
  464.     p_sh->u_height = dirac_size_tbl[u_video_format].u_h;
  465.     if( dirac_bool( &bs ) )
  466.     {
  467.         p_sh->u_width = dirac_uint( &bs ); /* frame_width */
  468.         p_sh->u_height = dirac_uint( &bs ); /* frame_height */
  469.     }
  470.     if( dirac_bool( &bs ) )
  471.     {
  472.         dirac_uint( &bs ); /* chroma_format */
  473.     }
  474.     if( dirac_bool( &bs ) )
  475.     {
  476.         dirac_uint( &bs ); /* scan_format */
  477.     }
  478.     static const struct {
  479.         uint32_t u_n /* numerator */, u_d /* denominator */;
  480.     } dirac_frate_tbl[] = { /* table 10.3 */
  481.         {1, 1}, /* this value is not used */
  482.         {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
  483.         {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
  484.     };
  485.     const unsigned dirac_frate_tbl_size =
  486.         sizeof( dirac_frate_tbl ) / sizeof( *dirac_frate_tbl );
  487.     static const uint32_t dirac_vidfmt_frate[] = { /* table C.1 */
  488.         1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
  489.     };
  490.     p_sh->u_fps_num = dirac_frate_tbl[dirac_vidfmt_frate[u_video_format]].u_n;
  491.     p_sh->u_fps_den = dirac_frate_tbl[dirac_vidfmt_frate[u_video_format]].u_d;
  492.     if( dirac_bool( &bs ) )
  493.     {
  494.         uint32_t frame_rate_index = dirac_uint( &bs );
  495.         p_sh->u_fps_num = dirac_frate_tbl[frame_rate_index].u_n;
  496.         p_sh->u_fps_den = dirac_frate_tbl[frame_rate_index].u_d;
  497.         if( frame_rate_index >= dirac_frate_tbl_size )
  498.         {
  499.             /* invalid header */
  500.             return false;
  501.         }
  502.         if( frame_rate_index == 0 )
  503.         {
  504.             p_sh->u_fps_num = dirac_uint( &bs ); /* frame_rate_numerator */
  505.             p_sh->u_fps_den = dirac_uint( &bs ); /* frame_rate_denominator */
  506.         }
  507.     }
  508.     /* must have a valid framerate */
  509.     if( !p_sh->u_fps_num || !p_sh->u_fps_den )
  510.         return false;
  511.     if( dirac_bool( &bs ) )
  512.     {
  513.         uint32_t par_index = dirac_uint( &bs );
  514.         if( !par_index )
  515.         {
  516.             dirac_uint( &bs ); /* par_num */
  517.             dirac_uint( &bs ); /* par_den */
  518.         }
  519.     }
  520.     if( dirac_bool( &bs ) )
  521.     {
  522.         dirac_uint( &bs ); /* clean_width */
  523.         dirac_uint( &bs ); /* clean_height */
  524.         dirac_uint( &bs ); /* clean_left_offset */
  525.         dirac_uint( &bs ); /* clean_top_offset */
  526.     }
  527.     if( dirac_bool( &bs ) )
  528.     {
  529.         uint32_t signal_range_index = dirac_uint( &bs );
  530.         if( !signal_range_index )
  531.         {
  532.             dirac_uint( &bs ); /* luma_offset */
  533.             dirac_uint( &bs ); /* luma_excursion */
  534.             dirac_uint( &bs ); /* chroma_offset */
  535.             dirac_uint( &bs ); /* chroma_excursion */
  536.         }
  537.     }
  538.     if( dirac_bool( &bs ) )
  539.     {
  540.         uint32_t colour_spec_index = dirac_uint( &bs );
  541.         if( !colour_spec_index )
  542.         {
  543.             if( dirac_bool( &bs ) )
  544.             {
  545.                 dirac_uint( &bs ); /* colour_primaries_index */
  546.             }
  547.             if( dirac_bool( &bs ) )
  548.             {
  549.                 dirac_uint( &bs ); /* colour_matrix_index */
  550.             }
  551.             if( dirac_bool( &bs ) )
  552.             {
  553.                 dirac_uint( &bs ); /* transfer_function_index */
  554.             }
  555.         }
  556.     }
  557.     p_sh->u_picture_coding_mode = dirac_uint( &bs );
  558.     return true;
  559. }
  560. /***
  561.  * Data Unit marshalling functions
  562.  */
  563. static block_t *dirac_EmitEOS( decoder_t *p_dec, uint32_t i_prev_parse_offset )
  564. {
  565.     const uint8_t p_eos[] = { 'B','B','C','D',0x10,0,0,0,13,0,0,0,0 };
  566.     block_t *p_block = block_New( p_dec, 13 );
  567.     if( !p_block )
  568.         return NULL;
  569.     memcpy( p_block->p_buffer, p_eos, 13 );
  570.     SetDWBE( p_block->p_buffer + 9, i_prev_parse_offset );
  571.     p_block->i_flags = DIRAC_NON_DATED;
  572.     return p_block;
  573.     (void) p_dec;
  574. }
  575. /***
  576.  * Bytestream synchronizer
  577.  * maps [Bytes] -> DataUnit
  578.  */
  579. static block_t *dirac_DoSync( decoder_t *p_dec )
  580. {
  581.     decoder_sys_t *p_sys = p_dec->p_sys;
  582.     parse_info_t pu;
  583.     static const uint8_t p_parsecode[4] = {'B','B','C','D'};
  584.     do {
  585.         switch( p_sys->i_state )
  586.         {
  587.         case NOT_SYNCED:
  588.         {
  589.             if( VLC_SUCCESS !=
  590.                 block_FindStartcodeFromOffset( &p_sys->bytestream, &p_sys->i_offset, p_parsecode, 4 ) )
  591.             {
  592.                 /* p_sys->i_offset will have been set to:
  593.                  *   end of bytestream - amount of prefix found
  594.                  * can resume search from this point when more data arrives */
  595.                 return NULL;
  596.             }
  597.             /* candidate parse_code_prefix has been found at p_sys->i_offset */
  598.             if( VLC_SUCCESS != block_PeekOffsetBytes( &p_sys->bytestream, p_sys->i_offset + 12, NULL, 0 ) )
  599.             {
  600.                 /* insufficient data has been accumulated to fully extract
  601.                  * a parse_info header. exit for now in the hope of more
  602.                  * data later to retry at exactly the same point */
  603.                 return NULL;
  604.             }
  605.             p_sys->i_state = TRY_SYNC;
  606.             break; /* candidate found, try to sync */
  607.         }
  608.         case SYNCED: /* -> TRY_SYNC | NOT_SYNCED */
  609.             /* sanity: can only reach this after having extracted a DU,
  610.              * which causes data to be consumed and local i_offset to be reset */
  611.             assert( p_sys->i_offset == 0 );
  612.             if( VLC_SUCCESS != block_PeekOffsetBytes( &p_sys->bytestream, 12, NULL, 0 ) )
  613.             {
  614.                 /* insufficient data has been accumulated to fully extract
  615.                  * a parse_info header, retry later */
  616.                 return NULL;
  617.             }
  618.             if( !dirac_UnpackParseInfo( &pu, &p_sys->bytestream, 0 )
  619.              || !pu.u_next_offset || (p_sys->u_last_npo != pu.u_prev_offset) )
  620.             {
  621.                 /* !a: not a valid parse info.
  622.                  * !pu.u_next_offset: don't know the length of the data unit
  623.                  *                    search for the next one that points back
  624.                  *                    to this one to determine length.
  625.                  * (p_sys->u_last_npo != pu.u_prev_offset): some desync
  626.                  */
  627.                 p_sys->i_state = NOT_SYNCED;
  628.                 break;
  629.             }
  630.             if( pu.u_next_offset > 1024*1024 )
  631.             {
  632.                 /* sanity check for erronious hugs next_parse_offsets
  633.                  * (eg, 2^32-1) that would cause a very long wait
  634.                  * and large space consumption: fall back to try sync */
  635.                 p_sys->i_state = TRY_SYNC;
  636.                 break;
  637.             }
  638.             /* check that the start of the next data unit is avaliable */
  639.             if( VLC_SUCCESS !=
  640.                 block_PeekOffsetBytes( &p_sys->bytestream, pu.u_next_offset + 12, NULL, 0 ) )
  641.             {
  642.                 return NULL; /* retry later */
  643.             }
  644.             /* attempt to syncronise backwards from pu.u_next_offset */
  645.             p_sys->i_offset = pu.u_next_offset;
  646.             /* fall through */
  647.         case TRY_SYNC: /* -> SYNCED | NOT_SYNCED */
  648.         {
  649.             if( !p_sys->i_offset )
  650.                 goto sync_fail; /* if a is at start of bytestream, b can't be in buffer */
  651.             parse_info_t pu_a;
  652.             bool a = dirac_UnpackParseInfo( &pu_a, &p_sys->bytestream, p_sys->i_offset );
  653.             if( !a || (pu_a.u_prev_offset > p_sys->i_offset) )
  654.                 goto sync_fail; /* b lies beyond start of bytestream: can't sync */
  655.             if( !pu_a.u_prev_offset )
  656.             {
  657.                 if( p_sys->i_state == TRY_SYNC )
  658.                 {
  659.                     goto sync_fail; /* can't find different pu_b from pu_a */
  660.                 }
  661.                 /* state == SYNCED: already know where pu_b is.
  662.                  * pu_a has probably been inserted by something that doesn't
  663.                  * know what the last next_parse_offset was */
  664.                 pu_a.u_prev_offset = pu.u_next_offset;
  665.             }
  666.             parse_info_t *pu_b = &pu;
  667.             bool b = dirac_UnpackParseInfo( pu_b, &p_sys->bytestream, p_sys->i_offset - pu_a.u_prev_offset );
  668.             if( !b || (pu_b->u_next_offset && pu_a.u_prev_offset != pu_b->u_next_offset) )
  669.             {
  670.                 /* if pu_b->u_next_offset = 0, have to assume we've synced, ie,
  671.                  * just rely on finding a valid pu_b from pu_a. */
  672.                 goto sync_fail;
  673.             }
  674.             p_sys->u_last_npo = pu_b->u_next_offset;
  675.             if( !pu_b->u_next_offset ) pu_b->u_next_offset = pu_a.u_prev_offset;
  676.             /* offset was pointing at pu_a, rewind to point at pu_b */
  677.             p_sys->i_offset -= pu_a.u_prev_offset;
  678.             p_sys->i_state = SYNCED;
  679.             break;
  680.         }
  681. sync_fail:
  682.             if( p_sys->i_state == SYNCED ) p_sys->i_offset = 0;
  683.             p_sys->i_offset++;
  684.             p_sys->i_state = NOT_SYNCED;
  685.             break; /* find somewhere else to try again */
  686.         default:;
  687.         }
  688.     } while( SYNCED != p_sys->i_state );
  689.     /*
  690.      * synced, attempt to extract a data unit
  691.      */
  692.     /* recover any timestamps from the data that is about to be flushed */
  693.     dirac_RecoverTimestamps( p_dec, p_sys->i_offset );
  694.     /* flush everything upto the start of the DU */
  695.     block_SkipBytes( &p_sys->bytestream, p_sys->i_offset );
  696.     block_BytestreamFlush( &p_sys->bytestream );
  697.     p_sys->i_offset = 0;
  698.     /* setup the data unit buffer */
  699.     block_t *p_block = block_New( p_dec, pu.u_next_offset );
  700.     if( !p_block )
  701.         return NULL;
  702.     p_block->i_pts = p_sys->i_sync_pts;
  703.     p_block->i_dts = p_sys->i_sync_dts;
  704.     p_sys->i_sync_pts = p_sys->i_sync_dts = VLC_TS_INVALID;
  705.     /* recover any new timestamps from the data that is about to be consumed */
  706.     dirac_RecoverTimestamps( p_dec, p_sys->i_offset );
  707.     block_GetBytes( &p_sys->bytestream, p_block->p_buffer, p_block->i_buffer );
  708.     /* save parse offset in private area for later use */
  709.     dirac_block_encap_t *p_dbe = dirac_NewBlockEncap( &p_block );
  710.     if( p_dbe ) p_dbe->u_last_next_offset = pu.u_next_offset;
  711.     return p_block;
  712. }
  713. /***
  714.  * Packet (Data Unit) inspection, learns parameters from sequence
  715.  * headers, sets up flags, drops unwanted data units, sets
  716.  * encapsulation unit termination policy
  717.  */
  718. static int dirac_InspectDataUnit( decoder_t *p_dec, block_t **pp_block, block_t *p_eu )
  719. {
  720.     decoder_sys_t *p_sys = p_dec->p_sys;
  721.     block_t *p_block = *pp_block;
  722.     uint8_t u_parse_code = p_block->p_buffer[4];
  723.     if( dirac_isEOS( u_parse_code ) )
  724.     {
  725.         if( p_sys->b_seen_eos )
  726.         {
  727.             /* remove duplicate EOS packets */
  728.             block_Release( p_block );
  729.             *pp_block = NULL;
  730.             return DIRAC_DU_IN_EU;
  731.         }
  732.         /* p_block is an EOS packet */
  733.         p_eu->i_flags |= BLOCK_FLAG_END_OF_SEQUENCE;
  734.         /* for the moment, let this end an encapsulation unit */
  735.         /* seeing an eos packet requires a flush of the packetizer
  736.          * this is detected by the caller of this function */
  737.         p_sys->b_seen_seq_hdr = false;
  738.         p_sys->b_seen_eos = true;
  739.         return DIRAC_DU_ENDS_EU;
  740. #if 0
  741.         /* let anything down streem know too */
  742.         /*
  743.         Actually, this is a bad idea:
  744.          - It sets the discontinuity for every dirac EOS packet
  745.            which doesnt imply a time discontinuity.
  746.          - When the syncronizer detects a real discontinuity, it
  747.            should copy the flags through.
  748.         p_eu->i_flags |= BLOCK_FLAG_DISCONTINUITY;
  749.         */
  750. #endif
  751.     }
  752.     p_sys->b_seen_eos = false;
  753.     if( dirac_isPicture( u_parse_code ) )
  754.     {
  755.         /* timestamps apply to pictures only */
  756.         p_eu->i_dts = p_sys->i_eu_dts;
  757.         p_eu->i_pts = p_sys->i_eu_pts;
  758.         p_sys->i_eu_dts = p_sys->i_eu_pts = VLC_TS_INVALID;
  759.         if( !p_sys->b_seen_seq_hdr )
  760.         {
  761.             /* can't timestamp in this case, discard later
  762.              * so that the timestamps aren't lost */
  763.             p_eu->i_flags |= DIRAC_DISCARD;
  764.         }
  765.         /* p_block is a picture -- it ends the 'encapsulation unit' */
  766.         if( dirac_numRefs( u_parse_code ) )
  767.         {
  768.             /* if this picture is not an I frame, ensure that the
  769.              * random access point flags are not set */
  770.             p_eu->i_flags &= ~BLOCK_FLAG_TYPE_I;
  771.         }
  772.         dirac_block_encap_t *p_dbe = dirac_GetBlockEncap( p_block );
  773.         if( p_dbe && p_block->i_buffer > 13+4 )
  774.         {
  775.             /* record the picture number to save the time gen functions
  776.              * from having to inspect the data for it */
  777.             p_dbe->u_picture_number = GetDWBE( p_block->p_buffer + 13 );
  778.         }
  779.         return DIRAC_DU_ENDS_EU;
  780.     }
  781.     if( dirac_isSeqHdr( u_parse_code ) )
  782.     {
  783.         if( !dirac_UnpackSeqHdr( &p_sys->seq_hdr, p_block ) )
  784.         {
  785.             /* couldn't parse the sequence header, just ignore it */
  786.             return DIRAC_DU_IN_EU;
  787.         }
  788.         p_sys->b_seen_seq_hdr = true;
  789.        /* a sequence header followed by an I frame is a random
  790.         * access point; assume that this is the case */
  791.         p_eu->i_flags |= BLOCK_FLAG_TYPE_I;
  792.         es_format_t *p_es = &p_dec->fmt_out;
  793.         p_es->video.i_width  = p_sys->seq_hdr.u_width;
  794.         p_es->video.i_height = p_sys->seq_hdr.u_height;
  795.         vlc_ureduce( &p_es->video.i_frame_rate, &p_es->video.i_frame_rate_base
  796.                    , p_sys->seq_hdr.u_fps_num, p_sys->seq_hdr.u_fps_den, 0 );
  797.         /* when field coding, dts needs to be incremented in terms of field periods */
  798.         unsigned u_pics_per_sec = p_sys->seq_hdr.u_fps_num;
  799.         if( p_sys->seq_hdr.u_picture_coding_mode == DIRAC_FIELD_CODING )
  800.         {
  801.             u_pics_per_sec *= 2;
  802.         }
  803.         date_Change( &p_sys->dts, u_pics_per_sec, p_sys->seq_hdr.u_fps_den );
  804.         /* TODO: set p_sys->reorder_buf.u_size_max */
  805.         p_sys->i_pts_offset = p_sys->reorder_buf.u_size_max
  806.                             * 1000000
  807.                             * p_es->video.i_frame_rate_base / p_es->video.i_frame_rate + 1;
  808.         /* stash a copy of the seqhdr
  809.          *  - required for ogg muxing
  810.          *  - useful for error checking
  811.          *  - it isn't allowed to change until an eos */
  812.         if( p_es->p_extra )
  813.             free( p_es->p_extra );
  814.         p_es->p_extra = calloc( 1, p_block->i_buffer + 13 );
  815.         if( !p_es->p_extra )
  816.         {
  817.             p_es->i_extra = 0;
  818.             return DIRAC_DU_IN_EU;
  819.         }
  820.         p_es->i_extra = p_block->i_buffer;
  821.         memcpy( p_es->p_extra, p_block->p_buffer, p_block->i_buffer );
  822.         /* append EOS as per Ogg guidelines */
  823.         p_block = dirac_EmitEOS( p_dec, p_block->i_buffer );
  824.         if( p_block )
  825.         {
  826.             memcpy( (uint8_t*)p_es->p_extra + p_es->i_extra, p_block->p_buffer, 13 );
  827.             p_es->i_extra += 13;
  828.         }
  829.         return DIRAC_DU_IN_EU;
  830.     }
  831.     /* doesn't end an encapsulation unit */
  832.     return DIRAC_DU_IN_EU;
  833. }
  834. /***
  835.  * Encapsulation (packetization) suitable for all muxing standards
  836.  * maps [DataUnit] -> EncapsulationUnit
  837.  */
  838. static block_t *dirac_BuildEncapsulationUnit( decoder_t *p_dec, block_t *p_block )
  839. {
  840.     decoder_sys_t *p_sys = p_dec->p_sys;
  841.     assert(p_block->i_buffer >= 13 && 0x42424344 == GetDWBE( p_block->p_buffer ));
  842.     if( p_sys->i_eu_pts <= VLC_TS_INVALID && p_sys->i_eu_dts <= VLC_TS_INVALID )
  843.     {
  844.         /* earliest block with pts/dts gets to set the pts/dts for the dated
  845.          * encapsulation unit as a whole */
  846.         /* NB, the 'earliest block' criteria is aribtary */
  847.         if( p_block->i_pts > VLC_TS_INVALID || p_block->i_dts > VLC_TS_INVALID )
  848.         {
  849.             p_sys->i_eu_pts = p_block->i_pts;
  850.             p_sys->i_eu_dts = p_block->i_dts;
  851.         }
  852.     }
  853.     /* inpectdataunit also updates flags for the EU.
  854.      *  - if this is the first block in the EU, then it hasn't been added
  855.      *    to the chain yet (so, p_block will become the front of the chain
  856.      *  - otherwise, use the flags of the chain (first block) */
  857.     block_t *p_eu = p_sys->p_eu ? p_sys->p_eu : p_block;
  858.     int i_block = dirac_InspectDataUnit( p_dec, &p_block, p_eu);
  859.     if( !p_block )
  860.     {
  861.         /* block has been discarded during inspection */
  862.         /* becareful, don't discard anything that is dated,
  863.          * as this needs to go into the timegen loop.  set
  864.          * the DIRAC_DISCARD block flag, and it'll be dropped
  865.          * at output time */
  866.         return NULL;
  867.     }
  868.     block_ChainLastAppend( &p_sys->pp_eu_last, p_block );
  869.     dirac_block_encap_t *p_dbe = dirac_GetBlockEncap( p_block );
  870. #ifdef SANITIZE_PREV_PARSE_OFFSET
  871.     /* fixup prev_parse_offset to point to the last data unit
  872.      * to arrive */
  873.     if( p_dbe )
  874.     {
  875.         SetDWBE( p_block->p_buffer + 9, p_sys->u_eu_last_npo );
  876.         p_sys->u_eu_last_npo = p_dbe->u_last_next_offset;
  877.     }
  878. #endif
  879.     if( i_block != DIRAC_DU_ENDS_EU )
  880.     {
  881.         /* encapsulation unit not ended */
  882.         return NULL;
  883.     }
  884.     /* gather up encapsulation unit, reassociating the final
  885.      * private state with the gathered block */
  886.     block_t *p_eu_last = (block_t*) p_sys->pp_eu_last - offsetof( block_t, p_next );
  887.     p_dbe = dirac_RemoveBlockEncap( p_eu_last );
  888.     uint8_t u_parse_code = p_block->p_buffer[4];
  889.     /* gather up the encapsulation unit */
  890.     p_block = block_ChainGather( p_sys->p_eu );
  891.     assert( p_block ); /* block_ChainGather doesn't define when it frees chain */
  892.     p_block->i_flags |= DIRAC_NON_DATED;
  893.     if( p_dbe )
  894.     {
  895.         dirac_AddBlockEncap( &p_block, p_dbe );
  896.         if( dirac_isPicture( u_parse_code ) ) p_block->i_flags &= ~DIRAC_NON_DATED;
  897.     }
  898.     p_sys->p_eu = NULL;
  899.     p_sys->pp_eu_last = &p_sys->p_eu;
  900.     return p_block;
  901. }
  902. /**
  903.  * dirac_TimeGenPush:
  904.  * @p_dec: vlc object
  905.  * @p_block_in: whole encapsulation unit to generate timestamps for
  906.  *
  907.  * Returns:
  908.  *  0: everything ok
  909.  *  1: EOS occured, please flush and reset
  910.  *  2: picture number discontinuity, please flush and reset
  911.  */
  912. static int dirac_TimeGenPush( decoder_t *p_dec, block_t *p_block_in )
  913. {
  914.     decoder_sys_t *p_sys = p_dec->p_sys;
  915.     dirac_block_encap_t *p_dbe;
  916.     if( p_block_in->i_flags & BLOCK_FLAG_END_OF_SEQUENCE )
  917.     {
  918.         /* NB, this test occurs after the timegen push, so as to
  919.          * push the block into the output queue */
  920.         return 1;
  921.     }
  922.     if( p_block_in->i_flags & DIRAC_NON_DATED )
  923.     {
  924.         /* no picture found, which means p_block_in is a non-dated EU,
  925.          * do not try and put a date on it */
  926.         return 0;
  927.     }
  928.     p_dbe = dirac_GetBlockEncap( p_block_in );
  929.     uint32_t u_picnum = p_dbe ? p_dbe->u_picture_number : 0;
  930.     /*
  931.      * Simple DTS regeneration:
  932.      *  - DTS values linearly increase in stream order.
  933.      *  - Every time a DTS occurs at the input, sync to it
  934.      *    - If this is the first DTS seen, backdate all the previous ones that are undated
  935.      *  - If a DTS is missing, guess that it increases by one picture period
  936.      *  - If never seen DTS, don't do anything
  937.      */
  938.     /*
  939.      * Simple PTS regeneration
  940.      *  - PTS values do not linearly increase in stream order.
  941.      *  - Every time a PTS occurs at the input, sync to it and record picture number
  942.      *  - If a PTS is missing, guess that it differs by the product of picture
  943.      *    period and difference between picture number of sync point and current picture
  944.      *  - If this is the first PTS seen, backdate all previous ones that are undated
  945.      *  - If never seen PTS, don't do anything
  946.      */
  947.     /*
  948.      * Stage 1, sync to input timestamps, backdate timestamps for old
  949.      * EUs that are in the outqueue with missing dates
  950.      */
  951.     if( p_block_in->i_dts > VLC_TS_INVALID )
  952.     do {
  953.         /* if timestamps exist, sync to them */
  954.         if( p_sys->b_dts )
  955.             break;
  956.         /* first dts seen, backdate any packets in outqueue */
  957.         p_sys->b_dts = true;
  958.         date_t dts = p_sys->dts;
  959.         dirac_BackdateDTS( p_sys->p_outqueue, p_block_in, &dts );
  960.     } while( 0 );
  961.     if( p_block_in->i_pts > VLC_TS_INVALID )
  962.     do {
  963.         /* if timestamps exist, sync to them */
  964.         p_sys->u_pts_picnum = u_picnum;
  965.         p_sys->i_pts = p_block_in->i_pts;
  966.         if( p_sys->b_pts )
  967.             break;
  968.         /* first pts seen, backdate any packets in outqueue */
  969.         p_sys->b_pts = true;
  970.         date_t pts = p_sys->dts;
  971.         date_Set( &pts, p_sys->i_pts );
  972.         dirac_BackdatePTS( p_sys->p_outqueue, p_block_in, &pts, p_sys->u_pts_picnum );
  973.     } while( 0 );
  974.     /*
  975.      * Stage 2, don't attempt to forwards interpolate timestamps for
  976.      * blocks if the picture rates aren't known
  977.      */
  978.     if( !p_sys->b_seen_seq_hdr )
  979.     {
  980.         return 0;
  981.     }
  982.     /*
  983.      * Stage 3, for block_in, interpolate any missing timestamps
  984.      */
  985.     if( p_sys->b_dts && p_block_in->i_dts <= VLC_TS_INVALID )
  986.     {
  987.         /* dts has previously been seen, but not this time, interpolate */
  988.         p_block_in->i_dts = date_Increment( &p_sys->dts, 1 );
  989.     }
  990.     if( p_sys->b_pts && p_block_in->i_pts <= VLC_TS_INVALID )
  991.     {
  992.         /* pts has previously been seen, but not this time, interpolate */
  993.         date_t pts = p_sys->dts;
  994.         date_Set( &pts, p_sys->i_pts );
  995.         int32_t i_dist = u_picnum - p_sys->u_pts_picnum;
  996.         if( i_dist >= 0 )
  997.             p_block_in->i_pts = date_Increment( &pts, i_dist );
  998.         else
  999.             p_block_in->i_pts = date_Decrement( &pts, -i_dist );
  1000.     }
  1001.     /* If pts and dts have been seen, there is no need to simulate operation
  1002.      * of the decoder reorder buffer */
  1003.     /* If neither have been seen, there is little point in simulating */
  1004.     if( p_sys->b_dts == p_sys->b_pts )
  1005.         return 0;
  1006.     if( !p_sys->p_out_dts )
  1007.         p_sys->p_out_dts = p_sys->p_outqueue;
  1008.     /* model the reorder buffer */
  1009.     block_t *p_block = dirac_Reorder( p_dec, p_block_in, u_picnum );
  1010.     if( !p_block )
  1011.         return 0;
  1012.     /* A future ehancement is to stop modeling the reorder buffer as soon as
  1013.      * the first packet is output -- interpolate the past and freewheel for
  1014.      * the future */
  1015.     p_dbe = dirac_GetBlockEncap( p_block );
  1016.     u_picnum = p_dbe ? p_dbe->u_picture_number : 0;
  1017.     if( p_sys->b_tg_last_picnum )
  1018.     {
  1019.         if( dirac_PictureNbeforeM( u_picnum, p_sys->u_tg_last_picnum ) )
  1020.         {
  1021.             msg_Warn( p_dec, "stream jumped? %d < %d: resetting"
  1022.                     , u_picnum, p_sys->u_tg_last_picnum );
  1023.             /* pictures only emerge from the reorder buffer in sequence
  1024.              * if a stream suddenly jumped backwards without a signaling
  1025.              * a discontinuity, some pictures will get stuck in the RoB.
  1026.              * flush the RoB. */
  1027.             /* this could be a bit less indiscriminate */
  1028.             p_dbe = dirac_GetBlockEncap( p_sys->p_outqueue );
  1029.             uint32_t u_prev_parse_offset = p_dbe ? p_dbe->u_last_next_offset : 0;
  1030.             block_ChainRelease( p_sys->p_outqueue );
  1031.             p_sys->p_outqueue = dirac_EmitEOS( p_dec, u_prev_parse_offset );
  1032.             if( p_sys->p_outqueue )
  1033.                 p_sys->p_outqueue->i_flags = BLOCK_FLAG_DISCONTINUITY | DIRAC_NON_DATED;
  1034.             /* return 2, so as not to reset the b_dts flags -- needed if
  1035.              * using the rawdirac demuxer with broken stream */
  1036.             return 2;
  1037.         }
  1038.     }
  1039.     p_sys->b_tg_last_picnum = true;
  1040.     p_sys->u_tg_last_picnum = u_picnum;
  1041.     if( !p_sys->b_pts )
  1042.     {
  1043.         /* some demuxers (eg, AVI) will provide a series of fake dts values,
  1044.          * which are actually inorder pts values (ie, what should be seen at
  1045.          * the output of a decoder.  A main reason for simulating the reorder
  1046.          * buffer is to turn the inorder fakedts into an out-of-order pts */
  1047.         p_block->i_pts = p_sys->p_out_dts->i_dts;
  1048.         p_sys->p_out_dts->i_dts = VLC_TS_INVALID;
  1049.     }
  1050.     /* If pts was copied from dts, the dts needs to be corrected to account for reordering*/
  1051.     /* If dts has never been seen, the same needs to happen */
  1052.     p_sys->p_out_dts->i_dts = p_block->i_pts - p_sys->i_pts_offset;
  1053.     /* move dts pointer */
  1054.     if( p_sys->p_out_dts )
  1055.         p_sys->p_out_dts = p_sys->p_out_dts->p_next;
  1056.     return 0;
  1057. }
  1058. /*****************************************************************************
  1059.  * Packetize: form dated encapsulation units from anything
  1060.  *****************************************************************************/
  1061. static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
  1062. {
  1063.     decoder_sys_t *p_sys = p_dec->p_sys;
  1064.     block_t *p_block = NULL;
  1065.     int i_flushing = 0;
  1066.     if( pp_block && *pp_block )
  1067.     {
  1068.         p_block = *pp_block;
  1069.         *pp_block = NULL;
  1070.         if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
  1071.         {
  1072.             /* pre-emptively insert an EOS at a discontinuity, protects
  1073.              * any decoders from any sudden changes */
  1074.             block_Release( p_block );
  1075.             p_block = dirac_EmitEOS( p_dec, 0 );
  1076.             if( p_block )
  1077.             {
  1078.                 p_block->p_next = dirac_EmitEOS( p_dec, 13 );
  1079.                 /* need two EOS to ensure it gets detected by syncro
  1080.                  * duplicates get discarded in forming encapsulation unit */
  1081.             }
  1082.         }
  1083.         else if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
  1084.         {
  1085.             /* silently discard corruption sentinels,
  1086.              * synchronizer will then discard affected data units.
  1087.              * do not produce an EOS data unit as this is very
  1088.              * disruptive to the stream (and may make a larger error). */
  1089.             block_Release( p_block );
  1090.             p_block = NULL;
  1091.         }
  1092.         if( p_block )
  1093.             block_BytestreamPush( &p_sys->bytestream, p_block );
  1094.     }
  1095.     /* form as many encapsulation units as possible, give up
  1096.      * when the syncronizer runs out of input data */
  1097.     while( ( p_block = dirac_DoSync( p_dec ) ) )
  1098.     {
  1099.         p_block = dirac_BuildEncapsulationUnit( p_dec, p_block );
  1100.         if( !p_block )
  1101.             continue;
  1102.         /* add to tail of output queue (ie, not reordered) */
  1103.         block_ChainLastAppend( &p_sys->pp_outqueue_last, p_block );
  1104.         /* insert encapsulation unit into timestamp generator
  1105.          * which then calculates some timestamps if required */
  1106.         i_flushing = dirac_TimeGenPush( p_dec, p_block );
  1107.         if( i_flushing )
  1108.             break;
  1109.     }
  1110.     block_t *p_output = NULL;
  1111.     block_t **pp_output = &p_output;
  1112.     /* extract all the dated packets from the head of the ouput queue */
  1113.     /* explicitly nondated packets repeat the previous timestamps to
  1114.      * stop vlc discarding them */
  1115.     while( (p_block = p_sys->p_outqueue) )
  1116.     {
  1117.         if( p_block->i_flags & DIRAC_DISCARD )
  1118.         {
  1119.             p_sys->p_outqueue = p_block->p_next;
  1120.             p_block->p_next = NULL;
  1121.             block_Release( p_block );
  1122.             continue;
  1123.         }
  1124.         if( i_flushing || p_block->i_flags & DIRAC_NON_DATED )
  1125.         {
  1126.             p_block->i_dts = p_sys->i_dts_last_out;
  1127.             p_block->i_pts = p_sys->i_pts_last_out;
  1128.         }
  1129.         else if( p_block->i_pts <= VLC_TS_INVALID ) break;
  1130.         else if( p_block->i_dts <= VLC_TS_INVALID ) break;
  1131.         p_sys->i_dts_last_out = p_block->i_dts;
  1132.         p_sys->i_pts_last_out = p_block->i_pts;
  1133.         p_sys->p_outqueue = p_block->p_next;
  1134.         p_block->p_next = NULL;
  1135.         /* clear any flags we set */
  1136.         p_block->i_flags &= ~BLOCK_FLAG_PRIVATE_MASK;
  1137.         block_ChainLastAppend( &pp_output, p_block );
  1138.         mtime_t i_delay = p_block->i_pts - p_block->i_dts;
  1139.         if( i_delay < 0 )
  1140.             msg_Err( p_dec, "pts - dts is negative(%"PRId64"): incorrect RoB size", i_delay );
  1141.     }
  1142.     if( i_flushing )
  1143.     {
  1144.         p_sys->i_eu_dts = p_sys->i_eu_pts = VLC_TS_INVALID;
  1145.         /* reset timegen state (except synchronizer) */
  1146.         p_sys->b_seen_seq_hdr = false;
  1147.         if( i_flushing < 2 )
  1148.         {
  1149.             /* this state isn't safe to loose if there was
  1150.              * an unsignalled discontinuity */
  1151.             p_sys->b_pts = p_sys->b_dts = false;
  1152.         }
  1153.         p_sys->b_tg_last_picnum = false;
  1154.         dirac_ReorderInit( &p_sys->reorder_buf );
  1155.         assert( p_sys->p_outqueue == NULL );
  1156.         p_sys->p_out_dts = NULL;
  1157.     }
  1158.     /* perform sanity check:
  1159.      *  if there were a block at the front of outqueue that never
  1160.      *  satisfied the extraction criteria, but all blocks after did,
  1161.      *  the output queue would grow bounded by the stream length.
  1162.      * If there are 10 data units in the output queue, assume this
  1163.      * has happened and purge all blocks that fail extraction criteria */
  1164.     int i_count;
  1165.     block_ChainProperties( p_sys->p_outqueue, &i_count, NULL, NULL );
  1166.     if( i_count > 9 )
  1167.     {
  1168.         p_block = p_sys->p_outqueue;
  1169.         while( p_block )
  1170.         {
  1171.             block_t *p_block_next = p_block->p_next;
  1172.             if( p_block->i_pts > VLC_TS_INVALID && p_block->i_dts > VLC_TS_INVALID )
  1173.                 break;
  1174.             block_Release( p_block );
  1175.             p_sys->p_outqueue = p_block = p_block_next;
  1176.         }
  1177.     }
  1178.     if( !p_sys->p_outqueue )
  1179.     {
  1180.         p_sys->pp_outqueue_last = &p_sys->p_outqueue;
  1181.     }
  1182.     return p_output;
  1183. }
  1184. /*****************************************************************************
  1185.  * Open: probe the packetizer and return score
  1186.  *****************************************************************************/
  1187. static int Open( vlc_object_t *p_this )
  1188. {
  1189.     decoder_t     *p_dec = (decoder_t*)p_this;
  1190.     decoder_sys_t *p_sys;
  1191.     if( p_dec->fmt_in.i_codec !=  VLC_FOURCC( 'd','r','a','c' ) )
  1192.         return VLC_EGENERIC;
  1193.     p_dec->pf_packetize = Packetize;
  1194.     /* Create the output format */
  1195.     es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in );
  1196.     p_dec->p_sys = p_sys = calloc( 1, sizeof( decoder_sys_t ) );
  1197.     if( !p_sys )
  1198.         return VLC_ENOMEM;
  1199.     p_sys->i_eu_pts = p_sys->i_eu_dts = VLC_TS_INVALID;
  1200.     p_sys->i_sync_pts = p_sys->i_sync_dts = VLC_TS_INVALID;
  1201.     p_sys->i_dts_last_out = p_sys->i_pts_last_out = VLC_TS_INVALID;
  1202.     p_sys->i_state = NOT_SYNCED;
  1203.     p_sys->bytestream = block_BytestreamInit();
  1204.     p_sys->pp_outqueue_last = &p_sys->p_outqueue;
  1205.     p_sys->pp_eu_last = &p_sys->p_eu;
  1206.     date_Init( &p_sys->dts, 1, 1 );
  1207.     dirac_ReorderInit( &p_sys->reorder_buf );
  1208.     if( p_dec->fmt_in.i_extra > 0 )
  1209.     {
  1210.         /* handle hacky systems like ogg that dump some headers
  1211.          * in p_extra. and packetizers that expect it to be filled
  1212.          * in before real startup */
  1213.         block_t *p_init = block_New( p_dec, p_dec->fmt_in.i_extra );
  1214.         if( !p_init )
  1215.         {
  1216.             /* memory might be avaliable soon.  it isn't the end of
  1217.              * the world that fmt_in.i_extra isn't handled */
  1218.             return VLC_SUCCESS;
  1219.         }
  1220.         memcpy( p_init->p_buffer, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra );
  1221.         /* in theory p_extra should contain just a seqhdr&EOS.  if just a
  1222.          * seqhdr, ensure it is extracted by appending an EOS with
  1223.          * prev_offset = seqhdr length, ie i_extra.  If all were actually
  1224.          * ok, this won't do anything bad */
  1225.         if( ( p_init->p_next = dirac_EmitEOS( p_dec, p_dec->fmt_in.i_extra ) ) )
  1226.         {
  1227.             /* to ensure that one of these two EOS dataunits gets extracted,
  1228.              * send a second one */
  1229.             p_init->p_next->p_next = dirac_EmitEOS( p_dec, 13 );
  1230.         }
  1231.         block_t *p_block;
  1232.         while( ( p_block = Packetize( p_dec, &p_init ) ) )
  1233.             block_Release( p_block );
  1234.     }
  1235.     return VLC_SUCCESS;
  1236. }
  1237. /*****************************************************************************
  1238.  * Close:
  1239.  *****************************************************************************/
  1240. static void Close( vlc_object_t *p_this )
  1241. {
  1242.     decoder_t     *p_dec = (decoder_t*)p_this;
  1243.     decoder_sys_t *p_sys = p_dec->p_sys;
  1244.     block_BytestreamRelease( &p_sys->bytestream );
  1245.     if( p_sys->p_outqueue )
  1246.         block_ChainRelease( p_sys->p_outqueue );
  1247.     if( p_sys->p_eu )
  1248.         block_ChainRelease( p_sys->p_eu );
  1249.     free( p_sys );
  1250. }