⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pmt.c

📁 Dvbstreamer 用在解析MPTS的部分内容
💻 C
📖 第 1 页 / 共 2 页
字号:
          /* Signal a new PMT if the previous one wasn't active */          if(    (!p_pmt_decoder->current_pmt.b_current_next)              && (p_section->b_current_next))          {            dvbpsi_pmt_t* p_pmt = (dvbpsi_pmt_t*)ObjectCreateType(dvbpsi_pmt_t);            p_pmt_decoder->current_pmt.b_current_next = 1;            *p_pmt = p_pmt_decoder->current_pmt;            p_pmt_decoder->pf_callback(p_pmt_decoder->p_cb_data, p_pmt);          }          /* Don't decode since this version is already decoded */          b_append = 0;        }      }    }  }  /* Reinit the decoder if wanted */  if(b_reinit)  {    /* Force redecoding */    p_pmt_decoder->b_current_valid = 0;    /* Free structures */    if(p_pmt_decoder->p_building_pmt)    {      ObjectRefDec(p_pmt_decoder->p_building_pmt);      p_pmt_decoder->p_building_pmt = NULL;    }    /* Clear the section array */    for(i = 0; i <= 255; i++)    {      if(p_pmt_decoder->ap_sections[i] != NULL)      {        dvbpsi_ReleasePSISections(p_decoder, p_pmt_decoder->ap_sections[i]);        p_pmt_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_pmt_decoder->p_building_pmt)    {      dvbpsi_NewPMT(p_pmt_decoder->p_building_pmt,                     p_pmt_decoder->i_program_number,                     p_section->i_version,                     p_section->b_current_next,                       ((uint16_t)(p_section->p_payload_start[0] & 0x1f) << 8)                     | p_section->p_payload_start[1]);      p_pmt_decoder->i_last_section_number = p_section->i_last_number;    }    /* Fill the section array */    if(p_pmt_decoder->ap_sections[p_section->i_number] != NULL)    {      DVBPSI_DEBUG_ARG("PMT decoder", "overwrite section number %d",                       p_section->i_number);      dvbpsi_ReleasePSISections(p_decoder, p_pmt_decoder->ap_sections[p_section->i_number]);    }    p_pmt_decoder->ap_sections[p_section->i_number] = p_section;    /* Check if we have all the sections */    b_complete = 0;    for(i = 0; i <= p_pmt_decoder->i_last_section_number; i++)    {      if(!p_pmt_decoder->ap_sections[i])        break;      if(i == p_pmt_decoder->i_last_section_number)        b_complete = 1;    }    if(b_complete)    {      /* Save the current information */      p_pmt_decoder->current_pmt = *p_pmt_decoder->p_building_pmt;      p_pmt_decoder->b_current_valid = 1;      /* Chain the sections */      if(p_pmt_decoder->i_last_section_number)      {        for(i = 0; i <= p_pmt_decoder->i_last_section_number - 1; i++)          p_pmt_decoder->ap_sections[i]->p_next =                                        p_pmt_decoder->ap_sections[i + 1];      }      /* Decode the sections */      dvbpsi_DecodePMTSections(p_pmt_decoder->p_building_pmt,                               p_pmt_decoder->ap_sections[0]);      /* Delete the sections */      dvbpsi_ReleasePSISections(p_decoder, p_pmt_decoder->ap_sections[0]);      /* signal the new PMT */      p_pmt_decoder->pf_callback(p_pmt_decoder->p_cb_data,                                 p_pmt_decoder->p_building_pmt);      /* Reinitialize the structures */      p_pmt_decoder->p_building_pmt = NULL;      for(i = 0; i <= p_pmt_decoder->i_last_section_number; i++)        p_pmt_decoder->ap_sections[i] = NULL;    }  }  else  {    dvbpsi_ReleasePSISections(p_decoder, p_section);  }}/***************************************************************************** * dvbpsi_DecodePMTSections ***************************************************************************** * PMT decoder. *****************************************************************************/void dvbpsi_DecodePMTSections(dvbpsi_pmt_t* p_pmt,                              dvbpsi_psi_section_t* p_section){  uint8_t* p_byte, * p_end;  while(p_section)  {    /* - PMT descriptors */    p_byte = p_section->p_payload_start + 4;    p_end = p_byte + (   ((uint16_t)(p_section->p_payload_start[2] & 0x0f) << 8)                       | p_section->p_payload_start[3]);    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_PMTAddDescriptor(p_pmt, i_tag, i_length, p_byte + 2);      p_byte += 2 + i_length;    }    /* - ESs */    for(p_byte = p_end; p_byte + 5 <= p_section->p_payload_end;)    {      uint8_t i_type = p_byte[0];      uint16_t i_pid = ((uint16_t)(p_byte[1] & 0x1f) << 8) | p_byte[2];      uint16_t i_length = ((uint16_t)(p_byte[3] & 0x0f) << 8) | p_byte[4];      dvbpsi_pmt_es_t* p_es = dvbpsi_PMTAddES(p_pmt, i_type, i_pid);      /* - ES descriptors */      p_byte += 5;      p_end = p_byte + i_length;      if( p_end > p_section->p_payload_end )      {            p_end = p_section->p_payload_end;      }      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_PMTESAddDescriptor(p_es, i_tag, i_length, p_byte + 2);        p_byte += 2 + i_length;      }    }    p_section = p_section->p_next;  }}/***************************************************************************** * dvbpsi_GenPMTSections ***************************************************************************** * Generate PMT sections based on the dvbpsi_pmt_t structure. *****************************************************************************/dvbpsi_psi_section_t* dvbpsi_GenPMTSections(dvbpsi_pmt_t* p_pmt){  dvbpsi_psi_section_t* p_result = dvbpsi_NewPSISection(1024);  dvbpsi_psi_section_t* p_current = p_result;  dvbpsi_psi_section_t* p_prev;  dvbpsi_descriptor_t* p_descriptor = p_pmt->p_first_descriptor;  dvbpsi_pmt_es_t* p_es = p_pmt->p_first_es;  uint16_t i_info_length;  p_current->i_table_id = 0x02;  p_current->b_syntax_indicator = 1;  p_current->b_private_indicator = 0;  p_current->i_length = 13;                     /* header + CRC_32 */  p_current->i_extension = p_pmt->i_program_number;  p_current->i_version = p_pmt->i_version;  p_current->b_current_next = p_pmt->b_current_next;  p_current->i_number = 0;  p_current->p_payload_end += 12;               /* just after the header */  p_current->p_payload_start = p_current->p_data + 8;  /* PCR_PID */  p_current->p_data[8] = (p_pmt->i_pcr_pid >> 8) | 0xe0;  p_current->p_data[9] = p_pmt->i_pcr_pid;  /* PMT descriptors */  while(p_descriptor != NULL)  {    /* New section if needed */    /* written_data_length + descriptor_length + 2 > 1024 - CRC_32_length */    if(   (p_current->p_payload_end - p_current->p_data)                                + p_descriptor->i_length > 1018)    {      /* program_info_length */      i_info_length = (p_current->p_payload_end - p_current->p_data) - 12;      p_current->p_data[10] = (i_info_length >> 8) | 0xf0;      p_current->p_data[11] = i_info_length;      p_prev = p_current;      p_current = dvbpsi_NewPSISection(1024);      p_prev->p_next = p_current;      p_current->i_table_id = 0x02;      p_current->b_syntax_indicator = 1;      p_current->b_private_indicator = 0;      p_current->i_length = 13;                 /* header + CRC_32 */      p_current->i_extension = p_pmt->i_program_number;      p_current->i_version = p_pmt->i_version;      p_current->b_current_next = p_pmt->b_current_next;      p_current->i_number = p_prev->i_number + 1;      p_current->p_payload_end += 12;           /* just after the header */      p_current->p_payload_start = p_current->p_data + 8;      /* PCR_PID */      p_current->p_data[8] = (p_pmt->i_pcr_pid >> 8) | 0xe0;      p_current->p_data[9] = p_pmt->i_pcr_pid;    }    /* p_payload_end is where the descriptor begins */    p_current->p_payload_end[0] = p_descriptor->i_tag;    p_current->p_payload_end[1] = p_descriptor->i_length;    memcpy(p_current->p_payload_end + 2,           p_descriptor->p_data,           p_descriptor->i_length);    /* Increase length by descriptor_length + 2 */    p_current->p_payload_end += p_descriptor->i_length + 2;    p_current->i_length += p_descriptor->i_length + 2;    p_descriptor = p_descriptor->p_next;  }  /* program_info_length */  i_info_length = (p_current->p_payload_end - p_current->p_data) - 12;  p_current->p_data[10] = (i_info_length >> 8) | 0xf0;  p_current->p_data[11] = i_info_length;  /* PMT ESs */  while(p_es != NULL)  {    uint8_t* p_es_start = p_current->p_payload_end;    uint16_t i_es_length = 5;    /* Can the current section carry all the descriptors ? */    p_descriptor = p_es->p_first_descriptor;    while(    (p_descriptor != NULL)           && ((p_es_start - p_current->p_data) + i_es_length <= 1020))    {      i_es_length += p_descriptor->i_length + 2;      p_descriptor = p_descriptor->p_next;    }    /* If _no_ and the current section isn't empty and an empty section       may carry one more descriptor       then create a new section */    if(    (p_descriptor != NULL)        && (p_es_start - p_current->p_data != 12)        && (i_es_length <= 1008))    {      /* will put more descriptors in an empty section */      DVBPSI_DEBUG("PMT generator",                   "create a new section to carry more ES descriptors");      p_prev = p_current;      p_current = dvbpsi_NewPSISection(1024);      p_prev->p_next = p_current;      p_current->i_table_id = 0x02;      p_current->b_syntax_indicator = 1;      p_current->b_private_indicator = 0;      p_current->i_length = 13;                 /* header + CRC_32 */      p_current->i_extension = p_pmt->i_program_number;      p_current->i_version = p_pmt->i_version;      p_current->b_current_next = p_pmt->b_current_next;      p_current->i_number = p_prev->i_number + 1;      p_current->p_payload_end += 12;           /* just after the header */      p_current->p_payload_start = p_current->p_data + 8;      /* PCR_PID */      p_current->p_data[8] = (p_pmt->i_pcr_pid >> 8) | 0xe0;      p_current->p_data[9] = p_pmt->i_pcr_pid;      /* program_info_length */      i_info_length = 0;      p_current->p_data[10] = 0xf0;      p_current->p_data[11] = 0x00;      p_es_start = p_current->p_payload_end;    }    /* p_es_start is where the ES begins */    p_es_start[0] = p_es->i_type;    p_es_start[1] = (p_es->i_pid >> 8) | 0xe0;    p_es_start[2] = p_es->i_pid;    /* Increase the length by 5 */    p_current->p_payload_end += 5;    p_current->i_length += 5;    /* ES descriptors */    p_descriptor = p_es->p_first_descriptor;    while(    (p_descriptor != NULL)           && (   (p_current->p_payload_end - p_current->p_data)                + p_descriptor->i_length <= 1018))    {      /* p_payload_end is where the descriptor begins */      p_current->p_payload_end[0] = p_descriptor->i_tag;      p_current->p_payload_end[1] = p_descriptor->i_length;      memcpy(p_current->p_payload_end + 2,             p_descriptor->p_data,             p_descriptor->i_length);      /* Increase length by descriptor_length + 2 */      p_current->p_payload_end += p_descriptor->i_length + 2;      p_current->i_length += p_descriptor->i_length + 2;      p_descriptor = p_descriptor->p_next;    }    if(p_descriptor != NULL)      DVBPSI_ERROR("PMT generator", "unable to carry all the ES descriptors");    /* ES_info_length */    i_es_length = p_current->p_payload_end - p_es_start - 5;    p_es_start[3] = (i_es_length >> 8) | 0xf0;    p_es_start[4] = i_es_length;    p_es = p_es->p_next;  }  /* Finalization */  p_prev = p_result;  while(p_prev != NULL)  {    p_prev->i_last_number = p_current->i_number;    dvbpsi_BuildPSISection(p_prev);    p_prev = p_prev->p_next;  }  return p_result;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -