Пример #1
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;
}
Пример #2
0
//7.3.3.3 Decoded reference picture marking syntax
void structure(dec_ref_pic_marking)(h264_stream_t* h, bs_t* b)
{
    slice_header_t* sh = h->sh;
    // FIXME should be an array

    if( h->nal->nal_unit_type == 5 )
    {
        value( sh->drpm.no_output_of_prior_pics_flag, u1 );
        value( sh->drpm.long_term_reference_flag, u1 );
    }
    else
    {
        value( sh->drpm.adaptive_ref_pic_marking_mode_flag, u1 );
        if( sh->drpm.adaptive_ref_pic_marking_mode_flag )
        {
            int n = -1;
            do
            {
                n++;
                value( sh->drpm.memory_management_control_operation[ n ], ue );
                if( sh->drpm.memory_management_control_operation[ n ] == 1 ||
                        sh->drpm.memory_management_control_operation[ n ] == 3 )
                {
                    value( sh->drpm.difference_of_pic_nums_minus1[ n ], ue );
                }
                if(sh->drpm.memory_management_control_operation[ n ] == 2 )
                {
                    value( sh->drpm.long_term_pic_num[ n ], ue );
                }
                if( sh->drpm.memory_management_control_operation[ n ] == 3 ||
                        sh->drpm.memory_management_control_operation[ n ] == 6 )
                {
                    value( sh->drpm.long_term_frame_idx[ n ], ue );
                }
                if( sh->drpm.memory_management_control_operation[ n ] == 4 )
                {
                    value( sh->drpm.max_long_term_frame_idx_plus1[ n ], ue );
                }
            } while( sh->drpm.memory_management_control_operation[ n ] != 0 && ! bs_eof(b) );
        }
    }
}
Пример #3
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;
}
Пример #4
0
int more_rbsp_trailing_data(h264_stream_t* h, bs_t* b) {
    return !bs_eof(b);
}