/src/vlc/contrib/contrib-build/libdvbpsi/src/dvbpsi.c
Line | Count | Source |
1 | | /***************************************************************************** |
2 | | * dvbpsi.c: conversion from TS packets to PSI sections |
3 | | *---------------------------------------------------------------------------- |
4 | | * Copyright (C) 2001-2012 VideoLAN |
5 | | * $Id$ |
6 | | * |
7 | | * Authors: Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr> |
8 | | * Jean-Paul Saman <jpsaman@videolan.org> |
9 | | * |
10 | | * This library is free software; you can redistribute it and/or |
11 | | * modify it under the terms of the GNU Lesser General Public |
12 | | * License as published by the Free Software Foundation; either |
13 | | * version 2.1 of the License, or (at your option) any later version. |
14 | | * |
15 | | * This library is distributed in the hope that it will be useful, |
16 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
18 | | * Lesser General Public License for more details. |
19 | | * |
20 | | * You should have received a copy of the GNU Lesser General Public |
21 | | * License along with this library; if not, write to the Free Software |
22 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
23 | | * |
24 | | *---------------------------------------------------------------------------- |
25 | | * |
26 | | *****************************************************************************/ |
27 | | |
28 | | #include "config.h" |
29 | | |
30 | | #include <string.h> |
31 | | #include <stdio.h> |
32 | | #include <stdarg.h> |
33 | | #include <stdlib.h> |
34 | | #include <stdbool.h> |
35 | | |
36 | | #if defined(HAVE_INTTYPES_H) |
37 | | #include <inttypes.h> |
38 | | #elif defined(HAVE_STDINT_H) |
39 | | #include <stdint.h> |
40 | | #endif |
41 | | |
42 | | #include <assert.h> |
43 | | |
44 | | #include "dvbpsi.h" |
45 | | #include "dvbpsi_private.h" |
46 | | #include "psi.h" |
47 | | |
48 | | /***************************************************************************** |
49 | | * dvbpsi_new |
50 | | *****************************************************************************/ |
51 | | dvbpsi_t *dvbpsi_new(dvbpsi_message_cb callback, enum dvbpsi_msg_level level) |
52 | 93.8k | { |
53 | 93.8k | dvbpsi_t *p_dvbpsi = calloc(1, sizeof(dvbpsi_t)); |
54 | 93.8k | if (p_dvbpsi == NULL) |
55 | 0 | return NULL; |
56 | | |
57 | 93.8k | p_dvbpsi->p_decoder = NULL; |
58 | 93.8k | p_dvbpsi->pf_message = callback; |
59 | 93.8k | p_dvbpsi->i_msg_level = level; |
60 | 93.8k | return p_dvbpsi; |
61 | 93.8k | } |
62 | | |
63 | | /***************************************************************************** |
64 | | * dvbpsi_delete |
65 | | *****************************************************************************/ |
66 | | void dvbpsi_delete(dvbpsi_t *p_dvbpsi) |
67 | 93.8k | { |
68 | 93.8k | if (p_dvbpsi) { |
69 | 93.8k | assert(p_dvbpsi->p_decoder == NULL); |
70 | 93.8k | p_dvbpsi->pf_message = NULL; |
71 | 93.8k | } |
72 | 93.8k | free(p_dvbpsi); |
73 | 93.8k | } |
74 | | |
75 | | /***************************************************************************** |
76 | | * dvbpsi_decoder_new |
77 | | *****************************************************************************/ |
78 | 955k | #define DVBPSI_INVALID_CC (0xFF) |
79 | | void *dvbpsi_decoder_new(dvbpsi_callback_gather_t pf_gather, |
80 | | const int i_section_max_size, const bool b_discontinuity, const size_t psi_size) |
81 | 93.8k | { |
82 | 93.8k | assert(psi_size >= sizeof(dvbpsi_decoder_t)); |
83 | | |
84 | 93.8k | dvbpsi_decoder_t *p_decoder = (dvbpsi_decoder_t *) calloc(1, psi_size); |
85 | 93.8k | if (p_decoder == NULL) |
86 | 0 | return NULL; |
87 | | |
88 | 93.8k | memcpy(&p_decoder->i_magic[0], "psi", 3); |
89 | 93.8k | p_decoder->pf_gather = pf_gather; |
90 | 93.8k | p_decoder->p_current_section = NULL; |
91 | 93.8k | p_decoder->i_section_max_size = i_section_max_size; |
92 | 93.8k | p_decoder->b_discontinuity = b_discontinuity; |
93 | 93.8k | p_decoder->i_continuity_counter = DVBPSI_INVALID_CC; |
94 | 93.8k | p_decoder->prevpacket[0] = 0; |
95 | 93.8k | p_decoder->p_current_section = NULL; |
96 | 93.8k | p_decoder->b_current_valid = false; |
97 | | |
98 | 93.8k | p_decoder->i_last_section_number = 0; |
99 | 93.8k | p_decoder->p_sections = NULL; |
100 | 93.8k | p_decoder->b_complete_header = false; |
101 | | |
102 | 93.8k | return p_decoder; |
103 | 93.8k | } |
104 | | |
105 | | /***************************************************************************** |
106 | | * dvbpsi_decoder_reset |
107 | | *****************************************************************************/ |
108 | | void dvbpsi_decoder_reset(dvbpsi_decoder_t* p_decoder, const bool b_force) |
109 | 403k | { |
110 | 403k | assert(p_decoder); |
111 | | |
112 | | /* Force redecoding */ |
113 | 403k | if (b_force) |
114 | 144k | p_decoder->b_current_valid = false; |
115 | | |
116 | 403k | p_decoder->i_continuity_counter = DVBPSI_INVALID_CC; |
117 | 403k | p_decoder->prevpacket[0] = 0; |
118 | | |
119 | | /* Clear the section array */ |
120 | 403k | dvbpsi_DeletePSISections(p_decoder->p_sections); |
121 | 403k | p_decoder->p_sections = NULL; |
122 | 403k | } |
123 | | |
124 | | /***************************************************************************** |
125 | | * dvbpsi_decoder_psi_sections_completed |
126 | | *****************************************************************************/ |
127 | | bool dvbpsi_decoder_psi_sections_completed(dvbpsi_decoder_t* p_decoder) |
128 | 259k | { |
129 | 259k | assert(p_decoder); |
130 | | |
131 | 259k | bool b_complete = false; |
132 | | |
133 | 259k | dvbpsi_psi_section_t *p = p_decoder->p_sections; |
134 | 259k | unsigned int prev_nr = 0; |
135 | 518k | while (p) |
136 | 259k | { |
137 | 259k | assert(prev_nr < 256); |
138 | 259k | if (prev_nr != p->i_number) |
139 | 178 | break; |
140 | 259k | if (p_decoder->i_last_section_number == p->i_number) |
141 | 259k | b_complete = true; |
142 | 259k | p = p->p_next; |
143 | 259k | prev_nr++; |
144 | 259k | } |
145 | | |
146 | 259k | return b_complete; |
147 | 259k | } |
148 | | |
149 | | /***************************************************************************** |
150 | | * dvbpsi_decoder_psi_section_add |
151 | | *****************************************************************************/ |
152 | | bool dvbpsi_decoder_psi_section_add(dvbpsi_decoder_t *p_decoder, dvbpsi_psi_section_t *p_section) |
153 | 261k | { |
154 | 261k | assert(p_decoder); |
155 | 261k | assert(p_section); |
156 | 261k | assert(p_section->p_next == NULL); |
157 | | |
158 | | /* Empty list */ |
159 | 261k | if (!p_decoder->p_sections) |
160 | 260k | { |
161 | 260k | p_decoder->p_sections = p_section; |
162 | 260k | p_section->p_next = NULL; |
163 | 260k | return false; |
164 | 260k | } |
165 | | |
166 | | /* Insert in right place */ |
167 | 426 | dvbpsi_psi_section_t *p = p_decoder->p_sections; |
168 | 426 | dvbpsi_psi_section_t *p_prev = NULL; |
169 | 426 | bool b_overwrite = false; |
170 | | |
171 | 429 | while (p) |
172 | 426 | { |
173 | 426 | if (p->i_number == p_section->i_number) |
174 | 397 | { |
175 | | /* Replace */ |
176 | 397 | if (p_prev) |
177 | 0 | { |
178 | 0 | p_prev->p_next = p_section; |
179 | 0 | p_section->p_next = p->p_next; |
180 | 0 | p->p_next = NULL; |
181 | 0 | dvbpsi_DeletePSISections(p); |
182 | 0 | b_overwrite = true; |
183 | 0 | } |
184 | 397 | else |
185 | 397 | { |
186 | 397 | p_section->p_next = p->p_next; |
187 | 397 | p->p_next = NULL; |
188 | 397 | dvbpsi_DeletePSISections(p); |
189 | 397 | p = p_section; |
190 | 397 | p_decoder->p_sections = p; |
191 | 397 | b_overwrite = true; |
192 | 397 | } |
193 | 397 | goto out; |
194 | 397 | } |
195 | 29 | else if (p->i_number > p_section->i_number) |
196 | 26 | { |
197 | | /* Insert before p */ |
198 | 26 | if (p_prev) |
199 | 0 | { |
200 | 0 | p_prev->p_next = p_section; |
201 | 0 | p_section->p_next = p; |
202 | 0 | } |
203 | 26 | else |
204 | 26 | { |
205 | 26 | p_section->p_next = p; |
206 | 26 | p_decoder->p_sections = p_section; |
207 | 26 | } |
208 | 26 | goto out; |
209 | 26 | } |
210 | | |
211 | 3 | p_prev = p; |
212 | 3 | p = p->p_next; |
213 | 3 | } |
214 | | |
215 | | /* Add to end of list */ |
216 | 3 | if (p_prev->i_number < p_section->i_number) |
217 | 3 | { |
218 | 3 | p_decoder->i_last_section_number = p_section->i_last_number; |
219 | 3 | p_prev->p_next = p_section; |
220 | 3 | p_section->p_next = NULL; |
221 | 3 | } |
222 | | |
223 | 426 | out: |
224 | 426 | return b_overwrite; |
225 | 3 | } |
226 | | |
227 | | /***************************************************************************** |
228 | | * dvbpsi_decoder_delete |
229 | | *****************************************************************************/ |
230 | | void dvbpsi_decoder_delete(dvbpsi_decoder_t *p_decoder) |
231 | 93.8k | { |
232 | 93.8k | assert(p_decoder); |
233 | | |
234 | 93.8k | if (p_decoder->p_sections) |
235 | 174 | { |
236 | 174 | dvbpsi_DeletePSISections(p_decoder->p_sections); |
237 | 174 | p_decoder->p_sections = NULL; |
238 | 174 | } |
239 | | |
240 | 93.8k | dvbpsi_DeletePSISections(p_decoder->p_current_section); |
241 | 93.8k | free(p_decoder); |
242 | 93.8k | } |
243 | | |
244 | | /***************************************************************************** |
245 | | * dvbpsi_decoder_present |
246 | | *****************************************************************************/ |
247 | | bool dvbpsi_decoder_present(dvbpsi_t *p_dvbpsi) |
248 | 148k | { |
249 | 148k | if (p_dvbpsi && p_dvbpsi->p_decoder) |
250 | 133k | return true; |
251 | 14.3k | else |
252 | 14.3k | return false; |
253 | 148k | } |
254 | | |
255 | | /***************************************************************************** |
256 | | * dvbpsi_packet_push |
257 | | ***************************************************************************** |
258 | | * Injection of a TS packet into a PSI decoder. |
259 | | *****************************************************************************/ |
260 | | bool dvbpsi_packet_push(dvbpsi_t *p_dvbpsi, uint8_t* p_data) |
261 | 458k | { |
262 | 458k | uint8_t i_expected_counter; /* Expected continuity counter */ |
263 | 458k | dvbpsi_psi_section_t* p_section; /* Current section */ |
264 | 458k | uint8_t* p_payload_pos; /* Where in the TS packet */ |
265 | 458k | uint8_t* p_new_pos = NULL; /* Beginning of the new section, |
266 | | updated to NULL when the new |
267 | | section is handled */ |
268 | 458k | int i_available; /* Byte count available in the |
269 | | packet */ |
270 | 458k | const uint8_t *p_data_end = &p_data[188]; /* end of packet */ |
271 | | |
272 | 458k | dvbpsi_decoder_t *p_decoder = p_dvbpsi->p_decoder; |
273 | 458k | assert(p_decoder); |
274 | | |
275 | | /* TS start code */ |
276 | 458k | if (p_data[0] != 0x47) |
277 | 0 | { |
278 | 0 | dvbpsi_error(p_dvbpsi, "PSI decoder", "not a TS packet"); |
279 | 0 | return false; |
280 | 0 | } |
281 | | |
282 | | /* Continuity check */ |
283 | 458k | bool b_first = (p_decoder->i_continuity_counter == DVBPSI_INVALID_CC); |
284 | 458k | if (b_first) |
285 | 256k | p_decoder->i_continuity_counter = p_data[3] & 0xf; |
286 | 201k | else |
287 | 201k | { |
288 | 201k | i_expected_counter = (p_decoder->i_continuity_counter + 1) & 0xf; |
289 | 201k | p_decoder->i_continuity_counter = p_data[3] & 0xf; |
290 | | |
291 | 201k | if (i_expected_counter == ((p_decoder->i_continuity_counter + 1) & 0xf) |
292 | 162k | && !p_decoder->b_discontinuity) |
293 | 123k | { |
294 | 123k | if(!memcmp(p_decoder->prevpacket, p_data, 188)) |
295 | 49.1k | { |
296 | 49.1k | dvbpsi_debug(p_dvbpsi, "PSI decoder", |
297 | 49.1k | "TS duplicate (received %d, expected %d) for PID %d", |
298 | 49.1k | p_decoder->i_continuity_counter, i_expected_counter, |
299 | 49.1k | ((uint16_t)(p_data[1] & 0x1f) << 8) | p_data[2]); |
300 | 49.1k | return false; |
301 | 49.1k | } |
302 | 74.6k | else /* Fake duplicate */ |
303 | 74.6k | { |
304 | | /* force discontinuity */ |
305 | 74.6k | i_expected_counter = p_decoder->i_continuity_counter + 1; |
306 | 74.6k | } |
307 | 123k | } |
308 | | |
309 | 152k | if (i_expected_counter != p_decoder->i_continuity_counter) |
310 | 133k | { |
311 | 133k | dvbpsi_error(p_dvbpsi, "PSI decoder", |
312 | 133k | "TS discontinuity (received %d, expected %d) for PID %d", |
313 | 133k | p_decoder->i_continuity_counter, i_expected_counter, |
314 | 133k | ((uint16_t)(p_data[1] & 0x1f) << 8) | p_data[2]); |
315 | 133k | p_decoder->b_discontinuity = true; |
316 | 133k | if (p_decoder->p_current_section) |
317 | 48.1k | { |
318 | 48.1k | dvbpsi_DeletePSISections(p_decoder->p_current_section); |
319 | 48.1k | p_decoder->p_current_section = NULL; |
320 | 48.1k | } |
321 | 133k | } |
322 | 152k | } |
323 | | |
324 | 409k | memcpy(p_decoder->prevpacket, p_data, 188); |
325 | | |
326 | | /* Return if no payload in the TS packet */ |
327 | 409k | if (!(p_data[3] & 0x10)) |
328 | 73 | return false; |
329 | | |
330 | | /* Skip the adaptation_field if present */ |
331 | 409k | if (p_data[3] & 0x20) |
332 | 25.9k | { |
333 | 25.9k | p_payload_pos = p_data + 5 + p_data[4]; |
334 | 25.9k | if(p_payload_pos >= p_data_end) |
335 | 1 | return false; |
336 | 25.9k | } |
337 | 383k | else |
338 | 383k | p_payload_pos = p_data + 4; |
339 | | |
340 | | /* Unit start -> skip the pointer_field and a new section begins */ |
341 | 409k | if (p_data[1] & 0x40) |
342 | 399k | { |
343 | 399k | p_new_pos = p_payload_pos + *p_payload_pos + 1; |
344 | 399k | p_payload_pos += 1; |
345 | 399k | if(p_payload_pos >= p_data_end || p_new_pos >= p_data_end) |
346 | 1.20k | return false; |
347 | 399k | } |
348 | | |
349 | 408k | p_section = p_decoder->p_current_section; |
350 | | |
351 | | /* If the psi decoder needs a beginning of a section and a new section |
352 | | begins in the packet then initialize the dvbpsi_psi_section_t structure */ |
353 | 408k | if (p_section == NULL) |
354 | 378k | { |
355 | 378k | if (p_new_pos) |
356 | 375k | { |
357 | | /* Allocation of the structure */ |
358 | 375k | p_decoder->p_current_section |
359 | 375k | = p_section |
360 | 375k | = dvbpsi_NewPSISection(p_decoder->i_section_max_size); |
361 | 375k | if (!p_section) |
362 | 0 | return false; |
363 | | /* Update the position in the packet */ |
364 | 375k | p_payload_pos = p_new_pos; |
365 | | /* New section is being handled */ |
366 | 375k | p_new_pos = NULL; |
367 | | /* Just need the header to know how long is the section */ |
368 | 375k | p_decoder->i_need = 3; |
369 | 375k | p_decoder->b_complete_header = false; |
370 | 375k | } |
371 | 2.67k | else |
372 | 2.67k | { |
373 | | /* No new section => return */ |
374 | 2.67k | return false; |
375 | 2.67k | } |
376 | 378k | } |
377 | | |
378 | | /* Remaining bytes in the payload */ |
379 | 405k | i_available = p_data_end - p_payload_pos; |
380 | | |
381 | 1.36M | while (i_available > 0) |
382 | 968k | { |
383 | 968k | if (i_available >= p_decoder->i_need) |
384 | 890k | { |
385 | | /* There are enough bytes in this packet to complete the |
386 | | header/section */ |
387 | 890k | memcpy(p_section->p_payload_end, p_payload_pos, p_decoder->i_need); |
388 | 890k | p_payload_pos += p_decoder->i_need; |
389 | 890k | p_section->p_payload_end += p_decoder->i_need; |
390 | 890k | i_available -= p_decoder->i_need; |
391 | | |
392 | 890k | if (!p_decoder->b_complete_header) |
393 | 487k | { |
394 | | /* Compute p_section->i_length and update p_decoder->i_need */ |
395 | 487k | p_section->i_length = ((uint16_t)(p_section->p_data[1] & 0xf)) << 8 |
396 | 487k | | p_section->p_data[2]; |
397 | 487k | if(p_section->i_length > 4093) |
398 | 12.6k | return false; |
399 | 475k | p_decoder->i_need = p_section->i_length; |
400 | | /* Header is complete */ |
401 | 475k | p_decoder->b_complete_header = true; |
402 | | /* Check that the section isn't too long */ |
403 | 475k | if (p_decoder->i_need > p_decoder->i_section_max_size - 3) |
404 | 22.7k | { |
405 | 22.7k | dvbpsi_error(p_dvbpsi, "PSI decoder", "PSI section too long"); |
406 | 22.7k | dvbpsi_DeletePSISections(p_section); |
407 | 22.7k | p_decoder->p_current_section = NULL; |
408 | | /* If there is a new section not being handled then go forward |
409 | | in the packet */ |
410 | 22.7k | if (p_new_pos) |
411 | 1 | { |
412 | 1 | p_decoder->p_current_section |
413 | 1 | = p_section |
414 | 1 | = dvbpsi_NewPSISection(p_decoder->i_section_max_size); |
415 | 1 | if (!p_section) |
416 | 0 | return false; |
417 | 1 | p_payload_pos = p_new_pos; |
418 | 1 | p_new_pos = NULL; |
419 | 1 | p_decoder->i_need = 3; |
420 | 1 | p_decoder->b_complete_header = false; |
421 | 1 | i_available = p_data_end - p_payload_pos; |
422 | 1 | } |
423 | 22.7k | else |
424 | 22.7k | { |
425 | 22.7k | i_available = 0; |
426 | 22.7k | } |
427 | 22.7k | } |
428 | 475k | } |
429 | 402k | else |
430 | 402k | { |
431 | 402k | bool b_valid_crc32 = false; |
432 | 402k | bool has_crc32; |
433 | | |
434 | | /* PSI section is complete */ |
435 | 402k | p_section->i_table_id = p_section->p_data[0]; |
436 | 402k | p_section->b_syntax_indicator = p_section->p_data[1] & 0x80; |
437 | 402k | p_section->b_private_indicator = p_section->p_data[1] & 0x40; |
438 | | |
439 | | /* Update the end of the payload if CRC_32 is present */ |
440 | 402k | has_crc32 = dvbpsi_has_CRC32(p_section); |
441 | 402k | if (p_section->b_syntax_indicator || has_crc32) |
442 | 287k | p_section->p_payload_end -= 4; |
443 | | |
444 | | /* Check CRC32 if present */ |
445 | 402k | if (has_crc32) |
446 | 287k | b_valid_crc32 = dvbpsi_ValidPSISection(p_section); |
447 | | |
448 | 402k | if (!has_crc32 || b_valid_crc32) |
449 | 332k | { |
450 | | /* PSI section is valid */ |
451 | 332k | if (p_section->b_syntax_indicator) |
452 | 217k | { |
453 | 217k | p_section->i_extension = (p_section->p_data[3] << 8) |
454 | 217k | | p_section->p_data[4]; |
455 | 217k | p_section->i_version = (p_section->p_data[5] & 0x3e) >> 1; |
456 | 217k | p_section->b_current_next = p_section->p_data[5] & 0x1; |
457 | 217k | p_section->i_number = p_section->p_data[6]; |
458 | 217k | p_section->i_last_number = p_section->p_data[7]; |
459 | 217k | p_section->p_payload_start = p_section->p_data + 8; |
460 | 217k | } |
461 | 114k | else |
462 | 114k | { |
463 | 114k | p_section->i_extension = 0; |
464 | 114k | p_section->i_version = 0; |
465 | 114k | p_section->b_current_next = true; |
466 | 114k | p_section->i_number = 0; |
467 | 114k | p_section->i_last_number = 0; |
468 | 114k | p_section->p_payload_start = p_section->p_data + 3; |
469 | 114k | } |
470 | 332k | if (p_decoder->pf_gather) |
471 | 332k | p_decoder->pf_gather(p_dvbpsi, p_section); |
472 | 332k | p_decoder->p_current_section = NULL; |
473 | 332k | } |
474 | 69.8k | else |
475 | 69.8k | { |
476 | 69.8k | if (has_crc32 && !dvbpsi_ValidPSISection(p_section)) |
477 | 69.8k | dvbpsi_error(p_dvbpsi, "misc PSI", "Bad CRC_32 table 0x%x !!!", |
478 | 69.8k | p_section->p_data[0]); |
479 | 0 | else |
480 | 0 | dvbpsi_error(p_dvbpsi, "misc PSI", "table 0x%x", p_section->p_data[0]); |
481 | | |
482 | | /* PSI section isn't valid => trash it */ |
483 | 69.8k | dvbpsi_DeletePSISections(p_section); |
484 | 69.8k | p_decoder->p_current_section = NULL; |
485 | 69.8k | } |
486 | | |
487 | | /* A TS packet may contain any number of sections, only the first |
488 | | * new one is flagged by the pointer_field. If the next payload |
489 | | * byte isn't 0xff then a new section starts. */ |
490 | 402k | if (p_new_pos == NULL && i_available && *p_payload_pos != 0xff) |
491 | 106k | p_new_pos = p_payload_pos; |
492 | | |
493 | | /* If there is a new section not being handled then go forward |
494 | | in the packet */ |
495 | 402k | if (p_new_pos) |
496 | 110k | { |
497 | 110k | p_decoder->p_current_section |
498 | 110k | = p_section |
499 | 110k | = dvbpsi_NewPSISection(p_decoder->i_section_max_size); |
500 | 110k | if (!p_section) |
501 | 0 | return false; |
502 | 110k | p_payload_pos = p_new_pos; |
503 | 110k | p_new_pos = NULL; |
504 | 110k | p_decoder->i_need = 3; |
505 | 110k | p_decoder->b_complete_header = false; |
506 | 110k | i_available = p_data_end - p_payload_pos; |
507 | 110k | } |
508 | 291k | else |
509 | 291k | { |
510 | 291k | i_available = 0; |
511 | 291k | } |
512 | 402k | } |
513 | 890k | } |
514 | 78.1k | else |
515 | 78.1k | { |
516 | | /* There aren't enough bytes in this packet to complete the |
517 | | header/section */ |
518 | 78.1k | memcpy(p_section->p_payload_end, p_payload_pos, i_available); |
519 | 78.1k | p_section->p_payload_end += i_available; |
520 | 78.1k | p_decoder->i_need -= i_available; |
521 | 78.1k | i_available = 0; |
522 | 78.1k | } |
523 | 968k | } |
524 | 392k | return true; |
525 | 405k | } |
526 | | #undef DVBPSI_INVALID_CC |
527 | | |
528 | | /***************************************************************************** |
529 | | * Message error level: |
530 | | * -1 is disabled, |
531 | | * 0 is errors only |
532 | | * 1 is warning and errors |
533 | | * 2 is debug, warning and errors |
534 | | *****************************************************************************/ |
535 | | #if !defined(HAVE_ASPRINTF) |
536 | | # define DVBPSI_MSG_SIZE 1024 |
537 | | #endif |
538 | | |
539 | | #define DVBPSI_MSG_FORMAT "libdvbpsi (%s): " |
540 | | |
541 | | #ifdef HAVE_VARIADIC_MACROS |
542 | | void dvbpsi_message(dvbpsi_t *dvbpsi, const dvbpsi_msg_level_t level, const char *fmt, ...) |
543 | 489k | { |
544 | 489k | if ((dvbpsi->i_msg_level > DVBPSI_MSG_NONE) && |
545 | 489k | (level <= dvbpsi->i_msg_level)) |
546 | 489k | { |
547 | 489k | va_list ap; |
548 | 489k | va_start(ap, fmt); |
549 | 489k | char *msg = NULL; |
550 | 489k | #if defined(HAVE_ASPRINTF) |
551 | 489k | int err = vasprintf(&msg, fmt, ap); |
552 | | #else |
553 | | msg = malloc(DVBPSI_MSG_SIZE); |
554 | | if (msg == NULL) { |
555 | | va_end(ap); |
556 | | return; |
557 | | } |
558 | | int err = vsnprintf(msg, DVBPSI_MSG_SIZE, DVBPSI_MSG_FORMAT fmt, ap); |
559 | | #endif |
560 | 489k | va_end(ap); |
561 | 489k | if (err > 0) { |
562 | 489k | if (dvbpsi->pf_message) |
563 | 489k | dvbpsi->pf_message(dvbpsi, level, msg); |
564 | 489k | } |
565 | 489k | free(msg); |
566 | 489k | } |
567 | 489k | } |
568 | | #else |
569 | | |
570 | | /* Common code for printing messages */ |
571 | | # if defined(HAVE_ASPRINTF) |
572 | | # define DVBPSI_MSG_COMMON(level) \ |
573 | | do { \ |
574 | | va_list ap; \ |
575 | | va_start(ap, fmt); \ |
576 | | char *tmp = NULL; \ |
577 | | int err = vasprintf(&tmp, fmt, ap); \ |
578 | | if (err < 0) { \ |
579 | | va_end(ap); \ |
580 | | return; \ |
581 | | } \ |
582 | | char *msg = NULL; \ |
583 | | if (asprintf(&msg, DVBPSI_MSG_FORMAT "%s", src, tmp) < 0) { \ |
584 | | va_end(ap); \ |
585 | | free(tmp); \ |
586 | | return; \ |
587 | | } \ |
588 | | free(tmp); \ |
589 | | va_end(ap); \ |
590 | | if (err > 0) { \ |
591 | | if (dvbpsi->pf_message) \ |
592 | | dvbpsi->pf_message(dvbpsi, level, msg); \ |
593 | | } \ |
594 | | free(msg); \ |
595 | | } while(0); |
596 | | # else |
597 | | # define DVBPSI_MSG_COMMON(level) \ |
598 | | do { \ |
599 | | va_list ap; \ |
600 | | va_start(ap, fmt); \ |
601 | | char *tmp = malloc(DVBPSI_MSG_SIZE); \ |
602 | | char *msg = malloc(DVBPSI_MSG_SIZE); \ |
603 | | if ((tmp == NULL) || (msg == NULL)) { \ |
604 | | va_end(ap); \ |
605 | | if (tmp) free(tmp); \ |
606 | | if (msg) free(msg); \ |
607 | | return; \ |
608 | | } \ |
609 | | if (vsnprintf(tmp, DVBPSI_MSG_SIZE, fmt, ap) < 0) { \ |
610 | | va_end(ap); \ |
611 | | if (tmp) free(tmp); \ |
612 | | if (msg) free(msg); \ |
613 | | return; \ |
614 | | } \ |
615 | | va_end(ap); \ |
616 | | int err = snprintf(msg, DVBPSI_MSG_SIZE, DVBPSI_MSG_FORMAT "%s", src, tmp); \ |
617 | | if (err > 0) { \ |
618 | | if (dvbpsi->pf_message) \ |
619 | | dvbpsi->pf_message(dvbpsi, level, msg); \ |
620 | | } \ |
621 | | free(tmp); \ |
622 | | free(msg); \ |
623 | | } while(0); |
624 | | # endif |
625 | | |
626 | | void dvbpsi_error(dvbpsi_t *dvbpsi, const char *src, const char *fmt, ...) |
627 | | { |
628 | | if ((dvbpsi->i_msg_level > DVBPSI_MSG_NONE) && |
629 | | (DVBPSI_MSG_ERROR <= dvbpsi->i_msg_level)) |
630 | | { |
631 | | DVBPSI_MSG_COMMON(DVBPSI_MSG_ERROR) |
632 | | } |
633 | | } |
634 | | |
635 | | void dvbpsi_warning(dvbpsi_t *dvbpsi, const char *src, const char *fmt, ...) |
636 | | { |
637 | | if ((dvbpsi->i_msg_level > DVBPSI_MSG_NONE) && |
638 | | (DVBPSI_MSG_WARN <= dvbpsi->i_msg_level)) |
639 | | { |
640 | | DVBPSI_MSG_COMMON(DVBPSI_MSG_WARN) |
641 | | } |
642 | | } |
643 | | |
644 | | void dvbpsi_debug(dvbpsi_t *dvbpsi, const char *src, const char *fmt, ...) |
645 | | { |
646 | | if ((dvbpsi->i_msg_level > DVBPSI_MSG_NONE) && |
647 | | (DVBPSI_MSG_DEBUG <= dvbpsi->i_msg_level)) |
648 | | { |
649 | | DVBPSI_MSG_COMMON(DVBPSI_MSG_DEBUG) |
650 | | } |
651 | | } |
652 | | #endif |