ZLMediaKit/src/Extension/H264.h
mtdxc 754073918a
Header refactor (#2115)
* 优化MultiMediaSourceMuxer头文件包含

* 将MediaSinkDelegate和Demux移到MediaSink中

* MediaSource头文件重构, 独立出PacketCache.h
精简Frame和Track的头文件

* Rtmp头文件重构

* Rtsp头文件重构

* webrtc头文件重构

* 规范.h头文件包含,并将其移到.cpp中:
- 尽量不包含Common\config.h
- Util\File.h
- Rtsp/RtspPlayer.h
- Rtmp/RtmpPlayer.h

* 删除多余的Stamp.h和Base64包含
2022-11-29 11:07:13 +08:00

150 lines
4.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
*
* 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.
*/
#ifndef ZLMEDIAKIT_H264_H
#define ZLMEDIAKIT_H264_H
#include "Frame.h"
#include "Track.h"
#define H264_TYPE(v) ((uint8_t)(v) & 0x1F)
namespace mediakit{
bool getAVCInfo(const std::string &strSps,int &iVideoWidth, int &iVideoHeight, float &iVideoFps);
void splitH264(const char *ptr, size_t len, size_t prefix, const std::function<void(const char *, size_t, size_t)> &cb);
size_t prefixSize(const char *ptr, size_t len);
template<typename Parent>
class H264FrameHelper : public Parent{
public:
friend class FrameImp;
friend class toolkit::ResourcePool_l<H264FrameHelper>;
using Ptr = std::shared_ptr<H264FrameHelper>;
enum {
NAL_IDR = 5,
NAL_SEI = 6,
NAL_SPS = 7,
NAL_PPS = 8,
NAL_AUD = 9,
NAL_B_P = 1,
};
template<typename ...ARGS>
H264FrameHelper(ARGS &&...args): Parent(std::forward<ARGS>(args)...) {
this->_codec_id = CodecH264;
}
~H264FrameHelper() override = default;
bool keyFrame() const override {
auto nal_ptr = (uint8_t *) this->data() + this->prefixSize();
return H264_TYPE(*nal_ptr) == NAL_IDR && decodeAble();
}
bool configFrame() const override {
auto nal_ptr = (uint8_t *) this->data() + this->prefixSize();
switch (H264_TYPE(*nal_ptr)) {
case NAL_SPS:
case NAL_PPS: return true;
default: return false;
}
}
bool dropAble() const override {
auto nal_ptr = (uint8_t *) this->data() + this->prefixSize();
switch (H264_TYPE(*nal_ptr)) {
case NAL_SEI:
case NAL_AUD: return true;
default: return false;
}
}
bool decodeAble() const override {
auto nal_ptr = (uint8_t *) this->data() + this->prefixSize();
auto type = H264_TYPE(*nal_ptr);
//多slice情况下, first_mb_in_slice 表示其为一帧的开始
return type >= NAL_B_P && type <= NAL_IDR && (nal_ptr[1] & 0x80);
}
};
/**
* 264帧类
*/
using H264Frame = H264FrameHelper<FrameImp>;
/**
* 防止内存拷贝的H264类
* 用户可以通过该类型快速把一个指针无拷贝的包装成Frame类
*/
using H264FrameNoCacheAble = H264FrameHelper<FrameFromPtr>;
/**
* 264视频通道
*/
class H264Track : public VideoTrack{
public:
using Ptr = std::shared_ptr<H264Track>;
/**
* 不指定sps pps构造h264类型的媒体
* 在随后的inputFrame中获取sps pps
*/
H264Track() = default;
/**
* 构造h264类型的媒体
* @param sps sps帧数据
* @param pps pps帧数据
* @param sps_prefix_len 264头长度可以为3个或4个字节一般为0x00 00 00 01
* @param pps_prefix_len 264头长度可以为3个或4个字节一般为0x00 00 00 01
*/
H264Track(const std::string &sps,const std::string &pps,int sps_prefix_len = 4,int pps_prefix_len = 4);
/**
* 构造h264类型的媒体
* @param sps sps帧
* @param pps pps帧
*/
H264Track(const Frame::Ptr &sps,const Frame::Ptr &pps);
/**
* 返回不带0x00 00 00 01头的sps/pps
*/
const std::string &getSps() const;
const std::string &getPps() const;
bool ready() override;
CodecId getCodecId() const override;
int getVideoHeight() const override;
int getVideoWidth() const override;
float getVideoFps() const override;
bool inputFrame(const Frame::Ptr &frame) override;
private:
void onReady();
Sdp::Ptr getSdp() override;
Track::Ptr clone() override;
bool inputFrame_l(const Frame::Ptr &frame);
void insertConfigFrame(const Frame::Ptr &frame);
private:
bool _latest_is_config_frame = false;
int _width = 0;
int _height = 0;
float _fps = 0;
std::string _sps;
std::string _pps;
};
}//namespace mediakit
#endif //ZLMEDIAKIT_H264_H