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

📄 udp.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
    p_access->pf_write = Write;    p_access->pf_seek = Seek;    /* update p_sout->i_out_pace_nocontrol */    p_access->p_sout->i_out_pace_nocontrol++;    return VLC_SUCCESS;}/***************************************************************************** * 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;    vlc_object_kill( p_sys->p_thread );    block_FifoWake( p_sys->p_thread->p_fifo );    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_release( 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 ssize_t 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;        mtime_t now = mdate();        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 = 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 < now )            {                msg_Dbg( p_access, "late packet for UDP input (%"PRId64 ")",                         now - 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_payload_size = p_sys->i_mtu;            int i_write = __MIN( p_buffer->i_buffer, i_payload_size );            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 < now )                {                    msg_Dbg( p_access, "late packet for udp input (%"PRId64 ")",                             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 );}/***************************************************************************** * 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 ( block_FifoCount( p_sys->p_thread->p_empty_blocks ) > MAX_EMPTY_BLOCKS )    {        p_buffer = block_FifoGet( p_sys->p_thread->p_empty_blocks );        block_Release( p_buffer );    }    if( block_FifoCount( p_sys->p_thread->p_empty_blocks ) == 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;    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;    while( vlc_object_alive (p_thread) )    {        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_Dbg( 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 );        if( p_pk == NULL )            continue; /* forced wake-up */        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 (%"PRId64" > 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 (%"PRId64")",                             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;        }        ssize_t val = send( p_thread->i_handle, p_pk->p_buffer,                            p_pk->i_buffer, 0 );        if (val == -1)        {            msg_Warn( p_thread, "send error: %m" );        }        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 (%"PRId64 ")",                     i_sent - i_date );        }#endif        block_FifoPut( p_thread->p_empty_blocks, p_pk );        i_date_last = i_date;    }    return NULL;}

⌨️ 快捷键说明

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