目录
- 一、综述
- 需求分析
- 协议定制
- 二、MPEG2-TS协议
- 三、RTSP协议、RTP、RTCP、SDP
- RTSP
- RTP、RTCP、SDP
- 四、RTMP
- 五、HLS、HDS、HSS
- HLS
- HDS和HSS
- 六、MPEG-DASH
- 协议具体内容
- 应用
- 七、流媒体服务器
- 流媒体服务器的功能与挑战
- 客户端支持
- 协议支持
- 应用场景
- 应用特点
- 扩展技术
- 广告投放
- 录屏
- 其他
一、综述
需求分析
流媒体技术需要解决的问题:
1.允许客户端在不下载完整文件的时候即可以开始播放视频;
2.允许客户端从完整内容的任何位置开始播放(不包括视频直播);
3.针对视频直播,允许客户端从任意时间开始观看频道内容;
4.允许在客户的带宽条件和客户端的硬件条件下播放;
5.提供相对平稳的传输速度,以便用户基本流畅地完成播放。
并伴随两个衍生技术:
1.支持CDN传输,以提供服务扩展能力和较好的用户访问质量。
2.支持视频内容的加密,避免版权内容被人依靠复制传播牟利
协议定制
设计流媒体网络协议需要注意的问题:
1、协议应对传输的音视频格式进行规约,保证客户端可以容易解析并启动播放,并且数据冗余较小
2、流媒体的需求决定了数据必然将被分成较小的片段进行发送
3、是倚仗TCP的保证送达机制,还是基于UDP但加入纠错能力,客户端又如何应对数据缺失的状况
4、协议应具备机制帮助客户端可以尽量匀速或按可控的速度获取到视频数据
二、MPEG2-TS协议
MPEG2-TS 称Transport Stream或TS,是ISO/IEC标准13818-1或ITU-TRec.H.222.0中规定的标准的音视频传输协议,因传输的Packet可不经转换地存到文件中,又可被视为文件格式。
TS流可视为由一系列188字节的包组成(在一些扩展中可能有不同长度)的“列车”,包头固定为4字节,以0x47作为同步码起始,其中的关键信息是PID。
TS流由对一个或多个PES码流进行再封装得到,也即一个TS流可以包含多个PES流,一个音频PES包需要小于或等于64KB,视频PES包即是视频的一帧,由于TS包的负载大小仅为184字节,一个PES包需要被分成多个TS包进行传输。
除了数据,TS流中还需要Program Specific Information 信息。
·PAT(Program Association Table,节目关联表)。
·PMT(Program Map Tables,节目映射表)。
·CAT(Conditional Access Tables,条件访问表)。
·NIT(Network Information Table,网络信息表)。
·TSDT(Transport Stream Description Table,传输流描述表)。
客户端收到一个PAT包,则可以获得TS流中包含的所有节目和节目表好,以及不同节目对于PMT的PID值,同时也提供了NIT的PID。
PMT表用于指示组成某一频道的视频、音频或数据,可查到其PID值,以及节目时钟PCR的PID。
故而当客户端获取PAT和PMT包之后,即可了解TS流中包含哪些内容。
PID描述了TS流内所包含PES流的信息,用于拼接连续的包。
三、RTSP协议、RTP、RTCP、SDP
RTSP
RTSP通常与RTP和RTCP协议共同使用,其中RTSP是服务端与客户端间的双向协议,它不负责传输音视频数据,而是用来控制多个音视频流。
它基于TCP建立会话,与HTTP1.1类似。
一次使用RTSP协议的播放过程:
RTSP通过不同的命令构建完整的控制会话,同时依赖RTP和RTCP或其他协议传输音视频本身的数据。
一次典型的播放过程将在客户端和服务器间建立5个不同的Session:一路RTSP的Session、两路RTP的Session(音频和视频各一)以及两路RTCP Session(分别对应两路RTP Session),占用5个不同的端口(RTSP协议的默认端口是554,RTP及RTCP的端口由SETUP命令指定)
RTSP协议支持重定向,即将播放会话重定向,让其他服务器提供服务。协议也可选择不同的传输通道,例如基于TCP、UDP以及组播UDP传输RTP协议
RTP、RTCP、SDP
RTP是Real-time Transport Protocol的简称
RTP协议将不同编码和封装格式的音视频数据进行再封装,加上RTP头形成RTP包,再行发送,RTP包头内的重要信息包括序列号、时间戳、负载格式等。
RTP协议提供抖动补偿和数据无序到达的检测机制。
RTCP即RTP Control Protocol,协议本身并不发送数据,而是收集客户端的统计信息,包括传输字节数、传输分组数、丢失分组数、网络延迟、Jitter(抖动)等,服务器可籍此改变码率或调节数据发送速度。
Session DescriptionProtocol(会话描述协议)用于和RTSP以及SIP等协议协同工作。
SDP同样基于文本,前述RTSP协议中DESCRIBE命令的回复即是SDP格式,SDP的格式异常简单,由多个<类型>=<值>的字符串组成,用于描述会话信息,也用于描述音视频的类型和格式,所需要的带宽、时间范围甚至邮件地址、编码参数等。
允许双向交换信息,使用多达5个会话交换数据的RTSP方式流媒体传输,很像是在双向多车道的马路上奔驰,无疑很大程度上解决了交通的问题,但“成也萧何,败也萧何”,多车道对资源的占用或许就是被后来的RTMP等协议挤占的根源。
四、RTMP
RTMP(Real-Time Messaging Protocol,即实时消息传输协议)
RTMP并非一个单独协议,而是由多个相关协议组成的协议族。
1.RTMP,默认使用TCP端口1935的明文协议。
2.RTMPS,即通过TLS/SSL连接传输的RTMP。
3.RTMPE,使用Adobe私有安全机制加密的RTMP。
4.RTMPT,使用HTTP封装的RTMP、RTMPS或RTMPE,利于穿透防火墙。
5.RTMPFP,使用UDP的RTMP,允许用户进行P2P连接。
RTMP是基于TCP的可靠传输层协议,仅需一个会话即可相互通信,与RTSP协议相比,如同由轨道支撑的高速铁路,虽然形式略重,但效率高、速度快。
将音视频及其他数据封装为RTMP Message发送,而在实际传输时会进一步将Message划分为带有Message ID的Chunk。每个Chunk可以携带一个Message。但更多情况下,一个Message将由多个Chunk承载,直到客户端接收后将其还原。Chunk Stream是基于RTMP Chunk的逻辑抽象,客户端将据此区分不同类型的数据并组织接收以及还原。
BasicHeader可被扩展一到两个字节[stream id(c)],Chunk Header则含有如Message长度等信息。
建立TCP连接后,RTMP协议会要求进行3个包的握手代表连接的建立,客户端发送一个代表协议版本号的0x03初始化连接,随后发送1536个字节(包括4个字节的时间戳消息、4个值为0的字节以及1528个随机生成的字节),服务器亦将发送0x03的版本消息、1536字节消息,客户端和服务器随后发送回声字节(本方及对方的时间戳对以及1528个随机字节),并在收到后确认连接的建立.
实践中,由于只要满足了接收条件,即可建立RTMP连接,为减少交互次数,缩短连接建立时间,可以采用以下顺序:客户端发送C0和C1,服务端回复S0、S1和S2,客户端发送C2。
当握手完毕后,连接将被复用来发送一个或多个Chunk流,Chunk的默认大小为128字节,由客户端和服务器设置其可以接受的Chunk大小(可以动态调整),Chunk承载的Message类型不同,其Message Header亦有多种,不同的fmt取值将用以鉴别不同的Chunk类型。
RTMP协议定义了一些特殊的值来表示控制消息。
RTMP还定义了Command、Data、Audio、Video、Aggregate、Shared Object等多类消息,其中Command Message如下
RTMP协议支持Push和Pull两种模式,Pull即是普遍的客户端根据URL进行播放的方式,而Push基于RTMP的视频直播,其握手顺序和createStream步骤类似,由客户端使用Publish命令而非Play命令,发起自客户端到服务端的推送。
RTMP协议在进行视频服务时,对动态码率切换广告插入、播放列表、直播频道快速切换等较为无力,故而在许多解决方案中,被设计以通过SMILSMIL格式是一种描述多媒体集成的格式,常用于和RTMP协议一道构建流媒体服务,但应用范围远不限于此。的方式与服务器进行带外通信。使用SMIL进行码率切换的示例。
五、HLS、HDS、HSS
RTSP和RTMP是基于会话的流媒体协议,HLS(Http Live Streaming)、HDS(Http Dynamic Streaming)和Smooth Streaming(HSS)则是基于HTTP的协议。
HLS
协议的原理是将点播所需的多媒体文件或直播的视频流,切分成许多小块的文件,让客户端基于HTTP进行下载,当播放时,客户端需下载包含metadata信息的M3U8文件(也称作索引文件、Playlist或Manifest文件),根据M3U8文件的内容,同时依据网络条件选择不同码率的内容进行播放。
HLS支持如下音视频格式,首先是MPEG2-TS或fMP4(即Fragmented MP4)格式封装的切片文件(Segment)。其次,它支持打包的纯音频格式,包括以ADTS头封装的AAC帧、MP3、AC3和EAC3格式,对字幕,它只支持WebVTT格式
一个点播文件的M3U8示例如下
#EXTM3U、#EXT-X-TARGETDURATION等是M3U8文件规定的tag,其中包括原有的定义和由苹果扩展的tag,这个点播文件一共21s,分为3个TS的Segment。
直播的M3U8示例如下
此例中,协议希望客户端规律地访问服务器(例如7.975s访问一次)以观察是否有Segment持续被更新,而Segment的文件名也按顺序增加。
多码率的视频流的Master类型M3U8示例,描述了高、中、低三种码率的音视频流以及一路仅包含音频内容的AlternativeM3U8的访问URL
多码率HLS流的组织结构:
特点:
HLS协议的一大特点在于,将以往RTSP、RTMP等协议中实现复杂的多码率、多音轨的音视频流变得容易,并可以明晰地表达、理解和优化,在协议中规定需要传递给客户端的信息可以由Master和Alternative两种M3U8来表达。
在此设计中,客户端承担起了码率控制和选择的主要职责,每个播放器可以根据自己的网速选择合适的码率播放,并在网络环境波动或某些文件下载失败的情况下切换到其他码率,保持流畅播放,服务端则对缓存和CDN友好,毋需针对不同用户予以不同处理。
HLS协议支持在同一视频流中提供不同编码器的音频或视频流供客户端选择,于播放会话中,客户端根据自己的需求,切换码率进行下载播放。同一机制也可用于多语言的支持,对不同语言分提供不同的音轨。为支持多码率、多语言或不同Codec的切换,在节目制作时,应保证不同码率的流中,所有视频关键帧其时间戳完全对齐,否则客户端难以正确工作。
Tag功能
HLS协议中定义了许多不同的Tag以支持各类功能。例如EXT-X-DISCONTINUITY意味着后续的Segment和前面的内容并不连续,或许是Codec有所变化;EXT-X-I-FRAME-STREAM-INF可用于在Playlist中定义一个全由I帧组成的流,通常由缩略图预览使用;在直播流中,嵌入形如#EXT-X-PROGRAM-DATE-TIME:2018-0219T14:54:23.031+08:00的Tag将指明下一个Segment中第一帧对应的绝对时间,可用于估量直播流的延迟;EXT-X-DATERANGE用于指定一段时间内的特征,例如SCTE-35信息。
首先,早期的HLS流中大多使用固定长度为10s的Segment文件,但在启动时间和直播延迟上并不令人满意,现今常见的Segment长度根据不同公司的需求被设置成1~6s不等,在同一音视频流的不同码率间保持一致。
其次,为便于TS流的解析,PSI包即PAT/PMT表应插在Segment的头部,且视频的关键帧亦应置于Segment的头部,每个Segment中的视频由一个完整GOP组成是常见的做法。
苹果公司于2010年即将HLS协议提交为RFC,随后的多年中对其不断修订,添加新的功能,但正因此,使用者需要注意协议的版本,较旧的设备或客户端可能不支持某些新的功能,需要慎用。
HDS和HSS
与HLS同一时期制定的,具备相似特性(基于HTTP、支持多码率、音视频文件切片)的流媒体协议另有Adobe推出的HDS(HTTP Dynamic Streaming)和微软推出的SmoothStreaming,它们与MPEG-DASH一道,被称作AdaptiveBitrate Streaming技术(码率自适应的流媒体技术)。
HDS由Adobe自己的Flash Media Server支持,其文件格式为FLV、F4V和MP4,索引文件格式为F4M,支持直播和时移电视。
多码率、多音轨的F4M文件示例。
微软的Smooth Streaming是IIS服务器的多媒体服务扩展,支持PIFF格式的MP4文件,后缀为ISMV和ISMA,索引文件为ISM或ISMC,同样支持直播和时移电视
多码率的ISM文件示例
与服务端主导的旧式协议之间相区别,以HLS为代表的流媒体协议给予客户端极大的自由,并对Web服务器和CDN有天然的亲和性,让传输过程走向更加灵活和个性化的方向。
六、MPEG-DASH
MPEG-DASH是由MPEG牵头开发的基于HTTP的自适应码率流媒体技术,于2011年11月形成国际标准,其标准文档为ISO/IEC 23009-1。
基于HTTP的流媒体协议流行,从环境上考量,主要的原因是HTTP协议对防火墙友好,又天然适合CDN以缓存的方式分发。
鉴于互操作性的需求,私有协议终归不能成为主流,操作系统、浏览器的支持都将是促进标准化的推手,如果说之前各家推出的HLS、HDS、Smooth等协议是在用快递物流替代集中购物,那么DASH就好比快递公司接入了统一的菜鸟网络,能够以统一的方式提供服务。
协议具体内容
MPEG-DASH与前面介绍的HLS、HDS、Smooth Streaming的设计理念相近,将音视频文件或直播流分割成一系列可下载播放的文件切片,使用MPD文件描述切片信息。
MPD内有时间戳、编码、分辨率、码率等信息,对音视频内容的组织方式分为SegmentBase、SegmentTemplate、SegmentList和SegmentTimeline等类型,在客户端对MPD文件解析后,再行下载所需的文件切片,交由播放器组装并播放。
下面是不同基于HTTP的流媒体协议功能比较
DASH协议原则上可以支持任何编码格式,作为指导意见,推荐使用与HLS协议兼容的TS文件或ISO-BMFF的扩展作为多媒体文件格式(即Fragmented MP4),后者的文件后缀多见.mp4、.m4v、.m4a或.m4s。DASH所使用的MP4文件扩展来自于微软于2009年发布的PIFF文件扩展(ProtectedInteroperable File Format,如下图),这意味着SmoothStreaming协议可以MPEG-DASH协议和在音视频文件层面相互兼容。
DASH协议将对于音视频流描述的部分(也即文件头上的信息)封装为init文件并于MPD文件中提供URL,任何时候客户端均可单独下载解析,这就避免了TS文件反复插入PSI信息的消耗,客户端下载init文件后,则可任意下载切片文件播放(反之,切片将因缺少解码信息无法播放)。针对音视频,还可提供不同的init文件,增加客户端的灵活度。
DASH中的MPD符合XML格式,协议定义了大量标签以帮助描述,其中以Period定义一段连续的音视频片段,每个Period内包含多各音视频内容的集合(主要应用于多分辨率、帧率、码率或者多语言,相互可以切换)称作AdaptationSet,每个AdaptationSet内含多个Representation,即一个独立的音频或视频流,每个Representation再由一系列的多媒体Segment组成。
DASH协议在播放期间并不能随意从Representation切换,需要等到初始帧为一个关键帧的视频Segment。若AdaptationSet中各个视频流编码时是以关键帧对齐的,则可以从不同的流间进行切换。
应用
一些现代浏览器(如Chrome、Edge、Firefox、Safari等)均对W3C标准定义的MSE(MediaSource Extension,媒体源拓展)和EME(Encrypted MediaExtensions,加密媒体扩展)进行了支持,将以往由插件提供的功能收归浏览器,运用Javascript开发的网页播放器只需下载MPD文件并解析,再将音视频文件送给浏览器,就能很容易地播放。MSE和EME的详细内容可参考W3C网站:
** MSE原理**
ESE原理
除浏览器以外,Android、Chrome、Roku等多种平台上均有对MPEG-DASH的支持。在不支持DASH的平台上,亦可通过移植浏览器(Chromium,Chrome的开源版本)的方式加入视频播放功能。DASH协议为统一混乱的流媒体市场推进了一大步,但由于DASH和HLS的互不兼容,意味着为支持各类设备的全覆盖,在线视频服务商需要准备MPD和M3U8两种Manifest文件,更糟的是,需要编码fMP4和TS两份不同的音视频文件,同时,抛开研发和存储的成本,CDN将需要在所有边缘节点上存储两份视频文件,这意味着双倍的成本。
为避免上述尴尬的局面,微软、思科、苹果、Comcast等公司发起了CMAF标准(CommonMedia Application Format,通用媒体应用格式),这份标准统一了视频文件的容器格式,不论HLS,还是DASH,都可以使用同一份节目内容,在需要加密保护的场景,也可通过不同的DRM方案加密或解密同一份文件。此外,CMAF的一项新设计即对数秒长度的切片再分块传输,也对HTTP类型的流媒体协议最令人诟病的延迟问题大有裨益。
下面是CMAF的对象模型:
七、流媒体服务器
如同物流体系里物流中心的概念一样,流媒体服务器负责内容的高效分发。
虽然由于近年基于HTTP的流媒体协议大行其道,通用HTTP服务器附加流媒体协议插件的方案广泛应用,侵占了支持多协议的专用流媒体服务器的市场份额,但鉴于通用HTTP服务器和专用流媒体服务器之间对于高I/O、高并发、低延迟以及高可靠的追求高度一致,充分理解相关技术仍然对流媒体体系的搭建和优化非常重要。
流媒体服务器的功能与挑战
功能需求囊括点播和直播两类。
点播服务需要将硬盘或其他存储设备上的音视频文件转化成流媒体传输协议规定的一系列包(Packet),发送给不同的客户端。
直播服务则需要先将基于IP网络,由流媒体协议封装的音视频流导入服务器,再通过服务器转化成不同设备可以接收的流媒体封装,发送给各个客户端。
客户端支持
服务器面对的客户端多种多样,电脑上有Chrome、Edge、IE、Firefox、Opera、Safari等浏览器,也有VLC、QQ影音、暴风影音等播放器,其他设备从旧式基于嵌入式Linux或Symbian、黑莓系统的智能手机,到现代的苹果或Android设备,从Roku、FireTV、小米盒子类型的机顶盒到XBox、Play Station、Nintendo系列游戏机,从Chromecast类的无线投影设备到Oculus、Vive、HoloLens等虚拟现实、增强现实设备,各个设备上的音视频应用均是目标服务对象。
协议支持
不论点播,还是直播,由于不同的流媒体协议规定了不同的传输格式,也即对相同的音视频编码格式基础上采取了不同的封装,所以服务器主要的工作是
1、将文件转化为流媒体协议
2、流媒体协议转化为文件
3、一种流媒体协议转化为另一种流媒体协议
转化时根据文件格式和流媒体协议格式进行解包和封包(英文是Packetize和De-packetzie)
以H.264和AAC格式的音视频内容,在传输时需要封装为NAL格式和ADTS、LOAS格式,再封装到不同的协议包中,例如RTP包、TS包等,以此为单位发送或接收。
自服务器到客户端的流媒体传输,利用了前文介绍的MPEG2-TS、RTSP/RTP、RTMP、HLS、MPEG-DASH等协议。
MPEG2-TS和其他流媒体协议的不同之处在于,它只能用于主动推流的Push模式,而其他协议可能采取Pull或Push两种不同模式。
MPEG2-TS主要适用于有线电视领域,任何用户默认都是持续接收电视节目,其他协议则在设计时较多地考虑由客户端按需发起流媒体的传输连接。服务器导入直播流时,于不同的场景可以采取Pull和Push两种方式。
应用场景
流媒体服务器常见的应用位置是视频网站的源站,以及CDN服务中包括源站(Origin)、中间站(Proxy)、边缘站(Edge)在内的各级节点,构成视频分发的核心。
流媒体服务器根据所部署的位置,可以被定义成不同角色,如Publisher和Subscriber,Publisher即源站或上游站,Subscriber即下游站或边缘站,则对于直播流服务器而言,我们面对的主要问题是如何可靠和低延时地将流分发到边缘节点,对点播服务,请求边缘节点上不存在的视频会导致回源请求,而访问过的文件片段将被缓存在边缘节点以供下次访问,服务器的特殊挑战是如何高效地对缓存进行使用和管理。
专门的CDN服务商需要对服务器进行改造,实现VirtualHosting功能,其主要概念是对一台服务器进行虚拟化拆分。由于客户大小不同,对不同地域的边缘服务大半仅是零散地使用,为每个客户单独分配计算、存储和网络资源并不经济,其使用的流媒体服务器,可以根据用户请求的资源信息或Cookie分辨出其来自于哪家客户,在服务器内部的按需分配资源和计费)。
应用特点
针对于点播流:
对HTTP服务器而言,需要缓存的文件片段是基于Range请求获得的。
可以假设是某一个文件的从3000到7000字节,但于音视频文件则略有不同,由于视频关键帧概念的存在,获取或存储不完整的GOP数据并无意义,因此不论返回用户请求的内容还是在本地缓存音视频片段,都以贴近所请位置的GOP为单位较有效率,此时缓存中应有音视频片段对应的时间戳信息以便索引。
针对直播流:
因为用户可以从任意时间开始观看,为节约带宽并加快播放启动的速度,服务器应从自身持有的音视频流的队列中找到关键帧,由该处起始服务,避免发送不完整的GOP数据。
当用户在不同频道间切换时,如果音视频格式相同,流媒体服务器可以使用当前与用户之间的连接,从新频道的关键帧开始发送等方法(见图4-25),达到最佳的用户体验。
因为视频流的传输受到带宽、网络传输稳定性、客户端等待渲染等多方面限制,从编码器、源站服务器、代理服务器到边缘站服务器,以及播放器本身,每一个环节都会保持一份缓存,这有助于整个传输过程的流畅,但代价即是播放器的播放存在延迟,若在直播情况下,还将导致看到的节目系数秒乃至数十秒之前所发生的内容。服务器内部通常维护的Packet队列,可根据不同场景调整大小,在直播特有的追求低延时的场景下,该队列甚至可以被取消,即服务器收到任一Packet都会立刻处理转发。
流媒体服务器由于其流式服务的特性,对可靠性提出了极高的要求,毕竟用户偶尔访问网页失败,只需刷新重试即可获得服务,但视频播放中途失败对用户体验的打击要大得多,直播用户可能希望继续观看适才错失的片段,点播用户则预期观看进度可以被自动恢复。
较苛刻的服务器测试会构造各种模拟应用,经历7天或更长时间的播放测试,覆盖时间戳溢出,频繁播放等用例。对直播服务在高并发环境下仍要求全天候无中断的要求,服务器需支持热备份,可行的方式是预先配置多个冗余的直播流,服务器负责判断和切换,下图给出了一种直播流冗余备份方案的示意。
扩展技术
广告投放
不论点播抑或直播,对广告的动态插入均是普遍需求,根据广告投放的人群不同,其插入的位置有所不同。
对于直播服务:
例如,若将一份广告如同电视频道一样期望投放给所有用户,则首先适合在网站的编码侧直接编入直播流中,次选则是网站的直播源服务器上,替换原节目中的若干GOP,此时如广告长度和被替换的GOP不同,可以考虑对广告进行重新编码,丢弃部分帧,对整个直播节目的Timeline进行调整等手段。
如果希望可以针对不同人群投放不同广告,尤其是基于地理位置的投放,则投放可以在边缘站的流媒体服务器上进行。
对于点播服务:
对于点播服务,可行的做法是直接嵌入广告内容到实际内容之前
之后或某两个GOP之间,此时需由服务器调整Timeline[插图],保证播放的连续性。由于在已有音视频节目中嵌入广告的技术复杂性,更实用的方法是向播放器提供形成包含广告和实际节目的播放列表,将Timline的调整交由客户端完成。
录屏
针对直播服务的另一项常见需求,是用户选择对其中某个片段进行录像,以便日后回味。在流媒体服务器上开发这项功能是常见的选择,其中,与摄像采集设备一样对音视频流编码没有必要,相反,由于不论视频还是音频,各个流媒体协议定义的Packet都包含时间戳信息,对于视频有每一帧的起止信息和是否关键帧的标记,很容易将其收集并转换为视频文件。
其他
传统的流媒体服务器,除却基本用途外,还承载了许多额外功能,例如服务器文件浏览,简易的CMS(内容管理系统),循环播放,通过播放连接、时长、成功率、流量和存储占用等统计进行计费等。由于单独的流媒体服务器负责音视频内容的分发,它需要提供完整的API,令视频网站、内容导入、内容管理系统、广告服务、调度系统、用户交互系统、日志、计费等模块可以采取细粒度的控制。