NIT and BAT tables bugs

Angelo Schiavone <[email protected]>
Newsgroups gmane.comp.video.videolan.libdvbpsi.devel
Message-ID <CADyCdYd-YCcPfMeH3A9GvEy_5KE6iVBrfgX=88ENqHA1mphqVQ@mail.gmail.com>
Hi, my name is Angelo Schiavone and I'm a developer working
on a dvb transport stream analyzer which uses libdvbpsi version 1.0.0
library.
First of all thanks a lot for sharing your efforts.
I've noticed that there are 2 bugs in decoding BAT and NIT
tables, according to ETSI EN 300 468 standard, which makes tables decoding
wrong.

In BAT.c file ->  "dvbpsi_bat_sections_decode" function is :

void dvbpsi_bat_sections_decode(dvbpsi_bat_t* p_bat,

                              dvbpsi_psi_section_t* p_section)

{

  uint8_t* p_byte, * p_end, * p_end2;

  while(p_section)

  {

    /* - first loop descriptors */

    p_byte = p_section->p_payload_start + 2;

    p_end = p_byte + ( ((uint16_t)(p_section->p_payload_start[0] & 0x0f) << 8)

                       | p_section->p_payload_start[1]);

    while(p_byte + 2 <= p_end)

    {

      uint8_t i_tag = p_byte[0];

      uint8_t i_length = p_byte[1];

      if(i_length + 2 <= p_end - p_byte)

        dvbpsi_bat_bouquet_descriptor_add(p_bat, i_tag, i_length, p_byte + 2);

      p_byte += 2 + i_length;

    }

    p_end = p_byte + ( ((uint16_t)(p_byte[0] & 0x0f) << 8)

                       | p_byte[1]);

    if(p_end > p_section->p_payload_end)

    {

        p_end = p_section->p_payload_end;

    }

    /* - TSs */

    for(; p_byte + 6 <= p_end;)

    {

      p_byte += 2;

      uint16_t i_ts_id = ((uint16_t)p_byte[0] << 8) | p_byte[1];

      uint16_t i_orig_network_id = ((uint16_t)p_byte[2] << 8) | p_byte[3];

      uint16_t i_transport_descriptors_length = ((uint16_t)(p_byte[4]
& 0x0f) << 8) | p_byte[5];

      dvbpsi_bat_ts_t* p_ts = dvbpsi_bat_ts_add(p_bat, i_ts_id,
i_orig_network_id);

      /* - TS descriptors */

      p_byte += 6;

      p_end2 = p_byte + i_transport_descriptors_length;

      if( p_end2 > p_section->p_payload_end )

      {

            p_end2 = p_section->p_payload_end;

      }

      while(p_byte + 2 <= p_end2)

      {

        uint8_t i_tag = p_byte[0];

        uint8_t i_length = p_byte[1];

        if(i_length + 2 <= p_end2 - p_byte)

          dvbpsi_bat_ts_descriptor_add(p_ts, i_tag, i_length, p_byte + 2);

        p_byte += 2 + i_length;

      }

    }

    p_section = p_section->p_next;

  }

}




while it should be:

void dvbpsi_bat_sections_decode(dvbpsi_bat_t* p_bat,

                              dvbpsi_psi_section_t* p_section)

{

  uint8_t* p_byte, * p_end, * p_end2;

  while(p_section)

  {

    /* - first loop descriptors */

    p_byte = p_section->p_payload_start + 2;

    p_end = p_byte + ( ((uint16_t)(p_section->p_payload_start[0] & 0x0f) << 8)

                       | p_section->p_payload_start[1]);

    while(p_byte + 2 <= p_end)

    {

      uint8_t i_tag = p_byte[0];

      uint8_t i_length = p_byte[1];

      if(i_length + 2 <= p_end - p_byte)

        dvbpsi_bat_bouquet_descriptor_add(p_bat, i_tag, i_length, p_byte + 2);

      p_byte += 2 + i_length;

    }

    p_end =  2 +p_byte + ( ((uint16_t)(p_byte[0] & 0x0f) << 8)

                       | p_byte[1]);

    if(p_end > p_section->p_payload_end)

    {

        p_end = p_section->p_payload_end;

    }

    p_byte += 2;

    /* - TSs */

    for(; p_byte + 6 <= p_end;)

    {

      uint16_t i_ts_id = ((uint16_t)p_byte[0] << 8) | p_byte[1];

      uint16_t i_orig_network_id = ((uint16_t)p_byte[2] << 8) | p_byte[3];

      uint16_t i_transport_descriptors_length = ((uint16_t)(p_byte[4]
& 0x0f) << 8) | p_byte[5];

      dvbpsi_bat_ts_t* p_ts = dvbpsi_bat_ts_add(p_bat, i_ts_id,
i_orig_network_id);

      /* - TS descriptors */

      p_byte += 6;

      p_end2 = p_byte + i_transport_descriptors_length;

      if( p_end2 > p_section->p_payload_end )

      {

            p_end2 = p_section->p_payload_end;

      }

      while(p_byte + 2 <= p_end2)

      {

        uint8_t i_tag = p_byte[0];

        uint8_t i_length = p_byte[1];

        if(i_length + 2 <= p_end2 - p_byte)

          dvbpsi_bat_ts_descriptor_add(p_ts, i_tag, i_length, p_byte + 2);

        p_byte += 2 + i_length;

      }

    }

    p_section = p_section->p_next;

  }

}



In NIT.c file ->  "dvbpsi_nit_sections_decode" function is :

void dvbpsi_nit_sections_decode(dvbpsi_nit_t* p_nit,

                                dvbpsi_psi_section_t* p_section)

{

    uint8_t* p_byte, * p_end, * p_end2;

    while (p_section)

    {

        /* - NIT descriptors */

        p_byte = p_section->p_payload_start + 2;

        p_end = p_byte + (   ((uint16_t)(p_section->p_payload_start[0]
& 0x0f) << 8)

                           | p_section->p_payload_start[1]);

        while (p_byte + 2 <= p_end)

        {

            uint8_t i_tag = p_byte[0];

            uint8_t i_length = p_byte[1];

            if (i_length + 2 <= p_end - p_byte)

                dvbpsi_nit_descriptor_add(p_nit, i_tag, i_length, p_byte + 2);

            p_byte += 2 + i_length;

        }

        p_end = p_byte + (   ((uint16_t)(p_byte[0] & 0x0f) << 8)

                       | p_byte[1]);

        if (p_end > p_section->p_payload_end)

        {

            p_end = p_section->p_payload_end;

        }

        p_byte += 2;

        /* - TSs */

        for (; p_byte + 6 <= p_end;)

        {

            uint16_t i_ts_id = ((uint16_t)p_byte[0] << 8) | p_byte[1];

            uint16_t i_orig_network_id = ((uint16_t)p_byte[2] << 8) | p_byte[3];

            uint16_t i_ts_length = ((uint16_t)(p_byte[4] & 0x0f) << 8)
| p_byte[5];

            dvbpsi_nit_ts_t* p_ts = dvbpsi_nit_ts_add(p_nit, i_ts_id,
i_orig_network_id);

            /* - TS descriptors */

            p_byte += 6;

            p_end2 = p_byte + i_ts_length;

            if ( p_end2 > p_section->p_payload_end )

            {

                p_end2 = p_section->p_payload_end;

            }

            while (p_byte + 2 <= p_end2)

            {

                uint8_t i_tag = p_byte[0];

                uint8_t i_length = p_byte[1];

                if (i_length + 2 <= p_end2 - p_byte)

                    dvbpsi_nit_ts_descriptor_add(p_ts, i_tag,
i_length, p_byte + 2);

                p_byte += 2 + i_length;

            }

        }

        p_section = p_section->p_next;

    }

}


while it should be:

void dvbpsi_nit_sections_decode(dvbpsi_nit_t* p_nit,

                                dvbpsi_psi_section_t* p_section)

{

    uint8_t* p_byte, * p_end, * p_end2;

    while (p_section)

    {

        /* - NIT descriptors */

        p_byte = p_section->p_payload_start + 2;

        p_end = p_byte + (   ((uint16_t)(p_section->p_payload_start[0]
& 0x0f) << 8)

                           | p_section->p_payload_start[1]);

        while (p_byte + 2 <= p_end)

        {

            uint8_t i_tag = p_byte[0];

            uint8_t i_length = p_byte[1];

            if (i_length + 2 <= p_end - p_byte)

                dvbpsi_nit_descriptor_add(p_nit, i_tag, i_length, p_byte + 2);

            p_byte += 2 + i_length;

        }

        p_end = 2+p_byte + (   ((uint16_t)(p_byte[0] & 0x0f) << 8)

                       | p_byte[1]);

        if (p_end > p_section->p_payload_end)

        {

            p_end = p_section->p_payload_end;

        }

        p_byte += 2;

        /* - TSs */

        for (; p_byte + 6 <= p_end;)

        {

            uint16_t i_ts_id = ((uint16_t)p_byte[0] << 8) | p_byte[1];

            uint16_t i_orig_network_id = ((uint16_t)p_byte[2] << 8) | p_byte[3];

            uint16_t i_ts_length = ((uint16_t)(p_byte[4] & 0x0f) << 8)
| p_byte[5];

            dvbpsi_nit_ts_t* p_ts = dvbpsi_nit_ts_add(p_nit, i_ts_id,
i_orig_network_id);

            /* - TS descriptors */

            p_byte += 6;

            p_end2 = p_byte + i_ts_length;

            if ( p_end2 > p_section->p_payload_end )

            {

                p_end2 = p_section->p_payload_end;

            }

            while (p_byte + 2 <= p_end2)

            {

                uint8_t i_tag = p_byte[0];

                uint8_t i_length = p_byte[1];

                if (i_length + 2 <= p_end2 - p_byte)

                    dvbpsi_nit_ts_descriptor_add(p_ts, i_tag,
i_length, p_byte + 2);

                p_byte += 2 + i_length;

            }

        }

        p_section = p_section->p_next;

    }

}


I highlighted in green the diff.

I discovered them when trying to decode a transort stream with a NIT and a
BAT with 2 TS in the loop, if the second TS in the TS loop does not contain
descriptors it wont be decoded/seen by libdvbpsi without this patch

_______________________________________________
libdvbpsi-devel mailing list
[email protected]
http://mailman.videolan.org/listinfo/libdvbpsi-devel
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.