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 "iso_lang.h"
00037
00038 #include "bits.h"
00039 #include "pes.h"
00040 #include "csa.h"
00041
00042 #ifdef HAVE_DVBPSI_DR_H
00043 # include <dvbpsi/dvbpsi.h>
00044 # include <dvbpsi/demux.h>
00045 # include <dvbpsi/descriptor.h>
00046 # include <dvbpsi/pat.h>
00047 # include <dvbpsi/pmt.h>
00048 # include <dvbpsi/sdt.h>
00049 # include <dvbpsi/dr.h>
00050 # include <dvbpsi/psi.h>
00051 #else
00052 # include "dvbpsi.h"
00053 # include "demux.h"
00054 # include "descriptor.h"
00055 # include "tables/pat.h"
00056 # include "tables/pmt.h"
00057 # include "tables/sdt.h"
00058 # include "descriptors/dr.h"
00059 # include "psi.h"
00060 #endif
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 static int Open ( vlc_object_t * );
00081 static void Close ( vlc_object_t * );
00082
00083 #define VPID_TEXT N_("Video PID")
00084 #define VPID_LONGTEXT N_("Assigns a fixed PID to the video stream. The PCR " \
00085 "PID will automatically be the video.")
00086 #define APID_TEXT N_("Audio PID")
00087 #define APID_LONGTEXT N_("Assigns a fixed PID to the audio stream.")
00088 #define SPUPID_TEXT N_("SPU PID")
00089 #define SPUPID_LONGTEXT N_("Assigns a fixed PID to the SPU.")
00090 #define PMTPID_TEXT N_("PMT PID")
00091 #define PMTPID_LONGTEXT N_("Assigns a fixed PID to the PMT")
00092 #define TSID_TEXT N_("TS ID")
00093 #define TSID_LONGTEXT N_("Assigns a fixed Transport Stream ID.")
00094 #define NETID_TEXT N_("NET ID")
00095 #define NETID_LONGTEXT N_("Assigns a fixed Network ID (for SDT table)")
00096 #define PMTPROG_TEXT N_("PMT Program numbers (requires --sout-ts-es-id-pid)")
00097 #define PMTPROG_LONGTEXT N_("Assigns a program number to each PMT")
00098 #define MUXPMT_TEXT N_("Mux PMT (requires --sout-ts-es-id-pid)")
00099 #define MUXPMT_LONGTEXT N_("Defines the pids to add to each pmt." )
00100
00101 #define SDTDESC_TEXT N_("SDT Descriptors (requires --sout-ts-es-id-pid)")
00102 #define SDTDESC_LONGTEXT N_("Defines the descriptors of each SDT" )
00103
00104 #define PID_TEXT N_("Set PID to id of ES")
00105 #define PID_LONGTEXT N_("set PID to id of es")
00106
00107 #define SHAPING_TEXT N_("Shaping delay (ms)")
00108 #define SHAPING_LONGTEXT N_("If enabled, the TS muxer will cut the " \
00109 "stream in slices of the given duration, and ensure a constant bitrate " \
00110 "between the two boundaries. This avoids having huge bitrate peaks for " \
00111 "reference frames, in particular.")
00112 #define KEYF_TEXT N_("Use keyframes")
00113 #define KEYF_LONGTEXT N_("If enabled, and shaping is specified, " \
00114 "the TS muxer will place the boundaries at the end of I pictures. In " \
00115 "that case, the shaping duration given by the user is a worse case " \
00116 "used when no reference frame is available. This enhances the efficiency " \
00117 "of the shaping algorithm, since I frames are usually the biggest " \
00118 "frames in the stream.")
00119
00120 #define PCR_TEXT N_("PCR delay (ms)")
00121 #define PCR_LONGTEXT N_("This option allows you to set at which interval " \
00122 "PCRs (Program Clock Reference) will be sent. " \
00123 "This value should be below 100ms. (default is 70)")
00124
00125 #define BMIN_TEXT N_( "Minimum B (deprecated)")
00126 #define BMIN_LONGTEXT N_( "This setting is deprecated and not used anymore" )
00127
00128 #define BMAX_TEXT N_( "Maximum B (deprecated)")
00129 #define BMAX_LONGTEXT N_( "This setting is deprecated and not used anymore")
00130
00131 #define DTS_TEXT N_("DTS delay (ms)")
00132 #define DTS_LONGTEXT N_("This option will delay the DTS (decoding time " \
00133 "stamps) and PTS (presentation timestamps) of the data in the " \
00134 "stream, compared to the PCRs. This allows for some buffering inside " \
00135 "the client decoder.")
00136
00137 #define ACRYPT_TEXT N_("Crypt audio")
00138 #define ACRYPT_LONGTEXT N_("Crypt audio using CSA")
00139 #define VCRYPT_TEXT N_("Crypt video")
00140 #define VCRYPT_LONGTEXT N_("Crypt video using CSA")
00141
00142 #define CK_TEXT N_("CSA Key")
00143 #define CK_LONGTEXT N_("Defines the CSA encryption key. This must be a " \
00144 "16 char string (8 hexadecimal bytes).")
00145
00146 #define CPKT_TEXT N_("Packet size in bytes to encrypt")
00147 #define CPKT_LONGTEXT N_("Specify the size of the TS packet to encrypt. " \
00148 "The encryption routines subtract the TS-header from the value before " \
00149 "encrypting. " )
00150
00151 #define SOUT_CFG_PREFIX "sout-ts-"
00152 #ifdef HAVE_BSEARCH
00153 # define MAX_PMT 64
00154 #else
00155 # define MAX_PMT 1
00156 #endif
00157 #define MAX_PMT_PID 64
00158
00159 vlc_module_begin();
00160 set_description( _("TS muxer (libdvbpsi)") );
00161 set_shortname( "MPEG-TS");
00162 set_category( CAT_SOUT );
00163 set_subcategory( SUBCAT_SOUT_MUX );
00164 set_capability( "sout mux", 120 );
00165 add_shortcut( "ts" );
00166
00167 add_integer( SOUT_CFG_PREFIX "pid-video", 0, NULL,VPID_TEXT, VPID_LONGTEXT,
00168 VLC_TRUE );
00169 add_integer( SOUT_CFG_PREFIX "pid-audio", 0, NULL, APID_TEXT,
00170 APID_LONGTEXT, VLC_TRUE );
00171 add_integer( SOUT_CFG_PREFIX "pid-spu", 0, NULL, SPUPID_TEXT,
00172 SPUPID_LONGTEXT, VLC_TRUE );
00173 add_integer( SOUT_CFG_PREFIX "pid-pmt", 0, NULL, PMTPID_TEXT,
00174 PMTPID_LONGTEXT, VLC_TRUE );
00175 add_integer( SOUT_CFG_PREFIX "tsid", 0, NULL, TSID_TEXT,
00176 TSID_LONGTEXT, VLC_TRUE );
00177 #ifdef HAVE_DVBPSI_SDT
00178 add_integer( SOUT_CFG_PREFIX "netid", 0, NULL, NETID_TEXT,
00179 NETID_LONGTEXT, VLC_TRUE );
00180 #endif
00181 add_string( SOUT_CFG_PREFIX "program-pmt", NULL, NULL, PMTPROG_TEXT,
00182 PMTPROG_LONGTEXT, VLC_TRUE );
00183 add_bool( SOUT_CFG_PREFIX "es-id-pid", 0, NULL, PID_TEXT, PID_LONGTEXT,
00184 VLC_TRUE );
00185 add_string( SOUT_CFG_PREFIX "muxpmt", NULL, NULL, MUXPMT_TEXT, MUXPMT_LONGTEXT, VLC_TRUE );
00186 #ifdef HAVE_DVBPSI_SDT
00187 add_string( SOUT_CFG_PREFIX "sdtdesc", NULL, NULL, SDTDESC_TEXT, SDTDESC_LONGTEXT, VLC_TRUE );
00188 #endif
00189
00190 add_integer( SOUT_CFG_PREFIX "shaping", 200, NULL,SHAPING_TEXT,
00191 SHAPING_LONGTEXT, VLC_TRUE );
00192 add_bool( SOUT_CFG_PREFIX "use-key-frames", VLC_FALSE, NULL, KEYF_TEXT,
00193 KEYF_LONGTEXT, VLC_TRUE );
00194
00195 add_integer( SOUT_CFG_PREFIX "pcr", 70, NULL, PCR_TEXT, PCR_LONGTEXT,
00196 VLC_TRUE );
00197 add_integer( SOUT_CFG_PREFIX "bmin", 0, NULL, BMIN_TEXT, BMIN_LONGTEXT,
00198 VLC_TRUE );
00199 add_integer( SOUT_CFG_PREFIX "bmax", 0, NULL, BMAX_TEXT, BMAX_LONGTEXT,
00200 VLC_TRUE );
00201 add_integer( SOUT_CFG_PREFIX "dts-delay", 400, NULL, DTS_TEXT,
00202 DTS_LONGTEXT, VLC_TRUE );
00203
00204 add_bool( SOUT_CFG_PREFIX "crypt-audio", VLC_TRUE, NULL, ACRYPT_TEXT,
00205 ACRYPT_LONGTEXT, VLC_TRUE );
00206 add_bool( SOUT_CFG_PREFIX "crypt-video", VLC_TRUE, NULL, VCRYPT_TEXT,
00207 VCRYPT_LONGTEXT, VLC_TRUE );
00208
00209 add_string( SOUT_CFG_PREFIX "csa-ck", NULL, NULL, CK_TEXT, CK_LONGTEXT,
00210 VLC_TRUE );
00211 add_integer( SOUT_CFG_PREFIX "csa-pkt", 188, NULL, CPKT_TEXT, CPKT_LONGTEXT, VLC_TRUE );
00212
00213 set_callbacks( Open, Close );
00214 vlc_module_end();
00215
00216
00217
00218
00219 static const char *ppsz_sout_options[] = {
00220 "pid-video", "pid-audio", "pid-spu", "pid-pmt", "tsid", "netid",
00221 "es-id-pid", "shaping", "pcr", "bmin", "bmax", "use-key-frames",
00222 "dts-delay", "csa-ck", "csa-pkt", "crypt-audio", "crypt-video",
00223 "muxpmt", "sdtdesc", "program-pmt",
00224 NULL
00225 };
00226
00227 typedef struct pmt_map_t
00228 {
00229 int i_pid;
00230 unsigned long i_prog;
00231 } pmt_map_t;
00232
00233 typedef struct sdt_desc_t
00234 {
00235 char *psz_provider;
00236 char *psz_service_name;
00237 } sdt_desc_t;
00238
00239 typedef struct
00240 {
00241 int i_depth;
00242 block_t *p_first;
00243 block_t **pp_last;
00244 } sout_buffer_chain_t;
00245
00246 static inline void BufferChainInit ( sout_buffer_chain_t *c )
00247 {
00248 c->i_depth = 0;
00249 c->p_first = NULL;
00250 c->pp_last = &c->p_first;
00251 }
00252
00253 static inline void BufferChainAppend( sout_buffer_chain_t *c, block_t *b )
00254 {
00255 *c->pp_last = b;
00256 c->i_depth++;
00257
00258 while( b->p_next )
00259 {
00260 b = b->p_next;
00261 c->i_depth++;
00262 }
00263 c->pp_last = &b->p_next;
00264 }
00265
00266 static inline block_t *BufferChainGet( sout_buffer_chain_t *c )
00267 {
00268 block_t *b = c->p_first;
00269
00270 if( b )
00271 {
00272 c->i_depth--;
00273 c->p_first = b->p_next;
00274
00275 if( c->p_first == NULL )
00276 {
00277 c->pp_last = &c->p_first;
00278 }
00279
00280 b->p_next = NULL;
00281 }
00282 return b;
00283 }
00284
00285 static inline block_t *BufferChainPeek( sout_buffer_chain_t *c )
00286 {
00287 block_t *b = c->p_first;
00288
00289 return b;
00290 }
00291
00292 static inline void BufferChainClean( sout_instance_t *p_sout,
00293 sout_buffer_chain_t *c )
00294 {
00295 block_t *b;
00296
00297 while( ( b = BufferChainGet( c ) ) )
00298 {
00299 block_Release( b );
00300 }
00301 BufferChainInit( c );
00302 }
00303
00304 typedef struct ts_stream_t
00305 {
00306 int i_pid;
00307 vlc_fourcc_t i_codec;
00308
00309 int i_stream_type;
00310 int i_stream_id;
00311 int i_continuity_counter;
00312 vlc_bool_t b_discontinuity;
00313
00314
00315 vlc_fourcc_t i_bih_codec;
00316 int i_bih_width, i_bih_height;
00317
00318
00319 int i_es_id;
00320
00321 int i_decoder_specific_info;
00322 uint8_t *p_decoder_specific_info;
00323
00324
00325 uint8_t lang[3];
00326
00327 sout_buffer_chain_t chain_pes;
00328 mtime_t i_pes_dts;
00329 mtime_t i_pes_length;
00330 int i_pes_used;
00331 vlc_bool_t b_key_frame;
00332
00333 } ts_stream_t;
00334
00335 struct sout_mux_sys_t
00336 {
00337 int i_pcr_pid;
00338 sout_input_t *p_pcr_input;
00339
00340 int i_audio_bound;
00341 int i_video_bound;
00342
00343 vlc_bool_t b_es_id_pid;
00344 vlc_bool_t b_sdt;
00345 int i_pid_video;
00346 int i_pid_audio;
00347 int i_pid_spu;
00348 int i_pid_free;
00349
00350 int i_tsid;
00351 int i_netid;
00352 int i_num_pmt;
00353 int i_pmtslots;
00354 int i_pat_version_number;
00355 ts_stream_t pat;
00356
00357 int i_pmt_version_number;
00358 ts_stream_t pmt[MAX_PMT];
00359 pmt_map_t pmtmap[MAX_PMT_PID];
00360 int i_pmt_program_number[MAX_PMT];
00361 sdt_desc_t sdt_descriptors[MAX_PMT];
00362
00363 int i_mpeg4_streams;
00364
00365 int i_null_continuity_counter;
00366 ts_stream_t sdt;
00367 dvbpsi_pmt_t *dvbpmt;
00368
00369
00370 int64_t i_bitrate_min;
00371 int64_t i_bitrate_max;
00372
00373 int64_t i_shaping_delay;
00374 int64_t i_pcr_delay;
00375
00376 int64_t i_dts_delay;
00377
00378 vlc_bool_t b_use_key_frames;
00379
00380 mtime_t i_pcr;
00381
00382 csa_t *csa;
00383 int i_csa_pkt_size;
00384 vlc_bool_t b_crypt_audio;
00385 vlc_bool_t b_crypt_video;
00386 };
00387
00388
00389 static int AllocatePID( sout_mux_sys_t *p_sys, int i_cat )
00390 {
00391 int i_pid;
00392 if ( i_cat == VIDEO_ES && p_sys->i_pid_video )
00393 {
00394 i_pid = p_sys->i_pid_video;
00395 p_sys->i_pid_video = 0;
00396 }
00397 else if ( i_cat == AUDIO_ES && p_sys->i_pid_audio )
00398 {
00399 i_pid = p_sys->i_pid_audio;
00400 p_sys->i_pid_audio = 0;
00401 }
00402 else if ( i_cat == SPU_ES && p_sys->i_pid_spu )
00403 {
00404 i_pid = p_sys->i_pid_spu;
00405 p_sys->i_pid_spu = 0;
00406 }
00407 else
00408 {
00409 i_pid = ++p_sys->i_pid_free;
00410 }
00411 return i_pid;
00412 }
00413
00414 static int pmtcompare( const void *pa, const void *pb )
00415 {
00416 if ( ((pmt_map_t *)pa)->i_pid < ((pmt_map_t *)pb)->i_pid )
00417 return -1;
00418 else if ( ((pmt_map_t *)pa)->i_pid > ((pmt_map_t *)pb)->i_pid )
00419 return 1;
00420 else
00421 return 0;
00422 }
00423
00424 static int intcompare( const void *pa, const void *pb )
00425 {
00426 if ( *(int *)pa < *(int *)pb )
00427 return -1;
00428 else if ( *(int *)pa > *(int *)pb )
00429 return 1;
00430 else
00431 return 0;
00432 }
00433
00434
00435
00436
00437 static int Control ( sout_mux_t *, int, va_list );
00438 static int AddStream( sout_mux_t *, sout_input_t * );
00439 static int DelStream( sout_mux_t *, sout_input_t * );
00440 static int Mux ( sout_mux_t * );
00441
00442 static block_t *FixPES( sout_mux_t *p_mux, block_fifo_t *p_fifo );
00443 static void TSSchedule ( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
00444 mtime_t i_pcr_length, mtime_t i_pcr_dts );
00445 static void TSDate ( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
00446 mtime_t i_pcr_length, mtime_t i_pcr_dts );
00447 static void GetPAT( sout_mux_t *p_mux, sout_buffer_chain_t *c );
00448 static void GetPMT( sout_mux_t *p_mux, sout_buffer_chain_t *c );
00449
00450 static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, vlc_bool_t b_pcr );
00451 static void TSSetPCR( block_t *p_ts, mtime_t i_dts );
00452
00453 static void PEStoTS ( sout_instance_t *, sout_buffer_chain_t *, block_t *, ts_stream_t * );
00454
00455
00456
00457
00458 static int Open( vlc_object_t *p_this )
00459 {
00460 sout_mux_t *p_mux =(sout_mux_t*)p_this;
00461 sout_mux_sys_t *p_sys = NULL;
00462 vlc_value_t val;
00463 int i;
00464
00465 sout_CfgParse( p_mux, SOUT_CFG_PREFIX, ppsz_sout_options, p_mux->p_cfg );
00466
00467 p_sys = malloc( sizeof( sout_mux_sys_t ) );
00468 if( !p_sys )
00469 return VLC_ENOMEM;
00470 p_sys->i_pmtslots = p_sys->b_sdt = 0;
00471 p_sys->i_num_pmt = 1;
00472 p_sys->dvbpmt = NULL;
00473 memset( &p_sys->pmtmap, 0, sizeof(p_sys->pmtmap) );
00474
00475 p_mux->pf_control = Control;
00476 p_mux->pf_addstream = AddStream;
00477 p_mux->pf_delstream = DelStream;
00478 p_mux->pf_mux = Mux;
00479 p_mux->p_sys = p_sys;
00480
00481 srand( (uint32_t)mdate() );
00482 for ( i = 0; i < MAX_PMT; i++ )
00483 p_sys->sdt_descriptors[i].psz_service_name
00484 = p_sys->sdt_descriptors[i].psz_provider = NULL;
00485 memset( p_sys->sdt_descriptors, 0, sizeof(sdt_desc_t) );
00486
00487 p_sys->i_audio_bound = 0;
00488 p_sys->i_video_bound = 0;
00489
00490 var_Get( p_mux, SOUT_CFG_PREFIX "es-id-pid", &val );
00491 p_sys->b_es_id_pid = val.b_bool;
00492
00493 var_Get( p_mux, SOUT_CFG_PREFIX "muxpmt", &val );
00494
00495
00496
00497
00498 if( val.psz_string != NULL && *val.psz_string )
00499 {
00500 char *psz_next;
00501 char *psz = val.psz_string;
00502 uint16_t i_pid;
00503 psz_next = psz;
00504
00505 while( psz != NULL )
00506 {
00507 i_pid = strtoul( psz, &psz_next, 0 );
00508
00509 if ( strlen(psz_next) > 0 )
00510 psz = &psz_next[1];
00511 if ( i_pid == 0 )
00512 {
00513 p_sys->i_num_pmt++;
00514 if ( p_sys->i_num_pmt > MAX_PMT )
00515 {
00516 msg_Err( p_mux,
00517 "Number of PMTs greater than compiled maximum (%d)", MAX_PMT );
00518 p_sys->i_num_pmt = MAX_PMT;
00519 }
00520 }
00521 else
00522 {
00523 p_sys->pmtmap[p_sys->i_pmtslots].i_pid = i_pid;
00524 p_sys->pmtmap[p_sys->i_pmtslots].i_prog = p_sys->i_num_pmt - 1;
00525 p_sys->i_pmtslots++;
00526 if ( p_sys->i_pmtslots > MAX_PMT_PID )
00527 {
00528 msg_Err( p_mux,
00529 "Number of pids in PMT greater than compiled maximum (%d)",
00530 MAX_PMT_PID );
00531 p_sys->i_pmtslots = MAX_PMT_PID;
00532 }
00533 }
00534
00535
00536 qsort( (void *)p_sys->pmtmap, p_sys->i_pmtslots,
00537 sizeof(pmt_map_t), &pmtcompare );
00538 if ( !*psz_next )
00539 psz = NULL;
00540 }
00541 }
00542 if( val.psz_string != NULL) free( val.psz_string );
00543
00544 p_sys->i_pat_version_number = rand() % 32;
00545 p_sys->pat.i_pid = 0;
00546 p_sys->pat.i_continuity_counter = 0;
00547 p_sys->pat.b_discontinuity = VLC_FALSE;
00548
00549 var_Get( p_mux, SOUT_CFG_PREFIX "tsid", &val );
00550 if ( val.i_int )
00551 p_sys->i_tsid = val.i_int;
00552 else
00553 p_sys->i_tsid = rand() % 65536;
00554
00555 p_sys->i_netid = rand() % 65536;
00556 #ifdef HAVE_DVBPSI_SDT
00557 var_Get( p_mux, SOUT_CFG_PREFIX "netid", &val );
00558 if ( val.i_int )
00559 p_sys->i_netid = val.i_int;
00560 #endif
00561
00562 p_sys->i_pmt_version_number = rand() % 32;
00563 for( i = 0; i < p_sys->i_num_pmt; i++ )
00564 {
00565 p_sys->pmt[i].i_continuity_counter = 0;
00566 p_sys->pmt[i].b_discontinuity = VLC_FALSE;
00567 }
00568
00569 p_sys->sdt.i_pid = 0x11;
00570 p_sys->sdt.i_continuity_counter = 0;
00571 p_sys->sdt.b_discontinuity = VLC_FALSE;
00572
00573 #ifdef HAVE_DVBPSI_SDT
00574 var_Get( p_mux, SOUT_CFG_PREFIX "sdtdesc", &val );
00575 p_sys->b_sdt = val.psz_string && *val.psz_string ? VLC_TRUE : VLC_FALSE;
00576
00577
00578 if( p_sys->b_sdt )
00579 {
00580
00581 char *psz = val.psz_string;
00582 char *psz_sdttoken = psz;
00583
00584 i = 0;
00585 while ( psz_sdttoken != NULL )
00586 {
00587 char *psz_end = strchr( psz_sdttoken, ',' );
00588 if( psz_end != NULL )
00589 {
00590 *psz_end++ = '\0';
00591 }
00592 if ( !(i % 2) )
00593 {
00594 p_sys->sdt_descriptors[i/2].psz_provider
00595 = strdup(psz_sdttoken);
00596 }
00597 else
00598 {
00599 p_sys->sdt_descriptors[i/2].psz_service_name
00600 = strdup(psz_sdttoken);
00601 }
00602
00603 i++;
00604 psz_sdttoken = psz_end;
00605 }
00606 }
00607 if( val.psz_string != NULL ) free( val.psz_string );
00608 #else
00609 p_sys->b_sdt = VLC_FALSE;
00610 #endif
00611
00612 var_Get( p_mux, SOUT_CFG_PREFIX "program-pmt", &val );
00613 if( val.psz_string && *val.psz_string )
00614 {
00615 char *psz_next;
00616 char *psz = val.psz_string;
00617 uint16_t i_pid;
00618
00619 psz_next = psz;
00620 i = 0;
00621 while ( psz != NULL )
00622 {
00623 i_pid = strtoul( psz, &psz_next, 0 );
00624 if( strlen(psz_next) > 0 )
00625 psz = &psz_next[1];
00626 else
00627 psz = NULL;
00628
00629 if( i_pid == 0 )
00630 {
00631 if( i > MAX_PMT )
00632 msg_Err( p_mux, "Number of PMTs > maximum (%d)",
00633 MAX_PMT );
00634 }
00635 else
00636 {
00637 p_sys->i_pmt_program_number[i] = i_pid;
00638 i++;
00639 }
00640 }
00641 }
00642 else
00643 {
00644
00645 for( i = 0; i < p_sys->i_num_pmt; i++ )
00646 p_sys->i_pmt_program_number[i] = i + 1;
00647 }
00648 if( val.psz_string != NULL ) free( val.psz_string );
00649
00650 var_Get( p_mux, SOUT_CFG_PREFIX "pid-pmt", &val );
00651 if( val.i_int )
00652 {
00653 for( i = 0; i < p_sys->i_num_pmt; i++ )
00654 p_sys->pmt[i].i_pid = val.i_int + i;
00655 }
00656 else
00657 {
00658 for( i = 0; i < p_sys->i_num_pmt; i++ )
00659 p_sys->pmt[i].i_pid = 0x42 + i;
00660 }
00661
00662 p_sys->i_pid_free = p_sys->pmt[p_sys->i_num_pmt - 1].i_pid + 1;
00663
00664 var_Get( p_mux, SOUT_CFG_PREFIX "pid-video", &val );
00665 p_sys->i_pid_video = val.i_int;
00666 if ( p_sys->i_pid_video > p_sys->i_pid_free )
00667 {
00668 p_sys->i_pid_free = p_sys->i_pid_video + 1;
00669 }
00670
00671 var_Get( p_mux, SOUT_CFG_PREFIX "pid-audio", &val );
00672 p_sys->i_pid_audio = val.i_int;
00673 if ( p_sys->i_pid_audio > p_sys->i_pid_free )
00674 {
00675 p_sys->i_pid_free = p_sys->i_pid_audio + 1;
00676 }
00677
00678 var_Get( p_mux, SOUT_CFG_PREFIX "pid-spu", &val );
00679 p_sys->i_pid_spu = val.i_int;
00680 if ( p_sys->i_pid_spu > p_sys->i_pid_free )
00681 {
00682 p_sys->i_pid_free = p_sys->i_pid_spu + 1;
00683 }
00684
00685 p_sys->i_pcr_pid = 0x1fff;
00686 p_sys->p_pcr_input = NULL;
00687
00688 p_sys->i_mpeg4_streams = 0;
00689
00690 p_sys->i_null_continuity_counter = 0;
00691
00692
00693 var_Get( p_mux, SOUT_CFG_PREFIX "bmin", &val );
00694 p_sys->i_bitrate_min = val.i_int;
00695
00696 var_Get( p_mux, SOUT_CFG_PREFIX "bmax", &val );
00697 p_sys->i_bitrate_max = val.i_int;
00698
00699 if( p_sys->i_bitrate_min > 0 && p_sys->i_bitrate_max > 0 &&
00700 p_sys->i_bitrate_min > p_sys->i_bitrate_max )
00701 {
00702 msg_Err( p_mux, "incompatible minimum and maximum bitrate, "
00703 "disabling bitrate control" );
00704 p_sys->i_bitrate_min = 0;
00705 p_sys->i_bitrate_max = 0;
00706 }
00707 if( p_sys->i_bitrate_min > 0 || p_sys->i_bitrate_max > 0 )
00708 {
00709 msg_Err( p_mux, "bmin and bmax no more supported "
00710 "(if you need them report it)" );
00711 }
00712
00713 var_Get( p_mux, SOUT_CFG_PREFIX "shaping", &val );
00714 p_sys->i_shaping_delay = (int64_t)val.i_int * 1000;
00715 if( p_sys->i_shaping_delay <= 0 )
00716 {
00717 msg_Err( p_mux,
00718 "invalid shaping ("I64Fd"ms) resetting to 200ms",
00719 p_sys->i_shaping_delay / 1000 );
00720 p_sys->i_shaping_delay = 200000;
00721 }
00722
00723 var_Get( p_mux, SOUT_CFG_PREFIX "pcr", &val );
00724 p_sys->i_pcr_delay = (int64_t)val.i_int * 1000;
00725 if( p_sys->i_pcr_delay <= 0 ||
00726 p_sys->i_pcr_delay >= p_sys->i_shaping_delay )
00727 {
00728 msg_Err( p_mux,
00729 "invalid pcr delay ("I64Fd"ms) resetting to 70ms",
00730 p_sys->i_pcr_delay / 1000 );
00731 p_sys->i_pcr_delay = 70000;
00732 }
00733
00734 var_Get( p_mux, SOUT_CFG_PREFIX "dts-delay", &val );
00735 p_sys->i_dts_delay = (int64_t)val.i_int * 1000;
00736
00737 msg_Dbg( p_mux, "shaping="I64Fd" pcr="I64Fd" dts_delay="I64Fd,
00738 p_sys->i_shaping_delay, p_sys->i_pcr_delay, p_sys->i_dts_delay );
00739
00740 var_Get( p_mux, SOUT_CFG_PREFIX "use-key-frames", &val );
00741 p_sys->b_use_key_frames = val.b_bool;
00742
00743
00744 p_sys->i_pcr = 0;
00745
00746 p_sys->csa = NULL;
00747 var_Get( p_mux, SOUT_CFG_PREFIX "csa-ck", &val );
00748 if( val.psz_string && *val.psz_string )
00749 {
00750 char *psz = val.psz_string;
00751
00752
00753 if( psz[0] == '0' && ( psz[1] == 'x' || psz[1] == 'X' ) )
00754 {
00755 psz += 2;
00756 }
00757 if( strlen( psz ) != 16 )
00758 {
00759 msg_Dbg( p_mux, "invalid csa ck (it must be 16 chars long)" );
00760 }
00761 else
00762 {
00763 uint64_t i_ck = strtoull( psz, NULL, 16 );
00764 uint8_t ck[8];
00765 int i;
00766
00767 for( i = 0; i < 8; i++ )
00768 {
00769 ck[i] = ( i_ck >> ( 56 - 8*i) )&0xff;
00770 }
00771 #ifndef TS_NO_CSA_CK_MSG
00772 msg_Dbg( p_mux, "using CSA scrambling with ck=%x:%x:%x:%x:%x:%x:%x:%x",
00773 ck[0], ck[1], ck[2], ck[3], ck[4], ck[5], ck[6], ck[7] );
00774 #endif
00775 p_sys->csa = csa_New();
00776 if( p_sys->csa )
00777 {
00778 vlc_value_t pkt_val;
00779
00780 csa_SetCW( p_sys->csa, ck, ck );
00781
00782 var_Get( p_mux, SOUT_CFG_PREFIX "csa-pkt", &pkt_val );
00783 if( pkt_val.i_int < 12 || pkt_val.i_int > 188 )
00784 {
00785 msg_Err( p_mux, "wrong packet size %d specified.", pkt_val.i_int );
00786 msg_Warn( p_mux, "using default packet size of 188 bytes" );
00787 p_sys->i_csa_pkt_size = 188;
00788 }
00789 else p_sys->i_csa_pkt_size = pkt_val.i_int;
00790 msg_Dbg( p_mux, "encrypting %d bytes of packet", p_sys->i_csa_pkt_size );
00791 }
00792 }
00793 }
00794 if( val.psz_string ) free( val.psz_string );
00795
00796 var_Get( p_mux, SOUT_CFG_PREFIX "crypt-audio", &val );
00797 p_sys->b_crypt_audio = val.b_bool;
00798
00799 var_Get( p_mux, SOUT_CFG_PREFIX "crypt-video", &val );
00800 p_sys->b_crypt_video = val.b_bool;
00801
00802 return VLC_SUCCESS;
00803 }
00804
00805
00806
00807
00808 static void Close( vlc_object_t * p_this )
00809 {
00810 sout_mux_t *p_mux = (sout_mux_t*)p_this;
00811 sout_mux_sys_t *p_sys = p_mux->p_sys;
00812 int i;
00813
00814 if( p_sys->csa )
00815 {
00816 csa_Delete( p_sys->csa );
00817 }
00818 for( i = 0; i < MAX_PMT; i++ )
00819 {
00820 if( p_sys->sdt_descriptors[i].psz_service_name != NULL )
00821 free( p_sys->sdt_descriptors[i].psz_service_name );
00822 if( p_sys->sdt_descriptors[i].psz_provider != NULL )
00823 free( p_sys->sdt_descriptors[i].psz_provider );
00824 }
00825
00826 if( p_sys->dvbpmt != NULL )
00827 free ( p_sys->dvbpmt );
00828
00829 free( p_sys );
00830 }
00831
00832
00833
00834
00835 static int Control( sout_mux_t *p_mux, int i_query, va_list args )
00836 {
00837 vlc_bool_t *pb_bool;
00838 char **ppsz;
00839
00840 switch( i_query )
00841 {
00842 case MUX_CAN_ADD_STREAM_WHILE_MUXING:
00843 pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t * );
00844 *pb_bool = VLC_TRUE;
00845 return VLC_SUCCESS;
00846
00847 case MUX_GET_ADD_STREAM_WAIT:
00848 pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t * );
00849 *pb_bool = VLC_FALSE;
00850 return VLC_SUCCESS;
00851
00852 case MUX_GET_MIME:
00853 ppsz = (char**)va_arg( args, char ** );
00854 *ppsz = strdup( "video/mpeg" );
00855 return VLC_SUCCESS;
00856
00857 default:
00858 return VLC_EGENERIC;
00859 }
00860 }
00861
00862
00863
00864
00865 static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
00866 {
00867 sout_mux_sys_t *p_sys = p_mux->p_sys;
00868 ts_stream_t *p_stream;
00869
00870 p_input->p_sys = p_stream = malloc( sizeof( ts_stream_t ) );
00871
00872
00873 if ( p_sys->b_es_id_pid )
00874 p_stream->i_pid = p_input->p_fmt->i_id & 0x1fff;
00875 else
00876 p_stream->i_pid = AllocatePID( p_sys, p_input->p_fmt->i_cat );
00877 p_stream->i_codec = p_input->p_fmt->i_codec;
00878 p_stream->i_continuity_counter = 0;
00879 p_stream->b_discontinuity = VLC_FALSE;
00880 p_stream->i_decoder_specific_info = 0;
00881 p_stream->p_decoder_specific_info = NULL;
00882
00883 msg_Dbg( p_mux, "adding input codec=%4.4s pid=%d",
00884 (char*)&p_input->p_fmt->i_codec, p_stream->i_pid );
00885
00886
00887 switch( p_input->p_fmt->i_cat )
00888 {
00889 case VIDEO_ES:
00890 switch( p_input->p_fmt->i_codec )
00891 {
00892 case VLC_FOURCC( 'm', 'p','g', 'v' ):
00893
00894 p_stream->i_stream_type = 0x02;
00895 p_stream->i_stream_id = 0xe0;
00896 break;
00897 case VLC_FOURCC( 'm', 'p','4', 'v' ):
00898 p_stream->i_stream_type = 0x10;
00899 p_stream->i_stream_id = 0xe0;
00900 p_stream->i_es_id = p_stream->i_pid;
00901 break;
00902 case VLC_FOURCC( 'h', '2','6', '4' ):
00903 p_stream->i_stream_type = 0x1b;
00904 p_stream->i_stream_id = 0xe0;
00905 break;
00906
00907
00908
00909 case VLC_FOURCC( 'H', '2', '6', '3' ):
00910 case VLC_FOURCC( 'I', '2', '6', '3' ):
00911 case VLC_FOURCC( 'W', 'M', 'V', '3' ):
00912 case VLC_FOURCC( 'W', 'M', 'V', '2' ):
00913 case VLC_FOURCC( 'W', 'M', 'V', '1' ):
00914 case VLC_FOURCC( 'D', 'I', 'V', '3' ):
00915 case VLC_FOURCC( 'D', 'I', 'V', '2' ):
00916 case VLC_FOURCC( 'D', 'I', 'V', '1' ):
00917 case VLC_FOURCC( 'M', 'J', 'P', 'G' ):
00918 p_stream->i_stream_type = 0xa0;
00919 p_stream->i_stream_id = 0xa0;
00920 p_stream->i_bih_codec = p_input->p_fmt->i_codec;
00921 p_stream->i_bih_width = p_input->p_fmt->video.i_width;
00922 p_stream->i_bih_height = p_input->p_fmt->video.i_height;
00923 break;
00924 default:
00925 free( p_stream );
00926 return VLC_EGENERIC;
00927 }
00928 p_sys->i_video_bound++;
00929 break;
00930
00931 case AUDIO_ES:
00932 switch( p_input->p_fmt->i_codec )
00933 {
00934 case VLC_FOURCC( 'm', 'p','g', 'a' ):
00935 p_stream->i_stream_type =
00936 p_input->p_fmt->audio.i_rate >= 32000 ? 0x03 : 0x04;
00937 p_stream->i_stream_id = 0xc0;
00938 break;
00939 case VLC_FOURCC( 'a', '5','2', ' ' ):
00940 p_stream->i_stream_type = 0x81;
00941 p_stream->i_stream_id = 0xbd;
00942 break;
00943 case VLC_FOURCC( 'l', 'p','c', 'm' ):
00944 p_stream->i_stream_type = 0x83;
00945 p_stream->i_stream_id = 0xbd;
00946 break;
00947 case VLC_FOURCC( 'd', 't','s', ' ' ):
00948 p_stream->i_stream_type = 0x06;
00949 p_stream->i_stream_id = 0xbd;
00950 break;
00951 case VLC_FOURCC( 'm', 'p','4', 'a' ):
00952 p_stream->i_stream_type = 0x11;
00953 p_stream->i_stream_id = 0xfa;
00954 p_sys->i_mpeg4_streams++;
00955 p_stream->i_es_id = p_stream->i_pid;
00956 break;
00957 default:
00958 free( p_stream );
00959 return VLC_EGENERIC;
00960 }
00961 p_sys->i_audio_bound++;
00962 break;
00963
00964 case SPU_ES:
00965 switch( p_input->p_fmt->i_codec )
00966 {
00967 case VLC_FOURCC( 's', 'p','u', ' ' ):
00968 p_stream->i_stream_type = 0x82;
00969 p_stream->i_stream_id = 0xbd;
00970 break;
00971 case VLC_FOURCC( 's', 'u','b', 't' ):
00972 p_stream->i_stream_type = 0x12;
00973 p_stream->i_stream_id = 0xfa;
00974 p_sys->i_mpeg4_streams++;
00975 p_stream->i_es_id = p_stream->i_pid;
00976 break;
00977 case VLC_FOURCC('d','v','b','s'):
00978 p_stream->i_stream_type = 0x06;
00979 p_stream->i_es_id = p_input->p_fmt->subs.dvb.i_id;
00980 p_stream->i_stream_id = 0xbd;
00981 break;
00982 case VLC_FOURCC('t','e','l','x'):
00983 p_stream->i_stream_type = 0x06;
00984 p_stream->i_stream_id = 0xbd;
00985 break;
00986 default:
00987 free( p_stream );
00988 return VLC_EGENERIC;
00989 }
00990 break;
00991
00992 default:
00993 free( p_stream );
00994 return VLC_EGENERIC;
00995 }
00996
00997 p_stream->lang[0] =
00998 p_stream->lang[1] =
00999 p_stream->lang[2] = '\0';
01000 if( p_input->p_fmt->psz_language )
01001 {
01002 char *psz = p_input->p_fmt->psz_language;
01003 const iso639_lang_t *pl = NULL;
01004
01005 if( strlen( psz ) == 2 )
01006 {
01007 pl = GetLang_1( psz );
01008 }
01009 else if( strlen( psz ) == 3 )
01010 {
01011 pl = GetLang_2B( psz );
01012 if( !strcmp( pl->psz_iso639_1, "??" ) )
01013 {
01014 pl = GetLang_2T( psz );
01015 }
01016 }
01017 if( pl && strcmp( pl->psz_iso639_1, "??" ) )
01018 {
01019 p_stream->lang[0] = pl->psz_iso639_2T[0];
01020 p_stream->lang[1] = pl->psz_iso639_2T[1];
01021 p_stream->lang[2] = pl->psz_iso639_2T[2];
01022
01023 msg_Dbg( p_mux, " - lang=%c%c%c",
01024 p_stream->lang[0], p_stream->lang[1], p_stream->lang[2] );
01025 }
01026 }
01027
01028
01029 p_stream->i_decoder_specific_info = p_input->p_fmt->i_extra;
01030 if( p_stream->i_decoder_specific_info > 0 )
01031 {
01032 p_stream->p_decoder_specific_info =
01033 malloc( p_stream->i_decoder_specific_info );
01034 memcpy( p_stream->p_decoder_specific_info,
01035 p_input->p_fmt->p_extra,
01036 p_input->p_fmt->i_extra );
01037 }
01038
01039
01040 if( p_stream->i_codec == VLC_FOURCC( 's', 'u','b', 't' ) )
01041 {
01042 uint8_t *p;
01043
01044 p_stream->i_decoder_specific_info = 55;
01045 p_stream->p_decoder_specific_info = p =
01046 malloc( p_stream->i_decoder_specific_info );
01047
01048 p[0] = 0x10;
01049 p[1] = 0x00;
01050
01051
01052
01053 p[2] = 52;
01054
01055 p += 3;
01056
01057 p[0] = p[1] = p[2] = p[3] = 0; p+=4;
01058 *p++ = 0;
01059 *p++ = 1;
01060
01061 p[0] = p[1] = p[2] = 0x00; p+=3;
01062 *p++ = 0xff;
01063
01064 p[0] = p[1] = 0; p += 2;
01065 p[0] = p[1] = 0; p += 2;
01066 p[0] = p[1] = 0; p += 2;
01067 p[0] = p[1] = 0; p += 2;
01068
01069 p[0] = p[1] = 0; p += 2;
01070 p[0] = p[1] = 0; p += 2;
01071 p[0] = p[1] = 0; p += 2;
01072
01073 *p++ = 0;
01074 *p++ = 12;
01075
01076 p[0] = p[1] = p[2] = 0x00; p+=3;
01077 *p++ = 0x00;
01078
01079 p[0] = p[1] = p[2] = 0; p[3] = 22; p += 4;
01080 memcpy( p, "ftab", 4 ); p += 4;
01081 *p++ = 0; *p++ = 1;
01082 p[0] = p[1] = 0; p += 2;
01083 *p++ = 9;
01084 memcpy( p, "Helvetica", 9 );
01085 }
01086
01087
01088 BufferChainInit( &p_stream->chain_pes );
01089 p_stream->i_pes_dts = 0;
01090 p_stream->i_pes_length = 0;
01091 p_stream->i_pes_used = 0;
01092 p_stream->b_key_frame = 0;
01093
01094
01095 p_sys->i_pmt_version_number = ( p_sys->i_pmt_version_number + 1 )%32;
01096
01097
01098 if( p_input->p_fmt->i_cat != SPU_ES &&
01099 ( p_sys->i_pcr_pid == 0x1fff || p_input->p_fmt->i_cat == VIDEO_ES ) )
01100 {
01101 if( p_sys->p_pcr_input )
01102 {
01103
01104
01105 }
01106 p_sys->i_pcr_pid = p_stream->i_pid;
01107 p_sys->p_pcr_input = p_input;
01108
01109 msg_Dbg( p_mux, "new PCR PID is %d", p_sys->i_pcr_pid );
01110 }
01111
01112 return VLC_SUCCESS;
01113 }
01114
01115
01116
01117
01118 static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
01119 {
01120 sout_mux_sys_t *p_sys = p_mux->p_sys;
01121 ts_stream_t *p_stream;
01122 vlc_value_t val;
01123
01124 p_stream = (ts_stream_t*)p_input->p_sys;
01125 msg_Dbg( p_mux, "removing input pid=%d", p_stream->i_pid );
01126
01127 if( p_sys->i_pcr_pid == p_stream->i_pid )
01128 {
01129 int i;
01130
01131
01132 p_sys->i_pcr_pid = 0x1fff;
01133 p_sys->p_pcr_input = NULL;
01134 for( i = 0; i < p_mux->i_nb_inputs; i++ )
01135 {
01136 if( p_mux->pp_inputs[i] == p_input )
01137 {
01138 continue;
01139 }
01140
01141 if( p_mux->pp_inputs[i]->p_fmt->i_cat == VIDEO_ES )
01142 {
01143 p_sys->i_pcr_pid =
01144 ((ts_stream_t*)p_mux->pp_inputs[i]->p_sys)->i_pid;
01145 p_sys->p_pcr_input= p_mux->pp_inputs[i];
01146 break;
01147 }
01148 else if( p_mux->pp_inputs[i]->p_fmt->i_cat != SPU_ES &&
01149 p_sys->i_pcr_pid == 0x1fff )
01150 {
01151 p_sys->i_pcr_pid =
01152 ((ts_stream_t*)p_mux->pp_inputs[i]->p_sys)->i_pid;
01153 p_sys->p_pcr_input= p_mux->pp_inputs[i];
01154 }
01155 }
01156 if( p_sys->p_pcr_input )
01157 {
01158
01159
01160 }
01161 msg_Dbg( p_mux, "new PCR PID is %d", p_sys->i_pcr_pid );
01162 }
01163
01164
01165 BufferChainClean( p_mux->p_sout, &p_stream->chain_pes );
01166
01167 if( p_stream->p_decoder_specific_info )
01168 {
01169 free( p_stream->p_decoder_specific_info );
01170 }
01171 if( p_stream->i_stream_id == 0xfa ||
01172 p_stream->i_stream_id == 0xfb ||
01173 p_stream->i_stream_id == 0xfe )
01174 {
01175 p_sys->i_mpeg4_streams--;
01176 }
01177
01178 var_Get( p_mux, SOUT_CFG_PREFIX "pid-video", &val );
01179 if( val.i_int > 0 )
01180 {
01181 int i_pid_video = val.i_int;
01182 if ( i_pid_video == p_stream->i_pid )
01183 {
01184 p_sys->i_pid_video = i_pid_video;
01185 msg_Dbg( p_mux, "freeing video PID %d", i_pid_video );
01186 }
01187 }
01188 var_Get( p_mux, SOUT_CFG_PREFIX "pid-audio", &val );
01189 if( val.i_int > 0 )
01190 {
01191 int i_pid_audio = val.i_int;
01192 if ( i_pid_audio == p_stream->i_pid )
01193 {
01194 p_sys->i_pid_audio = i_pid_audio;
01195 msg_Dbg( p_mux, "freeing audio PID %d", i_pid_audio );
01196 }
01197 }
01198 var_Get( p_mux, SOUT_CFG_PREFIX "pid-spu", &val );
01199 if( val.i_int > 0 )
01200 {
01201 int i_pid_spu = val.i_int;
01202 if ( i_pid_spu == p_stream->i_pid )
01203 {
01204 p_sys->i_pid_spu = i_pid_spu;
01205 msg_Dbg( p_mux, "freeing spu PID %d", i_pid_spu );
01206 }
01207 }
01208 free( p_stream );
01209
01210
01211 p_sys->i_pmt_version_number++; p_sys->i_pmt_version_number %= 32;
01212
01213 return VLC_SUCCESS;
01214 }
01215
01216
01217
01218
01219
01220
01221 static int Mux( sout_mux_t *p_mux )
01222 {
01223 sout_mux_sys_t *p_sys = p_mux->p_sys;
01224 ts_stream_t *p_pcr_stream;
01225
01226 if( p_sys->i_pcr_pid == 0x1fff )
01227 {
01228 msg_Dbg( p_mux, "waiting for PCR streams" );
01229 msleep( 1000 );
01230 return VLC_SUCCESS;
01231 }
01232 p_pcr_stream = (ts_stream_t*)p_sys->p_pcr_input->p_sys;
01233
01234 for( ;; )
01235 {
01236 sout_buffer_chain_t chain_ts;
01237 int i_packet_count;
01238 int i_packet_pos;
01239 mtime_t i_pcr_dts;
01240 mtime_t i_pcr_length;
01241 mtime_t i_shaping_delay;
01242 int i;
01243
01244 if( p_pcr_stream->b_key_frame )
01245 {
01246 i_shaping_delay = p_pcr_stream->i_pes_length;
01247 }
01248 else
01249 {
01250 i_shaping_delay = p_sys->i_shaping_delay;
01251 }
01252
01253
01254 for( ;; )
01255 {
01256 vlc_bool_t b_ok = VLC_TRUE;
01257 block_t *p_data;
01258
01259
01260
01261 for( i = -1; i < p_mux->i_nb_inputs; i++ )
01262 {
01263 sout_input_t *p_input;
01264 ts_stream_t *p_stream;
01265 int64_t i_spu_delay = 0;
01266
01267 if( i == -1 )
01268 p_input = p_sys->p_pcr_input;
01269 else if( p_mux->pp_inputs[i]->p_sys == p_pcr_stream )
01270 continue;
01271 else
01272 p_input = p_mux->pp_inputs[i];
01273 p_stream = (ts_stream_t*)p_input->p_sys;
01274
01275 if( ( p_stream == p_pcr_stream &&
01276 p_stream->i_pes_length < i_shaping_delay ) ||
01277 p_stream->i_pes_dts + p_stream->i_pes_length <
01278 p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length )
01279 {
01280
01281 if( p_input->p_fifo->i_depth <= 1 )
01282 {
01283 if( p_input->p_fmt->i_cat == AUDIO_ES ||
01284 p_input->p_fmt->i_cat == VIDEO_ES )
01285 {
01286
01287 return VLC_SUCCESS;
01288 }
01289 else if( p_input->p_fifo->i_depth <= 0 )
01290 {
01291
01292 continue;
01293 }
01294 else
01295 {
01296
01297 block_t *p_spu = block_FifoShow( p_input->p_fifo );
01298
01299 i_spu_delay =
01300 p_spu->i_dts - p_pcr_stream->i_pes_dts;
01301
01302 if( i_spu_delay > i_shaping_delay &&
01303 i_spu_delay < I64C(100000000) )
01304 continue;
01305
01306 if ( i_spu_delay >= I64C(100000000)
01307 || i_spu_delay < 10000 )
01308 {
01309 BufferChainClean( p_mux->p_sout,
01310 &p_stream->chain_pes );
01311 p_stream->i_pes_dts = 0;
01312 p_stream->i_pes_used = 0;
01313 p_stream->i_pes_length = 0;
01314 continue;
01315 }
01316 }
01317 }
01318 b_ok = VLC_FALSE;
01319
01320 if( p_stream == p_pcr_stream
01321 || p_input->p_fmt->i_codec !=
01322 VLC_FOURCC('m', 'p', 'g', 'a') )
01323 p_data = block_FifoGet( p_input->p_fifo );
01324 else
01325 p_data = FixPES( p_mux, p_input->p_fifo );
01326
01327 if( p_input->p_fifo->i_depth > 0 &&
01328 p_input->p_fmt->i_cat != SPU_ES )
01329 {
01330 block_t *p_next = block_FifoShow( p_input->p_fifo );
01331 p_data->i_length = p_next->i_dts - p_data->i_dts;
01332 }
01333 else if( p_input->p_fmt->i_codec !=
01334 VLC_FOURCC('s', 'u', 'b', 't' ) )
01335 p_data->i_length = 1000;
01336
01337 if( ( p_pcr_stream->i_pes_dts > 0 &&
01338 p_data->i_dts - 10000000 > p_pcr_stream->i_pes_dts +
01339 p_pcr_stream->i_pes_length ) ||
01340 p_data->i_dts < p_stream->i_pes_dts ||
01341 ( p_stream->i_pes_dts > 0 &&
01342 p_input->p_fmt->i_cat != SPU_ES &&
01343 p_data->i_dts - 10000000 > p_stream->i_pes_dts +
01344 p_stream->i_pes_length ) )
01345 {
01346 msg_Warn( p_mux, "packet with too strange dts "
01347 "(dts="I64Fd",old="I64Fd",pcr="I64Fd")",
01348 p_data->i_dts, p_stream->i_pes_dts,
01349 p_pcr_stream->i_pes_dts );
01350 block_Release( p_data );
01351
01352 BufferChainClean( p_mux->p_sout,
01353 &p_stream->chain_pes );
01354 p_stream->i_pes_dts = 0;
01355 p_stream->i_pes_used = 0;
01356 p_stream->i_pes_length = 0;
01357
01358 if( p_input->p_fmt->i_cat != SPU_ES )
01359 {
01360 BufferChainClean( p_mux->p_sout,
01361 &p_pcr_stream->chain_pes );
01362 p_pcr_stream->i_pes_dts = 0;
01363 p_pcr_stream->i_pes_used = 0;
01364 p_pcr_stream->i_pes_length = 0;
01365 }
01366 }
01367 else
01368 {
01369 int i_header_size = 0;
01370 int b_data_alignment = 0;
01371 if( p_input->p_fmt->i_cat == SPU_ES )
01372 {
01373 if( p_input->p_fmt->i_codec ==
01374 VLC_FOURCC('s','u','b','t') )
01375 {
01376
01377 p_data = block_Realloc( p_data, 2,
01378 p_data->i_buffer );
01379 p_data->p_buffer[0] =
01380 ( (p_data->i_buffer - 2) >> 8) & 0xff;
01381 p_data->p_buffer[1] =
01382 ( (p_data->i_buffer - 2) ) & 0xff;
01383
01384
01385 if( p_data->i_buffer > 2 &&
01386 p_data->p_buffer[p_data->i_buffer -1] ==
01387 '\0' )
01388 p_data->i_buffer--;
01389
01390
01391 if( p_data->i_length > 0 &&
01392 !( p_data->i_buffer == 1 &&
01393 *p_data->p_buffer == ' ' ) )
01394 {
01395 block_t *p_spu = block_New( p_mux, 3 );
01396
01397 p_spu->i_dts = p_spu->i_pts =
01398 p_data->i_dts + p_data->i_length;
01399 p_spu->i_length = 1000;
01400
01401 p_spu->p_buffer[0] = 0;
01402 p_spu->p_buffer[1] = 1;
01403 p_spu->p_buffer[2] = ' ';
01404
01405 E_(EStoPES)( p_mux->p_sout, &p_spu, p_spu,
01406 p_input->p_fmt,
01407 p_stream->i_stream_id, 1,
01408 0, 0, 0 );
01409 p_data->p_next = p_spu;
01410 }
01411 }
01412 else if( p_input->p_fmt->i_codec ==
01413 VLC_FOURCC('t','e','l','x') )
01414 {
01415
01416 i_header_size = 0x24;
01417 b_data_alignment = 1;
01418 }
01419 }
01420 else if( p_data->i_length < 0 ||
01421 p_data->i_length > 2000000 )
01422 {
01423
01424
01425 p_data->i_length = 1000;
01426 }
01427
01428 p_stream->i_pes_length += p_data->i_length;
01429 if( p_stream->i_pes_dts == 0 )
01430 {
01431 p_stream->i_pes_dts = p_data->i_dts;
01432 }
01433
01434
01435 if( p_stream->i_stream_id == 0xa0 &&
01436 p_data->i_pts <= 0 )
01437 {
01438
01439
01440 p_data->i_pts = p_data->i_dts;
01441 }
01442
01443 E_( EStoPES )( p_mux->p_sout, &p_data, p_data,
01444 p_input->p_fmt, p_stream->i_stream_id,
01445 1, b_data_alignment, i_header_size, 0 );
01446
01447 BufferChainAppend( &p_stream->chain_pes, p_data );
01448
01449 if( p_sys->b_use_key_frames && p_stream == p_pcr_stream
01450 && (p_data->i_flags & BLOCK_FLAG_TYPE_I)
01451 && !(p_data->i_flags & BLOCK_FLAG_NO_KEYFRAME)
01452 && (p_stream->i_pes_length > 400000) )
01453 {
01454 i_shaping_delay = p_stream->i_pes_length;
01455 p_stream->b_key_frame = 1;
01456 }
01457 }
01458 }
01459 }
01460
01461 if( b_ok )
01462 {
01463 break;
01464 }
01465 }
01466
01467
01468 i_pcr_dts = p_pcr_stream->i_pes_dts;
01469 i_pcr_length = p_pcr_stream->i_pes_length;
01470 p_pcr_stream->b_key_frame = 0;
01471
01472
01473
01474 i_packet_count = 0;
01475 for( i = 0; i < p_mux->i_nb_inputs; i++ )
01476 {
01477 ts_stream_t *p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
01478 block_t *p_pes;
01479
01480
01481 for( p_pes = p_stream->chain_pes.p_first; p_pes != NULL;
01482 p_pes = p_pes->p_next )
01483 {
01484 int i_size = p_pes->i_buffer;
01485 if( p_pes->i_dts + p_pes->i_length >
01486 p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length )
01487 {
01488 mtime_t i_frag = p_pcr_stream->i_pes_dts +
01489 p_pcr_stream->i_pes_length - p_pes->i_dts;
01490 if( i_frag < 0 )
01491 {
01492
01493 break;
01494 }
01495 i_size = p_pes->i_buffer * i_frag / p_pes->i_length;
01496 }
01497 i_packet_count += ( i_size + 183 ) / 184;
01498 }
01499 }
01500
01501 i_packet_count += (8 * i_pcr_length / p_sys->i_pcr_delay + 175) / 176;
01502
01503
01504 BufferChainInit( &chain_ts );
01505
01506 GetPAT( p_mux, &chain_ts );
01507 GetPMT( p_mux, &chain_ts );
01508 i_packet_pos = 0;
01509 i_packet_count += chain_ts.i_depth;
01510
01511
01512 for( ;; )
01513 {
01514 int i_stream;
01515 mtime_t i_dts;
01516 ts_stream_t *p_stream;
01517 sout_input_t *p_input;
01518 block_t *p_ts;
01519 vlc_bool_t b_pcr;
01520
01521
01522 for( i = 0, i_stream = -1, i_dts = 0; i < p_mux->i_nb_inputs; i++ )
01523 {
01524 p_input = p_mux->pp_inputs[i];
01525 p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
01526
01527 if( p_stream->i_pes_dts == 0 )
01528 {
01529 continue;
01530 }
01531
01532 if( i_stream == -1 ||
01533 p_stream->i_pes_dts < i_dts )
01534 {
01535 i_stream = i;
01536 i_dts = p_stream->i_pes_dts;
01537 }
01538 }
01539 if( i_stream == -1 || i_dts > i_pcr_dts + i_pcr_length )
01540 {
01541 break;
01542 }
01543 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
01544
01545
01546 b_pcr = VLC_FALSE;
01547 if( p_stream == p_pcr_stream &&
01548 i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count >=
01549 p_sys->i_pcr + p_sys->i_pcr_delay )
01550 {
01551 b_pcr = VLC_TRUE;
01552 p_sys->i_pcr = i_pcr_dts + i_packet_pos *
01553 i_pcr_length / i_packet_count;
01554 }
01555
01556
01557 p_ts = TSNew( p_mux, p_stream, b_pcr );
01558 if( p_sys->csa != NULL &&
01559 (p_input->p_fmt->i_cat != AUDIO_ES || p_sys->b_crypt_audio) &&
01560 (p_input->p_fmt->i_cat != VIDEO_ES || p_sys->b_crypt_video) )
01561 {
01562 p_ts->i_flags |= BLOCK_FLAG_SCRAMBLED;
01563 }
01564 i_packet_pos++;
01565
01566
01567 BufferChainAppend( &chain_ts, p_ts );
01568 }
01569
01570
01571 TSSchedule( p_mux, &chain_ts, i_pcr_length, i_pcr_dts );
01572 }
01573 }
01574
01575 #define STD_PES_PAYLOAD 170
01576 static block_t *FixPES( sout_mux_t *p_mux, block_fifo_t *p_fifo )
01577 {
01578 block_t *p_data;
01579 int i_size;
01580
01581 p_data = block_FifoShow( p_fifo );
01582 i_size = p_data->i_buffer;
01583
01584 if( i_size == STD_PES_PAYLOAD )
01585 {
01586 return block_FifoGet( p_fifo );
01587 }
01588 else if( i_size > STD_PES_PAYLOAD )
01589 {
01590 block_t *p_new = block_New( p_mux, STD_PES_PAYLOAD );
01591 p_mux->p_vlc->pf_memcpy( p_new->p_buffer, p_data->p_buffer, STD_PES_PAYLOAD );
01592 p_new->i_pts = p_data->i_pts;
01593 p_new->i_dts = p_data->i_dts;
01594 p_new->i_length = p_data->i_length * STD_PES_PAYLOAD
01595 / p_data->i_buffer;
01596 p_data->i_buffer -= STD_PES_PAYLOAD;
01597 p_data->p_buffer += STD_PES_PAYLOAD;
01598 p_data->i_pts += p_new->i_length;
01599 p_data->i_dts += p_new->i_length;
01600 p_data->i_length -= p_new->i_length;
01601 p_data->i_flags |= BLOCK_FLAG_NO_KEYFRAME;
01602 return p_new;
01603 }
01604 else
01605 {
01606 block_t *p_next;
01607 int i_copy;
01608
01609 p_data = block_FifoGet( p_fifo );
01610 p_data = block_Realloc( p_data, 0, STD_PES_PAYLOAD );
01611 p_next = block_FifoShow( p_fifo );
01612 if ( p_data->i_flags & BLOCK_FLAG_NO_KEYFRAME )
01613 {
01614 p_data->i_flags &= ~BLOCK_FLAG_NO_KEYFRAME;
01615 p_data->i_pts = p_next->i_pts;
01616 p_data->i_dts = p_next->i_dts;
01617 }
01618 i_copy = __MIN( STD_PES_PAYLOAD - i_size, p_next->i_buffer );
01619
01620 p_mux->p_vlc->pf_memcpy( &p_data->p_buffer[i_size], p_next->p_buffer,
01621 i_copy );
01622 p_next->i_pts += p_next->i_length * i_copy / p_next->i_buffer;
01623 p_next->i_dts += p_next->i_length * i_copy / p_next->i_buffer;
01624 p_next->i_length -= p_next->i_length * i_copy / p_next->i_buffer;
01625 p_next->i_buffer -= i_copy;
01626 p_next->p_buffer += i_copy;
01627 p_next->i_flags |= BLOCK_FLAG_NO_KEYFRAME;
01628
01629 if( !p_next->i_buffer )
01630 {
01631 p_next = block_FifoGet( p_fifo );
01632 block_Release( p_next );
01633 }
01634 return p_data;
01635 }
01636 }
01637
01638 static void TSSchedule( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
01639 mtime_t i_pcr_length, mtime_t i_pcr_dts )
01640 {
01641 sout_mux_sys_t *p_sys = p_mux->p_sys;
01642 sout_buffer_chain_t new_chain;
01643 int i_packet_count = p_chain_ts->i_depth;
01644 int i;
01645
01646 BufferChainInit( &new_chain );
01647
01648 if ( i_pcr_length <= 0 )
01649 {
01650 i_pcr_length = i_packet_count;
01651 }
01652
01653 for( i = 0; i < i_packet_count; i++ )
01654 {
01655 block_t *p_ts = BufferChainGet( p_chain_ts );
01656 mtime_t i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
01657
01658 BufferChainAppend( &new_chain, p_ts );
01659
01660 if( p_ts->i_dts &&
01661 p_ts->i_dts + p_sys->i_dts_delay * 2/3 < i_new_dts )
01662 {
01663 mtime_t i_max_diff = i_new_dts - p_ts->i_dts;
01664 mtime_t i_cut_dts = p_ts->i_dts;
01665
01666 p_ts = BufferChainPeek( p_chain_ts );
01667 i++;
01668 i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
01669 while ( p_ts != NULL && i_new_dts - p_ts->i_dts >= i_max_diff )
01670 {
01671 p_ts = BufferChainGet( p_chain_ts );
01672 i_max_diff = i_new_dts - p_ts->i_dts;
01673 i_cut_dts = p_ts->i_dts;
01674 BufferChainAppend( &new_chain, p_ts );
01675
01676 p_ts = BufferChainPeek( p_chain_ts );
01677 i++;
01678 i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
01679 }
01680 msg_Dbg( p_mux, "adjusting rate at "I64Fd"/"I64Fd" (%d/%d)",
01681 i_cut_dts - i_pcr_dts, i_pcr_length, new_chain.i_depth,
01682 p_chain_ts->i_depth );
01683 if ( new_chain.i_depth )
01684 TSDate( p_mux, &new_chain,
01685 i_cut_dts - i_pcr_dts,
01686 i_pcr_dts );
01687 if ( p_chain_ts->i_depth )
01688 TSSchedule( p_mux,
01689 p_chain_ts, i_pcr_dts + i_pcr_length - i_cut_dts,
01690 i_cut_dts );
01691 return;
01692 }
01693 }
01694
01695 if ( new_chain.i_depth )
01696 TSDate( p_mux, &new_chain, i_pcr_length, i_pcr_dts );
01697 }
01698
01699 static void TSDate( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
01700 mtime_t i_pcr_length, mtime_t i_pcr_dts )
01701 {
01702 sout_mux_sys_t *p_sys = p_mux->p_sys;
01703 int i_packet_count = p_chain_ts->i_depth;
01704 int i;
01705
01706 if ( i_pcr_length / 1000 > 0 )
01707 {
01708 int i_bitrate = ((uint64_t)i_packet_count * 188 * 8000)
01709 / (uint64_t)(i_pcr_length / 1000);
01710 if ( p_sys->i_bitrate_max && p_sys->i_bitrate_max < i_bitrate )
01711 {
01712 msg_Warn( p_mux, "max bitrate exceeded at "I64Fd
01713 " (%d bi/s for %d pkt in "I64Fd" us)",
01714 i_pcr_dts + p_sys->i_shaping_delay * 3 / 2 - mdate(),
01715 i_bitrate, i_packet_count, i_pcr_length);
01716 }
01717 #if 0
01718 else
01719 {
01720 msg_Dbg( p_mux, "starting at "I64Fd
01721 " (%d bi/s for %d packets in "I64Fd" us)",
01722 i_pcr_dts + p_sys->i_shaping_delay * 3 / 2 - mdate(),
01723 i_bitrate, i_packet_count, i_pcr_length);
01724 }
01725 #endif
01726 }
01727 else
01728 {
01729
01730
01731 i_pcr_length = i_packet_count;
01732 }
01733
01734
01735 for( i = 0; i < i_packet_count; i++ )
01736 {
01737 block_t *p_ts = BufferChainGet( p_chain_ts );
01738 mtime_t i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
01739
01740 p_ts->i_dts = i_new_dts;
01741 p_ts->i_length = i_pcr_length / i_packet_count;
01742
01743 if( p_ts->i_flags & BLOCK_FLAG_CLOCK )
01744 {
01745
01746 TSSetPCR( p_ts, p_ts->i_dts - p_sys->i_dts_delay );
01747 }
01748 if( p_ts->i_flags & BLOCK_FLAG_SCRAMBLED )
01749 {
01750 csa_Encrypt( p_sys->csa, p_ts->p_buffer, p_sys->i_csa_pkt_size, 0 );
01751 }
01752
01753
01754 p_ts->i_dts += p_sys->i_shaping_delay * 3 / 2;
01755
01756 sout_AccessOutWrite( p_mux->p_access, p_ts );
01757 }
01758 }
01759
01760 static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream,
01761 vlc_bool_t b_pcr )
01762 {
01763 block_t *p_pes = p_stream->chain_pes.p_first;
01764 block_t *p_ts;
01765
01766 vlc_bool_t b_new_pes = VLC_FALSE;
01767 vlc_bool_t b_adaptation_field = VLC_FALSE;
01768
01769 int i_payload_max = 184 - ( b_pcr ? 8 : 0 );
01770 int i_payload;
01771
01772 if( p_stream->i_pes_used <= 0 )
01773 {
01774 b_new_pes = VLC_TRUE;
01775 }
01776 i_payload = __MIN( (int)p_pes->i_buffer - p_stream->i_pes_used,
01777 i_payload_max );
01778
01779 if( b_pcr || i_payload < i_payload_max )
01780 {
01781 b_adaptation_field = VLC_TRUE;
01782 }
01783
01784 p_ts = block_New( p_mux, 188 );
01785 p_ts->i_dts = p_pes->i_dts;
01786
01787 p_ts->p_buffer[0] = 0x47;
01788 p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 ) |
01789 ( ( p_stream->i_pid >> 8 )&0x1f );
01790 p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
01791 p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 ) |
01792 p_stream->i_continuity_counter;
01793
01794 p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
01795 p_stream->b_discontinuity = (p_pes->i_flags & BLOCK_FLAG_DISCONTINUITY);
01796
01797 if( b_adaptation_field )
01798 {
01799 int i;
01800
01801 if( b_pcr )
01802 {
01803 int i_stuffing = i_payload_max - i_payload;
01804
01805 p_ts->i_flags |= BLOCK_FLAG_CLOCK;
01806
01807 p_ts->p_buffer[4] = 7 + i_stuffing;
01808 p_ts->p_buffer[5] = 0x10;
01809 if( p_stream->b_discontinuity )
01810 {
01811 p_ts->p_buffer[5] |= 0x80;
01812 p_stream->b_discontinuity = VLC_FALSE;
01813 }
01814 p_ts->p_buffer[6] = ( 0 )&0xff;
01815 p_ts->p_buffer[7] = ( 0 )&0xff;
01816 p_ts->p_buffer[8] = ( 0 )&0xff;
01817 p_ts->p_buffer[9] = ( 0 )&0xff;
01818 p_ts->p_buffer[10]= ( ( 0 )&0x80 ) | 0x7e;
01819 p_ts->p_buffer[11]= 0;
01820
01821 for( i = 12; i < 12 + i_stuffing; i++ )
01822 {
01823 p_ts->p_buffer[i] = 0xff;
01824 }
01825 }
01826 else
01827 {
01828 int i_stuffing = i_payload_max - i_payload;
01829
01830 p_ts->p_buffer[4] = i_stuffing - 1;
01831 if( i_stuffing > 1 )
01832 {
01833 p_ts->p_buffer[5] = 0x00;
01834 for( i = 6; i < 6 + i_stuffing - 2; i++ )
01835 {
01836 p_ts->p_buffer[i] = 0xff;
01837 }
01838 }
01839 }
01840 }
01841
01842
01843 memcpy( &p_ts->p_buffer[188 - i_payload],
01844 &p_pes->p_buffer[p_stream->i_pes_used], i_payload );
01845
01846 p_stream->i_pes_used += i_payload;
01847 p_stream->i_pes_dts = p_pes->i_dts + p_pes->i_length *
01848 p_stream->i_pes_used / p_pes->i_buffer;
01849 p_stream->i_pes_length -= p_pes->i_length * i_payload / p_pes->i_buffer;
01850
01851 if( p_stream->i_pes_used >= (int)p_pes->i_buffer )
01852 {
01853 p_pes = BufferChainGet( &p_stream->chain_pes );
01854 block_Release( p_pes );
01855
01856 p_pes = p_stream->chain_pes.p_first;
01857 if( p_pes )
01858 {
01859 p_stream->i_pes_dts = p_pes->i_dts;
01860 p_stream->i_pes_length = 0;
01861 while( p_pes )
01862 {
01863 p_stream->i_pes_length += p_pes->i_length;
01864
01865 p_pes = p_pes->p_next;
01866 }
01867 }
01868 else
01869 {
01870 p_stream->i_pes_dts = 0;
01871 p_stream->i_pes_length = 0;
01872 }
01873 p_stream->i_pes_used = 0;
01874 }
01875
01876 return p_ts;
01877 }
01878
01879 static void TSSetPCR( block_t *p_ts, mtime_t i_dts )
01880 {
01881 mtime_t i_pcr = 9 * i_dts / 100;
01882
01883 p_ts->p_buffer[6] = ( i_pcr >> 25 )&0xff;
01884 p_ts->p_buffer[7] = ( i_pcr >> 17 )&0xff;
01885 p_ts->p_buffer[8] = ( i_pcr >> 9 )&0xff;
01886 p_ts->p_buffer[9] = ( i_pcr >> 1 )&0xff;
01887 p_ts->p_buffer[10]|= ( i_pcr << 7 )&0x80;
01888 }
01889
01890 #if 0
01891 static void TSSetConstraints( sout_mux_t *p_mux, sout_buffer_chain_t *c,
01892 mtime_t i_length, int i_bitrate_min,
01893 int i_bitrate_max )
01894 {
01895 sout_mux_sys_t *p_sys = p_mux->p_sys;
01896 sout_buffer_chain_t s = *c;
01897
01898 int i_packets = 0;
01899 int i_packets_min = 0;
01900 int i_packets_max = 0;
01901
01902 if( i_length <= 0 )
01903 {
01904 return;
01905 }
01906
01907 i_packets = c->i_depth;
01908 i_packets_min = ( (int64_t)i_bitrate_min * i_length / 8 / 1000000 + 187 ) / 188;
01909 i_packets_max = ( (int64_t)i_bitrate_max * i_length / 8 / 1000000 + 187 ) / 188;
01910
01911 if( i_packets < i_packets_min && i_packets_min > 0 )
01912 {
01913 block_t *p_pk;
01914 int i_div = ( i_packets_min - i_packets ) / i_packets;
01915 int i_mod = ( i_packets_min - i_packets ) % i_packets;
01916 int i_rest = 0;
01917
01918
01919
01920 msg_Dbg( p_mux,
01921 "packets=%d but min=%d -> adding %d packets of padding",
01922 i_packets, i_packets_min, i_packets_min - i_packets );
01923
01924 BufferChainInit( c );
01925 while( ( p_pk = BufferChainGet( &s ) ) )
01926 {
01927 int i, i_null;
01928
01929 BufferChainAppend( c, p_pk );
01930
01931 i_null = i_div + ( i_rest + i_mod ) / i_packets;
01932
01933 for( i = 0; i < i_null; i++ )
01934 {
01935 block_t *p_null;
01936
01937 p_null = sout_BufferNew( p_mux->p_sout, 188 );
01938 p_null->p_buffer[0] = 0x47;
01939 p_null->p_buffer[1] = 0x1f;
01940 p_null->p_buffer[2] = 0xff;
01941 p_null->p_buffer[3] = 0x10 | p_sys->i_null_continuity_counter;
01942 memset( &p_null->p_buffer[4], 0, 184 );
01943 p_sys->i_null_continuity_counter =
01944 ( p_sys->i_null_continuity_counter + 1 ) % 16;
01945
01946 BufferChainAppend( c, p_null );
01947 }
01948
01949 i_rest = ( i_rest + i_mod ) % i_packets;
01950 }
01951 }
01952 else if( i_packets > i_packets_max && i_packets_max > 0 )
01953 {
01954 block_t *p_pk;
01955 int i;
01956
01957
01958
01959
01960 msg_Warn( p_mux,
01961 "packets=%d but max=%d -> removing %d packets -> stream broken",
01962 i_packets, i_packets_max, i_packets - i_packets_max );
01963
01964 BufferChainInit( c );
01965 for( i = 0; i < i_packets_max; i++ )
01966 {
01967 BufferChainAppend( c, BufferChainGet( &s ) );
01968 }
01969
01970 while( ( p_pk = BufferChainGet( &s ) ) )
01971 {
01972 sout_BufferDelete( p_mux->p_sout, p_pk );
01973 }
01974 }
01975 }
01976 #endif
01977
01978 static void PEStoTS( sout_instance_t *p_sout,
01979 sout_buffer_chain_t *c, block_t *p_pes,
01980 ts_stream_t *p_stream )
01981 {
01982 uint8_t *p_data;
01983 int i_size;
01984 int b_new_pes;
01985
01986
01987 i_size = p_pes->i_buffer;
01988 p_data = p_pes->p_buffer;
01989
01990 b_new_pes = VLC_TRUE;
01991
01992 for( ;; )
01993 {
01994 int b_adaptation_field;
01995 int i_copy;
01996 block_t *p_ts;
01997
01998 p_ts = block_New( p_sout, 188 );
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010 i_copy = __MIN( i_size, 184 );
02011 b_adaptation_field = i_size < 184 ? VLC_TRUE : VLC_FALSE;
02012
02013 p_ts->p_buffer[0] = 0x47;
02014 p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|
02015 ( ( p_stream->i_pid >> 8 )&0x1f );
02016 p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
02017 p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|
02018 p_stream->i_continuity_counter;
02019
02020 b_new_pes = VLC_FALSE;
02021 p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
02022
02023 if( b_adaptation_field )
02024 {
02025 int i_stuffing = 184 - i_copy;
02026 int i;
02027
02028 p_ts->p_buffer[4] = i_stuffing - 1;
02029 if( i_stuffing > 1 )
02030 {
02031 p_ts->p_buffer[5] = 0x00;
02032 if( p_stream->b_discontinuity )
02033 {
02034 p_ts->p_buffer[5] |= 0x80;
02035 p_stream->b_discontinuity = VLC_FALSE;
02036 }
02037 for( i = 6; i < 6 + i_stuffing - 2; i++ )
02038 {
02039 p_ts->p_buffer[i] = 0xff;
02040 }
02041 }
02042 }
02043
02044 memcpy( &p_ts->p_buffer[188 - i_copy], p_data, i_copy );
02045 p_data += i_copy;
02046 i_size -= i_copy;
02047
02048 BufferChainAppend( c, p_ts );
02049
02050 if( i_size <= 0 )
02051 {
02052 block_t *p_next = p_pes->p_next;
02053
02054 p_pes->p_next = NULL;
02055 block_Release( p_pes );
02056 if( p_next == NULL )
02057 {
02058 break;
02059 }
02060 b_new_pes = VLC_TRUE;
02061 p_pes = p_next;
02062 i_size = p_pes->i_buffer;
02063 p_data = p_pes->p_buffer;
02064 }
02065 }
02066
02067 return;
02068 }
02069
02070 static block_t *WritePSISection( sout_instance_t *p_sout,
02071 dvbpsi_psi_section_t* p_section )
02072 {
02073 block_t *p_psi, *p_first = NULL;
02074
02075 while( p_section )
02076 {
02077 int i_size;
02078
02079 i_size = (uint32_t)( p_section->p_payload_end - p_section->p_data )+
02080 ( p_section->b_syntax_indicator ? 4 : 0 );
02081
02082 p_psi = block_New( p_sout, i_size + 1 );
02083 p_psi->i_pts = 0;
02084 p_psi->i_dts = 0;
02085 p_psi->i_length = 0;
02086 p_psi->i_buffer = i_size + 1;
02087
02088 p_psi->p_buffer[0] = 0;
02089 memcpy( p_psi->p_buffer + 1,
02090 p_section->p_data,
02091 i_size );
02092
02093 block_ChainAppend( &p_first, p_psi );
02094
02095 p_section = p_section->p_next;
02096 }
02097
02098 return( p_first );
02099 }
02100
02101 static void GetPAT( sout_mux_t *p_mux,
02102 sout_buffer_chain_t *c )
02103 {
02104 sout_mux_sys_t *p_sys = p_mux->p_sys;
02105 block_t *p_pat;
02106 dvbpsi_pat_t pat;
02107 dvbpsi_psi_section_t *p_section;
02108 int i;
02109
02110 dvbpsi_InitPAT( &pat, p_sys->i_tsid, p_sys->i_pat_version_number,
02111 1 );
02112
02113 for ( i = 0; i < p_sys->i_num_pmt; i++ )
02114 dvbpsi_PATAddProgram( &pat,
02115 p_sys->i_pmt_program_number[i],
02116 p_sys->pmt[i].i_pid );
02117
02118 p_section = dvbpsi_GenPATSections( &pat,
02119 0 );
02120
02121 p_pat = WritePSISection( p_mux->p_sout, p_section );
02122
02123 PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat );
02124
02125 dvbpsi_DeletePSISections( p_section );
02126 dvbpsi_EmptyPAT( &pat );
02127 }
02128
02129 static uint32_t GetDescriptorLength24b( int i_length )
02130 {
02131 uint32_t i_l1, i_l2, i_l3;
02132
02133 i_l1 = i_length&0x7f;
02134 i_l2 = ( i_length >> 7 )&0x7f;
02135 i_l3 = ( i_length >> 14 )&0x7f;
02136
02137 return( 0x808000 | ( i_l3 << 16 ) | ( i_l2 << 8 ) | i_l1 );
02138 }
02139
02140 static void GetPMT( sout_mux_t *p_mux, sout_buffer_chain_t *c )
02141 {
02142 sout_mux_sys_t *p_sys = p_mux->p_sys;
02143 block_t *p_pmt[MAX_PMT];
02144 block_t *p_sdt;
02145
02146 dvbpsi_sdt_t sdt;
02147 dvbpsi_pmt_es_t *p_es;
02148 dvbpsi_psi_section_t *p_section[MAX_PMT], *p_section2;
02149 dvbpsi_sdt_service_t *p_service;
02150 char *psz_sdt_desc;
02151 int i_pidinput;
02152
02153 int i_stream;
02154 int i;
02155 int *p_usepid = NULL;
02156
02157 if( p_sys->dvbpmt == NULL )
02158 p_sys->dvbpmt = malloc( p_sys->i_num_pmt * sizeof(dvbpsi_pmt_t) );
02159 #ifdef HAVE_DVBPSI_SDT
02160 if( p_sys->b_sdt )
02161 dvbpsi_InitSDT( &sdt, p_sys->i_tsid, 1, 1, p_sys->i_netid );
02162 #endif
02163
02164 for( i = 0; i < p_sys->i_num_pmt; i++ )
02165 {
02166 dvbpsi_InitPMT( &p_sys->dvbpmt[i],
02167 p_sys->i_pmt_program_number[i],
02168 p_sys->i_pmt_version_number,
02169 1,
02170 p_sys->i_pcr_pid );
02171
02172 #ifdef HAVE_DVBPSI_SDT
02173 if( p_sys->b_sdt )
02174 {
02175 p_service = dvbpsi_SDTAddService( &sdt,
02176 p_sys->i_pmt_program_number[i],
02177 0,
02178 0,
02179 4,
02180 0 );
02181
02182 #define psz_sdtprov p_sys->sdt_descriptors[i].psz_provider
02183 #define psz_sdtserv p_sys->sdt_descriptors[i].psz_service_name
02184
02185
02186 if( psz_sdtprov != NULL && psz_sdtserv != NULL )
02187 {
02188 psz_sdt_desc = malloc( 3 + strlen(psz_sdtprov)
02189 + strlen(psz_sdtserv) );
02190 psz_sdt_desc[0] = 0x01;
02191
02192
02193 psz_sdt_desc[1] = (char)strlen(psz_sdtprov);
02194 memcpy( &psz_sdt_desc[2], psz_sdtprov, strlen(psz_sdtprov) );
02195
02196
02197 psz_sdt_desc[ 2 + strlen(psz_sdtprov) ]
02198 = (char)strlen(psz_sdtserv);
02199 memcpy( &psz_sdt_desc[3+strlen(psz_sdtprov)], psz_sdtserv,
02200 strlen(psz_sdtserv) );
02201
02202 dvbpsi_SDTServiceAddDescriptor( p_service, 0x48,
02203 3 + strlen(psz_sdtprov) + strlen(psz_sdtserv),
02204 psz_sdt_desc );
02205 free( psz_sdt_desc );
02206 }
02207 #undef psz_sdtprov
02208 #undef psz_sdtserv
02209 }
02210 #endif
02211 }
02212
02213 if( p_sys->i_mpeg4_streams > 0 )
02214 {
02215 uint8_t iod[4096];
02216 bits_buffer_t bits;
02217 bits_buffer_t bits_fix_IOD;
02218
02219
02220
02221
02222 memset( iod, 0, 4096 );
02223
02224 bits_initwrite( &bits, 4096, iod );
02225
02226 bits_write( &bits, 8, 0x11 );
02227
02228 bits_write( &bits, 8, 0x01 );
02229
02230 bits_align( &bits );
02231 bits_write( &bits, 8, 0x02 );
02232 bits_fix_IOD = bits;
02233 bits_write( &bits, 24,
02234 GetDescriptorLength24b( 0 ) );
02235 bits_write( &bits, 10, 0x01 );
02236 bits_write( &bits, 1, 0x00 );
02237 bits_write( &bits, 1, 0x00 );
02238 bits_write( &bits, 4, 0x0f );
02239 bits_write( &bits, 8, 0xff );
02240 bits_write( &bits, 8, 0xff );
02241 bits_write( &bits, 8, 0xfe );
02242 bits_write( &bits, 8, 0xfe );
02243 bits_write( &bits, 8, 0xff );
02244 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
02245 {
02246 ts_stream_t *p_stream;
02247 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
02248
02249 if( p_stream->i_stream_id == 0xfa ||
02250 p_stream->i_stream_id == 0xfb ||
02251 p_stream->i_stream_id == 0xfe )
02252 {
02253 bits_buffer_t bits_fix_ESDescr, bits_fix_Decoder;
02254
02255 bits_align( &bits );
02256 bits_write( &bits, 8, 0x03 );
02257 bits_fix_ESDescr = bits;
02258 bits_write( &bits, 24,
02259 GetDescriptorLength24b( 0 ) );
02260 bits_write( &bits, 16, p_stream->i_es_id );
02261 bits_write( &bits, 1, 0x00 );
02262 bits_write( &bits, 1, 0x00 );
02263 bits_write( &bits, 1, 0x00 );
02264 bits_write( &bits, 5, 0x1f );
02265
02266
02267 bits_align( &bits );
02268 bits_write( &bits, 8, 0x04 );
02269 bits_fix_Decoder = bits;
02270 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) );
02271 if( p_stream->i_stream_type == 0x10 )
02272 {
02273 bits_write( &bits, 8, 0x20 );
02274 bits_write( &bits, 6, 0x04 );
02275 }
02276 else if( p_stream->i_stream_type == 0x1b )
02277 {
02278 bits_write( &bits, 8, 0x21 );
02279 bits_write( &bits, 6, 0x04 );
02280 }
02281 else if( p_stream->i_stream_type == 0x11 || p_stream->i_stream_type == 0x0f )
02282 {
02283 bits_write( &bits, 8, 0x40 );
02284 bits_write( &bits, 6, 0x05 );
02285 }
02286 else if( p_stream->i_stream_type == 0x12 &&
02287 p_stream->i_codec == VLC_FOURCC('s','u','b','t') )
02288 {
02289 bits_write( &bits, 8, 0x0B );
02290 bits_write( &bits, 6, 0x04 );
02291 }
02292 else
02293 {
02294 bits_write( &bits, 8, 0x00 );
02295 bits_write( &bits, 6, 0x00 );
02296
02297 msg_Err( p_mux->p_sout,"Unsupported stream_type => "
02298 "broken IOD" );
02299 }
02300 bits_write( &bits, 1, 0x00 );
02301 bits_write( &bits, 1, 0x01 );
02302 bits_write( &bits, 24, 1024 * 1024 );
02303 bits_write( &bits, 32, 0x7fffffff );
02304 bits_write( &bits, 32, 0 );
02305
02306 if( p_stream->i_decoder_specific_info > 0 )
02307 {
02308 int i;
02309
02310 bits_align( &bits );
02311 bits_write( &bits, 8, 0x05 );
02312 bits_write( &bits, 24, GetDescriptorLength24b(
02313 p_stream->i_decoder_specific_info ) );
02314 for( i = 0; i < p_stream->i_decoder_specific_info; i++ )
02315 {
02316 bits_write( &bits, 8,
02317 ((uint8_t*)p_stream->p_decoder_specific_info)[i] );
02318 }
02319 }
02320
02321 bits_write( &bits_fix_Decoder, 24,
02322 GetDescriptorLength24b( bits.i_data -
02323 bits_fix_Decoder.i_data - 3 ) );
02324
02325
02326 bits_align( &bits );
02327 bits_write( &bits, 8, 0x06 );
02328 bits_write( &bits, 24, GetDescriptorLength24b( 8 ) );
02329 bits_write( &bits, 8, 0x01 );
02330 bits_write( &bits, 1, 0 );
02331 bits_write( &bits, 32, 0 );
02332 bits_write( &bits, 8, 0 );
02333 bits_write( &bits, 8, 0 );
02334 bits_align( &bits );
02335
02336
02337 bits_write( &bits_fix_ESDescr, 24,
02338 GetDescriptorLength24b( bits.i_data -
02339 bits_fix_ESDescr.i_data - 3 ) );
02340 }
02341 }
02342 bits_align( &bits );
02343
02344 bits_write( &bits_fix_IOD, 24,
02345 GetDescriptorLength24b( bits.i_data -
02346 bits_fix_IOD.i_data - 3 ) );
02347
02348 #if 0//def HAVE_BSEARCH
02349 i_pidinput = p_mux->pp_inputs[i]->p_fmt->i_id;
02350 p_usepid = bsearch( &i_pidinput, p_sys->pmtmap, p_sys->i_pmtslots,
02351 sizeof(pmt_map_t), intcompare );
02352 p_usepid = bsearch( &p_usepid, p_sys->pmtmap, p_sys->i_num_pmt,
02353 sizeof(pmt_map_t), pmtcompare );
02354 if( p_usepid != NULL )
02355 dvbpsi_PMTAddDescriptor(
02356 &p_sys->dvbpmt[((pmt_map_t *)p_usepid)->i_prog], 0x1d,
02357 bits.i_data, bits.p_data );
02358 else
02359 msg_Err( p_mux, "Received an unmapped PID" );
02360 #else
02361 dvbpsi_PMTAddDescriptor( &p_sys->dvbpmt[0], 0x1d, bits.i_data,
02362 bits.p_data );
02363 #endif
02364 }
02365
02366 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
02367 {
02368 ts_stream_t *p_stream;
02369
02370 p_stream = (ts_stream_t *)p_mux->pp_inputs[i_stream]->p_sys;
02371
02372 #ifdef HAVE_BSEARCH
02373 i_pidinput = p_mux->pp_inputs[i_stream]->p_fmt->i_id;
02374 p_usepid = bsearch( &i_pidinput, p_sys->pmtmap, p_sys->i_pmtslots,
02375 sizeof(pmt_map_t), intcompare );
02376
02377 if( p_usepid != NULL )
02378 p_es = dvbpsi_PMTAddES(
02379 &p_sys->dvbpmt[((pmt_map_t *)p_usepid)->i_prog],
02380 p_stream->i_stream_type, p_stream->i_pid );
02381 else
02382
02383 #endif
02384 p_es = dvbpsi_PMTAddES( &p_sys->dvbpmt[0], p_stream->i_stream_type,
02385 p_stream->i_pid );
02386
02387 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
02388 {
02389 uint8_t es_id[2];
02390
02391
02392 es_id[0] = (p_stream->i_es_id >> 8)&0xff;
02393 es_id[1] = (p_stream->i_es_id)&0xff;
02394 dvbpsi_PMTESAddDescriptor( p_es, 0x1f, 2, es_id );
02395 }
02396 else if( p_stream->i_stream_type == 0xa0 )
02397 {
02398 uint8_t data[512];
02399 int i_extra = __MIN( p_stream->i_decoder_specific_info, 502 );
02400
02401
02402 memcpy( &data[0], &p_stream->i_bih_codec, 4 );
02403 data[4] = ( p_stream->i_bih_width >> 8 )&0xff;
02404 data[5] = ( p_stream->i_bih_width )&0xff;
02405 data[6] = ( p_stream->i_bih_height>> 8 )&0xff;
02406 data[7] = ( p_stream->i_bih_height )&0xff;
02407 data[8] = ( i_extra >> 8 )&0xff;
02408 data[9] = ( i_extra )&0xff;
02409 if( i_extra > 0 )
02410 {
02411 memcpy( &data[10], p_stream->p_decoder_specific_info, i_extra );
02412 }
02413
02414
02415 dvbpsi_PMTESAddDescriptor( p_es, 0xa0, i_extra + 10, data );
02416 }
02417 else if( p_stream->i_stream_type == 0x81 )
02418 {
02419 uint8_t format[4] = { 0x41, 0x43, 0x2d, 0x33 };
02420
02421
02422 dvbpsi_PMTESAddDescriptor( p_es, 0x05, 4, format );
02423 }
02424 else if( p_stream->i_codec == VLC_FOURCC('d','t','s',' ') )
02425 {
02426
02427
02428
02429 uint8_t data[4] = { 0x44, 0x54, 0x53, 0x32 };
02430 dvbpsi_PMTESAddDescriptor( p_es, 0x05, 4, data );
02431 }
02432 else if( p_stream->i_codec == VLC_FOURCC('t','e','l','x') )
02433 {
02434 dvbpsi_PMTESAddDescriptor( p_es, 0x56,
02435 p_stream->i_decoder_specific_info,
02436 p_stream->p_decoder_specific_info );
02437 }
02438 #ifdef _DVBPSI_DR_59_H_
02439 else if( p_stream->i_codec == VLC_FOURCC('d','v','b','s') )
02440 {
02441
02442 dvbpsi_subtitling_dr_t descr;
02443 dvbpsi_subtitle_t sub;
02444 dvbpsi_descriptor_t *p_descr;
02445
02446 memcpy( sub.i_iso6392_language_code, p_stream->lang, 3 );
02447 sub.i_subtitling_type = 0x10;
02448 sub.i_composition_page_id = p_stream->i_es_id & 0xFF;
02449 sub.i_ancillary_page_id = p_stream->i_es_id >> 16;
02450
02451 descr.i_subtitles_number = 1;
02452 descr.p_subtitle[0] = sub;
02453
02454 p_descr = dvbpsi_GenSubtitlingDr( &descr, 0 );
02455 p_descr->i_length = 8;
02456 dvbpsi_PMTESAddDescriptor( p_es, p_descr->i_tag,
02457 p_descr->i_length, p_descr->p_data );
02458 continue;
02459 }
02460 #endif
02461
02462 if( p_stream->lang[0] != 0 )
02463 {
02464 uint8_t data[4];
02465
02466
02467
02468 data[0] = p_stream->lang[0];
02469 data[1] = p_stream->lang[1];
02470 data[2] = p_stream->lang[2];
02471 data[3] = 0x00;
02472
02473 dvbpsi_PMTESAddDescriptor( p_es, 0x0a, 4, data );
02474 }
02475 }
02476
02477 for( i = 0; i < p_sys->i_num_pmt; i++ )
02478 {
02479 p_section[i] = dvbpsi_GenPMTSections( &p_sys->dvbpmt[i] );
02480 p_pmt[i] = WritePSISection( p_mux->p_sout, p_section[i] );
02481 PEStoTS( p_mux->p_sout, c, p_pmt[i], &p_sys->pmt[i] );
02482 dvbpsi_DeletePSISections( p_section[i] );
02483 dvbpsi_EmptyPMT( &p_sys->dvbpmt[i] );
02484 }
02485
02486 #ifdef HAVE_DVBPSI_SDT
02487 if( p_sys->b_sdt )
02488 {
02489 p_section2 = dvbpsi_GenSDTSections( &sdt );
02490 p_sdt = WritePSISection( p_mux->p_sout, p_section2 );
02491 PEStoTS( p_mux->p_sout, c, p_sdt, &p_sys->sdt );
02492 dvbpsi_DeletePSISections( p_section2 );
02493 dvbpsi_EmptySDT( &sdt );
02494 }
02495 #endif
02496 }