mpp icon indicating copy to clipboard operation
mpp copied to clipboard

usb摄像头急剧变化的区域有撕裂

Open circlefangzm opened this issue 1 year ago • 27 comments

大家好,遇到一个问题,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之类。

补充两点:

  1. usb那边读摄像头数据不到标准的30帧,随着时间的推移,比如10ms,可能只有290帧。这个windows上官方例程也试过,但是没有撕裂,所以应该跟这个没有关系。
  2. hdmi的mode0是1080P 65hz,试过改成60hz但是没生效。不过感觉也不是这个原因(不敢肯定)。

能否帮忙看看真实的原因是什么呢?大概的思路应该在哪里?谢谢

circlefangzm avatar Jul 21 '24 04:07 circlefangzm

另外解码出来第一帧也没有info change帧,正常吗?除了显示有撕裂感,画面倒是很正常,延迟也很低很稳定

circlefangzm avatar Jul 21 '24 05:07 circlefangzm

码流 buffer cache 问题,MppBuffer 送解码之加一个 mpp_buffer_sync_end

HermanChen avatar Jul 22 '24 01:07 HermanChen

码流 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 */

circlefangzm avatar Jul 22 '24 02:07 circlefangzm

说的是要把解码输入的 packet 的 MppBuffer 给 sync_end 一下 sync_end 函数是把 cpu 写的数据确实地写入到 ddr 里去给硬件访问

在这个之前 ret = mpp_task_meta_set_packet(task, KEY_INPUT_PACKET, packet);

HermanChen avatar Jul 22 '24 02:07 HermanChen

说的是要把解码输入的 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的使用可能还存在着一些误解,主要有两个疑问:

  1. 当我拿到摄像头的数据地址和大小的时候,应该怎么给packet?mjpeg给packet的时候一定需要再拷贝一次吗?这个packet一定需要关联一个mppbuffer吗?我现在参考的是这个。因为我试过别的方法都不太好使,所以我的做法就是偷偷从frame的buffergroup里分了一个mppbuffer专门给这个packet用(永久的,或每解完一帧释放还给buffergroup都没区别),再把摄像头数据memcpy到这个buffer里,最后mpp_packet_init_with_bufer初始化packet,然后packet再设一下pos和length就给input task。
  2. framebuffer里目前也是初始化的时候拿到了一个mppbuffer给frame用(mpp_frame_set_buffer),永久的,没有解完一帧还给buffergroup(试过每帧都还回去也没区别)。

不知道这里做有没有什么问题,我用的是libuvc,uvc回调里拿到data后就调用decode(准备packet,inputtask),那解码后的帧是另一个线程。

circlefangzm avatar Jul 22 '24 07:07 circlefangzm

区分两个东西,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。

HermanChen avatar Jul 22 '24 07:07 HermanChen

把摄像头数据memcpy到这个buffer里——之后再做 sync_enc 应该是可以的 可以把异常的图像贴上来看看是什么样的

HermanChen avatar Jul 22 '24 07:07 HermanChen

区分两个东西,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个左右)?

circlefangzm avatar Jul 22 '24 09:07 circlefangzm

把摄像头数据memcpy到这个buffer里——之后再做 sync_enc 应该是可以的 可以把异常的图像贴上来看看是什么样的

https://github.com/user-attachments/assets/a37d268d-5f11-4b59-aa14-9b1710b21687

麻烦大神看看,右边是字典,没有波纹,左边快速变化的地方有。如果变化的区域大,会更明显。但实际上源头一同录的视频完全没问题

circlefangzm avatar Jul 22 '24 12:07 circlefangzm

显示端有做图像的 cpu 拷贝么?还有显示 buffer 和解码 buffer 是怎么同步的?

HermanChen avatar Jul 23 '24 01:07 HermanChen

谢谢您的及时回复。 解码拿到帧后,就是取出fd,转成handle,用这个handle申请drmmodeaddfb2,然后就drmmodesetplane了(2个primary,4个overlay都能支持nv12,但只有一个plane有显示)。addfb2和setplane我看延时也不大(1ms左右)。

circlefangzm avatar Jul 23 '24 02:07 circlefangzm

在显示完成之前,不要释放这个 buffer 回解码器去解码,不然会被新的解码图像覆盖

HermanChen avatar Jul 23 '24 02:07 HermanChen

应该没有释放回。因为最早我只有一个线程,在uvc的回调里拿到帧给input_task,out_task拿到解码NV12给DRM,显示完uvc回调才结束,然后才是下一帧。跟现在做成两个线程没有看到任何明显区别。 而且我现在的做法是packet用的buffer和frame用的buffer,就是初始化时以及固定了,没有在buffergroup里轮转,每帧都是固定的两个buffer,也没有任何的put back或deinit。

circlefangzm avatar Jul 23 '24 02:07 circlefangzm

除非uvc的回调里可能会重入,我晚点试试

circlefangzm avatar Jul 23 '24 02:07 circlefangzm

试了一下,uvc回调是不可重入的。所以应该不会存在 没有显示完就释放掉frame的buffer了把。

您说的显示buffer和解码buffer要同步,我不是特别明白。半内部分配模式,解码后nv12不也是在gpu侧吗?drm显示最终也是拿到这个对应的handle,需要同步做什么呢?

circlefangzm avatar Jul 23 '24 03:07 circlefangzm

在显示完成之前,不要释放这个 buffer 回解码器去解码,不然会被新的解码图像覆盖

大神,帮帮忙吧,谢谢

circlefangzm avatar Jul 24 '24 04:07 circlefangzm

都是固定 buffer 的话,上一帧还在显示中,下一帧的解码数据就把正在显示的数据给覆盖破坏了

HermanChen avatar Jul 24 '24 06:07 HermanChen

都是固定 buffer 的话,上一帧还在显示中,下一帧的解码数据就把正在显示的数据给覆盖破坏了

明白了,我试试,谢谢

circlefangzm avatar Jul 24 '24 12:07 circlefangzm

都是固定 buffer 的话,上一帧还在显示中,下一帧的解码数据就把正在显示的数据给覆盖破坏了

明白了,我试试,谢谢

同样的问题,请问老哥解决了吗?

LeoD218 avatar Sep 19 '24 10:09 LeoD218

半内部分配模式差不多了,但是延迟有点大,比之前撕裂时增加了一倍。


发件人: 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: @.***>

circlefangzm avatar Sep 19 '24 13:09 circlefangzm

我也遇到了 你解决了吗?

Li-Chang-Yi avatar Mar 18 '25 08:03 Li-Chang-Yi

多分配几个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: @.***>

circlefangzm avatar Apr 17 '25 09:04 circlefangzm

你好,你这个usb摄像头程序端到端延迟有多少ms

zjmsky avatar Nov 10 '25 01:11 zjmsky

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: @.***>

circlefangzm avatar Nov 10 '25 12:11 circlefangzm

80+ms usb摄像头程序端到端 怎么测的

Li-Chang-Yi avatar Nov 11 '25 13:11 Li-Chang-Yi

你好,你这个usb摄像头程序端到端延迟有多少ms

端对端是从哪里到哪里?

Li-Chang-Yi avatar Nov 11 '25 13:11 Li-Chang-Yi

你好,你这个usb摄像头程序端到端延迟有多少ms

端对端是从哪里到哪里?

摄像头到屏幕显示,摄像头对着秒表拍,看和屏幕显示出来的时间差,我是这么测的

zjmsky avatar Nov 17 '25 03:11 zjmsky