簡單查看流程,如有錯誤請指出。
CameraNativePreview.ets--> ?這里開始進入uvc_camera庫
(CameraDevice.ets/CameraManager.ets) ?--> CameraUtils.ets-->
-->CameraNativeMethods(index.d.ts文件,路徑:
uvc_camera\src\main\cpp\types\libuvc_camera\index.d.ts)
-->camera_uvc.cpp-->(camera_factory_helper.h,camera->getUserStream())
其中camera->getUserStream()在ICameraDevice?中,是base類,有倆實現:
class CameraDeviceUsbImpl : public ICameraDevice
在camera_device_usb.h中,路徑camera/usb,實現camera_device_usb.cpp
class CameraDeviceV4L2Impl : public ICameraDevice
在camera_device_v4l2.h中,路徑camera/v4l2
這里分析camera_device_usb.cpp
-->CameraStreamUsbImpl(camera_stream_usb.cpp)-->(prepare_preview,do_preview):
prepare_preview-->(uvc_get_stream,uvc_get_frame_desc,這倆方法都指向stream.c,路徑:
uvc_camera\src\main\cpp\libuvc\src\stream.c)
do_preview-->uvc_start_streaming-->stream.c-->uvc_start_streaming-->
(uvc_stream_open_ctrl,uvc_stream_start):
uvc_stream_open_ctrl-->(_uvc_get_stream_if,uvc_claim_if,uvc_stream_ctrl)
uvc_stream_start-->(uvc_find_frame_desc_stream,
libusb_fill_iso_transfer/libusb_fill_bulk_transfer,
pthread_create(&strmh->cb_thread, NULL, _uvc_user_caller, (void *)strmh);
libusb_submit_transfer)
-------------------------------------------------------------------------------------------------------------
這里根據紅綠藍三顏色分別分析:
一:
libusb_fill_iso_transfer-->_uvc_stream_callback-->(
_uvc_process_payload??或者
(pthread_cond_broadcast(&strmh->cb_cond);
pthread_mutex_unlock(&strmh->cb_mutex);))
這里根據LIBUSB_TRANSFER_XXX狀態不同會走不同的路徑,而libusb_fill_bulk_transfer和libusb_fill_iso_transfer一樣都會走_uvc_stream_callback,路徑一致
二:
pthread_create(&strmh->cb_thread, NULL, _uvc_user_caller, (void*)strmh
-->_uvc_user_caller--->(_uvc_populate_frame,
pthread_mutex_unlock(&strmh->cb_mutex);
strmh->user_cb(&strmh->frame, strmh->user_ptr);
)。
三:libusb_submit_transfer-->io.c-->libusb_submit_transfer
其中:_uvc_process_payload-->_uvc_swap_buffers
-->(pthread_cond_broadcast(&strmh->cb_cond);
pthread_mutex_unlock(&strmh->cb_mutex);)
數據是從linux_usbfs.c 中來的,從打開流到關閉流的整個過程,這里都會不停地打印:
op_submit_transfer:2
submit_bulk_transfer
handle_bulk_completion
op_submit_transfer:2
submit_bulk_transfer
_uvc_user_caller
而在獲取參數的過程中:
就會開始不停地打印:
op_submit_transfer:0
submit_control_transfer
handle_control_completion
直到打開后突然就變成:
op_submit_transfer:2
submit_bulk_transfer
然后:?_uvc_user_caller
而_uvc_user_caller方法見下:
do {
????LOG_D("_uvc_user_caller");
????pthread_mutex_lock(&strmh->cb_mutex);
????while (strmh->running && last_seq == strmh->hold_seq) {
????????pthread_cond_wait(&strmh->cb_cond, &strmh->cb_mutex);
????}
????if (!strmh->running) {
????????pthread_mutex_unlock(&strmh->cb_mutex);
????????break;
????}
????last_seq = strmh->hold_seq;
????_uvc_populate_frame(strmh);
????pthread_mutex_unlock(&strmh->cb_mutex);
????strmh->user_cb(&strmh->frame, strmh->user_ptr);
} while (1);
這里能否繼續執行取決于&strmh->cb_cond,搜索&strmh->cb_cond發現多出調用了:
pthread_cond_broadcast(&strmh->cb_cond);
pthread_mutex_unlock(&strmh->cb_mutex);
如:_uvc_swap_buffers
_uvc_stream_callback
uvc_stream_stop
而在linux_usbfs.c中的執行是:
op_handle_events-->reap_for_handle-->r = ioctl(hpriv->fd, IOCTL_USBFS_REAPURBNDELAY, &urb);
-->handle_bulk_completion(itransfer, urb);-->usbi_mutex_unlock(&itransfer->lock);
或者是
op_submit_transfer-->submit_bulk_transfer-->ioctl(hpriv->fd, IOCTL_USBFS_SUBMITURB, urb);
然后通過itransfer的數據和狀態變化,或者喚醒?調用_uvc_stream_callback??? 這樣就會和下面這段連接起來
而在stream.c中一般是通過:uvc_stream_start(開始執行一次)-->
_uvc_stream_callback
-->_uvc_process_payload
(_uvc_process_payload(strmh, transfer->buffer, transfer->actual_length);)-->
(
????????if (header_info & UVC_STREAM_EOF || ?strmh->got_bytes == strmh->cur_ctrl.dwMaxVideoFrameSize) {
????????????//來交換緩沖區,表示已接收完整幀
????????????_uvc_swap_buffers(strmh);
????????}
)
-->_uvc_swap_buffers
-->_uvc_user_caller
uvc_camera\src\main\cpp\libusb\os\linux_usbfs.c
這個包括了基本的usb操作
uvcCamera\uvc_camera\src\main\cpp\libusb\io.c
這個包括了io
uvc_camera\src\main\cpp\libuvc\src\stream.c
這里封裝了基本的相機流操作
然后關于
pthread_cond_broadcast(&strmh->cb_cond)
pthread_mutex_unlock(&strmh->cb_mutex)
以及close流程 ??