mirror of
https://gitee.com/xia-chu/ZLMediaKit.git
synced 2026-05-06 10:57:50 +08:00
113 lines
3.0 KiB
C++
113 lines
3.0 KiB
C++
/*
|
||
* 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.
|
||
*/
|
||
|
||
#ifndef ZLMEDIAKIT_MP2VRTP_H
|
||
#define ZLMEDIAKIT_MP2VRTP_H
|
||
|
||
#include "MP2V.h"
|
||
#include "Common/Stamp.h"
|
||
#include "Rtsp/RtpCodec.h"
|
||
|
||
namespace mediakit {
|
||
|
||
// RFC 2250 MPEG Video-specific header (4 bytes)
|
||
//
|
||
// 0 1 2 3
|
||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||
// | MBZ |T| TR |N|S|B|E| P | | BFC | | FFC |
|
||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||
// AN FBV FFV
|
||
|
||
static constexpr size_t kMP2VHeaderSize = 4;
|
||
|
||
/**
|
||
* MP2V (MPEG-2 Video) RTP 解码器
|
||
* 将 MPEG-2 Video over RTP 解复用出 MP2V Frame
|
||
* RFC 2250
|
||
*/
|
||
class MP2VRtpDecoder : public RtpCodec {
|
||
public:
|
||
using Ptr = std::shared_ptr<MP2VRtpDecoder>;
|
||
|
||
MP2VRtpDecoder();
|
||
|
||
/**
|
||
* 输入 MPEG-2 Video RTP 包
|
||
* @param rtp rtp包
|
||
* @param key_pos 此参数忽略之
|
||
*/
|
||
bool inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = true) override;
|
||
|
||
private:
|
||
bool decodeRtp(const RtpPacket::Ptr &rtp);
|
||
void outputFrame(const RtpPacket::Ptr &rtp);
|
||
void obtainFrame();
|
||
|
||
private:
|
||
bool _gop_dropped = true;
|
||
bool _drop_flag = false;
|
||
uint16_t _last_seq = 0;
|
||
uint8_t _picture_type = 0;
|
||
MP2VFrame::Ptr _frame;
|
||
DtsGenerator _dts_generator;
|
||
};
|
||
|
||
/**
|
||
* MP2V (MPEG-2 Video) RTP 编码器
|
||
* 将 MPEG-2 Video 帧打包为 RTP
|
||
* RFC 2250
|
||
*/
|
||
class MP2VRtpEncoder : public RtpCodec {
|
||
public:
|
||
using Ptr = std::shared_ptr<MP2VRtpEncoder>;
|
||
|
||
/**
|
||
* 输入 MPEG-2 Video 帧
|
||
* @param frame 帧数据
|
||
*/
|
||
bool inputFrame(const Frame::Ptr &frame) override;
|
||
|
||
private:
|
||
/**
|
||
* 构建 RFC 2250 MPEG Video-specific header
|
||
* @param buf 输出缓冲区,至少4字节
|
||
* @param data MPEG-2 ES 数据
|
||
* @param size 数据大小
|
||
* @param is_begin_of_slice 是否为 slice 起始
|
||
* @param is_end_of_slice 是否为 slice 结束
|
||
*/
|
||
void buildMpvHeader(uint8_t *buf, const uint8_t *data, size_t size,
|
||
bool is_begin_of_slice, bool is_end_of_slice);
|
||
|
||
/**
|
||
* 解析当前帧信息(picture type, temporal reference 等)
|
||
*/
|
||
void parsePictureInfo(const uint8_t *data, size_t size);
|
||
|
||
/**
|
||
* 查找 sequence header 是否存在
|
||
*/
|
||
bool hasSequenceHeader(const uint8_t *data, size_t size);
|
||
|
||
private:
|
||
uint16_t _temporal_ref = 0;
|
||
uint8_t _picture_type = 0;
|
||
uint8_t _fbv = 0;
|
||
uint8_t _bfc = 0;
|
||
uint8_t _ffv = 0;
|
||
uint8_t _ffc = 0;
|
||
bool _has_seq_header = false;
|
||
};
|
||
|
||
} // namespace mediakit
|
||
|
||
#endif // ZLMEDIAKIT_MP2VRTP_H
|