|
@@ -126,6 +126,55 @@ void process_cat(struct ts *ts, uint16_t pid, uint8_t *ts_packet) {
|
126
|
126
|
}
|
127
|
127
|
}
|
128
|
128
|
|
|
129
|
+// Copied from libtsfuncs with added logic to return more than one PID
|
|
130
|
+static int find_CA_descriptor(uint8_t *data, int data_len, enum CA_system req_CA_type, uint16_t *CA_id, uint16_t *CA_pid, uint16_t *CA_pids, unsigned int *n_pids) {
|
|
131
|
+ while (data_len >= 2) {
|
|
132
|
+ uint8_t tag = data[0];
|
|
133
|
+ uint8_t this_length = data[1];
|
|
134
|
+ data += 2;
|
|
135
|
+ data_len -= 2;
|
|
136
|
+ if (tag == 9 && this_length >= 4) {
|
|
137
|
+ uint16_t CA_ID = (data[0] << 8) | data[1];
|
|
138
|
+ uint16_t CA_PID = ((data[2] & 0x1F) << 8) | data[3];
|
|
139
|
+ if (ts_get_CA_sys(CA_ID) == req_CA_type) {
|
|
140
|
+ *CA_id = CA_ID;
|
|
141
|
+ *CA_pid = CA_PID;
|
|
142
|
+ if (*n_pids < MAX_ECM_PIDS) {
|
|
143
|
+ unsigned int i, exist = 0;
|
|
144
|
+ for (i = 0; i < MAX_ECM_PIDS; i++) {
|
|
145
|
+ if (CA_pids[i] == CA_PID) {
|
|
146
|
+ exist = 1;
|
|
147
|
+ break;
|
|
148
|
+ }
|
|
149
|
+ }
|
|
150
|
+ if (!exist) {
|
|
151
|
+ CA_pids[(*n_pids)++] = CA_PID;
|
|
152
|
+ }
|
|
153
|
+ }
|
|
154
|
+ }
|
|
155
|
+ }
|
|
156
|
+ data_len -= this_length;
|
|
157
|
+ data += this_length;
|
|
158
|
+ }
|
|
159
|
+ return 0;
|
|
160
|
+}
|
|
161
|
+
|
|
162
|
+// Copied from libtsfuncs with added logic to return more than one PID
|
|
163
|
+int __ts_get_ecm_info(struct ts_pmt *pmt, enum CA_system req_CA_type, uint16_t *CA_id, uint16_t *CA_pid, uint16_t *CA_pids, unsigned int *n_pids) {
|
|
164
|
+ int i, result = find_CA_descriptor(pmt->program_info, pmt->program_info_size, req_CA_type, CA_id, CA_pid, CA_pids, n_pids);
|
|
165
|
+ if (!result) {
|
|
166
|
+ for(i=0;i<pmt->streams_num;i++) {
|
|
167
|
+ struct ts_pmt_stream *stream = pmt->streams[i];
|
|
168
|
+ if (stream->ES_info) {
|
|
169
|
+ result = find_CA_descriptor(stream->ES_info, stream->ES_info_size, req_CA_type, CA_id, CA_pid, CA_pids, n_pids);
|
|
170
|
+ if (result)
|
|
171
|
+ break;
|
|
172
|
+ }
|
|
173
|
+ }
|
|
174
|
+ }
|
|
175
|
+ return result;
|
|
176
|
+}
|
|
177
|
+
|
129
|
178
|
void process_pmt(struct ts *ts, uint16_t pid, uint8_t *ts_packet) {
|
130
|
179
|
int i;
|
131
|
180
|
if (!pid || pid != ts->pmt_pid)
|
|
@@ -156,11 +205,14 @@ void process_pmt(struct ts *ts, uint16_t pid, uint8_t *ts_packet) {
|
156
|
205
|
if (ts->camd.constant_codeword)
|
157
|
206
|
return;
|
158
|
207
|
|
|
208
|
+ ts->n_ecm_pids = 0;
|
159
|
209
|
if (ts->forced_caid) {
|
160
|
210
|
ts->ecm_caid = ts->forced_caid;
|
161
|
211
|
ts_get_ecm_info_by_caid(ts->pmt, ts->ecm_caid, &ts->ecm_pid);
|
|
212
|
+ ts->n_ecm_pids = 1; // TODO/FIXME: We should get the list of PIDS similar to how __ts_get_ecm_info does it
|
|
213
|
+ ts->ecm_pids[0] = ts->ecm_pid;
|
162
|
214
|
} else {
|
163
|
|
- ts_get_ecm_info(ts->pmt, ts->req_CA_sys, &ts->ecm_caid, &ts->ecm_pid);
|
|
215
|
+ __ts_get_ecm_info(ts->pmt, ts->req_CA_sys, &ts->ecm_caid, &ts->ecm_pid, &ts->ecm_pids[0], &ts->n_ecm_pids);
|
164
|
216
|
}
|
165
|
217
|
|
166
|
218
|
if (ts->forced_ecm_pid)
|
|
@@ -176,6 +228,11 @@ void process_pmt(struct ts *ts, uint16_t pid, uint8_t *ts_packet) {
|
176
|
228
|
ts->ecm_pid, CA_sys, ts->forced_ecm_pid);
|
177
|
229
|
ts->ecm_pid = ts->forced_ecm_pid;
|
178
|
230
|
}
|
|
231
|
+ if (ts->n_ecm_pids > 1) {
|
|
232
|
+ for (i = 0; i < (int)ts->n_ecm_pids; i++) {
|
|
233
|
+ ts_LOGf("--- | ECM pid : 0x%04x (%s) idx:%d\n", ts->ecm_pids[i], CA_sys, i);
|
|
234
|
+ }
|
|
235
|
+ }
|
179
|
236
|
} else {
|
180
|
237
|
ts_LOGf("*** | ERROR: Can't detect ECM pid.\n");
|
181
|
238
|
}
|