2026-05-31 00:15:25 +08:00
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
|
|
#include <cstdint>
|
|
|
|
|
|
#include <cstddef>
|
|
|
|
|
|
#include <string>
|
|
|
|
|
|
#include <functional>
|
|
|
|
|
|
|
2026-06-08 17:36:13 +08:00
|
|
|
|
// FFMediaStream 现为静态库(CONFIG += staticlib),不使用 DLL 导入/导出修饰,
|
|
|
|
|
|
// 否则 MSVC 会以 __imp_ 方式查找符号导致 LNK2019。
|
|
|
|
|
|
#define VR_FFMEDIA_API
|
2026-05-31 00:15:25 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 拉流帧输出格式
|
|
|
|
|
|
*/
|
|
|
|
|
|
enum class EFFPullPixelFormat
|
|
|
|
|
|
{
|
|
|
|
|
|
NV12 = 0, // 原生硬解输出,零拷贝最快
|
|
|
|
|
|
RGBA32, // 适合 QImage::Format_RGBA8888 直接显示
|
|
|
|
|
|
BGR24, // 适合 OpenCV
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 拉流参数
|
|
|
|
|
|
*/
|
|
|
|
|
|
struct VrFFPullConfig
|
|
|
|
|
|
{
|
|
|
|
|
|
std::string rtspUrl; // rtsp://user:pass@host:port/path
|
|
|
|
|
|
bool useTcp{true}; // true=TCP 模式,false=UDP(低延迟但容易丢包)
|
|
|
|
|
|
bool enableVideo{true};
|
|
|
|
|
|
bool enableAudio{false};
|
|
|
|
|
|
|
|
|
|
|
|
// 解码后输出:是否做 RGA 转换到 RGBA32 / BGR24,以及目标分辨率
|
|
|
|
|
|
EFFPullPixelFormat outputFormat{EFFPullPixelFormat::RGBA32};
|
|
|
|
|
|
unsigned int outputWidth{0}; // 0 = 跟随输入
|
|
|
|
|
|
unsigned int outputHeight{0};
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 拉流回调帧
|
|
|
|
|
|
*/
|
|
|
|
|
|
struct VrFFPulledFrame
|
|
|
|
|
|
{
|
|
|
|
|
|
const void* data{nullptr};
|
|
|
|
|
|
size_t size{0};
|
|
|
|
|
|
unsigned int width{0};
|
|
|
|
|
|
unsigned int height{0};
|
|
|
|
|
|
unsigned int stride{0}; // 一行字节数(RGBA=width*4,BGR=width*3,NV12=hstride)
|
|
|
|
|
|
EFFPullPixelFormat format{EFFPullPixelFormat::RGBA32};
|
|
|
|
|
|
int64_t ptsUs{0}; // PTS
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
using FFPulledFrameCallback = std::function<void(const VrFFPulledFrame&)>;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief IVrFFMediaPuller
|
|
|
|
|
|
*
|
2026-06-08 17:36:13 +08:00
|
|
|
|
* 基于 FFmpeg libavformat + MPP 硬件解码的 RTSP 拉流(RTSP -> MPP 解码 -> swscale 转换 -> 内存回调)。
|
2026-05-31 00:15:25 +08:00
|
|
|
|
*
|
|
|
|
|
|
* 典型用法:
|
|
|
|
|
|
* IVrFFMediaPuller* puller = nullptr;
|
|
|
|
|
|
* IVrFFMediaPuller::CreateObject(&puller);
|
|
|
|
|
|
* puller->Init(cfg);
|
|
|
|
|
|
* puller->SetFrameCallback([](const VrFFPulledFrame& f){ ... });
|
|
|
|
|
|
* puller->Start();
|
|
|
|
|
|
* ...
|
|
|
|
|
|
* puller->Stop();
|
|
|
|
|
|
* delete puller;
|
|
|
|
|
|
*/
|
|
|
|
|
|
class VR_FFMEDIA_API IVrFFMediaPuller
|
|
|
|
|
|
{
|
|
|
|
|
|
public:
|
|
|
|
|
|
virtual ~IVrFFMediaPuller() = default;
|
|
|
|
|
|
|
|
|
|
|
|
static bool CreateObject(IVrFFMediaPuller** ppPuller);
|
|
|
|
|
|
|
|
|
|
|
|
virtual int Init(const VrFFPullConfig& config) = 0;
|
|
|
|
|
|
|
|
|
|
|
|
virtual void SetFrameCallback(FFPulledFrameCallback callback) = 0;
|
|
|
|
|
|
|
|
|
|
|
|
virtual int Start() = 0;
|
|
|
|
|
|
virtual int Stop() = 0;
|
|
|
|
|
|
virtual int UnInit() = 0;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 当前是否处于拉流状态
|
|
|
|
|
|
*/
|
|
|
|
|
|
virtual bool IsStreaming() const = 0;
|
|
|
|
|
|
};
|