Ejemplo n.º 1
0
static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, int len)
{
    if (buf[1] != 200)
        return -1;
    s->last_rtcp_ntp_time = decode_be64(buf + 8);
    if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE)
        s->first_rtcp_ntp_time = s->last_rtcp_ntp_time;
    s->last_rtcp_timestamp = decode_be32(buf + 16);
    return 0;
}
Ejemplo n.º 2
0
Archivo: rtp.c Proyecto: KoetseJ/xumo
static int rtcp_parse_packet(AVFormatContext *s1, const unsigned char *buf, int len)
{
    RTPContext *s = s1->priv_data;

    if (buf[1] != 200)
        return -1;
    s->last_rtcp_ntp_time = decode_be64(buf + 8);
    if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE)
        s->first_rtcp_ntp_time = s->last_rtcp_ntp_time;
    else if (s->first_rtcp_ntp_time > s->last_rtcp_ntp_time) //added by ivan 
        s->first_rtcp_ntp_time = s->last_rtcp_ntp_time;
    s->last_rtcp_timestamp = decode_be32(buf + 16);

    rtcp_get_profile(s,s1->streams[0],s1->streams[1],(unsigned char *)buf);
    return 0;
}
Ejemplo n.º 3
0
static inline uint64_t decode_be64(const uint8_t *p)
{
    return ((uint64_t)decode_be32(p) << 32) | decode_be32(p + 4);
}
Ejemplo n.º 4
0
Archivo: rtp.c Proyecto: KoetseJ/xumo
/**
 * Parse an RTP packet directly sent as raw data. Can only be used if
 * 'raw' is given as input file
 * @param s1 media file context
 * @param pkt returned packet
 * @param buf input buffer
 * @param len buffer len
 * @return zero if no error.
 */
int rtp_parse_packet(AVFormatContext *s1, AVPacket *pkt, 
                     const unsigned char *buf, int len)
{
    RTPContext *s = s1->priv_data;
    unsigned int ssrc, h;
    int payload_type, seq, delta_timestamp,idx;
    AVStream *st;
    uint32_t timestamp;
    
    if (len < 12)
        return -1;

    if ((buf[0] & 0xc0) != (RTP_VERSION << 6))
        return -1;
    if (buf[1] >= 200 && buf[1] <= 204) {
        rtcp_parse_packet(s1, buf, len);
        if(pkt&&(pkt->data!=0))
        {
            //printf("free_packet\n");fflush(stdout);
            av_free_packet(pkt);
        }
 
        if(s->profile.a_size>0)
            s->seq=s->profile.a_seq-1;
        else if(s->profile.v_size>0)
            s->seq=s->profile.v_seq-1;
        else
            return -1;
             
        s->a_offset=0;
        s->v_offset=0;
        switch_order=1;
        s->first_rtcp=1; //need the first video rtcp packet for re-sync
        return -1;
    }

    payload_type = buf[1] & 0x7f;
    seq  = (buf[2] << 8) | buf[3];
    timestamp = decode_be32(buf + 4);
    ssrc = decode_be32(buf + 8);

#ifdef DEBUG //1
    printf("payload_type %d, seq=%d timestamp=0x%x first_rtcp=%d\n",payload_type,seq,timestamp,s->first_rtcp);
    fflush(stdout);
#endif

    if(s->first_rtcp==0)
    {
        //printf("NO first rtcp comming!\n");
        switch_order=0;
        return -1;
    }
    
#if 1 //ivan
    if(s->payload_record[0]<0)
        s->payload_record[0] = payload_type;
    else if(s->payload_record[1]<0)
        s->payload_record[1] = payload_type;
    if((payload_type==RTP_PT_MPEG4VIDEO)||(payload_type==RTP_PT_MJPEG)||(payload_type==RTP_PT_H264))
        idx=0;
    else if(payload_type==RTP_PT_ADPCM)
        idx=1;
    else
        return -1;
#else
    if (s->payload_type < 0) {
        s->payload_type = payload_type;
        
        if (payload_type == RTP_PT_MPEG2TS) {
            /* XXX: special case : not a single codec but a whole stream */
            return -1;
        } else {
            st = av_new_stream(s1, 0);
            if (!st)
                return -1;
            rtp_get_codec_info(&st->codec, payload_type);
        }
    }

    /* NOTE: we can handle only one payload type */
    if (s->payload_type != payload_type)
        return -1;
#endif

#if defined(DEBUG) || 1
    if(seq != 0) //ivan
    if (seq != ((s->seq + 1) & 0xffff)) {
        printf("RTP: PT=%02x: bad cseq %04x expected=%04x\n", 
               payload_type, seq, ((s->seq + 1) & 0xffff));
        s->seq = seq;
        if(pkt&&(pkt->data!=0))
        {
            //printf("free_packet\n");fflush(stdout);
            av_free_packet(pkt);
        }
        switch_order=0;
        s->first_rtcp=0;
        return -1;
    }
    s->seq = seq;
#else
    s->seq = seq;
#endif

    len -= 12;
    buf += 12;
    st = s1->streams[idx];
    switch(st->codec.codec_id) {
    case CODEC_ID_MP2:
        /* better than nothing: skip mpeg audio RTP header */
        if (len <= 4)
            return -1;
        h = decode_be32(buf);
        len -= 4;
        buf += 4;
        av_new_packet(pkt, len);
        memcpy(pkt->data, buf, len);
        break;
    case CODEC_ID_MPEG1VIDEO:
        /* better than nothing: skip mpeg audio RTP header */
        if (len <= 4)
            return -1;
        h = decode_be32(buf);
        buf += 4;
        len -= 4;
        if (h & (1 << 26)) {
            /* mpeg2 */
            if (len <= 4)
                return -1;
            buf += 4;
            len -= 4;
        }
        av_new_packet(pkt, len);
        memcpy(pkt->data, buf, len);
        break;
    case CODEC_ID_MPEG4:
    case CODEC_ID_MJPEG:
    case CODEC_ID_H264:
        if(pkt&&(pkt->data!=0)&&(s->a_offset!=0))
            av_free_packet(pkt);
        if(pkt->data==0)
        {
            if(av_new_packet(pkt,s->profile.v_size)<0)
                return -1;
            pkt->stream_index=0;
        }
        if((s->v_offset+len)>s->profile.v_size)
        {
            //printf("Packet Alignment Fail! free it!\n");fflush(stdout);
            av_free_packet(pkt);
            return -1;
		}
        memcpy(pkt->data+s->v_offset, buf, len);
        s->v_offset+=len;
        break;
    case CODEC_ID_ADPCM_IMA_WAV:
        if(pkt&&(pkt->data!=0)&&(s->v_offset!=0))
            av_free_packet(pkt);
        if(pkt->data==0)
        {
            if(av_new_packet(pkt,s->profile.a_size)<0)
                return -1;
            pkt->stream_index=1;
        }
        if((s->a_offset+len)>s->profile.a_size)
        {
            //printf("Packet Alignment Fail! free it!\n");fflush(stdout);
            av_free_packet(pkt);
            return -1;
        }
        memcpy(pkt->data+s->a_offset, buf, len);
        s->a_offset+=len;
        break;
    default:
        av_new_packet(pkt, len);
        memcpy(pkt->data, buf, len);
        break;
    }

    switch(st->codec.codec_id) {
    case CODEC_ID_MP2:
    case CODEC_ID_MPEG1VIDEO:
    case CODEC_ID_ADPCM_IMA_WAV:
    case CODEC_ID_MPEG4:
    case CODEC_ID_MJPEG:
    case CODEC_ID_H264:
        if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE) {
            int64_t addend;
            /* XXX: is it really necessary to unify the timestamp base ? */
            /* compute pts from timestamp with received ntp_time */
            delta_timestamp = timestamp - s->last_rtcp_timestamp;
            /* convert to 90 kHz without overflow */
            addend = (s->last_rtcp_ntp_time - s->first_rtcp_ntp_time) >> 14;
            addend = (addend * 5625) >> 14;
            pkt->pts = addend + delta_timestamp;
        }
        break;
    default:
        /* no timestamp info yet */
        break;
    }