ts.c
来自「VLC媒体播放程序」· C语言 代码 · 共 1,679 行 · 第 1/5 页
C
1,679 行
/***************************************************************************** * mpeg_ts.c : Transport Stream input module for vlc ***************************************************************************** * Copyright (C) 2000-2004 VideoLAN * $Id: ts.c,v 1.46 2004/01/25 20:05:28 hartman Exp $ * * Authors: Henri Fallon <henri@via.ecp.fr> * Johan Bilien <jobi@via.ecp.fr> * * 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 <stdlib.h>#include <vlc/vlc.h>#include <vlc/input.h>#include "iso_lang.h"#if defined MODULE_NAME_IS_ts_dvbpsi# ifdef HAVE_DVBPSI_DR_H# include <dvbpsi/dvbpsi.h># include <dvbpsi/descriptor.h># include <dvbpsi/pat.h># include <dvbpsi/pmt.h># include <dvbpsi/dr.h># else# include "dvbpsi.h"# include "descriptor.h"# include "tables/pat.h"# include "tables/pmt.h"# include "descriptors/dr.h"# endif#endif#include "system.h"#include "codecs.h"/***************************************************************************** * Constants *****************************************************************************/#define TS_READ_ONCE 200/***************************************************************************** * Private structure *****************************************************************************/struct demux_sys_t{ module_t * p_module; mpeg_demux_t mpeg;};#define local_iso639_getlang(p1, p2) \{ \ const iso639_lang_t * p_iso; \ p_iso = GetLang_2T((char*)(p1)); \ if( p_iso && strcmp(p_iso->psz_native_name,"Unknown")) \ { \ if( p_iso->psz_native_name[0] ) \ strncpy( (p2), p_iso->psz_native_name, 20 ); \ else \ strncpy( (p2), p_iso->psz_eng_name, 20 ); \ } \ else \ { \ p_iso = GetLang_2B((char*)(p1)); \ if ( p_iso ) \ { \ if( p_iso->psz_native_name[0] ) \ strncpy( (p2), p_iso->psz_native_name, 20 ); \ else \ strncpy( (p2), p_iso->psz_eng_name, 20 ); \ } \ else \ { \ strncpy( (p2), p1, 3 ); \ } \ } \}/***************************************************************************** * Local prototypes *****************************************************************************/static int Activate ( vlc_object_t * );static void Deactivate ( vlc_object_t * );static int Demux ( input_thread_t * );#if defined MODULE_NAME_IS_tsstatic void TSDemuxPSI ( input_thread_t *, data_packet_t *, es_descriptor_t *, vlc_bool_t );static void TSDecodePAT( input_thread_t *, es_descriptor_t *);static void TSDecodePMT( input_thread_t *, es_descriptor_t *);#define PSI_CALLBACK TSDemuxPSI#elif defined MODULE_NAME_IS_ts_dvbpsistatic void TS_DVBPSI_DemuxPSI ( input_thread_t *, data_packet_t *, es_descriptor_t *, vlc_bool_t );static void TS_DVBPSI_HandlePAT ( input_thread_t *, dvbpsi_pat_t * );static void TS_DVBPSI_HandlePMT ( input_thread_t *, dvbpsi_pmt_t * );#define PSI_CALLBACK TS_DVBPSI_DemuxPSI#endif/***************************************************************************** * Module descriptor *****************************************************************************/#define VLS_BACKWARDS_COMPAT_TEXT N_("Compatibility with pre-0.4 VLS")#define VLS_BACKWARDS_COMPAT_LONGTEXT N_( \ "The protocol for transmitting A/52 audio streams changed between VLC " \ "0.3.x and 0.4. By default VLC assumes you have the latest VLS. In case " \ "you're using an old version, select this option.")#define BUGGY_PSI_TEXT N_("Buggy PSI")#define BUGGY_PSI_LONGTEXT N_( \ "If you have a stream whose PSI packets do not feature incremented " \ "continuity counters, select this option.")vlc_module_begin();#if defined MODULE_NAME_IS_ts set_description( _("ISO 13818-1 MPEG Transport Stream input") ); set_capability( "demux", 160 ); add_shortcut( "ts" );#elif defined MODULE_NAME_IS_ts_dvbpsi set_description( _("ISO 13818-1 MPEG Transport Stream input (libdvbpsi)") ); set_capability( "demux", 170 ); add_shortcut( "ts_dvbpsi" );#endif add_bool( "vls-backwards-compat", 0, NULL, VLS_BACKWARDS_COMPAT_TEXT, VLS_BACKWARDS_COMPAT_LONGTEXT, VLC_TRUE ); add_bool( "buggy-psi", 0, NULL, BUGGY_PSI_TEXT, BUGGY_PSI_LONGTEXT, VLC_TRUE ); set_callbacks( Activate, Deactivate );vlc_module_end();/***************************************************************************** * Activate: initialize TS structures *****************************************************************************/static int Activate( vlc_object_t * p_this ){ input_thread_t * p_input = (input_thread_t *)p_this; demux_sys_t * p_demux; es_descriptor_t * p_pat_es; es_ts_data_t * p_demux_data; stream_ts_data_t * p_stream_data; byte_t * p_peek; vlc_bool_t b_force = VLC_FALSE; int i_sync_pos; /* Set the demux function */ p_input->pf_demux = Demux; p_input->pf_demux_control = demux_vaControlDefault; /* Have a peep at the show */ if( input_Peek( p_input, &p_peek, TS_PACKET_SIZE ) < TS_PACKET_SIZE ) { msg_Err( p_input, "cannot peek()" ); return VLC_EGENERIC; } if( *p_input->psz_demux && ( !strncmp( p_input->psz_demux, "ts", 3 ) || !strncmp( p_input->psz_demux, "ts_dvbpsi", 10 ) ) ) b_force = VLC_TRUE; /* In a TS_PACKET_SIZE buffer we should find a sync byte */ for( i_sync_pos = 0; i_sync_pos < TS_PACKET_SIZE && p_peek[i_sync_pos] != TS_SYNC_CODE; i_sync_pos++ ); if( i_sync_pos >= TS_PACKET_SIZE ) { if( b_force ) { /* User forced */ msg_Err( p_input, "this does not look like a TS stream, " "continuing anyway" ); } else { msg_Warn( p_input, "TS module discarded (no sync)" ); return VLC_EGENERIC; } } /* Now that we have the first TS_SYNC_CODE, check the following * TS_SYNC_CODEs are where they are supposed to be (one byte sync code * is not enough to ensure the sync). */ if( !b_force ) { if( input_Peek( p_input, &p_peek, TS_PACKET_SIZE * TS_SYNC_CODES_MIN ) < TS_PACKET_SIZE * TS_SYNC_CODES_MIN ) { msg_Err( p_input, "cannot peek()" ); return VLC_EGENERIC; } for( ; i_sync_pos < TS_PACKET_SIZE * TS_SYNC_CODES_MIN; i_sync_pos += TS_PACKET_SIZE ) { if( p_peek[i_sync_pos] != TS_SYNC_CODE ) { msg_Warn( p_input, "TS module discarded (lost sync)" ); return VLC_EGENERIC; } } } /* Adapt the bufsize for our only use. */ if( p_input->i_mtu != 0 ) { /* Have minimum granularity to avoid bottlenecks at the input level. */ p_input->i_bufsize = (p_input->i_mtu / TS_PACKET_SIZE) * TS_PACKET_SIZE; } p_demux = p_input->p_demux_data = malloc( sizeof(demux_sys_t ) ); if( p_demux == NULL ) { return -1; } p_input->p_private = (void*)&p_demux->mpeg; p_demux->p_module = module_Need( p_input, "mpeg-system", NULL ); if( p_demux->p_module == NULL ) { free( p_input->p_demux_data ); return -1; } vlc_mutex_lock( &p_input->stream.stream_lock ); if( input_InitStream( p_input, sizeof( stream_ts_data_t ) ) == -1 ) { module_Unneed( p_input, p_demux->p_module ); free( p_input->p_demux_data ); return -1; } p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data; p_stream_data->i_pat_version = PAT_UNINITIALIZED ; p_stream_data->b_buggy_psi = config_GetInt( p_input, "buggy-psi" );#ifdef MODULE_NAME_IS_ts_dvbpsi p_stream_data->p_pat_handle = (dvbpsi_handle *) dvbpsi_AttachPAT( (dvbpsi_pat_callback) &TS_DVBPSI_HandlePAT, p_input ); if( p_stream_data->p_pat_handle == NULL ) { msg_Err( p_input, "could not create PAT decoder" ); module_Unneed( p_input, p_demux->p_module ); free( p_input->p_demux_data ); return -1; }#endif /* We'll have to catch the PAT in order to continue * Then the input will catch the PMT and then the others ES * The PAT es is indepedent of any program. */ p_pat_es = input_AddES( p_input, NULL, 0x00, UNKNOWN_ES, NULL, sizeof( es_ts_data_t ) ); p_pat_es->i_fourcc = VLC_FOURCC( 'p', 'a', 't', ' ' ); p_demux_data = (es_ts_data_t *)p_pat_es->p_demux_data; p_demux_data->b_psi = 1; p_demux_data->i_psi_type = PSI_IS_PAT; p_demux_data->p_psi_section = malloc(sizeof(psi_section_t)); p_demux_data->p_psi_section->b_is_complete = 1; p_demux_data->i_continuity_counter = 0xFF; vlc_mutex_unlock( &p_input->stream.stream_lock ); return 0;}/***************************************************************************** * Deactivate: deinitialize TS structures *****************************************************************************/static void Deactivate( vlc_object_t * p_this ){ input_thread_t * p_input = (input_thread_t *)p_this; module_Unneed( p_input, p_input->p_demux_data->p_module ); free( p_input->p_demux_data );}/***************************************************************************** * Demux: reads and demuxes data packets ***************************************************************************** * Returns -1 in case of error, 0 in case of EOF, otherwise the number of * packets. *****************************************************************************/static int Demux( input_thread_t * p_input ){ demux_sys_t * p_demux = p_input->p_demux_data; int i_read_once = (p_input->i_mtu ? p_input->i_bufsize / TS_PACKET_SIZE : TS_READ_ONCE); int i; for( i = 0; i < i_read_once; i++ ) { data_packet_t * p_data; ssize_t i_result; i_result = p_demux->mpeg.pf_read_ts( p_input, &p_data ); if( i_result <= 0 ) { return i_result; } p_demux->mpeg.pf_demux_ts( p_input, p_data, (psi_callback_t) &PSI_CALLBACK ); } return i_read_once;}#if defined MODULE_NAME_IS_ts/* * PSI demultiplexing and decoding without libdvbpsi *//***************************************************************************** * DemuxPSI : makes up complete PSI data *****************************************************************************/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?