Re: [patch] EIT decoder problem

Johann Hanne <[email protected]>
Newsgroups gmane.comp.video.videolan.libdvbpsi.devel
Message-ID <200704091953.11451.jhml__31083.7185396396$1176141446$gmane$org@gmx.net>
Hi Christophe,

> Your reasoning is quite correct - libdvbpsi's behaviour is indeed
> non-compliant. But for a better understanding, you should have looked a
> few paragraphs below :
>
> segment_last_section_number: This 8-bit field specifies the number of
> the last section of this segment of the sub_table. For sub_tables which
> are not segmented, this field shall be set to the same value as the
> last_section_number field.
>
> So when a section with section_number == segment_last_section_number
> arrives, there may be a gap after this section. But it can't be anywhere
> in the sub_table, and it particular section_number must still start at
> 0. A gap is only allowed after a section with section_number ==
> segment_last_section is received.

thanks for the hint. The segment_last_section_number paragraph was indeed what 
I was missing, I think I now understand what's going on. However, I really 
don't know why it's done this way, and why it only applies to the EIT. If we 
miss a single segment now (and on my test transponder a segment only consists 
of one section), there is *zero* chance to detect that error. One could count 
the sections and make a new callback if the number of sections grows while 
the version number stays the same, but this would make the code even more 
confusing...

I've attached a new patch which should be ok now. Please apply if you don't 
have any more objections.

BTW, I'd be happy if you could release a 0.1.6 now, there are quite a few bugs 
fixed compared to 0.1.5. I have a rather complex application using PAT, PMT, 
SDT and EIT and it's working fine with latest SVN, so I'd like to sync with a 
release version.

Cheers, Johann
eit-fix.patch (text/x-diff, 3.3 KB)
--- libdvbpsi-svn141/src/tables/eit.c.orig	2007-04-09 18:48:16.000000000 +0200
+++ libdvbpsi-svn141/src/tables/eit.c	2007-04-09 18:43:17.000000000 +0200
@@ -405,6 +405,7 @@
                      p_section->p_payload_start[4],
                      p_section->p_payload_start[5]);
       p_eit_decoder->i_last_section_number = p_section->i_last_number;
+      p_eit_decoder->i_first_received_section_number = p_section->i_number;
     }
 
     /* Fill the section array */
@@ -418,13 +419,42 @@
 
     /* Check if we have all the sections */
     b_complete = 0;
-    for(i = 0; i <= p_eit_decoder->i_last_section_number; i++)
+    /* As there may be gaps in the section_number fields (see below), we 
+       have to wait until we have received a section_number twice - this 
+       is the only way to be sure that a complete table has been sent! */
+    if (p_section->i_number ==
+        p_eit_decoder->i_first_received_section_number)
     {
-      if(!p_eit_decoder->ap_sections[i])
-        break;
 
-      if(i == p_eit_decoder->i_last_section_number)
-        b_complete = 1;
+      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;
+          break;
+        }
+
+        /* ETSI EN 300 468 V1.5.1 section 5.2.4 says that the EIT
+           sections may be structured into a number of segments and
+           that there may be a gap in the section_number between
+           two segments (but not within a single segment); thus at
+           the end of a segment (indicated by
+           section_number == segment_last_section_number)
+           we have to search for the beginning of the next segment) */
+        if(i == p_eit_decoder->ap_sections[i]->p_payload_start[4])
+        {
+          while(!p_eit_decoder->ap_sections[i + 1] &&
+                (i + 1 < p_eit_decoder->i_last_section_number))
+          {
+            i++;
+          }
+        }
+
+      }
+
     }
 
     if(b_complete)
@@ -435,9 +465,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_prev_section;
+
+        p_prev_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_prev_section->p_next = p_eit_decoder->ap_sections[i];
+            p_prev_section = p_eit_decoder->ap_sections[i];
+          }
+        }
       }
       /* Decode the sections */
       dvbpsi_DecodeEITSections(p_eit_decoder->p_building_eit,
--- libdvbpsi-svn141/src/tables/eit_private.h.orig	2007-04-09 18:48:29.000000000 +0200
+++ libdvbpsi-svn141/src/tables/eit_private.h	2007-04-09 15:19:30.000000000 +0200
@@ -44,6 +44,7 @@
   int                           b_current_valid;
 
   uint8_t                       i_last_section_number;
+  uint8_t                       i_first_received_section_number;
   dvbpsi_psi_section_t *        ap_sections [256];
 
 } dvbpsi_eit_decoder_t;
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.