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"
#endif
typedef void (*f_print)(void *, const char *, ...);
typedef char * (*f_iconv)(void *, const char *, char *, size_t);
#ifdef __cplusplus
}
......
This diff is collapsed.
......@@ -16,9 +16,11 @@
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <inttypes.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <iconv.h>
#include <bitstream/mpeg/ts.h>
#include <bitstream/mpeg/psi.h>
......@@ -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_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];
va_list args;
......@@ -69,6 +75,57 @@ static void print(void *_unused, const char *psz_format, ...)
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
*****************************************************************************/
......@@ -179,7 +236,7 @@ static void handle_pat(void)
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)
......@@ -241,7 +298,7 @@ static void handle_pmt(uint16_t i_pid, uint8_t *p_pmt)
free(p_sid->p_current_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)
psi_table_copy(pp_current_nit_sections, 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)
......@@ -313,7 +371,8 @@ static void handle_sdt(void)
psi_table_copy(pp_current_sdt_sections, 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)
......
This diff is collapsed.
......@@ -32,42 +32,95 @@ extern "C"
/*****************************************************************************
* 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;
uint8_t *p_desc;
while ((p_desc = descs_get_desc(p_descs, j)) != NULL) {
uint8_t i_tag = desc_get_tag(p_desc);
j++;
/* I am not proud of this */
switch (desc_get_tag(p_desc)) {
switch (i_tag) {
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;
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;
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;
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;
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;
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;
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;
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;
default:
desc_print(p_desc, pf_print, opaque);
desc_print(p_desc, pf_print, print_opaque);
break;
}
}
......@@ -76,44 +129,49 @@ static inline void descs_print(uint8_t *p_descs, f_print pf_print, void *opaque)
/*****************************************************************************
* 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 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),
!psi_get_current(p_pmt) ? " (next)" : "",
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) {
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));
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
*****************************************************************************/
static inline void nit_table_print(uint8_t **pp_sections, f_print pf_print,
void *opaque)
static inline void nit_table_print(uint8_t **pp_sections,
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;
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 ?
"actual" : "other",
psi_table_get_tableidext(pp_sections),
psi_table_get_version(pp_sections),
!psi_table_get_current(pp_sections) ? " (next)" : "");
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++) {
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,
while ((p_ts = nit_get_ts(p_section, j)) != NULL) {
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));
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
*****************************************************************************/
static inline void sdt_table_print(uint8_t **pp_sections, f_print pf_print,
void *opaque)
static inline void sdt_table_print(uint8_t **pp_sections,
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;
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 ?
"actual" : "other",
psi_table_get_tableidext(pp_sections),
......@@ -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) {
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_eitschedule(p_service) ? " schedule" : "",
sdtn_get_eitpresent(p_service) ? " present" : "",
sdtn_get_running(p_service),
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
......
......@@ -52,7 +52,7 @@ static inline void ts_init(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)
......@@ -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)
{
return p_ts[1] & 0x40;
return !!(p_ts[1] & 0x40);
}
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)
{
return p_ts[1] & 0x20;
return !!(p_ts[1] & 0x20);
}
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)
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)
......@@ -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)
{
return (p_ts[3] & 0x20);
return !!(p_ts[3] & 0x20);
}
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)
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)
......@@ -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)
{
return p_ts[5] & 0x10;
return !!(p_ts[5] & 0x10);
}
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