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

📄 ts.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
            p_pes->i_pts = i_pts * 100 / 9;        }        p_pes->i_length = i_length * 100 / 9;        p_block = block_ChainGather( p_pes );        if( pid->es->fmt.i_codec == VLC_FOURCC( 's', 'u', 'b', 't' ) )        {            if( i_pes_size > 0 && p_block->i_buffer > i_pes_size )            {                p_block->i_buffer = i_pes_size;            }            /* Append a \0 */            p_block = block_Realloc( p_block, 0, p_block->i_buffer + 1 );            p_block->p_buffer[p_block->i_buffer -1] = '\0';        }        for( i = 0; i < pid->i_extra_es; i++ )        {            es_out_Send( p_demux->out, pid->extra_es[i]->id,                         block_Duplicate( p_block ) );        }        es_out_Send( p_demux->out, pid->es->id, p_block );    }    else    {        msg_Warn( p_demux, "empty pes" );    }}static void PCRHandle( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk ){    demux_sys_t   *p_sys = p_demux->p_sys;    const uint8_t *p = p_bk->p_buffer;    if( ( p[3]&0x20 ) && /* adaptation */        ( p[5]&0x10 ) &&        ( p[4] >= 7 ) )    {        int i;        mtime_t i_pcr;  /* 33 bits */        i_pcr = ( (mtime_t)p[6] << 25 ) |                ( (mtime_t)p[7] << 17 ) |                ( (mtime_t)p[8] << 9 ) |                ( (mtime_t)p[9] << 1 ) |                ( (mtime_t)p[10] >> 7 );        /* Search program and set the PCR */        for( i = 0; i < p_sys->i_pmt; i++ )        {            int i_prg;            for( i_prg = 0; i_prg < p_sys->pmt[i]->psi->i_prg; i_prg++ )            {                if( pid->i_pid == p_sys->pmt[i]->psi->prg[i_prg]->i_pid_pcr )                {                    es_out_Control( p_demux->out, ES_OUT_SET_GROUP_PCR,                                    (int)p_sys->pmt[i]->psi->prg[i_prg]->i_number,                                    (int64_t)(i_pcr * 100 / 9) );                }            }        }    }}static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk ){    const uint8_t    *p = p_bk->p_buffer;    const vlc_bool_t b_unit_start = p[1]&0x40;    const vlc_bool_t b_adaptation = p[3]&0x20;    const vlc_bool_t b_payload    = p[3]&0x10;    const int        i_cc         = p[3]&0x0f;   /* continuity counter */    vlc_bool_t       b_discontinuity = VLC_FALSE;/* discontinuity */        /* transport_scrambling_control is ignored */    int         i_skip = 0;    vlc_bool_t  i_ret  = VLC_FALSE;    int         i_diff;#if 0    msg_Dbg( p_demux, "pid=%d unit_start=%d adaptation=%d payload=%d "             "cc=0x%x", pid->i_pid, b_unit_start, b_adaptation,             b_payload, i_cc );#endif    /* For now, ignore additional error correction     * TODO: handle Reed-Solomon 204,188 error correction */    p_bk->i_buffer = TS_PACKET_SIZE_188;    if( p[1]&0x80 )    {        msg_Dbg( p_demux, "transport_error_indicator set (pid=%d)",                 pid->i_pid );        if( pid->es->p_pes ) //&& pid->es->fmt.i_cat == VIDEO_ES )            pid->es->p_pes->i_flags |= BLOCK_FLAG_CORRUPTED;    }    if( p_demux->p_sys->csa )    {        csa_Decrypt( p_demux->p_sys->csa, p_bk->p_buffer, p_demux->p_sys->i_csa_pkt_size );    }    if( !b_adaptation )    {        /* We don't have any adaptation_field, so payload starts         * immediately after the 4 byte TS header */        i_skip = 4;    }    else    {        /* p[4] is adaptation_field_length minus one */        i_skip = 5 + p[4];        if( p[4] > 0 )        {            /* discontinuity indicator found in stream */            b_discontinuity = (p[5]&0x80) ? VLC_TRUE : VLC_FALSE;            if( b_discontinuity && pid->es->p_pes )            {                msg_Warn( p_demux, "discontinuity indicator (pid=%d) ",                            pid->i_pid );                /* pid->es->p_pes->i_flags |= BLOCK_FLAG_DISCONTINUITY; */            }#if 0            if( p[5]&0x40 )                msg_Dbg( p_demux, "random access indicator (pid=%d) ", pid->i_pid );#endif        }    }    /* Test continuity counter */    /* 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_diff = ( i_cc - pid->i_cc )&0x0f;    if( b_payload && i_diff == 1 )    {        pid->i_cc = ( pid->i_cc + 1 ) & 0xf;    }    else    {        if( pid->i_cc == 0xff )        {            msg_Warn( p_demux, "first packet for pid=%d cc=0x%x",                      pid->i_pid, i_cc );            pid->i_cc = i_cc;        }        else if( i_diff != 0 && !b_discontinuity )        {            msg_Warn( p_demux, "discontinuity received 0x%x instead of 0x%x (pid=%d)",                      i_cc, ( pid->i_cc + 1 )&0x0f, pid->i_pid );            pid->i_cc = i_cc;            if( pid->es->p_pes && pid->es->fmt.i_cat != VIDEO_ES )            {                /* Small video artifacts are usually better then                 * dropping full frames */                pid->es->p_pes->i_flags |= BLOCK_FLAG_CORRUPTED;            }        }    }    PCRHandle( p_demux, pid, p_bk );    if( i_skip >= 188 || pid->es->id == NULL || p_demux->p_sys->b_udp_out )    {        block_Release( p_bk );        return i_ret;    }    /* We have to gather it */    p_bk->p_buffer += i_skip;    p_bk->i_buffer -= i_skip;    if( b_unit_start )    {        if( pid->es->p_pes )        {            ParsePES( p_demux, pid );            i_ret = VLC_TRUE;        }        block_ChainLastAppend( &pid->es->pp_last, p_bk );        if( p_bk->i_buffer > 6 )        {            pid->es->i_pes_size = GetWBE( &p_bk->p_buffer[4] );            if( pid->es->i_pes_size > 0 )            {                pid->es->i_pes_size += 6;            }        }        pid->es->i_pes_gathered += p_bk->i_buffer;        if( pid->es->i_pes_size > 0 &&            pid->es->i_pes_gathered >= pid->es->i_pes_size )        {            ParsePES( p_demux, pid );            i_ret = VLC_TRUE;        }    }    else    {        if( pid->es->p_pes == NULL )        {            /* msg_Dbg( p_demux, "broken packet" ); */            block_Release( p_bk );        }        else        {            block_ChainLastAppend( &pid->es->pp_last, p_bk );            pid->es->i_pes_gathered += p_bk->i_buffer;            if( pid->es->i_pes_size > 0 &&                pid->es->i_pes_gathered >= pid->es->i_pes_size )            {                ParsePES( p_demux, pid );                i_ret = VLC_TRUE;            }        }    }    return i_ret;}static int PIDFillFormat( ts_pid_t *pid, int i_stream_type ){    es_format_t *fmt = &pid->es->fmt;    switch( i_stream_type )    {        case 0x01:  /* MPEG-1 video */        case 0x02:  /* MPEG-2 video */        case 0x80:  /* MPEG-2 MOTO video */            es_format_Init( fmt, VIDEO_ES, VLC_FOURCC( 'm', 'p', 'g', 'v' ) );            break;        case 0x03:  /* MPEG-1 audio */        case 0x04:  /* MPEG-2 audio */            es_format_Init( fmt, AUDIO_ES, VLC_FOURCC( 'm', 'p', 'g', 'a' ) );            break;        case 0x11:  /* MPEG4 (audio) */        case 0x0f:  /* ISO/IEC 13818-7 Audio with ADTS transport syntax */            es_format_Init( fmt, AUDIO_ES, VLC_FOURCC( 'm', 'p', '4', 'a' ) );            break;        case 0x10:  /* MPEG4 (video) */            es_format_Init( fmt, VIDEO_ES, VLC_FOURCC( 'm', 'p', '4', 'v' ) );            pid->es->b_gather = VLC_TRUE;            break;        case 0x1B:  /* H264 <- check transport syntax/needed descriptor */            es_format_Init( fmt, VIDEO_ES, VLC_FOURCC( 'h', '2', '6', '4' ) );            break;        case 0x81:  /* A52 (audio) */            es_format_Init( fmt, AUDIO_ES, VLC_FOURCC( 'a', '5', '2', ' ' ) );            break;        case 0x82:  /* DVD_SPU (sub) */            es_format_Init( fmt, SPU_ES, VLC_FOURCC( 's', 'p', 'u', ' ' ) );            break;        case 0x83:  /* LPCM (audio) */            es_format_Init( fmt, AUDIO_ES, VLC_FOURCC( 'l', 'p', 'c', 'm' ) );            break;        case 0x84:  /* SDDS (audio) */            es_format_Init( fmt, AUDIO_ES, VLC_FOURCC( 's', 'd', 'd', 's' ) );            break;        case 0x85:  /* DTS (audio) */            es_format_Init( fmt, AUDIO_ES, VLC_FOURCC( 'd', 't', 's', ' ' ) );            break;        case 0x91:  /* A52 vls (audio) */            es_format_Init( fmt, AUDIO_ES, VLC_FOURCC( 'a', '5', '2', 'b' ) );            break;        case 0x92:  /* DVD_SPU vls (sub) */            es_format_Init( fmt, SPU_ES, VLC_FOURCC( 's', 'p', 'u', 'b' ) );            break;        case 0x94:  /* SDDS (audio) */            es_format_Init( fmt, AUDIO_ES, VLC_FOURCC( 's', 'd', 'd', 'b' ) );            break;        case 0xa0:  /* MSCODEC vlc (video) (fixed later) */            es_format_Init( fmt, UNKNOWN_ES, 0 );            pid->es->b_gather = VLC_TRUE;            break;        case 0x06:  /* PES_PRIVATE  (fixed later) */        case 0x12:  /* MPEG-4 generic (sub/scene/...) (fixed later) */        default:            es_format_Init( fmt, UNKNOWN_ES, 0 );            break;    }    /* PES packets usually contain truncated frames */    fmt->b_packetized = VLC_FALSE;    return fmt->i_cat == UNKNOWN_ES ? VLC_EGENERIC : VLC_SUCCESS ;}/***************************************************************************** * MP4 specific functions (IOD parser) *****************************************************************************/static int  IODDescriptorLength( int *pi_data, uint8_t **pp_data ){    unsigned int i_b;    unsigned int i_len = 0;    do    {        i_b = **pp_data;        (*pp_data)++;        (*pi_data)--;        i_len = ( i_len << 7 ) + ( i_b&0x7f );    } while( i_b&0x80 );    return( i_len );}static int IODGetByte( int *pi_data, uint8_t **pp_data ){    if( *pi_data > 0 )    {        const int i_b = **pp_data;        (*pp_data)++;        (*pi_data)--;        return( i_b );    }    return( 0 );}static int IODGetWord( int *pi_data, uint8_t **pp_data ){    const int i1 = IODGetByte( pi_data, pp_data );    const int i2 = IODGetByte( pi_data, pp_data );    return( ( i1 << 8 ) | i2 );}static int IODGet3Bytes( int *pi_data, uint8_t **pp_data ){    const int i1 = IODGetByte( pi_data, pp_data );    const int i2 = IODGetByte( pi_data, pp_data );    const int i3 = IODGetByte( pi_data, pp_data );    return( ( i1 << 16 ) | ( i2 << 8) | i3 );}static uint32_t IODGetDWord( int *pi_data, uint8_t **pp_data ){    const uint32_t i1 = IODGetWord( pi_data, pp_data );    const uint32_t i2 = IODGetWord( pi_data, pp_data );    return( ( i1 << 16 ) | i2 );}static char* IODGetURL( int *pi_data, uint8_t **pp_data ){    char *url;    int i_url_len, i;    i_url_len = IODGetByte( pi_data, pp_data );    url = malloc( i_url_len + 1 );    for( i = 0; i < i_url_len; i++ )    {        url[i] = IODGetByte( pi_data, pp_data );    }    url[i_url_len] = '\0';    return( url );}static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ){    iod_descriptor_t *p_iod;    int i;    int i_es_index;    uint8_t     i_flags, i_iod_tag, byte1, byte2, byte3;    vlc_bool_t  b_url;    int         i_iod_length;    p_iod = malloc( sizeof( iod_descriptor_t ) );    memset( p_iod, 0, sizeof( iod_descriptor_t ) );#ifdef TS_DEBUG    fprintf( stderr, "\n************ IOD ************" );#endif    for( i = 0; i < 255; i++ )    {        p_iod->es_descr[i].b_ok = 0;    }    i_es_index = 0;    if( i_data < 3 )    {        return p_iod;    }    byte1 = IODGetByte( &i_data, &p_data );    byte2 = IODGetByte( &i_data, &p_data );    byte3 = IODGetByte( &i_data, &p_data );    if( byte2 == 0x02 ) //old vlc's buggy implementation of the IOD_descriptor    {        p_iod->i_iod_label_scope = 0x11;        p_iod->i_iod_label = byte1;        i_iod_tag = byte2;    }    else  //correct implementation of the IOD_descriptor    {        p_iod->i_iod_label_scope = byte1;        p_iod->i_iod_label = byte2;        i_iod_tag = byte3;    }#ifdef TS_DEBUG    fprintf( stderr, "\n* iod_label:%d", p_iod->i_iod_label );    fprintf( stderr, "\n* ===========" );    fprintf( stderr, "\n* t

⌨️ 快捷键说明

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