static inline uint32_t section_header_read(section_header_t *sh, bs_t *b) {
	sh->table_id = bs_read_u8(b);
	sh->section_syntax_indicator = bs_read_u1(b);
	sh->private_indicator = bs_read_u1(b);
	bs_skip_u(b,2);
	sh->section_length = bs_read_u(b,12);
	return sh->table_id;
}
示例#2
0
//7.3.2.11 RBSP trailing bits syntax
void read_rbsp_trailing_bits(bs_t* b)
{
    bs_read_u1( b ); // equal to 1

    while( !bs_byte_aligned(b) )
    {
        bs_read_u1( b ); // equal to 0
    }
}
示例#3
0
void read_sei_end_bits(h264_stream_t* h, bs_t* b )
{
    // if the message doesn't end at a byte border
    if ( !bs_byte_aligned( b ) )
    {
        if ( !bs_read_u1( b ) ) fprintf(stderr, "WARNING: bit_equal_to_one is 0!!!!\n");
        while ( ! bs_byte_aligned( b ) )
        {
            if ( bs_read_u1( b ) ) fprintf(stderr, "WARNING: bit_equal_to_zero is 1!!!!\n");
        }
    }

    read_rbsp_trailing_bits(h, b);
}
示例#4
0
文件: bs.c 项目: dulton/nampu
uint32_t bs_read_ue(bs_t* b)
{
    int32_t r = 0;
    int i = 0;

    while( bs_read_u1(b) == 0 && i < 32 && !bs_eof(b) )
    {
        i++;
    }
    r = bs_read_u(b, i);
    r += (1 << i) - 1;
    return r;
}
示例#5
0
//Appendix E.1.2 HRD parameters syntax
void read_hrd_parameters(sps_t* sps, bs_t* b)
{
    int SchedSelIdx;

    sps->hrd.cpb_cnt_minus1 = bs_read_ue(b);
    sps->hrd.bit_rate_scale = bs_read_u(b,4);
    sps->hrd.cpb_size_scale = bs_read_u(b,4);
    for( SchedSelIdx = 0; SchedSelIdx <= sps->hrd.cpb_cnt_minus1; SchedSelIdx++ )
    {
        sps->hrd.bit_rate_value_minus1[ SchedSelIdx ] = bs_read_ue(b);
        sps->hrd.cpb_size_value_minus1[ SchedSelIdx ] = bs_read_ue(b);
        sps->hrd.cbr_flag[ SchedSelIdx ] = bs_read_u1(b);
    }
    sps->hrd.initial_cpb_removal_delay_length_minus1 = bs_read_u(b,5);
    sps->hrd.cpb_removal_delay_length_minus1 = bs_read_u(b,5);
    sps->hrd.dpb_output_delay_length_minus1 = bs_read_u(b,5);
    sps->hrd.time_offset_length = bs_read_u(b,5);
}
示例#6
0
int conditional_access_section_read(conditional_access_section_t *cas, uint8_t *buf, size_t buf_len, uint32_t payload_unit_start_indicator,
                                    psi_table_buffer_t *catBuffer) 
{ 
   if (cas == NULL || buf == NULL) 
   {
      SAFE_REPORT_TS_ERR(-1); 
      return 0;
   }
   
   bs_t *b = NULL;

   if (!payload_unit_start_indicator &&  catBuffer->buffer == NULL)
   {
      // this TS packet is not start of table, and we have no cached table data
      LOG_WARN ("conditional_access_section_read: payload_unit_start_indicator not set and no cached data");
      return 0;
   }

   if (payload_unit_start_indicator)
   {
      uint8_t payloadStartPtr = buf[0];
      buf += (payloadStartPtr + 1);
      buf_len -= (payloadStartPtr + 1);
      LOG_DEBUG_ARGS ("conditional_access_section_read: payloadStartPtr = %d", payloadStartPtr);
   }

   // check for pat spanning multiple TS packets
   if (catBuffer->buffer != NULL)
   {
      LOG_DEBUG_ARGS ("conditional_access_section_read: catBuffer detected: catBufferAllocSz = %d, catBufferUsedSz = %d", 
         catBuffer->bufferAllocSz, catBuffer->bufferUsedSz);
      size_t numBytesToCopy = buf_len;
      if (buf_len > (catBuffer->bufferAllocSz - catBuffer->bufferUsedSz))
      {
         numBytesToCopy = catBuffer->bufferAllocSz - catBuffer->bufferUsedSz;
      }
         
      LOG_DEBUG_ARGS ("conditional_access_section_read: copying %d bytes to catBuffer", numBytesToCopy);
      memcpy (catBuffer->buffer + catBuffer->bufferUsedSz, buf, numBytesToCopy);
      catBuffer->bufferUsedSz += numBytesToCopy;
      
      if (catBuffer->bufferUsedSz < catBuffer->bufferAllocSz)
      {
         LOG_DEBUG ("conditional_access_section_read: catBuffer not yet full -- returning");
         return 0;
      }

      b = bs_new(catBuffer->buffer, catBuffer->bufferUsedSz);
   }
   else
   {
      b = bs_new(buf, buf_len);
   }
         
   cas->table_id = bs_read_u8(b); 
   if (cas->table_id != conditional_access_section) 
   {
      LOG_ERROR_ARGS("Table ID in CAT is 0x%02X instead of expected 0x%02X", 
                     cas->table_id, conditional_access_section); 
      reportAddErrorLogArgs("Table ID in CAT is 0x%02X instead of expected 0x%02X", 
                     cas->table_id, conditional_access_section); 
      SAFE_REPORT_TS_ERR(-30); 
      resetPSITableBuffer(catBuffer);
      bs_free (b);
      return 0;
   }
   
   // read byte 0

   cas->section_syntax_indicator = bs_read_u1(b); 
   if (!cas->section_syntax_indicator) 
   {
      LOG_ERROR("section_syntax_indicator not set in CAT"); 
      reportAddErrorLog("section_syntax_indicator not set in CAT"); 
      SAFE_REPORT_TS_ERR(-31); 
      resetPSITableBuffer(catBuffer);
      bs_free (b);
      return 0;
   }
   bs_skip_u(b, 3); // TODO read the zero bit, check it to be zero
   cas->section_length = bs_read_u(b, 12); 
   if (cas->section_length > 1021) // max CAT length 
   {
      LOG_ERROR_ARGS("CAT section length is 0x%02X, larger than maximum allowed 0x%02X", 
                     cas->section_length, MAX_SECTION_LEN); 
      reportAddErrorLogArgs("CAT section length is 0x%02X, larger than maximum allowed 0x%02X", 
                     cas->section_length, MAX_SECTION_LEN); 
      SAFE_REPORT_TS_ERR(-32); 
      resetPSITableBuffer(catBuffer);
      bs_free (b);
      return 0;
   }
   
   if (cas->section_length > bs_bytes_left(b))
   {
      LOG_DEBUG ("conditional_access_section_read: Detected section spans more than one TS packet -- allocating buffer");

      if (catBuffer->buffer != NULL)
      {
         // should never get here
         LOG_ERROR ("conditional_access_section_read: unexpected catBufffer");
         reportAddErrorLog ("conditional_access_section_read: unexpected catBufffer");
         resetPSITableBuffer(catBuffer);
      }

      catBuffer->bufferAllocSz = cas->section_length + 3;
      catBuffer->buffer = (uint8_t *)calloc (cas->section_length + 3, 1);
      memcpy (catBuffer->buffer, buf, buf_len);
      catBuffer->bufferUsedSz = buf_len;

      bs_free (b);
      return 0;
   }

   // read bytes 1-2
   bs_read_u16(b); 
   
   // read bytes 3,4
   bs_skip_u(b, 2); 
   cas->version_number = bs_read_u(b, 5); 
   cas->current_next_indicator = bs_read_u1(b); 
   if (!cas->current_next_indicator) LOG_WARN("This CAT is not yet applicable/n"); 
   
   // read byte 5
   
   cas->section_number = bs_read_u8(b); 
   cas->last_section_number = bs_read_u8(b); 
   if (cas->section_number != 0 || cas->last_section_number != 0) LOG_WARN("Multi-section CAT is not supported yet/n"); 
   
   // read bytes 6,7
   read_descriptor_loop(cas->descriptors, b, cas->section_length - 5 - 4 ); 

   // explanation: section_length gives us the length from the end of section_length
   // we used 5 bytes for the mandatory section fields, and will use another 4 bytes for CRC
   // the remaining bytes contain descriptors, most probably only one
   // again, it's much shorter in C :-)
   

   cas->CRC_32 = bs_read_u32(b); 
   
   // check CRC
   crc_t cas_crc = crc_init(); 
   cas_crc = crc_update(cas_crc, buf, bs_pos(b) - 4); 
   cas_crc = crc_finalize(cas_crc); 
   if (cas_crc != cas->CRC_32) 
   {
      LOG_ERROR_ARGS("CAT CRC_32 specified as 0x%08X, but calculated as 0x%08X", cas->CRC_32, cas_crc); 
      reportAddErrorLogArgs("CAT CRC_32 specified as 0x%08X, but calculated as 0x%08X", cas->CRC_32, cas_crc); 
      SAFE_REPORT_TS_ERR(-33); 
      resetPSITableBuffer(catBuffer);
      bs_free (b);
      return 0;
   } 

   
   bs_free(b); 
   resetPSITableBuffer(catBuffer);
   return 1;
}
示例#7
0
int program_map_section_read(program_map_section_t *pms, uint8_t *buf, size_t buf_size, uint32_t payload_unit_start_indicator,
   psi_table_buffer_t *pmtBuffer) 
{ 
   LOG_DEBUG ("program_map_section_read -- entering");
   if (pms == NULL || buf == NULL) 
   {
      SAFE_REPORT_TS_ERR(-1); 
      return 0;
   }

   bs_t *b = NULL;

   if (!payload_unit_start_indicator &&  pmtBuffer->buffer == NULL)
   {
      // this TS packet is not start of table, and we have no cached table data
      LOG_WARN ("program_map_section_read: payload_unit_start_indicator not set and no cached data");
      return 0;
   }

   if (payload_unit_start_indicator)
   {
      uint8_t payloadStartPtr = buf[0];
      buf += (payloadStartPtr + 1);
      buf_size -= (payloadStartPtr + 1);
      LOG_DEBUG_ARGS ("program_map_section_read: payloadStartPtr = %d", payloadStartPtr);
   }

   // check for pmt spanning multiple TS packets
   if (pmtBuffer->buffer != NULL)
   {
      LOG_DEBUG_ARGS ("program_map_section_read: pmtBuffer detected: pmtBufferAllocSz = %d, pmtBufferUsedSz = %d", pmtBuffer->bufferAllocSz, pmtBuffer->bufferUsedSz);
      size_t numBytesToCopy = buf_size;
      if (buf_size > (pmtBuffer->bufferAllocSz - pmtBuffer->bufferUsedSz))
      {
         numBytesToCopy = pmtBuffer->bufferAllocSz - pmtBuffer->bufferUsedSz;
      }
         
      LOG_DEBUG_ARGS ("program_map_section_read: copying %d bytes to pmtBuffer", numBytesToCopy);
      memcpy (pmtBuffer->buffer + pmtBuffer->bufferUsedSz, buf, numBytesToCopy);
      pmtBuffer->bufferUsedSz += numBytesToCopy;
      
      if (pmtBuffer->bufferUsedSz < pmtBuffer->bufferAllocSz)
      {
         LOG_DEBUG ("program_map_section_read: pmtBuffer not yet full -- returning");
         return 0;
      }

      b = bs_new(pmtBuffer->buffer, pmtBuffer->bufferUsedSz);
   }
   else
   {
      b = bs_new(buf, buf_size);
   }
      
   pms->table_id = bs_read_u8(b); 
   if (pms->table_id != TS_program_map_section) 
   {
      LOG_ERROR_ARGS("Table ID in PMT is 0x%02X instead of expected 0x%02X", pms->table_id, TS_program_map_section); 
      reportAddErrorLogArgs("Table ID in PMT is 0x%02X instead of expected 0x%02X", pms->table_id, TS_program_map_section); 
      SAFE_REPORT_TS_ERR(-40);
      resetPSITableBuffer(pmtBuffer);
      bs_free (b);
      return 0;
   }

   pms->section_syntax_indicator = bs_read_u1(b); 
   if (!pms->section_syntax_indicator) 
   {
      LOG_ERROR("section_syntax_indicator not set in PMT"); 
      reportAddErrorLog("section_syntax_indicator not set in PMT"); 
      SAFE_REPORT_TS_ERR(-41); 
      resetPSITableBuffer(pmtBuffer);
      bs_free (b);
      return 0;
   }
   
   bs_skip_u(b, 3); 

   pms->section_length = bs_read_u(b, 12); 
   if (pms->section_length > MAX_SECTION_LEN) 
   {
      LOG_ERROR_ARGS("PMT section length is 0x%02X, larger than maximum allowed 0x%02X", 
                     pms->section_length, MAX_SECTION_LEN); 
      reportAddErrorLogArgs("PMT section length is 0x%02X, larger than maximum allowed 0x%02X", 
                     pms->section_length, MAX_SECTION_LEN); 
      SAFE_REPORT_TS_ERR(-42); 
      resetPSITableBuffer(pmtBuffer);
      bs_free (b);
      return 0;
   }

   if (pms->section_length > bs_bytes_left(b))
   {
      LOG_DEBUG ("program_map_section_read: Detected section spans more than one TS packet -- allocating buffer");

      if (pmtBuffer->buffer != NULL)
      {
         // should never get here
         LOG_ERROR ("program_map_section_read: unexpected pmtBufffer");
         reportAddErrorLog ("program_map_section_read: unexpected pmtBufffer");
         resetPSITableBuffer(pmtBuffer);
      }

      pmtBuffer->bufferAllocSz = pms->section_length + 3;
      pmtBuffer->buffer = (uint8_t *)calloc (pms->section_length + 3, 1);
      memcpy (pmtBuffer->buffer, buf, buf_size);
      pmtBuffer->bufferUsedSz = buf_size;

      bs_free (b);
      return 0;
   }

   int section_start = bs_pos(b); 
   
   // bytes 0,1
   pms->program_number = bs_read_u16(b); 
   
   // byte 2;
   bs_skip_u(b, 2); 
   pms->version_number = bs_read_u(b, 5); 
   pms->current_next_indicator = bs_read_u1(b); 
   if (!pms->current_next_indicator) LOG_WARN("This PMT is not yet applicable/n"); 
   
   // bytes 3,4
   pms->section_number = bs_read_u8(b); 
   pms->last_section_number = bs_read_u8(b); 
   if (pms->section_number != 0 || pms->last_section_number != 0) 
   {
      LOG_ERROR("Multi-section PMT is not allowed/n"); 
      reportAddErrorLog("Multi-section PMT is not allowed/n"); 
      SAFE_REPORT_TS_ERR(-43); 
      resetPSITableBuffer(pmtBuffer);
      bs_free (b);
      return 0;
   }
   
   bs_skip_u(b, 3); 
   pms->PCR_PID = bs_read_u(b, 13); 
   if (pms->PCR_PID < GENERAL_PURPOSE_PID_MIN || pms->PCR_PID > GENERAL_PURPOSE_PID_MAX) 
   {
      LOG_ERROR_ARGS("PCR PID has invalid value 0x%02X", pms->PCR_PID); 
      reportAddErrorLogArgs("PCR PID has invalid value 0x%02X", pms->PCR_PID); 
      SAFE_REPORT_TS_ERR(-44); 
      resetPSITableBuffer(pmtBuffer);
      bs_free (b);
      return 0;
   }
 //  printf ("PCR PID = %d\n", pms->PCR_PID);
   bs_skip_u(b, 4); 
   
   pms->program_info_length = bs_read_u(b, 12); 
   if (pms->program_info_length > MAX_PROGRAM_INFO_LEN) 
   {
      LOG_ERROR_ARGS("PMT program info length is 0x%02X, larger than maximum allowed 0x%02X", 
                     pms->program_info_length, MAX_PROGRAM_INFO_LEN); 
      reportAddErrorLogArgs("PMT program info length is 0x%02X, larger than maximum allowed 0x%02X", 
                     pms->program_info_length, MAX_PROGRAM_INFO_LEN); 
      SAFE_REPORT_TS_ERR(-45); 
      resetPSITableBuffer(pmtBuffer);
      bs_free (b);
      return 0;
   }
   
   read_descriptor_loop(pms->descriptors, b, pms->program_info_length); 

   while (!bs_eof(b) && pms->section_length - (bs_pos(b) - section_start) > 4) // account for CRC
   {
      elementary_stream_info_t *es = es_info_new();
      es_info_read(es, b); 
      vqarray_add(pms->es_info, es);
   }
   
   pms->CRC_32 = bs_read_u32(b); 
   
   // check CRC
   crc_t pas_crc = crc_init(); 
   pas_crc = crc_update(pas_crc, b->start, bs_pos(b) - 4); 
   pas_crc = crc_finalize(pas_crc); 
   if (pas_crc != pms->CRC_32) 
   {
      LOG_ERROR_ARGS("PMT CRC_32 specified as 0x%08X, but calculated as 0x%08X", pms->CRC_32, pas_crc); 
      reportAddErrorLogArgs("PMT CRC_32 specified as 0x%08X, but calculated as 0x%08X", pms->CRC_32, pas_crc); 
      SAFE_REPORT_TS_ERR(-46); 
      resetPSITableBuffer(pmtBuffer);
      bs_free (b);
      return 0;
   } 
   else 
   {
      // LOG_DEBUG("PMT CRC_32 checked successfully");
   }
   
   int bytes_read = bs_pos(b); 
   bs_free(b); 

   resetPSITableBuffer(pmtBuffer);

   return bytes_read;
}
示例#8
0
int program_association_section_read(program_association_section_t *pas, uint8_t *buf, size_t buf_len, uint32_t payload_unit_start_indicator,
                                     psi_table_buffer_t *patBuffer)
{ 
   vqarray_t *programs;
   int num_programs = 0;

   if (pas == NULL || buf == NULL) 
   {
      SAFE_REPORT_TS_ERR(-1); 
      return 0;
   }

   bs_t *b = NULL;

   if (!payload_unit_start_indicator &&  patBuffer->buffer == NULL)
   {
      // this TS packet is not start of table, and we have no cached table data
      LOG_WARN ("program_association_section_read: payload_unit_start_indicator not set and no cached data");
      return 0;
   }

   if (payload_unit_start_indicator)
   {
      uint8_t payloadStartPtr = buf[0];
      buf += (payloadStartPtr + 1);
      buf_len -= (payloadStartPtr + 1);
      LOG_DEBUG_ARGS ("program_association_section_read: payloadStartPtr = %d", payloadStartPtr);
   }


   // check for pat spanning multiple TS packets
   if (patBuffer->buffer != NULL)
   {
      LOG_DEBUG_ARGS ("program_association_section_read: patBuffer detected: patBufferAllocSz = %d, patBufferUsedSz = %d", 
         patBuffer->bufferAllocSz, patBuffer->bufferUsedSz);
      size_t numBytesToCopy = buf_len;
      if (buf_len > (patBuffer->bufferAllocSz - patBuffer->bufferUsedSz))
      {
         numBytesToCopy = patBuffer->bufferAllocSz - patBuffer->bufferUsedSz;
      }
         
      LOG_DEBUG_ARGS ("program_association_section_read: copying %d bytes to patBuffer", numBytesToCopy);
      memcpy (patBuffer->buffer + patBuffer->bufferUsedSz, buf, numBytesToCopy);
      patBuffer->bufferUsedSz += numBytesToCopy;
      
      if (patBuffer->bufferUsedSz < patBuffer->bufferAllocSz)
      {
         LOG_DEBUG ("program_association_section_read: patBuffer not yet full -- returning");
         return 0;
      }

      b = bs_new(patBuffer->buffer, patBuffer->bufferUsedSz);
   }
   else
   {
      b = bs_new(buf, buf_len);
   }
      

   pas->table_id = bs_read_u8(b); 
   if (pas->table_id != program_association_section) 
   {
      LOG_ERROR_ARGS("Table ID in PAT is 0x%02X instead of expected 0x%02X", 
                     pas->table_id, program_association_section); 
      reportAddErrorLogArgs("Table ID in PAT is 0x%02X instead of expected 0x%02X", 
                     pas->table_id, program_association_section); 
      SAFE_REPORT_TS_ERR(-30); 
      resetPSITableBuffer(patBuffer);
      bs_free (b);
      return 0;
   }
   
   // read byte 0
   
   pas->section_syntax_indicator = bs_read_u1(b); 
   if (!pas->section_syntax_indicator) 
   {
      LOG_ERROR("section_syntax_indicator not set in PAT"); 
      reportAddErrorLog("section_syntax_indicator not set in PAT"); 
      SAFE_REPORT_TS_ERR(-31); 
      resetPSITableBuffer(patBuffer);
      bs_free (b);
      return 0;
   }
   bs_skip_u(b, 3); // TODO read the zero bit, check it to be zero
   pas->section_length = bs_read_u(b, 12); 
   if (pas->section_length > MAX_SECTION_LEN) 
   {
      LOG_ERROR_ARGS("PAT section length is 0x%02X, larger than maximum allowed 0x%02X", 
                     pas->section_length, MAX_SECTION_LEN); 
      reportAddErrorLogArgs("PAT section length is 0x%02X, larger than maximum allowed 0x%02X", 
                     pas->section_length, MAX_SECTION_LEN); 
      SAFE_REPORT_TS_ERR(-32); 
      resetPSITableBuffer(patBuffer);
      bs_free (b);
      return 0;
   }
   
   if (pas->section_length > bs_bytes_left(b))
   {
      LOG_DEBUG ("program_association_section_read: Detected section spans more than one TS packet -- allocating buffer");

      if (patBuffer->buffer != NULL)
      {
         // should never get here
         LOG_ERROR ("program_association_section_read: unexpected patBufffer");
         reportAddErrorLog ("program_association_section_read: unexpected patBufffer");
         resetPSITableBuffer(patBuffer);
      }

      patBuffer->bufferAllocSz = pas->section_length + 3;
      patBuffer->buffer = (uint8_t *)calloc (pas->section_length + 3, 1);
      memcpy (patBuffer->buffer, buf, buf_len);
      patBuffer->bufferUsedSz = buf_len;

      bs_free (b);
      return 0;
   }

   // read bytes 1,2
   
   pas->transport_stream_id = bs_read_u16(b); 
   
   // read bytes 3,4
   
   bs_skip_u(b, 2); 
   pas->version_number = bs_read_u(b, 5); 
   pas->current_next_indicator = bs_read_u1(b); 
   if (!pas->current_next_indicator) LOG_WARN("This PAT is not yet applicable/n"); 
   
   // read byte 5
   
   pas->section_number = bs_read_u8(b); 
   pas->last_section_number = bs_read_u8(b); 
   if (pas->section_number != 0 || pas->last_section_number != 0) LOG_WARN("Multi-section PAT is not supported yet/n"); 
   
   // read bytes 6,7
   
   num_programs = (pas->section_length - 5 - 4) / 4;  // Programs listed in the PAT
   // explanation: section_length gives us the length from the end of section_length
   // we used 5 bytes for the mandatory section fields, and will use another 4 bytes for CRC
   // the remaining bytes contain program information, which is 4 bytes per iteration
   // It's much shorter in C :-)

   // Read the program loop, but ignore the NIT PID "program"
   programs = vqarray_new();
   for (uint32_t i = 0; i < num_programs; i++)
   {
      program_info_t *prog = malloc(sizeof(program_info_t));
      prog->program_number = bs_read_u16(b);
      if (prog->program_number == 0) { // Skip the NIT PID program (not a real program)
         free(prog);
         bs_skip_u(b, 16);
         continue;
      }
      bs_skip_u(b, 3);
      prog->program_map_PID = bs_read_u(b, 13);
      vqarray_add(programs, (vqarray_elem_t*)prog);
   }

   // This is our true number of programs
   pas->_num_programs = vqarray_length(programs);
   
   if (pas->_num_programs > 1) LOG_WARN_ARGS("%zd programs found, but only SPTS is fully supported. Patches are welcome.", pas->_num_programs); 
   
   // Copy form our vqarray into the native array
   pas->programs = malloc(pas->_num_programs * sizeof(program_info_t)); 
   for (uint32_t i = 0; i < pas->_num_programs; i++) 
   {
      program_info_t* prog = (program_info_t*)vqarray_pop(programs);
      pas->programs[i] = *prog;
      free(prog);
   }
   vqarray_free(programs);
   
   pas->CRC_32 = bs_read_u32(b); 
   
   // check CRC
   crc_t pas_crc = crc_init(); 
   pas_crc = crc_update(pas_crc, buf, bs_pos(b) - 4); 
   pas_crc = crc_finalize(pas_crc); 
   if (pas_crc != pas->CRC_32) 
   {
      LOG_ERROR_ARGS("PAT CRC_32 specified as 0x%08X, but calculated as 0x%08X", pas->CRC_32, pas_crc); 
      reportAddErrorLogArgs("PAT CRC_32 specified as 0x%08X, but calculated as 0x%08X", pas->CRC_32, pas_crc); 
      SAFE_REPORT_TS_ERR(-33); 
      resetPSITableBuffer(patBuffer);
      bs_free (b);
      return 0;
   } 
   else 
   {
      // LOG_DEBUG("PAT CRC_32 checked successfully");
      // don't enable unless you want to see this every ~100ms
   }
   

   bs_free(b); 
            
   resetPSITableBuffer(patBuffer);

   return 1;
}
int program_map_section_read(program_map_section_t *pms, uint8_t *buf, size_t buf_size) {
	if (pms == NULL || buf == NULL) {
		SAFE_REPORT_TS_ERR(-1);
		return 0;
	}

	bs_t *b = bs_new(buf, buf_size);

	pms->table_id = bs_read_u8(b);
	if (pms->table_id != TS_program_map_section) {
		LOG_ERROR_ARGS("Table ID in PMT is 0x%02X instead of expected 0x%02X", pms->table_id, TS_program_map_section);
		SAFE_REPORT_TS_ERR(-40);
		return 0;
	}

	pms->section_syntax_indicator = bs_read_u1(b);
	if (!pms->section_syntax_indicator) {
		LOG_ERROR("section_syntax_indicator not set in PMT");
		SAFE_REPORT_TS_ERR(-41);
		return 0;
	}

	bs_skip_u(b, 3);
	pms->section_length = bs_read_u(b, 12);
	if (pms->section_length > MAX_SECTION_LEN) {
		LOG_ERROR_ARGS("PMT section length is 0x%02X, larger than maximum allowed 0x%02X",
			pms->section_length, MAX_SECTION_LEN);
		SAFE_REPORT_TS_ERR(-42);
		return 0;
	}

	int section_start = bs_pos(b);

	// bytes 0,1
	pms->program_number = bs_read_u16(b);

	// byte 2;
	bs_skip_u(b, 2);
	pms->version_number = bs_read_u(b, 5);
	pms->current_next_indicator = bs_read_u1(b);
	if (!pms->current_next_indicator)
		LOG_WARN("This PMT is not yet applicable/n");

	// bytes 3,4
	pms->section_number = bs_read_u8(b);
	pms->last_section_number = bs_read_u8(b);
	if (pms->section_number != 0 || pms->last_section_number != 0) {
		LOG_ERROR("Multi-section PMT is not allowed/n");
		SAFE_REPORT_TS_ERR(-43);
		return 0;
	}

	bs_skip_u(b, 3);
	pms->PCR_PID = bs_read_u(b, 13);
	if (pms->PCR_PID < GENERAL_PURPOSE_PID_MIN || pms->PCR_PID > GENERAL_PURPOSE_PID_MAX) {
		LOG_ERROR_ARGS("PCR PID has invalid value 0x%02X", pms->PCR_PID);
		SAFE_REPORT_TS_ERR(-44);
		return 0;
	}
	bs_skip_u(b, 4);

	pms->program_info_length = bs_read_u(b, 12);
	if (pms->program_info_length > MAX_PROGRAM_INFO_LEN) {
		LOG_ERROR_ARGS("PMT program info length is 0x%02X, larger than maximum allowed 0x%02X",
			pms->program_info_length, MAX_PROGRAM_INFO_LEN);
		SAFE_REPORT_TS_ERR(-45);
		return 0;
	}

	read_descriptor_loop(pms->descriptors, b, pms->program_info_length);

	while (pms->section_length - (bs_pos(b) - section_start) > 4) { // account for CRC
		elementary_stream_info_t *es = es_info_new();
		es_info_read(es, b);
		vqarray_add(pms->es_info, es);
	}

	pms->CRC_32 = bs_read_u32(b);

	// check CRC
	crc_t pas_crc = crc_init();
	pas_crc = crc_update(pas_crc, buf, bs_pos(b) - 4);
	pas_crc = crc_finalize(pas_crc);
	if (pas_crc != pms->CRC_32) {
		LOG_ERROR_ARGS("PMT CRC_32 specified as 0x%08X, but calculated as 0x%08X", pms->CRC_32, pas_crc);
		SAFE_REPORT_TS_ERR(-46);
		return 0;
	} else {
		LOG_DEBUG("PMT CRC_32 checked successfully");
	}

	int bytes_read = bs_pos(b);
	bs_free(b);

	return bytes_read;
}
int program_association_section_read(program_association_section_t *pas, uint8_t *buf, size_t buf_len) {
	if (pas == NULL || buf == NULL) {
		SAFE_REPORT_TS_ERR(-1);
		return 0;
	}

	bs_t *b = bs_new(buf, buf_len);

	pas->table_id = bs_read_u8(b);
	if (pas->table_id != program_association_section) {
		LOG_ERROR_ARGS("Table ID in PAT is 0x%02X instead of expected 0x%02X",
			pas->table_id, program_association_section);
		SAFE_REPORT_TS_ERR(-30);
		return 0;
	}

	// read byte 0

	pas->section_syntax_indicator = bs_read_u1(b);
	if (!pas->section_syntax_indicator) {
		LOG_ERROR("section_syntax_indicator not set in PAT");
		SAFE_REPORT_TS_ERR(-31);
		return 0;
	}
	bs_skip_u(b, 3); // TODO read the zero bit, check it to be zero
	pas->section_length = bs_read_u(b, 12);
	if (pas->section_length > MAX_SECTION_LEN) {
		LOG_ERROR_ARGS("PAT section length is 0x%02X, larger than maximum allowed 0x%02X",
			pas->section_length, MAX_SECTION_LEN);
		SAFE_REPORT_TS_ERR(-32);
		return 0;
	}

	// read bytes 1,2

	pas->transport_stream_id = bs_read_u16(b);

	// read bytes 3,4

	bs_skip_u(b, 2);
	pas->version_number = bs_read_u(b, 5);
	pas->current_next_indicator = bs_read_u1(b);
	if (!pas->current_next_indicator)
		LOG_WARN("This PAT is not yet applicable/n");

	// read byte 5

	pas->section_number = bs_read_u8(b);
	pas->last_section_number = bs_read_u8(b);
	if (pas->section_number != 0 || pas->last_section_number != 0)
		LOG_WARN("Multi-section PAT is not supported yet/n");

	// read bytes 6,7

	pas->_num_programs = (pas->section_length - 5 - 4) / 4;
	// explanation: section_length gives us the length from the end of section_length
	// we used 5 bytes for the mandatory section fields, and will use another 4 bytes for CRC
	// the remaining bytes contain program information, which is 4 bytes per iteration
	// It's much shorter in C :-)

	if (pas->_num_programs > 1)
		LOG_WARN_ARGS("%zd programs found, but only SPTS is fully supported. Patches are welcome.", pas->_num_programs);

	pas->programs = malloc(pas->_num_programs * sizeof(program_info_t));
	for (uint32_t i = 0; i < pas->_num_programs; i++) {
		pas->programs[i].program_number = bs_read_u16(b);
		bs_skip_u(b, 3);
		pas->programs[i].program_map_PID = bs_read_u(b, 13);
	}

	pas->CRC_32 = bs_read_u32(b);

	// check CRC
	crc_t pas_crc = crc_init();
	pas_crc = crc_update(pas_crc, buf, bs_pos(b) - 4);
	pas_crc = crc_finalize(pas_crc);
	if (pas_crc != pas->CRC_32) {
		LOG_ERROR_ARGS("PAT CRC_32 specified as 0x%08X, but calculated as 0x%08X", pas->CRC_32, pas_crc);
		SAFE_REPORT_TS_ERR(-33);
		return 0;
	} else {
		LOG_DEBUG("PAT CRC_32 checked successfully");
	}

	bs_free(b);
	return 1;
}
int pes_read_header(pes_header_t *ph, bs_t *b) {
	int PES_packet_start = bs_pos(b);

	// we *really* care about bytes 0..19, as we can cheat and manipulate PTS/DTS this way
	if (bs_bytes_left(b) < 20)
		return 0;

	// bytes 0..2
	uint32_t pes_packet_start_code = bs_read_u24(b);
	if (pes_packet_start_code != PES_PACKET_START_CODE_PREFIX) {
		int actually_read = bs_pos(b) - PES_packet_start;
		b->p -= actually_read; // undo the read
		LOG_WARN_ARGS("PES packet starts with 0x%06X instead of expected start code 0x%06X, skipping it",
			pes_packet_start_code, PES_PACKET_START_CODE_PREFIX);
		return 0; // bail out! something is fishy!
	}

	// bytes 3..5
	ph->stream_id = bs_read_u8(b);
	ph->PES_packet_length = bs_read_u16(b);

	if (HAS_PES_HEADER(ph->stream_id)) {
		// byte 6
		bs_skip_u(b, 2);
		ph->PES_scrambling_control = bs_read_u(b, 2);
		ph->PES_priority = bs_read_u1(b);
		ph->data_alignment_indicator = bs_read_u1(b);
		ph->copyright = bs_read_u1(b);
		ph->original_or_copy = bs_read_u1(b);

		// byte 7
		ph->PTS_DTS_flags = bs_read_u(b, 2);
		ph->ESCR_flag = bs_read_u1(b);
		ph->ES_rate_flag = bs_read_u1(b);
		ph->DSM_trick_mode_flag = bs_read_u1(b);
		ph->additional_copy_info_flag = bs_read_u1(b);
		ph->PES_CRC_flag = bs_read_u1(b);
		ph->PES_extension_flag = bs_read_u1(b);

		// byte 8
		ph->PES_header_data_length = bs_read_u8(b);

		int PES_packet_optional_start = bs_pos(b);

		// byte 9..14
		if (ph->PTS_DTS_flags & PES_PTS_FLAG) {
			bs_skip_u(b, 4);
			ph->PTS = bs_read_90khz_timestamp(b);
		}
		// byte 15..19
		if (ph->PTS_DTS_flags & PES_DTS_FLAG) {
			bs_skip_u(b, 4);
			ph->DTS = bs_read_90khz_timestamp(b);
		}

		if (ph->ESCR_flag) {
			bs_skip_u(b, 2);
			ph->ESCR_base = bs_read_90khz_timestamp(b);
			ph->ESCR_extension = bs_read_u(b, 9);
			bs_skip_u1(b);
		}
		if (ph->ES_rate_flag) {
			bs_skip_u1(b);
			ph->ES_rate = bs_read_u(b, 22);
			bs_skip_u1(b);
		}
		if (ph->DSM_trick_mode_flag) {
			ph->trick_mode_control = bs_read_u(b, 3);
			switch (ph->trick_mode_control) {
			case PES_DSM_TRICK_MODE_CTL_FAST_FORWARD:
			case PES_DSM_TRICK_MODE_CTL_FAST_REVERSE:
				ph->field_id = bs_read_u(b, 2);
				ph->intra_slice_refresh = bs_read_u1(b);
				ph->frequency_truncation = bs_read_u(b, 2);
				break;

			case PES_DSM_TRICK_MODE_CTL_SLOW_MOTION:
			case PES_DSM_TRICK_MODE_CTL_SLOW_REVERSE:
				ph->rep_cntrl = bs_read_u(b, 5);
				break;

			case PES_DSM_TRICK_MODE_CTL_FREEZE_FRAME:
				ph->field_id = bs_read_u(b, 2);
				bs_skip_u(b, 3);
				break;

			default:
				bs_skip_u(b, 5);
				break;
			}
		}
		if (ph->additional_copy_info_flag) {
			bs_skip_u1(b);
			ph->additional_copy_info = bs_read_u(b, 7);
		}
		if (ph->PES_CRC_flag) {
			ph->previous_PES_packet_CRC = bs_read_u16(b);
		}
		if (ph->PES_extension_flag) {
			ph->PES_private_data_flag = bs_read_u1(b);
			ph->pack_header_field_flag = bs_read_u1(b);
			ph->program_packet_sequence_counter_flag = bs_read_u1(b);
			ph->PSTD_buffer_flag = bs_read_u1(b);
			bs_skip_u(b, 3);
			ph->PES_extension_flag_2 = bs_read_u1(b);

			if (ph->PES_private_data_flag)
				bs_read_bytes(b, ph->PES_private_data, 16);

			if (ph->pack_header_field_flag) {
				// whoever discovers the need for pack_header() is welcome to implement it.
				// I haven't.
				ph->pack_field_length = bs_read_u8(b);
				bs_skip_bytes(b, ph->pack_field_length);
			}
			if (ph->program_packet_sequence_counter_flag) {
				bs_skip_u1(b);
				ph->program_packet_sequence_counter = bs_read_u(b, 7);
				bs_skip_u1(b);
				ph->MPEG1_MPEG2_identifier = bs_read_u1(b);
				ph->original_stuff_length = bs_read_u(b, 6);
			}
			if (ph->PSTD_buffer_flag) {
				bs_skip_u(b, 2);
				ph->PSTD_buffer_scale = bs_read_u1(b);
				ph->PSTD_buffer_size = bs_read_u(b, 13);
			}
			if (ph->PES_extension_flag_2) {
				int PES_extension_field_start = bs_pos(b);
				bs_skip_u1(b);
				ph->PES_extension_field_length = bs_read_u(b, 7);
				ph->stream_id_extension_flag = bs_read_u1(b);
				if (!ph->stream_id_extension_flag) {
					ph->stream_id_extension = bs_read_u(b, 7);
				} else {
					bs_skip_u(b, 6);
					ph->tref_extension_flag = bs_read_u1(b);
					if (ph->tref_extension_flag) {
						bs_skip_u(b, 4);
						ph->TREF = bs_read_90khz_timestamp(b);
					}
				}
				int PES_extension_bytes_left = bs_pos(b) - PES_extension_field_start;
				if (PES_extension_bytes_left > 0)
					bs_skip_bytes(b, PES_extension_bytes_left);
			}
		}

		int PES_optional_bytes_read = bs_pos(b) - PES_packet_optional_start;
		int stuffing_bytes_len = ph->PES_header_data_length - PES_optional_bytes_read; // if any
		if (stuffing_bytes_len > 0)
			bs_skip_bytes(b, stuffing_bytes_len);
	}
	return (bs_pos(b) - PES_packet_start);
}
示例#12
0
// Appendix G.13.1.1 Scalability information SEI message syntax
void read_sei_scalability_info( h264_stream_t* h, bs_t* b )
{
    sei_scalability_info_t* sei_svc = h->sei->sei_svc;
    
    sei_svc->temporal_id_nesting_flag = bs_read_u1(b);
    sei_svc->priority_layer_info_present_flag = bs_read_u1(b);
    sei_svc->priority_id_setting_flag = bs_read_u1(b);
    sei_svc->num_layers_minus1 = bs_read_ue(b);
    
    for( int i = 0; i <= sei_svc->num_layers_minus1; i++ ) {
        sei_svc->layers[i].layer_id = bs_read_ue(b);
        sei_svc->layers[i].priority_id = bs_read_u(b, 6);
        sei_svc->layers[i].discardable_flag = bs_read_u1(b);
        sei_svc->layers[i].dependency_id = bs_read_u(b, 3);
        sei_svc->layers[i].quality_id = bs_read_u(b, 4);
        sei_svc->layers[i].temporal_id = bs_read_u(b, 3);
        sei_svc->layers[i].sub_pic_layer_flag = bs_read_u1(b);
        sei_svc->layers[i].sub_region_layer_flag = bs_read_u1(b);
        sei_svc->layers[i].iroi_division_info_present_flag = bs_read_u1(b);
        sei_svc->layers[i].profile_level_info_present_flag = bs_read_u1(b);
        sei_svc->layers[i].bitrate_info_present_flag = bs_read_u1(b);
        sei_svc->layers[i].frm_rate_info_present_flag = bs_read_u1(b);
        sei_svc->layers[i].frm_size_info_present_flag = bs_read_u1(b);
        sei_svc->layers[i].layer_dependency_info_present_flag = bs_read_u1(b);
        sei_svc->layers[i].parameter_sets_info_present_flag = bs_read_u1(b);
        sei_svc->layers[i].bitstream_restriction_info_present_flag = bs_read_u1(b);
        sei_svc->layers[i].exact_inter_layer_pred_flag = bs_read_u1(b);
        if( sei_svc->layers[i].sub_pic_layer_flag ||
            sei_svc->layers[i].iroi_division_info_present_flag )
        {
            sei_svc->layers[i].exact_sample_value_match_flag = bs_read_u1(b);
        }
        sei_svc->layers[i].layer_conversion_flag = bs_read_u1(b);
        sei_svc->layers[i].layer_output_flag = bs_read_u1(b);
        if( sei_svc->layers[i].profile_level_info_present_flag )
        {
            sei_svc->layers[i].layer_profile_level_idc = bs_read_u(b, 24);
        }
        if( sei_svc->layers[i].bitrate_info_present_flag )
        {
            sei_svc->layers[i].avg_bitrate = bs_read_u(b, 16);
            sei_svc->layers[i].max_bitrate_layer = bs_read_u(b, 16);
            sei_svc->layers[i].max_bitrate_layer_representation = bs_read_u(b, 16);
            sei_svc->layers[i].max_bitrate_calc_window = bs_read_u(b, 16);
        }
        if( sei_svc->layers[i].frm_rate_info_present_flag )
        {
            sei_svc->layers[i].constant_frm_rate_idc = bs_read_u(b, 2);
            sei_svc->layers[i].avg_frm_rate = bs_read_u(b, 16);
        }
        if( sei_svc->layers[i].frm_size_info_present_flag ||
            sei_svc->layers[i].iroi_division_info_present_flag )
        {
            sei_svc->layers[i].frm_width_in_mbs_minus1 = bs_read_ue(b);
            sei_svc->layers[i].frm_height_in_mbs_minus1 = bs_read_ue(b);
        }
        if( sei_svc->layers[i].sub_region_layer_flag )
        {
            sei_svc->layers[i].base_region_layer_id = bs_read_ue(b);
            sei_svc->layers[i].dynamic_rect_flag = bs_read_u1(b);
            if( sei_svc->layers[i].dynamic_rect_flag )
            {
                sei_svc->layers[i].horizontal_offset = bs_read_u(b, 16);
                sei_svc->layers[i].vertical_offset = bs_read_u(b, 16);
                sei_svc->layers[i].region_width = bs_read_u(b, 16);
                sei_svc->layers[i].region_height = bs_read_u(b, 16);
            }
        }
        if( sei_svc->layers[i].sub_pic_layer_flag )
        {
            sei_svc->layers[i].roi_id = bs_read_ue(b);
        }
        if( sei_svc->layers[i].iroi_division_info_present_flag )
        {
            sei_svc->layers[i].iroi_grid_flag = bs_read_u1(b);
            if( sei_svc->layers[i].iroi_grid_flag )
            {
                sei_svc->layers[i].grid_width_in_mbs_minus1 = bs_read_ue(b);
                sei_svc->layers[i].grid_height_in_mbs_minus1 = bs_read_ue(b);
            }
            else
            {
                sei_svc->layers[i].num_rois_minus1 = bs_read_ue(b);
                
                for( int j = 0; j <= sei_svc->layers[i].num_rois_minus1; j++ )
                {
                    sei_svc->layers[i].roi[j].first_mb_in_roi = bs_read_ue(b);
                    sei_svc->layers[i].roi[j].roi_width_in_mbs_minus1 = bs_read_ue(b);
                    sei_svc->layers[i].roi[j].roi_height_in_mbs_minus1 = bs_read_ue(b);
                }
            }
        }
        if( sei_svc->layers[i].layer_dependency_info_present_flag )
        {
            sei_svc->layers[i].num_directly_dependent_layers = bs_read_ue(b);
            for( int j = 0; j < sei_svc->layers[i].num_directly_dependent_layers; j++ )
            {
                sei_svc->layers[i].directly_dependent_layer_id_delta_minus1[j] = bs_read_ue(b);
            }
        }
        else
        {
            sei_svc->layers[i].layer_dependency_info_src_layer_id_delta = bs_read_ue(b);
        }
        if( sei_svc->layers[i].parameter_sets_info_present_flag )
        {
            sei_svc->layers[i].num_seq_parameter_sets = bs_read_ue(b);
            for( int j = 0; j < sei_svc->layers[i].num_seq_parameter_sets; j++ )
            {
                sei_svc->layers[i].seq_parameter_set_id_delta[j] = bs_read_ue(b);
            }
            sei_svc->layers[i].num_subset_seq_parameter_sets = bs_read_ue(b);
            for( int j = 0; j < sei_svc->layers[i].num_subset_seq_parameter_sets; j++ )
            {
                sei_svc->layers[i].subset_seq_parameter_set_id_delta[j] = bs_read_ue(b);
            }
            sei_svc->layers[i].num_pic_parameter_sets_minus1 = bs_read_ue(b);
            for( int j = 0; j < sei_svc->layers[i].num_pic_parameter_sets_minus1; j++ )
            {
                sei_svc->layers[i].pic_parameter_set_id_delta[j] = bs_read_ue(b);
            }
        }
        else
        {
            sei_svc->layers[i].parameter_sets_info_src_layer_id_delta = bs_read_ue(b);
        }
        if( sei_svc->layers[i].bitstream_restriction_info_present_flag )
        {
            sei_svc->layers[i].motion_vectors_over_pic_boundaries_flag = bs_read_u1(b);
            sei_svc->layers[i].max_bytes_per_pic_denom = bs_read_ue(b);
            sei_svc->layers[i].max_bits_per_mb_denom = bs_read_ue(b);
            sei_svc->layers[i].log2_max_mv_length_horizontal = bs_read_ue(b);
            sei_svc->layers[i].log2_max_mv_length_vertical = bs_read_ue(b);
            sei_svc->layers[i].max_num_reorder_frames = bs_read_ue(b);
            sei_svc->layers[i].max_dec_frame_buffering = bs_read_ue(b);
        }
        if( sei_svc->layers[i].layer_conversion_flag )
        {
            sei_svc->layers[i].conversion_type_idc = bs_read_ue(b);
            for( int j = 0; j < 2; j++ )
            {
                sei_svc->layers[i].rewriting_info_flag[j] = bs_read_u(b, 1);
                if( sei_svc->layers[i].rewriting_info_flag[j] )
                {
                    sei_svc->layers[i].rewriting_profile_level_idc[j] = bs_read_u(b, 24);
                    sei_svc->layers[i].rewriting_avg_bitrate[j] = bs_read_u(b, 16);
                    sei_svc->layers[i].rewriting_max_bitrate[j] = bs_read_u(b, 16);
                }
            }
        }
    }

    if( sei_svc->priority_layer_info_present_flag )
    {
        sei_svc->pr_num_dIds_minus1 = bs_read_ue(b);
        
        for( int i = 0; i <= sei_svc->pr_num_dIds_minus1; i++ ) {
            sei_svc->pr[i].pr_dependency_id = bs_read_u(b, 3);
            sei_svc->pr[i].pr_num_minus1 = bs_read_ue(b);
            for( int j = 0; j <= sei_svc->pr[i].pr_num_minus1; j++ )
            {
                sei_svc->pr[i].pr_info[j].pr_id = bs_read_ue(b);
                sei_svc->pr[i].pr_info[j].pr_profile_level_idc = bs_read_u(b, 24);
                sei_svc->pr[i].pr_info[j].pr_avg_bitrate = bs_read_u(b, 16);
                sei_svc->pr[i].pr_info[j].pr_max_bitrate = bs_read_u(b, 16);
            }
        }
        
    }

}
示例#13
0
//7.3.2.1 Sequence parameter set RBSP syntax
int read_seq_parameter_set_rbsp(sps_t* sps, bs_t* b) {

    int i;
    
    memset(sps, 0, sizeof(sps_t));

    sps->profile_idc = bs_read_u8(b);
    sps->constraint_set0_flag = bs_read_u1(b);
    sps->constraint_set1_flag = bs_read_u1(b);
    sps->constraint_set2_flag = bs_read_u1(b);
    sps->constraint_set3_flag = bs_read_u1(b);
    sps->constraint_set4_flag = bs_read_u1(b);
    sps->constraint_set5_flag = bs_read_u1(b);
    sps->reserved_zero_2bits  = bs_read_u(b,2);  /* all 0's */
    sps->level_idc = bs_read_u8(b);
    sps->seq_parameter_set_id = bs_read_ue(b);

    sps->chroma_format_idc = 1; 
    if( sps->profile_idc == 100 || sps->profile_idc == 110 ||
        sps->profile_idc == 122 || sps->profile_idc == 144 )
    {
        sps->chroma_format_idc = bs_read_ue(b);
        if( sps->chroma_format_idc == 3 )
        {
            sps->residual_colour_transform_flag = bs_read_u1(b);
        }
        sps->bit_depth_luma_minus8 = bs_read_ue(b);
        sps->bit_depth_chroma_minus8 = bs_read_ue(b);
        sps->qpprime_y_zero_transform_bypass_flag = bs_read_u1(b);
        sps->seq_scaling_matrix_present_flag = bs_read_u1(b);
        if( sps->seq_scaling_matrix_present_flag )
        {
            for( i = 0; i < 8; i++ )
            {
                sps->seq_scaling_list_present_flag[ i ] = bs_read_u1(b);
                if( sps->seq_scaling_list_present_flag[ i ] )
                {
                    if( i < 6 )
                    {
                        read_scaling_list( b, sps->ScalingList4x4[ i ], 16,
                                      sps->UseDefaultScalingMatrix4x4Flag[ i ]);
                    }
                    else
                    {
                        read_scaling_list( b, sps->ScalingList8x8[ i - 6 ], 64,
                                      sps->UseDefaultScalingMatrix8x8Flag[ i - 6 ] );
                    }
                }
            }
        }
    }
    sps->log2_max_frame_num_minus4 = bs_read_ue(b);
    sps->pic_order_cnt_type = bs_read_ue(b);
    if( sps->pic_order_cnt_type == 0 )
    {
        sps->log2_max_pic_order_cnt_lsb_minus4 = bs_read_ue(b);
    }
    else if( sps->pic_order_cnt_type == 1 )
    {
        sps->delta_pic_order_always_zero_flag = bs_read_u1(b);
        sps->offset_for_non_ref_pic = bs_read_se(b);
        sps->offset_for_top_to_bottom_field = bs_read_se(b);
        sps->num_ref_frames_in_pic_order_cnt_cycle = bs_read_ue(b);
        for( i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++ )
        {
            sps->offset_for_ref_frame[ i ] = bs_read_se(b);
        }
    }
    sps->num_ref_frames = bs_read_ue(b);
    sps->gaps_in_frame_num_value_allowed_flag = bs_read_u1(b);
    sps->pic_width_in_mbs_minus1 = bs_read_ue(b);
    sps->pic_height_in_map_units_minus1 = bs_read_ue(b);
    sps->frame_mbs_only_flag = bs_read_u1(b);
    if( !sps->frame_mbs_only_flag )
    {
        sps->mb_adaptive_frame_field_flag = bs_read_u1(b);
    }
    sps->direct_8x8_inference_flag = bs_read_u1(b);
    sps->frame_cropping_flag = bs_read_u1(b);
    if( sps->frame_cropping_flag )
    {
        sps->frame_crop_left_offset = bs_read_ue(b);
        sps->frame_crop_right_offset = bs_read_ue(b);
        sps->frame_crop_top_offset = bs_read_ue(b);
        sps->frame_crop_bottom_offset = bs_read_ue(b);
    }
    sps->vui_parameters_present_flag = bs_read_u1(b);
    if( sps->vui_parameters_present_flag )
    {
        read_vui_parameters(sps, b);
    }
    read_rbsp_trailing_bits(b);

    return 0;
}
示例#14
0
//Appendix E.1.1 VUI parameters syntax
void read_vui_parameters(sps_t* sps, bs_t* b)
{

    sps->vui.aspect_ratio_info_present_flag = bs_read_u1(b);
    if( sps->vui.aspect_ratio_info_present_flag )
    {
        sps->vui.aspect_ratio_idc = bs_read_u8(b);
        if( sps->vui.aspect_ratio_idc == SAR_Extended )
        {
            sps->vui.sar_width = bs_read_u(b,16);
            sps->vui.sar_height = bs_read_u(b,16);
        }
    }
    sps->vui.overscan_info_present_flag = bs_read_u1(b);
    if( sps->vui.overscan_info_present_flag )
    {
        sps->vui.overscan_appropriate_flag = bs_read_u1(b);
    }
    sps->vui.video_signal_type_present_flag = bs_read_u1(b);
    if( sps->vui.video_signal_type_present_flag )
    {
        sps->vui.video_format = bs_read_u(b,3);
        sps->vui.video_full_range_flag = bs_read_u1(b);
        sps->vui.colour_description_present_flag = bs_read_u1(b);
        if( sps->vui.colour_description_present_flag )
        {
            sps->vui.colour_primaries = bs_read_u8(b);
            sps->vui.transfer_characteristics = bs_read_u8(b);
            sps->vui.matrix_coefficients = bs_read_u8(b);
        }
    }
    sps->vui.chroma_loc_info_present_flag = bs_read_u1(b);
    if( sps->vui.chroma_loc_info_present_flag )
    {
        sps->vui.chroma_sample_loc_type_top_field = bs_read_ue(b);
        sps->vui.chroma_sample_loc_type_bottom_field = bs_read_ue(b);
    }
    sps->vui.timing_info_present_flag = bs_read_u1(b);
    if( sps->vui.timing_info_present_flag )
    {
        sps->vui.num_units_in_tick = bs_read_u(b,32);
        sps->vui.time_scale = bs_read_u(b,32);
        sps->vui.fixed_frame_rate_flag = bs_read_u1(b);
    }
    sps->vui.nal_hrd_parameters_present_flag = bs_read_u1(b);
    if( sps->vui.nal_hrd_parameters_present_flag )
    {
        read_hrd_parameters(sps, b);
    }
    sps->vui.vcl_hrd_parameters_present_flag = bs_read_u1(b);
    if( sps->vui.vcl_hrd_parameters_present_flag )
    {
        read_hrd_parameters(sps, b);
    }
    if( sps->vui.nal_hrd_parameters_present_flag || sps->vui.vcl_hrd_parameters_present_flag )
    {
        sps->vui.low_delay_hrd_flag = bs_read_u1(b);
    }
    sps->vui.pic_struct_present_flag = bs_read_u1(b);
    sps->vui.bitstream_restriction_flag = bs_read_u1(b);
    if( sps->vui.bitstream_restriction_flag )
    {
        sps->vui.motion_vectors_over_pic_boundaries_flag = bs_read_u1(b);
        sps->vui.max_bytes_per_pic_denom = bs_read_ue(b);
        sps->vui.max_bits_per_mb_denom = bs_read_ue(b);
        sps->vui.log2_max_mv_length_horizontal = bs_read_ue(b);
        sps->vui.log2_max_mv_length_vertical = bs_read_ue(b);
        sps->vui.num_reorder_frames = bs_read_ue(b);
        sps->vui.max_dec_frame_buffering = bs_read_ue(b);
    }
}