📄 ts.c
字号:
/***************************************************************************** * ts.c: Transport Stream input module for VLC. ***************************************************************************** * Copyright (C) 2004-2005 the VideoLAN team * $Id: e93ffa9f7bf03963b48a999684f8ab77f97cd6da $ * * Authors: Laurent Aimar <fenrir@via.ecp.fr> * Jean-Paul Saman <jpsaman #_at_# m2x.nl> * * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <vlc_plugin.h>#include <ctype.h>#include <vlc_access.h> /* DVB-specific things */#include <vlc_demux.h>#include <vlc_meta.h>#include <vlc_epg.h>#include <vlc_iso_lang.h>#include <vlc_network.h>#include <vlc_charset.h>#include "../mux/mpeg/csa.h"/* Include dvbpsi headers */#ifdef HAVE_DVBPSI_DR_H# include <dvbpsi/dvbpsi.h># include <dvbpsi/demux.h># include <dvbpsi/descriptor.h># include <dvbpsi/pat.h># include <dvbpsi/pmt.h># include <dvbpsi/sdt.h># include <dvbpsi/dr.h># include <dvbpsi/psi.h>#else# include "dvbpsi.h"# include "demux.h"# include "descriptor.h"# include "tables/pat.h"# include "tables/pmt.h"# include "tables/sdt.h"# include "descriptors/dr.h"# include "psi.h"#endif/* EIT support */#ifdef _DVBPSI_DR_4D_H_# define TS_USE_DVB_SI 1# ifdef HAVE_DVBPSI_DR_H# include <dvbpsi/eit.h># else# include "tables/eit.h"# endif#endif#ifdef HAVE_TIME_H# include <time.h>#endif#undef TS_DEBUG/* TODO: * - XXX: do not mark options message to be translated, they are too osbcure for now ... * - test it * - ... *//***************************************************************************** * Callback prototypes *****************************************************************************/static int ChangeKeyCallback ( vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void * );/***************************************************************************** * Module descriptor *****************************************************************************/static int Open ( vlc_object_t * );static void Close ( vlc_object_t * );/* TODO * - Rename "extra pmt" to "user pmt" * - Update extra pmt description * pmt_pid[:pmt_number][=pid_description[,pid_description]] * where pid_description could take 3 forms: * 1. pid:pcr (to force the pcr pid) * 2. pid:stream_type * 3. pid:type=fourcc where type=(video|audio|spu) */#define PMT_TEXT N_("Extra PMT")#define PMT_LONGTEXT N_( \ "Allows a user to specify an extra pmt (pmt_pid=pid:stream_type[,...])." )#define PID_TEXT N_("Set id of ES to PID")#define PID_LONGTEXT N_("Set the internal ID of each elementary stream" \ " handled by VLC to the same value as the PID in" \ " the TS stream, instead of 1, 2, 3, etc. Useful to" \ " do \'#duplicate{..., select=\"es=<pid>\"}\'.")#define TSOUT_TEXT N_("Fast udp streaming")#define TSOUT_LONGTEXT N_( \ "Sends TS to specific ip:port by udp (you must know what you are doing).")#define MTUOUT_TEXT N_("MTU for out mode")#define MTUOUT_LONGTEXT N_("MTU for out mode.")#define CSA_TEXT N_("CSA ck")#define CSA_LONGTEXT N_("Control word for the CSA encryption algorithm")#define CSA2_TEXT N_("Second CSA Key")#define CSA2_LONGTEXT N_("The even CSA encryption key. This must be a " \ "16 char string (8 hexadecimal bytes).")#define SILENT_TEXT N_("Silent mode")#define SILENT_LONGTEXT N_("Do not complain on encrypted PES.")#define CAPMT_SYSID_TEXT N_("CAPMT System ID")#define CAPMT_SYSID_LONGTEXT N_("Only forward descriptors from this SysID to the CAM.")#define CPKT_TEXT N_("Packet size in bytes to decrypt")#define CPKT_LONGTEXT N_("Specify the size of the TS packet to decrypt. " \ "The decryption routines subtract the TS-header from the value before " \ "decrypting. " )#define TSDUMP_TEXT N_("Filename of dump")#define TSDUMP_LONGTEXT N_("Specify a filename where to dump the TS in.")#define APPEND_TEXT N_("Append")#define APPEND_LONGTEXT N_( \ "If the file exists and this option is selected, the existing file " \ "will not be overwritten." )#define DUMPSIZE_TEXT N_("Dump buffer size")#define DUMPSIZE_LONGTEXT N_( \ "Tweak the buffer size for reading and writing an integer number of packets." \ "Specify the size of the buffer here and not the number of packets." )vlc_module_begin(); set_description( N_("MPEG Transport Stream demuxer") ); set_shortname ( "MPEG-TS" ); set_category( CAT_INPUT ); set_subcategory( SUBCAT_INPUT_DEMUX ); add_string( "ts-extra-pmt", NULL, NULL, PMT_TEXT, PMT_LONGTEXT, true ); add_bool( "ts-es-id-pid", 1, NULL, PID_TEXT, PID_LONGTEXT, true ); add_string( "ts-out", NULL, NULL, TSOUT_TEXT, TSOUT_LONGTEXT, true ); add_integer( "ts-out-mtu", 1400, NULL, MTUOUT_TEXT, MTUOUT_LONGTEXT, true ); add_string( "ts-csa-ck", NULL, NULL, CSA_TEXT, CSA_LONGTEXT, true ); add_string( "ts-csa2-ck", NULL, NULL, CSA_TEXT, CSA_LONGTEXT, true ); add_integer( "ts-csa-pkt", 188, NULL, CPKT_TEXT, CPKT_LONGTEXT, true ); add_bool( "ts-silent", 0, NULL, SILENT_TEXT, SILENT_LONGTEXT, true ); add_file( "ts-dump-file", NULL, NULL, TSDUMP_TEXT, TSDUMP_LONGTEXT, false ); change_unsafe(); add_bool( "ts-dump-append", 0, NULL, APPEND_TEXT, APPEND_LONGTEXT, false ); add_integer( "ts-dump-size", 16384, NULL, DUMPSIZE_TEXT, DUMPSIZE_LONGTEXT, true ); set_capability( "demux", 10 ); set_callbacks( Open, Close ); add_shortcut( "ts" );vlc_module_end();/***************************************************************************** * Local prototypes *****************************************************************************/typedef struct{ uint8_t i_objectTypeIndication; uint8_t i_streamType; bool b_upStream; uint32_t i_bufferSizeDB; uint32_t i_maxBitrate; uint32_t i_avgBitrate; int i_decoder_specific_info_len; uint8_t *p_decoder_specific_info;} decoder_config_descriptor_t;typedef struct{ bool b_useAccessUnitStartFlag; bool b_useAccessUnitEndFlag; bool b_useRandomAccessPointFlag; bool b_useRandomAccessUnitsOnlyFlag; bool b_usePaddingFlag; bool b_useTimeStampsFlags; bool b_useIdleFlag; bool b_durationFlag; uint32_t i_timeStampResolution; uint32_t i_OCRResolution; uint8_t i_timeStampLength; uint8_t i_OCRLength; uint8_t i_AU_Length; uint8_t i_instantBitrateLength; uint8_t i_degradationPriorityLength; uint8_t i_AU_seqNumLength; uint8_t i_packetSeqNumLength; uint32_t i_timeScale; uint16_t i_accessUnitDuration; uint16_t i_compositionUnitDuration; uint64_t i_startDecodingTimeStamp; uint64_t i_startCompositionTimeStamp;} sl_config_descriptor_t;typedef struct{ bool b_ok; uint16_t i_es_id; bool b_streamDependenceFlag; bool b_OCRStreamFlag; uint8_t i_streamPriority; char *psz_url; uint16_t i_dependOn_es_id; uint16_t i_OCR_es_id; decoder_config_descriptor_t dec_descr; sl_config_descriptor_t sl_descr;} es_mpeg4_descriptor_t;typedef struct{ uint8_t i_iod_label, i_iod_label_scope; /* IOD */ uint16_t i_od_id; char *psz_url; uint8_t i_ODProfileLevelIndication; uint8_t i_sceneProfileLevelIndication; uint8_t i_audioProfileLevelIndication; uint8_t i_visualProfileLevelIndication; uint8_t i_graphicsProfileLevelIndication; es_mpeg4_descriptor_t es_descr[255];} iod_descriptor_t;typedef struct{ dvbpsi_handle handle; int i_version; int i_number; int i_pid_pcr; int i_pid_pmt; /* IOD stuff (mpeg4) */ iod_descriptor_t *iod;} ts_prg_psi_t;typedef struct{ /* for special PAT/SDT case */ dvbpsi_handle handle; /* PAT/SDT/EIT */ int i_pat_version; int i_sdt_version; /* For PMT */ int i_prg; ts_prg_psi_t **prg;} ts_psi_t;typedef struct{ es_format_t fmt; es_out_id_t *id; int i_pes_size; int i_pes_gathered; block_t *p_pes; block_t **pp_last; es_mpeg4_descriptor_t *p_mpeg4desc; int b_gather;} ts_es_t;typedef struct{ int i_pid; bool b_seen; bool b_valid; int i_cc; /* countinuity counter */ /* PSI owner (ie PMT -> PAT, ES -> PMT */ ts_psi_t *p_owner; int i_owner_number; /* */ ts_psi_t *psi; ts_es_t *es; /* Some private streams encapsulate several ES (eg. DVB subtitles)*/ ts_es_t **extra_es; int i_extra_es;} ts_pid_t;struct demux_sys_t{ vlc_mutex_t csa_lock; /* TS packet size (188, 192, 204) */ int i_packet_size; /* how many TS packet we read at once */ int i_ts_read; /* All pid */ ts_pid_t pid[8192]; /* All PMT */ bool b_user_pmt; int i_pmt; ts_pid_t **pmt; /* */ bool b_es_id_pid; csa_t *csa; int i_csa_pkt_size; bool b_silent; bool b_udp_out; int fd; /* udp socket */ uint8_t *buffer; bool b_dvb_control; int i_dvb_program; int64_t i_dvb_start; int64_t i_dvb_length; vlc_list_t *p_programs_list; /* TS dump */ char *psz_file; /* file to dump data in */ FILE *p_file; /* filehandle */ uint64_t i_write; /* bytes written */ bool b_file_out; /* dump mode enabled */ /* */ bool b_meta;};static int Demux ( demux_t *p_demux );static int DemuxFile( demux_t *p_demux );static int Control( demux_t *p_demux, int i_query, va_list args );static void PIDInit ( ts_pid_t *pid, bool b_psi, ts_psi_t *p_owner );static void PIDClean( es_out_t *out, ts_pid_t *pid );static int PIDFillFormat( ts_pid_t *pid, int i_stream_type );static void PATCallBack( demux_t *, dvbpsi_pat_t * );static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt );#ifdef TS_USE_DVB_SIstatic void PSINewTableCallBack( demux_t *, dvbpsi_handle, uint8_t i_table_id, uint16_t i_extension );#endifstatic inline int PIDGet( block_t *p ){ return ( (p->p_buffer[1]&0x1f)<<8 )|p->p_buffer[2];}static bool GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk );static void PCRHandle( demux_t *p_demux, ts_pid_t *, block_t * );static iod_descriptor_t *IODNew( int , uint8_t * );static void IODFree( iod_descriptor_t * );#define TS_USER_PMT_NUMBER (0)static int UserPmt( demux_t *p_demux, const char * );#define TS_PACKET_SIZE_188 188#define TS_PACKET_SIZE_192 192#define TS_PACKET_SIZE_204 204#define TS_PACKET_SIZE_MAX 204#define TS_TOPFIELD_HEADER 1320/***************************************************************************** * Open
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -