카메라 입력 노드
CameraInput은 libcamera와 GStreamer의 libcamerasrc를 통해 노출된 MIPI 카메라에 대한 소스 노드입니다. 프레임이 run.push(...) 대신 DevKit 카메라 스택에서 가져와야 할 때 소스에서 소유한 그래프의 시작 부분에 사용합니다.
작업 가이드는 MIPI 카메라를 사용하세요.를 참조하십시오.
필수 조건
CameraInput을 사용하기 전에, Neat 외부에서 카메라를 실행하세요.
- Modalix DevKit의 전원이 꺼진 상태에서 카메라를 연결하십시오.
- 캐리어 보드, 카메라 제조업체, 센서 및 포트에 맞는
.dtbo오버레이를 선택합니다. - libcamera가 카메라 목록을 제대로 표시하는지 확인합니다.
- 요청하려는 정확한
format,width,height,framerate로libcamerasrc가 스트리밍할 수 있는지 확인하십시오.
camera_name은 libcamera 카메라 이름입니다. 기본 카메라를 사용하려면 이 값을 설정하지 않고, 보드가 둘 이상의 카메라를 지원하는 경우 cam -l에서 카메라 이름을 복사하여 설정하십시오.
빠른 시작
#include <neat.h>
namespace neat = simaai::neat;
neat::CameraInputOptions opt;
opt.width = 1920;
opt.height = 1080;
opt.framerate_num = 30;
opt.framerate_den = 1;
opt.format = "NV12";
opt.buffer_name = "camera0";
opt.allow_cpu_fallback = true;
neat::Graph graph;
graph.add(neat::nodes::CameraInput(opt));
graph.add(neat::nodes::Output("frames"));
neat::Run run = graph.build();
std::optional<neat::Sample> frame = run.pull(/*timeout_ms=*/5000);
CameraInput이 소스 데이터를 소유하므로, 애플리케이션에 다른 앱에서 제공하는 입력이 실제로 필요한 경우가 아니라면 공개 Input 노드를 생성하지 않고 그래프를 구축하십시오.
API 인터페이스
namespace simaai::neat {
struct CameraInputOptions;
class CameraInput;
}
namespace simaai::neat::nodes {
std::shared_ptr<simaai::neat::Node> CameraInput(
simaai::neat::CameraInputOptions opt = {});
std::shared_ptr<simaai::neat::Node> CameraInputWithCaptureBuffers(
simaai::neat::CameraInputOptions opt,
std::uint32_t capture_buffer_count);
}
파이썬:
opt = pyneat.CameraInputOptions()
node = pyneat.nodes.camera_input(opt, capture_buffer_count=32)
옵션
| 필드 | 기본값 | 설명 |
|---|---|---|
camera_name | 설정 해제 | 선택 사항: libcamera 카메라 이름입니다. 일반적으로 cam -l에서 복사합니다. 설정 해두면 libcamera가 기본 카메라를 선택합니다. |
width | 1920 | 픽셀 단위로 요청하는 프레임 너비입니다. 카메라 모드 및 오버레이에서 지원해야 합니다. |
height | 1080 | 픽셀 단위로 요청된 프레임 높이입니다. |
framerate_num | 30 | 프레임 속도 분자. |
framerate_den | 1 | 프레임 속도 분모입니다. 0은 1로 정규화됩니다. |
format | "NV12" | 형식의 video/x-raw가 요청되었습니다. NV12는 권장되는 모델 전처리 경로입니다. |
| <<번역>> | ||
buffer_name | "camera" | 후속 메타데이터 및 모델 경로 이름 지정에 사용되는 논리적 버퍼 이름입니다. |
insert_queue | true | 할당자 협상 및 제로 복사 검증 후에 작은 실시간 소스 큐를 삽입합니다. |
leaky_queue | true | 큐를 하류에서 누수되도록 만들어 실시간 그래프가 오래된 백로그보다 최신 프레임을 선호하도록 합니다. |
queue_depth | 2 | insert_queue가 참일 때, 대기열에 쌓을 수 있는 최대 버퍼 수입니다. |
allow_cpu_fallback | false | false인 경우 카메라의 DMA-BUF를 전달하고, 복사가 필요한 프레임이 있으면 실패합니다. Neat의 비공개 브리지가 이러한 프레임을 CMA DMA-BUF로 복사하도록 허용하려는 경우에만 true로 설정합니다. |
capture_buffer_count는 CameraInputOptions 필드가 아닌, CameraInputWithCaptureBuffers에 전달되는 인자입니다. 기본값은 0이며, 이는 카메라 파이프라인 자체의 기본값을 유지합니다. 카메라 파이프라인은 자체 제한을 검증하며, Neat의 공급자는 최대 128까지 지원합니다.
입력 및 출력 계약
| 계약 항목 | 행동 |
|---|---|
| 입력 역할: | 소스 노드. 이 그래프는 카메라에서 프레임을 가져옵니다. 앱에서 샘플을 이 노드로 보내지는 않습니다. |
| 출력 미디어 유형: | video/x-raw. |
| 출력 형식 | 요청된 형식은 일반적으로 format, 보통 NV12입니다. |
| 메모리 계약 | 카메라 자체의 DMA-BUF가 복사 없이 다운스트림으로 전달됩니다. 폴백 기능이 활성화되면 하나의 DMA-BUF가 아닌 프레임은 후속 CVU/MLA 단계를 위해 CMA DMA-BUF로 복사됩니다. |
| 요청된 옵션을 기반으로 정지된 힌트를 통해 기능 제한을 확정합니다. 런타임 기능 제한 협상은 여전히 카메라 스택에 따라 달라집니다. |
제로 복사 및 대체
allow_cpu_fallback = false는 기본값이며 엄격한 제로 복사 방식을 요청합니다. 카메라는 각 프레임을 자체 DMA-BUF에 기록하고, 모든 다운스트림 단계는 그 동일한 메모리를 읽습니다. Neat는 카메라의 메모리를 소유하지 않으므로 libcamerasrc 속성이 필요하지 않습니다. 물리적으로 연속된 DMA-BUF는 모두 유효한 EV74 입력이며, Neat의 EV74 허용 검사는 해당 DMA-BUF가 CMA 힙 또는 카메라의 연속 캡처 할당자(videobuf2_dma_contig)에서 온 경우 이를 받아들입니다.
Neat는 항상 자체 카메라 브리지를 capsfilter 바로 뒤, 라이브 큐 앞에 배치합니다. 브리지는 GST_QUERY_ALLOCATION을 통해 소스에 GstVideoMeta를 첨부하도록 요청한 다음, 평면들이 하나의 DMA-BUF 안에 연속으로 배치된 각 프레임을 단일 메모리로 전달하며, 모든 소비자가 해제할 때까지 카메라의 버퍼를 유지합니다. 엄격한 모드에서는 이 방식으로 전달할 수 없는 프레임이 파이프라인을 실패시키고, 폴백이 활성화된 경우에는 대신 CMA DMA-BUF로 복사됩니다.
다운스트림 소유자를 기반으로 capture_buffer_count를 카메라 팩토리에 전달합니다. 임시 인코더 또는 딥 비동기 ML 그래프는 32개의 버퍼가 필요할 수 있습니다. 낮은 대기 시간의 CV 그래프는 더 적은 버퍼를 사용하고 오래된 프레임을 삭제할 수 있습니다. 이 설정은 ISP 출력/애플리케이션 주기를 제어합니다. 커널의 개인 CSI-to-ISP RAW 전송 링을 확장하지 않으며 GStreamer의 queue_depth 삭제 정책과 독립적입니다. Platform 3.0에서는 libcamerasrc에 buffer-count 속성이 없으므로 해당 플랫폼에서는 capture_buffer_count를 0으로 두십시오.
브리지는 카메라 자체의 버퍼를 전달하므로, 다운스트림 단계가 아직 보유하고 있는 각 프레임은 libcamera 캡처 링의 버퍼 하나를 묶어 둡니다(Platform 3.0에서 IMX477로 1080p NV12를 캡처할 때 8개 버퍼). 그만큼 많은 프레임을 보유하는 그래프는 프레임을 삭제하는 대신 캡처를 정지시키므로, 가져온 프레임은 즉시 해제하십시오.
프레임이 평면들이 연속으로 배치된 하나의 DMA-BUF가 아닐 때 이미 존재하는 브리지가 복사할 수 있도록 allow_cpu_fallback = true를 명시적으로 설정합니다. 브리지는 그러한 DMA-BUF인 프레임은 계속 그대로 전달합니다. 그렇지 않으면 카메라 프레임을 비공개 풀의 CMA DMA-BUF로 복사하고 다운스트림 단계에서 예상하는 메타데이터를 연결합니다. 이 풀은 queue_depth에 의해 제한되는 대신 필요에 따라 최대 128개 버퍼까지 증가하므로 다운스트림의 누수 큐가 브리지가 먼저 중단되지 않고 오래된 프레임을 삭제할 수 있습니다.
폴백 이름은 브리지가 OS/libcamera 버퍼를 허용할 수 있음을 의미합니다. 크기 조정, 색상 변환 또는 정규화를 CPU로 이동해야 한다는 의미는 아닙니다. 해당 경로를 지원하는 경우 모델에서 관리하는 CVU 전처리에서 이러한 작업을 수행하십시오.
CameraInput에 대해 OsToSima 노드를 직접 추가하지 마십시오. 적응은 카메라 소스 경로에 속합니다.
일반적인 그래프 모양
카메라 프레임을 직접 가져오기:
CameraInput -> Output
모델에 카메라를 적용하여 실행합니다.
CameraInput -> model.graph({include_input=false, include_output=true})
모델 파이프라인의 경우, Model::Options::preprocess 또는 pyneat.ModelOptions.preprocess를 통해 전처리 설정을 구성하여 크기 조정, 색상 변환, 정규화, 양자화 및 테셀레이션이 모델에서 관리하는 CVU 경로 내에 있도록 합니다.
고장 유형
| 오류 | 발생 가능한 원인 |
|---|---|
build.plugin_missing | 런타임 플러그인 세트에서 libcamerasrc 또는 neatcamerabridge가 누락되었습니다. |
misconfig.media_caps / not-negotiated | 카메라가 요청된 형식, 해상도 또는 프레임 속도를 지원하지 않습니다. |
misconfig.media_caps / gstreamer.camera_configuration_unsupported | 카메라가 요청된 해상도 또는 픽셀 형식을 제공하지 않아 libcamerasrc의 협상이 실패했습니다. 지원되는 크기로 캡처하세요. 모델 그래프에서는 모델 전처리가 크기를 조정하도록 하고, 그 밖의 그래프에서는 VideoScale 다음에 CapsRaw를 사용하세요. |
| 엄격한 제로 복사 오류, | allow_cpu_fallback은 false이고 카메라가 평면들이 연속으로 배치된 하나의 DMA-BUF가 아닌 프레임을 전달했습니다. |
| 풀 타임아웃 | 카메라가 프레임을 전송하지 못했거나, 그래프에 역압력이 발생했거나, 카메라 스택이 스트리밍을 중단했습니다. |
| <<번역>> | |
| 녹색, 보라색 또는 색조가 강한 프레임 | 프레임 형식 또는 모델의 색상 변환 전처리 과정에 오류가 있거나, 카메라 ISP/libcamera 출력에 이미 색조가 적용되어 있습니다. 먼저 NV12 캡처를 Neat에서 확인하십시오. |