00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <stdlib.h>
00031
00032 #include <vlc/vlc.h>
00033 #include <vlc/input.h>
00034 #include <vlc/sout.h>
00035
00036 #include "codecs.h"
00037 #include "bits.h"
00038 #include "pes.h"
00039
00040 #include "iso_lang.h"
00041
00042
00043
00044
00045 #define DTS_TEXT N_("DTS delay (ms)")
00046 #define DTS_LONGTEXT N_("This option will delay the DTS (decoding time " \
00047 "stamps) and PTS (presentation timestamps) of the data in the " \
00048 "stream, compared to the SCRs. This allows for some buffering inside " \
00049 "the client decoder.")
00050
00051 #define PES_SIZE_TEXT N_("PES maximum size")
00052 #define PES_SIZE_LONGTEXT N_("This option will set the maximum allowed PES "\
00053 "size when producing the MPEG PS stream.")
00054
00055 static int Open ( vlc_object_t * );
00056 static void Close ( vlc_object_t * );
00057
00058 #define SOUT_CFG_PREFIX "sout-ps-"
00059
00060 vlc_module_begin();
00061 set_description( _("PS muxer") );
00062 set_shortname( "MPEG-PS" );
00063 set_category( CAT_SOUT );
00064 set_subcategory( SUBCAT_SOUT_MUX );
00065 set_capability( "sout mux", 50 );
00066 add_shortcut( "ps" );
00067 add_shortcut( "mpeg1" );
00068 add_shortcut( "dvd" );
00069 set_callbacks( Open, Close );
00070
00071 add_integer( SOUT_CFG_PREFIX "dts-delay", 200, NULL, DTS_TEXT,
00072 DTS_LONGTEXT, VLC_TRUE );
00073 add_integer( SOUT_CFG_PREFIX "pes-max-size", PES_PAYLOAD_SIZE_MAX, NULL,
00074 PES_SIZE_TEXT, PES_SIZE_LONGTEXT, VLC_TRUE );
00075 vlc_module_end();
00076
00077
00078
00079
00080 static int Control ( sout_mux_t *, int, va_list );
00081 static int AddStream( sout_mux_t *, sout_input_t * );
00082 static int DelStream( sout_mux_t *, sout_input_t * );
00083 static int Mux ( sout_mux_t * );
00084
00085
00086
00087
00088 static int MuxGetStream ( sout_mux_t *, int *, mtime_t * );
00089
00090 static void MuxWritePackHeader ( sout_mux_t *, block_t **, mtime_t );
00091 static void MuxWriteSystemHeader( sout_mux_t *, block_t **, mtime_t );
00092 static void MuxWritePSM ( sout_mux_t *, block_t **, mtime_t );
00093
00094 static void StreamIdInit ( vlc_bool_t *id, int i_range );
00095 static int StreamIdGet ( vlc_bool_t *id, int i_id_min, int i_id_max );
00096 static void StreamIdRelease ( vlc_bool_t *id, int i_id_min, int i_id );
00097
00098 typedef struct ps_stream_s
00099 {
00100 int i_stream_id;
00101 int i_stream_type;
00102 int i_max_buff_size;
00103
00104
00105 uint8_t lang[3];
00106
00107 } ps_stream_t;
00108
00109 struct sout_mux_sys_t
00110 {
00111
00112 vlc_bool_t stream_id_mpga[16];
00113 vlc_bool_t stream_id_mpgv[16];
00114 vlc_bool_t stream_id_a52[8];
00115 vlc_bool_t stream_id_spu[32];
00116 vlc_bool_t stream_id_dts[8];
00117 vlc_bool_t stream_id_lpcm[16];
00118
00119 int i_audio_bound;
00120 int i_video_bound;
00121 int i_pes_count;
00122 int i_system_header;
00123 int i_dts_delay;
00124 int i_rate_bound;
00125
00126 int64_t i_instant_bitrate;
00127 int64_t i_instant_size;
00128 int64_t i_instant_dts;
00129
00130 vlc_bool_t b_mpeg2;
00131
00132 int i_pes_max_size;
00133
00134 int i_psm_version;
00135 uint32_t crc32_table[256];
00136 };
00137
00138 static const char *ppsz_sout_options[] = {
00139 "dts-delay", "pes-max-size", NULL
00140 };
00141
00142
00143
00144
00145 static int Open( vlc_object_t *p_this )
00146 {
00147 sout_mux_t *p_mux = (sout_mux_t*)p_this;
00148 sout_mux_sys_t *p_sys;
00149 vlc_value_t val;
00150
00151 msg_Info( p_mux, "Open" );
00152 sout_CfgParse( p_mux, SOUT_CFG_PREFIX, ppsz_sout_options, p_mux->p_cfg );
00153
00154 p_mux->pf_control = Control;
00155 p_mux->pf_addstream = AddStream;
00156 p_mux->pf_delstream = DelStream;
00157 p_mux->pf_mux = Mux;
00158 p_mux->p_sys = p_sys = malloc( sizeof( sout_mux_sys_t ) );
00159
00160
00161 StreamIdInit( p_sys->stream_id_a52, 8 );
00162 StreamIdInit( p_sys->stream_id_dts, 8 );
00163 StreamIdInit( p_sys->stream_id_mpga, 16 );
00164 StreamIdInit( p_sys->stream_id_mpgv, 16 );
00165 StreamIdInit( p_sys->stream_id_lpcm, 16 );
00166 StreamIdInit( p_sys->stream_id_spu, 32 );
00167
00168 p_sys->i_audio_bound = 0;
00169 p_sys->i_video_bound = 0;
00170 p_sys->i_system_header = 0;
00171 p_sys->i_pes_count = 0;
00172
00173 p_sys->i_psm_version = 0;
00174
00175 p_sys->i_instant_bitrate = 0;
00176 p_sys->i_instant_size = 0;
00177 p_sys->i_instant_dts = 0;
00178 p_sys->i_rate_bound = 0;
00179 p_sys->b_mpeg2 = !(p_mux->psz_mux && !strcmp( p_mux->psz_mux, "mpeg1" ));
00180
00181 var_Get( p_mux, SOUT_CFG_PREFIX "dts-delay", &val );
00182 p_sys->i_dts_delay = (int64_t)val.i_int * 1000;
00183
00184 var_Get( p_mux, SOUT_CFG_PREFIX "pes-max-size", &val );
00185 p_sys->i_pes_max_size = (int64_t)val.i_int;
00186
00187
00188 if( p_sys->b_mpeg2 )
00189 {
00190 uint32_t i, j, k;
00191
00192 for( i = 0; i < 256; i++ )
00193 {
00194 k = 0;
00195 for( j = (i << 24) | 0x800000; j != 0x80000000; j <<= 1 )
00196 k = (k << 1) ^ (((k ^ j) & 0x80000000) ? 0x04c11db7 : 0);
00197
00198 p_sys->crc32_table[i] = k;
00199 }
00200 }
00201
00202 return VLC_SUCCESS;
00203 }
00204
00205
00206
00207
00208 static void Close( vlc_object_t * p_this )
00209 {
00210 sout_mux_t *p_mux = (sout_mux_t*)p_this;
00211 sout_mux_sys_t *p_sys = p_mux->p_sys;
00212
00213 block_t *p_end;
00214
00215 msg_Info( p_mux, "Close" );
00216
00217 p_end = block_New( p_mux, 4 );
00218 p_end->p_buffer[0] = 0x00; p_end->p_buffer[1] = 0x00;
00219 p_end->p_buffer[2] = 0x01; p_end->p_buffer[3] = 0xb9;
00220
00221 sout_AccessOutWrite( p_mux->p_access, p_end );
00222
00223 free( p_sys );
00224 }
00225
00226
00227
00228
00229 static int Control( sout_mux_t *p_mux, int i_query, va_list args )
00230 {
00231 vlc_bool_t *pb_bool;
00232 char **ppsz;
00233
00234 switch( i_query )
00235 {
00236 case MUX_CAN_ADD_STREAM_WHILE_MUXING:
00237 pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t * );
00238 *pb_bool = VLC_TRUE;
00239 return VLC_SUCCESS;
00240
00241 case MUX_GET_ADD_STREAM_WAIT:
00242 pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t * );
00243 *pb_bool = VLC_FALSE;
00244 return VLC_SUCCESS;
00245
00246 case MUX_GET_MIME:
00247 ppsz = (char**)va_arg( args, char ** );
00248 *ppsz = strdup( "video/mpeg" );
00249 return VLC_SUCCESS;
00250
00251 default:
00252 return VLC_EGENERIC;
00253 }
00254 }
00255
00256
00257
00258
00259 static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
00260 {
00261 sout_mux_sys_t *p_sys = p_mux->p_sys;
00262 ps_stream_t *p_stream;
00263
00264
00265 msg_Dbg( p_mux, "adding input codec=%4.4s",
00266 (char*)&p_input->p_fmt->i_codec );
00267
00268 p_input->p_sys = p_stream = malloc( sizeof( ps_stream_t ) );
00269 p_stream->i_stream_type = 0x81;
00270
00271
00272 switch( p_input->p_fmt->i_codec )
00273 {
00274 case VLC_FOURCC( 'm', 'p', '1', 'v' ):
00275 p_stream->i_stream_id =
00276 StreamIdGet( p_sys->stream_id_mpgv, 0xe0, 0xef );
00277 p_stream->i_stream_type = 0x01;
00278 break;
00279 case VLC_FOURCC( 'm', 'p', '2', 'v' ):
00280 case VLC_FOURCC( 'm', 'p', 'g', 'v' ):
00281 p_stream->i_stream_id =
00282 StreamIdGet( p_sys->stream_id_mpgv, 0xe0, 0xef );
00283 p_stream->i_stream_type = 0x02;
00284 break;
00285 case VLC_FOURCC( 'm', 'p', '4', 'v' ):
00286 p_stream->i_stream_id =
00287 StreamIdGet( p_sys->stream_id_mpgv, 0xe0, 0xef );
00288 p_stream->i_stream_type = 0x10;
00289 break;
00290 case VLC_FOURCC( 'h', '2', '6', '4' ):
00291 p_stream->i_stream_id =
00292 StreamIdGet( p_sys->stream_id_mpgv, 0xe0, 0xef );
00293 p_stream->i_stream_type = 0x1b;
00294 break;
00295 case VLC_FOURCC( 'l', 'p', 'c', 'm' ):
00296 p_stream->i_stream_id =
00297 0xbd00 | StreamIdGet( p_sys->stream_id_lpcm, 0xa0, 0xaf );
00298 break;
00299 case VLC_FOURCC( 'd', 't', 's', ' ' ):
00300 p_stream->i_stream_id =
00301 0xbd00 | StreamIdGet( p_sys->stream_id_dts, 0x88, 0x8f );
00302 break;
00303 case VLC_FOURCC( 'a', '5', '2', ' ' ):
00304 p_stream->i_stream_id =
00305 0xbd00 | StreamIdGet( p_sys->stream_id_a52, 0x80, 0x87 );
00306 break;
00307 case VLC_FOURCC( 'm', 'p', 'g', 'a' ):
00308 p_stream->i_stream_id =
00309 StreamIdGet( p_sys->stream_id_mpga, 0xc0, 0xcf );
00310 p_stream->i_stream_type = 0x03;
00311 break;
00312 case VLC_FOURCC( 'm', 'p', '4', 'a' ):
00313 p_stream->i_stream_id =
00314 StreamIdGet( p_sys->stream_id_mpga, 0xc0, 0xcf );
00315 p_stream->i_stream_type = 0x0f;
00316 break;
00317 case VLC_FOURCC( 's', 'p', 'u', ' ' ):
00318 p_stream->i_stream_id =
00319 0xbd00 | StreamIdGet( p_sys->stream_id_spu, 0x20, 0x3f );
00320 break;
00321 default:
00322 goto error;
00323 }
00324
00325 if( p_stream->i_stream_id < 0 ) goto error;
00326
00327 if( p_input->p_fmt->i_cat == AUDIO_ES )
00328 {
00329 p_sys->i_audio_bound++;
00330 p_stream->i_max_buff_size = 4 * 1024;
00331 }
00332 else if( p_input->p_fmt->i_cat == VIDEO_ES )
00333 {
00334 p_sys->i_video_bound++;
00335 p_stream->i_max_buff_size = 400 * 1024;
00336
00337 }
00338 else
00339 {
00340 p_stream->i_max_buff_size = 4 * 1024;
00341 }
00342
00343
00344 p_sys->i_instant_bitrate += p_input->p_fmt->i_bitrate + 1000;
00345
00346
00347
00348 p_sys->i_rate_bound += p_input->p_fmt->i_bitrate * 2 / (8 * 50);
00349 p_sys->i_psm_version++;
00350
00351 p_stream->lang[0] = p_stream->lang[1] = p_stream->lang[2] = 0;
00352 if( p_input->p_fmt->psz_language )
00353 {
00354 char *psz = p_input->p_fmt->psz_language;
00355 const iso639_lang_t *pl = NULL;
00356
00357 if( strlen( psz ) == 2 )
00358 {
00359 pl = GetLang_1( psz );
00360 }
00361 else if( strlen( psz ) == 3 )
00362 {
00363 pl = GetLang_2B( psz );
00364 if( !strcmp( pl->psz_iso639_1, "??" ) )
00365 {
00366 pl = GetLang_2T( psz );
00367 }
00368 }
00369 if( pl && strcmp( pl->psz_iso639_1, "??" ) )
00370 {
00371 p_stream->lang[0] = pl->psz_iso639_2T[0];
00372 p_stream->lang[1] = pl->psz_iso639_2T[1];
00373 p_stream->lang[2] = pl->psz_iso639_2T[2];
00374
00375 msg_Dbg( p_mux, " - lang=%c%c%c",
00376 p_stream->lang[0], p_stream->lang[1], p_stream->lang[2] );
00377 }
00378 }
00379 return VLC_SUCCESS;
00380
00381 error:
00382 free( p_stream );
00383 return VLC_EGENERIC;
00384 }
00385
00386
00387
00388
00389 static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
00390 {
00391 sout_mux_sys_t *p_sys = p_mux->p_sys;
00392 ps_stream_t *p_stream =(ps_stream_t*)p_input->p_sys;
00393
00394 msg_Dbg( p_mux, "removing input" );
00395 switch( p_input->p_fmt->i_codec )
00396 {
00397 case VLC_FOURCC( 'm', 'p', 'g', 'v' ):
00398 StreamIdRelease( p_sys->stream_id_mpgv, 0xe0,
00399 p_stream->i_stream_id );
00400 break;
00401 case VLC_FOURCC( 'l', 'p', 'c', 'm' ):
00402 StreamIdRelease( p_sys->stream_id_lpcm, 0xa0,
00403 p_stream->i_stream_id&0xff );
00404 break;
00405 case VLC_FOURCC( 'd', 't', 's', ' ' ):
00406 StreamIdRelease( p_sys->stream_id_dts, 0x88,
00407 p_stream->i_stream_id&0xff );
00408 break;
00409 case VLC_FOURCC( 'a', '5', '2', ' ' ):
00410 StreamIdRelease( p_sys->stream_id_a52, 0x80,
00411 p_stream->i_stream_id&0xff );
00412 break;
00413 case VLC_FOURCC( 'm', 'p', 'g', 'a' ):
00414 StreamIdRelease( p_sys->stream_id_mpga, 0xc0,
00415 p_stream->i_stream_id );
00416 break;
00417 case VLC_FOURCC( 's', 'p', 'u', ' ' ):
00418 StreamIdRelease( p_sys->stream_id_spu, 0x20,
00419 p_stream->i_stream_id&0xff );
00420 break;
00421 default:
00422
00423 break;
00424 }
00425
00426 if( p_input->p_fmt->i_cat == AUDIO_ES )
00427 {
00428 p_sys->i_audio_bound--;
00429 }
00430 else if( p_input->p_fmt->i_cat == VIDEO_ES )
00431 {
00432 p_sys->i_video_bound--;
00433 }
00434
00435
00436 p_sys->i_instant_bitrate -= (p_input->p_fmt->i_bitrate + 1000);
00437
00438 p_sys->i_rate_bound -= (p_input->p_fmt->i_bitrate * 2)/(8 * 50);
00439
00440 p_sys->i_psm_version++;
00441
00442 free( p_stream );
00443 return VLC_SUCCESS;
00444 }
00445
00446
00447
00448
00449 static int Mux( sout_mux_t *p_mux )
00450 {
00451 sout_mux_sys_t *p_sys = p_mux->p_sys;
00452
00453 for( ;; )
00454 {
00455 sout_input_t *p_input;
00456 ps_stream_t *p_stream;
00457
00458 block_t *p_ps, *p_data;
00459
00460 mtime_t i_dts;
00461 int i_stream;
00462
00463
00464 if( MuxGetStream( p_mux, &i_stream, &i_dts ) )
00465 {
00466 return VLC_SUCCESS;
00467 }
00468
00469 p_input = p_mux->pp_inputs[i_stream];
00470 p_stream = (ps_stream_t*)p_input->p_sys;
00471 p_ps = NULL;
00472
00473
00474 if( p_sys->i_pes_count % 30 == 0)
00475 {
00476
00477 if( p_sys->i_instant_size &&
00478 i_dts - p_sys->i_instant_dts > 1000000 )
00479 {
00480 int64_t i_instant_bitrate = p_sys->i_instant_size * 8000000 /
00481 ( i_dts - p_sys->i_instant_dts );
00482
00483 p_sys->i_instant_bitrate += i_instant_bitrate;
00484 p_sys->i_instant_bitrate /= 2;
00485
00486 p_sys->i_instant_size = 0;
00487 p_sys->i_instant_dts = i_dts;
00488 }
00489 else if( !p_sys->i_instant_size )
00490 {
00491 p_sys->i_instant_dts = i_dts;
00492 }
00493
00494 MuxWritePackHeader( p_mux, &p_ps, i_dts );
00495 }
00496
00497
00498 if( p_sys->i_pes_count % 300 == 0 )
00499 {
00500 block_t *p_pk;
00501
00502 MuxWriteSystemHeader( p_mux, &p_ps, i_dts );
00503
00504
00505 for( p_pk = p_ps; p_pk != NULL; p_pk = p_pk->p_next )
00506 {
00507 p_pk->i_flags |= BLOCK_FLAG_HEADER;
00508 }
00509 }
00510
00511
00512 if( p_sys->b_mpeg2 && p_sys->i_pes_count % 300 == 0 )
00513 {
00514 MuxWritePSM( p_mux, &p_ps, i_dts );
00515 }
00516
00517
00518 p_data = block_FifoGet( p_input->p_fifo );
00519 E_( EStoPES )( p_mux->p_sout, &p_data, p_data,
00520 p_input->p_fmt, p_stream->i_stream_id,
00521 p_sys->b_mpeg2, 0, 0, p_sys->i_pes_max_size );
00522
00523 block_ChainAppend( &p_ps, p_data );
00524
00525
00526 for( p_data = p_ps; p_data; p_data = p_data->p_next )
00527 {
00528 p_sys->i_instant_size += p_data->i_buffer;
00529 }
00530
00531 sout_AccessOutWrite( p_mux->p_access, p_ps );
00532
00533
00534 p_sys->i_pes_count++;
00535 }
00536
00537 return VLC_SUCCESS;
00538 }
00539
00540
00541
00542
00543 static void StreamIdInit( vlc_bool_t *id, int i_range )
00544 {
00545 int i;
00546
00547 for( i = 0; i < i_range; i++ )
00548 {
00549 id[i] = VLC_TRUE;
00550 }
00551 }
00552 static int StreamIdGet( vlc_bool_t *id, int i_id_min, int i_id_max )
00553 {
00554 int i;
00555
00556 for( i = 0; i <= i_id_max - i_id_min; i++ )
00557 {
00558 if( id[i] )
00559 {
00560 id[i] = VLC_FALSE;
00561
00562 return i_id_min + i;
00563 }
00564 }
00565 return -1;
00566 }
00567 static void StreamIdRelease( vlc_bool_t *id, int i_id_min, int i_id )
00568 {
00569 id[i_id - i_id_min] = VLC_TRUE;
00570 }
00571
00572 static void MuxWritePackHeader( sout_mux_t *p_mux, block_t **p_buf,
00573 mtime_t i_dts )
00574 {
00575 sout_mux_sys_t *p_sys = p_mux->p_sys;
00576 bits_buffer_t bits;
00577 block_t *p_hdr;
00578 mtime_t i_scr;
00579 int i_mux_rate;
00580
00581 i_scr = (i_dts - p_sys->i_dts_delay) * 9 / 100;
00582
00583 p_hdr = block_New( p_mux, 18 );
00584 p_hdr->i_pts = p_hdr->i_dts = i_dts;
00585 bits_initwrite( &bits, 14, p_hdr->p_buffer );
00586 bits_write( &bits, 32, 0x01ba );
00587
00588
00589 i_mux_rate = (p_sys->i_instant_bitrate + 8 * 50 - 1 ) / (8 * 50);
00590
00591 if( p_sys->b_mpeg2 )
00592 {
00593 bits_write( &bits, 2, 0x01 );
00594 }
00595 else
00596 {
00597 bits_write( &bits, 4, 0x02 );
00598 }
00599
00600 bits_write( &bits, 3, ( i_scr >> 30 )&0x07 );
00601 bits_write( &bits, 1, 1 );
00602 bits_write( &bits, 15, ( i_scr >> 15 )&0x7fff );
00603 bits_write( &bits, 1, 1 );
00604 bits_write( &bits, 15, i_scr&0x7fff );
00605 bits_write( &bits, 1, 1 );
00606
00607 if( p_sys->b_mpeg2 )
00608 {
00609 bits_write( &bits, 9, 0 );
00610 }
00611 bits_write( &bits, 1, 1 );
00612
00613 bits_write( &bits, 22, i_mux_rate);
00614 bits_write( &bits, 1, 1 );
00615
00616 if( p_sys->b_mpeg2 )
00617 {
00618 bits_write( &bits, 1, 1 );
00619 bits_write( &bits, 5, 0x1f );
00620 bits_write( &bits, 3, 0 );
00621 }
00622
00623 p_hdr->i_buffer = p_sys->b_mpeg2 ? 14: 12;
00624
00625 block_ChainAppend( p_buf, p_hdr );
00626 }
00627
00628 static void MuxWriteSystemHeader( sout_mux_t *p_mux, block_t **p_buf,
00629 mtime_t i_dts )
00630 {
00631 sout_mux_sys_t *p_sys = p_mux->p_sys;
00632 block_t *p_hdr;
00633 bits_buffer_t bits;
00634 vlc_bool_t b_private;
00635 int i_rate_bound;
00636
00637 int i_nb_private, i_nb_stream;
00638 int i;
00639
00640
00641 for( i = 0, i_nb_private = 0; i < p_mux->i_nb_inputs; i++ )
00642 {
00643 ps_stream_t *p_stream;
00644
00645 p_stream = (ps_stream_t*)p_mux->pp_inputs[i]->p_sys;
00646
00647 if( ( p_stream->i_stream_id&0xff00 ) == 0xbd00 )
00648 {
00649 i_nb_private++;
00650 }
00651 }
00652
00653
00654 i_nb_stream = p_mux->i_nb_inputs -
00655 ( i_nb_private > 0 ? i_nb_private - 1 : 0 );
00656
00657 p_hdr = block_New( p_mux, 12 + i_nb_stream * 3 );
00658 p_hdr->i_dts = p_hdr->i_pts = i_dts;
00659
00660
00661 i_rate_bound = (p_sys->i_rate_bound);
00662
00663 bits_initwrite( &bits, 12 + i_nb_stream * 3, p_hdr->p_buffer );
00664 bits_write( &bits, 32, 0x01bb );
00665 bits_write( &bits, 16, 12 - 6 + i_nb_stream * 3 );
00666 bits_write( &bits, 1, 1 );
00667 bits_write( &bits, 22, i_rate_bound);
00668 bits_write( &bits, 1, 1 );
00669
00670 bits_write( &bits, 6, p_sys->i_audio_bound );
00671 bits_write( &bits, 1, 0 );
00672 bits_write( &bits, 1, 0 );
00673 bits_write( &bits, 1, 0 );
00674 bits_write( &bits, 1, 0 );
00675
00676 bits_write( &bits, 1, 1 );
00677
00678 bits_write( &bits, 5, p_sys->i_video_bound );
00679 bits_write( &bits, 1, 1 );
00680 bits_write( &bits, 7, 0xff );
00681
00682
00683 for( i = 0, b_private = VLC_FALSE; i < p_mux->i_nb_inputs; i++ )
00684 {
00685 sout_input_t *p_input;
00686 ps_stream_t *p_stream;
00687
00688 p_input = p_mux->pp_inputs[i];
00689 p_stream = (ps_stream_t *)p_input->p_sys;
00690
00691 if( ( p_stream->i_stream_id&0xff00 ) == 0xbd00 )
00692 {
00693 if( b_private )
00694 {
00695 continue;
00696 }
00697 b_private = VLC_TRUE;
00698
00699 bits_write( &bits, 8, 0xbd );
00700 }
00701 else
00702 {
00703
00704 bits_write( &bits, 8, p_stream->i_stream_id&0xff );
00705 }
00706
00707 bits_write( &bits, 2, 0x03 );
00708 if( p_input->p_fmt->i_cat == AUDIO_ES )
00709 {
00710 bits_write( &bits, 1, 0 );
00711 bits_write( &bits, 13, p_stream->i_max_buff_size / 128 );
00712 }
00713 else if( p_input->p_fmt->i_cat == VIDEO_ES )
00714 {
00715 bits_write( &bits, 1, 1 );
00716 bits_write( &bits, 13, p_stream->i_max_buff_size / 1024);
00717 }
00718 else
00719 {
00720
00721 bits_write( &bits, 1, 0 );
00722 bits_write( &bits, 13, p_stream->i_max_buff_size / 128 );
00723 }
00724 }
00725
00726 block_ChainAppend( p_buf, p_hdr );
00727 }
00728
00729 static void MuxWritePSM( sout_mux_t *p_mux, block_t **p_buf, mtime_t i_dts )
00730 {
00731 sout_mux_sys_t *p_sys = p_mux->p_sys;
00732 block_t *p_hdr;
00733 bits_buffer_t bits;
00734 int i, i_psm_size = 16, i_es_map_size = 0;
00735
00736 for( i = 0; i < p_mux->i_nb_inputs; i++ )
00737 {
00738 sout_input_t *p_input = p_mux->pp_inputs[i];
00739 ps_stream_t *p_stream = p_input->p_sys;
00740
00741 i_es_map_size += 4;
00742 if( p_stream->lang[0] != 0 ) i_es_map_size += 6;
00743 }
00744
00745 i_psm_size += i_es_map_size;
00746
00747 p_hdr = block_New( p_mux, i_psm_size );
00748 p_hdr->i_dts = p_hdr->i_pts = i_dts;
00749
00750 memset( p_hdr->p_buffer, 0, p_hdr->i_buffer );
00751 bits_initwrite( &bits, i_psm_size, p_hdr->p_buffer );
00752 bits_write( &bits, 32, 0x01bc );
00753 bits_write( &bits, 16, i_psm_size - 6 );
00754 bits_write( &bits, 1, 1 );
00755 bits_write( &bits, 2, 0xF );
00756 bits_write( &bits, 5, p_sys->i_psm_version );
00757 bits_write( &bits, 7, 0xFF );
00758 bits_write( &bits, 1, 1 );
00759
00760 bits_write( &bits, 16, 0 );
00761
00762
00763 bits_write( &bits, 16, i_es_map_size );
00764 for( i = 0; i < p_mux->i_nb_inputs; i++ )
00765 {
00766 sout_input_t *p_input = p_mux->pp_inputs[i];
00767 ps_stream_t *p_stream = p_input->p_sys;
00768
00769 bits_write( &bits, 8, p_stream->i_stream_type );
00770 bits_write( &bits, 8, p_stream->i_stream_id );
00771
00772
00773 if( p_stream->lang[0] != 0 )
00774 {
00775 bits_write( &bits, 16, 6 );
00776
00777 bits_write( &bits, 8, 0x0a );
00778 bits_write( &bits, 8, 4 );
00779
00780 bits_write( &bits, 8, p_stream->lang[0] );
00781 bits_write( &bits, 8, p_stream->lang[1] );
00782 bits_write( &bits, 8, p_stream->lang[2] );
00783 bits_write( &bits, 8, 0 );
00784 }
00785 else
00786 {
00787 bits_write( &bits, 16, 0 );
00788 }
00789 }
00790
00791
00792 {
00793 uint32_t i_crc = 0xffffffff;
00794 for( i = 0; i < p_hdr->i_buffer; i++ )
00795 i_crc = (i_crc << 8) ^
00796 p_sys->crc32_table[((i_crc >> 24) ^ p_hdr->p_buffer[i]) & 0xff];
00797
00798 bits_write( &bits, 32, i_crc );
00799 }
00800
00801 block_ChainAppend( p_buf, p_hdr );
00802 }
00803
00804
00805
00806
00807 static int MuxGetStream( sout_mux_t *p_mux, int *pi_stream, mtime_t *pi_dts )
00808 {
00809 mtime_t i_dts;
00810 int i_stream;
00811 int i;
00812
00813 for( i = 0, i_dts = 0, i_stream = -1; i < p_mux->i_nb_inputs; i++ )
00814 {
00815 sout_input_t *p_input = p_mux->pp_inputs[i];
00816 block_t *p_data;
00817
00818 if( p_input->p_fifo->i_depth <= 0 )
00819 {
00820 if( p_input->p_fmt->i_cat == AUDIO_ES ||
00821 p_input->p_fmt->i_cat == VIDEO_ES )
00822 {
00823
00824 return VLC_EGENERIC;
00825 }
00826
00827
00828 continue;
00829 }
00830
00831 p_data = block_FifoShow( p_input->p_fifo );
00832 if( i_stream == -1 || p_data->i_dts < i_dts )
00833 {
00834 i_stream = i;
00835 i_dts = p_data->i_dts;
00836 }
00837 }
00838
00839 *pi_stream = i_stream;
00840 *pi_dts = i_dts;
00841
00842 return VLC_SUCCESS;
00843 }