📄 input_psi.c
字号:
* The checksum must be stored at the end of the data, and the given size must * include the 32 bits of the CRC. * Return 0 if the checksum is OK, any other value if the data are corrupted *****************************************************************************/int CheckCRC32(byte_t* p_data, int i_data_size){ int i; u32 i_crc = 0xffffffff; ASSERT(p_data); for (i = 0; i < i_data_size; i++) i_crc = (i_crc << 8) ^ i_crc_32_table[(i_crc >> 24) ^ p_data[i]]; return i_crc;}/***************************************************************************** * Is_known: check if a given section has already been received ***************************************************************************** * As a table cannot be segmented into more than 256 sections, we store a 256 * bits long table, each bit set to one indicating that the corresponding * saction has been received *****************************************************************************/boolean_t Is_known( byte_t* a_known_section, u8 i_section ){ byte_t mask; boolean_t b_is_known; /* Where to get the information ? */ int i_bit_in_byte = i_section % 8; int i_byte_in_table = (i_section - i_bit_in_byte) / 8; /* Build mask to read the Is_known flag */ mask = 0x01 << i_bit_in_byte; /* Read the flag */ b_is_known = a_known_section[i_byte_in_table] & mask; return b_is_known;}/***************************************************************************** * Set_known: mark a given section has having been received ***************************************************************************** * *****************************************************************************/static void Set_known( byte_t* a_known_section, u8 i_section ){ byte_t mask; /* Where to get the information ? */ int i_bit_in_byte = i_section % 8; int i_byte_in_table = (i_section - i_bit_in_byte) / 8; /* Build mask to read the Is_known flag */ mask = 0x01 << i_bit_in_byte; /* Set the flag */ a_known_section[i_byte_in_table] |= mask;}/***************************************************************************** * Unset_known: remove the 'received' mark for a given section ***************************************************************************** * *****************************************************************************/static void Unset_known( byte_t* a_known_section, u8 i_section ){ byte_t mask; /* Where to get the information ? */ int i_bit_in_byte = i_section % 8; int i_byte_in_table = (i_section - i_bit_in_byte) / 8; /* Build mask to read the Is_known flag */ mask = 0x01 << i_bit_in_byte; mask = ~mask; /* Unset the flag */ a_known_section[i_byte_in_table] &= mask;}/***************************************************************************** * AddStreamDescr: add and init the stream descriptor of the given input ***************************************************************************** * *****************************************************************************/static stream_descriptor_t* AddStreamDescr(input_thread_t* p_input, u16 i_stream_id){ ASSERT(p_input); intf_DbgMsg("Adding description for stream %d\n", i_stream_id); p_input->p_stream = malloc( sizeof(stream_descriptor_t) ); p_input->p_stream->i_stream_id = i_stream_id; p_input->p_stream->i_PAT_version = PSI_UNINITIALISED; p_input->p_stream->i_known_PAT_sections = 0; memset( p_input->p_stream->a_known_PAT_sections, 0, sizeof(*p_input->p_stream->a_known_PAT_sections) ); p_input->p_stream->b_is_PAT_complete = 0; p_input->p_stream->i_known_PMT_sections = 0; memset( p_input->p_stream->a_known_PMT_sections, 0, sizeof(*p_input->p_stream->a_known_PMT_sections) ); p_input->p_stream->b_is_PMT_complete = 0;#ifdef DVB_EXTENSIONS p_input->p_stream->i_SDT_version = PSI_UNINITIALISED; p_input->p_stream->i_known_SDT_sections = 0; memset( p_input->p_stream->a_known_SDT_sections, 0, sizeof(*p_input->p_stream->a_known_SDT_sections) ); p_input->p_stream->b_is_SDT_complete = 0;#endif p_input->p_stream->i_pgrm_number = 0; p_input->p_stream->ap_programs = NULL; return p_input->p_stream;}/***************************************************************************** * DestroyStreamDescr: destroy the stream desciptor of the given input ***************************************************************************** * *****************************************************************************/static void DestroyStreamDescr(input_thread_t* p_input, u16 i_stream_id){ int i_index; ASSERT(p_input); /* Free the structures that describes the programs of that stream */ for( i_index = 0; i_index < p_input->p_stream->i_pgrm_number; i_index++ ) { DestroyPgrmDescr( p_input, p_input->p_stream, p_input->p_stream->ap_programs[i_index]->i_number ); } /* Free the table of pgrm descriptors */ free( p_input->p_stream->ap_programs ); /* Free the structure that describes the stream itself */ free( p_input->p_stream ); /* Input thread has no more stream descriptor */ p_input->p_stream = NULL;}/***************************************************************************** * AddPgrmDescr: add and init a program descriptor ***************************************************************************** * This program descriptor will be referenced in the given stream descriptor *****************************************************************************/static pgrm_descriptor_t* AddPgrmDescr( stream_descriptor_t* p_stream, u16 i_pgrm_id){ int i_pgrm_index = p_stream->i_pgrm_number; /* Where to add the pgrm */ ASSERT(p_stream); intf_DbgMsg("Adding description for pgrm %d\n", i_pgrm_id); /* Add an entry to the list of program associated with the stream */ p_stream->i_pgrm_number++; p_stream->ap_programs = realloc( p_stream->ap_programs, p_stream->i_pgrm_number*sizeof(pgrm_descriptor_t*) ); /* Allocate the structure to store this description */ p_stream->ap_programs[i_pgrm_index] = malloc(sizeof(pgrm_descriptor_t)); /* Init this entry */ p_stream->ap_programs[i_pgrm_index]->i_number = i_pgrm_id; p_stream->ap_programs[i_pgrm_index]->i_version = PSI_UNINITIALISED; p_stream->ap_programs[i_pgrm_index]->b_is_ok = 0; p_stream->ap_programs[i_pgrm_index]->i_es_number = 0; p_stream->ap_programs[i_pgrm_index]->ap_es = NULL; /* descriptors ? XXX?? */ return p_stream->ap_programs[i_pgrm_index];}/***************************************************************************** * AddPgrmDescr: destroy a program descriptor ***************************************************************************** * All ES descriptions referenced in the descriptor will be deleted. *****************************************************************************/static void DestroyPgrmDescr( input_thread_t * p_input, stream_descriptor_t * p_stream, u16 i_pgrm_id ){ int i_index, i_pgrm_index = -1; pgrm_descriptor_t* p_pgrm = NULL; ASSERT( p_stream ); intf_DbgMsg("Deleting description for pgrm %d\n", i_pgrm_id); /* Find where this program is described */ for( i_index = 0; i_index < p_stream->i_pgrm_number; i_index++ ) { if( p_stream->ap_programs[i_index]->i_number == i_pgrm_id ) { i_pgrm_index = i_index; p_pgrm = p_stream->ap_programs[ i_pgrm_index ]; break; } } /* Make sure that the pgrm exists */ ASSERT(i_pgrm_index >= 0); ASSERT(p_pgrm); /* Free the structures that describe the es that belongs to that program */ for( i_index = 0; i_index < p_pgrm->i_es_number; i_index++ ) { DestroyESDescr( p_input, p_pgrm, p_pgrm->ap_es[i_index]->i_id ); } /* Free the table of es descriptors */ free( p_pgrm->ap_es ); /* Free the description of this stream */ free( p_pgrm ); /* Remove this program from the stream's list of programs */ p_stream->i_pgrm_number--; p_stream->ap_programs[i_pgrm_index] = p_stream->ap_programs[p_stream->i_pgrm_number]; p_stream->ap_programs = realloc( p_stream->ap_programs, p_stream->i_pgrm_number*sizeof(pgrm_descriptor_t *) );}/***************************************************************************** * AddESDescr: ***************************************************************************** * Reserve a slot in the table of ES descritors for the ES and add it to the * list of ES of p_pgrm. If p_pgrm if NULL, then the ES is considered as stand * alone (PSI ?) *****************************************************************************/static es_descriptor_t* AddESDescr(input_thread_t* p_input, pgrm_descriptor_t* p_pgrm, u16 i_es_pid){ int i_index; es_descriptor_t* p_es = NULL; ASSERT(p_input); intf_DbgMsg("Adding description for ES %d\n", i_es_pid); /* Find an empty slot to store the description of that es */ for( i_index = 0; i_index < INPUT_MAX_ES && p_input->p_es[i_index].i_id != EMPTY_PID; i_index++ ); if( i_index >= INPUT_MAX_ES ) { /* No slot is empty */ intf_ErrMsg("Stream carries to many PID for our decoder\n"); } else { /* Reserve the slot for that ES */ p_es = &p_input->p_es[i_index]; p_es->i_id = i_es_pid; intf_DbgMsg("Slot %d in p_es table assigned to ES %d\n", i_index, i_es_pid); /* Init its values */ p_es->i_type = 0; /* XXX?? */ p_es->b_psi = 0; p_es->b_pcr = 0; p_es->i_continuity_counter = 0xFF; p_es->p_pes_packet = NULL;// p_es->p_next_pes_packet = NULL; p_es->p_dec = NULL; /* Add this ES to the program definition if one is given */ if( p_pgrm ) { p_pgrm->i_es_number++; p_pgrm->ap_es = realloc( p_pgrm->ap_es, p_pgrm->i_es_number*sizeof(es_descriptor_t *) ); p_pgrm->ap_es[p_pgrm->i_es_number-1] = p_es; intf_DbgMsg( "Added ES %d to definition of pgrm %d\n", i_es_pid, p_pgrm->i_number ); } else intf_DbgMsg( "Added ES %d not added to the definition of any pgrm\n", i_es_pid ); } return p_es;}/***************************************************************************** * DestroyESDescr: ***************************************************************************** * *****************************************************************************/static void DestroyESDescr(input_thread_t* p_input, pgrm_descriptor_t* p_pgrm, u16 i_pid){ int i_index; /* Look for the description of the ES */ for(i_index = 0; i_index < INPUT_MAX_ES; i_index++) { if( p_input->p_es[i_index].i_id == i_pid ) { /* The table of stream descriptors is static, so don't free memory but just mark the slot as unused */ p_input->p_es[i_index].i_id = EMPTY_PID; break; } } /* Remove this ES from the description of the program if it is associated to one */ if( p_pgrm ) { for( i_index = 0; i_index < INPUT_MAX_ES; i_index++ ) { if( p_input->p_es[i_index].i_id == i_pid ) { p_pgrm->i_es_number--; p_pgrm->ap_es[i_index] = p_pgrm->ap_es[p_pgrm->i_es_number]; p_pgrm->ap_es = realloc(p_pgrm->ap_es, p_pgrm->i_es_number); break; } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -