📄 input_psi.c
字号:
} break; default: break; } }#endif } } }#undef p_descr}/***************************************************************************** * DecodeSrvDescrSection ***************************************************************************** * FIXME: A finir et a refaire proprement ?? *****************************************************************************/void DecodeSrvDescrSection( byte_t* p_sdt, input_thread_t *p_input ){ u16 i_stream_id; u8 i_version; u16 i_length; int i_index; int i_offset; boolean_t b_must_update = 0; int i_descr_end; ASSERT(p_sdt); ASSERT(p_input);#define p_stream (p_input->p_stream) /* Read stream id and version number immediately, to be sure they will be initialised in all the cases in which we will need them */ i_stream_id = U16_AT(&p_sdt[3]); i_version = (p_sdt[5] >> 1) & 0x1F; intf_DbgMsg("TS Id: %d, version: %d\n", i_stream_id, i_version); /* Take the descriptor into account only if it describes the streams we are receiving */ if( p_stream->i_stream_id != i_stream_id ) { intf_DbgMsg("SDT doen't apply to our TS but to %s: aborting\n", U16_AT(&p_sdt[3])); } else { /* Section applyies to our TS, test if the SDT is up to date */ if( p_stream->i_SDT_version != i_version ) { intf_DbgMsg("SDT has been updated, NOT YET IMPLEMENTED\n"); /* Ask the PSI decoder to rebuild the table */ b_must_update = 1; } } /* Rebuild the table if needed */ if( b_must_update ) { intf_DbgMsg("Updating SDT table\n"); i_length = p_sdt[1] & 0x0FFF; i_offset = 11; while(i_offset < i_length) { /* Find the program to which the description applies */ for( i_index = 0; i_index < p_stream->i_pgrm_number; i_index++ ) { if( p_stream->ap_programs[i_index]->i_number == U16_AT(&p_sdt[i_offset]) ) { /* Here we are */ intf_DbgMsg("FOUND: %d\n", p_stream->ap_programs[i_index]->i_number); break; } } /* Copy the info to the description of that program */ i_offset += 5; intf_DbgMsg("description length for SDT: %d\n", (U16_AT(&p_sdt[i_offset-2]) & 0x0FFF)); i_descr_end = (U16_AT(&p_sdt[i_offset-2]) & 0x0FFF) + i_offset; intf_DbgMsg("description ends at offset: %d\n", i_descr_end); while( i_offset < i_descr_end ) { DecodePgrmDescriptor(&p_sdt[i_offset], p_stream->ap_programs[i_index]); i_offset += p_sdt[i_offset+1] + 2; } } }#undef p_stream}/***************************************************************************** * DecodePgrmDescr ***************************************************************************** * Decode any descriptor applying to the definition of a program *****************************************************************************/static void DecodePgrmDescriptor( byte_t* p_descriptor, pgrm_descriptor_t* p_pgrm ){ u8 i_type; /* Type of the descriptor */ u8 i_length; /* Length of the descriptor */#ifdef DVB_EXTENSIONS int i_offset; /* Current position in the descriptor */#endif ASSERT(p_descriptor); ASSERT(p_pgrm); /* Read type and length of the descriptor */ i_type = p_descriptor[0]; i_length = p_descriptor[1]; /* Handle specific descriptor info */ switch(i_type) {#ifdef DVB_EXTENSIONS case PSI_SERVICE_DESCRIPTOR: { /* Store service type */ p_pgrm->i_srv_type = p_descriptor[2]; /* Jump to the beginning of the service name */ i_offset = p_descriptor[3] + 5; /* Check that the charset used is the normal one (latin) by testing the first byte of the name */ if( p_descriptor[i_offset] >= 0x20 ) { /* The charset is the one of our computer: just dup the string */ p_pgrm->psz_srv_name = malloc(i_length - i_offset +1); memcpy(p_pgrm->psz_srv_name, &p_descriptor[i_offset], i_length - i_offset); p_pgrm->psz_srv_name[i_length - i_offset + 1] = '\0'; } else { /* Indicate that the name couldn't be printed */ p_pgrm->psz_srv_name = "Ununderstandable :)"; } break; }#endif default:// intf_DbgMsg("Unhandled program descriptor received (type: %d)\n", i_type);// intf_DbgMsg("Unhandled ES descriptor received (type: %d)\n", i_type); }}/***************************************************************************** * DecodeESDescriptor ***************************************************************************** * Decode any descriptor applying to the definition of an ES *****************************************************************************/static void DecodeESDescriptor( byte_t* p_descriptor, es_descriptor_t* p_es ){ u8 i_type; /* Type of the descriptor */ u8 i_length; /* Length of the descriptor */// int i_offset; /* Current position in the descriptor */ ASSERT(p_descriptor); ASSERT(p_es); /* Read type and length of the descriptor */ i_type = p_descriptor[0]; i_length = p_descriptor[1]; switch( i_type ) { case PSI_VIDEO_STREAM_DESCRIPTOR: { intf_DbgMsg("Video stream descriptor received\n"); break; } case PSI_AUDIO_STREAM_DESCRIPTOR: { intf_DbgMsg("Audio stream descriptor received\n"); break; } case PSI_TARGET_BACKGROUND_GRID_DESCRIPTOR: { intf_DbgMsg("Target background descriptor received\n"); break; } case PSI_VIDEO_WINDOW_DESCRIPTOR: { intf_DbgMsg("Video window descriptor received\n"); break; } default:// intf_DbgMsg("Unhandled ES descriptor received (type: %d)\n", i_type);// intf_DbgMsg("Unhandled ES descriptor received (type: %d)\n", i_type); }}/***************************************************************************** * input_AddPsiPID: Start to receive the PSI info contained in a PID ***************************************************************************** * Add a descriptor to the table of es descriptor for that es and mark the es * as being to be received by the input (since all PSI must be received to * build the description of the program) *****************************************************************************/static int input_AddPsiPID( input_thread_t *p_input, int i_pid ){ int i_index; es_descriptor_t* p_psi_es; int i_rc = 0; /* Store the description of this stream in the input thread */ p_psi_es = AddESDescr(p_input, NULL, i_pid); if(p_psi_es) { /* Precise this ES carries PSI */ p_psi_es->b_psi = 1; /* Create the buffer needed by the PSI decoder */ p_psi_es->p_psi_section = malloc( sizeof( psi_section_t) ); if( !p_psi_es->p_psi_section ) { intf_ErrMsg( "Malloc error\n" ); i_rc = -1; } else { /* Init the reception for that PID */ p_psi_es->p_psi_section->b_running_section = 0;// p_psi_es->p_psi_section->b_discard_payload = 0; /* Ask the input thread to demultiplex it: since the interface can also access the table of selected es, lock the elementary stream structure */ vlc_mutex_lock( &p_input->es_lock ); for( i_index = 0; i_index < INPUT_MAX_SELECTED_ES; i_index++ ) { if( !p_input->pp_selected_es[i_index] ) { intf_DbgMsg( "Free Selected ES slot found at offset %d for PID %d\n", i_index, i_pid ); p_input->pp_selected_es[i_index] = p_psi_es; break; } } vlc_mutex_unlock( &p_input->es_lock ); if( i_index >= INPUT_MAX_SELECTED_ES ) { intf_ErrMsg( "Stream carries to many PID for our decoder\n" ); i_rc = -1; } } } return( i_rc );}/***************************************************************************** * input_DelPsiPID: Stop to receive the PSI info contained in a PID ***************************************************************************** * Remove the PID from the list of ES descriptors and from the list of ES that * the input must receive. * Known PID for PSI should always be received, so that their description * should be pointed out by a member of pp_selected_es. But as INPUT_MAX_ES * can be different of INPUT_MAX_SELECTED_ES, this may happen, so that we must * do 2 loops. *****************************************************************************/static int input_DelPsiPID( input_thread_t *p_input, int i_pid ){ int i_es_index, i_last_sel; intf_DbgMsg( "Deleting PSI PID %d\n", i_pid ); /* Stop to receive the ES. Since the interface can also access the table of selected es, lock the elementary stream structure */ vlc_mutex_lock( &p_input->es_lock ); for( i_es_index = 0; i_es_index < INPUT_MAX_SELECTED_ES; i_es_index++ ) { if( p_input->pp_selected_es[i_es_index] && p_input->pp_selected_es[i_es_index]->i_id == i_pid ) { /* Unmark the stream */ p_input->pp_selected_es[i_es_index] = NULL; /* There must not be any gap in the pp_selected_es, so move the last selected stream to this slot */ for( i_last_sel = i_es_index; p_input->pp_selected_es[i_last_sel] && i_last_sel < INPUT_MAX_SELECTED_ES; i_last_sel++ ); p_input->pp_selected_es[i_es_index] = p_input->pp_selected_es[i_last_sel]; p_input->pp_selected_es[i_last_sel] = NULL; break; } } vlc_mutex_unlock( &p_input->es_lock );#ifdef DEBUG /* Check if the pp_selected_es table may be corrupted */ if( i_es_index >= INPUT_MAX_PROGRAM_ES ) { intf_ErrMsg( "DelPsiPID error: PID %d is not currently received\n", i_pid ); }#endif /* Remove the desription of that ES from the table of ES */ DestroyESDescr(p_input, NULL, i_pid); return( 0 );}/***************************************************************************** * Precalculate the 32-bit CRC table ***************************************************************************** * This table is a global variable shared by all decoders, so it has to be * initialised only once *****************************************************************************/void BuildCrc32Table( ){ u32 i, j, k; for( i = 0 ; i < 256 ; i++ ) { k = 0; for (j = (i << 24) | 0x800000 ; j != 0x80000000 ; j <<= 1) k = (k << 1) ^ (((k ^ j) & 0x80000000) ? 0x04c11db7 : 0); i_crc_32_table[i] = k; }}/***************************************************************************** * Test the validity of a checksum *****************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -