Commit 0b8f8669 authored by Christophe Massiot's avatar Christophe Massiot

* mpeg/psi.h, dvb/si.h: Add descXX_validate() functions. * mpeg/psi_print.h:...

* mpeg/psi.h, dvb/si.h: Add descXX_validate() functions. * mpeg/psi_print.h: Validate descriptors before accessing them. * mpeg/psi.h: Avoid duplicate copies of the CRC32 table. * ALL: Make sure we return booleans. * dvb/si.h: Add support for DVB character sets. * dvb/si.h: Add content delivery descriptors 0x43, 0x44 and 0x5a. * dvb/si.h: Add VBI teletext descriptor 0x46. * examples/dvb_print_si.c: Add support for charset conversion via iconv.
parent 3df65446
...@@ -22,6 +22,7 @@ extern "C" ...@@ -22,6 +22,7 @@ extern "C"
#endif #endif
typedef void (*f_print)(void *, const char *, ...); typedef void (*f_print)(void *, const char *, ...);
typedef char * (*f_iconv)(void *, const char *, char *, size_t);
#ifdef __cplusplus #ifdef __cplusplus
} }
......
This diff is collapsed.
...@@ -16,9 +16,11 @@ ...@@ -16,9 +16,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <inttypes.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <iconv.h>
#include <bitstream/mpeg/ts.h> #include <bitstream/mpeg/ts.h>
#include <bitstream/mpeg/psi.h> #include <bitstream/mpeg/psi.h>
...@@ -56,10 +58,14 @@ static PSI_TABLE_DECLARE(pp_next_nit_sections); ...@@ -56,10 +58,14 @@ static PSI_TABLE_DECLARE(pp_next_nit_sections);
static PSI_TABLE_DECLARE(pp_current_sdt_sections); static PSI_TABLE_DECLARE(pp_current_sdt_sections);
static PSI_TABLE_DECLARE(pp_next_sdt_sections); static PSI_TABLE_DECLARE(pp_next_sdt_sections);
static const char *psz_native_encoding = "UTF-8";
static const char *psz_current_encoding = "";
static iconv_t iconv_handle = (iconv_t)-1;
/***************************************************************************** /*****************************************************************************
* print * print_wrapper
*****************************************************************************/ *****************************************************************************/
static void print(void *_unused, const char *psz_format, ...) static void print_wrapper(void *_unused, const char *psz_format, ...)
{ {
char psz_fmt[strlen(psz_format) + 2]; char psz_fmt[strlen(psz_format) + 2];
va_list args; va_list args;
...@@ -69,6 +75,57 @@ static void print(void *_unused, const char *psz_format, ...) ...@@ -69,6 +75,57 @@ static void print(void *_unused, const char *psz_format, ...)
vprintf(psz_fmt, args); vprintf(psz_fmt, args);
} }
/*****************************************************************************
* iconv_wrapper
*****************************************************************************/
static char *iconv_append_null(const char *p_string, size_t i_length)
{
char *psz_string = malloc(i_length + 1);
memcpy(psz_string, p_string, i_length);
psz_string[i_length] = '\0';
return psz_string;
}
static char *iconv_wrapper(void *_unused, const char *psz_encoding,
char *p_string, size_t i_length)
{
char *psz_string, *p;
size_t i_out_length;
if (!strcmp(psz_encoding, psz_native_encoding))
return iconv_append_null(p_string, i_length);
if (iconv_handle != (iconv_t)-1 &&
strcmp(psz_encoding, psz_current_encoding)) {
iconv_close(iconv_handle);
iconv_handle = (iconv_t)-1;
}
if (iconv_handle == (iconv_t)-1)
iconv_handle = iconv_open(psz_native_encoding, psz_encoding);
if (iconv_handle == (iconv_t)-1) {
fprintf(stderr, "couldn't convert from %s to %s (%m)", psz_encoding,
psz_native_encoding);
return iconv_append_null(p_string, i_length);
}
/* converted strings can be up to six times larger */
i_out_length = i_length * 6;
p = psz_string = malloc(i_out_length);
if (iconv(iconv_handle, &p_string, &i_length, &p, &i_out_length) == -1) {
fprintf(stderr, "couldn't convert from %s to %s (%m)", psz_encoding,
psz_native_encoding);
free(psz_string);
return iconv_append_null(p_string, i_length);
}
if (i_length)
fprintf(stderr, "partial conversion from %s to %s", psz_encoding,
psz_native_encoding);
*p = '\0';
return psz_string;
}
/***************************************************************************** /*****************************************************************************
* handle_pat * handle_pat
*****************************************************************************/ *****************************************************************************/
...@@ -179,7 +236,7 @@ static void handle_pat(void) ...@@ -179,7 +236,7 @@ static void handle_pat(void)
psi_table_free(pp_old_pat_sections); psi_table_free(pp_old_pat_sections);
} }
pat_table_print( pp_current_pat_sections, print, NULL ); pat_table_print( pp_current_pat_sections, print_wrapper, NULL );
} }
static void handle_pat_section(uint16_t i_pid, uint8_t *p_section) static void handle_pat_section(uint16_t i_pid, uint8_t *p_section)
...@@ -241,7 +298,7 @@ static void handle_pmt(uint16_t i_pid, uint8_t *p_pmt) ...@@ -241,7 +298,7 @@ static void handle_pmt(uint16_t i_pid, uint8_t *p_pmt)
free(p_sid->p_current_pmt); free(p_sid->p_current_pmt);
p_sid->p_current_pmt = p_pmt; p_sid->p_current_pmt = p_pmt;
pmt_print(p_pmt, print, NULL); pmt_print(p_pmt, print_wrapper, NULL, iconv_wrapper, NULL);
} }
/***************************************************************************** /*****************************************************************************
...@@ -270,7 +327,8 @@ static void handle_nit(void) ...@@ -270,7 +327,8 @@ static void handle_nit(void)
psi_table_copy(pp_current_nit_sections, pp_next_nit_sections); psi_table_copy(pp_current_nit_sections, pp_next_nit_sections);
psi_table_init(pp_next_nit_sections); psi_table_init(pp_next_nit_sections);
nit_table_print(pp_current_nit_sections, print, NULL); nit_table_print(pp_current_nit_sections, print_wrapper, NULL,
iconv_wrapper, NULL);
} }
static void handle_nit_section(uint16_t i_pid, uint8_t *p_section) static void handle_nit_section(uint16_t i_pid, uint8_t *p_section)
...@@ -313,7 +371,8 @@ static void handle_sdt(void) ...@@ -313,7 +371,8 @@ static void handle_sdt(void)
psi_table_copy(pp_current_sdt_sections, pp_next_sdt_sections); psi_table_copy(pp_current_sdt_sections, pp_next_sdt_sections);
psi_table_init(pp_next_sdt_sections); psi_table_init(pp_next_sdt_sections);
sdt_table_print(pp_current_sdt_sections, print, NULL); sdt_table_print(pp_current_sdt_sections, print_wrapper, NULL,
iconv_wrapper, NULL);
} }
static void handle_sdt_section(uint16_t i_pid, uint8_t *p_section) static void handle_sdt_section(uint16_t i_pid, uint8_t *p_section)
......
This diff is collapsed.
...@@ -32,42 +32,95 @@ extern "C" ...@@ -32,42 +32,95 @@ extern "C"
/***************************************************************************** /*****************************************************************************
* Descriptors list * Descriptors list
*****************************************************************************/ *****************************************************************************/
static inline void descs_print(uint8_t *p_descs, f_print pf_print, void *opaque) static inline void descs_print(uint8_t *p_descs,
f_print pf_print, void *print_opaque,
f_iconv pf_iconv, void *iconv_opaque)
{ {
uint16_t j = 0; uint16_t j = 0;
uint8_t *p_desc; uint8_t *p_desc;
while ((p_desc = descs_get_desc(p_descs, j)) != NULL) { while ((p_desc = descs_get_desc(p_descs, j)) != NULL) {
uint8_t i_tag = desc_get_tag(p_desc);
j++; j++;
/* I am not proud of this */ /* I am not proud of this */
switch (desc_get_tag(p_desc)) { switch (i_tag) {
case 0x05: case 0x05:
desc05_print(p_desc, pf_print, opaque); if (desc05_validate(p_desc))
desc05_print(p_desc, pf_print, print_opaque);
else
pf_print(print_opaque, "desc %hhx invalid", i_tag);
break; break;
case 0x09: case 0x09:
desc09_print(p_desc, pf_print, opaque); if (desc09_validate(p_desc))
desc09_print(p_desc, pf_print, print_opaque);
else
pf_print(print_opaque, "desc %hhx invalid", i_tag);
break; break;
case 0x0a: case 0x0a:
desc0a_print(p_desc, pf_print, opaque); if (desc0a_validate(p_desc))
desc0a_print(p_desc, pf_print, print_opaque);
else
pf_print(print_opaque, "desc %hhx invalid", i_tag);
break; break;
case 0x40: case 0x40:
desc40_print(p_desc, pf_print, opaque); if (desc40_validate(p_desc))
desc40_print(p_desc, pf_print, print_opaque,
pf_iconv, iconv_opaque);
else
pf_print(print_opaque, "desc %hhx invalid", i_tag);
break;
case 0x43:
if (desc43_validate(p_desc))
desc43_print(p_desc, pf_print, print_opaque);
else
pf_print(print_opaque, "desc %hhx invalid", i_tag);
break;
case 0x44:
if (desc44_validate(p_desc))
desc44_print(p_desc, pf_print, print_opaque);
else
pf_print(print_opaque, "desc %hhx invalid", i_tag);
break;
case 0x46:
if (desc46_validate(p_desc))
desc46_print(p_desc, pf_print, print_opaque);
else
pf_print(print_opaque, "desc %hhx invalid", i_tag);
break; break;
case 0x48: case 0x48:
desc48_print(p_desc, pf_print, opaque); if (desc48_validate(p_desc))
desc48_print(p_desc, pf_print, print_opaque,
pf_iconv, iconv_opaque);
else
pf_print(print_opaque, "desc %hhx invalid", i_tag);
break; break;
case 0x56: case 0x56:
desc56_print(p_desc, pf_print, opaque); if (desc56_validate(p_desc))
desc56_print(p_desc, pf_print, print_opaque);
else
pf_print(print_opaque, "desc %hhx invalid", i_tag);
break; break;
case 0x59: case 0x59:
desc59_print(p_desc, pf_print, opaque); if (desc59_validate(p_desc))
desc59_print(p_desc, pf_print, print_opaque);
else
pf_print(print_opaque, "desc %hhx invalid", i_tag);
break;
case 0x5a:
if (desc5a_validate(p_desc))
desc5a_print(p_desc, pf_print, print_opaque);
else
pf_print(print_opaque, "desc %hhx invalid", i_tag);
break; break;
case 0x6a: case 0x6a:
desc6a_print(p_desc, pf_print, opaque); if (desc6a_validate(p_desc))
desc6a_print(p_desc, pf_print, print_opaque);
else
pf_print(print_opaque, "desc %hhx invalid", i_tag);
break; break;
default: default:
desc_print(p_desc, pf_print, opaque); desc_print(p_desc, pf_print, print_opaque);
break; break;
} }
} }
...@@ -76,44 +129,49 @@ static inline void descs_print(uint8_t *p_descs, f_print pf_print, void *opaque) ...@@ -76,44 +129,49 @@ static inline void descs_print(uint8_t *p_descs, f_print pf_print, void *opaque)
/***************************************************************************** /*****************************************************************************
* Program Map Table * Program Map Table
*****************************************************************************/ *****************************************************************************/
static inline void pmt_print(uint8_t *p_pmt, f_print pf_print, void *opaque) static inline void pmt_print(uint8_t *p_pmt,
f_print pf_print, void *print_opaque,
f_iconv pf_iconv, void *iconv_opaque)
{ {
uint8_t *p_es; uint8_t *p_es;
uint8_t j = 0; uint8_t j = 0;
pf_print(opaque, "new PMT program=%hu version=%hhu%s pcrpid=%hu", pf_print(print_opaque, "new PMT program=%hu version=%hhu%s pcrpid=%hu",
pmt_get_program(p_pmt), psi_get_version(p_pmt), pmt_get_program(p_pmt), psi_get_version(p_pmt),
!psi_get_current(p_pmt) ? " (next)" : "", !psi_get_current(p_pmt) ? " (next)" : "",
pmt_get_pcrpid(p_pmt)); pmt_get_pcrpid(p_pmt));
descs_print(pmt_get_descs(p_pmt), pf_print, opaque); descs_print(pmt_get_descs(p_pmt), pf_print, print_opaque,
pf_iconv, iconv_opaque);
while ((p_es = pmt_get_es(p_pmt, j)) != NULL) { while ((p_es = pmt_get_es(p_pmt, j)) != NULL) {
j++; j++;
pf_print(opaque, " * ES pid=%hu streamtype=0x%hx", pmtn_get_pid(p_es), pf_print(print_opaque, " * ES pid=%hu streamtype=0x%hx", pmtn_get_pid(p_es),
pmtn_get_streamtype(p_es)); pmtn_get_streamtype(p_es));
descs_print(pmtn_get_descs(p_es), pf_print, opaque); descs_print(pmtn_get_descs(p_es), pf_print, print_opaque,
pf_iconv, iconv_opaque);
} }
pf_print(opaque, "end PMT"); pf_print(print_opaque, "end PMT");
} }
/***************************************************************************** /*****************************************************************************
* Network Information Table * Network Information Table
*****************************************************************************/ *****************************************************************************/
static inline void nit_table_print(uint8_t **pp_sections, f_print pf_print, static inline void nit_table_print(uint8_t **pp_sections,
void *opaque) f_print pf_print, void *print_opaque,
f_iconv pf_iconv, void *iconv_opaque)
{ {
uint8_t i_last_section = psi_table_get_lastsection(pp_sections); uint8_t i_last_section = psi_table_get_lastsection(pp_sections);
uint8_t i; uint8_t i;
pf_print(opaque, "new NIT %s networkid=%hu version=%hhu%s", pf_print(print_opaque, "new NIT %s networkid=%hu version=%hhu%s",
psi_table_get_tableid(pp_sections) == NIT_TABLE_ID_ACTUAL ? psi_table_get_tableid(pp_sections) == NIT_TABLE_ID_ACTUAL ?
"actual" : "other", "actual" : "other",
psi_table_get_tableidext(pp_sections), psi_table_get_tableidext(pp_sections),
psi_table_get_version(pp_sections), psi_table_get_version(pp_sections),
!psi_table_get_current(pp_sections) ? " (next)" : ""); !psi_table_get_current(pp_sections) ? " (next)" : "");
descs_print(nit_get_descs(psi_table_get_section(pp_sections, 0)), descs_print(nit_get_descs(psi_table_get_section(pp_sections, 0)),
pf_print, opaque); pf_print, print_opaque, pf_iconv, iconv_opaque);
for (i = 0; i <= i_last_section; i++) { for (i = 0; i <= i_last_section; i++) {
uint8_t *p_section = psi_table_get_section(pp_sections, i); uint8_t *p_section = psi_table_get_section(pp_sections, i);
...@@ -122,25 +180,27 @@ static inline void nit_table_print(uint8_t **pp_sections, f_print pf_print, ...@@ -122,25 +180,27 @@ static inline void nit_table_print(uint8_t **pp_sections, f_print pf_print,
while ((p_ts = nit_get_ts(p_section, j)) != NULL) { while ((p_ts = nit_get_ts(p_section, j)) != NULL) {
j++; j++;
pf_print(opaque, " * ts tsid=%hu onid=%hu", pf_print(print_opaque, " * ts tsid=%hu onid=%hu",
nitn_get_tsid(p_ts), nitn_get_onid(p_ts)); nitn_get_tsid(p_ts), nitn_get_onid(p_ts));
descs_print(nitn_get_descs(p_ts), pf_print, opaque); descs_print(nitn_get_descs(p_ts), pf_print, print_opaque,
pf_iconv, iconv_opaque);
} }
} }
pf_print(opaque, "end NIT"); pf_print(print_opaque, "end NIT");
} }
/***************************************************************************** /*****************************************************************************
* Service Description Table * Service Description Table
*****************************************************************************/ *****************************************************************************/
static inline void sdt_table_print(uint8_t **pp_sections, f_print pf_print, static inline void sdt_table_print(uint8_t **pp_sections,
void *opaque) f_print pf_print, void *print_opaque,
f_iconv pf_iconv, void *iconv_opaque)
{ {
uint8_t i_last_section = psi_table_get_lastsection(pp_sections); uint8_t i_last_section = psi_table_get_lastsection(pp_sections);
uint8_t i; uint8_t i;
pf_print(opaque, "new SDT %s tsid=%hu version=%hhu%s onid=%hu", pf_print(print_opaque, "new SDT %s tsid=%hu version=%hhu%s onid=%hu",
psi_table_get_tableid(pp_sections) == SDT_TABLE_ID_ACTUAL ? psi_table_get_tableid(pp_sections) == SDT_TABLE_ID_ACTUAL ?
"actual" : "other", "actual" : "other",
psi_table_get_tableidext(pp_sections), psi_table_get_tableidext(pp_sections),
...@@ -155,17 +215,18 @@ static inline void sdt_table_print(uint8_t **pp_sections, f_print pf_print, ...@@ -155,17 +215,18 @@ static inline void sdt_table_print(uint8_t **pp_sections, f_print pf_print,
while ((p_service = sdt_get_service(p_section, j)) != NULL) { while ((p_service = sdt_get_service(p_section, j)) != NULL) {
j++; j++;
pf_print(opaque, " * service sid=%hu eit%s%s running=%hhu%s", pf_print(print_opaque, " * service sid=%hu eit%s%s running=%hhu%s",
sdtn_get_sid(p_service), sdtn_get_sid(p_service),
sdtn_get_eitschedule(p_service) ? " schedule" : "", sdtn_get_eitschedule(p_service) ? " schedule" : "",
sdtn_get_eitpresent(p_service) ? " present" : "", sdtn_get_eitpresent(p_service) ? " present" : "",
sdtn_get_running(p_service), sdtn_get_running(p_service),
sdtn_get_ca(p_service) ? " scrambled" : ""); sdtn_get_ca(p_service) ? " scrambled" : "");
descs_print(sdtn_get_descs(p_service), pf_print, opaque); descs_print(sdtn_get_descs(p_service), pf_print, print_opaque,
pf_iconv, iconv_opaque);
} }
} }
pf_print(opaque, "end SDT"); pf_print(print_opaque, "end SDT");
} }
#ifdef __cplusplus #ifdef __cplusplus
......
...@@ -52,7 +52,7 @@ static inline void ts_init(uint8_t *p_ts) ...@@ -52,7 +52,7 @@ static inline void ts_init(uint8_t *p_ts)
static inline bool ts_get_transporterror(const uint8_t *p_ts) static inline bool ts_get_transporterror(const uint8_t *p_ts)
{ {
return p_ts[1] & 0x80; return !!(p_ts[1] & 0x80);
} }
static inline void ts_set_unitstart(uint8_t *p_ts) static inline void ts_set_unitstart(uint8_t *p_ts)
...@@ -62,7 +62,7 @@ static inline void ts_set_unitstart(uint8_t *p_ts) ...@@ -62,7 +62,7 @@ static inline void ts_set_unitstart(uint8_t *p_ts)
static inline bool ts_get_unitstart(const uint8_t *p_ts) static inline bool ts_get_unitstart(const uint8_t *p_ts)
{ {
return p_ts[1] & 0x40; return !!(p_ts[1] & 0x40);
} }
static inline void ts_set_transportpriority(uint8_t *p_ts) static inline void ts_set_transportpriority(uint8_t *p_ts)
...@@ -72,7 +72,7 @@ static inline void ts_set_transportpriority(uint8_t *p_ts) ...@@ -72,7 +72,7 @@ static inline void ts_set_transportpriority(uint8_t *p_ts)
static inline bool ts_get_transportpriority(const uint8_t *p_ts) static inline bool ts_get_transportpriority(const uint8_t *p_ts)
{ {
return p_ts[1] & 0x20; return !!(p_ts[1] & 0x20);
} }
static inline void ts_set_pid(uint8_t *p_ts, uint16_t i_pid) static inline void ts_set_pid(uint8_t *p_ts, uint16_t i_pid)
...@@ -105,7 +105,7 @@ static inline void ts_set_payload(uint8_t *p_ts) ...@@ -105,7 +105,7 @@ static inline void ts_set_payload(uint8_t *p_ts)
static inline bool ts_has_payload(const uint8_t *p_ts) static inline bool ts_has_payload(const uint8_t *p_ts)
{ {
return p_ts[3] & 0x10; return !!(p_ts[3] & 0x10);
} }
static inline void ts_set_adaptation(uint8_t *p_ts, uint8_t i_length) static inline void ts_set_adaptation(uint8_t *p_ts, uint8_t i_length)
...@@ -120,7 +120,7 @@ static inline void ts_set_adaptation(uint8_t *p_ts, uint8_t i_length) ...@@ -120,7 +120,7 @@ static inline void ts_set_adaptation(uint8_t *p_ts, uint8_t i_length)
static inline bool ts_has_adaptation(const uint8_t *p_ts) static inline bool ts_has_adaptation(const uint8_t *p_ts)
{ {
return (p_ts[3] & 0x20); return !!(p_ts[3] & 0x20);
} }
static inline uint8_t ts_get_adaptation(const uint8_t *p_ts) static inline uint8_t ts_get_adaptation(const uint8_t *p_ts)
...@@ -193,7 +193,7 @@ static inline void tsaf_set_randomaccess(uint8_t *p_ts) ...@@ -193,7 +193,7 @@ static inline void tsaf_set_randomaccess(uint8_t *p_ts)
static inline bool tsaf_has_randomaccess(const uint8_t *p_ts) static inline bool tsaf_has_randomaccess(const uint8_t *p_ts)
{ {
return p_ts[5] & 0x40; return !!(p_ts[5] & 0x40);
} }
static inline void tsaf_set_streampriority(uint8_t *p_ts) static inline void tsaf_set_streampriority(uint8_t *p_ts)
...@@ -220,7 +220,7 @@ static inline void tsaf_set_pcrext(uint8_t *p_ts, uint16_t i_pcr_ext) ...@@ -220,7 +220,7 @@ static inline void tsaf_set_pcrext(uint8_t *p_ts, uint16_t i_pcr_ext)
static inline bool tsaf_has_pcr(uint8_t *p_ts) static inline bool tsaf_has_pcr(uint8_t *p_ts)
{ {
return p_ts[5] & 0x10; return !!(p_ts[5] & 0x10);
} }
static inline uint64_t tsaf_get_pcr(const uint8_t *p_ts) static inline uint64_t tsaf_get_pcr(const uint8_t *p_ts)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment