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

📄 udp.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * Close: close the target *****************************************************************************/static void Close( vlc_object_t * p_this ){    sout_access_out_t     *p_access = (sout_access_out_t*)p_this;    sout_access_out_sys_t *p_sys = p_access->p_sys;    int i;    p_sys->p_thread->b_die = 1;    for( i = 0; i < 10; i++ )    {        block_t *p_dummy = block_New( p_access, p_sys->i_mtu );        p_dummy->i_dts = 0;        p_dummy->i_pts = 0;        p_dummy->i_length = 0;        memset( p_dummy->p_buffer, 0, p_dummy->i_buffer );        block_FifoPut( p_sys->p_thread->p_fifo, p_dummy );    }    vlc_thread_join( p_sys->p_thread );    block_FifoRelease( p_sys->p_thread->p_fifo );    block_FifoRelease( p_sys->p_thread->p_empty_blocks );    if( p_sys->p_buffer ) block_Release( p_sys->p_buffer );    net_Close( p_sys->p_thread->i_handle );    vlc_object_detach( p_sys->p_thread );    vlc_object_destroy( p_sys->p_thread );    /* update p_sout->i_out_pace_nocontrol */    p_access->p_sout->i_out_pace_nocontrol--;    msg_Dbg( p_access, "udp access output closed" );    free( p_sys );}/***************************************************************************** * Write: standard write on a file descriptor. *****************************************************************************/static int Write( sout_access_out_t *p_access, block_t *p_buffer ){    sout_access_out_sys_t *p_sys = p_access->p_sys;    int i_len = 0;    while( p_buffer )    {        block_t *p_next;        int i_packets = 0;        if( !p_sys->b_mtu_warning && p_buffer->i_buffer > p_sys->i_mtu )        {            msg_Warn( p_access, "packet size > MTU, you should probably "                      "increase the MTU" );            p_sys->b_mtu_warning = VLC_TRUE;        }        /* Check if there is enough space in the buffer */        if( p_sys->p_buffer &&            p_sys->p_buffer->i_buffer + p_buffer->i_buffer > p_sys->i_mtu )        {            if( p_sys->p_buffer->i_dts + p_sys->p_thread->i_caching < mdate() )            {                msg_Dbg( p_access, "late packet for udp input (" I64Fd ")",                         mdate() - p_sys->p_buffer->i_dts                          - p_sys->p_thread->i_caching );            }            block_FifoPut( p_sys->p_thread->p_fifo, p_sys->p_buffer );            p_sys->p_buffer = NULL;        }        i_len += p_buffer->i_buffer;        while( p_buffer->i_buffer )        {            int i_write = __MIN( p_buffer->i_buffer, p_sys->i_mtu );            i_packets++;            if( !p_sys->p_buffer )            {                p_sys->p_buffer = NewUDPPacket( p_access, p_buffer->i_dts );                if( !p_sys->p_buffer ) break;            }            memcpy( p_sys->p_buffer->p_buffer + p_sys->p_buffer->i_buffer,                    p_buffer->p_buffer, i_write );            p_sys->p_buffer->i_buffer += i_write;            p_buffer->p_buffer += i_write;            p_buffer->i_buffer -= i_write;            if ( p_buffer->i_flags & BLOCK_FLAG_CLOCK )            {                if ( p_sys->p_buffer->i_flags & BLOCK_FLAG_CLOCK )                    msg_Warn( p_access, "putting two PCRs at once" );                p_sys->p_buffer->i_flags |= BLOCK_FLAG_CLOCK;            }            if( p_sys->p_buffer->i_buffer == p_sys->i_mtu || i_packets > 1 )            {                /* Flush */                if( p_sys->p_buffer->i_dts + p_sys->p_thread->i_caching                      < mdate() )                {                    msg_Dbg( p_access, "late packet for udp input (" I64Fd ")",                             mdate() - p_sys->p_buffer->i_dts                              - p_sys->p_thread->i_caching );                }                block_FifoPut( p_sys->p_thread->p_fifo, p_sys->p_buffer );                p_sys->p_buffer = NULL;            }        }        p_next = p_buffer->p_next;        block_Release( p_buffer );        p_buffer = p_next;    }    return( p_sys->p_thread->b_error ? -1 : i_len );}/***************************************************************************** * WriteRaw: write p_buffer without trying to fill mtu *****************************************************************************/static int WriteRaw( sout_access_out_t *p_access, block_t *p_buffer ){    sout_access_out_sys_t   *p_sys = p_access->p_sys;    block_t *p_buf;    int i_len;    while ( p_sys->p_thread->p_empty_blocks->i_depth >= MAX_EMPTY_BLOCKS )    {        p_buf = block_FifoGet(p_sys->p_thread->p_empty_blocks);        block_Release( p_buf );    }    i_len = p_buffer->i_buffer;    block_FifoPut( p_sys->p_thread->p_fifo, p_buffer );    return( p_sys->p_thread->b_error ? -1 : i_len );}/***************************************************************************** * Seek: seek to a specific location in a file *****************************************************************************/static int Seek( sout_access_out_t *p_access, off_t i_pos ){    msg_Err( p_access, "UDP sout access cannot seek" );    return -1;}/***************************************************************************** * NewUDPPacket: allocate a new UDP packet of size p_sys->i_mtu *****************************************************************************/static block_t *NewUDPPacket( sout_access_out_t *p_access, mtime_t i_dts){    sout_access_out_sys_t *p_sys = p_access->p_sys;    block_t *p_buffer;    while ( p_sys->p_thread->p_empty_blocks->i_depth > MAX_EMPTY_BLOCKS )    {        p_buffer = block_FifoGet( p_sys->p_thread->p_empty_blocks );        block_Release( p_buffer );    }    if( p_sys->p_thread->p_empty_blocks->i_depth == 0 )    {        p_buffer = block_New( p_access->p_sout, p_sys->i_mtu );    }    else    {        p_buffer = block_FifoGet(p_sys->p_thread->p_empty_blocks );               p_buffer->i_flags = 0;        p_buffer = block_Realloc( p_buffer, 0, p_sys->i_mtu );    }    p_buffer->i_dts = i_dts;    p_buffer->i_buffer = 0;    if( p_sys->b_rtpts )    {        mtime_t i_timestamp = p_buffer->i_dts * 9 / 100;        /* add rtp/ts header */        p_buffer->p_buffer[0] = 0x80;        p_buffer->p_buffer[1] = 0x21; // mpeg2-ts        p_buffer->p_buffer[2] = ( p_sys->i_sequence_number >> 8 )&0xff;        p_buffer->p_buffer[3] = p_sys->i_sequence_number&0xff;        p_sys->i_sequence_number++;        p_buffer->p_buffer[4] = ( i_timestamp >> 24 )&0xff;        p_buffer->p_buffer[5] = ( i_timestamp >> 16 )&0xff;        p_buffer->p_buffer[6] = ( i_timestamp >>  8 )&0xff;        p_buffer->p_buffer[7] = i_timestamp&0xff;        p_buffer->p_buffer[ 8] = ( p_sys->i_ssrc >> 24 )&0xff;        p_buffer->p_buffer[ 9] = ( p_sys->i_ssrc >> 16 )&0xff;        p_buffer->p_buffer[10] = ( p_sys->i_ssrc >>  8 )&0xff;        p_buffer->p_buffer[11] = p_sys->i_ssrc&0xff;        p_buffer->i_buffer = 12;    }    return p_buffer;}/***************************************************************************** * ThreadWrite: Write a packet on the network at the good time. *****************************************************************************/static void ThreadWrite( vlc_object_t *p_this ){    sout_access_thread_t *p_thread = (sout_access_thread_t*)p_this;    mtime_t              i_date_last = -1;    mtime_t              i_to_send = p_thread->i_group;    int                  i_dropped_packets = 0;#if defined(WIN32) || defined(UNDER_CE)    char strerror_buf[WINSOCK_STRERROR_SIZE];# define strerror( x ) winsock_strerror( strerror_buf )#endif    while( !p_thread->b_die )    {        block_t *p_pk;        mtime_t       i_date, i_sent;#if 0        if( (i++ % 1000)==0 ) {          int i = 0;          int j = 0;          block_t *p_tmp = p_thread->p_empty_blocks->p_first;          while( p_tmp ) { p_tmp = p_tmp->p_next; i++;}          p_tmp = p_thread->p_fifo->p_first;          while( p_tmp ) { p_tmp = p_tmp->p_next; j++;}	  msg_Err( p_thread, "fifo depth: %d/%d, empty blocks: %d/%d",                   p_thread->p_fifo->i_depth, j,p_thread->p_empty_blocks->i_depth,i );	}#endif        p_pk = block_FifoGet( p_thread->p_fifo );        i_date = p_thread->i_caching + p_pk->i_dts;        if( i_date_last > 0 )        {            if( i_date - i_date_last > 2000000 )            {                if( !i_dropped_packets )                    msg_Dbg( p_thread, "mmh, hole ("I64Fd" > 2s) -> drop",                             i_date - i_date_last );                block_FifoPut( p_thread->p_empty_blocks, p_pk );                i_date_last = i_date;                i_dropped_packets++;                continue;            }            else if( i_date - i_date_last < -1000 )            {                if( !i_dropped_packets )                    msg_Dbg( p_thread, "mmh, packets in the past ("I64Fd")",                             i_date_last - i_date );            }        }        i_to_send--;        if( !i_to_send || (p_pk->i_flags & BLOCK_FLAG_CLOCK) )        {            mwait( i_date );            i_to_send = p_thread->i_group;        }        if( send( p_thread->i_handle, p_pk->p_buffer, p_pk->i_buffer, 0 )              == -1 )        {            msg_Warn( p_thread, "send error: %s", strerror(errno) );        }        if( i_dropped_packets )        {            msg_Dbg( p_thread, "dropped %i packets", i_dropped_packets );            i_dropped_packets = 0;        }#if 1        i_sent = mdate();        if ( i_sent > i_date + 20000 )        {            msg_Dbg( p_thread, "packet has been sent too late (" I64Fd ")",                     i_sent - i_date );        }#endif        block_FifoPut( p_thread->p_empty_blocks, p_pk );        i_date_last = i_date;    }}

⌨️ 快捷键说明

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