Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37409276
en ru br
Репозитории ALT

Группа :: Разработка/C
Пакет: bitstream-headers

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: bitstream-headers-1.0-alt3.patch
Скачать


 .gear/rules                                        |    3 +
 .../tags/15e34b4060dcb388af65705b428ebd76864c3574  |    6 +
 .gear/tags/list                                    |    1 +
 alt-linux/bitstream.spec                           |   43 +++++
 dvb/si/bat_print.h                                 |    4 +-
 dvb/si/eit.h                                       |    8 +-
 dvb/si/eit_print.h                                 |   31 ++--
 dvb/si/rst.h                                       |    4 +-
 dvb/si/rst_print.h                                 |    8 +-
 dvb/si/sit.h                                       |    4 +-
 dvb/si/sit_print.h                                 |    8 +-
 examples/dvb_gen_si.c                              |   27 +--
 examples/dvb_print_si.c                            |  180 ++++++++++++++++----
 examples/dvb_print_si.output.txt                   |    4 +-
 examples/dvb_print_si.output.xml                   |    4 +-
 ietf/rtp.h                                         |    2 +-
 mpeg/ts.h                                          |    2 +-
 17 files changed, 251 insertions(+), 88 deletions(-)
diff --git a/.gear/rules b/.gear/rules
new file mode 100644
index 0000000..4238c99
--- /dev/null
+++ b/.gear/rules
@@ -0,0 +1,3 @@
+spec: alt-linux/bitstream.spec
+tar: @version@:.
+diff: @version@:. .
diff --git a/.gear/tags/15e34b4060dcb388af65705b428ebd76864c3574 b/.gear/tags/15e34b4060dcb388af65705b428ebd76864c3574
new file mode 100644
index 0000000..d4190dd
--- /dev/null
+++ b/.gear/tags/15e34b4060dcb388af65705b428ebd76864c3574
@@ -0,0 +1,6 @@
+object abdf4ed39b706f82751ecc2cbee8b5fcf7dd5fd3
+type commit
+tag 1.0
+tagger Christophe Massiot <massiot@via.ecp.fr> 1323980162 +0100
+
+1.0 release
diff --git a/.gear/tags/list b/.gear/tags/list
new file mode 100644
index 0000000..cae8fa9
--- /dev/null
+++ b/.gear/tags/list
@@ -0,0 +1 @@
+15e34b4060dcb388af65705b428ebd76864c3574 1.0
diff --git a/alt-linux/bitstream.spec b/alt-linux/bitstream.spec
new file mode 100644
index 0000000..2c561b5
--- /dev/null
+++ b/alt-linux/bitstream.spec
@@ -0,0 +1,43 @@
+Name: bitstream-headers
+Version: 1.0
+Release: alt3
+Summary: biTStream is a set of C headers allowing a simpler access to binary structures such as specified by MPEG, DVB, IETF, etc.
+Group: Development/C
+
+Packager: Alexei Takaseev <taf@altlinux.ru>
+
+License: MIT
+Url: http://www.videolan.org/developers/bitstream.html
+Source0: %name-%version.tar
+Patch0: %name-%version-%release.patch
+BuildArch: noarch
+
+%description
+biTStream is a set of C headers allowing a simpler access to binary
+structures such as specified by MPEG, DVB, IETF, etc.
+
+biTStream is lower level, and more efficient: fewer memory allocations,
+fewer memory copies. It also features a better separation between layers
+and specifications.
+
+%prep
+%setup
+%patch0 -p1
+
+%install
+make PREFIX=%buildroot/usr install
+
+%files
+%doc AUTHORS COPYING INSTALL NEWS README TODO
+%_includedir/bitstream
+%_includedir/bitstream/*
+
+%changelog
+* Sat Aug 11 2012 Alexei Takaseev <taf@altlinux.org> 1.0-alt3
+- Enforce consistency naming between tables (git: 6a24504cc5b5c4c4bd11dffc89209f2e2474b814)
+
+* Tue Jun 26 2012 Alexei Takaseev <taf@altlinux.org> 1.0-alt2
+- Issue with bit 33 in PCR
+
+* Sat May 19 2012 Alexei Takaseev <taf@altlinux.org> 1.0-alt1
+- Initial RPM release
diff --git a/dvb/si/bat_print.h b/dvb/si/bat_print.h
index 016c08c..2c7ebcf 100644
--- a/dvb/si/bat_print.h
+++ b/dvb/si/bat_print.h
@@ -52,14 +52,14 @@ static inline void bat_table_print(uint8_t **pp_sections,
 
     switch (i_print_type) {
     case PRINT_XML:
-        pf_print(print_opaque, "<BAT tid=\"%hhu\" networkid=\"%hu\" version=\"%hhu\" current_next=\"%d\">",
+        pf_print(print_opaque, "<BAT tid=\"%hhu\" bouquetid=\"%hu\" version=\"%hhu\" current_next=\"%d\">",
                  psi_table_get_tableid(pp_sections),
                  psi_table_get_tableidext(pp_sections),
                  psi_table_get_version(pp_sections),
                  !psi_table_get_current(pp_sections) ? 0 : 1);
         break;
     default:
-        pf_print(print_opaque, "new BAT networkid=%hu version=%hhu%s",
+        pf_print(print_opaque, "new BAT bouquetid=%hu version=%hhu%s",
                  psi_table_get_tableidext(pp_sections),
                  psi_table_get_version(pp_sections),
                  !psi_table_get_current(pp_sections) ? " (next)" : "");
diff --git a/dvb/si/eit.h b/dvb/si/eit.h
index b7f4253..0a49cfd 100644
--- a/dvb/si/eit.h
+++ b/dvb/si/eit.h
@@ -152,22 +152,22 @@ static inline void eitn_set_duration_bcd(uint8_t *p_eit_n, uint32_t i_duration_b
     p_eit_n[9] = i_duration_bcd         & 0xff;
 }
 
-static inline uint8_t eitn_get_running_status(const uint8_t *p_eit_n)
+static inline uint8_t eitn_get_running(const uint8_t *p_eit_n)
 {
     return p_eit_n[10] >> 5;
 }
 
-static inline void eitn_set_running_status(uint8_t *p_eit_n, uint8_t i_running_status)
+static inline void eitn_set_running(uint8_t *p_eit_n, uint8_t i_running_status)
 {
     p_eit_n[10] = (p_eit_n[10] & 0x1f) | (i_running_status << 5);
 }
 
-static inline bool eitn_get_free_CA_mode(const uint8_t *p_eit_n)
+static inline bool eitn_get_ca(const uint8_t *p_eit_n)
 {
     return (p_eit_n[10] & 0x10) == 0x10;
 }
 
-static inline void eitn_set_free_CA_mode(uint8_t *p_eit_n, bool b_free_CA_mode)
+static inline void eitn_set_ca(uint8_t *p_eit_n, bool b_free_CA_mode)
 {
     p_eit_n[10] = b_free_CA_mode ? (p_eit_n[10] | 0x10) : (p_eit_n[10] &~ 0x10);
 }
diff --git a/dvb/si/eit_print.h b/dvb/si/eit_print.h
index 5adedf8..a08b591 100644
--- a/dvb/si/eit_print.h
+++ b/dvb/si/eit_print.h
@@ -64,29 +64,26 @@ static inline void eit_print(uint8_t *p_eit,
     switch (i_print_type) {
     case PRINT_XML:
         pf_print(print_opaque,
-                "<EIT tableid=\"0x%02x\" type=\"%s\" version=\"%u\""
-                " current_next=\"%u\" tsid=\"%u\" onid=\"%u\""
-                " seg_last_sec_number=\"%u\" last_table_id=\"0x%02x\">",
+                "<EIT tableid=\"0x%02x\" type=\"%s\" service_id=\"%u\" version=\"%u\""
+                " current_next=\"%u\" tsid=\"%u\" onid=\"%u\">",
                  i_tid, psz_tid,
+                 eit_get_sid(p_eit),
                  psi_get_version(p_eit),
                  !psi_get_current(p_eit) ? 0 : 1,
                  eit_get_tsid(p_eit),
-                 eit_get_onid(p_eit),
-                 eit_get_segment_last_sec_number(p_eit),
-                 eit_get_last_table_id(p_eit)
+                 eit_get_onid(p_eit)
                 );
         break;
     default:
         pf_print(print_opaque,
-                 "new EIT tableid=0x%02x type=%s version=%u%s tsid=%u"
-                 " onid=%u seg_last_sec_number=%u last_table_id=0x%02x",
+                 "new EIT tableid=0x%02x type=%s service_id=%u version=%u%s tsid=%u"
+                 " onid=%u",
                  i_tid, psz_tid,
+                 eit_get_sid(p_eit),
                  psi_get_version(p_eit),
                  !psi_get_current(p_eit) ? " (next)" : "",
                  eit_get_tsid(p_eit),
-                 eit_get_onid(p_eit),
-                 eit_get_segment_last_sec_number(p_eit),
-                 eit_get_last_table_id(p_eit)
+                 eit_get_onid(p_eit)
                 );
     }
 
@@ -105,21 +102,21 @@ static inline void eit_print(uint8_t *p_eit,
         case PRINT_XML:
             pf_print(print_opaque, "<EVENT id=\"%u\" start_time=\"%ld\" start_time_dec=\"%s\""
                                    " duration=\"%u\" duration_dec=\"%s\""
-                                   " running_status=\"%d\" free_CA_mode=\"%d\">",
+                                   " running=\"%d\" free_CA=\"%d\">",
                      eitn_get_event_id(p_event),
                      start_ts, start_str,
                      duration, duration_str,
-                     eitn_get_running_status(p_event),
-                     eitn_get_free_CA_mode(p_event)
+                     eitn_get_running(p_event),
+                     eitn_get_ca(p_event)
                     );
             break;
         default:
-            pf_print(print_opaque, "  * EVENT id=%u start_time=%ld start_time_dec=\"%s\" duration=%u duration_dec=%s running_status=%d free_CA_mode=%d",
+            pf_print(print_opaque, "  * EVENT id=%u start_time=%ld start_time_dec=\"%s\" duration=%u duration_dec=%s running=%d free_CA=%d",
                      eitn_get_event_id(p_event),
                      start_ts, start_str,
                      duration, duration_str,
-                     eitn_get_running_status(p_event),
-                     eitn_get_free_CA_mode(p_event)
+                     eitn_get_running(p_event),
+                     eitn_get_ca(p_event)
                     );
         }
 
diff --git a/dvb/si/rst.h b/dvb/si/rst.h
index 113c54b..0897815 100644
--- a/dvb/si/rst.h
+++ b/dvb/si/rst.h
@@ -110,12 +110,12 @@ static inline void rstn_set_event_id(uint8_t *p_rst_n, uint16_t i_event_id)
     p_rst_n[7] = i_event_id & 0xff;
 }
 
-static inline uint8_t rstn_get_running_status(const uint8_t *p_rst_n)
+static inline uint8_t rstn_get_running(const uint8_t *p_rst_n)
 {
     return p_rst_n[8] & 0x07;
 }
 
-static inline void rstn_set_running_status(uint8_t *p_rst_n, uint8_t i_running_status)
+static inline void rstn_set_running(uint8_t *p_rst_n, uint8_t i_running_status)
 {
     p_rst_n[8] = 0xf8 | (i_running_status & 0x07);
 }
diff --git a/dvb/si/rst_print.h b/dvb/si/rst_print.h
index 0d859f4..7eed4dd 100644
--- a/dvb/si/rst_print.h
+++ b/dvb/si/rst_print.h
@@ -60,23 +60,23 @@ static inline void rst_print(uint8_t *p_rst,
         case PRINT_XML:
             pf_print(print_opaque,
                      "<STATUS tsid=\"%hu\" onid=\"%hu\" service_id=\"%hu\""
-                     " event_id=\"%hu\" running_status=\"%hu\"/>",
+                     " event_id=\"%hu\" running=\"%hu\"/>",
                      rstn_get_tsid(p_rst_n),
                      rstn_get_onid(p_rst_n),
                      rstn_get_service_id(p_rst_n),
                      rstn_get_event_id(p_rst_n),
-                     rstn_get_running_status(p_rst_n)
+                     rstn_get_running(p_rst_n)
                     );
             break;
         default:
             pf_print(print_opaque,
                      "  * status tsid=\"%hu\" onid=\"%hu\" service_id=\"%hu\""
-                     " event_id=\"%hu\" running_status=\"%hu\"",
+                     " event_id=\"%hu\" running=\"%hu\"",
                      rstn_get_tsid(p_rst_n),
                      rstn_get_onid(p_rst_n),
                      rstn_get_service_id(p_rst_n),
                      rstn_get_event_id(p_rst_n),
-                     rstn_get_running_status(p_rst_n)
+                     rstn_get_running(p_rst_n)
                     );
         }
     }
diff --git a/dvb/si/sit.h b/dvb/si/sit.h
index ae11716..a275569 100644
--- a/dvb/si/sit.h
+++ b/dvb/si/sit.h
@@ -99,12 +99,12 @@ static inline void sitn_set_sid(uint8_t *p_sit_n, uint16_t i_sid)
     p_sit_n[1] =  i_sid       & 0xff;
 }
 
-static inline uint8_t sitn_get_running_status(const uint8_t *p_sit_n)
+static inline uint8_t sitn_get_running(const uint8_t *p_sit_n)
 {
     return (p_sit_n[2] & 0x70) >> 4;
 }
 
-static inline void sitn_set_running_status(uint8_t *p_sit_n, uint8_t i_running_status)
+static inline void sitn_set_running(uint8_t *p_sit_n, uint8_t i_running_status)
 {
     p_sit_n[2] = (p_sit_n[2] &~ 0x70) | ((i_running_status & 0x07) << 4);
 }
diff --git a/dvb/si/sit_print.h b/dvb/si/sit_print.h
index 68a1cb0..107852c 100644
--- a/dvb/si/sit_print.h
+++ b/dvb/si/sit_print.h
@@ -66,15 +66,15 @@ static inline void sit_print(uint8_t *p_sit,
         j++;
         switch (i_print_type) {
         case PRINT_XML:
-            pf_print(print_opaque, "<SERVICE sid=\"%hu\" running_status=\"%u\">",
+            pf_print(print_opaque, "<SERVICE sid=\"%hu\" running=\"%u\">",
                      sitn_get_sid(p_service),
-                     sitn_get_running_status(p_service)
+                     sitn_get_running(p_service)
                     );
             break;
         default:
-            pf_print(print_opaque, "  * SERVICE sid=%hu running_status=%u",
+            pf_print(print_opaque, "  * SERVICE sid=%hu running=%u",
                      sitn_get_sid(p_service),
-                     sitn_get_running_status(p_service)
+                     sitn_get_running(p_service)
                     );
         }
 
diff --git a/examples/dvb_gen_si.c b/examples/dvb_gen_si.c
index e929cc6..2ea7bef 100644
--- a/examples/dvb_gen_si.c
+++ b/examples/dvb_gen_si.c
@@ -2359,6 +2359,7 @@ static void generate_eit(void) {
     psi_set_current(eit);
 
     eit_set_length(eit, 0);
+    eit_set_sid(eit, sid);
     eit_set_tsid(eit, tsid);
     eit_set_onid(eit, onid);
     eit_set_segment_last_sec_number(eit, 0);
@@ -2383,8 +2384,8 @@ static void generate_eit(void) {
         eitn_set_event_id(eit_n, event_id);
         eitn_set_start_time(eit_n, dvb_time_encode_UTC(ts_0));
         eitn_set_duration_bcd(eit_n, dvb_time_encode_duration(86399));
-        eitn_set_running_status(eit_n, 2);
-        eitn_set_free_CA_mode(eit_n, false);
+        eitn_set_running(eit_n, 2);
+        eitn_set_ca(eit_n, false);
         eitn_set_desclength(eit_n, 0);
         {
             // Add descriptors to transport_stream_n
@@ -2404,8 +2405,8 @@ static void generate_eit(void) {
         eitn_set_event_id(eit_n, event_id + 100);
         eitn_set_start_time(eit_n, dvb_time_encode_UTC(ts_1));
         eitn_set_duration_bcd(eit_n, dvb_time_encode_duration(3600));
-        eitn_set_running_status(eit_n, 1);
-        eitn_set_free_CA_mode(eit_n, false);
+        eitn_set_running(eit_n, 1);
+        eitn_set_ca(eit_n, false);
         eitn_set_desclength(eit_n, 0);
         {
             // Add descriptors to transport_stream_n
@@ -2434,8 +2435,8 @@ static void generate_eit(void) {
         eitn_set_event_id(eit_n, event_id + 200);
         eitn_set_start_time(eit_n, dvb_time_encode_UTC(ts_2));
         eitn_set_duration_bcd(eit_n, dvb_time_encode_duration(7200));
-        eitn_set_running_status(eit_n, 0);
-        eitn_set_free_CA_mode(eit_n, false);
+        eitn_set_running(eit_n, 0);
+        eitn_set_ca(eit_n, false);
         eitn_set_desclength(eit_n, 0);
         {
             // Add descriptors to transport_stream_n
@@ -2470,8 +2471,8 @@ static void generate_eit(void) {
         eitn_set_event_id(eit_n, event_id + 300);
         eitn_set_start_time(eit_n, dvb_time_encode_UTC(ts_2));
         eitn_set_duration_bcd(eit_n, dvb_time_encode_duration(7200));
-        eitn_set_running_status(eit_n, 4);
-        eitn_set_free_CA_mode(eit_n, true);
+        eitn_set_running(eit_n, 4);
+        eitn_set_ca(eit_n, true);
         eitn_set_desclength(eit_n, 0);
         {
             // Add descriptors to transport_stream_n
@@ -2601,7 +2602,7 @@ static void generate_rst(void) {
     rstn_set_onid(rst_n, onid);
     rstn_set_service_id(rst_n, sid);
     rstn_set_event_id(rst_n, event_id);
-    rstn_set_running_status(rst_n, 1);
+    rstn_set_running(rst_n, 1);
 
     rst_n = rst_get_status(rst, j++);
     rstn_init(rst_n);
@@ -2609,7 +2610,7 @@ static void generate_rst(void) {
     rstn_set_onid(rst_n, onid + 100);
     rstn_set_service_id(rst_n, sid + 100);
     rstn_set_event_id(rst_n, event_id + 100);
-    rstn_set_running_status(rst_n, 2);
+    rstn_set_running(rst_n, 2);
 
     rst_n = rst_get_status(rst, j++);
     rstn_init(rst_n);
@@ -2617,7 +2618,7 @@ static void generate_rst(void) {
     rstn_set_onid(rst_n, onid + 200);
     rstn_set_service_id(rst_n, sid + 200);
     rstn_set_event_id(rst_n, event_id + 200);
-    rstn_set_running_status(rst_n, 3);
+    rstn_set_running(rst_n, 3);
 
     // Set correct rst length
     rst_n = rst_get_status(rst, j); // Get offset of the end of last status
@@ -3036,7 +3037,7 @@ static void generate_sit(void) {
         sit_n = sit_get_service(sit, sit_n_counter++);
         sitn_init(sit_n);
         sitn_set_sid(sit_n, sid);
-        sitn_set_running_status(sit_n, 1);
+        sitn_set_running(sit_n, 1);
         sitn_set_desclength(sit_n, 0);
         {
             // Add descriptors to transport_stream_n
@@ -3061,7 +3062,7 @@ static void generate_sit(void) {
         sit_n = sit_get_service(sit, sit_n_counter++);
         sitn_init(sit_n);
         sitn_set_sid(sit_n, sid + 1000);
-        sitn_set_running_status(sit_n, 3);
+        sitn_set_running(sit_n, 3);
         sitn_set_desclength(sit_n, 0);
 
         // Set transport_stream_loop length
diff --git a/examples/dvb_print_si.c b/examples/dvb_print_si.c
index 469428d..896e79e 100644
--- a/examples/dvb_print_si.c
+++ b/examples/dvb_print_si.c
@@ -57,15 +57,26 @@ typedef struct ts_pid_t {
     uint16_t i_psi_buffer_used;
 } ts_pid_t;
 
+static ts_pid_t p_pids[MAX_PIDS];
+
 typedef struct sid_t {
     uint16_t i_sid, i_pmt_pid;
     uint8_t *p_current_pmt;
+    PSI_TABLE_DECLARE(pp_eit_sections);
 } sid_t;
 
-ts_pid_t p_pids[MAX_PIDS];
 static sid_t **pp_sids = NULL;
 static int i_nb_sids = 0;
 
+typedef struct bouquet_t {
+    uint16_t i_bouquet;
+    PSI_TABLE_DECLARE(pp_current_bat_sections);
+    PSI_TABLE_DECLARE(pp_next_bat_sections);
+} bouquet_t;
+
+static bouquet_t **pp_bouquets = NULL;
+static int i_nb_bouquets = 0;
+
 static PSI_TABLE_DECLARE(pp_current_pat_sections);
 static PSI_TABLE_DECLARE(pp_next_pat_sections);
 static PSI_TABLE_DECLARE(pp_current_cat_sections);
@@ -74,8 +85,6 @@ static PSI_TABLE_DECLARE(pp_current_tsdt_sections);
 static PSI_TABLE_DECLARE(pp_next_tsdt_sections);
 static PSI_TABLE_DECLARE(pp_current_nit_sections);
 static PSI_TABLE_DECLARE(pp_next_nit_sections);
-static PSI_TABLE_DECLARE(pp_current_bat_sections);
-static PSI_TABLE_DECLARE(pp_next_bat_sections);
 static PSI_TABLE_DECLARE(pp_current_sdt_sections);
 static PSI_TABLE_DECLARE(pp_next_sdt_sections);
 
@@ -246,6 +255,7 @@ static void handle_pat(void)
                     pp_sids = realloc(pp_sids, ++i_nb_sids * sizeof(sid_t *));
                     pp_sids[i_pmt] = p_sid;
                     p_sid->p_current_pmt = NULL;
+                    psi_table_init(p_sid->pp_eit_sections);
                 }
                 else
                     p_sid = pp_sids[i_pmt];
@@ -278,6 +288,8 @@ static void handle_pat(void)
                             pp_sids[i_pmt]->i_sid = 0;
                             free(pp_sids[i_pmt]->p_current_pmt);
                             pp_sids[i_pmt]->p_current_pmt = NULL;
+                            psi_table_free(pp_sids[i]->pp_eit_sections);
+                            psi_table_init(pp_sids[i]->pp_eit_sections);
                             break;
                         }
                 }
@@ -477,6 +489,7 @@ static void handle_pmt(uint16_t i_pid, uint8_t *p_pmt)
         p_sid->i_sid = i_sid;
         p_sid->i_pmt_pid = i_pid;
         p_sid->p_current_pmt = NULL;
+        psi_table_init(p_sid->pp_eit_sections);
     } else {
         p_sid = pp_sids[i];
         if (i_pid != p_sid->i_pmt_pid) {
@@ -528,8 +541,8 @@ static void handle_nit(void)
         default:
             printf("invalid NIT received\n");
         }
-        psi_table_free( pp_next_nit_sections );
-        psi_table_init( pp_next_nit_sections );
+        psi_table_free(pp_next_nit_sections);
+        psi_table_init(pp_next_nit_sections);
         return;
     }
 
@@ -567,17 +580,18 @@ static void handle_nit_section(uint16_t i_pid, uint8_t *p_section)
 /*****************************************************************************
  * handle_bat
  *****************************************************************************/
-static void handle_bat(void)
+static void handle_bat(bouquet_t *p_bouquet)
 {
-    if (psi_table_validate(pp_current_bat_sections) &&
-        psi_table_compare(pp_current_bat_sections, pp_next_bat_sections)) {
+    if (psi_table_validate(p_bouquet->pp_current_bat_sections) &&
+        psi_table_compare(p_bouquet->pp_current_bat_sections,
+                          p_bouquet->pp_next_bat_sections)) {
         /* Same version BAT. Shortcut. */
-        psi_table_free(pp_next_bat_sections);
-        psi_table_init(pp_next_bat_sections);
+        psi_table_free(p_bouquet->pp_next_bat_sections);
+        psi_table_init(p_bouquet->pp_next_bat_sections);
         return;
     }
 
-    if (!bat_table_validate(pp_next_bat_sections)) {
+    if (!bat_table_validate(p_bouquet->pp_next_bat_sections)) {
         switch (i_print_type) {
         case PRINT_XML:
             printf("<ERROR type=\"invalid_bat\"/>\n");
@@ -585,23 +599,28 @@ static void handle_bat(void)
         default:
             printf("invalid BAT received\n");
         }
-        psi_table_free( pp_next_bat_sections );
-        psi_table_init( pp_next_bat_sections );
+        psi_table_free(p_bouquet->pp_next_bat_sections);
+        psi_table_init(p_bouquet->pp_next_bat_sections);
         return;
     }
 
     /* Switch tables. */
-    psi_table_free(pp_current_bat_sections);
-    psi_table_copy(pp_current_bat_sections, pp_next_bat_sections);
-    psi_table_init(pp_next_bat_sections);
+    psi_table_free(p_bouquet->pp_current_bat_sections);
+    psi_table_copy(p_bouquet->pp_current_bat_sections,
+                   p_bouquet->pp_next_bat_sections);
+    psi_table_init(p_bouquet->pp_next_bat_sections);
 
     if (pb_print_table[TABLE_BAT])
-        bat_table_print(pp_current_bat_sections, print_wrapper, NULL,
+        bat_table_print(p_bouquet->pp_current_bat_sections, print_wrapper, NULL,
                         iconv_wrapper, NULL, i_print_type);
 }
 
 static void handle_bat_section(uint16_t i_pid, uint8_t *p_section)
 {
+    uint16_t i_bouquet;
+    bouquet_t *p_bouquet;
+    int i;
+
     if (i_pid != BAT_PID || !bat_validate(p_section)) {
         switch (i_print_type) {
         case PRINT_XML:
@@ -615,10 +634,24 @@ static void handle_bat_section(uint16_t i_pid, uint8_t *p_section)
         return;
     }
 
-    if (!psi_table_section(pp_next_bat_sections, p_section))
+    i_bouquet = psi_get_tableidext(p_section);
+    for (i = 0; i < i_nb_bouquets; i++)
+        if (pp_bouquets[i]->i_bouquet && pp_bouquets[i]->i_bouquet == i_bouquet)
+            break;
+    if (i == i_nb_bouquets) {
+        p_bouquet = malloc(sizeof(bouquet_t));
+        pp_bouquets = realloc(pp_bouquets, ++i_nb_bouquets * sizeof(bouquet_t *));
+        pp_bouquets[i] = p_bouquet;
+        p_bouquet->i_bouquet = i_bouquet;
+        psi_table_init(p_bouquet->pp_current_bat_sections);
+        psi_table_init(p_bouquet->pp_next_bat_sections);
+    } else
+        p_bouquet = pp_bouquets[i];
+
+    if (!psi_table_section(p_bouquet->pp_next_bat_sections, p_section))
         return;
 
-    handle_bat();
+    handle_bat(p_bouquet);
 }
 
 /*****************************************************************************
@@ -681,9 +714,14 @@ static void handle_sdt_section(uint16_t i_pid, uint8_t *p_section)
 /*****************************************************************************
  * handle_eit
  *****************************************************************************/
-static void handle_eit_section(uint16_t i_pid, uint8_t *p_eit)
+static void handle_eit_section(uint16_t i_pid, uint8_t *p_section)
 {
-    if (i_pid != EIT_PID || !eit_validate(p_eit)) {
+    uint16_t i_sid;
+    uint8_t i_section;
+    sid_t *p_sid;
+    int i;
+
+    if (i_pid != EIT_PID || !eit_validate(p_section)) {
         switch (i_print_type) {
         case PRINT_XML:
             printf("<ERROR type=\"invalid_eit_section\" pid=\"%hu\"/>\n",
@@ -692,15 +730,49 @@ static void handle_eit_section(uint16_t i_pid, uint8_t *p_eit)
         default:
             printf("invalid EIT section received on PID %hu\n", i_pid);
         }
-        free(p_eit);
+        free(p_section);
+        return;
+    }
+
+    i_sid = psi_get_tableidext(p_section);
+    for (i = 0; i < i_nb_sids; i++)
+        if (pp_sids[i]->i_sid && pp_sids[i]->i_sid == i_sid)
+            break;
+    if (i == i_nb_sids) {
+        switch (i_print_type) {
+        case PRINT_XML:
+            printf("<ERROR type=\"ghost_eit\" sid=\"%hu\"/>\n", i_sid);
+            break;
+        default:
+            printf("ghost EIT for service %hu\n", i_sid);
+        }
+        p_sid = malloc(sizeof(sid_t));
+        pp_sids = realloc(pp_sids, ++i_nb_sids * sizeof(sid_t *));
+        pp_sids[i] = p_sid;
+        p_sid->i_sid = i_sid;
+        p_sid->i_pmt_pid = 0;
+        p_sid->p_current_pmt = NULL;
+        psi_table_init(p_sid->pp_eit_sections);
+    } else
+        p_sid = pp_sids[i];
+
+    /* We do not use psi_table_* primitives as the spec allows for holes in
+     * section numbering, and there is no sure way to know whether you have
+     * gathered all sections. */
+    i_section = psi_get_section(p_section);
+    if (p_sid->pp_eit_sections[i_section] != NULL &&
+        psi_compare(p_sid->pp_eit_sections[i_section], p_section)) {
+        /* Identical section. Shortcut. */
+        free(p_section);
         return;
     }
 
+    free(p_sid->pp_eit_sections[i_section]);
+    p_sid->pp_eit_sections[i_section] = p_section;
+
     if (pb_print_table[TABLE_EIT])
-        eit_print(p_eit, print_wrapper, NULL, iconv_wrapper, NULL,
+        eit_print(p_section, print_wrapper, NULL, iconv_wrapper, NULL,
                   i_print_type);
-
-    free(p_eit);
 }
 
 /*****************************************************************************
@@ -896,14 +968,11 @@ static void handle_section(uint16_t i_pid, uint8_t *p_section)
         handle_sit_section(i_pid, p_section);
         break;
 
-    default:
-        if (i_table_id == EIT_TABLE_ID_PF_ACTUAL ||
-           (i_table_id >= EIT_TABLE_ID_SCHED_ACTUAL_FIRST &&
-            i_table_id <= EIT_TABLE_ID_SCHED_ACTUAL_LAST)) {
-            handle_eit_section(i_pid, p_section);
-            break;
-        }
+    case EIT_TABLE_ID_PF_ACTUAL:
+        handle_eit_section(i_pid, p_section);
+        break;
 
+    default:
         free( p_section );
         break;
     }
@@ -1009,8 +1078,8 @@ int main(int i_argc, char **ppsz_argv)
 
     for (i = 0; i < 8192; i++) {
         p_pids[i].i_last_cc = -1;
-        psi_assemble_init( &p_pids[i].p_psi_buffer,
-                           &p_pids[i].i_psi_buffer_used );
+        psi_assemble_init(&p_pids[i].p_psi_buffer,
+                          &p_pids[i].i_psi_buffer_used);
     }
 
     p_pids[PAT_PID].i_psi_refcount++;
@@ -1025,6 +1094,17 @@ int main(int i_argc, char **ppsz_argv)
     p_pids[DIT_PID].i_psi_refcount++;
     p_pids[SIT_PID].i_psi_refcount++;
 
+    psi_table_init(pp_current_pat_sections);
+    psi_table_init(pp_next_pat_sections);
+    psi_table_init(pp_current_cat_sections);
+    psi_table_init(pp_next_cat_sections);
+    psi_table_init(pp_current_tsdt_sections);
+    psi_table_init(pp_next_tsdt_sections);
+    psi_table_init(pp_current_nit_sections);
+    psi_table_init(pp_next_nit_sections);
+    psi_table_init(pp_current_sdt_sections);
+    psi_table_init(pp_next_sdt_sections);
+
     if (psz_tables != NULL) {
         char *psz_table = psz_tables;
         for (i = 0; i < TABLE_END; i++)
@@ -1084,5 +1164,37 @@ int main(int i_argc, char **ppsz_argv)
         break;
     }
 
+    if (iconv_handle != (iconv_t)-1)
+        iconv_close(iconv_handle);
+
+    psi_table_free(pp_current_pat_sections);
+    psi_table_free(pp_next_pat_sections);
+    psi_table_free(pp_current_cat_sections);
+    psi_table_free(pp_next_cat_sections);
+    psi_table_free(pp_current_tsdt_sections);
+    psi_table_free(pp_next_tsdt_sections);
+    psi_table_free(pp_current_nit_sections);
+    psi_table_free(pp_next_nit_sections);
+    psi_table_free(pp_current_sdt_sections);
+    psi_table_free(pp_next_sdt_sections);
+
+    for (i = 0; i < i_nb_bouquets; i++) {
+        psi_table_free(pp_bouquets[i]->pp_current_bat_sections);
+        psi_table_free(pp_bouquets[i]->pp_next_bat_sections);
+        free(pp_bouquets[i]);
+    }
+    free(pp_bouquets);
+
+    for (i = 0; i < i_nb_sids; i++) {
+        psi_table_free(pp_sids[i]->pp_eit_sections);
+        free(pp_sids[i]->p_current_pmt);
+        free(pp_sids[i]);
+    }
+    free(pp_sids);
+
+    for (i = 0; i < 8192; i++)
+        psi_assemble_reset(&p_pids[i].p_psi_buffer,
+                           &p_pids[i].i_psi_buffer_used);
+
     return EXIT_SUCCESS;
 }
diff --git a/examples/dvb_print_si.output.txt b/examples/dvb_print_si.output.txt
index 815f3ea..2772124 100644
--- a/examples/dvb_print_si.output.txt
+++ b/examples/dvb_print_si.output.txt
@@ -141,9 +141,9 @@ new SDT actual tsid=10000 version=1 onid=40000
     - desc 4b nvod_reference tsid=10200 onid=40200 sid=20200
     - desc 5f private_data specifier=0xaabbccdd
 end SDT
-new EIT tableid=0x4e type=actual_pf version=0 tsid=10000 onid=40000 seg_last_sec_number=0 last_table_id=0x00
+new EIT tableid=0x4e type=actual_pf service_id=20000 version=0 tsid=10000 onid=40000 seg_last_sec_number=0 last_table_id=0x00
 end EIT
-new EIT tableid=0x4e type=actual_pf version=1 tsid=10000 onid=40000 seg_last_sec_number=0 last_table_id=0x00
+new EIT tableid=0x4e type=actual_pf service_id=20000 version=1 tsid=10000 onid=40000 seg_last_sec_number=0 last_table_id=0x00
   * EVENT id=30000 start_time=1234567890 start_time_dec="2009-02-13 23:31:30 UTC" duration=86399 duration_dec=23:59:59 running_status=2 free_CA_mode=0
     - desc 4d short_event lang=eng event_name="Major TV event" text="The event of the century!"
   * EVENT id=30100 start_time=1 start_time_dec="1970-01-01 00:00:01 UTC" duration=3600 duration_dec=01:00:00 running_status=1 free_CA_mode=0
diff --git a/examples/dvb_print_si.output.xml b/examples/dvb_print_si.output.xml
index 955713e..727bea7 100644
--- a/examples/dvb_print_si.output.xml
+++ b/examples/dvb_print_si.output.xml
@@ -248,9 +248,9 @@
 </DESC>
 </SERVICE>
 </SDT>
-<EIT tableid="0x4e" type="actual_pf" version="0" current_next="1" tsid="10000" onid="40000" seg_last_sec_number="0" last_table_id="0x00">
+<EIT tableid="0x4e" type="actual_pf" service_id="20000" version="0" current_next="1" tsid="10000" onid="40000" seg_last_sec_number="0" last_table_id="0x00">
 </EIT>
-<EIT tableid="0x4e" type="actual_pf" version="1" current_next="1" tsid="10000" onid="40000" seg_last_sec_number="0" last_table_id="0x00">
+<EIT tableid="0x4e" type="actual_pf" service_id="20000" version="1" current_next="1" tsid="10000" onid="40000" seg_last_sec_number="0" last_table_id="0x00">
 <EVENT id="30000" start_time="1234567890" start_time_dec="2009-02-13 23:31:30 UTC" duration="86399" duration_dec="23:59:59" running_status="2" free_CA_mode="0">
 <DESC id="0x4d" length="44" value="656e670e4d616a6f72205456206576656e7419546865206576656e74206f66207468652063656e7475727921">
 <SHORT_EVENT_DESC lang="eng" event_name="Major TV event" text="The event of the century!"/>
diff --git a/ietf/rtp.h b/ietf/rtp.h
index 37419c7..68bcf45 100644
--- a/ietf/rtp.h
+++ b/ietf/rtp.h
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * rtp.h: Real-Time Protocol
+ * rtp.h: Real-time Transport Protocol
  *****************************************************************************
  * Copyright (C) 2009 VideoLAN
  *
diff --git a/mpeg/ts.h b/mpeg/ts.h
index 4bcedc5..c343916 100644
--- a/mpeg/ts.h
+++ b/mpeg/ts.h
@@ -250,7 +250,7 @@ static inline bool tsaf_has_pcr(const uint8_t *p_ts)
 
 static inline uint64_t tsaf_get_pcr(const uint8_t *p_ts)
 {
-    return (p_ts[6] << 25) | (p_ts[7] << 17) | (p_ts[8] << 9) | (p_ts[9] << 1) |
+    return ((uint64_t) p_ts[6] << 25) | (p_ts[7] << 17) | (p_ts[8] << 9) | (p_ts[9] << 1) |
            (p_ts[10] >> 7);
 }
 
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin