- mag160c_demo3.c 从内联管线重写为 render API 调用:删除 DDT 加载/NUC/ LUT/gray/2x/FFC 状态机实现(~700 行),保留 USB 取帧/GDI/探针/附加环节 - 附加环节(0x230 帧差/0x41fe8 隔行平滑/0x30 gray 覆盖)经 render 的 post_nuc/post_gray 钩子挂接,编译开关与运行时按键 0/8/9 不变 - mag160c_render 新增 mag160c_render_request_ffc / get_nuc 访问器 - 实测无回归:FFC 时序 init@20→FFC(1)@28→漂移触发,与 v5 一致; stats 正常,auto BMP 生成正常;全开关版本编译通过 - linux_demo 修帧组装(38400px+28B 尾),快门=31492 sel=2 正常
111 lines
4.7 KiB
C
111 lines
4.7 KiB
C
/*
|
|
* mag160c_render.h - platform-independent official rendering pipeline.
|
|
*
|
|
* Mirrors the official CoreSDKLib.dll frame path (verified pixel-exact):
|
|
* raw frame -> shutter extract -> FFC state machine -> endpoint select
|
|
* + Q12 table interp -> ref (4x type-1 mean) -> NUC lookup -> blind
|
|
* compensation -> stats/window -> LUT1024 rebuild -> gray -> 2x
|
|
* upscale -> palette -> RGB24 output.
|
|
*
|
|
* No OS/display dependencies: feed it USB frames, get 320x240 RGB24.
|
|
* FFC commands are emitted through a callback so the caller owns the
|
|
* transport (libusb on Linux, bulk transfers on Windows, ...).
|
|
*/
|
|
#ifndef MAG160C_RENDER_H
|
|
#define MAG160C_RENDER_H
|
|
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include "mag160c.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* Default output geometry (official: 2x of the 160x120 sensor). */
|
|
#define MAG160C_RENDER_OUT_W 320
|
|
#define MAG160C_RENDER_OUT_H 240
|
|
|
|
/* FFC command callback: param 0 = FFC(0), 1 = FFC(1). */
|
|
typedef void (*mag160c_render_ffc_cb_t)(void *user, int param);
|
|
|
|
/* Optional post-NUC hook (called after NUC+blind, before stats/window).
|
|
* Lets the app run the official extra paths (frame-diff 0x230, interlace
|
|
* smoothing 0x41fe8) on the NUC buffer. */
|
|
typedef void (*mag160c_render_post_nuc_cb_t)(void *user, unsigned short *nuc);
|
|
|
|
/* Optional post-gray hook (called after the 160x120 gray is mapped,
|
|
* before the 2x upscale). Lets the app run the official 0x30 gray
|
|
* overlay paths (0x17770 auto / 0x17c40 manual) on the gray buffer. */
|
|
typedef void (*mag160c_render_post_gray_cb_t)(void *user, unsigned char *gray160);
|
|
|
|
typedef struct mag160c_render_t mag160c_render_t;
|
|
|
|
typedef struct mag160c_render_cfg_t {
|
|
uint16_t width; /* sensor width, 160 */
|
|
uint16_t height; /* sensor height, 120 */
|
|
const char *ddt_path; /* official DDT calibration file */
|
|
int ffc_period; /* frames between FFC pairs, official 1800 */
|
|
int ffc_drift; /* shutter drift threshold, official 250 */
|
|
int startup_force_ffc; /* official frame-75 forced FFC, 1 = on */
|
|
int warm_frames; /* frames dropped after start, official 20 */
|
|
int cdf_pivot_75; /* 0x8c: CDF pivot at 75% cumulative, 1 = on */
|
|
mag160c_render_ffc_cb_t ffc_cb;
|
|
void *ffc_user;
|
|
mag160c_render_post_nuc_cb_t post_nuc_cb;
|
|
void *post_nuc_user;
|
|
mag160c_render_post_gray_cb_t post_gray_cb;
|
|
void *post_gray_user;
|
|
} mag160c_render_cfg_t;
|
|
|
|
MAG160C_API mag160c_error_t
|
|
mag160c_render_init(mag160c_render_t **out, const mag160c_render_cfg_t *cfg);
|
|
|
|
/* Process one raw frame.
|
|
* frame : USB frame buffer. If has_hdr, the 28-byte header is at
|
|
* frame[0] (marker 0x1bb1b11b, counter, len, type, ...) and
|
|
* the shutter word is extracted from the tail; otherwise
|
|
* frame is the bare 38400-byte pixel buffer and shutter
|
|
* must be supplied via mag160c_render_set_shutter().
|
|
* out_rgb : 320x240x3 RGB24 (palette-colored).
|
|
* Returns MAG160C_OK when out_rgb was written, MAG160C_ERR_NOT_READY
|
|
* while the startup/FFC window is running (image frozen by caller). */
|
|
MAG160C_API mag160c_error_t
|
|
mag160c_render_frame(mag160c_render_t *r, const uint8_t *frame,
|
|
int has_hdr, uint8_t *out_rgb);
|
|
|
|
/* Bare-pixel mode: set the current shutter (device temperature proxy)
|
|
* before calling mag160c_render_frame(). */
|
|
MAG160C_API void mag160c_render_set_shutter(mag160c_render_t *r, int shutter);
|
|
|
|
/* Per-frame diagnostics for UI overlays. */
|
|
MAG160C_API void mag160c_render_get_stats(mag160c_render_t *r,
|
|
int *win_lo, int *win_hi,
|
|
int *fmin, int *fmax,
|
|
int *mean, int *stddev);
|
|
MAG160C_API int mag160c_render_get_shutter(mag160c_render_t *r);
|
|
MAG160C_API int mag160c_render_get_endpoint(mag160c_render_t *r);
|
|
MAG160C_API int mag160c_render_get_frame_index(mag160c_render_t *r);
|
|
MAG160C_API int mag160c_render_has_reference(mag160c_render_t *r);
|
|
|
|
/* Manual FFC trigger (official FFC button / recenter): forces FFC(0) at
|
|
* the next rendered frame. */
|
|
MAG160C_API void mag160c_render_request_ffc(mag160c_render_t *r);
|
|
|
|
/* NUC-domain pixel read (valid when mag160c_render_has_reference()).
|
|
* Returns 0 when no reference yet. Used for hot-spot scan / overlay. */
|
|
MAG160C_API uint32_t mag160c_render_get_nuc(mag160c_render_t *r, uint32_t idx);
|
|
|
|
/* Temperature probe on the current NUC output (millidegrees C). */
|
|
MAG160C_API mag160c_error_t
|
|
mag160c_render_probe_temp(mag160c_render_t *r, uint32_t x, uint32_t y,
|
|
int32_t *out_temp_mc);
|
|
|
|
MAG160C_API void mag160c_render_destroy(mag160c_render_t *r);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* MAG160C_RENDER_H */
|