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

📄 rtpfmt.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
    return VLC_SUCCESS;}/* rfc2429 */#define RTP_H263_HEADER_SIZE (2)  // plen = 0#define RTP_H263_PAYLOAD_START (14)  // plen = 0int rtp_packetize_h263( sout_stream_id_t *id, block_t *in ){    uint8_t *p_data = in->p_buffer;    int     i_data  = in->i_buffer;    int     i;    int     i_max   = rtp_mtu (id) - RTP_H263_HEADER_SIZE; /* payload max in one packet */    int     i_count;    int     b_p_bit;    int     b_v_bit = 0; // no pesky error resilience    int     i_plen = 0; // normally plen=0 for PSC packet    int     i_pebit = 0; // because plen=0    uint16_t h;    if( i_data < 2 )    {        return VLC_EGENERIC;    }    if( p_data[0] || p_data[1] )    {        return VLC_EGENERIC;    }    /* remove 2 leading 0 bytes */    p_data += 2;    i_data -= 2;    i_count = ( i_data + i_max - 1 ) / i_max;    for( i = 0; i < i_count; i++ )    {        int      i_payload = __MIN( i_max, i_data );        block_t *out = block_Alloc( RTP_H263_PAYLOAD_START + i_payload );        b_p_bit = (i == 0) ? 1 : 0;        h = ( b_p_bit << 10 )|            ( b_v_bit << 9  )|            ( i_plen  << 3  )|              i_pebit;        /* rtp common header */        //b_m_bit = 1; // always contains end of frame        rtp_packetize_common( id, out, (i == i_count - 1)?1:0,                              in->i_pts > 0 ? in->i_pts : in->i_dts );        /* h263 header */        out->p_buffer[12] = ( h >>  8 )&0xff;        out->p_buffer[13] = ( h       )&0xff;        memcpy( &out->p_buffer[RTP_H263_PAYLOAD_START], p_data, i_payload );        out->i_buffer = RTP_H263_PAYLOAD_START + i_payload;        out->i_dts    = in->i_dts + i * in->i_length / i_count;        out->i_length = in->i_length / i_count;        rtp_packetize_send( id, out );        p_data += i_payload;        i_data -= i_payload;    }    return VLC_SUCCESS;}/* rfc3984 */intrtp_packetize_h264_nal( sout_stream_id_t *id,                        const uint8_t *p_data, int i_data, int64_t i_pts,                        int64_t i_dts, bool b_last, int64_t i_length ){    const int i_max = rtp_mtu (id); /* payload max in one packet */    int i_nal_hdr;    int i_nal_type;    if( i_data < 5 )        return VLC_SUCCESS;    i_nal_hdr = p_data[3];    i_nal_type = i_nal_hdr&0x1f;    /* Skip start code */    p_data += 3;    i_data -= 3;    /* */    if( i_data <= i_max )    {        /* Single NAL unit packet */        block_t *out = block_Alloc( 12 + i_data );        out->i_dts    = i_dts;        out->i_length = i_length;        /* */        rtp_packetize_common( id, out, b_last, i_pts );        out->i_buffer = 12 + i_data;        memcpy( &out->p_buffer[12], p_data, i_data );        rtp_packetize_send( id, out );    }    else    {        /* FU-A Fragmentation Unit without interleaving */        const int i_count = ( i_data-1 + i_max-2 - 1 ) / (i_max-2);        int i;        p_data++;        i_data--;        for( i = 0; i < i_count; i++ )        {            const int i_payload = __MIN( i_data, i_max-2 );            block_t *out = block_Alloc( 12 + 2 + i_payload );            out->i_dts    = i_dts + i * i_length / i_count;            out->i_length = i_length / i_count;            /* */            rtp_packetize_common( id, out, (b_last && i_payload == i_data), i_pts );            out->i_buffer = 14 + i_payload;            /* FU indicator */            out->p_buffer[12] = 0x00 | (i_nal_hdr & 0x60) | 28;            /* FU header */            out->p_buffer[13] = ( i == 0 ? 0x80 : 0x00 ) | ( (i == i_count-1) ? 0x40 : 0x00 )  | i_nal_type;            memcpy( &out->p_buffer[14], p_data, i_payload );            rtp_packetize_send( id, out );            i_data -= i_payload;            p_data += i_payload;        }    }    return VLC_SUCCESS;}int rtp_packetize_h264( sout_stream_id_t *id, block_t *in ){    const uint8_t *p_buffer = in->p_buffer;    int i_buffer = in->i_buffer;    while( i_buffer > 4 && ( p_buffer[0] != 0 || p_buffer[1] != 0 || p_buffer[2] != 1 ) )    {        i_buffer--;        p_buffer++;    }    /* Split nal units */    while( i_buffer > 4 )    {        int i_offset;        int i_size = i_buffer;        int i_skip = i_buffer;        /* search nal end */        for( i_offset = 4; i_offset+2 < i_buffer ; i_offset++)        {            if( p_buffer[i_offset] == 0 && p_buffer[i_offset+1] == 0 && p_buffer[i_offset+2] == 1 )            {                /* we found another startcode */                i_size = i_offset - ( p_buffer[i_offset-1] == 0 ? 1 : 0);                i_skip = i_offset;                break;            }        }        /* TODO add STAP-A to remove a lot of overhead with small slice/sei/... */        rtp_packetize_h264_nal( id, p_buffer, i_size,                                (in->i_pts > 0 ? in->i_pts : in->i_dts), in->i_dts,                                (i_size >= i_buffer), in->i_length * i_size / in->i_buffer );        i_buffer -= i_skip;        p_buffer += i_skip;    }    return VLC_SUCCESS;}int rtp_packetize_amr( sout_stream_id_t *id, block_t *in ){    int     i_max   = rtp_mtu (id) - 2; /* payload max in one packet */    int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;    uint8_t *p_data = in->p_buffer;    int     i_data  = in->i_buffer;    int     i;    /* Only supports octet-aligned mode */    for( i = 0; i < i_count; i++ )    {        int           i_payload = __MIN( i_max, i_data );        block_t *out = block_Alloc( 14 + i_payload );        /* rtp common header */        rtp_packetize_common( id, out, ((i == i_count - 1)?1:0),                              (in->i_pts > 0 ? in->i_pts : in->i_dts) );        /* Payload header */        out->p_buffer[12] = 0xF0; /* CMR */        out->p_buffer[13] = p_data[0]&0x7C; /* ToC */ /* FIXME: frame type */        /* FIXME: are we fed multiple frames ? */        memcpy( &out->p_buffer[14], p_data+1, i_payload-1 );        out->i_buffer   = 14 + i_payload-1;        out->i_dts    = in->i_dts + i * in->i_length / i_count;        out->i_length = in->i_length / i_count;        rtp_packetize_send( id, out );        p_data += i_payload;        i_data -= i_payload;    }    return VLC_SUCCESS;}int rtp_packetize_t140( sout_stream_id_t *id, block_t *in ){    const size_t   i_max  = rtp_mtu (id);    const uint8_t *p_data = in->p_buffer;    size_t         i_data = in->i_buffer;    for( unsigned i_packet = 0; i_data > 0; i_packet++ )    {        size_t i_payload = i_data;        /* Make sure we stop on an UTF-8 character boundary         * (assuming the input is valid UTF-8) */        if( i_data > i_max )        {            i_payload = i_max;            while( ( p_data[i_payload] & 0xC0 ) == 0x80 )            {                if( i_payload == 0 )                    return VLC_SUCCESS; /* fishy input! */                i_payload--;            }        }        block_t *out = block_Alloc( 12 + i_payload );        if( out == NULL )            return VLC_SUCCESS;        rtp_packetize_common( id, out, 0, in->i_pts + i_packet );        memcpy( out->p_buffer + 12, p_data, i_payload );        out->i_buffer = 12 + i_payload;        out->i_dts    = out->i_pts;        out->i_length = 0;        rtp_packetize_send( id, out );        p_data += i_payload;        i_data -= i_payload;    }    return VLC_SUCCESS;}int rtp_packetize_spx( sout_stream_id_t *id, block_t *in ){    uint8_t *p_buffer = in->p_buffer;    int i_data_size, i_payload_size, i_payload_padding;    i_data_size = i_payload_size = in->i_buffer;    i_payload_padding = 0;    block_t *p_out;    if ( in->i_buffer > rtp_mtu (id) )        return VLC_SUCCESS;    /*      RFC for Speex in RTP says that each packet must end on an octet       boundary. So, we check to see if the number of bytes % 4 is zero.      If not, we have to add some padding.       This MAY be overkill since packetization is handled elsewhere and       appears to ensure the octet boundary. However, better safe than      sorry.    */    if ( i_payload_size % 4 )    {        i_payload_padding = 4 - ( i_payload_size % 4 );        i_payload_size += i_payload_padding;    }    /*      Allocate a new RTP p_output block of the appropriate size.       Allow for 12 extra bytes of RTP header.     */    p_out = block_Alloc( 12 + i_payload_size );    if ( i_payload_padding )    {    /*      The padding is required to be a zero followed by all 1s.    */        char c_first_pad, c_remaining_pad;        c_first_pad = 0x7F;        c_remaining_pad = 0xFF;        /*          Allow for 12 bytes before the i_data_size because          of the expected RTP header added during          rtp_packetize_common.        */        p_out->p_buffer[12 + i_data_size] = c_first_pad;         switch (i_payload_padding)        {          case 2:            p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad;             break;          case 3:            p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad;             p_out->p_buffer[12 + i_data_size + 2] = c_remaining_pad;             break;        }    }    /* Add the RTP header to our p_output buffer. */    rtp_packetize_common( id, p_out, 0, (in->i_pts > 0 ? in->i_pts : in->i_dts) );    /* Copy the Speex payload to the p_output buffer */    memcpy( &p_out->p_buffer[12], p_buffer, i_data_size );    p_out->i_buffer = 12 + i_payload_size;    p_out->i_dts = in->i_dts;    p_out->i_length = in->i_length;    /* Queue the buffer for actual transmission. */    rtp_packetize_send( id, p_out );    return VLC_SUCCESS;}

⌨️ 快捷键说明

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