当前位置: 首页 > news >正文

Android Camera SDK NDK NDK_vendor介绍

Android Camera JNI NDK NDK_vendor介绍

  • 前言
  • 主要有哪几种interface?
  • Android SDK
    • Camera API 1
    • Camera API 2
    • 小结
  • Android NDK
    • NDK Interface
    • NDK Vendor Interface
    • 小结
  • Camera VTS Testcase
  • 总结
  • Reference

前言

本篇博客是想介绍Android camera从application layer到camera service layer整个框架中,能够使用的所有接口方式。

主要有哪几种interface?

分为两大类:Android SDK,Android NDK。
Android NDK分为NDK和NDK vendor。对于camera module Android SDK可以分为camera API 1和camera API 2。最后有一种特殊的方式是用过HIDL interface来实现camera APP,给出总体架构图:
Android camera overall architecture diagram

Android SDK

Camera API 1

  • API 1作为最原始的一套camera API现在已经被Google启用,已经不在有功能上的升级,可以提供基础capture pictures and videos in your applications。API 1流程非常的特殊,他是通过JNI layer调用到libcameraservice,如果想了解JNI移步:链接: Camera Java Native Interface(JNI)介绍。
  • 接下来通过camera open代码分析JNI调用过程
frameworks/base/core/java/android/hardware/Camera.java
public static Camera open() {int numberOfCameras = getNumberOfCameras();CameraInfo cameraInfo = new CameraInfo();for (int i = 0; i < numberOfCameras; i++) {getCameraInfo(i, cameraInfo);if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {return new Camera(i);}}return null;
}

如果在camera APP中调用API 1的open function去打开默认后置camera,一开始会新建一个camera device object,直接调用camera构造函数。

frameworks/base/core/java/android/hardware/Camera.java
Camera(int cameraId) {if(cameraId >= getNumberOfCameras()){throw new RuntimeException("Unknown camera ID");}int err = cameraInit(cameraId);initAppOps();
}

在camera 构造函数中调用cameraInit。

frameworks/base/core/java/android/hardware/Camera.java
private int cameraInit(int cameraId) {//调用到JNI中android_hardware_Camera_native_setupreturn native_setup(new WeakReference<Camera>(this), cameraId,ActivityThread.currentOpPackageName());
}

在camera Init中通过native_setup interface就会调用到JNI中android_hardware_Camera_native_setup function。

frameworks/base/core/jni/android_hardware_Camera.cpp
static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,jobject weak_this, jint cameraId, jstring clientPackageName)
{const char16_t *rawClientName = reinterpret_cast<const char16_t*>(env->GetStringChars(clientPackageName, NULL));jsize rawClientNameLen = env->GetStringLength(clientPackageName);String16 clientName(rawClientName, rawClientNameLen);env->ReleaseStringChars(clientPackageName,reinterpret_cast<const jchar*>(rawClientName));int targetSdkVersion = android_get_application_target_sdk_version();sp<Camera> camera = Camera::connect(cameraId, clientName, Camera::USE_CALLING_UID,Camera::USE_CALLING_PID, targetSdkVersion);…sp<JNICameraContext> context = new JNICameraContext(env, weak_this, clazz, camera);context->incStrong((void*)android_hardware_Camera_native_setup);camera->setListener(context);return NO_ERROR;
}
  • android_hardware_Camera_native_setup 中connect是Camera C/S架构的客户端,调用connect函数向服务器发送连接请求。
  • JNICameraContext这个类是一个监听类,用于处理底层Camera回调函数传来的数据和消息。
frameworks/av/camera/Camera.cpp
sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,int clientUid, int clientPid, int targetSdkVersion)
{return CameraBaseT::connect(cameraId, clientPackageName, clientUid,clientPid, targetSdkVersion);
}

JNI调用进入C++ framework camera file connect function。

frameworks/av/camera/CameraBase.cpp
template <typename TCam, typename TCamTraits>
sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId,const String16& clientPackageName,int clientUid, int clientPid, int targetSdkVersion)
{ALOGV("%s: connect", __FUNCTION__);//创建一个camera对象,调用Camera和CameraBase构造函数sp<TCam> c = new TCam(cameraId);sp<TCamCallbacks> cl = c;//获取camera service对象const sp<::android::hardware::ICameraService> cs = getCameraService();binder::Status ret;if (cs != nullptr) {TCamConnectService fnConnectService = TCamTraits::fnConnectService;ret = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid,clientPid, targetSdkVersion, /*out*/ &c->mCamera);}return c;
}

CameraBase中通过获得到server端(camera service)代理对象ICameraService。
然后ICameraService通过fnConnectService链接camera service。

frameworks/av/camera/CameraBase.cpp
// establish binder interface to camera service
template <typename TCam, typename TCamTraits>
const sp<::android::hardware::ICameraService> CameraBase<TCam, TCamTraits>::getCameraService()
{Mutex::Autolock _l(gLock);if (gCameraService.get() == 0) {if (CameraUtils::isCameraServiceDisabled()) {return gCameraService;}//通过binder获取camera servicesp<IServiceManager> sm = defaultServiceManager();sp<IBinder> binder;do {binder = sm->getService(String16(kCameraServiceName));if (binder != 0) {break;}ALOGW("CameraService not published, waiting...");usleep(kCameraServicePollDelay);} while(true);if (gDeathNotifier == NULL) {gDeathNotifier = new DeathNotifier();}binder->linkToDeath(gDeathNotifier);gCameraService = interface_cast<::android::hardware::ICameraService>(binder);}ALOGE_IF(gCameraService == 0, "no CameraService!?");return gCameraService;
}

getCameraService function中主要是展示通过binder的方法获取到camera service代理对象。
为什么fnConnectService可以链接camera device呢?因为fnConnectService就等于connect,如下代码:

frameworks/av/camera/Camera.cpp
CameraTraits<Camera>::TCamConnectService CameraTraits<Camera>::fnConnectService =&::android::hardware::ICameraService::connect;

而connect本身定义为AIDL interface,就是通过binder实现跨进程调用到camera service,在camera service中进一步处理。

frameworks/av/camera/aidl/android/hardware/ICameraService.aidl
AIDL 文件中定义的connect interface,目的为跨进程调用
ICamera connect(ICameraClient client,int cameraId,String opPackageName,int clientUid, int clientPid,int targetSdkVersion);

到此camera API 1的流程就梳理完毕,JNI在其中做一个桥梁的作用,API 1通过JNI连接到C++ framework,也展示JNI的目的就是为让java field可以调用到C++ field。

Camera API 2

  • 为更好的控制camera device,Google抛弃camera API 1重新设计camera API 2接口。
  • Camera2 provides in-depth controls for complex use cases, but requires you to manage device-specific configurations。
  • Camera API2 框架为应用提供更接近底层的相机控件,包括高效的零复制连拍/视频流以及曝光、增益、白平衡增益、颜色转换、去噪、锐化等方面的每帧控件。
  • camera API 2调用流程相对简单,直接从API 2 interface通过AIDL调用到camera service,接下来也是举例openCamera流程进行分析。
frameworks/base/core/java/android/hardware/camera2/CameraManager.java
public void openCamera(@NonNull String cameraId,@NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler)throws CameraAccessException {openCameraForUid(cameraId, callback, CameraDeviceImpl.checkAndWrapHandler(handler),USE_CALLING_UID);
}public void openCameraForUid(@NonNull String cameraId,@NonNull final CameraDevice.StateCallback callback, @NonNull Executor executor,int clientUid, int oomScoreOffset) throws CameraAccessException {openCameraDeviceUserAsync(cameraId, callback, executor, clientUid, oomScoreOffset);
}

APP通过API 2 open camera操作可以调用到camera manager中的openCamera function,进而调用到openCameraForUid、openCameraDeviceUserAsync。

frameworks/base/core/java/android/hardware/camera2/CameraManager.java
private CameraDevice openCameraDeviceUserAsync(String cameraId,CameraDevice.StateCallback callback, Executor executor, final int uid,final int oomScoreOffset) throws CameraAccessException {CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);CameraDevice device = null;Map<String, CameraCharacteristics> physicalIdsToChars =getPhysicalIdToCharsMap(characteristics);synchronized (mLock) {ICameraDeviceUser cameraUser = null;android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =new android.hardware.camera2.impl.CameraDeviceImpl(cameraId,callback,executor,characteristics,physicalIdsToChars,mContext.getApplicationInfo().targetSdkVersion,mContext);ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();try {ICameraService cameraService = CameraManagerGlobal.get().getCameraService();if (cameraService == null) {throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED,"Camera service is currently unavailable");}cameraUser = cameraService.connectDevice(callbacks, cameraId,mContext.getOpPackageName(),  mContext.getAttributionTag(), uid,oomScoreOffset, mContext.getApplicationInfo().targetSdkVersion);} catch (ServiceSpecificException e) {}return device;
}

openCameraDeviceUserAsync function中通过getCameraService获取到camera service代理ICameraService,这部分操作是在class CameraManagerGlobal中实现。

frameworks/base/core/java/android/hardware/camera2/CameraManager.java
class CameraManagerGlobal {public ICameraService getCameraService() {synchronized(mLock) {connectCameraServiceLocked();if (mCameraService == null && !sCameraServiceDisabled) {Log.e(TAG, "Camera service is unavailable");}return mCameraService;}}private void connectCameraServiceLocked() {// Only reconnect if necessaryif (mCameraService != null || sCameraServiceDisabled) return;Log.i(TAG, "Connecting to camera service");IBinder cameraServiceBinder = ServiceManager.getService(CAMERA_SERVICE_BINDER_NAME);if (cameraServiceBinder == null) {// Camera service is now down, leave mCameraService as nullreturn;}try {cameraServiceBinder.linkToDeath(this, /*flags*/ 0);} catch (RemoteException e) {// Camera service is now down, leave mCameraService as nullreturn;}//直接通过AIDL 获取camera serviceICameraService cameraService = ICameraService.Stub.asInterface(cameraServiceBinder);}
}
  • global manger camera class主要作为保持和camera service的链接,并且distribute camera device callback notice。
  • getCameraService调用到connectCameraServiceLocked,可以很清楚的看到通过binder获取到cameraService。
  • 因为connectDevice interface本身定义为AIDL,跨进程的方式从java framework调用到camera service中。
frameworks/av/camera/aidl/android/hardware/ICameraService.aidlICameraDeviceUser connectDevice(ICameraDeviceCallbacks callbacks,String cameraId,String opPackageName,@nullable String featureId,int clientUid, int oomScoreOffset,int targetSdkVersion);

以上就讲解完通过 API 2方式从APP调用到camera service。

小结

  • 虽然Android SDK中的API 1和API 2都是通过AIDL调用到camera service,但是分别是在C++ code和java code中调用,这里就体现AIDL这种接口描述性语言的优势,不需要考虑binder service和client两端的编程语言,只需要按照要求编写好AIDL interface,编译之后自动生成代码,在使用的时候按接口标准就可以实现。

Android NDK

NDK Interface

  • NDK的全拼是:Native Develop Kit,Android NDK 是一套允许您使用原生代码语言(例如C和C++)实现部分应用的工具集。在开发某些类型应用时,这有助于您重复使用以这些语言编写的代码库。
  • 我们来分析要是使用NDK的方式来编写camera APP进程的代码,open camera的流程是怎么样的。
frameworks/av/camera/ndk/NdkCameraManager.cpp
camera_status_t ACameraManager_openCamera(ACameraManager* mgr, const char* cameraId,ACameraDevice_StateCallbacks* callback,/*out*/ACameraDevice** device) {return mgr->openCamera(cameraId, callback, device);
}

在system分区中通过使用C++代码编写的camera APP,open camera调用的是NDK中的ACameraManager_openCamera,进一步进入camera manager openCamera function。

frameworks/av/camera/ndk/NdkCameraManager.cpp
camera_status_t
ACameraManager::openCamera(const char* cameraId,ACameraDevice_StateCallbacks* callback,/*out*/ACameraDevice** outDevice)
{sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = device->getServiceCallback();sp<hardware::camera2::ICameraDeviceUser> deviceRemote;int targetSdkVersion = android_get_application_target_sdk_version();//调用CameraService::connectDevicebinder::Status serviceRet = cs->connectDevice(callbacks, String16(cameraId), String16(""), {},hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/0,targetSdkVersion, /*out*/&deviceRemote);...
}

openCamera function中先通过getCameraService获取到camera service代理对象(其中代码流程同上,就不分析了),再通过connectDevice AIDL interface 跨进程连接到camera service。

NDK Vendor Interface

  • VNDK的全称是Vendor Native Development Kit,是Android 8.0引入的一种新技术。它表现一系列库的合集,用于让供应商开发自己的HALs。VNDK 包含在 system.img 中,并在运行时与供应商代码动态关联。
  • 使用vndk的原因是自Android8.0以来,Google引入了Treble架构,希望对vendor和system分区进行解耦处理,期待实现:framwork进程不加载vendor共享库,vendor进程仅加载vendor共享库(和部分framework共享库),而framework进程和vendor进程之间通过HIDL和hwbinder来通信
  • 这里也是通过open camera function,来分析在vendor分区中编写C++ 代码的camera APP 调用到camera service。
frameworks/av/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
camera_status_t
ACameraManager::openCamera(const char* cameraId,ACameraDevice_StateCallbacks* callback,/*out*/ACameraDevice** outDevice) {sp<ACameraMetadata> rawChars;camera_status_t ret = getCameraCharacteristics(cameraId, &rawChars);Mutex::Autolock _l(mLock);if (ret != ACAMERA_OK) {ALOGE("%s: cannot get camera characteristics for camera %s. err %d",__FUNCTION__, cameraId, ret);return ACAMERA_ERROR_INVALID_PARAMETER;}ACameraDevice* device = new ACameraDevice(cameraId, callback, std::move(rawChars));sp<ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();if (cs == nullptr) {ALOGE("%s: Cannot reach camera service!", __FUNCTION__);delete device;return ACAMERA_ERROR_CAMERA_DISCONNECTED;}sp<ICameraDeviceCallback> callbacks = device->getServiceCallback();sp<ICameraDeviceUser_2_0> deviceRemote_2_0;//通过调用HidlCameraService中connectDevice,hidl方式Status status = Status::NO_ERROR;auto serviceRet = cs->connectDevice(callbacks, cameraId, [&status, &deviceRemote_2_0](auto s, auto &device) {status = s;deviceRemote_2_0 = device;});…sp<ICameraDeviceUser> deviceRemote = castResult;device->setRemoteDevice(deviceRemote);device->setDeviceMetadataQueues();*outDevice = device;return ACAMERA_OK;
}

这里直接给出的是NDK Vendor中的openCamera function,但是这个函数也是被ACameraManager_openCamera调用。
其中mgr->openCamera是调用NDK还是NDK Vendor中的interface呢?需要通过mCameraManager来确定。

ACameraManager_openCamera(mCameraManager, mCameraId, &mDeviceCb, &mDevice);
mCameraManager = ACameraManager_create();
ACameraManager* ACameraManager_create() {ATRACE_CALL();return new ACameraManager();
}
  • ACameraManager_openCamera调用时会传入mCameraManager,mCameraManager是由ACameraManager_create创建出来。ACameraManager_create 创建过程直接new ACameraManager对象。
NDK ACameraManager:
struct ACameraManager {ACameraManager() :mGlobalManager(&(android::acam::CameraManagerGlobal::getInstance())) {}~ACameraManager();camera_status_t getCameraIdList(ACameraIdList** cameraIdList);static void     deleteCameraIdList(ACameraIdList* cameraIdList);camera_status_t getCameraCharacteristics(const char* cameraId, android::sp<ACameraMetadata>* characteristics);camera_status_t openCamera(const char* cameraId,ACameraDevice_StateCallbacks* callback,/*out*/ACameraDevice** device);private:enum {kCameraIdListNotInit = -1};android::Mutex         mLock;android::sp<android::acam::CameraManagerGlobal> mGlobalManager;
};NDK Vendor ACameraManager:
struct ACameraManager {ACameraManager() :mGlobalManager(&(android::acam::CameraManagerGlobal::getInstance())) {}~ACameraManager();camera_status_t getCameraIdList(ACameraIdList** cameraIdList);static void     deleteCameraIdList(ACameraIdList* cameraIdList);camera_status_t getCameraCharacteristics(const char* cameraId, android::sp<ACameraMetadata>* characteristics);camera_status_t openCamera(const char* cameraId,ACameraDevice_StateCallbacks* callback,/*out*/ACameraDevice** device);camera_status_t getTagFromName(const char *cameraId, const char *name, uint32_t *tag);private:enum {kCameraIdListNotInit = -1};android::Mutex         mLock;android::sp<android::acam::CameraManagerGlobal> mGlobalManager;
};
  • new ACameraManager需要区分是调用NDK还是NDK Vendor创建对象,不同的对象进而实现不同的调用接口逻辑。
  • 再回来看openCamera function中的connectDevice interface,其中传递的参数和NDK代码中明显不同,因为NDK Vendor调用的是HIDL 定义connectDevice interface。
frameworks/hardware/interfaces/cameraservice/service/2.0/ICameraService.hal
connectDevice(ICameraDeviceCallback callback, string cameraId)generates (Status status, ICameraDeviceUser device);
  • ICameraService.hal文件中定义的HIDL connectDevice interface。
  • cs->connectDevice通过binder跨进程可以调用到HidlCameraService::connectDevice中。

小结

  • 以上分析了通过NDK和NDK Vendor方式,connect device连接到camera service的代码流程,区别在于NDK使用AIDL interface而NDK Vendor使用 HIDL interface,并且在libcameraservice中对接的接口也不一样。
  • System分区中new ACameraManager实例调用NDK interface,Vendor 分区中new ACameraManager实例调用NDK Vendor interface。
  • HidlCameraService对上连接NDK Vendor,但是最终实现功能还是依赖于CameraService。

Camera VTS Testcase

  • HIDL interface提供的接口是可以直接实现camera device所有基础的功能,但是由于没有 camera service的介入对于管理camera device是非常困难的。使用这种方式构建camera APP非常的特殊,没有经过整个Android framework,可以直接对HAL进行测试。
  • Camera VTS testcase 是基于HDIL interface来实现功能的测试程序,毕竟是Google提供给HAL 厂商稳定的接口,肯定需要测试保证其稳定性。
  • 对于如果是camera service process没有启动的情况下,可以使用HDIL interface来写camera APP,感兴趣可以移步: Camera HIDL接口实现camera preview功能

总结

  • 这篇博客主要是对Android framework接口方式进行介绍,其中包括Android SDK和Android NDK,Android SDK可以分为API 1和API 2,其中API 1通过JNI的方式调用实现。
  • JNI调用的cameraBase是和NDK、NDK vendor处于同一目录下,framework中的audio和video服务层(av目录名字含义)。
  • CameraBase、API 2和NDK都是通过AIDL跨进程调用到libcameraservice,而只有NDK Vendor独特的使用HIDL跨进程调用到libcameraservice。

Reference

链接: Android JNI(一)——NDK与JNI基础

相关文章:

Android Camera SDK NDK NDK_vendor介绍

Android Camera JNI NDK NDK_vendor介绍前言主要有哪几种interface&#xff1f;Android SDKCamera API 1Camera API 2小结Android NDKNDK InterfaceNDK Vendor Interface小结Camera VTS Testcase总结Reference前言 本篇博客是想介绍Android camera从application layer到camera…...

SQL基础语句小结

&#x1f34e;道阻且长&#xff0c;行则将至。&#x1f353; 目录 一、SQL概述 1.简介 2.格式语法 3.SQL分类 二、DDL操作数据库 1.创建数据库 2.查询与使用 3.删除数据库 三、DDL:操作表 (1)数据类型 (2)创建表 (3)查询当前数据库的表 (4)删除表 (5)修改表 四、DML…...

管理类书籍推荐

管理类书籍对于每一位想要获得管理能力提升或者实现职业生涯更上一层楼的企业管理者或领导者而言&#xff0c;都是不可或缺的一项重要学习工具。作为管理工作从事者的职场必需品&#xff0c;一本出色的管理类书籍可以为我们提供大量宝贵的经验与专业建议&#xff0c;从而让管理…...

win10 mingw 调用python

ubuntu调用pythonhttps://blog.csdn.net/qq_39942341/article/details/129333969 我这里mingw是用msys2的 opencv也是msys2装的 安装msys2和opencv可以参考这个https://blog.csdn.net/qq_39942341/article/details/129380197?spm1001.2014.3001.5502 环境变量里加入python路…...

教你使用三种方式写一个最基本的spark程序

当需要处理大规模数据并且需要进行复杂的数据处理时&#xff0c;通常会使用Hadoop生态系统中的Hive和Spark来完成任务。在下面的例子中&#xff0c;我将说明如何使用Spark编写一个程序来处理Hive中的数据&#xff0c;以满足某个特定需求。假设我们有一个Hive表&#xff0c;其中…...

软件设计师错题集

软件设计师错题集一、计算机组成与体系结构1.1 浮点数1.2 Flynn分类法1.3 指令流水线1.4 层次化存储体系1.4.1 程序的局限性1.5 Cache1.6 输入输出技术1.7 总线系统1.8 CRC循环冗余校验码二、数据结构与算法基础2.1 队列与栈2.2 树与二叉树的特殊性2.3 最优二叉树&#xff08;哈…...

【华为机试真题详解 Python实现】静态扫描最优成本【2023 Q1 | 100分】

文章目录前言题目描述输入描述输出描述示例 1输入&#xff1a;输出&#xff1a;示例 2输入&#xff1a;输出&#xff1a;题目解析参考代码前言 《华为机试真题详解》专栏含牛客网华为专栏、华为面经试题、华为OD机试真题。 如果您在准备华为的面试&#xff0c;期间有想了解的…...

算法刷题总结 (四) 动态规划

算法总结4 动态规划一、动态规划1.1、基础问题11.1.1、509. 斐波那契数列1.1.2、70. 爬楼梯1.1.3、746. 使用最小花费爬楼梯1.2、基础问题21.2.1、62. 不同路径1.2.2、63. 不同路径Ⅱ1.2.3、343. 整数拆分1.2.4、96. 不同的二叉搜索树1.3、背包问题1.3.1、01背包1.3.1.1、单次选…...

Grafana 转换数据的工具介绍

转换数据 Grafana 可以在数据显示到面板前对数据进行处理 1、点击Transform选项卡 2、选择要使用的转换类型&#xff0c;不同的转换类型配置不同 3、要新增转换类型&#xff0c;点击Add transformation 4、使用右上角调式按钮可以调式转换 支持的转换类型&#xff1a; Add f…...

Linux 学习笔记

一、 概述 1. 操作系统 ① 计算机由硬件和软件组成 ② 操作系统属于软件范畴&#xff0c;主要作用是协助用户调度硬件工作&#xff0c;充当用户和计算机硬件之间的桥梁 ③ 常见的操作系统 &#x1f920; PC端&#xff1a;Windows、Linux、MacOS&#x1f920; 移动端&#…...

HTML注入专精整理

目录 HTML注入介绍 抽象解释 HTML注入的影响 HTML注入与XSS的区别 HTML元素流程图...

看完这篇我不信你不会二叉树的层序遍历【C语言】

目录 实现思路 代码实现 之前介绍了二叉树的前、中、后序三种遍历&#xff0c;采用的是递归的方式。今天我们来学习另外一种遍历方式——层序遍历。层序遍历不容小觑&#xff0c;虽然实现方法并不难&#xff0c;但是它所采取的思路是很值得学习的&#xff0c;与前三者不同&am…...

案例17-环境混用带来的影响

目录一、背景介绍背景事故二、思路&方案三、过程四、总结nginx做转发fastdfs&#xff08;文件上传下载&#xff09;五、升华一、背景介绍 本篇博客主要介绍开发中项目使用依赖项环境闭一只带来的恶劣影响&#xff0c;在错误中成长进步。 背景 本公司另外一个产品开发God…...

知识蒸馏论文阅读:DKD算法笔记

标题&#xff1a;Decoupled Knowledge Distillation 会议&#xff1a;CVPR2022 论文地址&#xff1a;https://ieeexplore.ieee.org/document/9879819/ 官方代码&#xff1a;https://github.com/megvii-research/mdistiller 作者单位&#xff1a;旷视科技、早稻田大学、清华大学…...

Sentinel架构篇 - 熔断降级

熔断降级 概念 除了流量控制以外&#xff0c;对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。一个服务常常会调用其它模块&#xff0c;可能是一个远程服务、数据库、或者第三方 API 等。然而&#xff0c;被依赖的服务的稳定性是不能保证的。如果依赖的服…...

shell脚本的一些记录 与jenkins的介绍

shell 脚本的执行 sh ***.sh shell脚本里面的命令 其实就是终端执行一些命令 shell 连接服务器 可以直接ssh连接 但是这样最好是无密码的 不然后面的命令就不好写了 换而言之有密码得 不好写脚本 需要下载一些expect的插件之类的才可以 判断语句 的示例 需要注意的是…...

JVM的了解与学习

一:jvm是什么 jvm是java虚拟机java Virtual Machine的缩写 jdk包含jre和java DevelopmentTools 二:什么是java虚拟机 虚拟机是一种抽象化的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现的。java虚拟机有自己完善的硬体结构,如处理器、堆栈、寄存器等,还有…...

提升数字品牌的5个技巧

“品牌”或“品牌推广”的概念通常用于营销。因为建立您的企业品牌对于产品来说极其重要&#xff0c;品牌代表了您与客户互动的身份和声音。今天&#xff0c;让我们来看看在数字领域提升品牌的一些有用的技巧。如何在数字领域提升您的品牌&#xff1f;在了解这些技巧之前&#…...

java通过反射获取加了某个注解的所有的类

有时候我们会碰到这样的情况&#xff1a;有n个场景&#xff0c;每个场景都有自己的逻辑&#xff0c;即n个处理逻辑&#xff0c;这时候我们就需要通过某个参数的值代表这n个场景&#xff0c;然后去加载每个场景不同的bean对象&#xff0c;即不同的类&#xff0c;这些类中都有一个…...

Warshall算法

&#x1f680;write in front&#x1f680; &#x1f4dc;所属专栏&#xff1a;> 算法 &#x1f6f0;️博客主页&#xff1a;睿睿的博客主页 &#x1f6f0;️代码仓库&#xff1a;&#x1f389;VS2022_C语言仓库 &#x1f3a1;您的点赞、关注、收藏、评论&#xff0c;是对我…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会

在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…...