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

VLC 播放的音视频数据处理流水线搭建

VLC 用 input_thread_t 对象直接或间接管理音视频播放有关的各种资源,包括 AccessDemuxDecodeOutputFilter 等,这个类型定义 (位于 vlc-3.0.16/include/vlc_input.h) 如下:

struct input_thread_t
{VLC_COMMON_MEMBERS
};

input_thread_t 是个抽象类型,VLC 中这个类型的具体实现为 input_thread_private_t,后者定义 (位于 vlc-3.0.16/src/input/input_internal.h) 如下:

#define INPUT_CONTROL_FIFO_SIZE    100/* input_source_t: gathers all information per input source */
typedef struct
{VLC_COMMON_MEMBERSdemux_t  *p_demux; /**< Demux object (most downstream) *//* Title infos for that input */bool         b_title_demux; /* Titles/Seekpoints provided by demux */int          i_title;input_title_t **title;int i_title_offset;int i_seekpoint_offset;int i_title_start;int i_title_end;int i_seekpoint_start;int i_seekpoint_end;/* Properties */bool b_can_pause;bool b_can_pace_control;bool b_can_rate_control;bool b_can_stream_record;bool b_rescale_ts;double f_fps;/* */int64_t i_pts_delay;bool       b_eof;   /* eof of demuxer */} input_source_t;typedef struct
{int         i_type;vlc_value_t val;
} input_control_t;/** Private input fields */
typedef struct input_thread_private_t
{struct input_thread_t input;/* Global properties */bool        b_preparsing;bool        b_can_pause;bool        b_can_rate_control;bool        b_can_pace_control;/* Current state */int         i_state;bool        is_running;bool        is_stopped;bool        b_recording;int         i_rate;/* Playtime configuration and state */int64_t     i_start;    /* :start-time,0 by default */int64_t     i_stop;     /* :stop-time, 0 if none */int64_t     i_time;     /* Current time */bool        b_fast_seek;/* :input-fast-seek *//* Output */bool            b_out_pace_control; /* XXX Move it ot es_sout ? */sout_instance_t *p_sout;            /* Idem ? */es_out_t        *p_es_out;es_out_t        *p_es_out_display;vlc_viewpoint_t viewpoint;bool            viewpoint_changed;vlc_renderer_item_t *p_renderer;/* Title infos FIXME multi-input (not easy) ? */int          i_title;const input_title_t **title;int i_title_offset;int i_seekpoint_offset;/* User bookmarks FIXME won't be easy with multiples input */seekpoint_t bookmark;int         i_bookmark;seekpoint_t **pp_bookmark;/* Input attachment */int i_attachment;input_attachment_t **attachment;const demux_t **attachment_demux;/* Main input properties *//* Input item */input_item_t   *p_item;/* Main source */input_source_t *master;/* Slave sources (subs, and others) */int            i_slave;input_source_t **slave;/* Resources */input_resource_t *p_resource;input_resource_t *p_resource_private;/* Stats counters */struct {counter_t *p_read_packets;counter_t *p_read_bytes;counter_t *p_input_bitrate;counter_t *p_demux_read;counter_t *p_demux_bitrate;counter_t *p_demux_corrupted;counter_t *p_demux_discontinuity;counter_t *p_decoded_audio;counter_t *p_decoded_video;counter_t *p_decoded_sub;counter_t *p_sout_sent_packets;counter_t *p_sout_sent_bytes;counter_t *p_sout_send_bitrate;counter_t *p_played_abuffers;counter_t *p_lost_abuffers;counter_t *p_displayed_pictures;counter_t *p_lost_pictures;vlc_mutex_t counters_lock;} counters;/* Buffer of pending actions */vlc_mutex_t lock_control;vlc_cond_t  wait_control;int i_control;input_control_t control[INPUT_CONTROL_FIFO_SIZE];vlc_thread_t thread;vlc_interrupt_t interrupt;
} input_thread_private_t;

播放 VLC 播放列表中的一个音视频流的时候,音视频流的播放通过 PlayItem() 函数起动,这个函数被调用的调用栈如下:

Thread 3 "vlc" hit Breakpoint 14, PlayItem (p_item=<optimized out>, p_playlist=0xaaaaaab37980) at playlist/thread.c:227
227	        if( input_Start( p_input_thread ) )
(gdb) bt
#0  PlayItem (p_item=<optimized out>, p_playlist=0xaaaaaab37980) at playlist/thread.c:227
#1  Next (p_playlist=0xaaaaaab37980) at playlist/thread.c:474
#2  Thread (data=0xaaaaaab37980) at playlist/thread.c:499
#3  0x0000fffff7e4d5c8 in start_thread (arg=0x0) at ./nptl/pthread_create.c:442

PlayItem() 函数定义 (位于 vlc-3.0.16/src/playlist/thread.c) 如下:

static bool PlayItem( playlist_t *p_playlist, playlist_item_t *p_item )
{playlist_private_t *p_sys = pl_priv(p_playlist);input_item_t *p_input = p_item->p_input;vlc_renderer_item_t *p_renderer;PL_ASSERT_LOCKED;msg_Dbg( p_playlist, "creating new input thread" );p_item->i_nb_played++;set_current_status_item( p_playlist, p_item );p_renderer = p_sys->p_renderer;/* Retain the renderer now to avoid it to be released by* playlist_SetRenderer when we exit the locked scope. If the last reference* was to be released, we would use a dangling pointer */if( p_renderer )vlc_renderer_item_hold( p_renderer );assert( p_sys->p_input == NULL );PL_UNLOCK;libvlc_MetadataCancel( p_playlist->obj.libvlc, p_item );input_thread_t *p_input_thread = input_Create( p_playlist, p_input, NULL,p_sys->p_input_resource,p_renderer );if( p_renderer )vlc_renderer_item_release( p_renderer );if( likely(p_input_thread != NULL) ){var_AddCallback( p_input_thread, "intf-event",InputEvent, p_playlist );if( input_Start( p_input_thread ) ){var_DelCallback( p_input_thread, "intf-event",InputEvent, p_playlist );vlc_object_release( p_input_thread );p_input_thread = NULL;}}/* TODO store art policy in playlist private data */char *psz_arturl = input_item_GetArtURL( p_input );/* p_input->p_meta should not be null after a successful CreateThread */bool b_has_art = !EMPTY_STR( psz_arturl );if( !b_has_art || strncmp( psz_arturl, "attachment://", 13 ) ){PL_DEBUG( "requesting art for new input thread" );libvlc_ArtRequest( p_playlist->obj.libvlc, p_input, META_REQUEST_OPTION_NONE );}free( psz_arturl );PL_LOCK;p_sys->p_input = p_input_thread;PL_UNLOCK;var_SetAddress( p_playlist, "input-current", p_input_thread );PL_LOCK;return p_input_thread != NULL;
}

PlayItem() 函数接收 playlist_item_t 类型的 p_item 参数,这个类型定义 (位于 vlc-3.0.16/include/vlc_playlist.h) 如下:

/** playlist item / node */
struct playlist_item_t
{input_item_t           *p_input;    /**< Linked input item */playlist_item_t      **pp_children; /**< Children nodes/items */playlist_item_t       *p_parent;    /**< Item parent */int                    i_children;  /**< Number of children, -1 if not a node */unsigned               i_nb_played; /**< Times played */int                    i_id;        /**< Playlist item specific id */uint8_t                i_flags;     /**< Flags \see playlist_item_flags_e */
};

playlist_item_t 类型包含一个类型为 input_item_t 的字段 p_input,其中包含要播放的音视频流的各种信息,如 URI,名称,基础流的个数及格式等,input_item_t 类型的详细定义 (位于 vlc-3.0.16/include/vlc_input_item.h) 如下:

struct info_t
{char *psz_name;            /**< Name of this info */char *psz_value;           /**< Value of the info */
};struct info_category_t
{char   *psz_name;      /**< Name of this category */int    i_infos;        /**< Number of infos in the category */struct info_t **pp_infos;     /**< Pointer to an array of infos */
};/*** Describes an input and is used to spawn input_thread_t objects.*/
struct input_item_t
{char       *psz_name;            /**< text describing this item */char       *psz_uri;             /**< mrl of this item */int        i_options;            /**< Number of input options */char       **ppsz_options;       /**< Array of input options */uint8_t    *optflagv;            /**< Some flags of input options */unsigned   optflagc;input_item_opaque_t *opaques;    /**< List of opaque pointer values */mtime_t    i_duration;           /**< Duration in microseconds */int        i_categories;         /**< Number of info categories */info_category_t **pp_categories; /**< Pointer to the first info category */int         i_es;                /**< Number of es format descriptions */es_format_t **es;                /**< Es formats */input_stats_t *p_stats;          /**< Statistics */vlc_meta_t *p_meta;int         i_epg;               /**< Number of EPG entries */vlc_epg_t   **pp_epg;            /**< EPG entries */int64_t     i_epg_time;          /** EPG timedate as epoch time */const vlc_epg_t *p_epg_table;    /** running/selected program cur/next EPG table */int         i_slaves;            /**< Number of slaves */input_item_slave_t **pp_slaves;  /**< Slave entries that will be loaded bythe input_thread */vlc_event_manager_t event_manager;vlc_mutex_t lock;                 /**< Lock for the item */uint8_t     i_type;              /**< Type (file, disc, ... see input_item_type_e) */bool        b_net;               /**< Net: always true for TYPE_STREAM, itdepends for others types */bool        b_error_when_reading;/**< Error When Reading */int         i_preparse_depth;    /**< How many level of sub items can be preparsed:-1: recursive, 0: none, >0: n levels */bool        b_preparse_interact; /**< Force interaction with the user whenpreparsing.*/
};

这里的几个类型的结构关系大概如下图所示:
VLC Objects
PlayItem() 函数主要是调用 input_Create() 函数创建 input_thread_t/input_thread_private_t 对象,并调用 input_Start() 函数启动对音视频流的处理。

input_Create()input_Start() 函数函数定义 (位于 vlc-3.0.16/src/input/input.c) 如下:

input_thread_t *input_Create( vlc_object_t *p_parent,input_item_t *p_item,const char *psz_log, input_resource_t *p_resource,vlc_renderer_item_t *p_renderer )
{return Create( p_parent, p_item, psz_log, false, p_resource, p_renderer );
}. . . . . .
/*** Start a input_thread_t created by input_Create.** You must not start an already running input_thread_t.** \param the input thread to start*/
int input_Start( input_thread_t *p_input )
{input_thread_private_t *priv = input_priv(p_input);void *(*func)(void *) = Run;if( priv->b_preparsing )func = Preparse;assert( !priv->is_running );/* Create thread and wait for its readiness. */priv->is_running = !vlc_clone( &priv->thread, func, priv,VLC_THREAD_PRIORITY_INPUT );if( !priv->is_running ){input_ChangeState( p_input, ERROR_S );msg_Err( p_input, "cannot create input thread" );return VLC_EGENERIC;}return VLC_SUCCESS;
}. . . . . .static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,const char *psz_header, bool b_preparsing,input_resource_t *p_resource,vlc_renderer_item_t *p_renderer )
{/* Allocate descriptor */input_thread_private_t *priv;priv = vlc_custom_create( p_parent, sizeof( *priv ), "input" );if( unlikely(priv == NULL) )return NULL;input_thread_t *p_input = &priv->input;. . . . . .}
static void *Run( void *data )
{input_thread_private_t *priv = data;input_thread_t *p_input = &priv->input;vlc_interrupt_set(&priv->interrupt);if( !Init( p_input ) ){if( priv->b_can_pace_control && priv->b_out_pace_control ){/* We don't want a high input priority here or we'll* end-up sucking up all the CPU time */vlc_set_priority( priv->thread, VLC_THREAD_PRIORITY_LOW );}MainLoop( p_input, true ); /* FIXME it can be wrong (like with VLM) *//* Clean up */End( p_input );}input_SendEventDead( p_input );return NULL;
}

除了 b_preparsing 参数传 false 外,input_Create() 函数将接收的各个参数传给 Create(),通过后者创建 input_thread_private_t 对象。input_Start() 函数启动一个新的线程处理音视频流,默认情况下,新起的线程跑 Run() 函数,但如果设置了 b_preparsing,新起的线程跑 Preparse() 函数。

播放列表中各个音频流的信息,也通过 input_thread_t 获取。当我们往 VLC 的播放列表拖入一个文件时,UI 事件向播放列表添加一个输入项,输入项最终被放入播放列表预解析器的待解析队列中,这个调用过程如下面的调用栈所示:

#0  background_worker_Push (worker=0xaaaaaaae2e40, entity=entity@entry=0xffffc885fec0, id=id@entry=0xffffc87f5ac0, timeout=timeout@entry=-1) at misc/background_worker.c:211
#1  0x0000fffff7ced04c in playlist_preparser_Push (preparser=0xaaaaaaadbe00, item=item@entry=0xffffc885fec0, i_options=META_REQUEST_OPTION_NONE, timeout=-1, id=0xffffc87f5ac0)at playlist/preparser.c:178
#2  0x0000fffff7cca748 in vlc_MetadataRequest(libvlc=0xaaaaaaab58e0, item=item@entry=0xffffc885fec0, i_options=i_options@entry=META_REQUEST_OPTION_NONE, timeout=timeout@entry=-1, id=id@entry=0xffffc87f5ac0) at libvlc.c:504
#3  0x0000fffff7ceee5c in playlist_Preparse (p_item=0xffffc87f5ac0, p_playlist=0xaaaaaab37980) at playlist/item.c:750
#4  playlist_NodeAddInput (p_playlist=p_playlist@entry=0xaaaaaab37980, p_input=p_input@entry=0xffffc885fec0, p_parent=<optimized out>, i_pos=i_pos@entry=-1) at playlist/item.c:541
#5  0x0000fffff7ceef20 in playlist_AddInput (p_playlist=p_playlist@entry=0xaaaaaab37980, p_input=p_input@entry=0xffffc885fec0, play_now=play_now@entry=false, b_playlist=b_playlist@entry=true)at playlist/item.c:504
#6  0x0000fffff7ceefe4 in playlist_AddExt(p_playlist=0xaaaaaab37980, psz_uri=<optimized out>, psz_name=<optimized out>, play_now=false, i_options=0, ppsz_options=0x0, i_option_flags=2, b_playlist=true) at playlist/item.c:483
#7  0x0000ffffe51d4440 in Open::openMRLwithOptions(intf_thread_t*, QString const&, QStringList*, bool, bool, char const*)(p_intf=0xaaaaaad8e8d0, mrl=..., options=<optimized out>, b_start=false, b_playlist=true, title=0x0) at /usr/include/aarch64-linux-gnu/qt5/QtCore/qarraydata.h:61
#8  0x0000ffffe51ba768 in MainInterface::dropEventPlay(QDropEvent*, bool, bool) (this=0xffffc81475f0, event=0xffffe319d020, b_play=<optimized out>, b_playlist=true)at gui/qt/main_interface.cpp:1580
#9  0x0000ffffe4b96378 in QWidget::event(QEvent*) () at /usr/lib/aarch64-linux-gnu/libQt5Widgets.so.5
#10 0x0000ffffe4b52ac0 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/lib/aarch64-linux-gnu/libQt5Widgets.so.5
#11 0x0000ffffe4b5a2e0 in QApplication::notify(QObject*, QEvent*) () at /usr/lib/aarch64-linux-gnu/libQt5Widgets.so.5
#12 0x0000ffffe40acb90 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /usr/lib/aarch64-linux-gnu/libQt5Core.so.5

其中 input_item_t 对象在 playlist_AddExt() 函数中创建,它所属的 playlist_item_t 对象则在 playlist_AddInput() 函数中通过 playlist_NodeAddInput() 创建。VLC 起一个后台线程来预解析音视频流,VLC 调用 PreparserOpenInput() 函数预解析音视频流,这个函数被调用的调用栈如下:

Thread 32 "vlc" hit Breakpoint 7, PreparserOpenInput (preparser_=0xaaaaaaadbe00, item_=0xffffc8730830, out=0xffffb021e790) at playlist/preparser.c:55
55	    playlist_preparser_t* preparser = preparser_;
(gdb) bt
#0  PreparserOpenInput (preparser_=0xaaaaaaadbe00, item_=0xffffc8730830, out=0xffffb021e790) at playlist/preparser.c:55
#1  0x0000fffff7d43c1c in Thread (data=0xaaaaaaae2e40) at misc/background_worker.c:115
#2  0x0000fffff7e4d5c8 in start_thread (arg=0x0) at ./nptl/pthread_create.c:442

PreparserOpenInput() 函数定义 (位于 vlc-3.0.16/src/playlist/preparser.c) 如下:

static int PreparserOpenInput( void* preparser_, void* item_, void** out )
{playlist_preparser_t* preparser = preparser_;input_thread_t* input = input_CreatePreparser( preparser->owner, item_ );i

相关文章:

VLC 播放的音视频数据处理流水线搭建

VLC 用 input_thread_t 对象直接或间接管理音视频播放有关的各种资源,包括 Access,Demux,Decode,Output,Filter 等,这个类型定义 (位于 vlc-3.0.16/include/vlc_input.h) 如下: struct input_thread_t {VLC_COMMON_MEMBERS };input_thread_t 是个抽象类型,VLC 中这个类…...

何时在 SQL 中使用 CHAR、VARCHAR 和 VARCHAR(MAX)

在管理数据库表时&#xff0c;考虑 CHAR、VARCHAR 和 VARCHAR(MAX) 是必不可少的。此外&#xff0c;使用正确的工具&#xff08;例如dbForge Studio for SQL Server&#xff09; &#xff0c;与数据库相关的任务都会变得更加容易。它是针对 SQL Server 专业人员的强大的一体化解…...

学习笔记043——HashMap源码学习1

文章目录 1、HashMap2、Hashtable3、TreeMap4、HashMap 底层结构4.1、什么是红黑树&#xff1f; 1、HashMap HashMap key 是不能重复的&#xff0c;value 可以重复 底层结构 key-value 进行存储&#xff0c;key-value 存入到 Set 中&#xff0c;再将 Set 装载到 HashMap pack…...

单点登录原理

允许跨域–>单点登录。 例如https://www.jd.com/ 同一个浏览器下&#xff1a;通过登录页面产生的cookie里的一个随机字符串的标识&#xff0c;在其他子域名下访问共享cookie获取标识进行单点登录&#xff0c;如果没有该标识则返回登录页进行登录。 在hosts文件下面做的域名…...

【随笔】AI大模型对软件开发的影响

随着 AI 技术的不断发展&#xff0c;AI大模型正在重塑软件开发流程&#xff0c;从代码自动生成到智能测试&#xff0c;未来&#xff0c;AI 大模型将会对软件开发者、企业&#xff0c;以及整个产业链都产生深远的影响。欢迎探讨 AI 是如何重塑软件开发的各个环节以及带来的新的流…...

JAVA中接口类和抽象类的区别

在Java中&#xff0c;接口&#xff08;Interface&#xff09;和抽象类&#xff08;Abstract Class&#xff09;都是实现抽象概念的方式&#xff0c;但它们之间存在一些关键的区别&#xff1a; 1. 定义和声明 抽象类&#xff1a; 使用abstract关键字声明。可以包含构造方法、成…...

【AI系统】昇腾 AI 架构介绍

昇腾 AI 架构介绍 昇腾计算的基础软硬件是产业的核⼼&#xff0c;也是 AI 计算能⼒的来源。华为&#xff0c;作为昇腾计算产业⽣态的⼀员&#xff0c;是基础软硬件系统的核⼼贡献者。昇腾计算软硬件包括硬件系统、基础软件和应⽤使能等。 而本书介绍的 AI 系统整体架构&#…...

uniapp input只输入一个字符就自动失去焦点

下面一段代码在每次输入后自动失去焦点&#xff0c;这是因为绑定的:key是动态的&#xff0c;输入改变后都需要重新刷新渲染&#xff0c;这是造成input只能输入一次就自动失去焦点的原因。 <view class"" v-for"(item, index) in phoneList" :key"…...

定时/延时任务-ScheduledThreadPoolExecutor的使用

文章目录 1. 概要2. 固定速率和固定延时2.1 固定速率2.2 固定延时 3. API 解释3.1 schedule3.2 固定延时 - scheduleWithFixedDelay3.2 固定速率 - scheduleWithFixedDelay 4. 小结 1. 概要 前三篇文章的地址&#xff1a; 定时/延时任务-自己实现一个简单的定时器定时/延时任…...

自编码器(一)

其实自编码器也可以算是自监督学习的一环&#xff0c;因 此我们可以再简单回顾一下自监督学习的框架。如图1.1所示&#xff0c;首先你有大量的没有标注的 数据&#xff0c;用这些没有标注的数据&#xff0c;你可以去训练一个模型&#xff0c;你必须设计一些不需要标注数据的 任…...

Spring Cloud(Kilburn 2022.0.2版本)系列教程(五) 服务网关(SpringCloud Gateway)

Spring Cloud(Kilburn 2022.0.2版本)系列教程(五) 服务网关(SpringCloud Gateway) 一、服务网关 1.1 什么是网关 在微服务架构中&#xff0c;服务网关是一个至关重要的组件。它作为系统的入口&#xff0c;负责接收客户端的请求&#xff0c;并将这些请求路由到相应的后端服务…...

40分钟学 Go 语言高并发:Go程序性能优化方法论

Go程序性能优化方法论 一、性能指标概述 指标类型关键指标重要程度优化目标CPU相关CPU使用率、线程数、上下文切换⭐⭐⭐⭐⭐降低CPU使用率&#xff0c;减少上下文切换内存相关内存使用量、GC频率、对象分配⭐⭐⭐⭐⭐减少内存分配&#xff0c;优化GC延迟指标响应时间、处理延…...

一文解析Kettle开源ETL工具!

ETL&#xff08;Extract, Transform, Load&#xff09;工具是用于数据抽取、转换和加载的软件工具&#xff0c;用于支持数据仓库和数据集成过程。Kettle作为传统的ETL工具备受用户推崇。本文就来详细说下Kettle。 一、Kettle是什么&#xff1f; Kettle 是一款开源的 ETL&#x…...

Tomcat新手成长之路:安装部署优化全解析(上)

文章目录 1.Tomcat简介2.Tomcat原理架构2.1.总体架构2.2.连接器2.2.1.具体功能2.2.2.IO模型2.2.3.逻辑处理流程2.2.4.内部处理流程 2.3.容器2.4.启动过程2.5.请求过程 3.Tomcat适用场景4.Tomcat与其他Web容器对比5.Tomcat安装和启动5.1.Java环境变量5.2.系统服务5.3.启动关闭 6…...

跟我学C++中级篇——通信的数据的传递形式

一、通信的数据传递 在开发程序中&#xff0c;无可避免的会进行数据的传递。这种传递方式有很多种&#xff0c;字节流、消息、Json、参数以及对象甚至可能的方法。那么在传递这些数据时&#xff0c;如何正确的采用更合适的方法&#xff0c;就成为了一个设计的首选的问题。 二…...

C语言 qsort及应用

qsort及应用 qsort:快速排序函数,需要引用stdlib.h文件. void qsort( void *base, size_t num, size_t width, int (__cdecl *compare )(const void *, const void *) ); 参数: base:需要排序的数组 num:数据个数(数组长度) width:每个数据的字节数(sizeof(数据类型)) compa…...

【C语言】连接陷阱探秘(4):检查外部类型

目录 一、外部类型概述 1.1. 外部类型的重要性 1.2. 外部类型在C语言中的使用 1.3. 注意事项 二、常见的外部类型陷阱 2.1. 结构体和联合体的大小不匹配 2.1.1. 示例代码 2.1.2. 正确的做法 2.2. 枚举类型的值不匹配 2.3. 函数签名不一致 2.3.1. 函数签名不一致的问…...

打造双层环形图:基础与高级渐变效果的应用

在数据可视化领域&#xff0c;环形图因其独特的展示方式而广受欢迎。今天&#xff0c;我们将通过ECharts库来创建一个具有双层渐变效果的高级环形图。本文将详细介绍如何实现这种视觉效果。 1. 环形图基础 首先&#xff0c;我们需要了解环形图的基本构成。环形图由内外两个圆…...

【Git】Git 完全指南:从入门到精通

Git 完全指南&#xff1a;从入门到精通 Git 是现代软件开发中最重要的版本控制工具之一&#xff0c;它帮助开发者高效地管理项目&#xff0c;支持分布式协作和版本控制。无论是个人项目还是团队开发&#xff0c;Git 都能提供强大的功能来跟踪、管理代码变更&#xff0c;并保障…...

【mac】mac自动定时开关机和其他常用命令,管理电源设置的工具pmset

一、操作步骤 1、打开终端 2、pmset 是用于管理电源设置的强大工具&#xff0c;我们将使用这个命令 &#xff08;1&#xff09;查询当前任务 pmset -g sched查看到我当前的设置是 唤醒电源开启在 工作日的每天早上8点半 上班时不用手动开机了 &#xff08;2&#xff09;删…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...