OpenEdv-开源电子网

 找回密码
 立即注册
查看: 1314|回复: 3

在ATK-DLRV1126上使用usb摄像头+rkmedia实现图像采集

[复制链接]

9

主题

890

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
2390
金钱
2390
注册时间
2019-9-25
在线时间
397 小时
发表于 2024-6-14 11:20:40 | 显示全部楼层 |阅读模式
本帖最后由 仰望星空之云 于 2024-6-14 15:38 编辑

1、查看摄像头的video节点
插入USB摄像头以后,多了一个media5节点:
  1. [root@ATK-DLRV1126:/demo/bin]# ls /dev/media*
  2. /dev/media0  /dev/media1  /dev/media2  /dev/media3  /dev/media4  /dev/media5
复制代码
查看media5的拓扑结构:
  1. [root@ATK-DLRV1126:/demo/bin]# media-ctl -p -d /dev/media5
  2. Media controller API version 4.19.111

  3. Media device information
  4. ------------------------
  5. driver          uvcvideo
  6. model           USB Camera: USB Camera
  7. serial
  8. bus info        usb-ffe00000.usb-1.3
  9. hw revision     0x924
  10. driver version  4.19.111

  11. Device topology
  12. - entity 1: USB Camera: USB Camera (1 pad, 1 link)
  13.             type Node subtype V4L flags 1
  14.             device node name /dev/video45
  15.         pad0: Sink
  16.                 <- "Extension 4":1 [ENABLED,IMMUTABLE]

  17. - entity 4: USB Camera: USB Camera (0 pad, 0 link)
  18.             type Node subtype V4L flags 0
  19.             device node name /dev/video46

  20. - entity 8: Extension 4 (2 pads, 2 links)
  21.             type V4L2 subdev subtype Unknown flags 0
  22.         pad0: Sink
  23.                 <- "Processing 3":1 [ENABLED,IMMUTABLE]
  24.         pad1: Source
  25.                 -> "USB Camera: USB Camera":0 [ENABLED,IMMUTABLE]

  26. - entity 11: Processing 3 (2 pads, 2 links)
  27.              type V4L2 subdev subtype Unknown flags 0
  28.         pad0: Sink
  29.                 <- "Camera 1":0 [ENABLED,IMMUTABLE]
  30.         pad1: Source
  31.                 -> "Extension 4":0 [ENABLED,IMMUTABLE]

  32. - entity 14: Camera 1 (1 pad, 1 link)
  33.              type V4L2 subdev subtype Unknown flags 0
  34.         pad0: Source
  35.                 -> "Processing 3":0 [ENABLED,IMMUTABLE]
复制代码
那么,USB摄像头的video节点是video45还是video46呢,可以用如下命令来查看:
  1. [root@ATK-DLRV1126:/demo/bin]# v4l2-ctl -d /dev/video45 --all
  2. Driver Info:
  3.         Driver name      : uvcvideo
  4.         Card type        : USB Camera: USB Camera
  5.         Bus info         : usb-ffe00000.usb-1.3
  6.         Driver version   : 4.19.111
  7.         Capabilities     : 0x84a00001
  8.                 Video Capture
  9.                 Metadata Capture
  10.                 Streaming
  11.                 Extended Pix Format
  12.                 Device Capabilities
  13.         Device Caps      : 0x04200001
  14.                 Video Capture
  15.                 Streaming
  16.                 Extended Pix Format
  17. Media Driver Info:
  18.         Driver name      : uvcvideo
  19.         Model            : USB Camera: USB Camera
  20.         Serial           :
  21.         Bus info         : usb-ffe00000.usb-1.3
  22.         Media version    : 4.19.111
  23.         Hardware revision: 0x00000924 (2340)
  24.         Driver version   : 4.19.111
  25. Interface Info:
  26.         ID               : 0x03000002
  27.         Type             : V4L Video
  28. Entity Info:
  29.         ID               : 0x00000001 (1)
  30.         Name             : USB Camera: USB Camera
  31.         Function         : V4L2 I/O
  32.         Flags         : default
  33.         Pad 0x01000007   : 0: Sink
  34.           Link 0x02000010: from remote pad 0x100000a of entity 'Extension 4': Data, Enabled, Immutable
  35. Priority: 2
  36. Video input : 0 (Camera 1: ok)
  37. Format Video Capture:
  38.         Width/Height      : 640/480
  39.         Pixel Format      : 'MJPG' (Motion-JPEG)
  40.         Field             : None
  41.         Bytes per Line    : 0
  42.         Size Image        : 307200
  43.         Colorspace        : sRGB
  44.         Transfer Function : Default (maps to sRGB)
  45.         YCbCr/HSV Encoding: Default (maps to ITU-R 601)
  46.         Quantization      : Default (maps to Full Range)
  47.         Flags             :
  48. Crop Capability Video Capture:
  49.         Bounds      : Left 0, Top 0, Width 640, Height 480
  50.         Default     : Left 0, Top 0, Width 640, Height 480
  51.         Pixel Aspect: 1/1
  52. Selection: crop_default, Left 0, Top 0, Width 640, Height 480, Flags:
  53. Selection: crop_bounds, Left 0, Top 0, Width 640, Height 480, Flags:
  54. Streaming Parameters Video Capture:
  55.         Capabilities     : timeperframe
  56.         Frames per second: 10.000 (10/1)
  57.         Read buffers     : 0
  58.                      brightness 0x00980900 (int)    : min=0 max=255 step=1 default=128 value=128
  59.                        contrast 0x00980901 (int)    : min=0 max=100 step=1 default=0 value=0
  60.                      saturation 0x00980902 (int)    : min=0 max=200 step=1 default=90 value=90
  61.                             hue 0x00980903 (int)    : min=-180 max=180 step=1 default=0 value=0
  62. white_balance_temperature_auto 0x0098090c (bool)   : default=1 value=1
  63.                           gamma 0x00980910 (int)    : min=40 max=220 step=1 default=70 value=70
  64.            power_line_frequency 0x00980918 (menu)   : min=0 max=2 default=2 value=1
  65.       white_balance_temperature 0x0098091a (int)    : min=2800 max=6500 step=1 default=5000 value=6480 flags=inactive
  66.                       sharpness 0x0098091b (int)    : min=0 max=10 step=1 default=4 value=4
  67.          backlight_compensation 0x0098091c (int)    : min=0 max=5 step=1 default=0 value=0
  68.                   exposure_auto 0x009a0901 (menu)   : min=0 max=3 default=3 value=3
  69.               exposure_absolute 0x009a0902 (int)    : min=10 max=5000 step=1 default=2500 value=2500 flags=inactive
  70.                   zoom_absolute 0x009a090d (int)    : min=0 max=50 step=1 default=0 value=0
复制代码
看到video45有像素格式,那么,USB摄像头应该使用的是video45
2、V4L2采集图像
查看video节点格式
先查看video45节点只支持的所有像素格式和分辨率吧:
  1. [root@ATK-DLRV1126:/demo/bin]# v4l2-ctl -d /dev/video45 --list-formats
  2. ioctl: VIDIOC_ENUM_FMT
  3.         Type: Video Capture

  4.         [0]: 'MJPG' (Motion-JPEG, compressed)
  5.         [1]: 'YUYV' (YUYV 4:2:2)
  6.         
  7. [root@ATK-DLRV1126:/demo/bin]# v4l2-ctl -d /dev/video45 --list-formats-ext
  8. ioctl: VIDIOC_ENUM_FMT
  9.         Type: Video Capture

  10.         [0]: 'MJPG' (Motion-JPEG, compressed)
  11.                 Size: Discrete 640x480
  12.                         Interval: Stepwise 0.033s - 1.000s with step 0.033s (1.000-30.000 fps)
  13.                 Size: Discrete 320x240
  14.                         Interval: Stepwise 0.033s - 1.000s with step 0.033s (1.000-30.000 fps)
  15.                 Size: Discrete 160x120
  16.                         Interval: Stepwise 0.033s - 1.000s with step 0.033s (1.000-30.000 fps)
  17.                 Size: Discrete 176x144
  18.                         Interval: Stepwise 0.033s - 1.000s with step 0.033s (1.000-30.000 fps)
  19.                 Size: Discrete 352x288
  20.                         Interval: Stepwise 0.033s - 1.000s with step 0.033s (1.000-30.000 fps)
  21.         [1]: 'YUYV' (YUYV 4:2:2)
  22.                 Size: Discrete 640x480
  23.                         Interval: Discrete 0.033s (30.000 fps)
  24.                         Interval: Discrete 0.050s (20.000 fps)
  25.                         Interval: Discrete 0.067s (15.000 fps)
  26.                         Interval: Discrete 0.100s (10.000 fps)
  27.                         Interval: Discrete 0.200s (5.000 fps)
  28.                         Interval: Discrete 1.000s (1.000 fps)
  29.                 Size: Discrete 320x240
  30.                         Interval: Discrete 0.033s (30.000 fps)
  31.                         Interval: Discrete 0.050s (20.000 fps)
  32.                         Interval: Discrete 0.067s (15.000 fps)
  33.                         Interval: Discrete 0.100s (10.000 fps)
  34.                         Interval: Discrete 0.102s (9.833 fps)
  35.                         Interval: Discrete 1.000s (1.000 fps)
  36.                 Size: Discrete 160x120
  37.                         Interval: Discrete 0.033s (30.000 fps)
  38.                         Interval: Discrete 0.050s (20.000 fps)
  39.                         Interval: Discrete 0.067s (15.000 fps)
  40.                         Interval: Discrete 0.100s (10.000 fps)
  41.                         Interval: Discrete 0.102s (9.833 fps)
  42.                         Interval: Discrete 1.000s (1.000 fps)
  43.                 Size: Discrete 176x144
  44.                         Interval: Discrete 0.033s (30.000 fps)
  45.                         Interval: Discrete 0.050s (20.000 fps)
  46.                         Interval: Discrete 0.067s (15.000 fps)
  47.                         Interval: Discrete 0.100s (10.000 fps)
  48.                         Interval: Discrete 0.102s (9.833 fps)
  49.                         Interval: Discrete 1.000s (1.000 fps)
  50.                 Size: Discrete 352x288
  51.                         Interval: Discrete 0.033s (30.000 fps)
  52.                         Interval: Discrete 0.050s (20.000 fps)
  53.                         Interval: Discrete 0.067s (15.000 fps)
  54.                         Interval: Discrete 0.100s (10.000 fps)
  55.                         Interval: Discrete 0.102s (9.833 fps)
  56.                         Interval: Discrete 1.000s (1.000 fps)
  57. [root@ATK-DLRV1126:/demo/bin]#
复制代码
可以看到,支持YUYV 4:2:2,640x480大小,那么我们就采集这个格式的视频吧。
采集图像
  1. v4l2-ctl -d /dev/video45 \
  2. --set-fmt-video=width=640,height=480,\
  3. pixelformat=YUYV \
  4. --stream-mmap=3 \
  5. --stream-skip=3 \
  6. --stream-to=/tmp/cif.raw \
  7. --stream-count=1 \
  8. --stream-poll
复制代码
使用adb命令拷贝到ubuntu下查看,ubuntu下执行命令:
  1. adb pull /tmp/cif.raw .
  2. ffplay -f rawvideo -s 640x480 -pix_fmt yuyv422 cif.raw
复制代码
可以看到图片,v4l2能抓到图。


3、使用RKMedia采集图像
rkmedia_vi_vo代码改写
  1. // Copyright 2020 Fuzhou Rockchip Electronics Co., Ltd. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.

  4. #include <assert.h>
  5. #include <fcntl.h>
  6. #include <getopt.h>
  7. #include <signal.h>
  8. #include <stdbool.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <time.h>
  13. #include <unistd.h>

  14. #include "common/sample_common.h"
  15. #include "rkmedia_api.h"

  16. static bool quit = false;
  17. static void sigterm_handler(int sig) {
  18.   fprintf(stderr, "signal %d\n", sig);
  19.   quit = true;
  20. }

  21. static RK_CHAR optstr[] = "?::a::I:h:w:M:";
  22. static const struct option long_options[] = {
  23.     {"aiq", optional_argument, NULL, 'a'},
  24.     {"camid", required_argument, NULL, 'I'},
  25.     {"multictx", required_argument, NULL, 'M'},
  26.     {"help", optional_argument, NULL, '?'},
  27.     {NULL, 0, NULL, 0},
  28. };

  29. static void print_usage(const RK_CHAR *name) {
  30.   printf("usage example:\n");
  31. #ifdef RKAIQ
  32.   printf("\t%s [-a [iqfiles_dir]]"
  33.          "[-I 0] "
  34.          "[-M 0] "
  35.          "\n",
  36.          name);
  37.   printf("\t-a | --aiq: enable aiq with dirpath provided, eg:-a "
  38.          "/oem/etc/iqfiles/, "
  39.          "set dirpath empty to using path by default, without this option aiq "
  40.          "should run in other application\n");
  41.   printf("\t-M | --multictx: switch of multictx in isp, set 0 to disable, set "
  42.          "1 to enable. Default: 0\n");
  43. #else
  44.   printf("\t%s [-I 0]\n", name);
  45. #endif
  46.   printf("\t-I | --camid: camera ctx id, Default 0\n");
  47.   printf("\t-w: DisplayWidth, Default: 720\n");
  48.   printf("\t-h: DisplayHeight, Default: 1280\n");
  49. }

  50. int main(int argc, char *argv[]) {
  51.   int ret = 0;
  52.   
  53. /*int video_width = 1920;
  54.   int video_height = 1080;
  55.   
  56.   int disp_width = 720;
  57.   int disp_height = 1280;*/
  58.   RK_S32 s32CamId = 0;
  59. #ifdef RKAIQ
  60.   RK_BOOL bMultictx = RK_FALSE;
  61. #endif
  62.   int c;
  63.   char *iq_file_dir = NULL;
  64.   while ((c = getopt_long(argc, argv, optstr, long_options, NULL)) != -1) {
  65.     const char *tmp_optarg = optarg;
  66.     switch (c) {
  67.     case 'a':
  68.       if (!optarg && NULL != argv[optind] && '-' != argv[optind][0]) {
  69.         tmp_optarg = argv[optind++];
  70.       }
  71.       if (tmp_optarg) {
  72.         iq_file_dir = (char *)tmp_optarg;
  73.       } else {
  74.         iq_file_dir = "/oem/etc/iqfiles";
  75.       }
  76.       break;
  77.     case 'I':
  78.       s32CamId = atoi(optarg);
  79.       break;
  80.     case 'w':
  81.       //disp_width = atoi(optarg);
  82.       break;
  83.     case 'h':
  84.       //disp_height = atoi(optarg);
  85.       break;
  86. #ifdef RKAIQ
  87.     case 'M':
  88.       if (atoi(optarg)) {
  89.         bMultictx = RK_TRUE;
  90.       }
  91.       break;
  92. #endif
  93.     case '?':
  94.     default:
  95.       print_usage(argv[0]);
  96.       return 0;
  97.     }
  98.   }

  99.   printf("#CameraIdx: %d\n\n", s32CamId);
  100.   if (iq_file_dir) {
  101. #ifdef RKAIQ
  102.     printf("#Rkaiq XML DirPath: %s\n", iq_file_dir);
  103.     printf("#bMultictx: %d\n\n", bMultictx);
  104.     rk_aiq_working_mode_t hdr_mode = RK_AIQ_WORKING_MODE_NORMAL;
  105.     int fps = 30;
  106.     SAMPLE_COMM_ISP_Init(s32CamId, hdr_mode, bMultictx, iq_file_dir);
  107.     SAMPLE_COMM_ISP_Run(s32CamId);
  108.     SAMPLE_COMM_ISP_SetFrameRate(s32CamId, fps);
  109. #endif
  110.   }

  111.   RK_MPI_SYS_Init();
  112.   VI_CHN_ATTR_S vi_chn_attr;
  113.   vi_chn_attr.pcVideoNode = "/dev/video45";
  114.   vi_chn_attr.u32BufCnt = 3;
  115.   vi_chn_attr.u32Width = 640;
  116.   vi_chn_attr.u32Height = 480;
  117.   vi_chn_attr.enPixFmt = IMAGE_TYPE_YUYV422;
  118.   vi_chn_attr.enWorkMode = VI_WORK_MODE_NORMAL;
  119.   ret = RK_MPI_VI_SetChnAttr(s32CamId, 0, &vi_chn_attr);
  120.   ret |= RK_MPI_VI_EnableChn(s32CamId, 0);
  121.   if (ret) {
  122.     printf("Create vi[0] failed! ret=%d\n", ret);
  123.     return -1;
  124.   }

  125.   /* test rgn cover */
  126.   COVER_INFO_S CoverInfo;
  127.   OSD_REGION_INFO_S RngInfo;
  128.   memset(&CoverInfo, 0, sizeof(CoverInfo));
  129.   memset(&RngInfo, 0, sizeof(RngInfo));
  130.   CoverInfo.enPixelFormat = PIXEL_FORMAT_ARGB_8888;
  131.   CoverInfo.u32Color = 0xFFFF0000; // blue
  132.   RngInfo.enRegionId = REGION_ID_0;
  133.   RngInfo.u32PosX = 0;
  134.   RngInfo.u32PosY = 0;
  135.   RngInfo.u32Width = 100;
  136.   RngInfo.u32Height = 100;
  137.   RngInfo.u8Enable = 1;
  138.   RK_MPI_VI_RGN_SetCover(s32CamId, 1, &RngInfo, &CoverInfo);

  139.   // rga0 for primary plane
  140.   RGA_ATTR_S stRgaAttr;
  141.   memset(&stRgaAttr, 0, sizeof(stRgaAttr));
  142.   stRgaAttr.bEnBufPool = RK_TRUE;
  143.   stRgaAttr.u16BufPoolCnt = 3;
  144.   stRgaAttr.u16Rotaion = 90;
  145.   stRgaAttr.stImgIn.u32X = 0;
  146.   stRgaAttr.stImgIn.u32Y = 0;
  147.   stRgaAttr.stImgIn.imgType = IMAGE_TYPE_YUYV422;
  148.   stRgaAttr.stImgIn.u32Width = 640;
  149.   stRgaAttr.stImgIn.u32Height = 480;
  150.   stRgaAttr.stImgIn.u32HorStride = 640;
  151.   stRgaAttr.stImgIn.u32VirStride = 480;
  152.   stRgaAttr.stImgOut.u32X = 0;
  153.   stRgaAttr.stImgOut.u32Y = 0;
  154.   stRgaAttr.stImgOut.imgType = IMAGE_TYPE_RGB888;
  155.   stRgaAttr.stImgOut.u32Width = 640;
  156.   stRgaAttr.stImgOut.u32Height = 480;
  157.   stRgaAttr.stImgOut.u32HorStride = 640;
  158.   stRgaAttr.stImgOut.u32VirStride = 480;
  159.   ret = RK_MPI_RGA_CreateChn(0, &stRgaAttr);
  160.   if (ret) {
  161.     printf("Create rga[0] falied! ret=%d\n", ret);
  162.     return -1;
  163.   }

  164.   VO_CHN_ATTR_S stVoAttr = {0};
  165.   // VO[0] for primary plane
  166.   stVoAttr.pcDevNode = "/dev/dri/card0";
  167.   stVoAttr.emPlaneType = VO_PLANE_PRIMARY;
  168.   stVoAttr.enImgType = IMAGE_TYPE_RGB888;
  169.   stVoAttr.u16Zpos = 0;
  170.   stVoAttr.stImgRect.s32X = 0;
  171.   stVoAttr.stImgRect.s32Y = 0;
  172.   stVoAttr.stImgRect.u32Width = 640;
  173.   stVoAttr.stImgRect.u32Height = 480;
  174.   stVoAttr.stDispRect.s32X = 0;
  175.   stVoAttr.stDispRect.s32Y = 0;
  176.   stVoAttr.stDispRect.u32Width = 640;
  177.   stVoAttr.stDispRect.u32Height = 480;
  178.   ret = RK_MPI_VO_CreateChn(0, &stVoAttr);
  179.   if (ret) {
  180.     printf("Create vo[0] failed! ret=%d\n", ret);
  181.     return -1;
  182.   }

  183.   MPP_CHN_S stSrcChn = {0};
  184.   MPP_CHN_S stDestChn = {0};

  185.   printf("#Bind VI[0] to RGA[0]....\n");
  186.   stSrcChn.enModId = RK_ID_VI;
  187.   stSrcChn.s32ChnId = 0;
  188.   stDestChn.enModId = RK_ID_RGA;
  189.   stDestChn.s32ChnId = 0;
  190.   ret = RK_MPI_SYS_Bind(&stSrcChn, &stDestChn);
  191.   if (ret) {
  192.     printf("Bind vi[0] to rga[0] failed! ret=%d\n", ret);
  193.     return -1;
  194.   }

  195.   printf("# Bind RGA[0] to VO[0]....\n");
  196.   stSrcChn.enModId = RK_ID_RGA;
  197.   stSrcChn.s32ChnId = 0;
  198.   stDestChn.enModId = RK_ID_VO;
  199.   stDestChn.s32ChnId = 0;
  200.   ret = RK_MPI_SYS_Bind(&stSrcChn, &stDestChn);
  201.   if (ret) {
  202.     printf("Bind rga[0] to vo[0] failed! ret=%d\n", ret);
  203.     return -1;
  204.   }

  205.   printf("%s initial finish\n", __func__);
  206.   signal(SIGINT, sigterm_handler);
  207.   while (!quit) {
  208.     usleep(500000);
  209.   }

  210.   printf("%s exit!\n", __func__);
  211.   stSrcChn.enModId = RK_ID_VI;
  212.   stSrcChn.s32ChnId = 0;
  213.   stDestChn.enModId = RK_ID_RGA;
  214.   stDestChn.s32ChnId = 0;
  215.   ret = RK_MPI_SYS_UnBind(&stSrcChn, &stDestChn);
  216.   if (ret) {
  217.     printf("UnBind vi[0] to rga[0] failed! ret=%d\n", ret);
  218.     return -1;
  219.   }

  220.   stSrcChn.enModId = RK_ID_RGA;
  221.   stSrcChn.s32ChnId = 0;
  222.   stDestChn.enModId = RK_ID_VO;
  223.   stDestChn.s32ChnId = 0;
  224.   ret = RK_MPI_SYS_UnBind(&stSrcChn, &stDestChn);
  225.   if (ret) {
  226.     printf("UnBind rga[0] to vo[0] failed! ret=%d\n", ret);
  227.     return -1;
  228.   }

  229.   RK_MPI_VO_DestroyChn(0);
  230.   RK_MPI_RGA_DestroyChn(0);
  231.   RK_MPI_VI_DisableChn(s32CamId, 0);

  232.   if (iq_file_dir) {
  233. #ifdef RKAIQ
  234.     SAMPLE_COMM_ISP_Stop(s32CamId);
  235. #endif
  236.   }
  237.   return 0;
  238. }
复制代码
测试方法
  1. ./rkmedia_vi_vo_test -a /etc/iqfiles/
复制代码
最终,屏幕上可以显示USB摄像头采集的图像。

关于rkmedia的使用,可以去看SDK中的rkmedia的例子,API说明可以看RK提供的《Rockchip_Developer_Guide_Linux_RKMedia_CN.pdf》,视频教程可以看《【正点原子】AI人工智能深度学习(RV1126/RK3568/RK3588)-第2期 提高篇》


























下载 (2).png
下载 (1).png
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
5
金钱
5
注册时间
2024-6-27
在线时间
0 小时
发表于 2024-6-27 19:24:12 | 显示全部楼层
大佬问一下如何读取网络摄像头+rkmedia实现模型检测
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
4
金钱
4
注册时间
2024-6-18
在线时间
0 小时
发表于 2024-7-9 15:50:29 | 显示全部楼层
感谢分享,参考实现可以预览USB摄像头画面。
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
8
金钱
8
注册时间
2023-6-29
在线时间
1 小时
发表于 2024-9-25 08:52:48 | 显示全部楼层
感谢分享
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 06:19

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表