-
Notifications
You must be signed in to change notification settings - Fork 916
Closed
Description
Answers checklist.
- I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
- I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
- I have searched the issue tracker for a similar issue and not found a similar issue.
IDF version.
ESP-IDF v5.5.0
Espressif SoC revision.
ESP32-P4 (revision v1.0)
Operating System used.
Windows
How did you build your project?
VS Code IDE
If you are using Windows, please specify command line type.
None
Development Kit.
Custom Board
Power Supply used.
USB
What is the expected behavior?
运行程序, 使用 PotPlayer 打开摄像头设备. 正常运行, 输出图像:
I (3803) usbd_uvc: Mount
I (4422) usbd_uvc: bFrameIndex: 1
I (4422) usbd_uvc: dwFrameInterval: 333333
I (4423) uvc_device.c: 摄像头1 协商格式: MJPEG, 宽度: 1280, 高度: 720, 帧率: 30
I (4434) sdio_host_uvc: UVC 视频开始: 格式=0, 尺寸=1280x720, 帧率=30
I (4445) sdio_host_uvc: UVC视频参数验证通过, SDIO接收任务已在运行
D (4480) usbd_uvc: frame 0 taking picture...
D (4592) usbd_uvc: Picture taken! Its size was: 101427 bytes
D (4607) usbd_uvc: frame 0 transfer start, size 101427
D (4619) usbd_uvc: frame 1 taking picture...
D (4731) usbd_uvc: Picture taken! Its size was: 101427 bytes
D (4746) usbd_uvc: frame 1 transfer start, size 101427程序会一直正常运行, 直到关闭 PotPlayer 软件.
如果关闭软件会, 日志输出会戛然而止, 没有打印 Resume .
D (9016) usbd_uvc: frame 72 taking picture...
D (9045) usbd_uvc: Picture taken! Its size was: 48972 bytes
D (9048) usbd_uvc: frame 72 transfer start, size 48972
D (9054) usbd_uvc: frame 73 taking picture...
D (9078) usbd_uvc: Picture taken! Its size was: 49420 bytes
D (9081) usbd_uvc: frame 73 transfer start, size 49420
D (9087) usbd_uvc: frame 74 taking picture...
D (9113) usbd_uvc: Picture taken! Its size was: 49846 bytes
D (9114) usbd_uvc: frame 74 transfer start, size 49846What is the actual behavior?
再次打开 PotPlayer 软件的打开摄像头设备, 日志会打印如下内容,
这时才会打印 Resume , 并重新继续传输. 一到两帧, 后就不会再传输.
I (284154) usbd_uvc: Resume
I (284154) uvc_device.c: 摄像头1 停止
I (284155) sdio_host_uvc: UVC视频停止, SDIO接收任务继续运行
I (284166) usbd_uvc: Suspend
I (285756) usbd_uvc: bFrameIndex: 1
I (285756) usbd_uvc: dwFrameInterval: 333333
I (285757) uvc_device.c: 摄像头1 协商格式: MJPEG, 宽度: 1280, 高度: 720, 帧率: 30
I (285768) sdio_host_uvc: UVC 视频开始: 格式=0, 尺寸=1280x720, 帧率=30
I (285779) sdio_host_uvc: UVC视频参数验证通过, SDIO接收任务已在运行
D (285814) usbd_uvc: frame 0 taking picture...
D (285814) usbd_uvc: Picture taken! Its size was: 48622 bytes
D (285816) usbd_uvc: frame 0 transfer start, size 48622
D (285847) usbd_uvc: frame 1 taking picture...
D (285848) usbd_uvc: Picture taken! Its size was: 48527 bytes
D (285849) usbd_uvc: frame 1 transfer start, size 48527Steps to reproduce.
这是个稳定触发的bug, 我进入调试模式, 查看 usb_device_uvc.c 文件内的 video_task() 函数运行情况,
发现它是一直卡在下面这段代码, ulTaskNotifyTake() 一直返回 0 导致任务一直认为上一帧没有发送完毕, 不会进行下一帧.
if (tx_busy) {
uint32_t xfer_done = ulTaskNotifyTake(pdTRUE, 1);
if (xfer_done == 0) {
continue;
}
++frame_num;
tx_busy = 0;
}也就是下面这个函数 tud_video_frame_xfer_complete_cb() 没有执行, 没有通知任务 video_task() 导致的.
void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx)
{
(void)ctl_idx;
(void)stm_idx;
xTaskNotifyGive(s_uvc_device.uvc_task_hdl[ctl_idx]);
}也就是下面没有执行, 大概, 我目前只回溯到这种程度:
bool videod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) {
(void)result; (void)xferred_bytes;
/* find streaming handle */
uint_fast8_t itf;
videod_interface_t *ctl;
videod_streaming_interface_t *stm;
for (itf = 0; itf < CFG_TUD_VIDEO_STREAMING; ++itf) {
stm = &_videod_streaming_itf[itf];
uint_fast16_t const ep_ofs = stm->desc.ep[0];
if (!ep_ofs) continue;
ctl = &_videod_itf[stm->index_vc];
uint8_t const *desc = ctl->beg;
if (ep_addr == _desc_ep_addr(desc + ep_ofs)) break;
}
TU_ASSERT(itf < CFG_TUD_VIDEO_STREAMING);
videod_streaming_epbuf_t *stm_epbuf = &_videod_streaming_epbuf[itf];
if (stm->offset < stm->bufsize) {
/* Claim the endpoint */
TU_VERIFY( usbd_edpt_claim(rhport, ep_addr), 0);
uint_fast16_t pkt_len = _prepare_in_payload(stm, stm_epbuf->buf);
TU_ASSERT( usbd_edpt_xfer(rhport, ep_addr, stm_epbuf->buf, (uint16_t) pkt_len), 0);
} else {
stm->buffer = NULL;
stm->bufsize = 0;
stm->offset = 0;
tud_video_frame_xfer_complete_cb(stm->index_vc, stm->index_vs);
}
return true;
}Debug Logs.
More Information.
我目前的疑惑:
- 为什么关闭
PotPlayer后没有立刻打印Resume, 而是等到下次打开时才打印. - 为什么关闭后再打开, 就不会继续传输数据了.
Metadata
Metadata
Assignees
Labels
No labels