mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-10-27 16:00:49 +08:00
perf(video): 消除中间帧复制并优化 MJPEG 有界预取
通过 Bytes 所有权和只读 AVBufferRef 引用池化 NV12 输入,消除中间 AVFrame 的整帧复制,并保留 V4L2 编码包脱离硬件缓冲的处理。 允许输出健康时有界预取 MJPEG,在输出背压时优先解码前丢帧;增加等帧、输出等待、丢帧原因及编码分段耗时统计,提供预取和所有权输入的对照开关。 补充缓冲寿命、只读保护、软件编码回退和队列策略测试及接口说明,保留现有 PTS、解码 worker、音频和加密行为。
This commit is contained in:
51
libs/hwcodec/cpp/ffmpeg_ram/owned_nv12_frame.h
Normal file
51
libs/hwcodec/cpp/ffmpeg_ram/owned_nv12_frame.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifndef OWNED_NV12_FRAME_H
|
||||
#define OWNED_NV12_FRAME_H
|
||||
|
||||
extern "C" {
|
||||
#include <libavutil/frame.h>
|
||||
}
|
||||
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
|
||||
using RamInputRelease = void (*)(void *, uint8_t *);
|
||||
|
||||
struct RamFrameDeleter {
|
||||
void operator()(AVFrame *frame) const { av_frame_free(&frame); }
|
||||
};
|
||||
|
||||
using RamOwnedFrame = std::unique_ptr<AVFrame, RamFrameDeleter>;
|
||||
|
||||
static RamOwnedFrame make_owned_nv12_frame(const uint8_t *data, int length,
|
||||
int width, int height, void *owner,
|
||||
RamInputRelease release) {
|
||||
const int64_t pixels = static_cast<int64_t>(width) * height;
|
||||
if (!data || !release || width <= 0 || height <= 0 || width % 2 ||
|
||||
height % 2 || pixels > std::numeric_limits<int>::max() / 3 * 2 ||
|
||||
length < pixels + pixels / 2) {
|
||||
if (release)
|
||||
release(owner, const_cast<uint8_t *>(data));
|
||||
return RamOwnedFrame();
|
||||
}
|
||||
RamOwnedFrame frame(av_frame_alloc());
|
||||
if (!frame) {
|
||||
release(owner, const_cast<uint8_t *>(data));
|
||||
return frame;
|
||||
}
|
||||
frame->buf[0] = av_buffer_create(const_cast<uint8_t *>(data), length, release,
|
||||
owner, AV_BUFFER_FLAG_READONLY);
|
||||
if (!frame->buf[0]) {
|
||||
release(owner, const_cast<uint8_t *>(data));
|
||||
return RamOwnedFrame();
|
||||
}
|
||||
frame->format = AV_PIX_FMT_NV12;
|
||||
frame->width = width;
|
||||
frame->height = height;
|
||||
frame->data[0] = frame->buf[0]->data;
|
||||
frame->data[1] = frame->data[0] + pixels;
|
||||
frame->linesize[0] = width;
|
||||
frame->linesize[1] = width;
|
||||
return frame;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user