文章目录

  • 前言
  • 一、开发环境
  • 二、概述
  • 三、硬件介绍
    • 1、ES7210
    • 2、ES8156
    • 3、数字麦克风阵列
    • 4、音频示意图
  • 四、下载SDK
  • 五、编译、烧写
    • 1、u-boot
    • 2、kernel
    • 3、Android SDK
    • 4、烧写分区
    • 5、烧写固件
  • 六、声卡驱动
    • 1、添加codec代码
    • 2、修改Kconfig
    • 3、修改Makefile
    • 4、修改rockchip_defconfig
    • 5、修改DTS
  • 七、声卡调试
    • 1、查看声卡注册信息
    • 2、使用tinycap/tinyplay录音和放音
    • 3、使用示波器观测
  • 八、修改HAL层
    • 1、修改默认capture/playback设备
    • 2、使用设备自带录音机、播放器测试效果
  • 九、问题分析
    • 1、声卡i2c读写失败
    • 2、开发板无法启动
    • 3、 声卡SDOUT无输出
  • 十、 参考资料

前言

本文主要介绍在RK3399开发板中增加自己的声卡codec,并替换系统默认的capture/playback设备。


一、开发环境

SDK RK3399_ANDROID9.0_SDK_V1.0_20190104
开发板 RK_EXCAVATOR_MAIN_V13
CAPTURE CODEC ES7210
PLAYBACK CODEC ES8156

二、概述

本文将讲述如何在RK3399平台上增加一款自己的声卡设备,包含codec驱动、设备树、编译脚本以及少量HAL层的代码修改。
将ES7210注册为capture设备。
将ES8156注册为playback设备。
将会指导用户使用tinycap/tinyplay工具对声卡设备进行初步调试。

三、硬件介绍

1、ES7210

  • ES7210是一款支持4路A-MIC的ADC芯片
  • 支持24-bit, 8 to 100kHz采样率
  • 支持I2S/PCM,支持TDM
  • 框图如下:

    MIC1/MIC2的模拟输入经由ADC算法处理,从SDOUT1输出;
    MIC3/MIC4的模拟输入经由ADC算法处理,从SDOUT2输出;
    MCLK为主时钟,由SOC提供;
    LRCK为左右声道切换时钟,由SOC提供;
    SCLK为位时钟,由SOC提供;
    AD0/AD1决定了I2C设备地址。7位Chip Address=1 0 0 0 0 AD1 AD0;(若AD1/AD0均接地,则Chip Address=0x40)

2、ES8156

  • ES8156是一款支持立体声播放的DAC芯片
  • 支持24-bit, 8 to 96 kHz采样率
  • 支持I2S/PCM
  • 框图如下
    SOC的音频数据从SDIN输入芯片,经DAC处理后,从LOUT/ROUT输出到模拟功放或者SPEAKER;
    MCLK为主时钟,由SOC提供;
    LRCK为左右声道切换时钟,由SOC提供;
    SCLK为位时钟,由SOC提供;
    CE决定了I2C设备地址。7位Chip Address=0 0 0 1 0 0 CE;(若CE接地,则Chip Address=0x08)

3、数字麦克风阵列

  • 数字麦克风采用ICS-43434,阵列包含4路D-MIC
  • 支持24-bit, I2S接口
  • 该D-MIC阵列直接通过I2S连接SOC的I2S0_SDI0和I2S0_SDI1
  • 无I2C控制接口

4、音频示意图

  • I2S0共4路输入:I2S0_SDI0~I2S0_SDI3,每一路承载两通道音频数据,共支持8路同时录音
  • I2S0一路输出:I2S0_SDO0,连接ES8156的SDIN,然后两路输出到模拟功放或speaker进行播放

四、下载SDK

 repo init -u ssh://xxx/rockchip/rk3399_9.0/manifest -m rk3399_9.0.xml -b dev --no-clone-bundlerepo syncrepo start dev --all

五、编译、烧写

1、u-boot

 cd u-bootmake cleanmake mrproper./make.sh rk3399        // 适用于 RK3399 芯片

输出位置:u-boot/rk3399_loader_v1.22.119.bin

2、kernel

 cd kernelmake ARCH=arm64 rockchip_defconfigmake ARCH=arm64 rk3399-sapphire-excavator-edp-avb.img

输出位置:kernel/, 有kernel.img、boot.img(这个是可以直接在AndroidTool中烧写的镜像文件)

3、Android SDK

 source build/envsetup.shlunch        // 选择对应的版本,输入序号make -j32

输出位置:out/target/product/rk3399/,有system.img、vendor.img

4、烧写分区

以烧写boot.img为例:

 1、PC安装驱动DriverAssitant_v4.5;2、使用TYPE-C数据线连接开发板与PC;3、开发板开机后,打开AndroidTool.exe能识别到ADB设备;4、点击“切换”,切换至LOADER模式,切换成功会识别到LOADER设备;5、点击“设备分区表”重新读取设备分区表;6、将勾选框的√全部取消,只勾选Boot分区;7、点击Boot分区栏最右侧空白格,选中要烧写的boot.img;8、点击“执行”,即可开始烧写。完成后会自动重启;

5、烧写固件

 1、参考4.2节先切换到LOADER模式;2、点AndroidTool工具上方的“升级固件”;3、点击“固件”,选择要升级的固件包update.img;4、点击“升级”即可;

六、声卡驱动

1、添加codec代码

在kernel/sound/soc/codecs/增加es7210.c、es7210.h、es8156.c、es8156.h,此为codec驱动,一般由codec厂家提供。

2、修改Kconfig

kernel/sound/soc/codecs/Kconfig

     --- a/sound/soc/codecs/Kconfig+++ b/sound/soc/codecs/Kconfig@@ -491,6 +491,14 @@ config SND_SOC_ES8316config SND_SOC_ES8323tristate "Everest Semi ES8323 CODEC"depends on I2C+       +config SND_SOC_ES7210+       tristate "Everest Semi ES7210 CODEC"+       depends on I2C+       +config SND_SOC_ES8156+       tristate "Everest Semi ES8156 CODEC"+       depends on I2Cconfig SND_SOC_HDMI_CODECtristate

3、修改Makefile

kernel/sound/soc/codecs/Makefile:

     --- a/sound/soc/codecs/Makefile+++ b/sound/soc/codecs/Makefile@@ -62,6 +62,8 @@ snd-soc-dmic-objs := dmic.osnd-soc-es8316-objs := es8316.osnd-soc-es8323-objs := es8323.osnd-soc-es8328-objs := es8328.o+snd-soc-es7210-objs := es7210.o+snd-soc-es8156-objs := es8156.osnd-soc-es8328-i2c-objs := es8328-i2c.osnd-soc-es8328-spi-objs := es8328-spi.osnd-soc-es8396-objs := es8396.o@@ -275,6 +277,8 @@ obj-$(CONFIG_SND_SOC_DMIC)  += snd-soc-dmic.oobj-$(CONFIG_SND_SOC_ES8316)   += snd-soc-es8316.oobj-$(CONFIG_SND_SOC_ES8323)   += snd-soc-es8323.oobj-$(CONFIG_SND_SOC_ES8328)   += snd-soc-es8328.o+obj-$(CONFIG_SND_SOC_ES7210)   += snd-soc-es7210.o+obj-$(CONFIG_SND_SOC_ES8156)   += snd-soc-es8156.oobj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.oobj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.oobj-$(CONFIG_SND_SOC_ES8396)   += snd-soc-es8396.o

4、修改rockchip_defconfig

kernel/arch/arm64/configs/rockchip_defconfig:

     --- a/arch/arm64/configs/rockchip_defconfig+++ b/arch/arm64/configs/rockchip_defconfig@@ -561,6 +561,8 @@ CONFIG_SND_SOC_DUMMY_CODEC=yCONFIG_SND_SOC_BT_SCO=yCONFIG_SND_SOC_ES8316=yCONFIG_SND_SOC_ES8396=y+CONFIG_SND_SOC_ES7210=y+CONFIG_SND_SOC_ES8156=yCONFIG_SND_SOC_FM1288=yCONFIG_SND_SOC_RK1000=yCONFIG_SND_SOC_RK3328=y

5、修改DTS

kernel/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-edp.dtsi:

     --- a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-edp.dtsi+++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-edp.dtsi@@ -106,8 +106,48 @@compatible = "rockchip,rockchip-rt5651-tc358749x-sound";rockchip,cpu = <&i2s0>;rockchip,codec = <&rt5651 &rt5651 &tc358749x>;+               status = "disabled";+       };+       +       es7210-es8156-sound {status = "okay";+               compatible = "simple-audio-card";+               simple-audio-card,format = "i2s";+               simple-audio-card,name = "everest,es7210-es8156-codec";+               simple-audio-card,mclk-fs = <256>;+               simple-audio-card,widgets =+                       "Microphone", "Microphone Jack",+                       "Headphone", "Headphone Jack";+               simple-audio-card,routing =+                       "MIC1", "Microphone Jack",+                       "MIC2", "Microphone Jack",+                       "Microphone Jack", "micbias1",+                       "Headphone Jack", "HPOL",+                       "Headphone Jack", "HPOR";++               simple-audio-card,dai-link@0 {+                       format = "i2s";+                       cpu {+                               sound-dai = <&i2s0>;+                       };++                       codec {+                               sound-dai = <&es7210>;+                       };+               };+               +               simple-audio-card,dai-link@1 {+                       format = "i2s";+                       cpu {+                               sound-dai = <&i2s0>;+                       };++                       codec {+                               sound-dai = <&es8156>;+                       };+               };};+};&backlight {@@ -170,6 +210,7 @@gsl3673: gsl3673@40 {compatible = "GSL,GSL3673";reg = <0x40>;+               status = "disabled";screen_max_x = <1536>;screen_max_y = <2048>;irq_gpio_number = <&gpio1 20 IRQ_TYPE_LEVEL_LOW>;@@ -190,6 +231,26 @@pinctrl-0 = <&hdmiin_gpios>;status = "okay";};+       +       es7210: es7210@40 {+               #sound-dai-cells = <0>;+               compatible = "MicArray_0";+               reg = <0x40>;+               clocks = <&cru SCLK_I2S_8CH_OUT>;+               clock-names = "mclk";+               pinctrl-names = "default";+               pinctrl-0 = <&i2s_8ch_mclk>;+       };+       +       es8156: es8156@08 {+               #sound-dai-cells = <0>;+               compatible = "everest,es8156";+               reg = <0x08>;+               clocks = <&cru SCLK_I2S_8CH_OUT>;+               clock-names = "mclk";+               pinctrl-names = "default";+               pinctrl-0 = <&i2s_8ch_mclk>;+       };vm149c: vm149c@0c {compatible = "silicon touch,vm149c";
说明:1、将原来的声卡"rockchip-rt5651-tc358749x-sound"置为"disabled";2、增加了我们的声卡"es7210-es8156-sound",使用"simple-audio-card"驱动框架。注意是一个声卡包含两个dai-link,分别对应ES7210 codec和ES8156 codec;3、注意mclk-fs的值256代表mclk是256倍的fs。fs一般等于LRCK,即采样率。3、将"gsl3673"设备置为"disabled",disable掉之后,开发板触控屏将无法使用。但是这一步是必要的,因为I2C addr为0x40,与我们添加的ES7210冲突;4、在i2c1节点中增加es7210和es8156设备节点,注意reg填写正确的i2c address,否则会导致注册失败;5、注意es7210和es8156节点的compatible属性一定要与es7210.c、es8156.c中of_device_id的compatible属性保持一致;
然后重新编译kernel,升级boot.img分区。启动后使用dmesg查看系统打印,解决相关错误,确保声卡注册成功。

七、声卡调试

1、查看声卡注册信息

看到有我们的声卡出现,说明注册成功,声卡号为1。

     rk3399:/ # cat /proc/asound/cards0 [ROCKCHIPSPDIF  ]: ROCKCHIP_SPDIF - ROCKCHIP,SPDIFROCKCHIP,SPDIF1 [everestes7210es]: everest_es7210- - everest,es7210-es8156-codeceverest,es7210-es8156-codec2 [rkhdmidpsound  ]: rk-hdmi-dp-soun - rk-hdmi-dp-soundrk-hdmi-dp-sound

pcmC1D0c 为我们的capture设备,即es7210;
pcmC1D1p 为我们的playback设备,即es8156;

     rk3399:/ # ls -l /dev/snd/total 0crw-rw---- 1 system audio 116,   2 2013-01-18 08:50 controlC0crw-rw---- 1 system audio 116,   4 2013-01-18 08:50 controlC1crw-rw---- 1 system audio 116,   7 2013-01-18 08:50 controlC2crw-rw---- 1 system audio 116,   3 2013-01-18 08:50 pcmC0D0pcrw-rw---- 1 system audio 116,   5 2013-01-18 08:50 pcmC1D0ccrw-rw---- 1 system audio 116,   6 2013-01-18 08:50 pcmC1D1pcrw-rw---- 1 system audio 116,   8 2013-01-18 08:50 pcmC2D0pcrw-rw---- 1 system audio 116,  33 2013-01-18 08:50 timer

2、使用tinycap/tinyplay录音和放音

1)使用tinycap录音,可以修改声道数、采样率等参数。录音过程中也可分别敲击各个MIC,方便分析。

 tinycap /data/test.wav -D 1 -d 0 -c 8 -r 16000

2)将录音文件通过adb pull拉取到本地,使用Audacity打开进行播放、分析。注意如果要使用“导入原始数据”方式打开,要跳过头部44字节的wav头。

3)用tinyplay播放录制的音频,注意tinyplay只支持2channel、16kHz格式。

 tinypaly /data/test.wav -D 1 -d 1 -c 2 -r 16000

3、使用示波器观测

1)声卡打开状态,无数据传输时的SCL、LRCK、SDA。SDA上无数据,但时钟信号要有。

2)声卡打开状态,有数据传输时的SCL、LRCK、SDA。时钟信号有,SDA上也能看到数据,对着MIC说话,可观察到SDA的动态变化。

八、修改HAL层

要想使用系统自带的录音APP或者音视频播放软件进行录音和放音,还需要修改Android HAL层。

1、修改默认capture/playback设备

1)增加新的 SPEAKER_NAME 和 MIC_NAME。与7.1节查看到的声卡名称保持一致。

     diff --git a/tinyalsa_hal/audio_hw.c b/tinyalsa_hal/audio_hw.cindex f666f93..60d0ca1 100755--- a/tinyalsa_hal/audio_hw.c+++ b/tinyalsa_hal/audio_hw.c@@ -317,6 +317,7 @@ static char* SPEAKER_NAME [] ="rockchipes8316c","rockchiprk809co","rockchiprt5640c",+   "everestes7210es",};static bool is_speaker_out_sound_card(char* buf)@@ -397,6 +398,7 @@ static char* MIC_NAME [] ="rockchipes8316c","rockchiprk809co","rockchiprt5640c",+    "everestes7210es",};

2)修改默认声卡号。与7.1节查看到的声卡序号保持一致。

     diff --git a/tinyalsa_hal/alsa_route.c b/tinyalsa_hal/alsa_route.cindex 5084c4b..674423e 100755--- a/tinyalsa_hal/alsa_route.c+++ b/tinyalsa_hal/alsa_route.c@@ -12,7 +12,7 @@#define LOG_TAG "alsa_route"-//#define LOG_NDEBUG 0+#define LOG_NDEBUG 0#include <cutils/log.h>#include <cutils/config_utils.h>@@ -65,7 +65,7 @@ int route_init(void)ALOGV("route_init()");-    fp = fopen("/proc/asound/card0/id", "rt");+    fp = fopen("/proc/asound/card1/id", "rt");if (!fp) {ALOGE("Open sound card0 id error!");} else {@@ -491,6 +491,8 @@ void route_pcm_open(uint32_t route)route_init();}

3)修改默认playback设备的设备号。与7.2节查看到的playback设备号保持一致。

     diff --git a/tinyalsa_hal/audio_hw.c b/tinyalsa_hal/audio_hw.cindex f666f93..60d0ca1 100755--- a/tinyalsa_hal/audio_hw.c+++ b/tinyalsa_hal/audio_hw.cin->pcm = pcm_open(card, PCM_DEVICE, PCM_IN, in->config);} else {card = adev->in_card[SND_IN_SOUND_CARD_BT];@@ -2792,7 +2804,7 @@ static int adev_open_output_stream(struct audio_hw_device *dev,type = OUTPUT_DEEP_BUF;} else {out->config = pcm_config;-        out->pcm_device = PCM_DEVICE;+        out->pcm_device = PCM_DEVICE_SCO;//PCM_DEVICE;type = OUTPUT_LOW_LATENCY;}

4)新增头文件tinyalsa_hal/codec_config/es7210_es8156_config.h,实现es7210_es8156_config_table结构体,可参考codec_config目录下的其它声卡的config.h。

5)增加声卡的config table。

     diff --git a/tinyalsa_hal/codec_config/config_list.h b/tinyalsa_hal/codec_config/config_list.hindex b02e790..d94f0e6 100755--- a/tinyalsa_hal/codec_config/config_list.h+++ b/tinyalsa_hal/codec_config/config_list.h@@ -25,6 +25,7 @@#include "es8316_config.h"#include "cx2072_config.h"#include "hdmi_analog_config.h"+#include "es7210_es8156_config.h"struct alsa_sound_card_config{@@ -93,6 +94,10 @@ struct alsa_sound_card_config sound_card_config_list[] = {{.sound_card_name = "rkhdmianalogsnd",.route_table = &hdmi_analog_config_table,+    },+    {+        .sound_card_name = "everestes7210es",+        .route_table = &es7210_es8156_config_table,}};

6)编译HAL静态库,替换到系统中。

 mmm hardware/rockchip/audio/tinyalsa_hal

hal库生成位置:./out/target/product/rk3399/vendor/lib/hw/audio.primary.rk30board.so
替换到设备中:

 adb push audio.primary.rk30board.so /vendor/lib/hw/

——至此HAL层的全部修改已完成,理论上可直接用系统自带录音机/播放器测试声卡了。如果要修改其它声卡参数,可修改如下结构体:
hardware/rockchip/audio/tinyalsa_hal/audio_hw.h

     #elsestruct pcm_config pcm_config = {.channels = 2,.rate = 44100,.period_size = 512,.period_count = 6,.format = PCM_FORMAT_S16_LE,.flag = HW_PARAMS_FLAG_LPCM,};struct pcm_config pcm_config_in = {.channels = 2,.rate = 44100,#ifdef SPEEX_DENOISE_ENABLE.period_size = 1024,#else.period_size = 256,#endif.period_count = 4,.format = PCM_FORMAT_S16_LE,.flag = HW_PARAMS_FLAG_LPCM,};#endif

2、使用设备自带录音机、播放器测试效果

1)打开“录音机”进行录音,正常情况下能录到我们通过ES7210、数字麦阵列输入的声音。点击播放,能从ES8156连接的SPEAKER设备输出。

2)用音乐播放器或视频播放器播放音视频文件,能够从SPEAKER设备输出。

九、问题分析

1、声卡i2c读写失败

 1、测量MCLK时钟,一般12.88MHz左右正常;2、排查同一总线上设备address是否有冲突;3、检查设备address地址硬件设置是否正确;4、测量设备供电是否正常;

2、开发板无法启动

 无法启动,包括开机卡在kernel开机画面、反复重启、AndroidTool无法发现设备等无法正常进入系统或烧写镜像的情况,俗称——变砖。1、设备断电;2、依次摁下“RST”键和“RECOVERY”键并保持住;3、摁下开机开关,几秒钟后,AndroidTool就能发现LOADER设备了;4、重新烧写分区或升级包即可;

3、 声卡SDOUT无输出

 1、测量各个MIC是否供电正常;2、测量ES7210各路模拟输入是否有信号;3、查看ES7210是否初始化成功、寄存器配置无误,可咨询FAE;4、确认ES7210的配置是否正确,主要是I2S的模式,比如应该是normal模式还是TDM模式,可咨询FAE;

十、 参考资料

《ES7210 DS_1620649768764.pdf》
《ES8156 DS——DAC芯片规格书.pdf》
《Rockchip_Developer_Guide_Audio_CN.pdf》
《Rockchip_Developer_Guide_Linux4.4_Audio_CN.pdf》
《Rockchip_User_Guide_Recovery_CN&EN.pdf》
《Rockchip_RK3399_Developer_Guide_Android9.0_Software_CN&EN.pdf》
《Rockchip_Developer_Guide_Linux4.4_Audio_CN.pdf》
《RK音频简介以及常见问题debug方法v1.1.pdf》
《Rockchip集成ES7210多通道录音方案指南v1.0.pdf》

【RK3399】Android平台增加一款声卡设备(ES7210+ES8156),进行录音/播放测试。相关推荐

  1. android平台的一款mud工具,全平台 MUD 客户端 TinTin++ 之安卓篇

    本帖最后由 xgg 于 2021-4-7 12:48 PM 编辑 全平台 MUD 客户端 TinTin++ 之安卓篇 ============================= TinTin++(以下 ...

  2. Android用usb命令控制音量,如何在Android平台上使用USB Audio设备

    上网搜了有关USB Audio Hotplug的东西,比较适用的资源如下: 题目看起来很吻合我们的问题,事实上并没有多少参考价值.其中脚本/etc/hotplug/usb/extigy或许可以捕捉到U ...

  3. GB/T28181-2016传输要求和Android平台设备接入技术实现

    相关协议规范 GB/T28181-2016公共安全视频监控联网系统 信息传输.交换.控制技术要求相关的传输要求如下: 5.1 网络传输协议要求 联网系统网络层应支持IP协议,传输层应支持 TCP和 U ...

  4. 光学模拟 Android,基于Android平台的光学字符识别应用的设计与实现

    摘要: 随着数字化时代的蓬勃发展,信息量以指数级的速度增长,然而手工录入并存储信息的速度远不及信息的产生速度.光学字符识别(OCR)技术能够自动化地检测信息并识别出来,有效地解决了信息录入速度和正确率 ...

  5. Android平台实现系统内录(捕获播放的音频)并推送RTMP服务技术方案探究

    几年来,我们在做无纸化同屏或在线教育相关场景的时候,总是被一件事情困扰:如何实现Android平台的系统内录,并推送到其他播放端,常用的场景比如做无纸化会议或教育的时候,主讲人或老师需要放一个视频,该 ...

  6. android 平台上,AndroidAPP如何在Android平台上架?

    AndroidAPP如何在Android平台上架?以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! AndroidAPP如 ...

  7. android项目服装管理系统,基于Android平台的服装零售管理系统的设计与实现

    摘要: 服装零售管理系统是基于Android平台的一款应用软件.目前,Android操作系统是当今智能手机最主要的[1],占比十分大的一类操作系统.在现有的Android应用中,可以应用于服装零售行业 ...

  8. Ubuntu 下ALSA声卡设备的配置与使用

    最近做项目有一个需求,就是对ubuntu下的ALSA声卡进行使用,在摸索了一大圈之后,将所得记录下来,以备后期查看. 首先先插上声卡设备 以下所用的声卡设备皆为3.5mm的耳机测试. 需要使用usb转 ...

  9. 移植ffplay媒体播放器和sdl2到Android平台

    前言 前述博文<基于FFmpeg和Android的音视频同步播放实现>中,我们按照自己的方法实现了一个简单的媒体播放器,并做了音视频同步.但是这个程序在播放更多码流时,遇到了一些问题,包括 ...

最新文章

  1. EXCHANGE证书
  2. web3.js(三)查询智能合约币数量(erc20)
  3. HDU - 4738 Caocao's Bridges(边双缩点)
  4. CentOS下面ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
  5. 2022,前端工具链十年盘点
  6. Sharepoint 2010新体验之一-----基于Claims的全新验证机制
  7. observable_Java Observable deleteObserver()方法与示例
  8. Canvas学习:封装Canvas绘制基本图形API
  9. 11g DG中的参数
  10. SAP License:SAP学习心得
  11. python数据分析之(4)读写数据文件CSV,EXCEL等
  12. react native环境搭建的一些坑
  13. OpenSSL密码库算法笔记——第6.5章 密钥协商
  14. 图片加水印怎么加?教你一个好操作的办法
  15. 启动模式,BOOT0和BOOT1详解
  16. Linux下使用Shell脚本实现反向ssh自动交互
  17. 7-242 母牛问题
  18. 工业4.0万物联网兴起 智能手机或将消亡
  19. 2011世界财富500强
  20. [OpenPose翻译] Realtime Multi-Person 2D Pose Estimation using Part Affinity Fields ∗原文翻译(注释版)

热门文章

  1. 服务器端渲染和客户端渲染有什么区别?
  2. 日本旅游必须要知道的5条规定,小心受罚
  3. Lotus Notes常见问题答疑(转)
  4. 视频聊天开发参考资料
  5. mysql.cj.jdbc_com.mysql.jdbc.Driver和com.mysql.cj.jdbc.Driver的区别
  6. 培训python机构排名
  7. Python degrees() 函数
  8. Linux下调试1588单步时间戳报文
  9. CSS高度塌陷问题(float塌陷margin塌陷)
  10. Windows动态库注册和取消注册