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

📄 rtp.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
    return VLC_EGENERIC;}/** * Checks if a file descriptor is hung up. */static bool fd_dead (int fd){    struct pollfd ufd = { .fd = fd, };    return (poll (&ufd, 1, 0) == 1) && (ufd.revents & POLLHUP);}/** * Gets a datagram from the network, or NULL in case of fatal error. */static block_t *rtp_dgram_recv (demux_t *demux, int fd){    block_t *block = block_Alloc (0xffff);    ssize_t len;    do    {        len = net_Read (VLC_OBJECT (demux), fd, NULL,                                block->p_buffer, block->i_buffer, false);        if (((len <= 0) && fd_dead (fd))         || !vlc_object_alive (demux))        {            block_Release (block);            return NULL;        }    }    while (len == -1);    return block_Realloc (block, 0, len);}/** * Gets a framed RTP packet, or NULL in case of fatal error. */static block_t *rtp_stream_recv (demux_t *demux, int fd){    ssize_t len = 0;    uint8_t hdr[2]; /* frame header */    /* Receives the RTP frame header */    do    {        ssize_t val = net_Read (VLC_OBJECT (demux), fd, NULL,                                hdr + len, 2 - len, false);        if (val <= 0)            return NULL;        len += val;    }    while (len < 2);    block_t *block = block_Alloc (GetWBE (hdr));    /* Receives the RTP packet */    for (ssize_t i = 0; i < len;)    {        ssize_t val;        val = net_Read (VLC_OBJECT (demux), fd, NULL,                        block->p_buffer + i, block->i_buffer - i, false);        if (val <= 0)        {            block_Release (block);            return NULL;        }        i += val;    }    return block;}/* * Generic packet handlers */static void *codec_init (demux_t *demux, es_format_t *fmt){    return es_out_Add (demux->out, fmt);}static void codec_destroy (demux_t *demux, void *data){    if (data)        es_out_Del (demux->out, (es_out_id_t *)data);}/* Send a packet to decoder */static void codec_decode (demux_t *demux, void *data, block_t *block){    if (data)    {        block->i_dts = 0; /* RTP does not specify this */        es_out_Control (demux->out, ES_OUT_SET_PCR, block->i_pts );        es_out_Send (demux->out, (es_out_id_t *)data, block);    }    else        block_Release (block);}static void *stream_init (demux_t *demux, const char *name){    return stream_DemuxNew (demux, name, demux->out);}static void stream_destroy (demux_t *demux, void *data){    if (data)        stream_DemuxDelete ((stream_t *)data);    (void)demux;}/* Send a packet to a chained demuxer */static void stream_decode (demux_t *demux, void *data, block_t *block){    if (data)        stream_DemuxSend ((stream_t *)data, block);    else        block_Release (block);    (void)demux;}/* * Static payload types handler *//* PT=0 * PCMU: G.711 µ-law (RFC3551) */static void *pcmu_init (demux_t *demux){    es_format_t fmt;    es_format_Init (&fmt, AUDIO_ES, VLC_FOURCC ('u', 'l', 'a', 'w'));    fmt.audio.i_rate = 8000;    fmt.audio.i_channels = 1;    return codec_init (demux, &fmt);}/* PT=8 * PCMA: G.711 A-law (RFC3551) */static void *pcma_init (demux_t *demux){    es_format_t fmt;    es_format_Init (&fmt, AUDIO_ES, VLC_FOURCC ('a', 'l', 'a', 'w'));    fmt.audio.i_rate = 8000;    fmt.audio.i_channels = 1;    return codec_init (demux, &fmt);}/* PT=10,11 * L16: 16-bits (network byte order) PCM */static void *l16s_init (demux_t *demux){    es_format_t fmt;    es_format_Init (&fmt, AUDIO_ES, VLC_FOURCC ('s', '1', '6', 'b'));    fmt.audio.i_rate = 44100;    fmt.audio.i_channels = 2;    return codec_init (demux, &fmt);}static void *l16m_init (demux_t *demux){    es_format_t fmt;    es_format_Init (&fmt, AUDIO_ES, VLC_FOURCC ('s', '1', '6', 'b'));    fmt.audio.i_rate = 44100;    fmt.audio.i_channels = 1;    return codec_init (demux, &fmt);}/* PT=14 * MPA: MPEG Audio (RFC2250, §3.4) */static void *mpa_init (demux_t *demux){    es_format_t fmt;    es_format_Init (&fmt, AUDIO_ES, VLC_FOURCC ('m', 'p', 'g', 'a'));    fmt.audio.i_channels = 2;    return codec_init (demux, &fmt);}static void mpa_decode (demux_t *demux, void *data, block_t *block){    if (block->i_buffer < 4)    {        block_Release (block);        return;    }    block->i_buffer -= 4; /* 32-bits RTP/MPA header */    block->p_buffer += 4;    codec_decode (demux, data, block);}/* PT=32 * MPV: MPEG Video (RFC2250, §3.5) */static void *mpv_init (demux_t *demux){    es_format_t fmt;    es_format_Init (&fmt, VIDEO_ES, VLC_FOURCC ('m', 'p', 'g', 'v'));    return codec_init (demux, &fmt);}static void mpv_decode (demux_t *demux, void *data, block_t *block){    if (block->i_buffer < 4)    {        block_Release (block);        return;    }    block->i_buffer -= 4; /* 32-bits RTP/MPV header */    block->p_buffer += 4;#if 0    if (block->p_buffer[-3] & 0x4)    {        /* MPEG2 Video extension header */        /* TODO: shouldn't we skip this too ? */    }#endif    codec_decode (demux, data, block);}/* PT=33 * MP2: MPEG TS (RFC2250, §2) */static void *ts_init (demux_t *demux){    return stream_init (demux, "ts");}/* * Dynamic payload type handlers * Hmm, none implemented yet. *//** * Processing callback */static int Demux (demux_t *demux){    demux_sys_t *p_sys = demux->p_sys;    block_t     *block;    block = p_sys->framed_rtp        ? rtp_stream_recv (demux, p_sys->fd)        : rtp_dgram_recv (demux, p_sys->fd);    if (!block)        return 0;    if (block->i_buffer < 2)        goto drop;    const uint8_t ptype = block->p_buffer[1] & 0x7F;    if (ptype >= 72 && ptype <= 76)        goto drop; /* Muxed RTCP, ignore for now */    if (p_sys->srtp)    {        size_t len = block->i_buffer;        if (srtp_recv (p_sys->srtp, block->p_buffer, &len))        {            msg_Dbg (demux, "SRTP authentication/decryption failed");            goto drop;        }        block->i_buffer = len;    }    /* Not using SDP, we need to guess the payload format used */    /* see http://www.iana.org/assignments/rtp-parameters */    if (p_sys->autodetect)    {        rtp_pt_t pt = {            .init = NULL,            .destroy = codec_destroy,            .decode = codec_decode,            .frequency = 0,            .number = ptype,        };        switch (ptype)        {          case 0:            msg_Dbg (demux, "detected G.711 mu-law");            pt.init = pcmu_init;            pt.frequency = 8000;            break;          case 8:            msg_Dbg (demux, "detected G.711 A-law");            pt.init = pcma_init;            pt.frequency = 8000;            break;          case 10:            msg_Dbg (demux, "detected stereo PCM");            pt.init = l16s_init;            pt.frequency = 44100;            break;          case 11:            msg_Dbg (demux, "detected mono PCM");            pt.init = l16m_init;            pt.frequency = 44100;            break;          case 14:            msg_Dbg (demux, "detected MPEG Audio");            pt.init = mpa_init;            pt.decode = mpa_decode;            pt.frequency = 90000;            break;          case 32:            msg_Dbg (demux, "detected MPEG Video");            pt.init = mpv_init;            pt.decode = mpv_decode;            pt.frequency = 90000;            break;          case 33:            msg_Dbg (demux, "detected MPEG2 TS");            pt.init = ts_init;            pt.destroy = stream_destroy;            pt.decode = stream_decode;            pt.frequency = 90000;            break;          default:            goto drop;        }        rtp_add_type (demux, p_sys->session, &pt);        p_sys->autodetect = false;    }    rtp_receive (demux, p_sys->session, block);    return 1;drop:    block_Release (block);    return 1;}

⌨️ 快捷键说明

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