6 PES包格式

标准的传输流包语法如表1所述。

表1

Stream_id

'1011 1101' 标示 "private_stream_1"

PES_packet_length

data_alignment_indicator

设为1表示subtitle分段使用PES包对齐

Presentation_Time_Stamp of subtitle

PES_packet_data_byte

这些字节的编码和下面的PES_data_field保持一致

7 subtitle的PES包数据

7.1 subtitle 的PES_data_filed语法

Syntax

Size

Type

PES_data_field() {

data_identifier

8

bslbf

subtitle_stream_id

8

bslbf

while nextbits() == '0000 1111' {

Subtitling_segment()

}

end_of_PES_data_field_marker

8

bslbf

}

Data_identifier: subtitling的数据该值应该设为0x20

Subtitle_stream_id:该字段标示存储在PES中的subtitle流。Subtitling数据该值应为0x00

end_of_PES_data_field_marker: 一个8位的字段,值为: '1111 1111'.

7.2 subtitling分段的语法和语义

Subtitling流的基本语法元素是“segment”。它构成了subtitling规范中个元素的通用的格式。

Syntax

Size

Type

Subtitling_segment() {

sync_byte

8

bslbf

segment_type

8

bslbf

page_id

16

bslbf

segment_length

16

uimsbf

segment_data_field()

}

Sync_byte:值固定为'0000 1111'的8位字段,目的在于允许解码过程进行同步检测

Segment_type:该值标识了segment_data_filed包含的数据类型。表2显示了subtitling规范中定义的segment_type的值。

表2

0x10

页构成分段Page compostion segment

0x11

区域构成分段 region composition segment

0x12

CLUT 定义分段

0x13

对象数据分段 object data segment

0x40-0x7F

供未来使用

0x80-0xEF

私有数据

0xFF

填充stuffing

其他值

供未来使用

Page_id :该字段标识了subtitling_segment被包含的页。

Segment_length:该字段表示该字段后直到subtitling_segment结束的字节的数量

Segment_data_field:segment的负载。不同的分段类型语法不同。

注释:

一个subtitling显示是由最多两页的信息构成的;它们是PMT中的subtitle_descriptor中由composition_page_id和ancillary_page_id定义的。

composition_page_id标识了构成页;它至少包含了顶层数据结构的定义,即也构成分段(page_composition_segment)。这种页可能额外包含subtitling显示所需的其他段的数据。构成页中的分段可能会引用辅助页中的分段,但是它们(构成页中的分段)仅能被同一个组成页中的分段引用。

ancillary_page_id标识了一个可选的辅助页;它包含可能在不同subtitle显示中使用的分段。它不包含page_composition_segment。辅助页中的分段仅能引用该页中的分段,但是它们可以被其他(composition)页引用。因此,一个辅助页可能会包含很多不会被特殊页构成使用的分段。

7.2.1 页构成分段

Syntax

Size

Type

page_composition_segment() {

Sync_byte【0x0F】

8

bslbf

Segment_type【0x10】

8

bslbf

Page_id

16

bslbf

Segment_length

16

uimsbf

Page_time_out

8

uimsbf

Page_version_number

4

uimsbf

Page_state

2

bslbf

reserved

2

bslbf

While(processed_length < segment_length){

Region_id

8

bslbf

reserved

8

bslbf

Region_horizontal_address

16

uimsbf

Region_vertical_address

16

uimsbf

}

}

Page_time_out:以秒为单位的时间,在该时间后该page不再有效因此应该从屏幕擦除,在这之前期不应该被重新定义。Time_out计时从第一次收到page_composition_segment开始。如果有相同的版本号的相同分段再次被收到,time-out计时不应该重新计算。Time-out的目的是为了避免如果IRD碰巧丢失了page的冲定义或者删除信息而造成该page长时间存留在屏幕上的情况。IRD对time-out不需要计时的十分精确,-0/+5秒都是可以的。

Page_version_number:分段数据的版本号。该段的内容的任何变化,版本号都会增加(模16)。

Page_state:该字段表示页组合分段中和subtitling页描述相关联的内存规划的状态。Page_state的值定义在下面的表中:

表3

00

Normal case

页组合分段后跟着不完整的region集合

01

Acquisition point

页组合分段后跟着完整的region集合,描述当前的内存规划

10

Mode change

页组合分段后跟着regions,描述一个新的内存规划

11

reserved

保留

Processed_length:从该字段起包含while循环在内需要解码器处理的字节数。

Region_id: 页中唯一标识一个区域的元素。所有的region都应该按照region_vertical_address字段中的顺序排列在页组合分段中。每个region在页中都有一个唯一的ID。

region_horizontal_address: 该字段指定了region的左上角像素的水平地址。720个有效像素的最左像素的索引值为0,且像素索引从左向右递增。地址的水平地址应该小于720.

region_vertical_address: 该字段指定了region的顶行的垂直地址。720x576帧的顶行是0行,且行的索引在帧内从上到下依次增加。垂直地址的值应该小于576。

注释:

所有的像素的地址都是基于720x576扫描线的。数值和图象的长宽比无关;在16:9的显示中一个详述要比4:3的看起来宽一些。在某些情况下,对一个logo实例来说,这可能导致无法接受的变形。独立的数据可能会用来为不同的长宽比提供描述。Subtitle_descriptor表示是否一个subtitle数据流可以显示在任意的显示器上或者只能显示在特定长宽比的显示器上。

7.2.2 区域构成分段

Syntax

Size

Type

region_composition_segment() {

Sync_byte【0x0F】

8

bslbf

Stream_type【0x11】

8

bslbf

Page_id

16

bslbf

Segment_length

16

uimsbf

Region_id

8

uimsbf

Region_version_number

4

uimsbf

Region_fill_flag

1

bslbf

reserved

3

bslbf

Region_width

16

uimsbf

Region_height

16

uimsbf

Region_level_of_compatibility

3

bslbf

Region_depth

3

bslbf

reserved

2

bslbf

CLUT_id

8

bslbf

Region_8-bit_pixel_code

8

bslbf

Region_4-bit_pixel_code

4

bslbf

Region_2-bit_pixel_code

2

bslbf

reserved

2

bslbf

While(processed_length<segment_length){

Object_id

16

bslbf

Object_type

2

bslbf

Object_provider_flag

2

bslbf

Object_horiziontal_position

12

uimsbf

reserved

4

bslbf

Object_vertical_position

12

uimsbf

If(object_type ==0x01 or object_type == 0x02){

foreground_pixel_code

8

bslbf

background_pixel_code

8

bslbf

}

}

}

Region_id: 该8位字段唯一表示了一个region,该region的信息包含在这个region构成分段中。

Region_version_number:该字段指示分段数据的版本号。该分段内容的任何变化,除了lower_level_change_flag,都会使得版本号增加(模16)。

region_fill_flag: 如果设置为1,表示region中的所有object都被设置为固定的值。

region_width:表示region的宽度,水平像素的值。该字段的值应该在1到720之前,且region_width和region_horizontal_address的和不应该超过720.

region_height:表示region的高度,垂直扫描线的值。该字段的值应该在1到576之前,且region_height和region_vertical_address的和不应该超过576.

region_level_of_compatibility: 该值表示解码器解码该region所需的CLUT的最小类型

表4

0x01

2比特的CLUT条目

0x02

4比特的CLUT条目

0x03

8比特的CLUT条目

注意:其他值保留

如果解码器不支持该字段指示的CLUT类型,那么这个独立region中的像素数据不应该可见,及时其他一些需要更低的CLUT类型可能会被呈现。

Region_depth:标识该region可以使用的最大的像素深度

CLUT_id:标识供该region使用的CLUT族

region_8-bit_pixel-code:标识当region_fill_flag被设置时,供给region使用的256色的像素编码

region_4-bit_pixel-code:标识当region_fill_flag被设置时,供给region使用的16色的像素编码

region_2-bit_pixel-code:标识当region_fill_flag被设置时,供给region使用的4色的像素编码

processed_length:表示

object_id:标识region中显示的一个object

object_type:标识object的类型

表5

0x00

基本类型,位图

0x01

基本类型,字符

0x02

组合对象,字符串

0x03

保留

object_provider_flag: 一个2比特的标识,表示object的来源

表6

0x00

来自subtitling流

0x01

来自IRD的ROM

0x02

保留

0x03

保留

object_horizontal_position: 指定object的水平位置,单位为像素,相对于相关联的region的左边缘

object_vertical_position: 指定object的垂直位置,单位为扫描线,相对于相关联的region的顶部

foreground_pixel_code:标识定义字符的前景色的8_bit_pixel_code(CLUT 条目)

background_pixel_code:标识定义字符的背景色的8_bit_pixel_code(CLUT 条目)

注释:

只有4条目或16条目的CLUT的IRD通过在第九章中描述的方式查找前景色和背景色。

7.2.3 CLUT定义分段

Syntax

Size

Type

CLUT_definition_segment() {

Sync_byte【0x0f】

8

bslbf

Segment_type【0x12】

8

bslbf

Page_id

16

bslbf

Segment_length

16

uimsbf

CLUT-id

8

bslbf

CLUT_version_number

4

uimsbf

Reserved

4

bslbf

while (processed_length < segment_length) {

CLUT_entry_id

8

bslbf

2-bit/entry_CLUT_flag

1

bslbf

4-bit/entry_CLUT_flag

1

bslbf

8-bit/entry_CLUT_flag

1

bslbf

reserved

4

bslbf

Full_range_flag

1

bslbf

if (full_range_flag =='1') {

Y-value

8

bslbf

Cr-value

8

bslbf

Cb-value

8

bslbf

T-value

8

bslbf

}else{

Y-value

8

bslbf

Cr-value

4

bslbf

Cb-value

4

bslbf

T-value

2

bslbf

}

}

}

CLUT-id:唯一标识在CLUT_definition_segment中包含的CLUT组数据

CLUT_version_number:表示该分段数据的版本。该分段任何内容的修改都会引起版本号增加(模16)

Processed_length:while循环中已经被解码器处理的数据的字节数

CLUT_entry_id:指定CLUT的条目号。CLUT第一个条目号码为0。

2-bit/entry_CLUT_flag: 如果设置为‘1’,表示该CLUT值将被用于标识2-bit/entry CLUT的条目

4-bit/entry_CLUT_flag: 如果设置为‘1’,表示该CLUT值将被用于标识4-bit/entry CLUT的条目

8-bit/entry_CLUT_flag: 如果设置为‘1’,表示该CLUT值将被用于标识8-bit/entry CLUT的条目

full_range_flag: 如果设置为‘1’,表示Y_value,Cr_value,Cb_value和T_value字段为8比特方案。如果设置为‘0’,这些字段进包含最重要的比特位。

Y_value:该条目中CLUT的Y(亮度)输出值。Y_value值为0表示完全透明。这种情况下,Cr_value,Cb_value和T_value的值就没用用了,应该被设置为0。

Cr_value:该条目中CLUT的Cr(色调)输出值。

Cb_value:该条目中CLUT的Cb(饱和度)输出值。

注释1:

Y,Cr,Cb的含义定义在ITU-R文档中。

T_value:该条目中CLUT的透明度输出值。值为0表示不透明。最大值正1对应着完全透明。其他值的透明度为线性差值定义。

全透明通过Y_value设置为0值获得。

注释2:

将像素编码转换为Y,Cr,Cb和T值的解码器模型在第九章中描述。默认的CLUT内容在第十章中给出。

注释3:

所有的CLUT可以被重定义。不需要所有的CLUT固定为像第十章中给出的一样的默认内容。

7.2.4 对象数据分段

Sytax

Size

Type

object_data_segment() {

Sync_byte   【0x0F】

8

blsbf

Segment_type 【0x13】

Page_id

Segment_length

Object_id

Object_version_number

Object_coding_method

Non_modifying_colour_flag

reserved

if (object_coding_method == '00'){

top_field_data_block_length

bottom_field_data_block_length

while(processed_length<top_field_data_block_length)

pixel-data_sub-block()

while(processed_length<bottom_field_data_block_length)

pixel-data_sub-block()

if (!wordaligned())

8_stuff_bits

}

if (object_coding_method == '01') {

number of codes

for (i == 1, i <= number of codes, i ++)

character_code

}

}

object_id:标识object_data_segment中的object数据

object_version_number: 表示segment数据的版本。该分段任何内容的变化,版本号都会增加(模16)

object_coding_method:指示用于object编码的方法。

表7

0x00

像素编码

0x01

字符串编码

0x02

保留

0x03

保留

non_modifying_colour_flag: 设置为‘1’的话表示CLUT条目值‘1’是一个非修改的颜色。意味着其不应该覆盖任何底层的object。

top_field_data_block_length: 表示随后顶部区域包含的data_sub-blocks的字节数。

bottom_field_data_block_length: 表示随后底部区域包含的data_sub-blocks的字节数。

processed_length:while循环中已经被解码器处理的数据的字节数

8_stuff_bits: 8填充位,应该如‘0000 0000’一样编码。

一个object的顶部区域和底部区域的像素数据子块都应该在相同的的object_data_segment中传输。如果一个segment没有携带底部区域数据,即,bottom_field_data_block_length值为“0x0000”,这时,顶部区域的数据对底部区域来说应该也是有效的。

number_of_codes:表示字符串中编码字符的数量

character_code:表示通过定义在subtitle_descriptor中的字符表的索引来标示一个字符。每个队字符表的引用被看做是一个单独的字符编码,即使最终的字符是没有空间的。例如,浮动音标就被当做独立的字符编码。

7.2.4.1 Pixel-data sub-block

Syntax

Size

Type

pixel-data_sub-block() {

Sync_byte【0X0F】

8

bslbf

Segment_type【】

8

bslbf

Page_id

16

bslbf

Segment_length

16

uimsbf

Data_type

8

bslbf

if data_type =='0x10' {

Repeat{

2-bit/pixel_code_string()

}until (end of 2-bit/pixel_code_string)

While((!bytealigned())

2_stuff_bits

2

bslbf

}

if data_type =='0x11' {

Repeat{

4-bit/pixel_code_string()

}until (end of 4-bit/pixel_code_string)

While((!bytealigned())

4_stuff_bits

4

bslbf

}

if data_type =='0x12' {

Repeat{

4-bit/pixel_code_string()

}until (end of 4-bit/pixel_code_string)

}

if data_type =='0x20'

2_to_4-bit_map-table

16

bslbf

if data_type =='0x21'

2_to_8-bit_map-table

32

bslbf

if data_type =='0x22'

4_to_8-bit_map-table

128

bslbf

}

Data_type: 标识包含在data_sub-block中的信息的类型。

表8

0x10

2比特像素编码串

0x11

4比特像素编码串

0x12

8比特像素编码串

0x20

2_to_4比特映射表数据

0x21

2_to_8比特映射表数据

0x22

4_to_8比特映射表数据

0xF0

Object行编码结束

NOTE:其他值保留

‘0x0F’编码应该被包含在每一些列编码串之后,来表示一个object的一个扫描行。

2_to_4-bit_map-table:说明通过列出4个4比特条目如何将2bit/pixel编码映射到4bit/pixel的CLUT条目上。条目号0是第一个,3是最后一个。

2_to_8-bit_map-table:说明通过列出4个8比特条目如何将2bit/pixel编码映射到8bit/pixel的CLUT条目上。条目号0是第一个,3是最后一个。

4_to_8-bit_map-table:说明通过列出16个8比特条目如何将4bit/pixel编码映射到8bit/pixel的CLUT条目上。条目号0是第一个,15是最后一个。

2_stuff_bits: 2填充位编码为‘00’

4_stuff_bits: 4填充位编码为‘0000’

7.2.4.2 Syntax and semantics of the pixel code strings 像素编码串的语法

Syntax

Size

Type

2-bit/pixel_code_string() {

if (nextbits() != '00') {

2-bit_pixel-code

2

bslbf

} else {

2-bit_zero

2

bslbf

Switch_1

1

bslbf

if (switch_1 == '1') {

run_length_3-10

3

uimsbf

2-bit_pixel-code

2

bslbf

}else{

Switch_2

1

bslbf

if (switch_2 == '0') {

Switch_3

2

bslbf

if (switch_3 == '10') {

run_length_12-27

4

uimsbf

2-bit_pixel-code

2

bslbf

}

if (switch_3 == '11') {

run_length_29-284

8

uimsbf

2-bit_pixel-code

2

bslbf

}

}

}

}

}

2-bit_pixel-code: 一个2比特编码,表示一个像素的伪色彩是一个有四个条目的CLUT的一个条目号或者一个映射表的一个条目号

2-bit_zero: 即‘00’

switch_1:一个1比特开关,表示后面字段数据的含义

run_length_3-10: 应该被设为下面定义的伪色彩的像素数量。该值不应该小于3.

switch_2: 一个1比特开关,如果设为‘1’,表示这个像素应该被设置为伪色彩‘00’,否则其表示后面存在数据域。

switch_3: 一个2比特开关,含义如下:

表9

00

2-bit/pixel_code_string的结尾

01

两个像素应该设置为伪色彩‘00’

10

接下来的6比特包含补偿编码像素数据

11

接下来的10比特包含补偿编码像素数据

run_length_12-27: 应该被设为下面定义的伪色彩的像素数量。该值不应该小于12.

run_length_29-284:应该被设为下面定义的伪色彩的像素数量。该值不应该小于29.

Syntax

Size

Type

4-bit/pixel_code_string() {

if (nextbits() != '0000') {

4-bit_pixel-code

4

bslbf

} else {

4-bit_zero

4

bslbf

Switch_1

1

bslbf

if (switch_1 == '0') {

if (nextbits() != '000')

run_length_3-9

3

uimsbf

else

end_of_string_signal

3

bslbf

}else{

Switch_2

1

bslbf

if (switch_2 == '0') {

run_length_4-7

2

bslbf

4-bit_pixel-code

4

bslbf

}else{

switch_3

2

bslbf

if (switch_3 == '10') {

run_length_9-24

4

uimsbf

4-bit_pixel-code

4

bslbf

}

if (switch_3 == '11') {

run_length_25-280

8

uimsbf

4-bit_pixel-code

4

bslbf

}

}

}

}

}

4-bit_pixel-code:一个4比特编码,表示一个像素的伪色彩是一个有四个条目的CLUT的一个条目号或者一个映射表的一个条目号

4-bit_zero: 即‘0000’

switch_1: 一个1比特开关,表示后面字段数据的含义

run_length_3-9:应该被设为下面定义的伪色彩的像素数量。该值不应该小于3.

end_of_string_signal: 一个值为‘000’的3比特字段。该字段的出现,即nextbits() == '000'表示4-bit/pixel_code_string的结尾。

switch_2: 一个1比特开关,如果设为‘0’,表示后面的6bie包含游程编码像素数据,否则其表示后面存在数据域。

switch_3: 一个2比特开关,含义如下:

表10

00

1 pixel shall be set to pseudo-colour (entry) '0000'

01

2 pixels shall be set to pseudo-colour (entry) '0000'

10

接下来的8比特包含游程编码像素数据

11

接下来的12比特包含游程编码像素数据

run_length_9-24: 应该被设为下面定义的伪色彩的像素数量。该值不应该小于9.

run_length_25-280: 应该被设为下面定义的伪色彩的像素数量。该值不应该小于25.

Syntax

Size

Type

8-bit/pixel_code_string() {

if (nextbits() != '0000 0000') {

8-bit_pixel-code

8

bslbf

}else{

8-bit_zero

8

bslbf

switch_1

1

bslbf

if switch_1 == '0' {

if nextbits() != '000 0000'

run_length_1-127

7

uimsbf

else

end_of_string_signal

7

bslbs

}else{

run_length_3-127

7

uimsbf

8-bit_pixel-code

8

bslbf

}

}

}

8-bit_pixel-code: 一个8比特编码,表示一个像素的伪色彩,是有256个条目的CLUT中的一个条目

8-bit_zero:即‘0000 0000’

switch_1: 一个1比特开关,表示后面字段数据的含义

run_length_1-127:应该被设为下面定义的伪色彩的像素数量 '0x00'.

end_of_string_signal:一个值为‘000 0000’的3比特字段。该字段的出现,即nextbits() == '000 0000'表示8-bit/pixel_code_string的结尾。

run_length_3-127: 应该被设为下面定义的伪色彩的像素数量。该值不应该小于3.

数字视频广播字幕系统(第6.7章)相关推荐

  1. 《嵌入式系统数字视频处理权威指南》——第1章 现实世界中的视频

    本节书摘来自华章计算机<嵌入式系统数字视频处理权威指南>一书中的第1章,作者:(美)Michael Parker Suhel Dhanani 更多章节内容可以访问云栖社区"华章计 ...

  2. DTV 学习(三) 数字视频广播-DVB

    现行模拟电视,有PAL/NTSC/SECAM 三种制式,而数字电视标准,主要是美国的ATSC(Advanced television system committee)和欧洲的 DVB.在信源编码方面 ...

  3. MPEG-2 数字视频技术参考指南 (6)—— DVB数字视频广播

    转载请注明出处:http://blog.csdn.net/zhubin215130/article/details/8959335 虽然MPEG-2的PSI tables能够让解码器解译单个TS流中的 ...

  4. 数字视频内容行业调研报告 - 市场现状分析与发展前景预测

    数字视频内容市场的企业竞争态势 该报告涉及的主要国际市场参与者有Comcast.Amazon.com.Google.British Telecom.Rovi.SnagFilms.CinemaNow.C ...

  5. 数字视频监控系统开发及应用

    前言  第1章 概述  1.1 模拟视频监控现状  1.1.1 模拟视频监控系统简介  1.1.2 模拟视频监控系统存在的问题  1.2 数字视频监控系统  1.2.1 数字视频监控系统的组成  1. ...

  6. 《视频解密》中文版(第四版) 第六章 数字视频接口(第三部分)

    视频模块接口(VMI) 视频模块接口(VMI)开发用于不同多媒体IC生产商的互联.它的目标是如MPGE解码器,NTSC/PAL解码器和图像芯片的视频接口标准化. 图6.39 VMI 8比特 4:2:2 ...

  7. 《视频解密》中文版(第四版) 第七章 数字视频处理(第一部分)

    除了MPEG,NTSC/PAL和其他类型的视频编解码之外,一个典型的系统经常需要大量的其它视频处理. 由于许多消费类显示器和大部分计算机显示器是逐行(非隔行)扫描方式的,隔行扫描的视频必须转换成逐行扫 ...

  8. 音视频处理基础知识扫盲:数字视频YUV像素表示法以及视频帧和编解码概念介绍

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt+moviepy音视频剪辑实战 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一. ...

  9. 数字视频的发展从1080i到720p再到1080p

    1080i和720p同是国际认可的数字高清晰度电视标准.原NTSC国家采用的是1080i/60Hz格式,与NTSC模拟电视场频相同.而欧洲以及中国等一些原PAL制国家则采用了1080i/50Hz模式, ...

  10. MPEGl和MPEG2数字视频编码标准

    MPEGl和MPEG2数字视频编码标准(转) 2007-08-31 15:11 本文的目的在于给出有关MPEGl和MPEG2视频编码算法及标准的概述.以及它们在视频通信中的作用.论文的正文是这样安 排 ...

最新文章

  1. unity2018关联不到vs_律道|蓝月传奇VS烈焰武尊:角色扮演类游戏独创性如何认定?...
  2. R语言vtreat包的mkCrossFrameCExperiment函数交叉验证构建数据处理计划并进行模型训练、通过显著性进行变量筛选(删除相关性较强的变量)、构建多变量模型、转化为分类模型、模型评估
  3. tplink 文件服务器,tplink云存储服务器地址
  4. Docker php 环境搭建dockerfile
  5. WebRTC 的 log 系统实现分析
  6. sublime快捷操作emmet语法
  7. idea debugger console 不见了--还原 console 图标
  8. vue替换全部符合’字符串_技术成长日记-Vim实用技巧-4.7查找替换
  9. A - Giga Tower
  10. ARM上的Bootloader的具体实现1071098736
  11. tomcat 实现域名crm.test.com訪问
  12. php区块链开发游戏,php程序员如何开发区块链、以太坊、智能合约的教程
  13. Java中观察者模式与委托的对比
  14. 用计算机按余弦,知道余弦的值怎么用计算器求度数
  15. bundle adjustment算法学习
  16. 英语3500词(四)workplace主题 (2022.1.16)
  17. 利用人性弱电的互联网服务
  18. 【C语言/C++程序员编程】一小时做出来的数字雨(一颗开花的树)!
  19. 相对论【1】洛伦兹变换
  20. 北交大计算机电子信息,北京交通大学电子信息工程学院

热门文章

  1. 微信小程序_for循环
  2. 3d数字孪生工厂可视化三维建模平台
  3. 树莓派4b IO引脚输出模式异常
  4. Drools7中文教程 文档 指南
  5. 微信小程序人脸识别java_微信小程序使用face++实现人脸识别登录注册
  6. 饿了么移动 APP 的架构演进
  7. 首字母筛选 java_【Java习作】提取汉字拼音首字母(Java版)
  8. 油猴(Tampermonkey)使用教程
  9. HDB3码和AMI码通过Matlab实现编码和解码
  10. NCL做一个简单的EOF分析例子