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

📄 ts.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* Init p_sys field */    p_sys->b_meta = VLC_TRUE;    p_sys->b_dvb_control = VLC_TRUE;    p_sys->i_dvb_program = 0;    for( i = 0; i < 8192; i++ )    {        ts_pid_t *pid = &p_sys->pid[i];        pid->i_pid      = i;        pid->b_seen     = VLC_FALSE;        pid->b_valid    = VLC_FALSE;    }    p_sys->i_packet_size = i_packet_size;    p_sys->b_udp_out = VLC_FALSE;    p_sys->i_ts_read = 50;    p_sys->csa = NULL;    /* Init PAT handler */    pat = &p_sys->pid[0];    PIDInit( pat, VLC_TRUE, NULL );    pat->psi->handle = dvbpsi_AttachPAT( (dvbpsi_pat_callback)PATCallBack,                                         p_demux );#ifdef TS_USE_DVB_SI    if( p_sys->b_meta )    {        ts_pid_t *sdt = &p_sys->pid[0x11];        ts_pid_t *eit = &p_sys->pid[0x12];        PIDInit( sdt, VLC_TRUE, NULL );        sdt->psi->handle =            dvbpsi_AttachDemux( (dvbpsi_demux_new_cb_t)PSINewTableCallBack,                                p_demux );        PIDInit( eit, VLC_TRUE, NULL );        eit->psi->handle =            dvbpsi_AttachDemux( (dvbpsi_demux_new_cb_t)PSINewTableCallBack,                                p_demux );        if( p_sys->b_dvb_control )        {            stream_Control( p_demux->s, STREAM_CONTROL_ACCESS,                            ACCESS_SET_PRIVATE_ID_STATE, 0x11, VLC_TRUE );            stream_Control( p_demux->s, STREAM_CONTROL_ACCESS,                            ACCESS_SET_PRIVATE_ID_STATE, 0x12, VLC_TRUE );        }    }#endif    /* Init PMT array */    p_sys->i_pmt = 0;    p_sys->pmt   = NULL;    /* Read config */    var_Create( p_demux, "ts-es-id-pid", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );    var_Get( p_demux, "ts-es-id-pid", &val );    p_sys->b_es_id_pid = val.b_bool;    var_Create( p_demux, "ts-out", VLC_VAR_STRING | VLC_VAR_DOINHERIT );    var_Get( p_demux, "ts-out", &val );    if( val.psz_string && *val.psz_string )    {        vlc_value_t mtu;        char *psz = strchr( val.psz_string, ':' );        int   i_port = 0;        p_sys->b_udp_out = VLC_TRUE;        if( psz )        {            *psz++ = '\0';            i_port = atoi( psz );        }        if( i_port <= 0 ) i_port  = 1234;        msg_Dbg( p_demux, "resend ts to '%s:%d'", val.psz_string, i_port );        p_sys->fd = net_OpenUDP( p_demux, "", 0, val.psz_string, i_port );        if( p_sys->fd < 0 )        {            msg_Err( p_demux, "failed to open udp socket, send disabled" );            p_sys->b_udp_out = VLC_FALSE;        }        else        {            var_Create( p_demux, "ts-out-mtu",                        VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );            var_Get( p_demux, "ts-out-mtu", &mtu );            p_sys->i_ts_read = mtu.i_int / p_sys->i_packet_size;            if( p_sys->i_ts_read <= 0 )            {                p_sys->i_ts_read = 1500 / p_sys->i_packet_size;            }            p_sys->buffer = malloc( p_sys->i_packet_size * p_sys->i_ts_read );        }    }    if( val.psz_string )    {        free( val.psz_string );    }    /* We handle description of an extra PMT */    var_Create( p_demux, "ts-extra-pmt", VLC_VAR_STRING | VLC_VAR_DOINHERIT );    var_Get( p_demux, "ts-extra-pmt", &val );    if( val.psz_string && strchr( val.psz_string, '=' ) != NULL )    {        char *psz = val.psz_string;        int  i_pid = strtol( psz, &psz, 0 );        if( i_pid >= 2 && i_pid < 8192 )        {            ts_pid_t *pmt = &p_sys->pid[i_pid];            msg_Dbg( p_demux, "extra pmt specified (pid=%d)", i_pid );            PIDInit( pmt, VLC_TRUE, NULL );            pmt->psi->i_prg = 1;            pmt->psi->prg = malloc( sizeof(ts_prg_psi_t) );            /* FIXME we should also ask for a number */            pmt->psi->prg[0]->handle =                dvbpsi_AttachPMT( 1, (dvbpsi_pmt_callback)PMTCallBack,                                  p_demux );            pmt->psi->prg[0]->i_number = 0; /* special one */            psz = strchr( psz, '=' ) + 1;   /* can't failed */            while( psz && *psz )            {                char *psz_next = strchr( psz, ',' );                int i_pid, i_stream_type;                if( psz_next )                {                    *psz_next++ = '\0';                }                i_pid = strtol( psz, &psz, 0 );                if( *psz == ':' )                {                    i_stream_type = strtol( psz + 1, &psz, 0 );                    if( i_pid >= 2 && i_pid < 8192 &&                        !p_sys->pid[i_pid].b_valid )                    {                        ts_pid_t *pid = &p_sys->pid[i_pid];                        PIDInit( pid, VLC_FALSE, pmt->psi);                        if( pmt->psi->prg[0]->i_pid_pcr <= 0 )                        {                            pmt->psi->prg[0]->i_pid_pcr = i_pid;                        }                        PIDFillFormat( pid, i_stream_type);                        if( pid->es->fmt.i_cat != UNKNOWN_ES )                        {                            if( p_sys->b_es_id_pid )                            {                                pid->es->fmt.i_id = i_pid;                            }                            msg_Dbg( p_demux, "  * es pid=%d type=%d "                                     "fcc=%4.4s", i_pid, i_stream_type,                                     (char*)&pid->es->fmt.i_codec );                            pid->es->id = es_out_Add( p_demux->out,                                                      &pid->es->fmt );                        }                    }                }                psz = psz_next;            }        }    }    if( val.psz_string )    {        free( val.psz_string );    }    var_Create( p_demux, "ts-csa-ck", VLC_VAR_STRING | VLC_VAR_DOINHERIT );    var_Get( p_demux, "ts-csa-ck", &val );    if( val.psz_string && *val.psz_string )    {        char *psz = val.psz_string;        if( psz[0] == '0' && ( psz[1] == 'x' || psz[1] == 'X' ) )        {            psz += 2;        }        if( strlen( psz ) != 16 )        {            msg_Warn( p_demux, "invalid csa ck (it must be 16 chars long)" );        }        else        {#ifndef UNDER_CE            uint64_t i_ck = strtoull( psz, NULL, 16 );#else            uint64_t i_ck = strtoll( psz, NULL, 16 );#endif            uint8_t ck[8];            int     i;            for( i = 0; i < 8; i++ )            {                ck[i] = ( i_ck >> ( 56 - 8*i) )&0xff;            }            msg_Dbg( p_demux, "using CSA scrambling with "                     "ck=%x:%x:%x:%x:%x:%x:%x:%x",                     ck[0], ck[1], ck[2], ck[3], ck[4], ck[5], ck[6], ck[7] );            p_sys->csa = csa_New();            csa_SetCW( p_sys->csa, ck, ck );        }    }    if( val.psz_string )    {        free( val.psz_string );    }    var_Create( p_demux, "ts-silent", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );    var_Get( p_demux, "ts-silent", &val );    p_sys->b_silent = val.b_bool;    return VLC_SUCCESS;}/***************************************************************************** * Close *****************************************************************************/static void Close( vlc_object_t *p_this ){    demux_t     *p_demux = (demux_t*)p_this;    demux_sys_t *p_sys = p_demux->p_sys;    int          i;    msg_Dbg( p_demux, "pid list:" );    for( i = 0; i < 8192; i++ )    {        ts_pid_t *pid = &p_sys->pid[i];        if( pid->b_valid && pid->psi )        {            switch( pid->i_pid )            {                case 0: /* PAT */                    dvbpsi_DetachPAT( pid->psi->handle );                    free( pid->psi );                    break;                case 1: /* CAT */                    free( pid->psi );                    break;                case 0x11: /* SDT */                case 0x12: /* EIT */                    dvbpsi_DetachDemux( pid->psi->handle );                    free( pid->psi );                    break;                default:                    PIDClean( p_demux->out, pid );                    break;            }        }        else if( pid->b_valid && pid->es )        {            PIDClean( p_demux->out, pid );        }        if( pid->b_seen )        {            msg_Dbg( p_demux, "  - pid[%d] seen", pid->i_pid );        }        if( p_sys->b_dvb_control && pid->i_pid > 0 )        {            /* too much */            stream_Control( p_demux->s, STREAM_CONTROL_ACCESS, ACCESS_SET_PRIVATE_ID_STATE, pid->i_pid, VLC_FALSE );        }    }    if( p_sys->b_udp_out )    {        net_Close( p_sys->fd );        free( p_sys->buffer );    }    if( p_sys->csa )    {        csa_Delete( p_sys->csa );    }    if( p_sys->i_pmt ) free( p_sys->pmt );    if ( p_sys->p_programs_list )    {        vlc_value_t val;        val.p_list = p_sys->p_programs_list;        var_Change( p_demux, "programs", VLC_VAR_FREELIST, &val, NULL );    }    free( p_sys );}/***************************************************************************** * Demux: *****************************************************************************/static int Demux( demux_t *p_demux ){    demux_sys_t *p_sys = p_demux->p_sys;    int          i_pkt;    /* We read at most 100 TS packet or until a frame is completed */    for( i_pkt = 0; i_pkt < p_sys->i_ts_read; i_pkt++ )    {        vlc_bool_t  b_frame = VLC_FALSE;        block_t     *p_pkt;        ts_pid_t    *p_pid;        /* Get a new TS packet */        if( !( p_pkt = stream_Block( p_demux->s, p_sys->i_packet_size ) ) )        {            msg_Dbg( p_demux, "eof ?" );            return 0;        }        /* Check sync byte and re-sync if needed */        if( p_pkt->p_buffer[0] != 0x47 )        {            msg_Warn( p_demux, "lost synchro" );            block_Release( p_pkt );            while( !p_demux->b_die )            {                uint8_t *p_peek;                int i_peek, i_skip = 0;                i_peek = stream_Peek( p_demux->s, &p_peek,                                      p_sys->i_packet_size * 10 );                if( i_peek < p_sys->i_packet_size + 1 )                {                    msg_Dbg( p_demux, "eof ?" );                    return 0;                }                while( i_skip < i_peek - p_sys->i_packet_size )                {                    if( p_peek[i_skip] == 0x47 &&                        p_peek[i_skip + p_sys->i_packet_size] == 0x47 )                    {                        break;                    }                    i_skip++;                }                msg_Dbg( p_demux, "skipping %d bytes of garbage", i_skip );                stream_Read( p_demux->s, NULL, i_skip );                if( i_skip < i_peek - p_sys->i_packet_size )                {                    break;                }            }            if( !( p_pkt = stream_Block( p_demux->s, p_sys->i_packet_size ) ) )            {                msg_Dbg( p_demux, "eof ?" );                return 0;            }        }        if( p_sys->b_udp_out )        {            memcpy( &p_sys->buffer[i_pkt * p_sys->i_packet_size],                    p_pkt->p_buffer, p_sys->i_packet_size );        }        /* Parse the TS packet */        p_pid = &p_sys->pid[PIDGet( p_pkt )];        if( p_pid->b_valid )        {            if( p_pid->psi )            {                if( p_pid->i_pid == 0 || p_pid->i_pid == 0x11 || p_pid->i_pid == 0x12 )                {                    dvbpsi_PushPacket( p_pid->psi->handle, p_pkt->p_buffer );                }                else                {                    int i_prg;                    for( i_prg = 0; i_prg < p_pid->psi->i_prg; i_prg++ )                    {                        dvbpsi_PushPacket( p_pid->psi->prg[i_prg]->handle,                                           p_pkt->p_buffer );                    }                }                block_Release( p_pkt );            }            else if( !p_sys->b_udp_out )            {                b_frame = GatherPES( p_demux, p_pid, p_pkt );            }            else            {                PCRHandle( p_demux, p_pid, p_pkt );                block_Release( p_pkt );            }        }        else        {            if( !p_pid->b_seen )            {                msg_Dbg( p_demux, "pid[%d] unknown", p_pid->i_pid );            }            /* We have to handle PCR if present */

⌨️ 快捷键说明

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