靈芯派的 V4L2 驅動根本不會因為“設置 320×200”去重啓傳感器或重新協商媒體類型,它只在驅動層做裁剪/縮放,所以零額外耗時;Windows 的 Direc

 

一、V4L2 為什麼敢“秒切”

  1. 攝像頭硬件本身只輸出 固定幾種分辨率(比如 1920×1080 MJPEG、640×480 YUYV …)。
  2. 靈芯派內核驅動(bcm2835-v4l2 / sunxi-v4l2)在 open() 時就已經讓傳感器跑在 某一種原生模式(通常是 1920×1080 MJPEG)。
  3. 當你 cap.set(CAP_PROP_FRAME_WIDTH, 320) 時,V4L2 只做兩件事:
  • 在 VIDIOC_S_FMT 裏把返回的 width/height 字段改成 320×200;
  • 後續每次 read() 到達時,驅動 現場做裁剪或縮小,再把數據拷貝到用户空間。
    傳感器時鐘一次都沒停,所以感覺不到延遲。

二、Windows DirectShow 為什麼“必卡”

  1. DirectShow 的 Capture Pin 在 graph 運行後 不允許動態改格式;
  2. 你一旦 set(320, 200),Filter Graph Manager 必須:
  • 停止整個 graph → 釋放 Pin → 重新協商 AM_MEDIA_TYPE → 重新 connect → 再 run;
  1. 這一步要 重新打開內核流接口,USB 攝像頭固件會收到 SET_CUR 請求,很多芯片會 掉電-上電 切換輸出,物理重啓流 3-4 s 就這樣來的。

 

 

  1. 靈芯派(V4L2)
  • 驅動確實很少重啓傳感器,你設任意分辨率都當成「用户想要的後處理尺寸」——實時裁剪/縮放,成本就是 CPU(或 NEON/VPU)算力。
  • 例外:如果你設置的尺寸正好等於驅動列表裏的某個原生模式,部分驅動會「順水推舟」把傳感器切過去,這時 CPU 開銷為零,但切換本身仍比 Windows 快得多(內核級,無 Pin 重建)。
  1. Windows
  • DirectShow / MediaFoundation 的框架規定:Pin 一旦運行就不能改格式,所以「前期固定」與「後期 CPU 裁」是二選一——
  • 想省 CPU → 提前選好原生分辨率,接受 3-4 s 重啓;
  • 想秒開 → 原生分辨率+軟件 resize,代價是持續佔用 CPU/GPU 算力。
  • 因此只有 Windows 才需要糾結「啓動慢 vs 運行慢」的權衡。

總結一句話:
靈芯派永遠可以「後期軟件裁」而幾乎不額外耗時;Windows 下如果你不想等 3-8 s,就必須接受後期 CPU 裁。

import cv2, time

def fast_open():
    start = time.time()
    # 1) 原生打開
    cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
    cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)   # 減少內部緩衝
    # 2) 立即讀一幀
    ret, frame = cap.read()
    open_time = time.time()
    print(f"原生打開+首幀: {open_time - start:.3f}s  shape={frame.shape}")

    # 3) 軟件縮到目標尺寸
    small = cv2.resize(frame, (320, 200))
    resize_time = time.time()
    print(f"軟件縮放耗時: {resize_time - open_time:.3f}s")

    cv2.imshow("small", small)
    cv2.waitKey(0)
    cap.release()

if __name__ == "__main__":
    fast_open()