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

📄 ts.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
        }        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,                            false );        }    }    if( p_sys->b_udp_out )    {        net_Close( p_sys->fd );        free( p_sys->buffer );    }    vlc_mutex_lock( &p_sys->csa_lock );    if( p_sys->csa )    {        var_DelCallback( p_demux, "ts-csa-ck", ChangeKeyCallback, NULL );        var_DelCallback( p_demux, "ts-csa2-ck", ChangeKeyCallback, NULL );        csa_Delete( p_sys->csa );        p_sys->csa = NULL;    }    vlc_mutex_unlock( &p_sys->csa_lock );    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 (%"PRId64" 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;    vlc_mutex_destroy( &p_sys->csa_lock );    free( p_sys );}/***************************************************************************** * ChangeKeyCallback: called when changing the odd encryption key on the fly. *****************************************************************************/static int ChangeKeyCallback( vlc_object_t *p_this, char const *psz_cmd,                           vlc_value_t oldval, vlc_value_t newval,                           void *p_data ){    VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval);    demux_t     *p_demux = (demux_t*)p_this;    demux_sys_t *p_sys = p_demux->p_sys;    int         i_tmp = (intptr_t)p_data;    vlc_mutex_lock( &p_sys->csa_lock );    if ( i_tmp )        i_tmp = csa_SetCW( p_this, p_sys->csa, newval.psz_string, true );    else        i_tmp = csa_SetCW( p_this, p_sys->csa, newval.psz_string, false );    vlc_mutex_unlock( &p_sys->csa_lock );    return i_tmp;}/***************************************************************************** * 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 */        bool      b_payload; /* indicates a packet with payload */        bool      b_adaptation; /* adaptation field */        int       i_cc  = 0;    /* continuity counter */        if( p_sys->buffer[i_pos] != 0x47 )        {            msg_Warn( p_demux, "lost sync" );            while( vlc_object_alive (p_demux) && (i_pos < i_data) )            {                i_pos++;                if( p_sys->buffer[i_pos] == 0x47 )                    break;            }            if( vlc_object_alive (p_demux) )                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 )        {            vlc_mutex_lock( &p_sys->csa_lock );            csa_Decrypt( p_demux->p_sys->csa, &p_buffer[i_pos], p_demux->p_sys->i_csa_pkt_size );            vlc_mutex_unlock( &p_sys->csa_lock );        }        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++ )    {        bool         b_frame = 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( vlc_object_alive (p_demux) )            {                const 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 = 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 DVBEventInformation( demux_t *p_demux, int64_t *pi_time, int64_t *pi_length ){    demux_sys_t *p_sys = p_demux->p_sys;    if( pi_length )        *pi_length = 0;    if( pi_time )        *pi_time = 0;#ifdef HAVE_TIME_H    if( p_sys->b_dvb_control && p_sys->i_dvb_length > 0 )    {        /* FIXME we should not use time() but read the date from the tdt */        const time_t t = time( NULL );        if( p_sys->i_dvb_start <= t && t < p_sys->i_dvb_start + p_sys->i_dvb_length )        {            if( pi_length )                *pi_length = p_sys->i_dvb_length * INT64_C(1000000);            if( pi_time )                *pi_time   = (t - p_sys->i_dvb_start) * INT64_C(1000000);            return VLC_SUCCESS;        }    }#endif    return VLC_EGENERIC;}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 demux_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            {                int64_t i_time, i_length;                if( !DVBEventInformation( p_demux, &i_time, &i_length ) && i_length > 0 )                    *pf = (double)i_time/(double)i_length;                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;            }

⌨️ 快捷键说明

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