HDMI-CEC是HDMI的控制协议,使有HDMI的设备能通过HDMI线缆进行互相控制。CEC是Consumer Electronics Control(消费者电器控制)的缩写。有了HDMI-CEC,电视,蓝光/DVD机,音箱就可以使用一个遥控器操作。同时也使One Touch Play成为可能,比如启动蓝光机就会同时启动电视和音箱。
各个厂商都有自己的HDMI-CEC,具体上层实现方式各不相同,不过都是基于HDMI-CEC的规范。每个厂商都有自己的名字,比如三星的Anynet+, 夏普的Aquos Link,索尼的BRAVIA Link/Sync, LG的SimpLink等
CEC是单线通信,有点像I2C。具体可参照官方规范
现在PC段显卡都有HDMI接口,但是90%的显卡厂商并不支持HDMI-CEC,包括著名的Nvidia和AMD。要在PC上使用CEC的话需要使用如下的USB-CEC适配器。
https://www.pulse-eight.com/p/104/usb-hdmi-cec-adapter
使用了该适配器就可以通过USB端口控制HDMICEC。该软件支持免费媒体管理软件XBMC(最新版叫Kodi)该厂商还提供USB-CEC开源库函数和相应调试软件。
博主购买了该适配器,使用了一下,发现该适配器完美支持XBMC。运行XBMC后可以用电视遥控器上的按钮控制XBMC,暂停播放多媒体文件,利用遥控器的方向键浏览菜单。见下面视频:
height="498" width="510" src="http://player.youku.com/embed/XOTE5NDEwMDQw" frameborder="0" allowfullscreen="">利用官方提供的应用libCECTray还能使CEC支持Windows的媒体中心。在libCECTray的Windows Media Center选项卡里可以自定义媒体中心里电视遥控器和电脑键盘按键的映射关系。XBMC里不能自定义按键映射,因为XBMC是内部支持的。控制媒体中心的情况见下面视频:
官方还提供了一个命令行调试程序cec-client,利用该程序可以检测CEC数据包传输或向CEC发送自定义数据包。下面分析下该调试软件的日志。日志中语句分为error,warning,notice,traffic, debug五种,分别代表错误,警告,提示,数据,调试语句。
每个数据包第一个字节是发出者接受者地址。一个设备分配一个地址,地址1半字节,可以是0到F。F代表所有设备,所以真正有效地址是0到E,所以HDMI-CEC最多支持15个设备。一般来说0设备是主设备电视。软件把CEC适配器模拟成一个recorder(录像机),分配给1地址。如果第一字节是01,就代表是电视发送给1设备(USBCEC适配器)的数据包,如果第一字节是0f,就代表是电视(0)发送给所有设备的广播。
数据包第二字节是命令码,代表了256种可能的命令。具体每个命令的含义可参考官方代码里cectypes.h 里 enum cec_opcode的定义。命令码为空的话代表轮询指令(POLL)
数据包第三字节往后是命令码的数据段,每个命令码数据段格式不同,具体可参照代码或官方HDMI CEC规范。
DEBUG: [ 22] unregistering all CEC clients
DEBUG: [ 26] Broadcast (F): osd name set to 'Broadcast'
DEBUG: [ 33] connection opened, clearing any previous input and waiting for active transmissions to end before starting
DEBUG: [ 47] communication thread started
DEBUG: [ 106] turning controlled mode on
NOTICE: [ 331] connection opened//链接打开
DEBUG: [ 335] processor thread started
DEBUG: [ 335] << Broadcast (F) -> TV (0): POLL
TRAFFIC: [ 342] << f0//发送数据包 f0, 进行轮询
DEBUG: [ 385] setting the line timeout to 3
DEBUG: [ 526] >> POLL sent
DEBUG: [ 530] TV (0): device status changed into 'present'
DEBUG: [ 535] << requesting vendor ID of 'TV' (0)
TRAFFIC: [ 539] << f0:8c//向电视请求厂商ID
TRAFFIC: [ 839] >> 0f:87:00:e0:91 //电视回复,厂商ID是00e091,厂商是LG,可参考cectypes.h中 enum cec_vendor_id
DEBUG: [ 842] >> TV (0) -> Broadcast (F): device vendor id (87)
DEBUG: [ 847] TV (0): vendor = LG (00e091)
DEBUG: [ 851] expected response received (87: device vendor id)
DEBUG: [ 857] replacing the command handler for device 'TV' (0)
DEBUG: [ 862] TV (0): CEC version 1.3a
DEBUG: [ 865] TV (0): menu language set to 'eng'
NOTICE: [ 869] registering new CEC client - v2.2.0
DEBUG: [ 873] detecting logical address for type 'recording device'
DEBUG: [ 879] trying logical address 'Recorder 1'
DEBUG: [ 884] << Recorder 1 (1) -> Recorder 1 (1): POLL
TRAFFIC: [ 888] << 11
TRAFFIC: [ 938] >> 0f:8c
DEBUG: [ 941] >> TV (0) -> Broadcast (F): give device vendor id (8C)
DEBUG: [ 1023] CEC transmission - received response - TRANSMIT_FAILED_ACK
TRAFFIC: [ 1029] << 11
DEBUG: [ 1117] CEC transmission - received response - TRANSMIT_FAILED_ACK
DEBUG: [ 1124] >> POLL not sent
DEBUG: [ 1127] using logical address 'Recorder 1'
DEBUG: [ 1131] Recorder 1 (1): device status changed into 'handled by libCEC'
DEBUG: [ 1136] Recorder 1 (1): power status changed from 'unknown' to 'on'
DEBUG: [ 1142] Recorder 1 (1): vendor = Pulse Eight (001582)
DEBUG: [ 1147]