[patch] EIT decoder problem

Johann Hanne <[email protected]>
Newsgroups gmane.comp.video.videolan.libdvbpsi.devel
Message-ID <200704072141.31287.jhml__6375.26580035246$1175968677$gmane$org@gmx.net>
Hi,

there seems to be a problem with the EIT decoder.

The current SVN version contains the following code in src/tables/eit.c:
--
    /* Check if we have all the sections */
    b_complete = 0;
    for(i = 0; i <= p_eit_decoder->i_last_section_number; i++)
    {
      if(!p_eit_decoder->ap_sections[i])
        break;

      if(i == p_eit_decoder->i_last_section_number)
        b_complete = 1;
    }
--
I.e. if it has not received *every* section_number from 0 to 
last_section_number, it will discard everything. This seems to be the correct 
thing for every PSI table but the EIT.  ETSI EN 300 468 V1.5.1 (2003-01) says 
the following for the section_number of an EIT:
--
section_number: This 8-bit field gives the number of the section. The 
section_number of the first section in the sub_table shall be "0x00". The 
section_number shall be incremented by 1 with each additional section with 
the same table_id, service_id, transport_stream_id, and original_network_id. 
In this case, the sub_table may be structured as a number of segments. Within 
each segment the section_number shall increment by 1 with each additional 
section, but a gap in numbering is permitted between the last section of a 
segment and the first section of the adjacent segment.
--
The point seems to be "a gap in numbering is permitted". To be honest, I don't 
understand the whole paragraph: As far as I understand, PSI tables are put 
into sections, and sections are split into TS packets. Sections have a 
maximum of 1024/4096 bytes and thus a PSI table which is too large may be put 
into more than one section (this is what section_number and 
last_section_number is all about). However, I don't understand what "segment" 
means and specifically not "section of a segment". Can somebody give me a 
hint, please?

Whatsoever, I've added the following debug code to src/dvbpsi.c:
--
         if(p_section->b_syntax_indicator)
          {
            p_section->i_extension =   (p_section->p_data[3] << 8)
                                     | p_section->p_data[4];
            p_section->i_version = (p_section->p_data[5] & 0x3e) >> 1;
            p_section->b_current_next = p_section->p_data[5] & 0x1;
            p_section->i_number = p_section->p_data[6];
            p_section->i_last_number = p_section->p_data[7];
            p_section->p_payload_start = p_section->p_data + 8;

            /* new code >>> */
            if (((((uint16_t)(p_data[1] & 0x1f) << 8) | p_data[2]) == 0x12) &&
                p_section->i_table_id == 0x50 &&
                p_section->i_extension == 28106) {
              printf("i_table_id=0x%02x, i_extension=%d, i_number=%d, 
i_last_number=%d\n",
                     p_section->i_table_id,  p_section->i_extension,
                     p_section->i_number, p_section->i_last_number);
            }
/* <<< new code */
--
0x50 is the subtable for the scheduled events of the current TS, 28106 is the 
service id of a german TV station (ARD/Das Erste). When I feed the EIT PID 
0x12 to libdvbpsi now, this gives the following output:
--
...
i_table_id=0x50, i_extension=28106, i_number=56, i_last_number=248
i_table_id=0x50, i_extension=28106, i_number=64, i_last_number=248
i_table_id=0x50, i_extension=28106, i_number=72, i_last_number=248
i_table_id=0x50, i_extension=28106, i_number=80, i_last_number=248
i_table_id=0x50, i_extension=28106, i_number=88, i_last_number=248
i_table_id=0x50, i_extension=28106, i_number=96, i_last_number=248
i_table_id=0x50, i_extension=28106, i_number=104, i_last_number=248
...
--
So there are indeed gaps in section_number. The attached patch modifies 
src/tables/eit.c so that accepts the gaps. It's not perfect, but it works.

Comments, please?

Cheers,
  Johann
libdvbpsi-eit.patch (text/x-diff, 1.4 KB)
--- src/tables/eit.c.orig	2007-04-07 21:03:20.000000000 +0200
+++ src/tables/eit.c	2007-04-07 21:05:39.000000000 +0200
@@ -418,13 +418,9 @@
 
     /* Check if we have all the sections */
     b_complete = 0;
-    for(i = 0; i <= p_eit_decoder->i_last_section_number; i++)
-    {
-      if(!p_eit_decoder->ap_sections[i])
-        break;
-
-      if(i == p_eit_decoder->i_last_section_number)
-        b_complete = 1;
+    if (p_eit_decoder->ap_sections[0] != NULL &&
+        p_section->i_number == p_eit_decoder->i_last_section_number) {
+      b_complete = 1;
     }
 
     if(b_complete)
@@ -435,9 +431,17 @@
       /* Chain the sections */
       if(p_eit_decoder->i_last_section_number)
       {
-        for(i = 0; i <= p_eit_decoder->i_last_section_number - 1; i++)
-          p_eit_decoder->ap_sections[i]->p_next =
-                                        p_eit_decoder->ap_sections[i + 1];
+        dvbpsi_psi_section_t * p_last_section;
+
+        p_last_section = p_eit_decoder->ap_sections[0];
+        for(i = 1; i <= p_eit_decoder->i_last_section_number; i++)
+        {
+          if (p_eit_decoder->ap_sections[i] != NULL)
+          {
+            p_last_section->p_next = p_eit_decoder->ap_sections[i];
+            p_last_section = p_eit_decoder->ap_sections[i];
+          }
+        }
       }
       /* Decode the sections */
       dvbpsi_DecodeEITSections(p_eit_decoder->p_building_eit,
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.