Example #1
0
/*****************************************************************************
 * dvbpsi_GatherBATSections
 *****************************************************************************
 * Callback for the subtable demultiplexor.
 *****************************************************************************/
void dvbpsi_GatherBATSections(dvbpsi_t *p_dvbpsi,
                              void * p_private_decoder,
                              dvbpsi_psi_section_t * p_section)
{
    dvbpsi_demux_t *p_demux = (dvbpsi_demux_t *) p_dvbpsi->p_private;
    dvbpsi_bat_decoder_t * p_bat_decoder
                        = (dvbpsi_bat_decoder_t*)p_private_decoder;

    bool b_reinit = false;

    assert(p_dvbpsi);
    assert(p_dvbpsi->p_private);

    if (!p_section->b_syntax_indicator)
    {
        /* Invalid section_syntax_indicator */
        dvbpsi_error(p_dvbpsi, "BAT decoder",
                     "invalid section (section_syntax_indicator == 0)");
        dvbpsi_DeletePSISections(p_section);
        return;
    }

    dvbpsi_debug(p_dvbpsi, "BAT decoder",
                   "Table version %2d, " "i_table_id %2d, " "i_extension %5d, "
                   "section %3d up to %3d, " "current %1d",
                   p_section->i_version, p_section->i_table_id,
                   p_section->i_extension,
                   p_section->i_number, p_section->i_last_number,
                   p_section->b_current_next);

    /* We have a valid BAT section */
    /* TS discontinuity check */
    if (p_demux->b_discontinuity)
    {
        b_reinit = true;
        p_demux->b_discontinuity = false;
    }
    else
    {
        /* Perform a few sanity checks */
        if (p_bat_decoder->p_building_bat)
        {
            if (p_bat_decoder->p_building_bat->i_bouquet_id != p_section->i_extension)
            {
                /* bouquet_id */
                dvbpsi_error(p_dvbpsi, "BAT decoder", "'bouquet_id' differs"
                                " whereas no TS discontinuity has occured");
                b_reinit = true;
            }
            else if (p_bat_decoder->p_building_bat->i_version
                                                != p_section->i_version)
            {
                /* version_number */
                dvbpsi_error(p_dvbpsi, "BAT decoder", "'version_number' differs"
                                " whereas no discontinuity has occured");
                b_reinit = true;
            }
            else if (p_bat_decoder->i_last_section_number !=
                                                p_section->i_last_number)
            {
                /* last_section_number */
                dvbpsi_error(p_dvbpsi, "BAT decoder", "'last_section_number' differs"
                                " whereas no discontinuity has occured");
                b_reinit = true;
            }
        }
        else
        {
            if (   (p_bat_decoder->b_current_valid)
                && (p_bat_decoder->current_bat.i_version == p_section->i_version)
                && (p_bat_decoder->current_bat.b_current_next ==
                                               p_section->b_current_next))
            {
                /* Don't decode since this version is already decoded */
                dvbpsi_debug(p_dvbpsi, "BAT decoder",
                             "ignoring already decoded section %d",
                             p_section->i_number);
            }
            else if (  (!p_bat_decoder->current_bat.b_current_next)
                     && (p_section->b_current_next))
            {
                /* Signal a new BAT if the previous one wasn't active */
                dvbpsi_bat_t *p_bat = (dvbpsi_bat_t*)malloc(sizeof(dvbpsi_bat_t));
                if (p_bat)
                {
                    p_bat_decoder->current_bat.b_current_next = true;
                    memcpy(p_bat, &p_bat_decoder->current_bat, sizeof(dvbpsi_bat_t));
                    p_bat_decoder->pf_bat_callback(p_bat_decoder->p_cb_data, p_bat);
                }
                else
                    dvbpsi_error(p_dvbpsi, "BAT decoder", "Could not signal new BAT.");
            }
            dvbpsi_DeletePSISections(p_section);
            return;
        }
    }

    /* Reinit the decoder if wanted */
    if (b_reinit)
    {
        /* Force redecoding */
        p_bat_decoder->b_current_valid = false;
        /* Free structures */
        if (p_bat_decoder->p_building_bat)
        {
            free(p_bat_decoder->p_building_bat);
            p_bat_decoder->p_building_bat = NULL;
        }
        /* Clear the section array */
        for (unsigned int i = 0; i < 256; i++)
        {
            if (p_bat_decoder->ap_sections[i] != NULL)
            {
                dvbpsi_DeletePSISections(p_bat_decoder->ap_sections[i]);
                p_bat_decoder->ap_sections[i] = NULL;
            }
        }
    }

    /* Append the section to the list if wanted */
    bool b_complete = false;

    /* Initialize the structures if it's the first section received */
    if (!p_bat_decoder->p_building_bat)
    {
        p_bat_decoder->p_building_bat =
                            (dvbpsi_bat_t*)malloc(sizeof(dvbpsi_bat_t));
        if (p_bat_decoder->p_building_bat)
            dvbpsi_InitBAT(p_bat_decoder->p_building_bat,
                         p_section->i_extension,
                         p_section->i_version,
                         p_section->b_current_next);
        else
            dvbpsi_error(p_dvbpsi, "BAT decoder", "failed decoding BAT section");

        p_bat_decoder->i_last_section_number = p_section->i_last_number;
    }

    /* Fill the section array */
    if (p_bat_decoder->ap_sections[p_section->i_number] != NULL)
    {
        dvbpsi_debug(p_dvbpsi, "BAT decoder", "overwrite section number %d",
                     p_section->i_number);
        dvbpsi_DeletePSISections(p_bat_decoder->ap_sections[p_section->i_number]);
    }
    p_bat_decoder->ap_sections[p_section->i_number] = p_section;

    /* Check if we have all the sections */
    for (unsigned int i = 0; i <= p_bat_decoder->i_last_section_number; i++)
    {
        if (!p_bat_decoder->ap_sections[i])
            break;
        if (i == p_bat_decoder->i_last_section_number)
            b_complete = true;
    }

    if (b_complete)
    {
        /* Save the current information */
        p_bat_decoder->current_bat = *p_bat_decoder->p_building_bat;
        p_bat_decoder->b_current_valid = true;
        /* Chain the sections */
        if (p_bat_decoder->i_last_section_number)
        {
            for (int j = 0; j <= p_bat_decoder->i_last_section_number - 1; j++)
                p_bat_decoder->ap_sections[j]->p_next =
                                    p_bat_decoder->ap_sections[j + 1];
        }
        /* Decode the sections */
        dvbpsi_DecodeBATSections(p_bat_decoder->p_building_bat,
                                 p_bat_decoder->ap_sections[0]);
        /* Delete the sections */
        dvbpsi_DeletePSISections(p_bat_decoder->ap_sections[0]);
        /* signal the new BAT */
        p_bat_decoder->pf_bat_callback(p_bat_decoder->p_cb_data,
                                       p_bat_decoder->p_building_bat);
        /* Reinitialize the structures */
        p_bat_decoder->p_building_bat = NULL;
        for (unsigned int i = 0; i <= p_bat_decoder->i_last_section_number; i++)
            p_bat_decoder->ap_sections[i] = NULL;
    }
}
Example #2
0
/*****************************************************************************
 * dvbpsi_GatherBATSections
 *****************************************************************************
 * Callback for the PSI decoder.
 *****************************************************************************/
void dvbpsi_GatherBATSections(dvbpsi_decoder_t * p_decoder,
                              void * p_private_decoder,
                              dvbpsi_psi_section_t * p_section)
{
  dvbpsi_bat_decoder_t* p_bat_decoder
                        = (dvbpsi_bat_decoder_t*)p_private_decoder;
  int b_append = 1;
  int b_reinit = 0;
  unsigned int i;

  DVBPSI_DEBUG_ARG("BAT decoder",
                   "Table version %2d, " "i_extension %5d, "
                   "section %3d up to %3d, " "current %1d",
                   p_section->i_version, p_section->i_extension,
                   p_section->i_number, p_section->i_last_number,
                   p_section->b_current_next);

  if(p_section->i_table_id != 0x40 && p_section->i_table_id != 0x41)
  {
    /* Invalid table_id value */
    DVBPSI_ERROR_ARG("BAT decoder",
                     "invalid section (table_id == 0x%02x)",
                     p_section->i_table_id);
    b_append = 0;
  }

  if(b_append && !p_section->b_syntax_indicator)
  {
    /* Invalid section_syntax_indicator */
    DVBPSI_ERROR("BAT decoder",
                 "invalid section (section_syntax_indicator == 0)");
    b_append = 0;
  }

  /* Now if b_append is true then we have a valid BAT section */
  if(b_append && (p_bat_decoder->i_bouquet_id != p_section->i_extension))
  {
    /* Invalid program_number */
#if 0
    DVBPSI_ERROR("BAT decoder", "'bouquet_id' don't match");
#endif
    b_append = 0;
  }

  if(b_append)
  {
    /* TS discontinuity check */
    if(p_decoder->b_discontinuity)
    {
      b_reinit = 1;
      p_decoder->b_discontinuity = 0;
    }
    else
    {
      /* Perform some few sanity checks */
      if(p_bat_decoder->p_building_bat)
      {
        if(p_bat_decoder->p_building_bat->i_version != p_section->i_version)
        {
          /* version_number */
          DVBPSI_ERROR("BAT decoder",
                       "'version_number' differs"
                       " whereas no discontinuity has occured");
          b_reinit = 1;
        }
        else if(p_bat_decoder->i_last_section_number
                                                != p_section->i_last_number)
        {
          /* last_section_number */
          DVBPSI_ERROR("BAT decoder",
                       "'last_section_number' differs"
                       " whereas no discontinuity has occured");
          b_reinit = 1;
        }
      }
      else
      {
        if(    (p_bat_decoder->b_current_valid)
            && (p_bat_decoder->current_bat.i_version == p_section->i_version)
            && (p_bat_decoder->current_bat.b_current_next ==
                                           p_section->b_current_next))
        {
          /* Don't decode since this version is already decoded */
          b_append = 0;
        }
      }
    }
  }

  /* Reinit the decoder if wanted */
  if(b_reinit)
  {
    /* Force redecoding */
    p_bat_decoder->b_current_valid = 0;
    /* Free structures */
    if(p_bat_decoder->p_building_bat)
    {
      free(p_bat_decoder->p_building_bat);
      p_bat_decoder->p_building_bat = NULL;
    }
    /* Clear the section array */
    for(i = 0; i <= 255; i++)
    {
      if(p_bat_decoder->ap_sections[i] != NULL)
      {
        dvbpsi_DeletePSISections(p_bat_decoder->ap_sections[i]);
        p_bat_decoder->ap_sections[i] = NULL;
      }
    }
  }

  /* Append the section to the list if wanted */
  if(b_append)
  {
    int b_complete;

    /* Initialize the structures if it's the first section received */
    if(!p_bat_decoder->p_building_bat)
    {
      p_bat_decoder->p_building_bat =
                                (dvbpsi_bat_t*)malloc(sizeof(dvbpsi_bat_t));
      dvbpsi_InitBAT(p_bat_decoder->p_building_bat,
                     p_bat_decoder->i_bouquet_id,
                     p_section->i_version,
                     p_section->b_current_next);
      p_bat_decoder->i_last_section_number = p_section->i_last_number;
    }

    /* Fill the section array */
    if(p_bat_decoder->ap_sections[p_section->i_number] != NULL)
    {
      DVBPSI_DEBUG_ARG("BAT decoder", "overwrite section number %d",
                       p_section->i_number);
      dvbpsi_DeletePSISections(p_bat_decoder->ap_sections[p_section->i_number]);
    }
    p_bat_decoder->ap_sections[p_section->i_number] = p_section;

    /* Check if we have all the sections */
    b_complete = 0;
    for(i = 0; i <= p_bat_decoder->i_last_section_number; i++)
    {
      if(!p_bat_decoder->ap_sections[i])
        break;

      if(i == p_bat_decoder->i_last_section_number)
        b_complete = 1;
    }

    if(b_complete)
    {
      /* Save the current information */
      p_bat_decoder->current_bat = *p_bat_decoder->p_building_bat;
      p_bat_decoder->b_current_valid = 1;
      /* Chain the sections */
      if(p_bat_decoder->i_last_section_number)
      {
        for(i = 0; (int)i <= p_bat_decoder->i_last_section_number - 1; i++)
          p_bat_decoder->ap_sections[i]->p_next =
                                        p_bat_decoder->ap_sections[i + 1];
      }
      /* Decode the sections */
      dvbpsi_DecodeBATSections(p_bat_decoder->p_building_bat,
                               p_bat_decoder->ap_sections[0]);
      /* Delete the sections */
      dvbpsi_DeletePSISections(p_bat_decoder->ap_sections[0]);
      /* signal the new BAT */
      p_bat_decoder->pf_callback(p_bat_decoder->p_cb_data,
                                 p_bat_decoder->p_building_bat);
      /* Reinitialize the structures */
      p_bat_decoder->p_building_bat = NULL;
      for(i = 0; i <= p_bat_decoder->i_last_section_number; i++)
        p_bat_decoder->ap_sections[i] = NULL;
    }
  }
  else
  {
    dvbpsi_DeletePSISections(p_section);
  }
}