RtpReceiver.cpp 2.87 KB
Newer Older
xiongziliang committed
1
/*
xiongziliang committed
2
 * Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
xiongziliang committed
3
 *
4
 * This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
xiongziliang committed
5
 *
xiongziliang committed
6 7 8
 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
xiongziliang committed
9 10 11 12 13
 */

#include "Common/config.h"
#include "RtpReceiver.h"

14
#define RTP_MAX_SIZE (10 * 1024)
xiongziliang committed
15 16 17

namespace mediakit {

xiongziliang committed
18 19 20
RtpReceiver::RtpReceiver() {
    int index = 0;
    for (auto &sortor : _rtp_sortor) {
21
        sortor.setOnSort([this, index](uint16_t seq, RtpPacket::Ptr &packet) {
xiongziliang committed
22 23 24 25 26
            onRtpSorted(packet, index);
        });
        ++index;
    }
}
xiongziliang committed
27

xiongziliang committed
28 29
RtpReceiver::~RtpReceiver() {}

xiongziliang committed
30 31 32
bool RtpReceiver::handleOneRtp(int index, TrackType type, int sample_rate, uint8_t *ptr, size_t len) {
    if (len < RtpPacket::kRtpHeaderSize) {
        WarnL << "rtp包太小:" << len;
xiongziliang committed
33 34
        return false;
    }
xiongziliang committed
35 36 37
    if (len > RTP_MAX_SIZE) {
        WarnL << "超大的rtp包:" << len << " > " << RTP_MAX_SIZE;
        return false;
xiongziliang committed
38
    }
xiongziliang committed
39
    if (!sample_rate) {
40
        //无法把时间戳转换成毫秒
xiongziliang committed
41 42
        return false;
    }
xiongziliang committed
43 44 45
    RtpHeader *header = (RtpHeader *) ptr;
    if (header->version != RtpPacket::kRtpVersion) {
        throw std::invalid_argument("非法的rtp,version字段非法");
xiongziliang committed
46
    }
xiongziliang committed
47
    if (!header->getPayloadSize(len)) {
48
        //无有效负载的rtp包
49 50 51
        return false;
    }

xiongziliang committed
52 53 54 55 56 57 58 59 60
    //比对缓存ssrc
    auto ssrc = ntohl(header->ssrc);

    if (!_ssrc[index]) {
        //保存SSRC至track对象
        _ssrc[index] = ssrc;
    } else if (_ssrc[index] != ssrc) {
        //ssrc错误
        WarnL << "ssrc错误:" << ssrc << " != " << _ssrc[index];
61 62 63
        return false;
    }

xiongziliang committed
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
    auto rtp = _rtp_pool.obtain();
    //需要添加4个字节的rtp over tcp头
    rtp->setCapacity(RtpPacket::kRtpTcpHeaderSize + len);
    rtp->setSize(RtpPacket::kRtpTcpHeaderSize + len);
    rtp->sample_rate = sample_rate;
    rtp->type = type;

    //赋值4个字节的rtp over tcp头
    uint8_t *data = (uint8_t *) rtp->data();
    data[0] = '$';
    data[1] = 2 * type;
    data[2] = (len >> 8) & 0xFF;
    data[3] = len & 0xFF;
    //拷贝rtp
    memcpy(&data[4], ptr, len);

    onBeforeRtpSorted(rtp, index);
    auto seq = rtp->getSeq();
    _rtp_sortor[index].sortPacket(seq, std::move(rtp));
83 84
    return true;
}
xiongziliang committed
85 86

void RtpReceiver::clear() {
xiongziliang committed
87
    CLEAR_ARR(_ssrc);
xiongziliang committed
88 89 90
    for (auto &sortor : _rtp_sortor) {
        sortor.clear();
    }
xiongziliang committed
91 92
}

93
void RtpReceiver::setPoolSize(size_t size) {
94
    _rtp_pool.setSize(size);
xiongziliang committed
95 96
}

xiongziliang committed
97 98
size_t RtpReceiver::getJitterSize(int index) const{
    return _rtp_sortor[index].getJitterSize();
xiongziliang committed
99 100
}

xiongziliang committed
101 102
size_t RtpReceiver::getCycleCount(int index) const{
    return _rtp_sortor[index].getCycleCount();
xiongziliang committed
103 104
}

xiongziliang committed
105 106
uint32_t RtpReceiver::getSSRC(int index) const{
    return _ssrc[index];
ziyue committed
107
}
xiongziliang committed
108

xiongziliang committed
109
}//namespace mediakit