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

📄 ts.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    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 );    }    /* If in dump mode, then close the file */    if( p_sys->b_file_out )    {        msg_Info( p_demux ,"closing %s ("I64Fd" Kbytes dumped)", p_sys->psz_file,                  p_sys->i_write / 1024 );        if( p_sys->p_file != stdout )        {            fclose( p_sys->p_file );            p_sys->p_file = NULL;        }        free( p_sys->buffer );    }    free( p_sys->psz_file );    p_sys->psz_file = NULL;    free( p_sys );}/***************************************************************************** * DemuxFile: *****************************************************************************/static int DemuxFile( demux_t *p_demux ){    demux_sys_t *p_sys = p_demux->p_sys;    uint8_t     *p_buffer = p_sys->buffer; /* Put first on sync byte */    int i_diff= 0;    int i_data= 0;    int i_pos = 0;    int i_bufsize = p_sys->i_packet_size * p_sys->i_ts_read;    i_data = stream_Read( p_demux->s, p_sys->buffer, i_bufsize );    if( (i_data <= 0) && (i_data < p_sys->i_packet_size) )    {        msg_Dbg( p_demux, "error reading malformed packets" );        return i_data;    }    /* Test continuity counter */    while( i_pos < i_data )    {        ts_pid_t    *p_pid;   /* point to a PID structure */        vlc_bool_t b_payload; /* indicates a packet with payload */        vlc_bool_t b_adaptation; /* adaptation field */        int i_cc  = 0;        /* continuity counter */        if( p_sys->buffer[i_pos] != 0x47 )        {            msg_Warn( p_demux, "lost sync" );            while( !p_demux->b_die && (i_pos < i_data) )            {                i_pos++;                if( p_sys->buffer[i_pos] == 0x47 )                    break;            }            if( !p_demux->b_die )                msg_Warn( p_demux, "sync found" );        }        /* continuous when (one of this):         * diff == 1         * diff == 0 and payload == 0         * diff == 0 and duplicate packet (playload != 0) <- should we         *   test the content ?         */        i_cc  = p_buffer[i_pos+3]&0x0f;        b_payload = p_buffer[i_pos+3]&0x10;        b_adaptation = p_buffer[i_pos+3]&0x20;        /* Get the PID */        p_pid = &p_sys->pid[ ((p_buffer[i_pos+1]&0x1f)<<8)|p_buffer[i_pos+2] ];        /* Detect discontinuity indicator in adaptation field */        if( b_adaptation && p_buffer[i_pos + 4] > 0 )        {            if( p_buffer[i_pos+5]&0x80 )                msg_Warn( p_demux, "discontinuity indicator (pid=%d) ", p_pid->i_pid );            if( p_buffer[i_pos+5]&0x40 )                msg_Warn( p_demux, "random access indicator (pid=%d) ", p_pid->i_pid );        }        i_diff = ( i_cc - p_pid->i_cc )&0x0f;        if( b_payload && i_diff == 1 )        {            p_pid->i_cc = ( p_pid->i_cc + 1 ) & 0xf;        }        else        {            if( p_pid->i_cc == 0xff )            {                msg_Warn( p_demux, "first packet for pid=%d cc=0x%x",                        p_pid->i_pid, i_cc );                p_pid->i_cc = i_cc;            }            else if( i_diff != 0 )            {                /* FIXME what to do when discontinuity_indicator is set ? */                msg_Warn( p_demux, "transport error detected 0x%x instead of 0x%x",                          i_cc, ( p_pid->i_cc + 1 )&0x0f );                p_pid->i_cc = i_cc;                /* Mark transport error in the TS packet. */                p_buffer[i_pos+1] |= 0x80;            }        }        /* Test if user wants to decrypt it first */        if( p_sys->csa )            csa_Decrypt( p_demux->p_sys->csa, &p_buffer[i_pos], p_demux->p_sys->i_csa_pkt_size );        i_pos += p_sys->i_packet_size;    }    /* Then write */    i_data = fwrite( p_sys->buffer, 1, i_data, p_sys->p_file );    if( i_data < 0 )    {        msg_Err( p_demux, "failed to write data" );        return -1;    }#if 0    msg_Dbg( p_demux, "dumped %d bytes", i_data );#endif    p_sys->i_write += i_data;    return 1;}/***************************************************************************** * 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 */            PCRHandle( p_demux, p_pid, p_pkt );            block_Release( p_pkt );        }        p_pid->b_seen = VLC_TRUE;        if( b_frame )        {            break;        }    }    if( p_sys->b_udp_out )    {        /* Send the complete block */        net_Write( p_demux, p_sys->fd, NULL, p_sys->buffer,                   p_sys->i_ts_read * p_sys->i_packet_size );    }    return 1;}/***************************************************************************** * Control: *****************************************************************************/static int Control( demux_t *p_demux, int i_query, va_list args ){    demux_sys_t *p_sys = p_demux->p_sys;    double f, *pf;    int64_t i64;    int64_t *pi64;    int i_int;    if( p_sys->b_file_out )        return demux2_vaControlHelper( p_demux->s, 0, -1, 0, 1, i_query, args );    switch( i_query )    {        case DEMUX_GET_POSITION:            pf = (double*) va_arg( args, double* );            i64 = stream_Size( p_demux->s );            if( i64 > 0 )            {                *pf = (double)stream_Tell( p_demux->s ) / (double)i64;            }            else            {                *pf = 0.0;            }            return VLC_SUCCESS;        case DEMUX_SET_POSITION:            f = (double) va_arg( args, double );            i64 = stream_Size( p_demux->s );            es_out_Control( p_demux->out, ES_OUT_RESET_PCR );            if( stream_Seek( p_demux->s, (int64_t)(i64 * f) ) )            {                return VLC_EGENERIC;            }            return VLC_SUCCESS;#if 0        case DEMUX_GET_TIME:            pi64 = (int64_t*)va_arg( args, int64_t * );            if( p_sys->i_time < 0 )            {                *pi64 = 0;                return VLC_EGENERIC;            }            *pi64 = p_sys->i_time;            return VLC_SUCCESS;        case DEMUX_GET_LENGTH:            pi64 = (int64_t*)va_arg( args, int64_t * );            if( p_sys->i_mux_rate > 0 )            {                *pi64 = I64C(1000000) * ( stream_Size( p_demux->s ) / 50 ) /                        p_sys->i_mux_rate;                return VLC_SUCCESS;            }            *pi64 = 0;            return VLC_EGENERIC;#else        case DEMUX_GET_TIME:        case DEMUX_GET_LENGTH:            pi64 = (int64_t*)va_arg( args, int64_t * );            *pi64 = 0;            return VLC_SUCCESS;#endif        case DEMUX_SET_GROUP:        {            uint16_t i_vpid = 0, i_apid1 = 0, i_apid2 = 0, i_apid3 = 0;            ts_prg_psi_t *p_prg = NULL;            vlc_list_t *p_list;            i_int = (int)va_arg( args, int );            p_list = (vlc_list_t *)va_arg( args, vlc_list_t * );            msg_Dbg( p_demux, "DEMUX_SET_GROUP %d %p", i_int, p_list );            if( p_sys->b_dvb_control && i_int > 0 && i_int != p_sys->i_dvb_program )            {                int i_pmt_pid = -1;                int i;

⌨️ 快捷键说明

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