[videodb] remove unused seasons table from episode_view
[xbmc.git] / xbmc / cores / AudioEngine / Utils / AEELDParser.cpp
blobf7d3043d5e583f479edaa7fbb8f983b96bd04c74
1 /*
2 * Copyright (C) 2012-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "AEELDParser.h"
11 #include "AEDeviceInfo.h"
12 #include "utils/EndianSwap.h"
14 #include <algorithm>
15 #include <functional>
16 #include <stdio.h>
17 #include <string.h>
19 #define GRAB_BITS(buf, byte, lowbit, bits) ((buf[byte] >> (lowbit)) & ((1 << (bits)) - 1))
21 typedef struct
23 uint8_t eld_ver;
24 uint8_t baseline_eid_len;
25 uint8_t cea_edid_ver;
26 uint8_t monitor_name_length;
27 uint8_t sad_count;
28 uint8_t conn_type;
29 bool s_ai;
30 bool hdcp;
31 uint8_t audio_sync_delay;
32 bool rlrc; /* rear left and right of center */
33 bool flrc; /* front left and right of center */
34 bool rc; /* rear center */
35 bool rlr; /* rear left and right */
36 bool fc; /* front center */
37 bool lfe; /* LFE */
38 bool flr; /* front left and right */
39 uint64_t port_id;
40 char mfg_name[4];
41 uint16_t product_code;
42 std::string monitor_name;
43 } ELDHeader;
45 #define ELD_VER_CEA_816D 2
46 #define ELD_VER_PARTIAL 31
48 #define ELD_EDID_VER_NONE 0
49 #define ELD_EDID_VER_CEA_861 1
50 #define ELD_EDID_VER_CEA_861_A 2
51 #define ELD_EDID_VER_CEA_861_BCD 3
53 #define ELD_CONN_TYPE_HDMI 0
54 #define ELD_CONN_TYPE_DP 1
55 #define ELD_CONN_TYPE_RESERVED1 2
56 #define ELD_CONN_TYPE_RESERVED2 3
58 #define CEA_861_FORMAT_RESERVED1 0
59 #define CEA_861_FORMAT_LPCM 1
60 #define CEA_861_FORMAT_AC3 2
61 #define CEA_861_FORMAT_MPEG1 3
62 #define CEA_861_FORMAT_MP3 4
63 #define CEA_861_FORMAT_MPEG2 5
64 #define CEA_861_FORMAT_AAC 6
65 #define CEA_861_FORMAT_DTS 7
66 #define CEA_861_FORMAT_ATRAC 8
67 #define CEA_861_FORMAT_SACD 9
68 #define CEA_861_FORMAT_EAC3 10
69 #define CEA_861_FORMAT_DTSHD 11
70 #define CEA_861_FORMAT_MLP 12
71 #define CEA_861_FORMAT_DST 13
72 #define CEA_861_FORMAT_WMAPRO 14
73 #define CEA_861_FORMAT_RESERVED2 15
75 void CAEELDParser::Parse(const uint8_t *data, size_t length, CAEDeviceInfo& info)
77 ELDHeader header;
78 header.eld_ver = (data[0 ] & 0xF8) >> 3;
79 if (header.eld_ver != ELD_VER_CEA_816D && header.eld_ver != ELD_VER_PARTIAL)
80 return;
82 header.baseline_eid_len = data[2 ];
83 header.cea_edid_ver = (data[4 ] & 0xE0) >> 5;
84 header.monitor_name_length = data[4 ] & 0x1F;
85 header.sad_count = (data[5 ] & 0xF0) >> 4;
86 header.conn_type = (data[5 ] & 0x0C) >> 2;
87 header.s_ai = (data[5 ] & 0x02) == 0x02;
88 header.hdcp = (data[5 ] & 0x01) == 0x01;
89 header.audio_sync_delay = data[6 ];
90 header.rlrc = (data[7 ] & 0x40) == 0x40;
91 header.flrc = (data[7 ] & 0x20) == 0x20;
92 header.rc = (data[7 ] & 0x10) == 0x10;
93 header.rlr = (data[7 ] & 0x08) == 0x08;
94 header.fc = (data[7 ] & 0x04) == 0x04;
95 header.lfe = (data[7 ] & 0x02) == 0x02;
96 header.flr = (data[7 ] & 0x01) == 0x01;
97 header.port_id = Endian_SwapLE64(*((const uint64_t*)(data + 8)));
98 header.mfg_name[0] = 'A' + ((data[16] >> 2) & 0x1F) - 1;
99 header.mfg_name[1] = 'A' + (((data[16] << 3) | (data[17] >> 5)) & 0x1F) - 1;
100 header.mfg_name[2] = 'A' + (data[17] & 0x1F) - 1;
101 header.mfg_name[3] = '\0';
102 header.product_code = Endian_SwapLE16(*((const uint16_t*)(data + 18)));
104 switch (header.conn_type)
106 case ELD_CONN_TYPE_HDMI: info.m_deviceType = AE_DEVTYPE_HDMI; break;
107 case ELD_CONN_TYPE_DP : info.m_deviceType = AE_DEVTYPE_DP ; break;
110 info.m_displayNameExtra = header.mfg_name;
111 if (header.monitor_name_length <= 16)
113 header.monitor_name.assign((const char *)(data + 20), header.monitor_name_length);
114 header.monitor_name.erase(std::find_if(header.monitor_name.rbegin(), header.monitor_name.rend(),
115 [](char c) { return !std::isspace(c); })
116 .base(),
117 header.monitor_name.end());
118 if (header.monitor_name.length() > 0)
120 info.m_displayNameExtra.append(" ");
121 info.m_displayNameExtra.append(header.monitor_name);
122 if (header.conn_type == ELD_CONN_TYPE_HDMI)
123 info.m_displayNameExtra.append(" on HDMI" );
124 else
125 info.m_displayNameExtra.append(" on DisplayPort");
129 if (header.flr)
131 if (!info.m_channels.HasChannel(AE_CH_FL))
132 info.m_channels += AE_CH_FL;
133 if (!info.m_channels.HasChannel(AE_CH_FR))
134 info.m_channels += AE_CH_FR;
137 if (header.lfe)
138 if (!info.m_channels.HasChannel(AE_CH_LFE))
139 info.m_channels += AE_CH_LFE;
141 if (header.fc)
142 if (!info.m_channels.HasChannel(AE_CH_FC))
143 info.m_channels += AE_CH_FC;
145 if (header.rlr)
147 if (!info.m_channels.HasChannel(AE_CH_BL))
148 info.m_channels += AE_CH_BL;
149 if (!info.m_channels.HasChannel(AE_CH_BR))
150 info.m_channels += AE_CH_BR;
153 if (header.rc)
154 if (!info.m_channels.HasChannel(AE_CH_BC))
155 info.m_channels += AE_CH_BC;
157 if (header.flrc)
159 if (!info.m_channels.HasChannel(AE_CH_FLOC))
160 info.m_channels += AE_CH_FLOC;
161 if (!info.m_channels.HasChannel(AE_CH_FROC))
162 info.m_channels += AE_CH_FROC;
165 if (header.rlrc)
167 if (!info.m_channels.HasChannel(AE_CH_BLOC))
168 info.m_channels += AE_CH_BLOC;
169 if (!info.m_channels.HasChannel(AE_CH_BROC))
170 info.m_channels += AE_CH_BROC;
173 const uint8_t *sad = data + 20 + header.monitor_name_length;
174 for(uint8_t i = 0; i < header.sad_count; ++i)
176 uint8_t offset = i * 3;
177 uint8_t formatCode = (sad[offset + 0] >> 3) & 0xF;
178 //uint8_t channelCount = (sad[offset + 0] & 0x7) + 1;
179 //uint8_t sampleRates = sad[offset + 1];
181 AEDataFormat fmt = AE_FMT_INVALID;
182 switch (formatCode)
184 //! @todo implement
185 case CEA_861_FORMAT_AC3 : fmt = AE_FMT_RAW ; break;
186 case CEA_861_FORMAT_DTS : fmt = AE_FMT_RAW ; break;
187 case CEA_861_FORMAT_DTSHD: fmt = AE_FMT_RAW ; break;
188 case CEA_861_FORMAT_EAC3 : fmt = AE_FMT_RAW ; break;
189 case CEA_861_FORMAT_LPCM : fmt = AE_FMT_RAW ; break;
190 case CEA_861_FORMAT_MLP : fmt = AE_FMT_RAW; break;
193 if (fmt == AE_FMT_INVALID)
194 continue;
196 if (std::find(info.m_dataFormats.begin(), info.m_dataFormats.end(), fmt) == info.m_dataFormats.end())
197 info.m_dataFormats.push_back(fmt);