📄 input.c
字号:
/***************************************************************************** * input.c: input thread * Read an MPEG2 stream, demultiplex and parse it before sending it to * decoders. ***************************************************************************** * Copyright (C) 1998, 1999, 2000 VideoLAN * * Authors: * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include "defs.h"#include <errno.h> /* errno */#include <sys/types.h> /* on BSD, uio.h needs types.h */#include <sys/uio.h> /* "input.h" */#include <string.h> /* strerror() */#include <stdlib.h> /* free() */#include <netinet/in.h> /* ntohs() */#include "config.h"#include "common.h"#include "threads.h"#include "mtime.h"#include "intf_msg.h"#include "plugins.h"#include "debug.h"#include "input.h"#include "input_psi.h"#include "input_pcr.h"#include "input_netlist.h"#include "decoder_fifo.h"#include "input_file.h"#include "input_network.h"#include "audio_output.h" /* aout_thread_t */#include "audio_decoder.h" /* audiodec_t (for audio_decoder_thread.h) */#include "audio_decoder_thread.h" /* adec_thread_t */#include "ac3_decoder.h" /* ac3dec_t (for ac3_decoder_thread.h) */#include "ac3_decoder_thread.h" /* ac3dec_thread_t */#include "lpcm_decoder.h"#include "lpcm_decoder_thread.h"#include "video.h" /* picture_t (for video_output.h) */#include "video_output.h" /* vout_thread_t */#include "vdec_idct.h" /* dctelem_t (for video_parser.h) */#include "vdec_motion.h" /* f_motion_t (for video_parser.h) */#include "vpar_blocks.h" /* macroblock_t (for video_parser.h) */#include "vpar_headers.h" /* sequence_t (for video_parser.h) */#include "vpar_synchro.h" /* video_synchro_t (for video_parser.h) */#include "video_parser.h" /* vpar_thread_t */#include "spu_decoder.h" /* spudec_thread_t */#include "main.h"/***************************************************************************** * Local prototypes *****************************************************************************/static void RunThread ( input_thread_t *p_input );static void ErrorThread ( input_thread_t *p_input );static void EndThread ( input_thread_t *p_input );static __inline__ int input_ReadPacket( input_thread_t *p_input );static __inline__ void input_SortPacket( input_thread_t *p_input, ts_packet_t *ts_packet );static __inline__ void input_DemuxTS( input_thread_t *p_input, ts_packet_t *ts_packet, es_descriptor_t *es_descriptor );static __inline__ void input_DemuxPES( input_thread_t *p_input, ts_packet_t *ts_packet, es_descriptor_t *p_es_descriptor, boolean_t b_unit_start, boolean_t b_packet_lost );static __inline__ void input_ParsePES( input_thread_t *p_input, es_descriptor_t *p_es_descriptor );static __inline__ void input_DemuxPSI( input_thread_t *p_input, ts_packet_t *ts_packet, es_descriptor_t *p_es_descriptor, boolean_t b_unit_start, boolean_t b_packet_lost );/***************************************************************************** * input_CreateThread: creates a new input thread ***************************************************************************** * This function creates a new input, and returns a pointer * to its description. On error, it returns NULL. * If pi_status is NULL, then the function will block until the thread is ready. * If not, it will be updated using one of the THREAD_* constants. *****************************************************************************/input_thread_t *input_CreateThread ( int i_method, void *p_source, int i_port, int i_vlan, p_vout_thread_t p_vout, p_aout_thread_t p_aout, int *pi_status ){ input_thread_t * p_input; /* thread descriptor */ int i_status; /* thread status */ int i_index; /* index for tables initialization */ /* Allocate descriptor */ intf_DbgMsg("\n"); p_input = (input_thread_t *)malloc( sizeof(input_thread_t) ); if( p_input == NULL ) { intf_ErrMsg("error: %s\n", strerror(ENOMEM)); return( NULL ); } /* Initialize thread properties */ p_input->b_die = 0; p_input->b_error = 0; p_input->pi_status = (pi_status != NULL) ? pi_status : &i_status; *p_input->pi_status = THREAD_CREATE; /* Initialize input method description */ p_input->i_method = i_method; p_input->p_source = p_source; p_input->i_port = i_port; p_input->i_vlan = i_vlan; switch( i_method ) { case INPUT_METHOD_TS_FILE: /* file methods */ p_input->p_Open = input_FileOpen; p_input->p_Read = input_FileRead; p_input->p_Close = input_FileClose; break; case INPUT_METHOD_TS_VLAN_BCAST: /* vlan network method */ if( !p_main->b_vlans ) { intf_ErrMsg("error: vlans are not activated\n"); free( p_input ); return( NULL ); } /* ... pass through */ case INPUT_METHOD_TS_UCAST: /* network methods */ case INPUT_METHOD_TS_MCAST: case INPUT_METHOD_TS_BCAST: p_input->p_Open = input_NetworkOpen; p_input->p_Read = input_NetworkRead; p_input->p_Close = input_NetworkClose; break; default: intf_ErrMsg("error: unknow input method\n"); free( p_input ); return( NULL ); break; } /* Initialize stream description */ for( i_index = 0; i_index < INPUT_MAX_ES; i_index++ ) { p_input->p_es[i_index].i_id = EMPTY_PID; p_input->pp_selected_es[i_index] = NULL; } /* Initialize default settings for spawned decoders */ p_input->p_aout = p_aout; p_input->p_vout = p_vout;#ifdef STATS /* Initialize statistics */ p_input->c_loops = 0; p_input->c_bytes = 0; p_input->c_payload_bytes = 0; p_input->c_packets_read = 0; p_input->c_packets_trashed = 0;#endif /* Initialize PSI and PCR decoders */ if( input_PsiInit( p_input ) ) { free( p_input ); return( NULL ); } if( input_PcrInit( p_input ) ) { input_PsiEnd( p_input ); free( p_input ); return( NULL ); } /* Initialize netlists */ if( input_NetlistInit( p_input ) ) { input_PsiEnd( p_input ); input_PcrEnd( p_input ); free( p_input ); return( NULL ); } intf_DbgMsg("configuration: method=%d, source=%s, port=%d, vlan=%d\n", i_method, p_source, i_port, i_vlan ); /* Let the appropriate method open the socket. */ if( p_input->p_Open( p_input ) ) { input_NetlistEnd( p_input ); input_PsiEnd( p_input ); input_PcrEnd( p_input ); free( p_input ); return( NULL ); } /* Create thread and set locks. */ vlc_mutex_init( &p_input->netlist.lock ); vlc_mutex_init( &p_input->programs_lock ); vlc_mutex_init( &p_input->es_lock ); if( vlc_thread_create(&p_input->thread_id, "input", (void *) RunThread, (void *) p_input) ) { intf_ErrMsg("error: %s\n", strerror(errno) ); p_input->p_Close( p_input ); input_NetlistEnd( p_input );; input_PsiEnd( p_input ); input_PcrEnd( p_input ); free( p_input ); return( NULL ); } intf_Msg("Input initialized\n"); /* If status is NULL, wait until the thread is created */ if( pi_status == NULL ) { do { msleep( THREAD_SLEEP ); }while( (i_status != THREAD_READY) && (i_status != THREAD_ERROR) && (i_status != THREAD_FATAL) ); if( i_status != THREAD_READY ) { return( NULL ); } } return( p_input );}/***************************************************************************** * input_DestroyThread: mark an input thread as zombie ***************************************************************************** * This function should not return until the thread is effectively cancelled. *****************************************************************************/void input_DestroyThread( input_thread_t *p_input, int *pi_status ){ int i_status; /* thread status */ /* Set status */ p_input->pi_status = (pi_status != NULL) ? pi_status : &i_status; *p_input->pi_status = THREAD_DESTROY; /* Request thread destruction */ p_input->b_die = 1; /* If status is NULL, wait until thread has been destroyed */ if( pi_status == NULL ) { do { msleep( THREAD_SLEEP ); }while( (i_status != THREAD_OVER) && (i_status != THREAD_ERROR) && (i_status != THREAD_FATAL) ); }}#if 0/***************************************************************************** * input_OpenAudioStream: open an audio stream ***************************************************************************** * This function spawns an audio decoder and plugs it on the audio output * thread. *****************************************************************************/int input_OpenAudioStream( input_thread_t *p_input, int i_id ){ /* XXX?? */}/***************************************************************************** * input_CloseAudioStream: close an audio stream ***************************************************************************** * This function destroys an audio decoder. *****************************************************************************/void input_CloseAudioStream( input_thread_t *p_input, int i_id ){ /* XXX?? */}/***************************************************************************** * input_OpenVideoStream: open a video stream ***************************************************************************** * This function spawns a video decoder and plugs it on a video output thread. *****************************************************************************/int input_OpenVideoStream( input_thread_t *p_input, struct vout_thread_s *p_vout, struct video_cfg_s * p_cfg ){ /* XXX?? */}/***************************************************************************** * input_CloseVideoStream: close a video stream ***************************************************************************** * This function destroys an video decoder. *****************************************************************************/void input_CloseVideoStream( input_thread_t *p_input, int i_id ){ /* XXX?? */}#endif/* following functions are local *//***************************************************************************** * InitThread: initialize input thread ***************************************************************************** * This function is called from RunThread and performs the second step of the * initialization. It returns 0 on success. Note that the thread's flag are not * modified inside this function. *****************************************************************************/static int InitThread( input_thread_t *p_input ){ /* Mark thread as running and return */ intf_DbgMsg("\n"); *p_input->pi_status = THREAD_READY; intf_DbgMsg("thread ready\n"); return( 0 );}/***************************************************************************** * RunThread: main thread loop ***************************************************************************** * Thread in charge of processing the network packets and demultiplexing. *****************************************************************************/static void RunThread( input_thread_t *p_input ){ /* * Initialize thread and free configuration */ p_input->b_error = InitThread( p_input ); if( p_input->b_error ) { free( p_input ); /* destroy descriptor */ return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -