CommonRtp.cpp 2.81 KB
Newer Older
xiongziliang committed
1
/*
2 3
 * Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
 *
4
 * This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
5 6 7 8 9 10 11 12
 *
 * 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.
 */

#include "CommonRtp.h"

13
CommonRtpDecoder::CommonRtpDecoder(CodecId codec, size_t max_frame_size ){
14
    _codec = codec;
15
    _max_frame_size = max_frame_size;
16 17 18 19 20 21 22 23
    obtainFrame();
}

CodecId CommonRtpDecoder::getCodecId() const {
    return _codec;
}

void CommonRtpDecoder::obtainFrame() {
24
    _frame = FrameImp::create();
25 26 27 28
    _frame->_codec_id = _codec;
}

bool CommonRtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool){
xiongziliang committed
29 30 31 32
    auto payload = rtp->getPayload();
    auto size = rtp->getPayloadSize();
    auto stamp = rtp->getStampMS();
    auto seq = rtp->getSeq();
33 34 35 36 37
    if (size <= 0) {
        //无实际负载
        return false;
    }

xiongziliang committed
38
    if (_frame->_dts != stamp || _frame->_buffer.size() > _max_frame_size) {
39 40 41 42 43 44 45 46
        //时间戳发生变化或者缓存超过MAX_FRAME_SIZE,则清空上帧数据
        if (!_frame->_buffer.empty()) {
            //有有效帧,则输出
            RtpCodec::inputFrame(_frame);
        }

        //新的一帧数据
        obtainFrame();
xiongziliang committed
47
        _frame->_dts = stamp;
48
        _drop_flag = false;
xiongziliang committed
49
    } else if (_last_seq != 0 && (uint16_t)(_last_seq + 1) != seq) {
50
        //时间戳未发生变化,但是seq却不连续,说明中间rtp丢包了,那么整帧应该废弃
xiongziliang committed
51
        WarnL << "rtp丢包:" << _last_seq << " -> " << seq;
52 53 54 55 56
        _drop_flag = true;
        _frame->_buffer.clear();
    }

    if (!_drop_flag) {
xiongziliang committed
57
        _frame->_buffer.append((char *)payload, size);
58 59
    }

xiongziliang committed
60
    _last_seq = seq;
61 62 63 64 65 66 67 68 69 70 71
    return false;
}

////////////////////////////////////////////////////////////////

CommonRtpEncoder::CommonRtpEncoder(CodecId codec, uint32_t ssrc, uint32_t mtu_size,
                                   uint32_t sample_rate,  uint8_t payload_type, uint8_t interleaved)
        : CommonRtpDecoder(codec), RtpInfo(ssrc, mtu_size, sample_rate, payload_type, interleaved) {
}

void CommonRtpEncoder::inputFrame(const Frame::Ptr &frame){
xiongziliang committed
72
    auto stamp = frame->dts();
73 74 75
    auto ptr = frame->data() + frame->prefixSize();
    auto len = frame->size() - frame->prefixSize();
    auto remain_size = len;
xiongziliang committed
76
    auto max_size = getMaxSize();
77

78
    bool mark = false;
79
    while (remain_size > 0) {
80
        size_t rtp_size;
xiongziliang committed
81 82
        if (remain_size > max_size) {
            rtp_size = max_size;
83 84 85 86 87
        } else {
            rtp_size = remain_size;
            mark = true;
        }
        RtpCodec::inputRtp(makeRtp(getTrackType(), ptr, rtp_size, mark, stamp), false);
88 89 90 91
        ptr += rtp_size;
        remain_size -= rtp_size;
    }
}