shallen320的专栏

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,暂停播放多媒体文件,利用遥控器的方向键浏览菜单。见下面视频:

利用官方提供的应用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 clientsDEBUG: [ 26]Broadcast (F): osd name set to ‘Broadcast’DEBUG: [ 33]connection opened, clearing any previous input and waiting for active transmissions to end before startingDEBUG: [ 47]communication thread startedDEBUG: [ 106]turning controlled mode onNOTICE: [ 331]connection opened//链接打开DEBUG: [ 335]processor thread startedDEBUG: [ 335]<< Broadcast (F) -> TV (0): POLLTRAFFIC: [ 342]<< f0//发送数据包 f0, 进行轮询DEBUG: [ 385]setting the line timeout to 3DEBUG: [ 526]>> POLL sentDEBUG: [ 530]TV (0): device status changed into ‘present’DEBUG: [ 535]<< requesting vendor ID of ‘TV’ (0)TRAFFIC: [ 539]<< f0:8c//向电视请求厂商IDTRAFFIC: [ 839]>> 0f:87:00:e0:91//电视回复,厂商ID是00e091,厂商是LG,可参考cectypes.h中 enumcec_vendor_idDEBUG: [ 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.3aDEBUG: [ 865]TV (0): menu language set to ‘eng’NOTICE: [ 869]registering new CEC client – v2.2.0DEBUG: [ 873]detecting logical address for type ‘recording device’DEBUG: [ 879]trying logical address ‘Recorder 1’DEBUG: [ 884]<< Recorder 1 (1) -> Recorder 1 (1): POLLTRAFFIC: [ 888]<< 11TRAFFIC: [ 938]>> 0f:8cDEBUG: [ 941]>> TV (0) -> Broadcast (F): give device vendor id (8C)DEBUG: [ 1023]CEC transmission – received response – TRANSMIT_FAILED_ACKTRAFFIC: [ 1029]<< 11DEBUG: [ 1117]CEC transmission – received response – TRANSMIT_FAILED_ACKDEBUG: [ 1124]>> POLL not sentDEBUG: [ 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]Recorder 1 (1): CEC version 1.4DEBUG: [ 1151]CEC::CCECClient::AllocateLogicalAddresses – device ‘0’, type ‘recording device’, LA ‘1’DEBUG: [ 1180]setting ackmask to 2DEBUG: [ 1236]Recorder 1 (1): osd name set to ‘CECTester’DEBUG: [ 1242]Recorder 1 (1): menu language set to ‘eng’DEBUG: [ 1246]CEC::CUSBCECAdapterCommunication::GetPhysicalAddress – trying to get the physical address via ADLDEBUG: [ 1256]CEC::CUSBCECAdapterCommunication::GetPhysicalAddress – ADL returned physical address 0000DEBUG: [ 1264]CEC::CUSBCECAdapterCommunication::GetPhysicalAddress – trying to get the physical address via nvidia driverDEBUG: [ 1274]CEC::CUSBCECAdapterCommunication::GetPhysicalAddress – nvidia driver returned physical address 0000DEBUG: [ 1281]CEC::CUSBCECAdapterCommunication::GetPhysicalAddress – trying to get the physical address from the OSDEBUG: [ 1287]CEC::CUSBCECAdapterCommunication::GetPhysicalAddress – OS returned physical address 0000DEBUG: [ 1292]CEC::CCECClient::SetDevicePhysicalAddress – not setting invalid physical address 0000NOTICE: [ 1297]setting HDMI port to 1 on device TV (0)DEBUG: [ 1300]Recorder 1 (1): physical address changed from ffff to 1000DEBUG: [ 1303]<< Recorder 1 (1) -> broadcast (F): physical adddress 1000TRAFFIC: [ 1306]<< 1f:84:10:00:01//录像机广播物理地址1000DEBUG: [ 1542]using persisted autonomous mode setting: ‘enabled’TRAFFIC: [ 1571]>> 01:8fDEBUG: [ 1574]>> TV (0) -> Recorder 1 (1): give device power status (8F)DEBUG: [ 1580]<< Recorder 1 (1) -> TV (0): onTRAFFIC: [ 1583]<< 10:90:00DEBUG: [ 1627]using persisted CEC version setting: ‘1.4’DEBUG: [ 1664]using persisted logical address setting: ‘Recorder 1’DEBUG: [ 1759]using persisted device type setting: ‘recording device’DEBUG: [ 1807]using persisted logical address mask setting: ‘206’TRAFFIC: [ 1863]>> 01:1a:01DEBUG: [ 1867]>> TV (0) -> Recorder 1 (1): give deck status (1A)DEBUG: [ 1872]>> Recorder 1 (1): deck status changed from ‘stop’ to ‘LG other’DEBUG: [ 1880]<< Recorder 1 (1) -> TV (0): deck status ‘LG other’TRAFFIC: [ 1885]<< 10:1b:20DEBUG: [ 1929]using persisted device name setting: ‘CECTester’DEBUG: [ 2020]using persisted physical address setting: ‘1000’NOTICE: [ 2026]CEC client registered: libCEC version = 2.2.0, client version = 2.2.0, firmware version = 4, firmware build date: Thu Dec 06 11:15:20 2012 +0000, logical address(es) = Recorder 1 (1) , base device: TV (0), HDMI port number: 1, physical address: 1.0.0.0, host: Windows (x86), features: ‘P8 USB’ ‘P8 USB detect’, compiled: Oct 28 2014DEBUG: [ 2051]Recorder 1 (1): vendor = LG (00e091)DEBUG: [ 2055]replacing the command handler for device ‘Recorder 1’ (1)DEBUG: [ 2060]Recorder 1 (1): CEC version 1.3aDEBUG: [ 2062]<< Recorder 1 (1) -> TV (0): OSD name ‘CECTester’TRAFFIC: [ 2065]<< 10:47:43:45:43:54:65:73:74:65:72DEBUG: [ 2402]<< requesting power status of ‘TV’ (0)TRAFFIC: [ 2407]<< 10:8fTRAFFIC: [ 2685]>> 01:90:00DEBUG: [ 2688]>> TV (0) -> Recorder 1 (1): report power status (90)DEBUG: [ 2693]TV (0): power status changed from ‘unknown’ to ‘on’DEBUG: [ 2698]expected response received (90: report power status)TRAFFIC: [ 14015]>> 0f:36DEBUG: [ 14018]>> TV (0) -> Broadcast (F): standby (36)NOTICE: [ 14023]resetting SL initialised stateDEBUG: [ 14027]Recorder 1 (1): power status changed from ‘on’ to ‘in transition from standby to on’DEBUG: [ 14034]TV (0): power status changed from ‘on’ to ‘standby’TRAFFIC: [ 14102]>> 0f:36NOTICE: [ 14106]resetting SL initialised stateTRAFFIC: [ 14377]>> 0f:36NOTICE: [ 14381]resetting SL initialised stateTRAFFIC: [ 14471]>> 0f:36NOTICE: [ 14475]resetting SL initialised stateTRAFFIC: [ 24969]>> 0f:87:00:e0:91DEBUG: [ 24971]>> TV (0) -> Broadcast (F): device vendor id (87)DEBUG: [ 24974]<< Recorder 1 (1) -> Broadcast (F): vendor id LG (e091)TRAFFIC: [ 24977]<< 1f:87:00:e0:91TRAFFIC: [ 38531]>> 0f:87:00:e0:91DEBUG: [ 38535]>> TV (0) -> Broadcast (F): device vendor id (87)DEBUG: [ 38540]<< Recorder 1 (1) -> Broadcast (F): vendor id LG (e091)TRAFFIC: [ 38545]<< 1f:87:00:e0:91TRAFFIC: [ 38766]>> 0f:87:00:e0:91DEBUG: [ 38770]>> TV (0) -> Broadcast (F): device vendor id (87)DEBUG: [ 38775]<< Recorder 1 (1) -> Broadcast (F): vendor id LG (e091)TRAFFIC: [ 38780]<< 1f:87:00:e0:91TRAFFIC: [ 39036]>> 0f:87:00:e0:91DEBUG: [ 39040]>> TV (0) -> Broadcast (F): device vendor id (87)DEBUG: [ 39045]<< Recorder 1 (1) -> Broadcast (F): vendor id LG (e091)TRAFFIC: [ 39051]<< 1f:87:00:e0:91TRAFFIC: [ 39256]>> 01DEBUG: [ 39259]<< POLL: TV (0) -> Recorder 1 (1)TRAFFIC: [ 39339]>> 01:8cDEBUG: [ 39342]>> TV (0) -> Recorder 1 (1): give device vendor id (8C)DEBUG: [ 39348]<< Recorder 1 (1) -> TV (0): vendor id LG (e091)TRAFFIC: [ 39353]<< 1f:87:00:e0:91TRAFFIC: [ 39406]>> 01:89:0bDEBUG: [ 39409]>> TV (0) -> Recorder 1 (1): vendor command (89)DEBUG: [ 39414]sending abort with opcode 89 and reason ‘invalid operand’ to TVDEBUG: [ 39420]<< transmitting abort messageTRAFFIC: [ 39424]<< 10:00:89:03NOTICE: [ 39442]Unmapped code detected. Please send an email to support@pulse-eight.com with the following details, and if you pressed a key, tell us which one you pressed, and we’ll add support for this it.CEC command: >> 01:89:0bVendor ID: LG (00e091)TRAFFIC: [ 39921]>> 01:89:0bDEBUG: [ 39925]>> TV (0) -> Recorder 1 (1): vendor command (89)DEBUG: [ 39930]sending abort with opcode 89 and reason ‘invalid operand’ to TVDEBUG: [ 39936]<< transmitting abort messageTRAFFIC: [ 39940]<< 10:00:89:03TRAFFIC: [ 40374]>> 01:89:01DEBUG: [ 40377]>> TV (0) -> Recorder 1 (1): vendor command (89)DEBUG: [ 40382]Recorder 1 (1): power status changed from ‘in transition from standby to on’ to ‘standby’DEBUG: [ 40390]<< Recorder 1 (1) -> TV (0): standbyTRAFFIC: [ 40394]<< 10:90:01TRAFFIC: [ 40429]<< 10:89:02:05NOTICE: [ 40433]SL initialisedTRAFFIC: [ 40748]>> 01:8fDEBUG: [ 40751]>> TV (0) -> Recorder 1 (1): give device power status (8F)DEBUG: [ 40757]<< Recorder 1 (1) -> TV (0): standbyTRAFFIC: [ 40761]<< 10:90:01DEBUG: [ 40803]Recorder 1 (1): power status changed from ‘standby’ to ‘on’TRAFFIC: [ 41000]>> 01:46DEBUG: [ 41004]>> TV (0) -> Recorder 1 (1): give osd name (46)DEBUG: [ 41009]<< Recorder 1 (1) -> TV (0): OSD name ‘CECTester’TRAFFIC: [ 41014]<< 10:47:43:45:43:54:65:73:74:65:72TRAFFIC: [ 41426]>> 01:83DEBUG: [ 41429]>> TV (0) -> Recorder 1 (1): give physical address (83)DEBUG: [ 41435]<< Recorder 1 (1) -> broadcast (F): physical adddress 1000TRAFFIC: [ 41440]<< 1f:84:10:00:01TRAFFIC: [ 41701]>> 02DEBUG: [ 41704]<< POLL: TV (0) -> Recorder 2 (2)//电视隔一定时间轮询设备2TRAFFIC: [ 41802]>> 02DEBUG: [ 41805]<< POLL: TV (0) -> Recorder 2 (2)TRAFFIC: [ 41846]>> 04DEBUG: [ 41849]<< POLL: TV (0) -> Playback 1 (4)//电视隔一定时间轮询设备4TRAFFIC: [ 41890]>> 04DEBUG: [ 41893]<< POLL: TV (0) -> Playback 1 (4)TRAFFIC: [ 41933]>> 05DEBUG: [ 41936]<< POLL: TV (0) -> Audio (5)//电视隔一定时间轮询设备5TRAFFIC: [ 41940]>> 05DEBUG: [ 41942]<< POLL: TV (0) -> Audio (5)TRAFFIC: [ 41988]>> 08DEBUG: [ 41991]<< POLL: TV (0) -> Playback 2 (8)//电视隔一定时间轮询设备8TRAFFIC: [ 42043]>> 08DEBUG: [ 42046]<< POLL: TV (0) -> Playback 2 (8)TRAFFIC: [ 42098]>> 09DEBUG: [ 42101]<< POLL: TV (0) -> Recorder 3 (9)//电视隔一定时间轮询设备9TRAFFIC: [ 42151]>> 09DEBUG: [ 42154]<< POLL: TV (0) -> Recorder 3 (9)TRAFFIC: [ 42195]>> 0aDEBUG: [ 42197]<< POLL: TV (0) -> Tuner 4 (a)//电视隔一定时间轮询设备aTRAFFIC: [ 42238]>> 0aDEBUG: [ 42241]<< POLL: TV (0) -> Tuner 4 (a)TRAFFIC: [ 42282]>> 0bDEBUG: [ 42285]<< POLL: TV (0) -> Playback 3 (b)//电视隔一定时间轮询设备bTRAFFIC: [ 42289]>> 0bDEBUG: [ 42291]<< POLL: TV (0) -> Playback 3 (b).

.

.

.

所有的失败,与失去自己的失败比起来,更是微不足道

shallen320的专栏

相关文章:

你感兴趣的文章:

标签云: