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;