119 lines
3.5 KiB
C++
119 lines
3.5 KiB
C++
#pragma once
|
|
#include <cstdint>
|
|
#include <cstddef>
|
|
#include <string_view>
|
|
#include <vector>
|
|
#include <initializer_list>
|
|
|
|
namespace ffmsep {
|
|
|
|
inline constexpr int CP_SUCCESS = 0;
|
|
inline constexpr int CP_ERROR_EOF = -1;
|
|
inline constexpr int CP_ERROR_EAGAIN = -2;
|
|
inline constexpr int CP_ERROR_NOT_OPEN = -3;
|
|
inline constexpr int CP_ERROR_INVALID_STATE = -4;
|
|
inline constexpr int CP_ERROR_INVALID_ARGUMENT = -5;
|
|
|
|
enum class CPMediaType : std::uint8_t {
|
|
Unknow = 0,
|
|
Data,
|
|
};
|
|
|
|
enum class CPCodecID : std::uint32_t {
|
|
Unknow = 0,
|
|
Tactile = 0x54514354u // 'T','Q','C','T':触觉传感器协议标识 Tactile Quick Codec Type
|
|
};
|
|
|
|
struct CPPacket {
|
|
std::vector<std::uint8_t> payload;
|
|
std::int64_t pts = 0;
|
|
std::int64_t dts = 0;
|
|
bool end_of_stream = false;
|
|
bool flush = false;
|
|
|
|
CPPacket() = default;
|
|
CPPacket(std::vector<std::uint8_t> data, std::int64_t pts_value = 0, std::int64_t dts_value = 0) noexcept
|
|
: payload(std::move(data)), pts(pts_value), dts(dts_value) {}
|
|
|
|
[[nodiscard]] bool empty() const noexcept {return payload.empty();}
|
|
};
|
|
|
|
struct CPFrame {
|
|
std::vector<std::uint8_t> data;
|
|
std::int64_t pts = 0;
|
|
bool key_frame = false;
|
|
bool valid = false;
|
|
|
|
void reset() noexcept {
|
|
data.clear();
|
|
key_frame = false;
|
|
valid = false;
|
|
pts = 0;
|
|
}
|
|
};
|
|
|
|
struct CPCodecContext;
|
|
|
|
struct CPCodec {
|
|
using InitFn = int(*)(CPCodecContext*);
|
|
using CloseFn = void(*)(CPCodecContext*);
|
|
using SendPacketFn = int(*)(CPCodecContext*, const CPPacket&);
|
|
using ReceiveFrameFn = int(*)(CPCodecContext*, CPFrame&);
|
|
|
|
const char* name = nullptr;
|
|
const char* long_name = nullptr;
|
|
CPMediaType type = CPMediaType::Unknow;
|
|
CPCodecID id = CPCodecID::Unknow;
|
|
std::size_t priv_data_size = 0;
|
|
InitFn init = nullptr;
|
|
CloseFn close = nullptr;
|
|
SendPacketFn send_packet = nullptr;
|
|
ReceiveFrameFn receive_frame = nullptr;
|
|
};
|
|
|
|
struct CPCodecContext {
|
|
const CPCodec* codec = nullptr;
|
|
void* priv_data = nullptr;
|
|
CPMediaType codec_type = CPMediaType::Unknow;
|
|
bool is_open = false;
|
|
|
|
void clear() noexcept {
|
|
codec = nullptr;
|
|
priv_data = nullptr;
|
|
codec_type = CPMediaType::Unknow;
|
|
is_open = false;
|
|
priv_storage.clear();
|
|
}
|
|
|
|
void* ensure_priv_storage(std::size_t size);
|
|
void release_priv_storage() noexcept;
|
|
|
|
template<typename T>
|
|
[[nodiscard]] T* priv_as() noexcept {
|
|
return static_cast<T*>(priv_data);
|
|
}
|
|
|
|
template<typename T>
|
|
[[nodiscard]] const T* priv_as() const noexcept {
|
|
return static_cast<const T*>(priv_data);
|
|
}
|
|
|
|
private:
|
|
std::vector<std::uint8_t> priv_storage;
|
|
friend CPCodecContext* cpcodec_alloc_context(const CPCodec*);
|
|
friend int cpcodec_open(CPCodecContext*, const CPCodec*);
|
|
friend int cpcodec_close(CPCodecContext*);
|
|
};
|
|
void cpcodec_register(const CPCodec* codec);
|
|
void cpcodec_register_many(std::initializer_list<const CPCodec*> codecs);
|
|
const CPCodec* cpcodec_find_decoder(CPCodecID id);
|
|
const CPCodec* cpcodec_find_decoder_by_name(std::string_view name);
|
|
std::vector<const CPCodec*> cpcodec_list_codecs();
|
|
|
|
CPCodecContext* cpcodec_alloc_context(const CPCodec* codec);
|
|
int cpcodec_open(CPCodecContext*, const CPCodec*);
|
|
int cpcodec_close(CPCodecContext*);
|
|
void cpcodec_free_context(CPCodecContext **ctx);
|
|
int cpcodec_send_packet(CPCodecContext*, const CPPacket*);
|
|
int cpcodec_receive_frame(CPCodecContext*, CPFrame*);
|
|
} |