跳到主要内容

3.4.3 JDK API 说明

data_type

枚举 media_type

设备媒体类型枚举:

含义
MEDIA_TYPE_CANT_STAT无法获取设备状态
MEDIA_TYPE_UNKNOWN未知
MEDIA_TYPE_VIDEO视频
MEDIA_TYPE_VBIVBI(垂直消隐)
MEDIA_TYPE_RADIO广播
MEDIA_TYPE_SDRSDR(软件定义无线电)
MEDIA_TYPE_TOUCH触摸输入
MEDIA_TYPE_SUBDEV子设备
MEDIA_TYPE_DVB_FRONTEND数字电视前端
MEDIA_TYPE_DVB_DEMUX数字电视解复用
MEDIA_TYPE_DVB_DVR数字电视录像
MEDIA_TYPE_DVB_NET数字电视网络
MEDIA_TYPE_DTV_CA数字电视条件访问
MEDIA_TYPE_MEDIA媒体设备

枚举 codec_type

表示当前设备或上下文是否为编码或解码:

含义
NOT_CODEC非编解码
CODEC_DEC解码
CODEC_ENC编码

结构体 v4l2_ctx

V4L2 捕获及编码上下文结构体定义:

struct v4l2_ctx {
int fd; // 设备文件句柄
unsigned int width; // 视频宽度
unsigned int height; // 视频高度
unsigned int pixelformat; // 输入像素格式
unsigned int out_pixelformat; // 输出像素格式
int nplanes; // 输入平面数
int out_nplanes; // 输出平面数
struct buffer* cap_buffers; // 捕获缓冲区数组
struct buffer* out_buffers; // 输出缓冲区数组
__u32 bytesperline[VIDEO_MAX_PLANES]; // 各输入平面行字节数
__u32 out_bytesperline[VIDEO_MAX_PLANES]; // 各输出平面行字节数
FILE* file[2]; // 输入/输出文件指针
int verbose; // 日志详细等级
enum codec_type ctype; // 编码/解码类型
};

JdkFrame

表示一帧视频数据的封装类:

class JdkFrame {
public:
JdkFrame(int dma_fd_, size_t size_, int w, int h);
~JdkFrame();

// 将 DMA 缓冲区映射到 CPU 内存并返回指针
unsigned char* toHost() const;
// 克隆返回数据副本
std::vector<unsigned char> Clone() const;
// 保存为 NV12 格式 .yuv 文件
bool saveToFile(const std::string& filename) const;
// 从文件加载数据(与 saveToFile 配对使用)
bool loadFromFile(const std::string& filename, size_t expected_size);

// 获取底层 DMA FD
int getDMAFd() const;
// 获取缓冲区大小
size_t getSize() const { return size_; }
// 获取分辨率
int getWidth() const { return width_; }
int getHeight() const { return height_; }

// 将原始 NALU 数据拷贝到内部 buffer(如编码后写入)
// offset:目标缓冲区偏移
int MemCopy(const uint8_t* nalu, int nalu_size, int offset = 0);

private:
size_t size_; // 缓冲区总大小
int width_;
int height_;
JdkDma dma_; // DMA 同步辅助
std::shared_ptr<JdkDmaBuffer> data; // 底层 DMA buffer
};

using JdkFramePtr = std::shared_ptr<JdkFrame>;

JdkDma

DMA 缓冲区及异步复制类:

class JdkDmaBuffer {
public:
// 构造并分配 DMA 缓冲区
explicit JdkDmaBuffer(size_t size);
~JdkDmaBuffer();

// 返回映射后的用户空间地址
void* data() const;
// 整块填充值
void fill(uint8_t val);

// 获取物理地址(需先调用 map_phys_addr)
void map_phys_addr();

// 公开字段(只读)
size_t m_size;
uint64_t m_phys;
};

class JdkDma {
public:
// 通过 DMA 引擎异步复制数据
int Asyn(const JdkDmaBuffer& dst, const JdkDmaBuffer& src, size_t size);
// FD 间的 DMA 复制
int Asyn(const int& dst_fd, const int& src_fd, size_t size);
};

JdkCamera

摄像头采集接口:

class JdkCamera {
public:
/**
* 创建并打开 V4L2 设备
* @param device 设备路径 (e.g. "/dev/video0")
* @param width 期望采集宽度
* @param height 期望采集高度
* @param pixfmt V4L2 像素格式 (e.g. V4L2_PIX_FMT_NV12)
* @param req_count 请求的缓冲区数量 (默认 4)
* @return 成功返回 JdkCameraPtr,否则返回 nullptr
*/
static std::shared_ptr<JdkCamera> create(const std::string& device,
int width,
int height,
__u32 pixfmt,
int req_count = 4);
/** 获取一帧图像(阻塞) */
JdkFramePtr getFrame();

~JdkCamera();

private:
explicit JdkCamera(const std::string& device);
class Impl;
std::unique_ptr<Impl> impl_;
};
using JdkCameraPtr = std::shared_ptr<JdkCamera>;

JdkDecoder

硬件解码器:

class JdkDecoder {
public:
/**
* 初始化硬件解码器
* @param width 输出分辨率宽度
* @param height 输出分辨率高度
* @param payload 输入码流类型 (见 MppCodingType)
* @param Format 输出像素格式 (默认 NV12)
*/
JdkDecoder(int width, int height,
MppCodingType payload,
MppPixelFormat Format = PIXEL_FORMAT_NV12);
~JdkDecoder();

/** 解码,从已封装帧中解码 */
std::shared_ptr<JdkFrame> Decode(std::shared_ptr<JdkFrame> frame);
/** 解码,从裸 NALU 数据解码 */
std::shared_ptr<JdkFrame> Decode(const uint8_t* nalu, int nalu_size);

private:
int width_;
int height_;
MppCodingType payload_;
int format_;
int channel_id_;
MppVdecCtx* pVdecCtx = nullptr;
};

JdkEncoder

硬件编码器:

class JdkEncoder {
public:
/**
* 初始化硬件编码器
* @param width 输入分辨率宽度
* @param height 输入分辨率高度
* @param payload 输出码流类型 (见 MppCodingType)
* @param Format 输入像素格式 (默认 NV12)
*/
JdkEncoder(int width, int height,
MppCodingType payload,
MppPixelFormat Format = PIXEL_FORMAT_NV12);
~JdkEncoder();

/** 编码,将原始帧编码为压缩码流 */
std::shared_ptr<JdkFrame> Encode(std::shared_ptr<JdkFrame> frame);

private:
int width_;
int height_;
MppCodingType payload_;
int format_;
int encoder_id_ = 0;
MppVencCtx* pVencCtx = nullptr;
};

JdkDrm

DRM 显示接口:

/** 支持的像素格式 */
enum class PixelFmt : uint32_t {
NV12 = DRM_FORMAT_NV12
};

class JdkDrm {
public:
/**
* 打开 DRM 设备并初始化
* @param width 显示宽度
* @param height 显示高度
* @param stride 行跨度 (bytes)
* @param fmt 像素格式
* @param device DRM 设备路径 (默认 "/dev/dri/card0")
*/
JdkDrm(int width, int height, int stride,
PixelFmt fmt = PixelFmt::NV12,
const char* device = "/dev/dri/card0");
~JdkDrm();

/** 发送一帧到 DRM 屏幕 */
int sendFrame(std::shared_ptr<JdkFrame> frame);
/** 销毁指定的 framebuffer */
void destroyFb(uint32_t fb, uint32_t handle);
/** 打开 DRM 设备 */
int openCard(const char* dev);
/** 自动选取合适的 connector/crtc/plane */
int pickConnectorCrtcPlane();
/** 导入 DMA FD 为 DRM framebuffer */
int importFb(int dma_fd, uint32_t& fb_id, uint32_t& handle);

private:
struct LastFB {
uint32_t fb_id;
uint32_t handle;
int dma_fd;
} last_;
};

JdkV2D

视频图像处理接口:

/** 支持的目标像素格式(枚举值请参考完整头文件) */
enum V2DFormat {
// 例如: V2D_NV12, V2D_RGB888, ……
};

/** 矩形区域 */
struct V2DRect {
int x, y, width, height;
};

class JdkV2D {
public:
JdkV2D() = default;
~JdkV2D() = default;

/** 格式转换 */
JdkFramePtr convert_format(const JdkFramePtr& input,
V2DFormat out_format);
/** 缩放 */
JdkFramePtr resize(const JdkFramePtr& input,
int out_width, int out_height);
/** 同时缩放并格式转换 */
JdkFramePtr resize_and_convert(const JdkFramePtr& input,
int out_width, int out_height,
V2DFormat out_format);
/** 填充矩形区域 */
bool fill_rect(const JdkFramePtr& image,
const V2DRect& rect,
uint32_t rgba_color);
/** 绘制矩形边框 */
bool draw_rect(const JdkFramePtr& image,
const V2DRect& rect,
uint32_t rgba_color,
int thickness = 2);
/** 绘制多矩形 */
bool draw_rects(const JdkFramePtr& image,
const std::vector<V2DRect>& rects,
uint32_t rgba_color,
int thickness = 2);
/** 图像融合(bottom 上叠加 top) */
JdkFramePtr blend(const JdkFramePtr& bottom,
const JdkFramePtr& top);
};

JdkVo

视频输出接口:

class JdkVo {
public:
/**
* 初始化 Vo 输出
* @param width 输出宽度
* @param height 输出高度
* @param Format 像素格式 (默认 NV12)
*/
JdkVo(int width, int height,
MppPixelFormat Format = PIXEL_FORMAT_NV12);
~JdkVo();

/** 发送一帧到 Vo 硬件输出 */
int sendFrame(std::shared_ptr<JdkFrame> frame);

private:
int width_;
int height_;
MppPixelFormat format_;
int channel_id_;
MppVoCtx* pVoCtx = nullptr;
};

使用提示

  • 枚举值及常量请参考对应头文件以获取完整定义。
  • 大多数返回 int 函数中,0 表示成功,非零为错误码。
  • 智能指针(std::shared_ptr)用于自动管理资源,避免手动释放。
  • 具体示例及错误处理可根据项目需求补充完善。