Exemplo n.º 1
0
/*****************************************************************************
 * dvbpsi_decoder_delete
 *****************************************************************************/
void dvbpsi_decoder_delete(dvbpsi_decoder_t *p_decoder)
{
    assert(p_decoder);

    if (p_decoder->p_sections)
    {
        dvbpsi_DeletePSISections(p_decoder->p_sections);
        p_decoder->p_sections = NULL;
    }

    dvbpsi_DeletePSISections(p_decoder->p_current_section);
    free(p_decoder);
}
Exemplo n.º 2
0
Arquivo: parse.cpp Projeto: gk1/teev
void parse::rewrite_pat()
{
	if (0 == service_ids.size())
		return;

#if !USING_DVBPSI_VERSION_0
	dvbpsi_class dvbpsi;
#else
#define dvbpsi_pat_init(a, b, c, d)     dvbpsi_InitPAT(a, b, c, d)
#define dvbpsi_pat_program_add(a, b, c) dvbpsi_PATAddProgram(a, b, c)
#define dvbpsi_pat_sections_generate(a, b, c) dvbpsi_GenPATSections(b, c)
#define dvbpsi_pat_empty(a) dvbpsi_EmptyPAT(a)
#endif
	dvbpsi_pat_t pat;
	dvbpsi_psi_section_t* p_section;
	const decoded_pat_t *decoded_pat = decoders[ts_id].get_decoded_pat();

	if (rewritten_pat_ver_offset == 0x1e)
		rewritten_pat_ver_offset = 0;

	dvbpsi_pat_init(&pat, ts_id, 0x1f & (++rewritten_pat_ver_offset + decoded_pat->version), 1);

	for (map_pidtype::const_iterator iter = service_ids.begin(); iter != service_ids.end(); ++iter)
		dvbpsi_pat_program_add(&pat, iter->first, ((decoded_pat_t *) decoded_pat)->programs[iter->first]);

	p_section = dvbpsi_pat_sections_generate(dvbpsi.get_handle(), &pat, 0);
	pat_pkt[0] = 0x47;
	pat_pkt[1] = pat_pkt[2] = pat_pkt[3] = 0x00;
	writePSI(pat_pkt, p_section);
	dvbpsi_DeletePSISections(p_section);
	dvbpsi_pat_empty(&pat);
}
Exemplo n.º 3
0
/*****************************************************************************
 * dvbpsi_decoder_reset
 *****************************************************************************/
void dvbpsi_decoder_reset(dvbpsi_decoder_t* p_decoder, const bool b_force)
{
    assert(p_decoder);

    /* Force redecoding */
    if (b_force)
        p_decoder->b_current_valid = false;

    /* Clear the section array */
    dvbpsi_DeletePSISections(p_decoder->p_sections);
    p_decoder->p_sections = NULL;
}
Exemplo n.º 4
0
Arquivo: cat.c Projeto: ares89/vlc
/*****************************************************************************
 * dvbpsi_DetachCAT
 *****************************************************************************
 * Close a CAT decoder. The handle isn't valid any more.
 *****************************************************************************/
void dvbpsi_DetachCAT(dvbpsi_handle h_dvbpsi)
{
  dvbpsi_cat_decoder_t* p_cat_decoder
                        = (dvbpsi_cat_decoder_t*)h_dvbpsi->p_private_decoder;

  free(p_cat_decoder->p_building_cat);

  for(unsigned int i = 0; i <= 255; i++)
  {
    if(p_cat_decoder->ap_sections[i])
      free(p_cat_decoder->ap_sections[i]);
  }

  free(h_dvbpsi->p_private_decoder);
  if(h_dvbpsi->p_current_section)
    dvbpsi_DeletePSISections(h_dvbpsi->p_current_section);
  free(h_dvbpsi);
}
Exemplo n.º 5
0
/*****************************************************************************
 * dvbpsi_DetachVCT
 *****************************************************************************
 * Close a VCT decoder. The handle isn't valid any more.
 *****************************************************************************/
void dvbpsi_DetachVCT(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension)
{
    assert(p_dvbpsi);
    assert(p_dvbpsi->p_private);

    dvbpsi_demux_t *p_demux = (dvbpsi_demux_t *) p_dvbpsi->p_private;
    dvbpsi_demux_subdec_t* p_subdec;
    dvbpsi_demux_subdec_t** pp_prev_subdec;
    dvbpsi_vct_decoder_t* p_vct_decoder;

    p_subdec = dvbpsi_demuxGetSubDec(p_demux, i_table_id, i_extension);
    if (p_subdec == NULL)
    {
        dvbpsi_error(p_dvbpsi, "VCT Decoder",
                     "No such VCT decoder (table_id == 0x%02x,"
                     "extension == 0x%02x)",
                     i_table_id, i_extension);
        return;
    }

    p_vct_decoder = (dvbpsi_vct_decoder_t*)p_subdec->p_cb_data;
    free(p_vct_decoder->p_building_vct);

    for (unsigned int i = 0; i <= 255; i++)
    {
        if (p_vct_decoder->ap_sections[i])
        {
            dvbpsi_DeletePSISections(p_vct_decoder->ap_sections[i]);
            p_vct_decoder->ap_sections[i] = NULL;
        }
    }
    free(p_subdec->p_cb_data);

    pp_prev_subdec = &p_demux->p_first_subdec;
    while(*pp_prev_subdec != p_subdec)
        pp_prev_subdec = &(*pp_prev_subdec)->p_next;

    *pp_prev_subdec = p_subdec->p_next;
    free(p_subdec);
    p_subdec = NULL;
}
Exemplo n.º 6
0
/*****************************************************************************
 * dvbpsi_DetachNIT
 *****************************************************************************
 * Close a NIT decoder.
 *****************************************************************************/
void dvbpsi_DetachNIT(dvbpsi_demux_t * p_demux, uint8_t i_table_id,
                      uint16_t i_extension)
{
  dvbpsi_demux_subdec_t* p_subdec;
  dvbpsi_demux_subdec_t** pp_prev_subdec;
  dvbpsi_nit_decoder_t* p_nit_decoder;

  unsigned int i;

  p_subdec = dvbpsi_demuxGetSubDec(p_demux, i_table_id, i_extension);

  if(p_demux == NULL)
  {
    DVBPSI_ERROR_ARG("NIT Decoder",
                     "No such NIT decoder (table_id == 0x%02x,"
                     "extension == 0x%02x)",
                     i_table_id, i_extension);
    return;
  }

  p_nit_decoder = (dvbpsi_nit_decoder_t*)p_subdec->p_cb_data;

  free(p_nit_decoder->p_building_nit);

  for(i = 0; i <= 255; i++)
  {
    if(p_nit_decoder->ap_sections[i])
      dvbpsi_DeletePSISections(p_nit_decoder->ap_sections[i]);
  }

  free(p_subdec->p_cb_data);

  pp_prev_subdec = &p_demux->p_first_subdec;
  while(*pp_prev_subdec != p_subdec)
    pp_prev_subdec = &(*pp_prev_subdec)->p_next;

  *pp_prev_subdec = p_subdec->p_next;
  free(p_subdec);
}
Exemplo n.º 7
0
/*****************************************************************************
 * dvbpsi_packet_push
 *****************************************************************************
 * Injection of a TS packet into a PSI decoder.
 *****************************************************************************/
bool dvbpsi_packet_push(dvbpsi_t *p_dvbpsi, uint8_t* p_data)
{
    uint8_t i_expected_counter;           /* Expected continuity counter */
    dvbpsi_psi_section_t* p_section;      /* Current section */
    uint8_t* p_payload_pos;               /* Where in the TS packet */
    uint8_t* p_new_pos = NULL;            /* Beginning of the new section,
                                             updated to NULL when the new
                                             section is handled */
    int i_available;                      /* Byte count available in the
                                             packet */

    dvbpsi_decoder_t *p_decoder = p_dvbpsi->p_decoder;
    assert(p_decoder);

    /* TS start code */
    if (p_data[0] != 0x47)
    {
        dvbpsi_error(p_dvbpsi, "PSI decoder", "not a TS packet");
        return false;
    }

    /* Continuity check */
    bool b_first = (p_decoder->i_continuity_counter == DVBPSI_INVALID_CC);
    if (b_first)
        p_decoder->i_continuity_counter = p_data[3] & 0xf;
    else
    {
        i_expected_counter = (p_decoder->i_continuity_counter + 1) & 0xf;
        p_decoder->i_continuity_counter = p_data[3] & 0xf;

        if (i_expected_counter == ((p_decoder->i_continuity_counter + 1) & 0xf)
            && !p_decoder->b_discontinuity)
        {
            dvbpsi_error(p_dvbpsi, "PSI decoder",
                     "TS duplicate (received %d, expected %d) for PID %d",
                     p_decoder->i_continuity_counter, i_expected_counter,
                     ((uint16_t)(p_data[1] & 0x1f) << 8) | p_data[2]);
            return false;
        }

        if (i_expected_counter != p_decoder->i_continuity_counter)
        {
            dvbpsi_error(p_dvbpsi, "PSI decoder",
                     "TS discontinuity (received %d, expected %d) for PID %d",
                     p_decoder->i_continuity_counter, i_expected_counter,
                     ((uint16_t)(p_data[1] & 0x1f) << 8) | p_data[2]);
            p_decoder->b_discontinuity = true;
            if (p_decoder->p_current_section)
            {
                dvbpsi_DeletePSISections(p_decoder->p_current_section);
                p_decoder->p_current_section = NULL;
            }
        }
    }

    /* Return if no payload in the TS packet */
    if (!(p_data[3] & 0x10))
        return false;

    /* Skip the adaptation_field if present */
    if (p_data[3] & 0x20)
        p_payload_pos = p_data + 5 + p_data[4];
    else
        p_payload_pos = p_data + 4;

    /* Unit start -> skip the pointer_field and a new section begins */
    if (p_data[1] & 0x40)
    {
        p_new_pos = p_payload_pos + *p_payload_pos + 1;
        p_payload_pos += 1;
    }

    p_section = p_decoder->p_current_section;

    /* If the psi decoder needs a beginning of a section and a new section
       begins in the packet then initialize the dvbpsi_psi_section_t structure */
    if (p_section == NULL)
    {
        if (p_new_pos)
        {
            /* Allocation of the structure */
            p_decoder->p_current_section
                        = p_section
                        = dvbpsi_NewPSISection(p_decoder->i_section_max_size);
            if (!p_section)
                return false;
            /* Update the position in the packet */
            p_payload_pos = p_new_pos;
            /* New section is being handled */
            p_new_pos = NULL;
            /* Just need the header to know how long is the section */
            p_decoder->i_need = 3;
            p_decoder->b_complete_header = false;
        }
        else
        {
            /* No new section => return */
            return false;
        }
    }

    /* Remaining bytes in the payload */
    i_available = 188 + p_data - p_payload_pos;

    while (i_available > 0)
    {
        if (i_available >= p_decoder->i_need)
        {
            /* There are enough bytes in this packet to complete the
               header/section */
            memcpy(p_section->p_payload_end, p_payload_pos, p_decoder->i_need);
            p_payload_pos += p_decoder->i_need;
            p_section->p_payload_end += p_decoder->i_need;
            i_available -= p_decoder->i_need;

            if (!p_decoder->b_complete_header)
            {
                /* Header is complete */
                p_decoder->b_complete_header = true;
                /* Compute p_section->i_length and update p_decoder->i_need */
                p_decoder->i_need = p_section->i_length
                                  = ((uint16_t)(p_section->p_data[1] & 0xf)) << 8
                                       | p_section->p_data[2];
                /* Check that the section isn't too long */
                if (p_decoder->i_need > p_decoder->i_section_max_size - 3)
                {
                    dvbpsi_error(p_dvbpsi, "PSI decoder", "PSI section too long");
                    dvbpsi_DeletePSISections(p_section);
                    p_decoder->p_current_section = NULL;
                    /* If there is a new section not being handled then go forward
                       in the packet */
                    if (p_new_pos)
                    {
                        p_decoder->p_current_section
                                    = p_section
                                    = dvbpsi_NewPSISection(p_decoder->i_section_max_size);
                        if (!p_section)
                            return false;
                        p_payload_pos = p_new_pos;
                        p_new_pos = NULL;
                        p_decoder->i_need = 3;
                        p_decoder->b_complete_header = false;
                        i_available = 188 + p_data - p_payload_pos;
                    }
                    else
                    {
                        i_available = 0;
                    }
                }
            }
            else
            {
                bool b_valid_crc32 = false;
                bool has_crc32;

                /* PSI section is complete */
                p_section->i_table_id = p_section->p_data[0];
                p_section->b_syntax_indicator = p_section->p_data[1] & 0x80;
                p_section->b_private_indicator = p_section->p_data[1] & 0x40;

                /* Update the end of the payload if CRC_32 is present */
                has_crc32 = dvbpsi_has_CRC32(p_section);
                if (p_section->b_syntax_indicator || has_crc32)
                    p_section->p_payload_end -= 4;

                /* Check CRC32 if present */
                if (has_crc32)
                    b_valid_crc32 = dvbpsi_ValidPSISection(p_section);

                if (!has_crc32 || b_valid_crc32)
                {
                    /* PSI section is valid */
                    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;
                    }
                    else
                    {
                        p_section->i_extension = 0;
                        p_section->i_version = 0;
                        p_section->b_current_next = true;
                        p_section->i_number = 0;
                        p_section->i_last_number = 0;
                        p_section->p_payload_start = p_section->p_data + 3;
                    }
                    if (p_decoder->pf_gather)
                        p_decoder->pf_gather(p_dvbpsi, p_section);
                    p_decoder->p_current_section = NULL;
                }
                else
                {
                    if (has_crc32 && !dvbpsi_ValidPSISection(p_section))
Exemplo n.º 8
0
/*****************************************************************************
 * dvbpsi_tot_sections_gather
 *****************************************************************************
 * Callback for the PSI decoder.
 *****************************************************************************/
void dvbpsi_tot_sections_gather(dvbpsi_t* p_dvbpsi,
                                dvbpsi_decoder_t* p_decoder,
                                dvbpsi_psi_section_t* p_section)
{
    assert(p_dvbpsi);
    assert(p_dvbpsi->p_decoder);

    const uint8_t i_table_id = ((p_section->i_table_id == 0x70 ||  /* TDT */
                                 p_section->i_table_id == 0x73)) ? /* TOT */
                                    p_section->i_table_id : 0x70;

    if (!dvbpsi_CheckPSISection(p_dvbpsi, p_section, i_table_id, "TDT/TOT decoder"))
    {
        dvbpsi_DeletePSISections(p_section);
        return;
    }

    /* Valid TDT/TOT section */
    dvbpsi_tot_decoder_t* p_tot_decoder = (dvbpsi_tot_decoder_t*)p_decoder;

    /* TS discontinuity check */
    if (p_tot_decoder->b_discontinuity)
    {
        /* We don't care about discontinuities with the TDT/TOT as it
           only consists of one section anyway */
        //dvbpsi_ReInitTOT(p_tot_decoder, true);
        p_tot_decoder->b_discontinuity = false;
    }
    else
    {
        /* Perform a few sanity checks */
        if (p_tot_decoder->p_building_tot)
        {
            if (dvbpsi_CheckTOT(p_dvbpsi, p_tot_decoder, p_section))
                dvbpsi_ReInitTOT(p_tot_decoder, true);
        }
#if 0
/* FIXME: Check TDT/TOT table definition for how the version numbering works for this table */
        else
        {
            if(    (p_tot_decoder->b_current_valid)
                && (p_tot_decoder->current_tot.i_version == p_section->i_version)
                && (p_tot_decoder->current_tot.b_current_next == p_section->b_current_next))
            {
                /* Don't decode since this version is already decoded */
                dvbpsi_debug(p_dvbpsi, "TOT decoder",
                             "ignoring already decoded section %d",
                             p_section->i_number);
                dvbpsi_DeletePSISections(p_section);
                return;
            }
        }
#endif
    }

    /* Add section to TOT */
    if (!dvbpsi_AddSectionTOT(p_dvbpsi, p_tot_decoder, p_section))
    {
        dvbpsi_error(p_dvbpsi, "TOT decoder", "failed decoding section %d",
                     p_section->i_number);
        dvbpsi_DeletePSISections(p_section);
        return;
    }

    /* Check if we have all the sections */
    if (dvbpsi_decoder_psi_sections_completed(DVBPSI_DECODER(p_tot_decoder)))
    {
        assert(p_tot_decoder->pf_tot_callback);

        /* Save the current information */
        p_tot_decoder->current_tot = *p_tot_decoder->p_building_tot;
        p_tot_decoder->b_current_valid = true;

        /* Decode the sections */
        dvbpsi_tot_sections_decode(p_dvbpsi, p_tot_decoder->p_building_tot,
                                   p_tot_decoder->p_sections);
        /* Delete the sections */
        dvbpsi_DeletePSISections(p_tot_decoder->p_sections);
        p_tot_decoder->p_sections = NULL;
        /* signal the new TOT */
        p_tot_decoder->pf_tot_callback(p_tot_decoder->p_cb_data,
                                       p_tot_decoder->p_building_tot);
        /* Reinitialize the structures */
        dvbpsi_ReInitTOT(p_tot_decoder, false);
    }
}
Exemplo n.º 9
0
/*****************************************************************************
 * dvbpsi_decoder_psi_section_add
 *****************************************************************************/
bool dvbpsi_decoder_psi_section_add(dvbpsi_decoder_t *p_decoder, dvbpsi_psi_section_t *p_section)
{
    assert(p_decoder);
    assert(p_section);
    assert(p_section->p_next == NULL);

    /* Empty list */
    if (!p_decoder->p_sections)
    {
        p_decoder->p_sections = p_section;
        p_section->p_next = NULL;
        return false;
    }

    /* Insert in right place */
    dvbpsi_psi_section_t *p = p_decoder->p_sections;
    dvbpsi_psi_section_t *p_prev = NULL;
    bool b_overwrite = false;

    while (p)
    {
        if (p->i_number == p_section->i_number)
        {
            /* Replace */
            if (p_prev)
            {
                p_prev->p_next = p_section;
                p_section->p_next = p->p_next;
                p->p_next = NULL;
                dvbpsi_DeletePSISections(p);
                b_overwrite = true;
            }
            else
            {
                p_section->p_next = p->p_next;
                p->p_next = NULL;
                dvbpsi_DeletePSISections(p);
                p = p_section;
                p_decoder->p_sections = p;
                b_overwrite = true;
            }
            goto out;
        }
        else if (p->i_number > p_section->i_number)
        {
            /* Insert before p */
            if (p_prev)
            {
                p_prev->p_next = p_section;
                p_section->p_next = p;
            }
            else
            {
                p_section->p_next = p;
                p_decoder->p_sections = p_section;
            }
            goto out;
        }

        p_prev = p;
        p = p->p_next;
    }

    /* Add to end of list */
    if (p_prev->i_number < p_section->i_number)
    {
        p_prev->p_next = p_section;
        p_section->p_next = NULL;
    }

out:
    return b_overwrite;
}
Exemplo n.º 10
0
/*****************************************************************************
 * main
 *****************************************************************************/
int main(int i_argc, char* pa_argv[])
{
  uint8_t packet[188];
  dvbpsi_pat_t pat;
  dvbpsi_psi_section_t* p_section1, * p_section2;
  dvbpsi_psi_section_t* p_section3, * p_section4;
  dvbpsi_psi_section_t* p_section5, * p_section6;
  int i;

  dvbpsi_t *p_dvbpsi = dvbpsi_new(&message, DVBPSI_MSG_DEBUG);
  if (p_dvbpsi == NULL)
      return 1;

  /* PAT generation */
  dvbpsi_pat_init(&pat, 1, 0, 0);
  dvbpsi_pat_program_add(&pat, 0, 0x12);
  dvbpsi_pat_program_add(&pat, 1, 0x42);
  dvbpsi_pat_program_add(&pat, 2, 0x21);
  dvbpsi_pat_program_add(&pat, 3, 0x24);
  for(i = 4; i < 43; i++)
    dvbpsi_pat_program_add(&pat, i, i);

  p_section1 = dvbpsi_pat_sections_generate(p_dvbpsi, &pat, 4);
  pat.b_current_next = 1;
  p_section2 = dvbpsi_pat_sections_generate(p_dvbpsi, &pat, 8);

  pat.i_version = 1;

  pat.b_current_next = 0;
  p_section3 = dvbpsi_pat_sections_generate(p_dvbpsi, &pat, 16);
  pat.b_current_next = 1;
  p_section4 = dvbpsi_pat_sections_generate(p_dvbpsi, &pat, 300);

  pat.i_version = 2;

  pat.b_current_next = 0;
  p_section5 = dvbpsi_pat_sections_generate(p_dvbpsi, &pat, 16);
  pat.b_current_next = 1;
  p_section6 = dvbpsi_pat_sections_generate(p_dvbpsi, &pat, 16);

  /* TS packets generation */
  packet[0] = 0x47;
  packet[1] = packet[2] = 0x00;
  packet[3] = 0x00;

  writePSI(packet, p_section1);
  writePSI(packet, p_section2);
  writePSI(packet, p_section3);
  writePSI(packet, p_section4);
  writePSI(packet, p_section5);
  writePSI(packet, p_section6);

  dvbpsi_DeletePSISections(p_section1);
  dvbpsi_DeletePSISections(p_section2);
  dvbpsi_DeletePSISections(p_section3);
  dvbpsi_DeletePSISections(p_section4);
  dvbpsi_DeletePSISections(p_section5);
  dvbpsi_DeletePSISections(p_section6);

  dvbpsi_pat_empty(&pat);

  dvbpsi_delete(p_dvbpsi);
  return 0;
}
Exemplo n.º 11
0
/*****************************************************************************
* dvbpsi_pat_sections_generate
*****************************************************************************
* Generate PAT sections based on the dvbpsi_pat_t structure. The third
* argument is used to limit the number of program in each section (max: 253).
*****************************************************************************/
dvbpsi_psi_section_t* dvbpsi_pat_sections_generate( dvbpsi_t *p_dvbpsi,
						    dvbpsi_pat_t* p_pat, int i_max_pps )
{
	dvbpsi_psi_section_t	* p_result	= dvbpsi_NewPSISection( 1024 );
	dvbpsi_psi_section_t	* p_current	= p_result;
	dvbpsi_psi_section_t	* p_prev;
	dvbpsi_pat_program_t	* p_program	= p_pat->p_first_program;
	int			i_count		= 0;

	if ( p_current == NULL )
	{
		dvbpsi_error( p_dvbpsi, "PAT encoder", "failed to allocate new PSI section" );
		return(NULL);
	}

	/* A PAT section can carry up to 253 programs */
	if ( (i_max_pps <= 0) || (i_max_pps > 253) )
		i_max_pps = 253;

	p_current->i_table_id		= 0;
	p_current->b_syntax_indicator	= true;
	p_current->b_private_indicator	= false;
	p_current->i_length		= 9;            /* header + CRC_32 */
	p_current->i_extension		= p_pat->i_ts_id;
	p_current->i_version		= p_pat->i_version;
	p_current->b_current_next	= p_pat->b_current_next;
	p_current->i_number		= 0;
	p_current->p_payload_end	+= 8;           /* just after the header */
	p_current->p_payload_start	= p_current->p_payload_end;

	/* PAT programs */
	while ( p_program != NULL )
	{
		/* New section if needed */
		if ( ++i_count > i_max_pps )
		{
			p_prev		= p_current;
			p_current	= dvbpsi_NewPSISection( 1024 );
			if ( p_current == NULL )
			{
				dvbpsi_error( p_dvbpsi, "PAT encoder", "failed to allocate new PSI section" );
				goto error;
			}
			p_prev->p_next	= p_current;
			i_count		= 1;

			p_current->i_table_id		= 0;
			p_current->b_syntax_indicator	= true;
			p_current->b_private_indicator	= false;
			p_current->i_length		= 9;    /* header + CRC_32 */
			p_current->i_extension		= p_pat->i_ts_id;
			p_current->i_version		= p_pat->i_version;
			p_current->b_current_next	= p_pat->b_current_next;
			p_current->i_number		= p_prev->i_number + 1;
			p_current->p_payload_end	+= 8;   /* just after the header */
			p_current->p_payload_start	= p_current->p_payload_end;
		}

		/* p_payload_end is where the program begins */
		p_current->p_payload_end[0]	= p_program->i_number >> 8;
		p_current->p_payload_end[1]	= p_program->i_number;
		p_current->p_payload_end[2]	= (p_program->i_pid >> 8) | 0xe0;
		p_current->p_payload_end[3]	= p_program->i_pid;

		/* Increase length by 4 */
		p_current->p_payload_end	+= 4;
		p_current->i_length		+= 4;

		p_program = p_program->p_next;
	}

	/* Finalization */
	p_prev = p_result;
	while ( p_prev != NULL )
	{
		p_prev->i_last_number = p_current->i_number;
		dvbpsi_BuildPSISection( p_dvbpsi, p_prev );
		p_prev = p_prev->p_next;
	}

	return(p_result);

error:
	/* Cleanup on error */
	p_prev = p_result;
	dvbpsi_DeletePSISections( p_prev );
	return(NULL);
}
Exemplo n.º 12
0
/*****************************************************************************
 * dvbpsi_atsc_GatherEITSections
 *****************************************************************************
 * Callback for the subtable demultiplexor.
 *****************************************************************************/
static void dvbpsi_atsc_GatherEITSections(dvbpsi_t * p_dvbpsi,
                                          dvbpsi_decoder_t *p_decoder,
                                          dvbpsi_psi_section_t * p_section)
{
    assert(p_dvbpsi);
    assert(p_dvbpsi->p_decoder);

    if (!dvbpsi_CheckPSISection(p_dvbpsi, p_section, 0xCB, "ATSC EIT decoder"))
    {
        dvbpsi_DeletePSISections(p_section);
        return;
    }

    /* We have a valid EIT section */
    dvbpsi_demux_t *p_demux = (dvbpsi_demux_t *) p_dvbpsi->p_decoder;
    dvbpsi_atsc_eit_decoder_t *p_eit_decoder = (dvbpsi_atsc_eit_decoder_t*)p_decoder;
    if (!p_eit_decoder)
    {
        dvbpsi_error(p_dvbpsi, "ATSC EIT decoder", "No decoder specified");
        dvbpsi_DeletePSISections(p_section);
        return;
    }

    /* TS discontinuity check */
    if (p_demux->b_discontinuity)
    {
        dvbpsi_ReInitEIT(p_eit_decoder, true);
        p_eit_decoder->b_discontinuity = false;
        p_demux->b_discontinuity = false;
    }
    else
    {
        /* Perform a few sanity checks */
        if (p_eit_decoder->p_building_eit)
        {
            if (dvbpsi_CheckEIT(p_dvbpsi, p_eit_decoder, p_section))
                dvbpsi_ReInitEIT(p_eit_decoder, true);
        }
        else
        {
            if (   (p_eit_decoder->b_current_valid)
                && (p_eit_decoder->current_eit.i_version == p_section->i_version)
                && (p_eit_decoder->current_eit.b_current_next ==
                                               p_section->b_current_next))
            {
                /* Don't decode since this version is already decoded */
                dvbpsi_debug(p_dvbpsi, "ATSC EIT decoder",
                             "ignoring already decoded section %d",
                             p_section->i_number);
                dvbpsi_DeletePSISections(p_section);
                return;
            }
#if 0
            if ((p_eit_decoder->b_current_valid) &&
                (p_eit_decoder->current_eit.i_version == p_section->i_version))
            {
                /* Signal a new EIT if the previous one wasn't active */
                if ((!p_eit_decoder->current_eit.b_current_next) &&
                     (p_section->b_current_next))
                {
                    dvbpsi_atsc_eit_t * p_eit = (dvbpsi_atsc_eit_t*)malloc(sizeof(dvbpsi_atsc_eit_t));
                    if (p_eit)
                    {
                        p_eit_decoder->current_eit.b_current_next = true;
                        *p_eit = p_eit_decoder->current_eit;
                        p_eit_decoder->pf_eit_callback(p_eit_decoder->p_cb_data, p_eit);
                    }
                    else
                        dvbpsi_error(p_dvbpsi, "ATSC EIT decoder", "Could not signal new ATSC EIT.");
                }
            }
            dvbpsi_DeletePSISections(p_section);
            return;
#endif
        }
    }

    /* Add section to EIT */
    if (!dvbpsi_AddSectionEIT(p_dvbpsi, p_eit_decoder, p_section))
    {
        dvbpsi_error(p_dvbpsi, "ATSC EIT decoder", "failed decoding section %d",
                     p_section->i_number);
        dvbpsi_DeletePSISections(p_section);
        return;
    }

    /* Check if we have all the sections */
    if (dvbpsi_decoder_psi_sections_completed(DVBPSI_DECODER(p_eit_decoder)))
    {
        assert(p_eit_decoder->pf_eit_callback);

        /* Save the current information */
        p_eit_decoder->current_eit = *p_eit_decoder->p_building_eit;
        p_eit_decoder->b_current_valid = true;
        /* Decode the sections */
        dvbpsi_atsc_DecodeEITSections(p_eit_decoder->p_building_eit,
                                      p_eit_decoder->p_sections);
        /* Delete the sections */
        dvbpsi_DeletePSISections(p_eit_decoder->p_sections);
        p_eit_decoder->p_sections = NULL;
        /* signal the new EIT */
        p_eit_decoder->pf_eit_callback(p_eit_decoder->p_cb_data,
                                       p_eit_decoder->p_building_eit);
        /* Reinitialize the structures */
        dvbpsi_ReInitEIT(p_eit_decoder, false);
    }
}
Exemplo n.º 13
0
/*****************************************************************************
 * dvbpsi_pat_sections_gather
 *****************************************************************************
 * Callback for the PSI decoder.
 *****************************************************************************/
void dvbpsi_pat_sections_gather(dvbpsi_t* p_dvbpsi, dvbpsi_psi_section_t* p_section)
{

    assert(p_dvbpsi);

    if (!dvbpsi_CheckPSISection(p_dvbpsi, p_section, 0x00, "PAT decoder"))
    {
        dvbpsi_DeletePSISections(p_section);
        return;
    }

    /* Now we have a valid PAT section */
    dvbpsi_decoder_t *p_dec = dvbpsi_decoder_chain_get(p_dvbpsi, p_section->i_table_id, p_section->i_extension);
    if (!p_dec)
    {
        dvbpsi_DeletePSISections(p_section);
        return;
    }

    /* TS discontinuity check */
    dvbpsi_pat_decoder_t *p_pat_decoder = (dvbpsi_pat_decoder_t *)p_dec;
    if (p_pat_decoder->b_discontinuity)
    {
        dvbpsi_ReInitPAT(p_pat_decoder, true);
        p_pat_decoder->b_discontinuity = false;
    }
    else
    {
        if (p_pat_decoder->p_building_pat)
        {
            if (dvbpsi_CheckPAT(p_dvbpsi, p_pat_decoder, p_section))
                dvbpsi_ReInitPAT(p_pat_decoder, true);
        }
        else
        {
            if(    (p_pat_decoder->b_current_valid)
                && (p_pat_decoder->current_pat.i_version == p_section->i_version)
                && (p_pat_decoder->current_pat.b_current_next ==
                                               p_section->b_current_next))
            {
                /* Don't decode since this version is already decoded */
                dvbpsi_debug(p_dvbpsi, "PAT decoder",
                             "ignoring already decoded section %d",
                             p_section->i_number);
                dvbpsi_DeletePSISections(p_section);
                return;
            }
        }
    }

    /* Add section to PAT */
    if (!dvbpsi_AddSectionPAT(p_dvbpsi, p_pat_decoder, p_section))
    {
        dvbpsi_error(p_dvbpsi, "PAT decoder", "failed decoding section %d",
                     p_section->i_number);
        dvbpsi_DeletePSISections(p_section);
        return;
    }

    /* Check if we have all the sections */
    if (dvbpsi_decoder_psi_sections_completed(DVBPSI_DECODER(p_pat_decoder)))
    {
        assert(p_pat_decoder->pf_pat_callback);

        /* Save the current information */
        p_pat_decoder->current_pat = *p_pat_decoder->p_building_pat;

        /* Decode the sections */
        if (dvbpsi_pat_sections_decode(p_pat_decoder->p_building_pat,
                                       p_pat_decoder->p_sections))
            p_pat_decoder->b_current_valid = true;

        /* signal the new PAT */
        if (p_pat_decoder->b_current_valid)
            p_pat_decoder->pf_pat_callback(p_pat_decoder->p_priv,
                                           p_pat_decoder->p_building_pat);

        /* Delete sectioins and Reinitialize the structures */
        dvbpsi_ReInitPAT(p_pat_decoder, !p_pat_decoder->b_current_valid);
        assert(p_pat_decoder->p_sections == NULL);
    }
}
Exemplo n.º 14
0
void dvbpsi_pmt_sections_gather( dvbpsi_t *p_dvbpsi, dvbpsi_psi_section_t* p_section )
{
	assert( p_dvbpsi );
	assert( p_dvbpsi->p_decoder );

	/* ¼ì²étable_id */
	if ( !dvbpsi_CheckPSISection( p_dvbpsi, p_section, 0x02, "PMT decoder" ) )
	{
		dvbpsi_DeletePSISections( p_section );
		return;
	}

	/* */
	dvbpsi_pmt_decoder_t* p_pmt_decoder = (dvbpsi_pmt_decoder_t *) p_dvbpsi->p_decoder;
	assert( p_pmt_decoder );

	/* We have a valid PMT section */
	/* ½ÚÄ¿ºÅ¼ì²é*/
	if ( p_pmt_decoder->i_program_number != p_section->i_extension )
	{
		/* Invalid program_number */
		dvbpsi_debug( p_dvbpsi, "PMT decoder", "ignoring section %d not belonging to 'program_number' %d",
			      p_section->i_extension, p_pmt_decoder->i_program_number );
		dvbpsi_DeletePSISections( p_section );
		return;
	}

	/* TS discontinuity check */
	if ( p_pmt_decoder->b_discontinuity )
	{
		dvbpsi_ReInitPMT( p_pmt_decoder, true );
		p_pmt_decoder->b_discontinuity = false;
		
	}else  {
	
		/* Perform some few sanity checks */
		if ( p_pmt_decoder->p_building_pmt )
		{
			if ( dvbpsi_CheckPMT( p_dvbpsi, p_section ) )
				dvbpsi_ReInitPMT( p_pmt_decoder, true );
		}else  {
			if ( (p_pmt_decoder->b_current_valid)
			     && (p_pmt_decoder->current_pmt.i_version == p_section->i_version)
			     && (p_pmt_decoder->current_pmt.b_current_next ==
				 p_section->b_current_next) )
			{
				/* Don't decode since this version is already decoded */
				dvbpsi_debug( p_dvbpsi, "PMT decoder",
					      "ignoring already decoded section %d",
					      p_section->i_number );
				dvbpsi_DeletePSISections( p_section );
				return;
			}
		}
	}

	/* Add section to PMT */
	if ( !dvbpsi_AddSectionPMT( p_dvbpsi, p_pmt_decoder, p_section ) )
	{
		dvbpsi_error( p_dvbpsi, "PMT decoder", "failed decoding section %d",
			      p_section->i_number );
		dvbpsi_DeletePSISections( p_section );
		return;
	}

	if ( dvbpsi_decoder_psi_sections_completed( DVBPSI_DECODER( p_pmt_decoder ) ) )
	{
		assert( p_pmt_decoder->pf_pmt_callback );

		/* Save the current information */
		p_pmt_decoder->current_pmt	= *p_pmt_decoder->p_building_pmt;
		p_pmt_decoder->b_current_valid	= true;
		/* Decode the sections */
		dvbpsi_pmt_sections_decode( p_pmt_decoder->p_building_pmt,
					    p_pmt_decoder->p_sections );
		/* signal the new PMT */

		p_pmt_decoder->pf_pmt_callback( p_pmt_decoder->p_cb_data,
						p_pmt_decoder->p_building_pmt );
		/* Delete sections and Reinitialize the structures */
		dvbpsi_ReInitPMT( p_pmt_decoder, false );
		assert( p_pmt_decoder->p_sections == NULL );
	}
}
Exemplo n.º 15
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;
    }
}
Exemplo n.º 16
0
/*****************************************************************************
 * dvbpsi_cat_sections_gather
 *****************************************************************************
 * Callback for the PSI decoder.
 *****************************************************************************/
void dvbpsi_cat_sections_gather(dvbpsi_t *p_dvbpsi,
                              dvbpsi_psi_section_t* p_section)
{
    assert(p_dvbpsi);
    assert(p_dvbpsi->p_decoder);

    if (!dvbpsi_CheckPSISection(p_dvbpsi, p_section, 0x01, "CAT decoder"))
    {
        dvbpsi_DeletePSISections(p_section);
        return;
    }

    /* */
    dvbpsi_cat_decoder_t* p_cat_decoder
                          = (dvbpsi_cat_decoder_t*)p_dvbpsi->p_decoder;

    /* TS discontinuity check */
    if (p_cat_decoder->b_discontinuity)
    {
        dvbpsi_ReInitCAT(p_cat_decoder, true);
        p_cat_decoder->b_discontinuity = false;
    }
    else
    {
        /* Perform some few sanity checks */
        if (p_cat_decoder->p_building_cat)
        {
            if (dvbpsi_CheckCAT(p_dvbpsi, p_section))
                dvbpsi_ReInitCAT(p_cat_decoder, true);
        }
        else
        {
             if (   (p_cat_decoder->b_current_valid)
                 && (p_cat_decoder->current_cat.i_version == p_section->i_version)
                 && (p_cat_decoder->current_cat.b_current_next ==
                                                   p_section->b_current_next))
             {
                 /* Don't decode since this version is already decoded */
                 dvbpsi_debug(p_dvbpsi, "CAT decoder",
                              "ignoring already decoded section %d",
                              p_section->i_number);
                 dvbpsi_DeletePSISections(p_section);
                 return;
             }
        }
    }

    /* Add section to CAT */
    if (!dvbpsi_AddSectionCAT(p_dvbpsi, p_cat_decoder, p_section))
    {
        dvbpsi_error(p_dvbpsi, "CAT decoder", "failed decoding section %d",
                     p_section->i_number);
        dvbpsi_DeletePSISections(p_section);
        return;
    }

    /* Check if we have all the sections */
    if (dvbpsi_decoder_psi_sections_completed(DVBPSI_DECODER(p_cat_decoder)))
    {
        assert(p_cat_decoder->pf_cat_callback);

        /* Save the current information */
        p_cat_decoder->current_cat = *p_cat_decoder->p_building_cat;
        p_cat_decoder->b_current_valid = true;
        /* Decode the sections */
        dvbpsi_cat_sections_decode(p_cat_decoder->p_building_cat,
                                   p_cat_decoder->p_sections);
        /* signal the new CAT */
        p_cat_decoder->pf_cat_callback(p_cat_decoder->p_cb_data,
                                       p_cat_decoder->p_building_cat);
        /* Delete sections and Reinitialize the structures */
        dvbpsi_ReInitCAT(p_cat_decoder, false);
        assert(p_cat_decoder->p_sections == NULL);
    }
}
Exemplo n.º 17
0
/*****************************************************************************
 * dvbpsi_atsc_GatherETTSections
 *****************************************************************************
 * Callback for the PSI decoder.
 *****************************************************************************/
static void dvbpsi_atsc_GatherETTSections(dvbpsi_t* p_dvbpsi,
                                          dvbpsi_decoder_t *p_decoder,
                                          dvbpsi_psi_section_t* p_section)
{
    assert(p_dvbpsi);
    assert(p_dvbpsi->p_decoder);

    if (!dvbpsi_CheckPSISection(p_dvbpsi, p_section, 0xCC, "ATSC ETT decoder"))
    {
        dvbpsi_DeletePSISections(p_section);
        return;
    }

    /* We have a valid ETT section */
    dvbpsi_demux_t *p_demux = (dvbpsi_demux_t *) p_dvbpsi->p_decoder;
    dvbpsi_atsc_ett_decoder_t* p_ett_decoder = (dvbpsi_atsc_ett_decoder_t*)p_decoder;
    if (!p_ett_decoder)
    {
        dvbpsi_error(p_dvbpsi, "ATSC ETT decoder", "No decoder specified");
        dvbpsi_DeletePSISections(p_section);
        return;
    }

    /* TS discontinuity check */
    if (p_demux->b_discontinuity)
    {
        dvbpsi_ReInitETT(p_ett_decoder, true);
        p_ett_decoder->b_discontinuity = false;
        p_demux->b_discontinuity = false;
    }
    else
    {
        /* Perform a few sanity checks */
        if (p_ett_decoder->p_building_ett)
        {
            if (dvbpsi_CheckETT(p_dvbpsi, p_ett_decoder, p_section))
                dvbpsi_ReInitETT(p_ett_decoder, true);
        }
        else
        {
            if (   (p_ett_decoder->b_current_valid)
                && (p_ett_decoder->current_ett.i_version == p_section->i_version)
                && (p_ett_decoder->current_ett.b_current_next ==
                                               p_section->b_current_next))
            {
                /* Don't decode since this version is already decoded */
                dvbpsi_debug(p_dvbpsi, "ATSC ETT decoder",
                             "ignoring already decoded section %d",
                             p_section->i_number);
                dvbpsi_DeletePSISections(p_section);
                return;
            }
        }
    }

    /* Add section to ETT */
    if (!dvbpsi_AddSectionETT(p_dvbpsi, p_ett_decoder, p_section))
    {
        dvbpsi_error(p_dvbpsi, "ATSC ETT decoder", "failed decoding section %d",
                     p_section->i_number);
        dvbpsi_DeletePSISections(p_section);
        return;
    }

    /* Check if we have all the sections */
    if (dvbpsi_decoder_psi_sections_completed(DVBPSI_DECODER(p_ett_decoder)))
    {
        assert(p_ett_decoder->pf_ett_callback);

        /* Save the current information */
        p_ett_decoder->current_ett = *p_ett_decoder->p_building_ett;
        p_ett_decoder->b_current_valid = true;
        /* Decode the sections */
        dvbpsi_atsc_DecodeETTSections(p_ett_decoder->p_building_ett,
                                      p_ett_decoder->p_sections);
        /* signal the new ETT */
        p_ett_decoder->pf_ett_callback(p_ett_decoder->p_cb_data,
                                       p_ett_decoder->p_building_ett);
        /* Delete sections and Reinitialize the structures */
        dvbpsi_ReInitETT(p_ett_decoder, false);
        assert(p_ett_decoder->p_sections == NULL);
    }
}
Exemplo n.º 18
0
Arquivo: nit.c Projeto: egan2015/tsmux
/*****************************************************************************
 * dvbpsi_nit_sections_gather
 *****************************************************************************
 * Callback for the PSI decoder.
 *****************************************************************************/
void dvbpsi_nit_sections_gather(dvbpsi_t *p_dvbpsi,
                                dvbpsi_decoder_t *p_private_decoder,
                                dvbpsi_psi_section_t *p_section)
{
    assert(p_dvbpsi);

    const uint8_t i_table_id = ((p_section->i_table_id == 0x40) ||
                                (p_section->i_table_id == 0x41)) ?
                                    p_section->i_table_id : 0x40;

    if (!dvbpsi_CheckPSISection(p_dvbpsi, p_section, i_table_id, "NIT decoder"))
    {
        dvbpsi_DeletePSISections(p_section);
        return;
    }

    /* */
    dvbpsi_nit_decoder_t* p_nit_decoder
                        = (dvbpsi_nit_decoder_t*)p_private_decoder;

    /* We have a valid NIT section */
    if (p_nit_decoder->i_network_id != p_section->i_extension)
    {
        /* Invalid program_number */
        dvbpsi_error(p_dvbpsi, "NIT decoder", "'network_id' don't match");
        dvbpsi_DeletePSISections(p_section);
        return;
    }

    /* TS discontinuity check */
    if (p_nit_decoder->b_discontinuity)
    {
        dvbpsi_ReInitNIT(p_nit_decoder, true);
        p_nit_decoder->b_discontinuity = false;
    }
    else
    {
        /* Perform some few sanity checks */
        if (p_nit_decoder->p_building_nit)
        {
            if (dvbpsi_CheckNIT(p_dvbpsi, p_nit_decoder, p_section))
                dvbpsi_ReInitNIT(p_nit_decoder, true);
        }
        else
        {
            if (   (p_nit_decoder->b_current_valid)
                && (p_nit_decoder->current_nit.i_version == p_section->i_version)
                && (p_nit_decoder->current_nit.b_current_next == p_section->b_current_next))
            {
                /* Don't decode since this version is already decoded */
                dvbpsi_debug(p_dvbpsi, "NIT decoder",
                             "ignoring already decoded section %d",
                             p_section->i_number);
                dvbpsi_DeletePSISections(p_section);
                return;;
            }
        }
    }

    /* Add section to NIT */
    if (!dvbpsi_AddSectionNIT(p_dvbpsi, p_nit_decoder, p_section))
    {
        dvbpsi_error(p_dvbpsi, "NIT decoder", "failed decoding section %d",
                     p_section->i_number);
        dvbpsi_DeletePSISections(p_section);
        return;
    }

    /* Check if we have all the sections */
    if (dvbpsi_decoder_psi_sections_completed(DVBPSI_DECODER(p_nit_decoder)))
    {
        assert(p_nit_decoder->pf_nit_callback);

        /* Save the current information */
        p_nit_decoder->current_nit = *p_nit_decoder->p_building_nit;
        p_nit_decoder->b_current_valid = true;

        /* Decode the sections */
        dvbpsi_nit_sections_decode(p_nit_decoder->p_building_nit,
                                   p_nit_decoder->p_sections);
        /* signal the new NIT */
        p_nit_decoder->pf_nit_callback(p_nit_decoder->p_cb_data,
                                       p_nit_decoder->p_building_nit);
        /* Delete sections and Reinitialize the structures */
        dvbpsi_ReInitNIT(p_nit_decoder, false);
        assert(p_nit_decoder->p_sections == NULL);
    }
}
Exemplo n.º 19
0
/*****************************************************************************
 * dvbpsi_GatherVCTSections
 *****************************************************************************
 * Callback for the PSI decoder.
 *****************************************************************************/
void dvbpsi_GatherVCTSections(dvbpsi_t *p_dvbpsi,
                              void * p_private_decoder,
                              dvbpsi_psi_section_t * p_section)
{
   assert(p_dvbpsi);
   assert(p_dvbpsi->p_private);

   dvbpsi_demux_t *p_demux = (dvbpsi_demux_t *)p_dvbpsi->p_private;
   dvbpsi_vct_decoder_t *p_vct_decoder
                       = (dvbpsi_vct_decoder_t*)p_private_decoder;

   dvbpsi_debug(p_dvbpsi, "VCT 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);

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

   bool b_reinit = false;

   /* TS discontinuity check */
   if (p_demux->b_discontinuity)
   {
       b_reinit = true;
       p_demux->b_discontinuity = false;
   }
   else
   {
       /* Perform a few sanity checks */
       if (p_vct_decoder->p_building_vct)
       {
           if (p_vct_decoder->p_building_vct->i_ts_id != p_section->i_extension)
           {
               /* transport_stream_id */
               dvbpsi_error(p_dvbpsi, "VCT decoder",
                       "'transport_stream_id' differs"
                       " whereas no TS discontinuity has occured");
               b_reinit = true;
           }
           else if (p_vct_decoder->p_building_vct->i_version != p_section->i_version)
           {
               /* version_number */
               dvbpsi_error(p_dvbpsi, "VCT decoder",
                       "'version_number' differs"
                       " whereas no discontinuity has occured");
               b_reinit = true;
           }
           else if (p_vct_decoder->i_last_section_number != p_section->i_last_number)
           {
               /* last_section_number */
               dvbpsi_error(p_dvbpsi, "VCT decoder",
                       "'last_section_number' differs"
                       " whereas no discontinuity has occured");
               b_reinit = true;
           }
       }
       else
       {
           if(    (p_vct_decoder->b_current_valid)
               && (p_vct_decoder->current_vct.i_version == p_section->i_version)
               && (p_vct_decoder->current_vct.b_current_next == p_section->b_current_next))
           {
               /* Don't decode since this version is already decoded */
               dvbpsi_DeletePSISections(p_section);
               return;
           }
       }
   }

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

   /* Initialize the structures if it's the first section received */
   if (!p_vct_decoder->p_building_vct)
   {
       p_vct_decoder->p_building_vct = (dvbpsi_vct_t*)calloc(1, sizeof(dvbpsi_vct_t));
       if (p_vct_decoder->p_building_vct)
       {
           dvbpsi_InitVCT(p_vct_decoder->p_building_vct,
                           p_section->i_extension,
                           p_section->i_version,
                           p_section->b_current_next,
                           p_section->i_table_id);
           p_vct_decoder->i_last_section_number = p_section->i_last_number;
       }
       else
           dvbpsi_debug(p_dvbpsi, "VCT decoder", "failed decoding section");
   }

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

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

       if (i == p_vct_decoder->i_last_section_number)
           b_complete = true;
   }

   if (b_complete)
   {
       /* Save the current information */
       p_vct_decoder->current_vct = *p_vct_decoder->p_building_vct;
       p_vct_decoder->b_current_valid = true;
       /* Chain the sections */
       if (p_vct_decoder->i_last_section_number)
       {
           for (unsigned int i = 0; (int)i <= p_vct_decoder->i_last_section_number - 1; i++)
               p_vct_decoder->ap_sections[i]->p_next = p_vct_decoder->ap_sections[i + 1];
       }
       /* Decode the sections */
       dvbpsi_DecodeVCTSections(p_vct_decoder->p_building_vct,
                                p_vct_decoder->ap_sections[0]);
       /* Delete the sections */
       dvbpsi_DeletePSISections(p_vct_decoder->ap_sections[0]);
       p_vct_decoder->ap_sections[0] = NULL;
       /* signal the new VCT */
       p_vct_decoder->pf_vct_callback(p_vct_decoder->p_cb_data,
                                      p_vct_decoder->p_building_vct);
       /* Reinitialize the structures */
       p_vct_decoder->p_building_vct = NULL;
       for (unsigned int i = 0; i <= p_vct_decoder->i_last_section_number; i++)
           p_vct_decoder->ap_sections[i] = NULL;
   }
}
Exemplo n.º 20
0
/*****************************************************************************
 * dvbpsi_GatherCATSections
 *****************************************************************************
 * Callback for the PSI decoder.
 *****************************************************************************/
void dvbpsi_GatherCATSections(dvbpsi_decoder_t* p_decoder,
                              dvbpsi_psi_section_t* p_section)
{
  dvbpsi_cat_decoder_t* p_cat_decoder
                        = (dvbpsi_cat_decoder_t*)p_decoder->p_private_decoder;
  int b_append = 1;
  int b_reinit = 0;
  unsigned int i;

  DVBPSI_DEBUG_ARG("CAT 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 != 0x01)
  {
    /* Invalid table_id value */
    DVBPSI_ERROR_ARG("CAT 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("CAT decoder",
                 "invalid section (section_syntax_indicator == 0)");
    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_cat_decoder->p_building_cat)
      {
        if(p_cat_decoder->p_building_cat->i_version != p_section->i_version)
        {
          /* version_number */
          DVBPSI_ERROR("CAT decoder",
                       "'version_number' differs"
                       " whereas no discontinuity has occured");
          b_reinit = 1;
        }
        else if(p_cat_decoder->i_last_section_number
                                                != p_section->i_last_number)
        {
          /* last_section_number */
          DVBPSI_ERROR("CAT decoder",
                       "'last_section_number' differs"
                       " whereas no discontinuity has occured");
          b_reinit = 1;
        }
      }
      else
      {
        if(    (p_cat_decoder->b_current_valid)
            && (p_cat_decoder->current_cat.i_version == p_section->i_version)
            && (p_cat_decoder->current_cat.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_cat_decoder->b_current_valid = 0;
    /* Free structures */
    if(p_cat_decoder->p_building_cat)
    {
      free(p_cat_decoder->p_building_cat);
      p_cat_decoder->p_building_cat = NULL;
    }
    /* Clear the section array */
    for(i = 0; i <= 255; i++)
    {
      if(p_cat_decoder->ap_sections[i] != NULL)
      {
        dvbpsi_DeletePSISections(p_cat_decoder->ap_sections[i]);
        p_cat_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_cat_decoder->p_building_cat)
    {
      p_cat_decoder->p_building_cat =
                                (dvbpsi_cat_t*)malloc(sizeof(dvbpsi_cat_t));
      dvbpsi_InitCAT(p_cat_decoder->p_building_cat,
                     p_section->i_version,
                     p_section->b_current_next);
      p_cat_decoder->i_last_section_number = p_section->i_last_number;
    }

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

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

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

    if(b_complete)
    {
      /* Save the current information */
      p_cat_decoder->current_cat = *p_cat_decoder->p_building_cat;
      p_cat_decoder->b_current_valid = 1;
      /* Chain the sections */
      if(p_cat_decoder->i_last_section_number)
      {
        for(i = 0; (int)i <= p_cat_decoder->i_last_section_number - 1; i++)
          p_cat_decoder->ap_sections[i]->p_next =
                                        p_cat_decoder->ap_sections[i + 1];
      }
      /* Decode the sections */
      dvbpsi_DecodeCATSections(p_cat_decoder->p_building_cat,
                               p_cat_decoder->ap_sections[0]);
      /* Delete the sections */
      dvbpsi_DeletePSISections(p_cat_decoder->ap_sections[0]);
      /* signal the new CAT */
      p_cat_decoder->pf_callback(p_cat_decoder->p_cb_data,
                                 p_cat_decoder->p_building_cat);
      /* Reinitialize the structures */
      p_cat_decoder->p_building_cat = NULL;
      for(i = 0; i <= p_cat_decoder->i_last_section_number; i++)
        p_cat_decoder->ap_sections[i] = NULL;
    }
  }
  else
  {
    dvbpsi_DeletePSISections(p_section);
  }
}
Exemplo n.º 21
0
/*****************************************************************************
 * dvbpsi_sis_sections_gather
 *****************************************************************************
 * Callback for the subtable demultiplexor.
 *****************************************************************************/
void dvbpsi_sis_sections_gather(dvbpsi_t *p_dvbpsi,
                              dvbpsi_decoder_t *p_decoder,
                              dvbpsi_psi_section_t * p_section)
{
    assert(p_dvbpsi);
    assert(p_dvbpsi->p_decoder);

    if (!dvbpsi_CheckPSISection(p_dvbpsi, p_section, 0xFC, "SIS decoder"))
    {
        dvbpsi_DeletePSISections(p_section);
        return;
    }

    /* */
    dvbpsi_demux_t *p_demux = (dvbpsi_demux_t *) p_dvbpsi->p_decoder;
    dvbpsi_sis_decoder_t * p_sis_decoder = (dvbpsi_sis_decoder_t*)p_decoder;

    if (p_section->b_private_indicator)
    {
        /* Invalid private_syntax_indicator */
        dvbpsi_error(p_dvbpsi, "SIS decoder",
                     "invalid private section (private_syntax_indicator != false)");
        dvbpsi_DeletePSISections(p_section);
        return;
    }

    /* TS discontinuity check */
    if (p_demux->b_discontinuity)
    {
        dvbpsi_ReInitSIS(p_sis_decoder, true);
        p_sis_decoder->b_discontinuity = false;
        p_demux->b_discontinuity = false;
    }
    else
    {
        /* Perform a few sanity checks */
        if (p_sis_decoder->p_building_sis)
        {
            if (dvbpsi_CheckSIS(p_dvbpsi, p_sis_decoder, p_section))
                dvbpsi_ReInitSIS(p_sis_decoder, true);
        }
        else
        {
            if(     (p_sis_decoder->b_current_valid)
                 && (p_sis_decoder->current_sis.i_version == p_section->i_version)
                 && (p_sis_decoder->current_sis.b_current_next == p_section->b_current_next))
             {
                 /* Don't decode since this version is already decoded */
                 dvbpsi_debug(p_dvbpsi, "SIT decoder",
                             "ignoring already decoded section %d",
                             p_section->i_number);
                 dvbpsi_DeletePSISections(p_section);
                 return;
             }
        }
    }

    /* Add section to SIS */
    if (!dvbpsi_AddSectionSIS(p_dvbpsi, p_sis_decoder, p_section))
    {
        dvbpsi_error(p_dvbpsi, "SIS decoder", "failed decoding section %d",
                     p_section->i_number);
        dvbpsi_DeletePSISections(p_section);
        return;
    }

    /* Check if we have all the sections */
    if (dvbpsi_decoder_psi_sections_completed(DVBPSI_DECODER(p_sis_decoder)))
    {
        assert(p_sis_decoder->pf_sis_callback);

        /* Save the current information */
        p_sis_decoder->current_sis = *p_sis_decoder->p_building_sis;
        p_sis_decoder->b_current_valid = true;
        /* Decode the sections */
        dvbpsi_sis_sections_decode(p_dvbpsi, p_sis_decoder->p_building_sis,
                                   p_sis_decoder->p_sections);
        /* Delete the sections */
        dvbpsi_DeletePSISections(p_sis_decoder->p_sections);
        p_sis_decoder->p_sections = NULL;
        /* signal the new SDT */
        p_sis_decoder->pf_sis_callback(p_sis_decoder->p_cb_data,
                                       p_sis_decoder->p_building_sis);
        /* Reinitialize the structures */
        dvbpsi_ReInitSIS(p_sis_decoder, false);
    }
}