usb摄像头急剧变化的区域有撕裂
大家好,遇到一个问题,usb摄像头mpp 走task模式解码出来给drm,半内部分配模式。一切都非常好,除了渲染出来的画面,静止的那一半区域很好,急剧变化的这一半区域有水波纹(应该就是撕裂),不知道该怎么解决。1080P,mjpeg,30帧。
试过一个线程下来,也就是usb读出来给mpp,task input 然后output都是阻塞,解码后通过fd/handle给drm(addfb2),都在一个线程里。也试过usb读帧给mpp task input一个线程,另一个线程从task output取NV12数据给drm(drmmodesetplane),都不行。
试过drmmodesetplane之前保证帧与帧之间33.333ms的间隔,也不行。(),相当于相对对齐模式。绝对对齐模式(也就是从第一帧到当前帧都要对齐到33.333ms的整数倍,帧来晚了就自动对齐到下一个33.333ms的倍数。貌似也不行)。所以感觉也不是这个原因,貌似drmmodesetplane底层会自动对齐vblank之类。
补充两点:
- usb那边读摄像头数据不到标准的30帧,随着时间的推移,比如10ms,可能只有290帧。这个windows上官方例程也试过,但是没有撕裂,所以应该跟这个没有关系。
- hdmi的mode0是1080P 65hz,试过改成60hz但是没生效。不过感觉也不是这个原因(不敢肯定)。
能否帮忙看看真实的原因是什么呢?大概的思路应该在哪里?谢谢
另外解码出来第一帧也没有info change帧,正常吗?除了显示有撕裂感,画面倒是很正常,延迟也很低很稳定
码流 buffer cache 问题,MppBuffer 送解码之加一个 mpp_buffer_sync_end
码流 buffer cache 问题,MppBuffer 送解码之加一个 mpp_buffer_sync_end
感谢大神的及时回复,抱歉不是特别明白,搜了一下只看到编码时有用到这两个函数,就是frame加载图片之前是个begin,加载之后用end。但是解码您说加这个是针对送给解码器的packet来说的,还是从解码器拿到的frame来说的。比如下面的流程,大概加到什么地方呢? mpi->poll(ctx, MPP_PORT_INPUT, MPP_POLL_BLOCK); mpi->dequeue(ctx, MPP_PORT_INPUT, &task); /* input queue / ret = mpp_task_meta_set_packet(task, KEY_INPUT_PACKET, packet); ret = mpp_task_meta_set_frame(task, KEY_OUTPUT_FRAME, frame); mpi->enqueue(ctx, MPP_PORT_INPUT, task); / input queue / mpi->poll(ctx, MPP_PORT_OUTPUT, MPP_POLL_BLOCK); / poll and wait here / mpi->dequeue(ctx, MPP_PORT_OUTPUT, &task); / output queue */
说的是要把解码输入的 packet 的 MppBuffer 给 sync_end 一下 sync_end 函数是把 cpu 写的数据确实地写入到 ddr 里去给硬件访问
在这个之前 ret = mpp_task_meta_set_packet(task, KEY_INPUT_PACKET, packet);
说的是要把解码输入的 packet 的 MppBuffer 给 sync_end 一下 sync_end 函数是把 cpu 写的数据确实地写入到 ddr 里去给硬件访问
在这个之前 ret = mpp_task_meta_set_packet(task, KEY_INPUT_PACKET, packet);
试了不行。无论mpp_packet_init_with_buffer前加不加sync_begin都一样。 我感觉对mppbuffer的使用可能还存在着一些误解,主要有两个疑问:
- 当我拿到摄像头的数据地址和大小的时候,应该怎么给packet?mjpeg给packet的时候一定需要再拷贝一次吗?这个packet一定需要关联一个mppbuffer吗?我现在参考的是这个。因为我试过别的方法都不太好使,所以我的做法就是偷偷从frame的buffergroup里分了一个mppbuffer专门给这个packet用(永久的,或每解完一帧释放还给buffergroup都没区别),再把摄像头数据memcpy到这个buffer里,最后mpp_packet_init_with_bufer初始化packet,然后packet再设一下pos和length就给input task。
- framebuffer里目前也是初始化的时候拿到了一个mppbuffer给frame用(mpp_frame_set_buffer),永久的,没有解完一帧还给buffergroup(试过每帧都还回去也没区别)。
不知道这里做有没有什么问题,我用的是libuvc,uvc回调里拿到data后就调用decode(准备packet,inputtask),那解码后的帧是另一个线程。
区分两个东西,cpu malloc 出来的 buffer 和硬件使用的 buffer,cpu malloc 出来的 buffer 是给 cpu 用的,无法直接给硬件使用,因为硬件的 mmu 和 cpu 的不同,使用的是不同的映射方式,所以硬件使用的 buffer 是单独配和建 mmu 表的。一般情况下都需要拷贝。 给硬件用的 buffer 抽象成 MppBuffer,MppPacket 可以认为是通用的 cpu buffer 和硬件 buffer 里的码流的封装。 目前 jpeg 解码的接口输入时需要是带成 MppBuffer 的 MppPacket,所以是需要从 cpu buffer 拷贝到这个硬件 buffer 里的,libuvc 出来的应该是一个 cpu 分的 buffer。
把摄像头数据memcpy到这个buffer里——之后再做 sync_enc 应该是可以的 可以把异常的图像贴上来看看是什么样的
区分两个东西,cpu malloc 出来的 buffer 和硬件使用的 buffer,cpu malloc 出来的 buffer 是给 cpu 用的,无法直接给硬件使用,因为硬件的 mmu 和 cpu 的不同,使用的是不同的映射方式,所以硬件使用的 buffer 是单独配和建 mmu 表的。一般情况下都需要拷贝。 给硬件用的 buffer 抽象成 MppBuffer,MppPacket 可以认为是通用的 cpu buffer 和硬件 buffer 里的码流的封装。 目前 jpeg 解码的接口输入时需要是带成 MppBuffer 的 MppPacket,所以是需要从 cpu buffer 拷贝到这个硬件 buffer 里的,libuvc 出来的应该是一个 cpu 分的 buffer。
听君一席话,胜自己捣鼓一个月。我晚点整理一下把代码片段和视频片段发到这里。
把摄像头数据memcpy到这个buffer里——之后再做 sync_enc 应该是可以的 可以把异常的图像贴上来看看是什么样的
我目前就是这样做的。但是sync_end放在了mpp_task_meta_set_packet(task, KEY_INPUT_PACKET, packet);的前面。
我还有点小疑问,就是关于buffergroup的使用,我虽然用了buffergroup,但是packet和frame分别都是对应初始化时取出来的两个固定的mppbuffer(解码时每帧把摄像头的数据memcpy到这个packet的mppbuffer里,然后用buffer初始化packet以及设置packet的pos和length)。虽然没算用到buffergroup的轮转,但是延迟出乎意料的小(80ms),而且非常稳定。这种就是用两个固定的mppbuffer的思路算不算有问题呢(手册里说264需要20个左右的buffer,其他解码可能需要10个左右)?
把摄像头数据memcpy到这个buffer里——之后再做 sync_enc 应该是可以的 可以把异常的图像贴上来看看是什么样的
https://github.com/user-attachments/assets/a37d268d-5f11-4b59-aa14-9b1710b21687
麻烦大神看看,右边是字典,没有波纹,左边快速变化的地方有。如果变化的区域大,会更明显。但实际上源头一同录的视频完全没问题
显示端有做图像的 cpu 拷贝么?还有显示 buffer 和解码 buffer 是怎么同步的?
谢谢您的及时回复。 解码拿到帧后,就是取出fd,转成handle,用这个handle申请drmmodeaddfb2,然后就drmmodesetplane了(2个primary,4个overlay都能支持nv12,但只有一个plane有显示)。addfb2和setplane我看延时也不大(1ms左右)。
在显示完成之前,不要释放这个 buffer 回解码器去解码,不然会被新的解码图像覆盖
应该没有释放回。因为最早我只有一个线程,在uvc的回调里拿到帧给input_task,out_task拿到解码NV12给DRM,显示完uvc回调才结束,然后才是下一帧。跟现在做成两个线程没有看到任何明显区别。 而且我现在的做法是packet用的buffer和frame用的buffer,就是初始化时以及固定了,没有在buffergroup里轮转,每帧都是固定的两个buffer,也没有任何的put back或deinit。
除非uvc的回调里可能会重入,我晚点试试
试了一下,uvc回调是不可重入的。所以应该不会存在 没有显示完就释放掉frame的buffer了把。
您说的显示buffer和解码buffer要同步,我不是特别明白。半内部分配模式,解码后nv12不也是在gpu侧吗?drm显示最终也是拿到这个对应的handle,需要同步做什么呢?
在显示完成之前,不要释放这个 buffer 回解码器去解码,不然会被新的解码图像覆盖
大神,帮帮忙吧,谢谢
都是固定 buffer 的话,上一帧还在显示中,下一帧的解码数据就把正在显示的数据给覆盖破坏了
都是固定 buffer 的话,上一帧还在显示中,下一帧的解码数据就把正在显示的数据给覆盖破坏了
明白了,我试试,谢谢
都是固定 buffer 的话,上一帧还在显示中,下一帧的解码数据就把正在显示的数据给覆盖破坏了
明白了,我试试,谢谢
同样的问题,请问老哥解决了吗?
半内部分配模式差不多了,但是延迟有点大,比之前撕裂时增加了一倍。
发件人: LeoD218 @.> 发送时间: 2024年9月19日 10:17 收件人: rockchip-linux/mpp @.> 抄送: 好奇的猫 @.>; Author @.> 主题: Re: [rockchip-linux/mpp] usb摄像头急剧变化的区域有撕裂 (Issue #635)
都是固定 buffer 的话,上一帧还在显示中,下一帧的解码数据就把正在显示的数据给覆盖破坏了
明白了,我试试,谢谢
同样的问题,请问老哥解决了吗?
― Reply to this email directly, view it on GitHubhttps://github.com/rockchip-linux/mpp/issues/635#issuecomment-2360587780, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AK63DHLDORDWYKEMPCB4VMLZXKQEPAVCNFSM6AAAAABLGQWOTOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGNRQGU4DONZYGA. You are receiving this because you authored the thread.Message ID: @.***>
我也遇到了 你解决了吗?
多分配几个buffer轮流使用
获取Outlook for Androidhttps://aka.ms/AAb9ysg
From: LCY @.> Sent: Tuesday, March 18, 2025 4:29:31 PM To: rockchip-linux/mpp @.> Cc: 好奇的猫 @.>; Author @.> Subject: Re: [rockchip-linux/mpp] usb摄像头急剧变化的区域有撕裂 (Issue #635)
我也遇到了 你解决了吗?
― Reply to this email directly, view it on GitHubhttps://github.com/rockchip-linux/mpp/issues/635#issuecomment-2732097477, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AK63DHN7Q3SITULO3UMTMOD2U7KOXAVCNFSM6AAAAABZHPQ6DCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDOMZSGA4TONBXG4. You are receiving this because you authored the thread.Message ID: @.***>
[Li-Chang-Yi]Li-Chang-Yi left a comment (rockchip-linux/mpp#635)https://github.com/rockchip-linux/mpp/issues/635#issuecomment-2732097477
我也遇到了 你解决了吗?
― Reply to this email directly, view it on GitHubhttps://github.com/rockchip-linux/mpp/issues/635#issuecomment-2732097477, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AK63DHN7Q3SITULO3UMTMOD2U7KOXAVCNFSM6AAAAABZHPQ6DCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDOMZSGA4TONBXG4. You are receiving this because you authored the thread.Message ID: @.***>
你好,你这个usb摄像头程序端到端延迟有多少ms
80+ms
发件人: zjmsky @.> 发送时间: 2025年11月10日 1:37 收件人: rockchip-linux/mpp @.> 抄送: 好奇的猫 @.>; Author @.> 主题: Re: [rockchip-linux/mpp] usb摄像头急剧变化的区域有撕裂 (Issue #635)
[https://avatars.githubusercontent.com/u/18650697?s=20&v=4]zjmsky left a comment (rockchip-linux/mpp#635)https://github.com/rockchip-linux/mpp/issues/635#issuecomment-3509098417
你好,你这个usb摄像头程序端到端延迟有多少ms
― Reply to this email directly, view it on GitHubhttps://github.com/rockchip-linux/mpp/issues/635#issuecomment-3509098417, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AK63DHMR6QN6ZVPYQ7V3II3337T63AVCNFSM6AAAAABZHPQ6DCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTKMBZGA4TQNBRG4. You are receiving this because you authored the thread.Message ID: @.***>
80+ms … usb摄像头程序端到端 怎么测的
你好,你这个usb摄像头程序端到端延迟有多少ms
端对端是从哪里到哪里?
你好,你这个usb摄像头程序端到端延迟有多少ms
端对端是从哪里到哪里?
摄像头到屏幕显示,摄像头对着秒表拍,看和屏幕显示出来的时间差,我是这么测的