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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * ps.c: MPEG PS (ISO/IEC 13818-1) / MPEG SYSTEM (ISO/IEC 1172-1)
  3.  *       multiplexer module for vlc
  4.  *****************************************************************************
  5.  * Copyright (C) 2001, 2002 the VideoLAN team
  6.  * $Id: f2ec618a204dc27af8763fd969c2f37ef9495506 $
  7.  *
  8.  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  9.  *          Eric Petit <titer@videolan.org>
  10.  *          Gildas Bazin <gbazin@videolan.org>
  11.  *
  12.  * This program is free software; you can redistribute it and/or modify
  13.  * it under the terms of the GNU General Public License as published by
  14.  * the Free Software Foundation; either version 2 of the License, or
  15.  * (at your option) any later version.
  16.  *
  17.  * This program is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  * GNU General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU General Public License
  23.  * along with this program; if not, write to the Free Software
  24.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  25.  *****************************************************************************/
  26. /*****************************************************************************
  27.  * Preamble
  28.  *****************************************************************************/
  29. #ifdef HAVE_CONFIG_H
  30. # include "config.h"
  31. #endif
  32. #include <vlc_common.h>
  33. #include <vlc_plugin.h>
  34. #include <vlc_sout.h>
  35. #include <vlc_codecs.h>
  36. #include <vlc_block.h>
  37. #include "bits.h"
  38. #include "pes.h"
  39. #include <vlc_iso_lang.h>
  40. /*****************************************************************************
  41.  * Module descriptor
  42.  *****************************************************************************/
  43. #define DTS_TEXT N_("DTS delay (ms)")
  44. #define DTS_LONGTEXT N_("Delay the DTS (decoding time " 
  45.   "stamps) and PTS (presentation timestamps) of the data in the " 
  46.   "stream, compared to the SCRs. This allows for some buffering inside " 
  47.   "the client decoder.")
  48. #define PES_SIZE_TEXT N_("PES maximum size")
  49. #define PES_SIZE_LONGTEXT N_("Set the maximum allowed PES "
  50.   "size when producing the MPEG PS streams.")
  51. static int     Open   ( vlc_object_t * );
  52. static void    Close  ( vlc_object_t * );
  53. #define SOUT_CFG_PREFIX "sout-ps-"
  54. vlc_module_begin ()
  55.     set_description( N_("PS muxer") )
  56.     set_shortname( "MPEG-PS" )
  57.     set_category( CAT_SOUT )
  58.     set_subcategory( SUBCAT_SOUT_MUX )
  59.     set_capability( "sout mux", 50 )
  60.     add_shortcut( "ps" )
  61.     add_shortcut( "mpeg1" )
  62.     add_shortcut( "dvd" )
  63.     set_callbacks( Open, Close )
  64.     add_integer( SOUT_CFG_PREFIX "dts-delay", 200, NULL, DTS_TEXT,
  65.                  DTS_LONGTEXT, true )
  66.     add_integer( SOUT_CFG_PREFIX "pes-max-size", PES_PAYLOAD_SIZE_MAX, NULL,
  67.                  PES_SIZE_TEXT, PES_SIZE_LONGTEXT, true )
  68. vlc_module_end ()
  69. /*****************************************************************************
  70.  * Exported prototypes
  71.  *****************************************************************************/
  72. static int Control  ( sout_mux_t *, int, va_list );
  73. static int AddStream( sout_mux_t *, sout_input_t * );
  74. static int DelStream( sout_mux_t *, sout_input_t * );
  75. static int Mux      ( sout_mux_t * );
  76. /*****************************************************************************
  77.  * Local prototypes
  78.  *****************************************************************************/
  79. static int  MuxGetStream        ( sout_mux_t *, int *, mtime_t * );
  80. static void MuxWritePackHeader  ( sout_mux_t *, block_t **, mtime_t );
  81. static void MuxWriteSystemHeader( sout_mux_t *, block_t **, mtime_t );
  82. static void MuxWritePSM         ( sout_mux_t *, block_t **, mtime_t );
  83. static void StreamIdInit        ( bool *id, int i_range );
  84. static int  StreamIdGet         ( bool *id, int i_id_min, int i_id_max );
  85. static void StreamIdRelease     ( bool *id, int i_id_min, int i_id );
  86. typedef struct ps_stream_s
  87. {
  88.     int i_stream_id;
  89.     int i_stream_type;
  90.     int i_max_buff_size; /* used in system header */
  91.     /* Language is iso639-2T */
  92.     uint8_t lang[3];
  93. } ps_stream_t;
  94. struct sout_mux_sys_t
  95. {
  96.     /* Which id are unused */
  97.     bool  stream_id_mpga[16]; /* 0xc0 -> 0xcf */
  98.     bool  stream_id_mpgv[16]; /* 0xe0 -> 0xef */
  99.     bool  stream_id_a52[8];   /* 0x80 -> 0x87 <- FIXME I'm not sure */
  100.     bool  stream_id_spu[32];  /* 0x20 -> 0x3f */
  101.     bool  stream_id_dts[8];   /* 0x88 -> 0x8f */
  102.     bool  stream_id_lpcm[16]; /* 0xa0 -> 0xaf */
  103.     int i_audio_bound;
  104.     int i_video_bound;
  105.     int i_pes_count;
  106.     int i_system_header;
  107.     int i_dts_delay;
  108.     int i_rate_bound; /* units of 50 bytes/second */
  109.  
  110.     int64_t i_instant_bitrate;
  111.     int64_t i_instant_size;
  112.     int64_t i_instant_dts;
  113.     bool b_mpeg2;
  114.     int i_pes_max_size;
  115.     int i_psm_version;
  116.     uint32_t crc32_table[256];
  117. };
  118. static const char *const ppsz_sout_options[] = {
  119.     "dts-delay", "pes-max-size", NULL
  120. };
  121. /*****************************************************************************
  122.  * Open:
  123.  *****************************************************************************/
  124. static int Open( vlc_object_t *p_this )
  125. {
  126.     sout_mux_t *p_mux = (sout_mux_t*)p_this;
  127.     sout_mux_sys_t *p_sys;
  128.     vlc_value_t val;
  129.     msg_Info( p_mux, "Open" );
  130.     config_ChainParse( p_mux, SOUT_CFG_PREFIX, ppsz_sout_options, p_mux->p_cfg );
  131.     p_mux->pf_control   = Control;
  132.     p_mux->pf_addstream = AddStream;
  133.     p_mux->pf_delstream = DelStream;
  134.     p_mux->pf_mux       = Mux;
  135.     p_mux->p_sys        = p_sys = malloc( sizeof( sout_mux_sys_t ) );
  136.     /* Init free stream id */
  137.     StreamIdInit( p_sys->stream_id_a52,  8  );
  138.     StreamIdInit( p_sys->stream_id_dts,  8  );
  139.     StreamIdInit( p_sys->stream_id_mpga, 16 );
  140.     StreamIdInit( p_sys->stream_id_mpgv, 16 );
  141.     StreamIdInit( p_sys->stream_id_lpcm, 16 );
  142.     StreamIdInit( p_sys->stream_id_spu,  32 );
  143.     p_sys->i_audio_bound   = 0;
  144.     p_sys->i_video_bound   = 0;
  145.     p_sys->i_system_header = 0;
  146.     p_sys->i_pes_count     = 0;
  147.     p_sys->i_psm_version   = 0;
  148.     p_sys->i_instant_bitrate  = 0;
  149.     p_sys->i_instant_size     = 0;
  150.     p_sys->i_instant_dts      = 0;
  151.     p_sys->i_rate_bound      = 0;
  152.     p_sys->b_mpeg2 = !(p_mux->psz_mux && !strcmp( p_mux->psz_mux, "mpeg1" ));
  153.     var_Get( p_mux, SOUT_CFG_PREFIX "dts-delay", &val );
  154.     p_sys->i_dts_delay = (int64_t)val.i_int * 1000;
  155.     var_Get( p_mux, SOUT_CFG_PREFIX "pes-max-size", &val );
  156.     p_sys->i_pes_max_size = (int64_t)val.i_int;
  157.     /* Initialise CRC32 table */
  158.     if( p_sys->b_mpeg2 )
  159.     {
  160.         uint32_t i, j, k;
  161.         for( i = 0; i < 256; i++ )
  162.         {
  163.             k = 0;
  164.             for( j = (i << 24) | 0x800000; j != 0x80000000; j <<= 1 )
  165.                 k = (k << 1) ^ (((k ^ j) & 0x80000000) ? 0x04c11db7 : 0);
  166.             p_sys->crc32_table[i] = k;
  167.         }
  168.     }
  169.     return VLC_SUCCESS;
  170. }
  171. /*****************************************************************************
  172.  * Close:
  173.  *****************************************************************************/
  174. static void Close( vlc_object_t * p_this )
  175. {
  176.     sout_mux_t      *p_mux = (sout_mux_t*)p_this;
  177.     sout_mux_sys_t  *p_sys = p_mux->p_sys;
  178.     block_t   *p_end;
  179.     msg_Info( p_mux, "Close" );
  180.     p_end = block_New( p_mux, 4 );
  181.     p_end->p_buffer[0] = 0x00; p_end->p_buffer[1] = 0x00;
  182.     p_end->p_buffer[2] = 0x01; p_end->p_buffer[3] = 0xb9;
  183.     sout_AccessOutWrite( p_mux->p_access, p_end );
  184.     free( p_sys );
  185. }
  186. /*****************************************************************************
  187.  * Control:
  188.  *****************************************************************************/
  189. static int Control( sout_mux_t *p_mux, int i_query, va_list args )
  190. {
  191.     VLC_UNUSED(p_mux);
  192.     bool *pb_bool;
  193.     char **ppsz;
  194.     switch( i_query )
  195.     {
  196.         case MUX_CAN_ADD_STREAM_WHILE_MUXING:
  197.             pb_bool = (bool*)va_arg( args, bool * );
  198.             *pb_bool = true;
  199.             return VLC_SUCCESS;
  200.         case MUX_GET_ADD_STREAM_WAIT:
  201.             pb_bool = (bool*)va_arg( args, bool * );
  202.             *pb_bool = false;
  203.             return VLC_SUCCESS;
  204.         case MUX_GET_MIME:
  205.             ppsz = (char**)va_arg( args, char ** );
  206.             *ppsz = strdup( "video/mpeg" );
  207.             return VLC_SUCCESS;
  208.         default:
  209.             return VLC_EGENERIC;
  210.     }
  211. }
  212. /*****************************************************************************
  213.  * AddStream:
  214.  *****************************************************************************/
  215. static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
  216. {
  217.     sout_mux_sys_t  *p_sys = p_mux->p_sys;
  218.     ps_stream_t *p_stream;
  219.  
  220.     msg_Dbg( p_mux, "adding input codec=%4.4s",
  221.              (char*)&p_input->p_fmt->i_codec );
  222.     p_input->p_sys = p_stream = malloc( sizeof( ps_stream_t ) );
  223.     p_stream->i_stream_type = 0x81;
  224.     /* Init this new stream */
  225.     switch( p_input->p_fmt->i_codec )
  226.     {
  227.         case VLC_FOURCC( 'm', 'p', '1', 'v' ):
  228.             p_stream->i_stream_id =
  229.                 StreamIdGet( p_sys->stream_id_mpgv, 0xe0, 0xef );
  230.             p_stream->i_stream_type = 0x01; /* ISO/IEC 11172 Video */
  231.             break;
  232.         case VLC_FOURCC( 'm', 'p', '2', 'v' ):
  233.         case VLC_FOURCC( 'm', 'p', 'g', 'v' ):
  234.             p_stream->i_stream_id =
  235.                 StreamIdGet( p_sys->stream_id_mpgv, 0xe0, 0xef );
  236.             p_stream->i_stream_type = 0x02; /* ISO/IEC 13818 Video */
  237.             break;
  238.         case VLC_FOURCC( 'm', 'p', '4', 'v' ):
  239.             p_stream->i_stream_id =
  240.                 StreamIdGet( p_sys->stream_id_mpgv, 0xe0, 0xef );
  241.             p_stream->i_stream_type = 0x10;
  242.             break;
  243.         case VLC_FOURCC( 'h', '2', '6', '4' ):
  244.             p_stream->i_stream_id =
  245.                 StreamIdGet( p_sys->stream_id_mpgv, 0xe0, 0xef );
  246.             p_stream->i_stream_type = 0x1b;
  247.             break;
  248.         case VLC_FOURCC( 'l', 'p', 'c', 'm' ):
  249.             p_stream->i_stream_id =
  250.                 0xbd00 | StreamIdGet( p_sys->stream_id_lpcm, 0xa0, 0xaf );
  251.             break;
  252.         case VLC_FOURCC( 'd', 't', 's', ' ' ):
  253.             p_stream->i_stream_id =
  254.                 0xbd00 | StreamIdGet( p_sys->stream_id_dts, 0x88, 0x8f );
  255.             break;
  256.         case VLC_FOURCC( 'a', '5', '2', ' ' ):
  257.             p_stream->i_stream_id =
  258.                 0xbd00 | StreamIdGet( p_sys->stream_id_a52, 0x80, 0x87 );
  259.             break;
  260.         case VLC_FOURCC( 'm', 'p', 'g', 'a' ):
  261.         case VLC_FOURCC( 'm', 'p', '3', ' ' ):
  262.             p_stream->i_stream_id =
  263.                 StreamIdGet( p_sys->stream_id_mpga, 0xc0, 0xcf );
  264.             p_stream->i_stream_type = 0x03; /* ISO/IEC 11172 Audio */
  265.             break;
  266.         case VLC_FOURCC( 'm', 'p', '4', 'a' ):
  267.             p_stream->i_stream_id =
  268.                 StreamIdGet( p_sys->stream_id_mpga, 0xc0, 0xcf );
  269.             p_stream->i_stream_type = 0x0f;
  270.             break;
  271.         case VLC_FOURCC( 's', 'p', 'u', ' ' ):
  272.             p_stream->i_stream_id =
  273.                 0xbd00 | StreamIdGet( p_sys->stream_id_spu, 0x20, 0x3f );
  274.             break;
  275.         default:
  276.             goto error;
  277.     }
  278.     if( p_stream->i_stream_id < 0 ) goto error;
  279.     if( p_input->p_fmt->i_cat == AUDIO_ES )
  280.     {
  281.         p_sys->i_audio_bound++;
  282.         p_stream->i_max_buff_size = 4 * 1024;
  283.     }
  284.     else if( p_input->p_fmt->i_cat == VIDEO_ES )
  285.     {
  286.         p_sys->i_video_bound++;
  287.         p_stream->i_max_buff_size = 400 * 1024; /* FIXME -- VCD uses 46, SVCD
  288.                         uses 230, ffmpeg has 230 with a note that it is small */
  289.     }
  290.     else
  291.     {   /* FIXME -- what's valid for not audio or video? */
  292.         p_stream->i_max_buff_size = 4 * 1024;
  293.     }
  294.     /* Try to set a sensible default value for the instant bitrate */
  295.     p_sys->i_instant_bitrate += p_input->p_fmt->i_bitrate + 1000/* overhead */;
  296.     /* FIXME -- spec requires  an upper limit rate boundary in the system header;
  297.        our codecs are VBR; using 2x nominal rate, convert to 50 bytes/sec */
  298.     p_sys->i_rate_bound += p_input->p_fmt->i_bitrate * 2 / (8 * 50);
  299.     p_sys->i_psm_version++;
  300.     p_stream->lang[0] = p_stream->lang[1] = p_stream->lang[2] = 0;
  301.     if( p_input->p_fmt->psz_language )
  302.     {
  303.         char *psz = p_input->p_fmt->psz_language;
  304.         const iso639_lang_t *pl = NULL;
  305.         if( strlen( psz ) == 2 )
  306.         {
  307.             pl = GetLang_1( psz );
  308.         }
  309.         else if( strlen( psz ) == 3 )
  310.         {
  311.             pl = GetLang_2B( psz );
  312.             if( !strcmp( pl->psz_iso639_1, "??" ) )
  313.             {
  314.                 pl = GetLang_2T( psz );
  315.             }
  316.         }
  317.         if( pl && strcmp( pl->psz_iso639_1, "??" ) )
  318.         {
  319.             p_stream->lang[0] = pl->psz_iso639_2T[0];
  320.             p_stream->lang[1] = pl->psz_iso639_2T[1];
  321.             p_stream->lang[2] = pl->psz_iso639_2T[2];
  322.             msg_Dbg( p_mux, "    - lang=%c%c%c",
  323.                      p_stream->lang[0], p_stream->lang[1], p_stream->lang[2] );
  324.         }
  325.     }
  326.     return VLC_SUCCESS;
  327. error:
  328.     free( p_stream );
  329.     return VLC_EGENERIC;
  330. }
  331. /*****************************************************************************
  332.  * DelStream:
  333.  *****************************************************************************/
  334. static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
  335. {
  336.     sout_mux_sys_t *p_sys = p_mux->p_sys;
  337.     ps_stream_t *p_stream =(ps_stream_t*)p_input->p_sys;
  338.     msg_Dbg( p_mux, "removing input" );
  339.     switch( p_input->p_fmt->i_codec )
  340.     {
  341.         case VLC_FOURCC( 'm', 'p', 'g', 'v' ):
  342.             StreamIdRelease( p_sys->stream_id_mpgv, 0xe0,
  343.                              p_stream->i_stream_id );
  344.             break;
  345.         case VLC_FOURCC( 'l', 'p', 'c', 'm' ):
  346.             StreamIdRelease( p_sys->stream_id_lpcm, 0xa0,
  347.                              p_stream->i_stream_id&0xff );
  348.             break;
  349.         case VLC_FOURCC( 'd', 't', 's', ' ' ):
  350.             StreamIdRelease( p_sys->stream_id_dts, 0x88,
  351.                              p_stream->i_stream_id&0xff );
  352.             break;
  353.         case VLC_FOURCC( 'a', '5', '2', ' ' ):
  354.             StreamIdRelease( p_sys->stream_id_a52, 0x80,
  355.                              p_stream->i_stream_id&0xff );
  356.             break;
  357.         case VLC_FOURCC( 'm', 'p', 'g', 'a' ):
  358.             StreamIdRelease( p_sys->stream_id_mpga, 0xc0,
  359.                              p_stream->i_stream_id  );
  360.             break;
  361.         case VLC_FOURCC( 's', 'p', 'u', ' ' ):
  362.             StreamIdRelease( p_sys->stream_id_spu, 0x20,
  363.                              p_stream->i_stream_id&0xff );
  364.             break;
  365.         default:
  366.             /* Never reached */
  367.             break;
  368.     }
  369.     if( p_input->p_fmt->i_cat == AUDIO_ES )
  370.     {
  371.         p_sys->i_audio_bound--;
  372.     }
  373.     else if( p_input->p_fmt->i_cat == VIDEO_ES )
  374.     {
  375.         p_sys->i_video_bound--;
  376.     }
  377.     /* Try to set a sensible default value for the instant bitrate */
  378.     p_sys->i_instant_bitrate -= (p_input->p_fmt->i_bitrate + 1000);
  379.     /* rate_bound is in units of 50 bytes/second */
  380.     p_sys->i_rate_bound -= (p_input->p_fmt->i_bitrate * 2)/(8 * 50);
  381.     p_sys->i_psm_version++;
  382.     free( p_stream );
  383.     return VLC_SUCCESS;
  384. }
  385. /*****************************************************************************
  386.  * Mux: Call each time there is new data for at least one stream
  387.  *****************************************************************************/
  388. static int Mux( sout_mux_t *p_mux )
  389. {
  390.     sout_mux_sys_t *p_sys = p_mux->p_sys;
  391.     for( ;; )
  392.     {
  393.         sout_input_t *p_input;
  394.         ps_stream_t *p_stream;
  395.         block_t *p_ps, *p_data;
  396.         mtime_t        i_dts;
  397.         int            i_stream;
  398.         /* Choose which stream to mux */
  399.         if( MuxGetStream( p_mux, &i_stream, &i_dts ) )
  400.         {
  401.             return VLC_SUCCESS;
  402.         }
  403.         p_input  = p_mux->pp_inputs[i_stream];
  404.         p_stream = (ps_stream_t*)p_input->p_sys;
  405.         p_ps     = NULL;
  406.         /* Write regulary PackHeader */
  407.         if( p_sys->i_pes_count % 30 == 0)
  408.         {
  409.             /* Update the instant bitrate every second or so */
  410.             if( p_sys->i_instant_size &&
  411.                 i_dts - p_sys->i_instant_dts > 1000000 )
  412.             {
  413.                 int64_t i_instant_bitrate = p_sys->i_instant_size * 8000000 /
  414.                     ( i_dts - p_sys->i_instant_dts );
  415.                 p_sys->i_instant_bitrate += i_instant_bitrate;
  416.                 p_sys->i_instant_bitrate /= 2;
  417.                 p_sys->i_instant_size = 0;
  418.                 p_sys->i_instant_dts = i_dts;
  419.             }
  420.             else if( !p_sys->i_instant_size )
  421.             {
  422.                 p_sys->i_instant_dts = i_dts;
  423.             }
  424.             MuxWritePackHeader( p_mux, &p_ps, i_dts );
  425.         }
  426.         /* Write regulary SystemHeader */
  427.         if( p_sys->i_pes_count % 300 == 0 )
  428.         {
  429.             block_t *p_pk;
  430.             MuxWriteSystemHeader( p_mux, &p_ps, i_dts );
  431.             /* For MPEG1 streaming, set HEADER flag */
  432.             for( p_pk = p_ps; p_pk != NULL; p_pk = p_pk->p_next )
  433.             {
  434.                 p_pk->i_flags |= BLOCK_FLAG_HEADER;
  435.             }
  436.         }
  437.         /* Write regulary ProgramStreamMap */
  438.         if( p_sys->b_mpeg2 && p_sys->i_pes_count % 300 == 0 )
  439.         {
  440.             MuxWritePSM( p_mux, &p_ps, i_dts );
  441.         }
  442.         /* Get and mux a packet */
  443.         p_data = block_FifoGet( p_input->p_fifo );
  444.          EStoPES ( p_mux->p_sout, &p_data, p_data,
  445.                        p_input->p_fmt, p_stream->i_stream_id,
  446.                        p_sys->b_mpeg2, 0, 0, p_sys->i_pes_max_size );
  447.         block_ChainAppend( &p_ps, p_data );
  448.         /* Get size of output data so we can calculate the instant bitrate */
  449.         for( p_data = p_ps; p_data; p_data = p_data->p_next )
  450.         {
  451.             p_sys->i_instant_size += p_data->i_buffer;
  452.         }
  453.         sout_AccessOutWrite( p_mux->p_access, p_ps );
  454.         /* Increase counter */
  455.         p_sys->i_pes_count++;
  456.     }
  457.     return VLC_SUCCESS;
  458. }
  459. /*****************************************************************************
  460.  *
  461.  *****************************************************************************/
  462. static void StreamIdInit( bool *id, int i_range )
  463. {
  464.     int i;
  465.     for( i = 0; i < i_range; i++ )
  466.     {
  467.         id[i] = true;
  468.     }
  469. }
  470. static int StreamIdGet( bool *id, int i_id_min, int i_id_max )
  471. {
  472.     int i;
  473.     for( i = 0; i <= i_id_max - i_id_min; i++ )
  474.     {
  475.         if( id[i] )
  476.         {
  477.             id[i] = false;
  478.             return i_id_min + i;
  479.         }
  480.     }
  481.     return -1;
  482. }
  483. static void StreamIdRelease( bool *id, int i_id_min, int i_id )
  484. {
  485.     id[i_id - i_id_min] = true;
  486. }
  487. static void MuxWritePackHeader( sout_mux_t *p_mux, block_t **p_buf,
  488.                                 mtime_t i_dts )
  489. {
  490.     sout_mux_sys_t *p_sys = p_mux->p_sys;
  491.     bits_buffer_t bits;
  492.     block_t *p_hdr;
  493.     mtime_t i_scr;
  494.     int i_mux_rate;
  495.     i_scr = (i_dts - p_sys->i_dts_delay) * 9 / 100;
  496.     p_hdr = block_New( p_mux, 18 );
  497.     p_hdr->i_pts = p_hdr->i_dts = i_dts;
  498.     bits_initwrite( &bits, 14, p_hdr->p_buffer );
  499.     bits_write( &bits, 32, 0x01ba );
  500.     /* The spec specifies that the mux rate must be rounded upwards */
  501.     i_mux_rate = (p_sys->i_instant_bitrate + 8 * 50 - 1 ) / (8 * 50);
  502.     if( p_sys->b_mpeg2 )
  503.     {
  504.         bits_write( &bits, 2, 0x01 );
  505.     }
  506.     else
  507.     {
  508.         bits_write( &bits, 4, 0x02 );
  509.     }
  510.     bits_write( &bits, 3, ( i_scr >> 30 )&0x07 );
  511.     bits_write( &bits, 1,  1 ); // marker
  512.     bits_write( &bits, 15, ( i_scr >> 15 )&0x7fff );
  513.     bits_write( &bits, 1,  1 ); // marker
  514.     bits_write( &bits, 15, i_scr&0x7fff );
  515.     bits_write( &bits, 1,  1 ); // marker
  516.     if( p_sys->b_mpeg2 )
  517.     {
  518.         bits_write( &bits, 9,  0 ); // src extension
  519.     }
  520.     bits_write( &bits, 1,  1 );     // marker
  521.     bits_write( &bits, 22, i_mux_rate);
  522.     bits_write( &bits, 1,  1 );     // marker
  523.     if( p_sys->b_mpeg2 )
  524.     {
  525.         bits_write( &bits, 1,  1 );     // marker
  526.         bits_write( &bits, 5,  0x1f );  // reserved
  527.         bits_write( &bits, 3,  0 );     // stuffing bytes
  528.     }
  529.     p_hdr->i_buffer = p_sys->b_mpeg2 ? 14: 12;
  530.     block_ChainAppend( p_buf, p_hdr );
  531. }
  532. static void MuxWriteSystemHeader( sout_mux_t *p_mux, block_t **p_buf,
  533.                                   mtime_t i_dts )
  534. {
  535.     sout_mux_sys_t  *p_sys = p_mux->p_sys;
  536.     block_t   *p_hdr;
  537.     bits_buffer_t   bits;
  538.     bool      b_private;
  539.     int i_rate_bound;
  540.     int             i_nb_private, i_nb_stream;
  541.     int i;
  542.     /* Count the number of private stream */
  543.     for( i = 0, i_nb_private = 0; i < p_mux->i_nb_inputs; i++ )
  544.     {
  545.         ps_stream_t *p_stream;
  546.         p_stream = (ps_stream_t*)p_mux->pp_inputs[i]->p_sys;
  547.         if( ( p_stream->i_stream_id&0xff00 ) == 0xbd00 )
  548.         {
  549.             i_nb_private++;
  550.         }
  551.     }
  552.     /* Private stream are declared only one time */
  553.     i_nb_stream = p_mux->i_nb_inputs -
  554.         ( i_nb_private > 0 ? i_nb_private - 1 : 0 );
  555.     p_hdr = block_New( p_mux, 12 + i_nb_stream * 3 );
  556.     p_hdr->i_dts = p_hdr->i_pts = i_dts;
  557.     /* The spec specifies that the reported rate_bound must be upper limit */
  558.     i_rate_bound = (p_sys->i_rate_bound);
  559.     bits_initwrite( &bits, 12 + i_nb_stream * 3, p_hdr->p_buffer );
  560.     bits_write( &bits, 32, 0x01bb );
  561.     bits_write( &bits, 16, 12 - 6 + i_nb_stream * 3 );
  562.     bits_write( &bits, 1,  1 ); // marker bit
  563.     bits_write( &bits, 22, i_rate_bound);
  564.     bits_write( &bits, 1,  1 ); // marker bit
  565.     bits_write( &bits, 6,  p_sys->i_audio_bound );
  566.     bits_write( &bits, 1,  0 ); // fixed flag
  567.     bits_write( &bits, 1,  0 ); // CSPS flag
  568.     bits_write( &bits, 1,  0 ); // system audio lock flag
  569.     bits_write( &bits, 1,  0 ); // system video lock flag
  570.     bits_write( &bits, 1,  1 ); // marker bit
  571.     bits_write( &bits, 5,  p_sys->i_video_bound );
  572.     bits_write( &bits, 1,  1 ); // packet rate restriction flag (1 for mpeg1)
  573.     bits_write( &bits, 7,  0xff ); // reserved bits
  574.     /* stream_id table */
  575.     for( i = 0, b_private = false; i < p_mux->i_nb_inputs; i++ )
  576.     {
  577.         sout_input_t *p_input;
  578.         ps_stream_t *p_stream;
  579.         p_input = p_mux->pp_inputs[i];
  580.         p_stream = (ps_stream_t *)p_input->p_sys;
  581.         if( ( p_stream->i_stream_id&0xff00 ) == 0xbd00 )
  582.         {
  583.             if( b_private )
  584.             {
  585.                 continue;
  586.             }
  587.             b_private = true;
  588.             /* Write stream id */
  589.             bits_write( &bits, 8, 0xbd );
  590.         }
  591.         else
  592.         {
  593.             /* Write stream id */
  594.             bits_write( &bits, 8, p_stream->i_stream_id&0xff );
  595.         }
  596.         bits_write( &bits, 2, 0x03 ); /* reserved */
  597.         if( p_input->p_fmt->i_cat == AUDIO_ES )
  598.         {
  599.             bits_write( &bits, 1, 0 );
  600.             bits_write( &bits, 13, p_stream->i_max_buff_size / 128 );
  601.         }
  602.         else if( p_input->p_fmt->i_cat == VIDEO_ES )
  603.         {
  604.             bits_write( &bits, 1, 1 );
  605.             bits_write( &bits, 13, p_stream->i_max_buff_size / 1024);
  606.         }
  607.         else
  608.         {
  609.             /* FIXME -- the scale of 0 means do a /128 */
  610.             bits_write( &bits, 1, 0 );
  611.             bits_write( &bits, 13, p_stream->i_max_buff_size / 128 );
  612.         }
  613.     }
  614.     block_ChainAppend( p_buf, p_hdr );
  615. }
  616. static void MuxWritePSM( sout_mux_t *p_mux, block_t **p_buf, mtime_t i_dts )
  617. {
  618.     sout_mux_sys_t *p_sys = p_mux->p_sys;
  619.     block_t *p_hdr;
  620.     bits_buffer_t bits;
  621.     int i, i_psm_size = 16, i_es_map_size = 0;
  622.     for( i = 0; i < p_mux->i_nb_inputs; i++ )
  623.     {
  624.         sout_input_t *p_input = p_mux->pp_inputs[i];
  625.         ps_stream_t *p_stream = p_input->p_sys;
  626.         i_es_map_size += 4;
  627.         if( p_stream->lang[0] != 0 ) i_es_map_size += 6;
  628.     }
  629.     i_psm_size += i_es_map_size;
  630.     p_hdr = block_New( p_mux, i_psm_size );
  631.     p_hdr->i_dts = p_hdr->i_pts = i_dts;
  632.     memset( p_hdr->p_buffer, 0, p_hdr->i_buffer );
  633.     bits_initwrite( &bits, i_psm_size, p_hdr->p_buffer );
  634.     bits_write( &bits, 32, 0x01bc );
  635.     bits_write( &bits, 16, i_psm_size - 6 );
  636.     bits_write( &bits, 1, 1 ); /* current_next_indicator */
  637.     bits_write( &bits, 2, 0xF ); /* reserved */
  638.     bits_write( &bits, 5, p_sys->i_psm_version );
  639.     bits_write( &bits, 7, 0xFF ); /* reserved */
  640.     bits_write( &bits, 1, 1 ); /* marker */
  641.     bits_write( &bits, 16, 0 ); /* program_stream_info_length */
  642.     /* empty */
  643.     bits_write( &bits, 16, i_es_map_size ); /* elementary_stream_map_length */
  644.     for( i = 0; i < p_mux->i_nb_inputs; i++ )
  645.     {
  646.         sout_input_t *p_input = p_mux->pp_inputs[i];
  647.         ps_stream_t *p_stream = p_input->p_sys;
  648.         bits_write( &bits, 8, p_stream->i_stream_type ); /* stream_type */
  649.         bits_write( &bits, 8, p_stream->i_stream_id ); /* elementary_stream_id */
  650.         /* ISO639 language descriptor */
  651.         if( p_stream->lang[0] != 0 )
  652.         {
  653.             bits_write( &bits, 16, 6 ); /* elementary_stream_info_length */
  654.             bits_write( &bits, 8, 0x0a ); /* descriptor_tag */
  655.             bits_write( &bits, 8, 4 ); /* descriptor_length */
  656.             bits_write( &bits, 8, p_stream->lang[0] );
  657.             bits_write( &bits, 8, p_stream->lang[1] );
  658.             bits_write( &bits, 8, p_stream->lang[2] );
  659.             bits_write( &bits, 8, 0 ); /* audio type: 0x00 undefined */
  660.         }
  661.         else
  662.         {
  663.             bits_write( &bits, 16, 0 ); /* elementary_stream_info_length */
  664.         }
  665.     }
  666.     /* CRC32 */
  667.     {
  668.         uint32_t i_crc = 0xffffffff;
  669.         for( i = 0; (size_t)i < p_hdr->i_buffer; i++ )
  670.         i_crc = (i_crc << 8) ^
  671.             p_sys->crc32_table[((i_crc >> 24) ^ p_hdr->p_buffer[i]) & 0xff];
  672.         bits_write( &bits, 32, i_crc );
  673.     }
  674.     block_ChainAppend( p_buf, p_hdr );
  675. }
  676. /*
  677.  * Find stream to be muxed.
  678.  */
  679. static int MuxGetStream( sout_mux_t *p_mux, int *pi_stream, mtime_t *pi_dts )
  680. {
  681.     mtime_t i_dts;
  682.     int     i_stream, i;
  683.     for( i = 0, i_dts = 0, i_stream = -1; i < p_mux->i_nb_inputs; i++ )
  684.     {
  685.         sout_input_t *p_input = p_mux->pp_inputs[i];
  686.         block_t *p_data;
  687.         if( block_FifoCount( p_input->p_fifo ) <= 0 )
  688.         {
  689.             if( p_input->p_fmt->i_cat == AUDIO_ES ||
  690.                 p_input->p_fmt->i_cat == VIDEO_ES )
  691.             {
  692.                 /* We need that audio+video fifo contain at least 1 packet */
  693.                 return VLC_EGENERIC;
  694.             }
  695.             /* SPU */
  696.             continue;
  697.         }
  698.         p_data = block_FifoShow( p_input->p_fifo );
  699.         if( i_stream == -1 || p_data->i_dts < i_dts )
  700.         {
  701.             i_stream = i;
  702.             i_dts    = p_data->i_dts;
  703.         }
  704.     }
  705.     *pi_stream = i_stream;
  706.     *pi_dts = i_dts;
  707.     return VLC_SUCCESS;
  708. }