Older/MediaServer/Extension/CommonRtp.cpp

96 lines
3.3 KiB
C++
Raw Permalink Normal View History

2024-09-28 23:55:00 +08:00
/*
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT-like 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"
using namespace mediakit;
CommonRtpDecoder::CommonRtpDecoder(CodecId codec, size_t max_frame_size ){
_codec = codec;
_max_frame_size = max_frame_size;
obtainFrame();
}
void CommonRtpDecoder::obtainFrame() {
_frame = FrameImp::create();
_frame->_codec_id = _codec;
}
bool CommonRtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool){
auto payload_size = rtp->getPayloadSize();
if (payload_size <= 0) {
// 无实际负载 [AUTO-TRANSLATED:305af48f]
// No actual load
return false;
}
auto payload = rtp->getPayload();
auto stamp = rtp->getStamp();
auto seq = rtp->getSeq();
if (_last_stamp != stamp || _frame->_buffer.size() > _max_frame_size) {
// 时间戳发生变化或者缓存超过MAX_FRAME_SIZE则清空上帧数据 [AUTO-TRANSLATED:96f15576]
// If the timestamp changes or the cache exceeds MAX_FRAME_SIZE, clear the previous frame data
if (!_frame->_buffer.empty()) {
// 有有效帧,则输出 [AUTO-TRANSLATED:f3ff1bda]
// If there is a valid frame, output it
RtpCodec::inputFrame(_frame);
}
// 新的一帧数据 [AUTO-TRANSLATED:5b5f3a35]
// New frame data
obtainFrame();
_frame->_dts = rtp->getStampMS();
_last_stamp = stamp;
_drop_flag = false;
} else if (_last_seq != 0 && (uint16_t)(_last_seq + 1) != seq) {
// 时间戳未发生变化但是seq却不连续说明中间rtp丢包了那么整帧应该废弃 [AUTO-TRANSLATED:577bf835]
// If the timestamp does not change, but the seq is not continuous, it means that the RTP packet has been lost in the middle, so the entire frame should be discarded
WarnL << "rtp丢包:" << _last_seq << " -> " << seq;
_drop_flag = true;
_frame->_buffer.clear();
}
if (!_drop_flag) {
_frame->_buffer.append((char *)payload, payload_size);
}
_last_seq = seq;
if (_drop_flag && rtp->getHeader()->mark) {
_drop_flag = false;
}
return false;
}
////////////////////////////////////////////////////////////////
bool CommonRtpEncoder::inputFrame(const Frame::Ptr &frame){
auto stamp = frame->pts();
auto ptr = frame->data() + frame->prefixSize();
auto len = frame->size() - frame->prefixSize();
auto remain_size = len;
auto max_size = getRtpInfo().getMaxSize();
bool is_key = frame->keyFrame();
bool mark = false;
while (remain_size > 0) {
size_t rtp_size;
if (remain_size > max_size) {
rtp_size = max_size;
} else {
rtp_size = remain_size;
mark = true;
}
RtpCodec::inputRtp(getRtpInfo().makeRtp(frame->getTrackType(), ptr, rtp_size, mark, stamp), is_key);
ptr += rtp_size;
remain_size -= rtp_size;
is_key = false;
}
return len > 0;
}