⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ts.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
    bool                b_key_frame;} ts_stream_t;struct sout_mux_sys_t{    int             i_pcr_pid;    sout_input_t    *p_pcr_input;    vlc_mutex_t     csa_lock;    int             i_audio_bound;    int             i_video_bound;    bool            b_es_id_pid;    bool            b_sdt;    int             i_pid_video;    int             i_pid_audio;    int             i_pid_spu;    int             i_pid_free; /* first usable pid */    int             i_tsid;    int             i_netid;    int             i_num_pmt;    int             i_pmtslots;    int             i_pat_version_number;    ts_stream_t     pat;    int             i_pmt_version_number;    ts_stream_t     pmt[MAX_PMT];    pmt_map_t       pmtmap[MAX_PMT_PID];    int             i_pmt_program_number[MAX_PMT];    sdt_desc_t      sdt_descriptors[MAX_PMT];    bool            b_data_alignment;    int             i_mpeg4_streams;    int             i_null_continuity_counter;  /* Needed ? */    ts_stream_t     sdt;    dvbpsi_pmt_t    *dvbpmt;    /* for TS building */    int64_t         i_bitrate_min;    int64_t         i_bitrate_max;    int64_t         i_shaping_delay;    int64_t         i_pcr_delay;    int64_t         i_dts_delay;    bool            b_use_key_frames;    mtime_t         i_pcr;  /* last PCR emited */    csa_t           *csa;    int             i_csa_pkt_size;    bool            b_crypt_audio;    bool            b_crypt_video;};/* Reserve a pid and return it */static int  AllocatePID( sout_mux_sys_t *p_sys, int i_cat ){    int i_pid;    if ( i_cat == VIDEO_ES && p_sys->i_pid_video )    {        i_pid = p_sys->i_pid_video;        p_sys->i_pid_video = 0;    }    else if ( i_cat == AUDIO_ES && p_sys->i_pid_audio )    {        i_pid = p_sys->i_pid_audio;        p_sys->i_pid_audio = 0;    }    else if ( i_cat == SPU_ES && p_sys->i_pid_spu )    {        i_pid = p_sys->i_pid_spu;        p_sys->i_pid_spu = 0;    }    else    {        i_pid = ++p_sys->i_pid_free;    }    return i_pid;}static int pmtcompare( const void *pa, const void *pb ){    if ( ((pmt_map_t *)pa)->i_pid  < ((pmt_map_t *)pb)->i_pid )        return -1;    else if ( ((pmt_map_t *)pa)->i_pid  > ((pmt_map_t *)pb)->i_pid )        return 1;    else        return 0;}static int intcompare( const void *pa, const void *pb ){    if ( *(int *)pa  < *(int *)pb )        return -1;    else if ( *(int *)pa > *(int *)pb )        return 1;    else        return 0;}/***************************************************************************** * Local prototypes *****************************************************************************/static int Control  ( sout_mux_t *, int, va_list );static int AddStream( sout_mux_t *, sout_input_t * );static int DelStream( sout_mux_t *, sout_input_t * );static int Mux      ( sout_mux_t * );static block_t *FixPES( sout_mux_t *p_mux, block_fifo_t *p_fifo );static block_t *Add_ADTS( block_t *, es_format_t * );static void TSSchedule  ( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,                          mtime_t i_pcr_length, mtime_t i_pcr_dts );static void TSDate      ( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,                          mtime_t i_pcr_length, mtime_t i_pcr_dts );static void GetPAT( sout_mux_t *p_mux, sout_buffer_chain_t *c );static void GetPMT( sout_mux_t *p_mux, sout_buffer_chain_t *c );static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, bool b_pcr );static void TSSetPCR( block_t *p_ts, mtime_t i_dts );static void PEStoTS  ( sout_instance_t *, sout_buffer_chain_t *, block_t *, ts_stream_t * );/***************************************************************************** * Open: *****************************************************************************/static int Open( vlc_object_t *p_this ){    sout_mux_t          *p_mux =(sout_mux_t*)p_this;    sout_mux_sys_t      *p_sys = NULL;    vlc_value_t         val;    int i;    config_ChainParse( p_mux, SOUT_CFG_PREFIX, ppsz_sout_options, p_mux->p_cfg );    p_sys = malloc( sizeof( sout_mux_sys_t ) );    if( !p_sys )        return VLC_ENOMEM;    p_sys->i_pmtslots = p_sys->b_sdt = 0;    p_sys->i_num_pmt = 1;    p_sys->dvbpmt = NULL;    memset( &p_sys->pmtmap, 0, sizeof(p_sys->pmtmap) );    vlc_mutex_init( &p_sys->csa_lock );    p_mux->pf_control   = Control;    p_mux->pf_addstream = AddStream;    p_mux->pf_delstream = DelStream;    p_mux->pf_mux       = Mux;    p_mux->p_sys        = p_sys;    srand( (uint32_t)mdate() );    for ( i = 0; i < MAX_PMT; i++ )        p_sys->sdt_descriptors[i].psz_service_name            = p_sys->sdt_descriptors[i].psz_provider = NULL;    memset( p_sys->sdt_descriptors, 0, sizeof(sdt_desc_t) );    p_sys->i_audio_bound = 0;    p_sys->i_video_bound = 0;    var_Get( p_mux, SOUT_CFG_PREFIX "es-id-pid", &val );    p_sys->b_es_id_pid = val.b_bool;    var_Get( p_mux, SOUT_CFG_PREFIX "muxpmt", &val );    /*       fetch string of pmts. Here's a sample: --sout-ts-muxpmt="0x451,0x200,0x28a,0x240,,0x450,0x201,0x28b,0x241,,0x452,0x202,0x28c,0x242"       This would mean 0x451, 0x200, 0x28a, 0x240 would fall under one pmt (program), 0x450,0x201,0x28b,0x241 would fall under another    */    if( val.psz_string != NULL && *val.psz_string )    {        char *psz_next;        char *psz = val.psz_string;        uint16_t i_pid;        psz_next = psz;        while( psz != NULL )        {            i_pid = strtoul( psz, &psz_next, 0 );            if ( strlen(psz_next) > 0 )                psz = &psz_next[1];            if ( i_pid == 0 )            {                p_sys->i_num_pmt++;                if ( p_sys->i_num_pmt > MAX_PMT )                {                    msg_Err( p_mux,             "Number of PMTs greater than compiled maximum (%d)", MAX_PMT );                    p_sys->i_num_pmt = MAX_PMT;                }            }            else            {                p_sys->pmtmap[p_sys->i_pmtslots].i_pid = i_pid;                p_sys->pmtmap[p_sys->i_pmtslots].i_prog = p_sys->i_num_pmt - 1;                p_sys->i_pmtslots++;                if ( p_sys->i_pmtslots > MAX_PMT_PID )                {                    msg_Err( p_mux,             "Number of pids in PMT greater than compiled maximum (%d)",                             MAX_PMT_PID );                    p_sys->i_pmtslots = MAX_PMT_PID;                }            }            /* Now sort according to pids for fast search later on */            qsort( (void *)p_sys->pmtmap, p_sys->i_pmtslots,                   sizeof(pmt_map_t), &pmtcompare );            if ( !*psz_next )                psz = NULL;        }    }    free( val.psz_string );    p_sys->i_pat_version_number = rand() % 32;    p_sys->pat.i_pid = 0;    p_sys->pat.i_continuity_counter = 0;    p_sys->pat.b_discontinuity = false;    var_Get( p_mux, SOUT_CFG_PREFIX "tsid", &val );    if ( val.i_int )        p_sys->i_tsid = val.i_int;    else        p_sys->i_tsid = rand() % 65536;    p_sys->i_netid = rand() % 65536;#ifdef HAVE_DVBPSI_SDT    var_Get( p_mux, SOUT_CFG_PREFIX "netid", &val );    if ( val.i_int )        p_sys->i_netid = val.i_int;#endif    p_sys->i_pmt_version_number = rand() % 32;    for( i = 0; i < p_sys->i_num_pmt; i++ )    {        p_sys->pmt[i].i_continuity_counter = 0;        p_sys->pmt[i].b_discontinuity = false;    }    p_sys->sdt.i_pid = 0x11;    p_sys->sdt.i_continuity_counter = 0;    p_sys->sdt.b_discontinuity = false;#ifdef HAVE_DVBPSI_SDT    var_Get( p_mux, SOUT_CFG_PREFIX "sdtdesc", &val );    p_sys->b_sdt = val.psz_string && *val.psz_string ? true : false;    /* Syntax is provider_sdt1,service_name_sdt1,provider_sdt2,service_name_sdt2... */    if( p_sys->b_sdt )    {        char *psz = val.psz_string;        char *psz_sdttoken = psz;        i = 0;        while ( psz_sdttoken != NULL )        {            char *psz_end = strchr( psz_sdttoken, ',' );            if( psz_end != NULL )            {                *psz_end++ = '\0';            }            if ( !(i % 2) )            {                p_sys->sdt_descriptors[i/2].psz_provider                    = strdup(psz_sdttoken);            }            else            {                p_sys->sdt_descriptors[i/2].psz_service_name                    = strdup(psz_sdttoken);            }            i++;            psz_sdttoken = psz_end;        }    }    free( val.psz_string );#else    p_sys->b_sdt = false;#endif    var_Get( p_mux, SOUT_CFG_PREFIX "alignment", &val );    p_sys->b_data_alignment = val.b_bool;    var_Get( p_mux, SOUT_CFG_PREFIX "program-pmt", &val );    if( val.psz_string && *val.psz_string )    {        char *psz_next;        char *psz = val.psz_string;        uint16_t i_pid;        psz_next = psz;        i = 0;        while ( psz != NULL )        {            i_pid = strtoul( psz, &psz_next, 0 );            if( strlen(psz_next) > 0 )                psz = &psz_next[1];            else                psz = NULL;            if( i_pid == 0 )            {                if( i > MAX_PMT )                    msg_Err( p_mux, "Number of PMTs > maximum (%d)",                             MAX_PMT );            }            else            {                p_sys->i_pmt_program_number[i] = i_pid;                i++;            }        }    }    else    {        /* Option not specified, use 1, 2, 3... */        for( i = 0; i < p_sys->i_num_pmt; i++ )            p_sys->i_pmt_program_number[i] = i + 1;    }    free( val.psz_string );    var_Get( p_mux, SOUT_CFG_PREFIX "pid-pmt", &val );    if( val.i_int )    {        for( i = 0; i < p_sys->i_num_pmt; i++ )            p_sys->pmt[i].i_pid = val.i_int + i; /* Does this make any sense? */    }    else    {        for( i = 0; i < p_sys->i_num_pmt; i++ )            p_sys->pmt[i].i_pid = 0x42 + i;    }    p_sys->i_pid_free = p_sys->pmt[p_sys->i_num_pmt - 1].i_pid + 1;    var_Get( p_mux, SOUT_CFG_PREFIX "pid-video", &val );    p_sys->i_pid_video = val.i_int;    if ( p_sys->i_pid_video > p_sys->i_pid_free )    {        p_sys->i_pid_free = p_sys->i_pid_video + 1;    }    var_Get( p_mux, SOUT_CFG_PREFIX "pid-audio", &val );    p_sys->i_pid_audio = val.i_int;    if ( p_sys->i_pid_audio > p_sys->i_pid_free )    {        p_sys->i_pid_free = p_sys->i_pid_audio + 1;    }    var_Get( p_mux, SOUT_CFG_PREFIX "pid-spu", &val );    p_sys->i_pid_spu = val.i_int;    if ( p_sys->i_pid_spu > p_sys->i_pid_free )    {        p_sys->i_pid_free = p_sys->i_pid_spu + 1;    }    p_sys->i_pcr_pid = 0x1fff;    p_sys->p_pcr_input = NULL;    p_sys->i_mpeg4_streams = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -