Commit efc1cee9 authored by Francois Cartegnie's avatar Francois Cartegnie

demux: ts: split the beast

parent fb98186a
...@@ -229,14 +229,27 @@ libplaylist_plugin_la_SOURCES = \ ...@@ -229,14 +229,27 @@ libplaylist_plugin_la_SOURCES = \
demux_LTLIBRARIES += libplaylist_plugin.la demux_LTLIBRARIES += libplaylist_plugin.la
libts_plugin_la_SOURCES = demux/mpeg/ts.c demux/mpeg/ts.h \ libts_plugin_la_SOURCES = demux/mpeg/ts.c demux/mpeg/ts.h \
demux/mpeg/ts_pid.h demux/mpeg/ts_pid.c \
demux/mpeg/ts_psi.h demux/mpeg/ts_psi.c \
demux/mpeg/ts_psi_eit.h demux/mpeg/ts_psi_eit.c \
demux/mpeg/ts_streams.h demux/mpeg/ts_streams.c \
demux/mpeg/ts_scte.h demux/mpeg/ts_scte.c \
demux/mpeg/sections.c demux/mpeg/sections.h \ demux/mpeg/sections.c demux/mpeg/sections.h \
demux/mpeg/mpeg4_iod.c demux/mpeg/mpeg4_iod.h \ demux/mpeg/mpeg4_iod.c demux/mpeg/mpeg4_iod.h \
demux/mpeg/ts_strings.h demux/mpeg/pes.h \ demux/mpeg/ts_sl.c demux/mpeg/ts_sl.h \
mux/mpeg/csa.c mux/mpeg/dvbpsi_compat.h \ demux/mpeg/ts_hotfixes.c demux/mpeg/ts_hotfixes.h \
mux/mpeg/streams.h mux/mpeg/tables.c mux/mpeg/tables.h \ demux/mpeg/ts_strings.h \
demux/mpeg/pes.h \
demux/mpeg/timestamps.h \
demux/dvb-text.h \
demux/opus.h \
mux/mpeg/csa.c \
mux/mpeg/dvbpsi_compat.h \
mux/mpeg/streams.h \
mux/mpeg/tables.c mux/mpeg/tables.h \
mux/mpeg/tsutil.c mux/mpeg/tsutil.h \ mux/mpeg/tsutil.c mux/mpeg/tsutil.h \
codec/scte18.h \ codec/scte18.h \
demux/dvb-text.h codec/opus_header.c demux/opus.h codec/opus_header.c
libts_plugin_la_CFLAGS = $(AM_CFLAGS) $(DVBPSI_CFLAGS) libts_plugin_la_CFLAGS = $(AM_CFLAGS) $(DVBPSI_CFLAGS)
libts_plugin_la_LIBADD = $(DVBPSI_LIBS) $(SOCKET_LIBS) libts_plugin_la_LIBADD = $(DVBPSI_LIBS) $(SOCKET_LIBS)
if HAVE_ARIBB24 if HAVE_ARIBB24
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
* along with this program; if not, write to the Free Software Foundation, * along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/ *****************************************************************************/
#ifndef VLC_MPEG4_IOD_H
#define VLC_MPEG4_IOD_H
#define ES_DESCRIPTOR_COUNT 255 #define ES_DESCRIPTOR_COUNT 255
typedef enum typedef enum
...@@ -61,7 +63,10 @@ typedef struct ...@@ -61,7 +63,10 @@ typedef struct
mtime_t i_pts; mtime_t i_pts;
} sl_header_data; } sl_header_data;
typedef struct typedef struct es_mpeg4_descriptor_t es_mpeg4_descriptor_t;
typedef struct decoder_config_descriptor_t decoder_config_descriptor_t;
struct decoder_config_descriptor_t
{ {
uint8_t i_objectTypeIndication; uint8_t i_objectTypeIndication;
uint8_t i_streamType; uint8_t i_streamType;
...@@ -69,9 +74,9 @@ typedef struct ...@@ -69,9 +74,9 @@ typedef struct
unsigned i_extra; unsigned i_extra;
uint8_t *p_extra; uint8_t *p_extra;
} decoder_config_descriptor_t; };
typedef struct struct es_mpeg4_descriptor_t
{ {
bool b_ok; bool b_ok;
uint16_t i_es_id; uint16_t i_es_id;
...@@ -81,7 +86,7 @@ typedef struct ...@@ -81,7 +86,7 @@ typedef struct
decoder_config_descriptor_t dec_descr; decoder_config_descriptor_t dec_descr;
sl_config_descriptor_t sl_descr; sl_config_descriptor_t sl_descr;
} es_mpeg4_descriptor_t; };
typedef struct typedef struct
{ {
...@@ -105,3 +110,4 @@ sl_header_data DecodeSLHeader( unsigned i_data, const uint8_t *p_data, ...@@ -105,3 +110,4 @@ sl_header_data DecodeSLHeader( unsigned i_data, const uint8_t *p_data,
const sl_config_descriptor_t *sl ); const sl_config_descriptor_t *sl );
void DecodeODCommand( vlc_object_t *p_object, od_descriptors_t *, void DecodeODCommand( vlc_object_t *p_object, od_descriptors_t *,
unsigned i_data, const uint8_t *p_data ); unsigned i_data, const uint8_t *p_data );
#endif
...@@ -17,12 +17,8 @@ ...@@ -17,12 +17,8 @@
* along with this program; if not, write to the Free Software Foundation, * along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/ *****************************************************************************/
#ifndef VLC_MPEG_PES_H
#define FROM_SCALE_NZ(x) ((x) * 100 / 9) #define VLC_MPEG_PES_H
#define TO_SCALE_NZ(x) ((x) * 9 / 100)
#define FROM_SCALE(x) (VLC_TS_0 + FROM_SCALE_NZ(x))
#define TO_SCALE(x) TO_SCALE_NZ((x) - VLC_TS_0)
static inline mtime_t ExtractPESTimestamp( const uint8_t *p_data ) static inline mtime_t ExtractPESTimestamp( const uint8_t *p_data )
{ {
...@@ -44,6 +40,7 @@ static inline mtime_t ExtractMPEG1PESTimestamp( const uint8_t *p_data ) ...@@ -44,6 +40,7 @@ static inline mtime_t ExtractMPEG1PESTimestamp( const uint8_t *p_data )
(mtime_t)(p_data[4] >> 3); (mtime_t)(p_data[4] >> 3);
} }
inline
static int ParsePESHeader( vlc_object_t *p_object, const uint8_t *p_header, size_t i_header, static int ParsePESHeader( vlc_object_t *p_object, const uint8_t *p_header, size_t i_header,
unsigned *pi_skip, mtime_t *pi_dts, mtime_t *pi_pts, unsigned *pi_skip, mtime_t *pi_dts, mtime_t *pi_pts,
uint8_t *pi_stream_id ) uint8_t *pi_stream_id )
...@@ -140,3 +137,5 @@ static int ParsePESHeader( vlc_object_t *p_object, const uint8_t *p_header, size ...@@ -140,3 +137,5 @@ static int ParsePESHeader( vlc_object_t *p_object, const uint8_t *p_header, size
*pi_skip = i_skip; *pi_skip = i_skip;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
#endif
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <assert.h> #include <assert.h>
#include <vlc_demux.h> #include <vlc_demux.h>
#include <vlc_memory.h> #include <vlc_memory.h>
#include "timestamps.h"
/* 256-0xC0 for normal stream, 256 for 0xbd stream, 256 for 0xfd stream, 8 for 0xa0 AOB stream */ /* 256-0xC0 for normal stream, 256 for 0xbd stream, 256 for 0xfd stream, 8 for 0xa0 AOB stream */
#define PS_TK_COUNT (256+256+256+8 - 0xc0) #define PS_TK_COUNT (256+256+256+8 - 0xc0)
......
...@@ -17,10 +17,16 @@ ...@@ -17,10 +17,16 @@
* along with this program; if not, write to the Free Software Foundation, * along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/ *****************************************************************************/
#include "sections.h" #ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_block.h> #include <vlc_block.h>
#include "ts_pid.h"
#include "sections.h"
typedef struct ts_sections_assembler_t typedef struct ts_sections_assembler_t
{ {
int8_t i_version; int8_t i_version;
......
...@@ -20,13 +20,6 @@ ...@@ -20,13 +20,6 @@
#ifndef TS_SECTIONS_H #ifndef TS_SECTIONS_H
#define TS_SECTIONS_H #define TS_SECTIONS_H
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "ts.h"
#include <vlc_common.h>
typedef void(* ts_section_callback_t)( demux_t *, ts_pid_t *, block_t * ); typedef void(* ts_section_callback_t)( demux_t *, ts_pid_t *, block_t * );
typedef struct ts_sections_processor_t ts_sections_processor_t; typedef struct ts_sections_processor_t ts_sections_processor_t;
......
/*****************************************************************************
* timestamps.h: MPEG TS/PS Timestamps helpers
*****************************************************************************
* Copyright (C) 2004-2016 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef VLC_MPEG_TIMESTAMPS_H
#define VLC_MPEG_TIMESTAMPS_H
#define FROM_SCALE_NZ(x) ((x) * 100 / 9)
#define TO_SCALE_NZ(x) ((x) * 9 / 100)
#define FROM_SCALE(x) (VLC_TS_0 + FROM_SCALE_NZ(x))
#define TO_SCALE(x) TO_SCALE_NZ((x) - VLC_TS_0)
static inline int64_t TimeStampWrapAround( int64_t i_first_pcr, int64_t i_time )
{
int64_t i_adjust = 0;
if( i_first_pcr > 0x0FFFFFFFF && i_time < 0x0FFFFFFFF )
i_adjust = 0x1FFFFFFFF;
return i_time + i_adjust;
}
#endif
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -20,6 +20,114 @@ ...@@ -20,6 +20,114 @@
#ifndef VLC_TS_H #ifndef VLC_TS_H
#define VLC_TS_H #define VLC_TS_H
typedef struct ts_pid_t ts_pid_t; #ifdef HAVE_ARIBB24
typedef struct arib_instance_t arib_instance_t;
#endif
typedef struct csa_t csa_t;
#define TS_USER_PMT_NUMBER (0)
typedef enum arib_modes_e
{
ARIBMODE_AUTO = -1,
ARIBMODE_DISABLED = 0,
ARIBMODE_ENABLED = 1
} arib_modes_e;
typedef struct
{
int i_service;
} vdr_info_t;
struct demux_sys_t
{
stream_t *stream;
bool b_canseek;
bool b_canfastseek;
vlc_mutex_t csa_lock;
/* TS packet size (188, 192, 204) */
unsigned i_packet_size;
/* Additional TS packet header size (BluRay TS packets have 4-byte header before sync byte) */
unsigned i_packet_header_size;
/* how many TS packet we read at once */
unsigned i_ts_read;
bool b_force_seek_per_percent;
bool b_atsc_eas;
struct
{
arib_modes_e e_mode;
#ifdef HAVE_ARIBB24
arib_instance_t *p_instance;
#endif
stream_t *b25stream;
} arib;
/* All pid */
ts_pid_list_t pids;
bool b_user_pmt;
int i_pmt_es;
bool b_es_all; /* If we need to return all es/programs */
enum
{
NO_ES, /* for preparse */
DELAY_ES,
CREATE_ES
} es_creation;
#define PREPARSING p_sys->es_creation == NO_ES
/* */
bool b_es_id_pid;
uint16_t i_next_extraid;
csa_t *csa;
int i_csa_pkt_size;
bool b_split_es;
bool b_trust_pcr;
/* */
bool b_access_control;
bool b_end_preparse;
/* */
bool b_dvb_meta;
int64_t i_tdt_delta;
int64_t i_dvb_start;
int64_t i_dvb_length;
bool b_broken_charset; /* True if broken encoding is used in EPG/SDT */
/* Selected programs */
DECL_ARRAY( int ) programs; /* List of selected/access-filtered programs */
bool b_default_selection; /* True if set by default to first pmt seen (to get data from filtered access) */
struct
{
mtime_t i_first_dts; /* first dts encountered for the stream */
int i_timesourcepid; /* which pid we saved the dts from */
enum { PAT_WAITING = 0, PAT_MISSING, PAT_FIXTRIED } status; /* set if we haven't seen PAT within MIN_PAT_INTERVAL */
} patfix;
vdr_info_t vdr;
/* */
bool b_start_record;
};
bool ProgramIsSelected( demux_sys_t *, uint16_t i_pgrm );
void UpdatePESFilters( demux_t *p_demux, bool b_all );
int ProbeStart( demux_t *p_demux, int i_program );
int ProbeEnd( demux_t *p_demux, int i_program );
void AddAndCreateES( demux_t *p_demux, ts_pid_t *pid, bool b_create_delayed );
int FindPCRCandidate( ts_pmt_t *p_pmt );
#endif #endif
This diff is collapsed.
/*****************************************************************************
* ts_hotfixes.h : MPEG PMT/PAT less streams fixups
*****************************************************************************
* Copyright (C) 2014-2016 - VideoLAN Authors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef VLC_TS_HOTFIXES_H
#define VLC_TS_HOTFIXES_H
#define MIN_PAT_INTERVAL CLOCK_FREQ // DVB is 500ms
void ProbePES( demux_t *p_demux, ts_pid_t *pid, const uint8_t *p_pesstart, size_t i_data, bool b_adaptfield );
void MissingPATPMTFixup( demux_t *p_demux );
#endif
/*****************************************************************************
* ts_pid.c: Transport Stream input module for VLC.
*****************************************************************************
* Copyright (C) 2004-2016 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_demux.h>
#include "ts_pid.h"
#include "ts_streams.h"
#include "ts.h"
#include <assert.h>
#define PID_ALLOC_CHUNK 16
void ts_pid_list_Init( ts_pid_list_t *p_list )
{
p_list->dummy.i_pid = 8191;
p_list->dummy.i_flags = FLAG_SEEN;
p_list->pp_all = NULL;
p_list->i_all = 0;
p_list->i_all_alloc = 0;
p_list->i_last_pid = 0;
p_list->p_last = NULL;
}
void ts_pid_list_Release( demux_t *p_demux, ts_pid_list_t *p_list )
{
for( int i = 0; i < p_list->i_all; i++ )
{
ts_pid_t *pid = p_list->pp_all[i];
#ifndef NDEBUG
if( pid->type != TYPE_FREE )
msg_Err( p_demux, "PID %d type %d not freed refcount %d", pid->i_pid, pid->type, pid->i_refcount );
#endif
free( pid );
}
free( p_list->pp_all );
}
ts_pid_t * ts_pid_Get( ts_pid_list_t *p_list, uint16_t i_pid )
{
switch( i_pid )
{
case 0:
return &p_list->pat;
case 0x1FFF:
return &p_list->dummy;
default:
if( p_list->i_last_pid == i_pid )
return p_list->p_last;
break;
}
for( int i=0; i < p_list->i_all; i++ )
{
if( p_list->pp_all[i]->i_pid == i_pid )
{
p_list->p_last = p_list->pp_all[i];
p_list->i_last_pid = i_pid;
return p_list->p_last;
}
}
if( p_list->i_all >= p_list->i_all_alloc )
{
ts_pid_t **p_realloc = realloc( p_list->pp_all,
(p_list->i_all_alloc + PID_ALLOC_CHUNK) * sizeof(ts_pid_t *) );
if( !p_realloc )
{
abort();
//return NULL;
}
p_list->pp_all = p_realloc;
p_list->i_all_alloc += PID_ALLOC_CHUNK;
}
ts_pid_t *p_pid = calloc( 1, sizeof(*p_pid) );
if( !p_pid )
{
abort();
//return NULL;
}
p_pid->i_pid = i_pid;
p_list->pp_all[p_list->i_all++] = p_pid;
p_list->p_last = p_pid;
p_list->i_last_pid = i_pid;
return p_pid;
}
ts_pid_t * ts_pid_Next( ts_pid_list_t *p_list, ts_pid_next_context_t *p_ctx )
{
if( likely(p_list->i_all && p_ctx) )
{
if( p_ctx->i_pos < p_list->i_all )
return p_list->pp_all[p_ctx->i_pos++];
}
return NULL;
}
static void PIDReset( ts_pid_t *pid )
{
assert(pid->i_refcount == 0);
pid->i_cc = 0xff;
pid->i_flags &= ~FLAG_SCRAMBLED;
pid->type = TYPE_FREE;
}
bool PIDSetup( demux_t *p_demux, ts_pid_type_t i_type, ts_pid_t *pid, ts_pid_t *p_parent )
{
if( pid == p_parent || pid->i_pid == 0x1FFF )
return false;
if( pid->i_refcount == 0 )
{
assert( pid->type == TYPE_FREE );
switch( i_type )
{
case TYPE_FREE: /* nonsense ?*/
PIDReset( pid );
return true;
case TYPE_PAT:
PIDReset( pid );
pid->u.p_pat = ts_pat_New( p_demux );
if( !pid->u.p_pat )
return false;
break;
case TYPE_PMT:
PIDReset( pid );
pid->u.p_pmt = ts_pmt_New( p_demux );
if( !pid->u.p_pmt )
return false;
break;
case TYPE_PES:
PIDReset( pid );
pid->u.p_pes = ts_pes_New( p_demux, p_parent->u.p_pmt );
if( !pid->u.p_pes )
return false;
break;
case TYPE_SDT:
case TYPE_TDT:
case TYPE_EIT:
PIDReset( pid );
pid->u.p_psi = ts_psi_New( p_demux );
if( !pid->u.p_psi )
return false;
break;
default:
assert(false);
break;
}
pid->i_refcount++;
pid->type = i_type;
}
else if( pid->type == i_type && pid->i_refcount < UINT16_MAX )
{
pid->i_refcount++;
}
else
{
if( pid->type != TYPE_FREE )
msg_Warn( p_demux, "Tried to redeclare pid %d with another type", pid->i_pid );
return false;
}
return true;
}
void PIDRelease( demux_t *p_demux, ts_pid_t *pid )
{
if( pid->i_refcount == 0 )
{
assert( pid->type == TYPE_FREE );
return;
}
else if( pid->i_refcount == 1 )
{
pid->i_refcount--;
}
else if( pid->i_refcount > 1 )
{
assert( pid->type != TYPE_FREE && pid->type != TYPE_PAT );
pid->i_refcount--;
}
if( pid->i_refcount == 0 )
{
switch( pid->type )
{
default:
case TYPE_FREE: /* nonsense ?*/
assert( pid->type != TYPE_FREE );
break;
case TYPE_PAT:
ts_pat_Del( p_demux, pid->u.p_pat );
pid->u.p_pat = NULL;
break;
case TYPE_PMT:
ts_pmt_Del( p_demux, pid->u.p_pmt );
pid->u.p_pmt = NULL;
break;
case TYPE_PES:
ts_pes_Del( p_demux, pid->u.p_pes );
pid->u.p_pes = NULL;
break;
case TYPE_SDT:
case TYPE_TDT:
case TYPE_EIT:
ts_psi_Del( p_demux, pid->u.p_psi );
pid->u.p_psi = NULL;
break;
}
SetPIDFilter( p_demux->p_sys, pid, false );
PIDReset( pid );
}
}
int UpdateHWFilter( demux_sys_t *p_sys, ts_pid_t *p_pid )
{
if( !p_sys->b_access_control )
return VLC_EGENERIC;
return stream_Control( p_sys->stream, STREAM_SET_PRIVATE_ID_STATE,
p_pid->i_pid, !!(p_pid->i_flags & FLAG_FILTERED) );
}
int SetPIDFilter( demux_sys_t *p_sys, ts_pid_t *p_pid, bool b_selected )
{
if( b_selected )
p_pid->i_flags |= FLAG_FILTERED;
else
p_pid->i_flags &= ~FLAG_FILTERED;
return UpdateHWFilter( p_sys, p_pid );
}
/*****************************************************************************
* ts_pid.h: Transport Stream input module for VLC.
*****************************************************************************
* Copyright (C) 2004-2016 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef VLC_TS_PID_H
#define VLC_TS_PID_H
typedef struct ts_pid_t ts_pid_t;
#define MIN_ES_PID 4 /* Should be 32.. broken muxers */
#define MAX_ES_PID 8190
#include "ts_streams.h"
typedef enum
{
TYPE_FREE = 0,
TYPE_PAT,
TYPE_PMT,
TYPE_PES,
TYPE_SDT,
TYPE_TDT,
TYPE_EIT,
} ts_pid_type_t;
enum
{
FLAGS_NONE = 0,
FLAG_SEEN = 1,
FLAG_SCRAMBLED = 2,
FLAG_FILTERED = 4
};
#define SEEN(x) ((x)->i_flags & FLAG_SEEN)
#define SCRAMBLED(x) ((x).i_flags & FLAG_SCRAMBLED)
struct ts_pid_t
{
uint16_t i_pid;
uint8_t i_flags;
uint8_t i_cc; /* countinuity counter */
uint8_t type;
uint16_t i_refcount;
/* */
union
{
ts_pat_t *p_pat;
ts_pmt_t *p_pmt;
ts_pes_t *p_pes;
ts_psi_t *p_psi;
} u;
struct
{
vlc_fourcc_t i_fourcc;
int i_type;
int i_pcr_count;
} probed;
};
typedef struct ts_pid_list_t
{
ts_pid_t pat;
ts_pid_t dummy;
/* all non commons ones, dynamically allocated */
ts_pid_t **pp_all;
int i_all;
int i_all_alloc;
/* last recently used */
uint16_t i_last_pid;
ts_pid_t *p_last;
} ts_pid_list_t;
/* opacified pid list */
void ts_pid_list_Init( ts_pid_list_t * );
void ts_pid_list_Release( demux_t *, ts_pid_list_t * );
/* creates missing pid on the fly */
ts_pid_t * ts_pid_Get( ts_pid_list_t *, uint16_t i_pid );
/* returns NULL on end. requires context */
typedef struct
{
int i_pos;
} ts_pid_next_context_t;
#define ts_pid_NextContextInitValue { 0 }
ts_pid_t * ts_pid_Next( ts_pid_list_t *, ts_pid_next_context_t * );
/* for legacy only: don't use and pass directly list reference */
#define GetPID(p_sys, i_pid) ts_pid_Get((&(p_sys)->pids), i_pid)
int UpdateHWFilter( demux_sys_t *, ts_pid_t * );
int SetPIDFilter( demux_sys_t *, ts_pid_t *, bool b_selected );
bool PIDSetup( demux_t *p_demux, ts_pid_type_t i_type, ts_pid_t *pid, ts_pid_t *p_parent );
void PIDRelease( demux_t *p_demux, ts_pid_t *pid );
#endif
This diff is collapsed.
/*****************************************************************************
* ts_psi.h: Transport Stream input module for VLC.
*****************************************************************************
* Copyright (C) 2004-2016 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef VLC_TS_PSI_H
#define VLC_TS_PSI_H
typedef enum
{
TS_PMT_REGISTRATION_NONE = 0,
TS_PMT_REGISTRATION_BLURAY,
TS_PMT_REGISTRATION_ATSC,
TS_PMT_REGISTRATION_ARIB,
} ts_pmt_registration_type_t;
void PATCallBack( void *, dvbpsi_pat_t * );
void PMTCallBack( void *, dvbpsi_pmt_t * );
int UserPmt( demux_t *p_demux, const char * );
#endif
This diff is collapsed.
/*****************************************************************************
* ts_psi_eit.h : TS demuxer EIT handling
*****************************************************************************
* Copyright (C) 2014-2016 - VideoLAN Authors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef VLC_TS_PSI_EIT_H
#define VLC_TS_PSI_EIT_H
bool AttachDvbpsiNewEITTableHandler( dvbpsi_t *p_handle, demux_t * p_demux );
#endif
/*****************************************************************************
* ts_scte.c: TS Demux SCTE section decoders/handlers
*****************************************************************************
* Copyright (C) 2004-2016 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_demux.h>
#include <vlc_es.h>
#include "ts_pid.h"
#include "ts_scte.h"
#include "ts_streams_private.h"
#include "timestamps.h"
#include <assert.h>
void SCTE18_Section_Handler( demux_t *p_demux, ts_pid_t *pid, block_t *p_content )
{
assert( pid->u.p_pes->p_es->fmt.i_codec == VLC_CODEC_SCTE_18 );
ts_pmt_t *p_pmt = pid->u.p_pes->p_es->p_program;
mtime_t i_date = TimeStampWrapAround( p_pmt->pcr.i_first, p_pmt->pcr.i_current );
int i_priority = scte18_get_EAS_priority( p_content->p_buffer, p_content->i_buffer );
msg_Dbg( p_demux, "Received EAS Alert with priority %d", i_priority );
/* We need to extract the truncated pts stored inside the payload */
ts_pes_es_t *p_es = pid->u.p_pes->p_es;
if( p_es->id )
{
if( i_priority == EAS_PRIORITY_HIGH || i_priority == EAS_PRIORITY_MAX )
es_out_Control( p_demux->out, ES_OUT_SET_ES_STATE, p_es->id, true );
p_content->i_dts = p_content->i_pts = FROM_SCALE( i_date );
es_out_Send( p_demux->out, p_es->id, p_content );
}
else
block_Release( p_content );
}
void SCTE27_Section_Handler( demux_t *p_demux, ts_pid_t *pid, block_t *p_content )
{
assert( pid->u.p_pes->p_es->fmt.i_codec == VLC_CODEC_SCTE_27 );
ts_pmt_t *p_pmt = pid->u.p_pes->p_es->p_program;
mtime_t i_date = p_pmt->pcr.i_current;
/* We need to extract the truncated pts stored inside the payload */
int i_index = 0;
size_t i_offset = 4;
if( p_content->p_buffer[3] & 0x40 )
{
i_index = ((p_content->p_buffer[7] & 0x0f) << 8) | /* segment number */
p_content->p_buffer[8];
i_offset += 5;
}
if( i_index == 0 && p_content->i_buffer > i_offset + 8 ) /* message body */
{
bool is_immediate = p_content->p_buffer[i_offset + 3] & 0x40;
if( !is_immediate )
{
mtime_t i_display_in = GetDWBE( &p_content->p_buffer[i_offset + 4] );
if( i_display_in < i_date )
i_date = i_display_in + (1ll << 32);
else
i_date = i_display_in;
}
}
p_content->i_dts = p_content->i_pts = VLC_TS_0 + i_date * 100 / 9;
//PCRFixHandle( p_demux, p_pmt, p_content );
if( pid->u.p_pes->p_es->id )
es_out_Send( p_demux->out, pid->u.p_pes->p_es->id, p_content );
else
block_Release( p_content );
}
/*****************************************************************************
* ts_scte.h: TS Demux SCTE section decoders/handlers
*****************************************************************************
* Copyright (C) 2004-2016 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef VLC_TS_SCTE_H
#define VLC_TS_SCTE_H
#include "../../codec/scte18.h"
void SCTE18_Section_Handler( demux_t *p_demux, ts_pid_t *pid, block_t *p_content );
void SCTE27_Section_Handler( demux_t *p_demux, ts_pid_t *pid, block_t *p_content );
#endif
/*****************************************************************************
* ts_sl.c : MPEG SL/FMC handling for TS demuxer
*****************************************************************************
* Copyright (C) 2014-2016 - VideoLAN Authors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_demux.h>
#include "ts_streams.h"
#include "ts_pid.h"
#include "ts_streams_private.h"
#include "ts.h"
#include "ts_sl.h"
const es_mpeg4_descriptor_t * GetMPEG4DescByEsId( const ts_pmt_t *pmt, uint16_t i_es_id )
{
for( int i = 0; i < ES_DESCRIPTOR_COUNT; i++ )
{
const es_mpeg4_descriptor_t *es_descr = &pmt->iod->es_descr[i];
if( es_descr->i_es_id == i_es_id && es_descr->b_ok )
return es_descr;
}
for( int i=0; i<pmt->od.objects.i_size; i++ )
{
const od_descriptor_t *od = pmt->od.objects.p_elems[i];
for( int j = 0; j < ES_DESCRIPTOR_COUNT; j++ )
{
const es_mpeg4_descriptor_t *es_descr = &od->es_descr[j];
if( es_descr->i_es_id == i_es_id && es_descr->b_ok )
return es_descr;
}
}
return NULL;
}
static ts_pes_es_t * GetPMTESBySLEsId( ts_pmt_t *pmt, uint16_t i_sl_es_id )
{
for( int i=0; i< pmt->e_streams.i_size; i++ )
{
ts_pes_es_t *p_es = pmt->e_streams.p_elems[i]->u.p_pes->p_es;
if( p_es->i_sl_es_id == i_sl_es_id )
return p_es;
}
return NULL;
}
bool SetupISO14496LogicalStream( demux_t *p_demux, const decoder_config_descriptor_t *dcd,
es_format_t *p_fmt )
{
msg_Dbg( p_demux, " - IOD objecttype: %"PRIx8" streamtype:%"PRIx8,
dcd->i_objectTypeIndication, dcd->i_streamType );
if( dcd->i_streamType == 0x04 ) /* VisualStream */
{
p_fmt->i_cat = VIDEO_ES;
switch( dcd->i_objectTypeIndication )
{
case 0x0B: /* mpeg4 sub */
p_fmt->i_cat = SPU_ES;
p_fmt->i_codec = VLC_CODEC_SUBT;
break;
case 0x20: /* mpeg4 */
p_fmt->i_codec = VLC_CODEC_MP4V;
break;
case 0x21: /* h264 */
p_fmt->i_codec = VLC_CODEC_H264;
break;
case 0x60:
case 0x61:
case 0x62:
case 0x63:
case 0x64:
case 0x65: /* mpeg2 */
p_fmt->i_codec = VLC_CODEC_MPGV;
break;
case 0x6a: /* mpeg1 */
p_fmt->i_codec = VLC_CODEC_MPGV;
break;
case 0x6c: /* mpeg1 */
p_fmt->i_codec = VLC_CODEC_JPEG;
break;
default:
p_fmt->i_cat = UNKNOWN_ES;
break;
}
}
else if( dcd->i_streamType == 0x05 ) /* AudioStream */
{
p_fmt->i_cat = AUDIO_ES;
switch( dcd->i_objectTypeIndication )
{
case 0x40: /* mpeg4 */
p_fmt->i_codec = VLC_CODEC_MP4A;
break;
case 0x66:
case 0x67:
case 0x68: /* mpeg2 aac */
p_fmt->i_codec = VLC_CODEC_MP4A;
break;
case 0x69: /* mpeg2 */
p_fmt->i_codec = VLC_CODEC_MPGA;
break;
case 0x6b: /* mpeg1 */
p_fmt->i_codec = VLC_CODEC_MPGA;
break;
default:
p_fmt->i_cat = UNKNOWN_ES;
break;
}
}
else
{
p_fmt->i_cat = UNKNOWN_ES;
}
if( p_fmt->i_cat != UNKNOWN_ES )
{
p_fmt->i_extra = __MIN(dcd->i_extra, INT32_MAX);
if( p_fmt->i_extra > 0 )
{
p_fmt->p_extra = malloc( p_fmt->i_extra );
if( p_fmt->p_extra )
memcpy( p_fmt->p_extra, dcd->p_extra, p_fmt->i_extra );
else
p_fmt->i_extra = 0;
}
}
return true;
}
/* Object stream SL in table sections */
void SLPackets_Section_Handler( demux_t *p_demux, ts_pid_t *pid, block_t *p_content )
{
ts_pmt_t *p_pmt = pid->u.p_pes->p_es->p_program;
const es_mpeg4_descriptor_t *p_mpeg4desc = GetMPEG4DescByEsId( p_pmt, pid->u.p_pes->p_es->i_sl_es_id );
if( p_mpeg4desc && p_mpeg4desc->dec_descr.i_objectTypeIndication == 0x01 &&
p_mpeg4desc->dec_descr.i_streamType == 0x01 /* Object */ )
{
const uint8_t *p_data = p_content->p_buffer;
int i_data = p_content->i_buffer;
od_descriptors_t *p_ods = &p_pmt->od;
sl_header_data header = DecodeSLHeader( i_data, p_data, &p_mpeg4desc->sl_descr );
DecodeODCommand( VLC_OBJECT(p_demux), p_ods, i_data - header.i_size, &p_data[header.i_size] );
bool b_changed = false;
for( int i=0; i<p_ods->objects.i_size; i++ )
{
od_descriptor_t *p_od = p_ods->objects.p_elems[i];
for( int j = 0; j < ES_DESCRIPTOR_COUNT && p_od->es_descr[j].b_ok; j++ )
{
p_mpeg4desc = &p_od->es_descr[j];
ts_pes_es_t *p_es = GetPMTESBySLEsId( p_pmt, p_mpeg4desc->i_es_id );
es_format_t fmt;
es_format_Init( &fmt, UNKNOWN_ES, 0 );
fmt.i_id = p_es->fmt.i_id;
fmt.i_group = p_es->fmt.i_group;
if ( p_mpeg4desc && p_mpeg4desc->b_ok && p_es &&
SetupISO14496LogicalStream( p_demux, &p_mpeg4desc->dec_descr, &fmt ) &&
!es_format_IsSimilar( &fmt, &p_es->fmt ) )
{
es_format_Clean( &p_es->fmt );
p_es->fmt = fmt;
if( p_es->id )
es_out_Del( p_demux->out, p_es->id );
p_es->fmt.b_packetized = true; /* Split by access unit, no sync code */
FREENULL( p_es->fmt.psz_description );
p_es->id = es_out_Add( p_demux->out, &p_es->fmt );
b_changed = true;
}
}
}
if( b_changed )
UpdatePESFilters( p_demux, p_demux->p_sys->b_es_all );
}
block_Release( p_content );
}
/*****************************************************************************
* ts_sl.h : MPEG SL/FMC handling for TS demuxer
*****************************************************************************
* Copyright (C) 2014-2016 - VideoLAN Authors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef VLC_TS_SL_H
#define VLC_TS_SL_H
typedef struct es_mpeg4_descriptor_t es_mpeg4_descriptor_t;
typedef struct decoder_config_descriptor_t decoder_config_descriptor_t;
const es_mpeg4_descriptor_t * GetMPEG4DescByEsId( const ts_pmt_t *pmt, uint16_t i_es_id );
void SLPackets_Section_Handler( demux_t *p_demux, ts_pid_t *pid, block_t *p_content );
bool SetupISO14496LogicalStream( demux_t *, const decoder_config_descriptor_t *,
es_format_t * );
#endif
/*****************************************************************************
* ts_streams.c: Transport Stream input module for VLC.
*****************************************************************************
* Copyright (C) 2004-2016 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include "ts_pid.h"
#include "ts_streams.h"
#include "ts_streams_private.h"
#ifndef _DVBPSI_DVBPSI_H_
#include <dvbpsi/dvbpsi.h>
#endif
#include <dvbpsi/demux.h>
#include <dvbpsi/descriptor.h>
#include <dvbpsi/pat.h>
#include <dvbpsi/pmt.h>
#include "../../mux/mpeg/dvbpsi_compat.h" /* dvbpsi_messages */
#include <vlc_demux.h>
#include <vlc_es.h>
#include <vlc_es_out.h>
#include "sections.h"
#include "ts_pid.h"
#include "ts.h"
static inline bool handle_Init( demux_t *p_demux, dvbpsi_t **handle )
{
*handle = dvbpsi_new( &dvbpsi_messages, DVBPSI_MSG_DEBUG );
if( !*handle )
return false;
(*handle)->p_sys = (void *) p_demux;
return true;
}
ts_pat_t *ts_pat_New( demux_t *p_demux )
{
ts_pat_t *pat = malloc( sizeof( ts_pat_t ) );
if( !pat )
return NULL;
if( !handle_Init( p_demux, &pat->handle ) )
{
free( pat );
return NULL;
}
pat->i_version = -1;
pat->i_ts_id = -1;
ARRAY_INIT( pat->programs );
return pat;
}
void ts_pat_Del( demux_t *p_demux, ts_pat_t *pat )
{
if( dvbpsi_decoder_present( pat->handle ) )
dvbpsi_pat_detach( pat->handle );
dvbpsi_delete( pat->handle );
for( int i=0; i<pat->programs.i_size; i++ )
PIDRelease( p_demux, pat->programs.p_elems[i] );
ARRAY_RESET( pat->programs );
free( pat );
}
ts_pmt_t *ts_pmt_New( demux_t *p_demux )
{
ts_pmt_t *pmt = malloc( sizeof( ts_pmt_t ) );
if( !pmt )
return NULL;
if( !handle_Init( p_demux, &pmt->handle ) )
{
free( pmt );
return NULL;
}
ARRAY_INIT( pmt->e_streams );
pmt->i_version = -1;
pmt->i_number = -1;
pmt->i_pid_pcr = 0x1FFF;
pmt->b_selected = false;
pmt->iod = NULL;
pmt->od.i_version = -1;
ARRAY_INIT( pmt->od.objects );
pmt->i_last_dts = -1;
pmt->p_mgt = NULL;
pmt->pcr.i_current = -1;
pmt->pcr.i_first = -1;
pmt->pcr.b_disable = false;
pmt->pcr.i_first_dts = VLC_TS_INVALID;
pmt->pcr.i_pcroffset = -1;
pmt->pcr.b_fix_done = false;
return pmt;
}
void ts_pmt_Del( demux_t *p_demux, ts_pmt_t *pmt )
{
if( dvbpsi_decoder_present( pmt->handle ) )
dvbpsi_pmt_detach( pmt->handle );
dvbpsi_delete( pmt->handle );
for( int i=0; i<pmt->e_streams.i_size; i++ )
PIDRelease( p_demux, pmt->e_streams.p_elems[i] );
ARRAY_RESET( pmt->e_streams );
if( pmt->p_mgt )
PIDRelease( p_demux, pmt->p_mgt );
if( pmt->iod )
ODFree( pmt->iod );
for( int i=0; i<pmt->od.objects.i_size; i++ )
ODFree( pmt->od.objects.p_elems[i] );
ARRAY_RESET( pmt->od.objects );
if( pmt->i_number > -1 )
es_out_Control( p_demux->out, ES_OUT_DEL_GROUP, pmt->i_number );
free( pmt );
}
ts_pes_es_t * ts_pes_es_New( ts_pmt_t *p_program )
{
ts_pes_es_t *p_es = malloc( sizeof(*p_es) );
if( p_es )
{
p_es->p_program = p_program;
p_es->id = NULL;
p_es->i_sl_es_id = 0;
p_es->p_extraes = NULL;
p_es->p_next = NULL;
p_es->b_interlaced = false;
es_format_Init( &p_es->fmt, UNKNOWN_ES, 0 );
p_es->fmt.i_group = p_program->i_number;
}
return p_es;
}
static void ts_pes_es_Clean( demux_t *p_demux, ts_pes_es_t *p_es )
{
if( p_es && p_es->id )
{
/* Ensure we don't wait for overlap hacks #14257 */
es_out_Control( p_demux->out, ES_OUT_SET_ES_STATE, p_es->id, false );
es_out_Del( p_demux->out, p_es->id );
p_demux->p_sys->i_pmt_es--;
}
es_format_Clean( &p_es->fmt );
}
void ts_pes_Add_es( ts_pes_t *p_pes, ts_pes_es_t *p_es, bool b_extra )
{
ts_pes_es_t **pp_es = (b_extra && p_pes->p_es) ? /* Ensure extra has main es */
&p_pes->p_es->p_extraes :
&p_pes->p_es;
if( likely(!*pp_es) )
{
*pp_es = p_es;
}
else
{
ts_pes_es_t *p_next = (*pp_es)->p_next;
(*pp_es)->p_next = p_es;
p_es->p_next = p_next;
}
}
ts_pes_es_t * ts_pes_Find_es( ts_pes_t *p_pes, const ts_pmt_t *p_pmt )
{
for( ts_pes_es_t *p_es = p_pes->p_es; p_es; p_es = p_es->p_next )
{
if( p_es->p_program == p_pmt )
return p_es;
}
return NULL;
}
ts_pes_es_t * ts_pes_Extract_es( ts_pes_t *p_pes, const ts_pmt_t *p_pmt )
{
ts_pes_es_t **pp_prev = &p_pes->p_es;
for( ts_pes_es_t *p_es = p_pes->p_es; p_es; p_es = p_es->p_next )
{
if( p_es->p_program == p_pmt )
{
*pp_prev = p_es->p_next;
p_es->p_next = NULL;
return p_es;
}
pp_prev = &p_es->p_next;
}
return NULL;
}
size_t ts_pes_Count_es( const ts_pes_es_t *p_es, bool b_active, const ts_pmt_t *p_pmt )
{
size_t i=0;
for( ; p_es; p_es = p_es->p_next )
{
i += ( b_active ) ? !!p_es->id : ( ( !p_pmt || p_pmt == p_es->p_program ) ? 1 : 0 );
i += ts_pes_Count_es( p_es->p_extraes, b_active, p_pmt );
}
return i;
}
static void ts_pes_ChainDelete_es( demux_t *p_demux, ts_pes_es_t *p_es )
{
while( p_es )
{
ts_pes_es_t *p_next = p_es->p_next;
ts_pes_ChainDelete_es( p_demux, p_es->p_extraes );
ts_pes_es_Clean( p_demux, p_es );
free( p_es );
p_es = p_next;
}
}
ts_pes_t *ts_pes_New( demux_t *p_demux, ts_pmt_t *p_program )
{
VLC_UNUSED(p_demux);
ts_pes_t *pes = malloc( sizeof( ts_pes_t ) );
if( !pes )
return NULL;
pes->p_es = ts_pes_es_New( p_program );
if( !pes->p_es )
{
free( pes );
return NULL;
}
pes->i_stream_type = 0;
pes->data_type = TS_ES_DATA_PES;
pes->i_data_size = 0;
pes->i_data_gathered = 0;
pes->p_data = NULL;
pes->pp_last = &pes->p_data;
pes->b_always_receive = false;
pes->p_sections_proc = NULL;
pes->p_prepcr_outqueue = NULL;
pes->sl.p_data = NULL;
pes->sl.pp_last = &pes->sl.p_data;
return pes;
}
void ts_pes_Del( demux_t *p_demux, ts_pes_t *pes )
{
ts_pes_ChainDelete_es( p_demux, pes->p_es );
if( pes->p_data )
block_ChainRelease( pes->p_data );
if( pes->p_sections_proc )
ts_sections_processor_ChainDelete( pes->p_sections_proc );
if( pes->p_prepcr_outqueue )
block_ChainRelease( pes->p_prepcr_outqueue );
free( pes );
}
ts_psi_t *ts_psi_New( demux_t *p_demux )
{
ts_psi_t *psi = malloc( sizeof( ts_psi_t ) );
if( !psi )
return NULL;
if( !handle_Init( p_demux, &psi->handle ) )
{
free( psi );
return NULL;
}
psi->i_version = -1;
return psi;
}
void ts_psi_Del( demux_t *p_demux, ts_psi_t *psi )
{
VLC_UNUSED(p_demux);
if( dvbpsi_decoder_present( psi->handle ) )
dvbpsi_DetachDemux( psi->handle );
dvbpsi_delete( psi->handle );
free( psi );
}
/*****************************************************************************
* ts_streams.h: Transport Stream input module for VLC.
*****************************************************************************
* Copyright (C) 2004-2016 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef VLC_TS_STREAMS_H
#define VLC_TS_STREAMS_H
typedef struct ts_pes_es_t ts_pes_es_t;
typedef struct ts_pat_t ts_pat_t;
typedef struct ts_pmt_t ts_pmt_t;
typedef struct ts_pes_t ts_pes_t;
typedef struct ts_psi_t ts_psi_t;
/* Structs */
ts_pat_t *ts_pat_New( demux_t * );
void ts_pat_Del( demux_t *, ts_pat_t * );
ts_pmt_t *ts_pmt_New( demux_t * );
void ts_pmt_Del( demux_t *, ts_pmt_t * );
ts_pes_es_t * ts_pes_es_New( ts_pmt_t * );
void ts_pes_Add_es( ts_pes_t *, ts_pes_es_t *, bool );
ts_pes_es_t * ts_pes_Extract_es( ts_pes_t *, const ts_pmt_t * );
ts_pes_es_t * ts_pes_Find_es( ts_pes_t *, const ts_pmt_t * );
size_t ts_pes_Count_es( const ts_pes_es_t *, bool, const ts_pmt_t * );
ts_pes_t *ts_pes_New( demux_t *, ts_pmt_t * );
void ts_pes_Del( demux_t *, ts_pes_t * );
ts_psi_t *ts_psi_New( demux_t * );
void ts_psi_Del( demux_t *, ts_psi_t * );
#endif
/*****************************************************************************
* ts_streams_private.h: Transport Stream input module for VLC.
*****************************************************************************
* Copyright (C) 2004-2016 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef VLC_TS_STREAMS_PRIVATE_H
#define VLC_TS_STREAMS_PRIVATE_H
typedef struct dvbpsi_s dvbpsi_t;
typedef struct ts_sections_processor_t ts_sections_processor_t;
#include "mpeg4_iod.h"
#include <vlc_common.h>
#include <vlc_es.h>
struct ts_pat_t
{
int i_version;
int i_ts_id;
dvbpsi_t *handle;
DECL_ARRAY(ts_pid_t *) programs;
};
struct ts_pmt_t
{
dvbpsi_t *handle;
int i_version;
int i_number;
int i_pid_pcr;
bool b_selected;
/* IOD stuff (mpeg4) */
od_descriptor_t *iod;
od_descriptors_t od;
DECL_ARRAY(ts_pid_t *) e_streams;
ts_pid_t *p_mgt;
struct
{
mtime_t i_current;
mtime_t i_first; // seen <> != -1
/* broken PCR handling */
mtime_t i_first_dts;
mtime_t i_pcroffset;
bool b_disable; /* ignore PCR field, use dts */
bool b_fix_done;
} pcr;
mtime_t i_last_dts;
};
struct ts_pes_es_t
{
ts_pmt_t *p_program;
es_format_t fmt;
es_out_id_t *id;
uint16_t i_sl_es_id;
ts_pes_es_t *p_extraes; /* Some private streams encapsulate several ES (eg. DVB subtitles) */
ts_pes_es_t *p_next; /* Next es on same pid from different pmt (shared pid) */
/* J2K stuff */
uint8_t b_interlaced;
};
typedef enum
{
TS_ES_DATA_PES,
TS_ES_DATA_TABLE_SECTION
} ts_es_data_type_t;
struct ts_pes_t
{
ts_pes_es_t *p_es;
uint8_t i_stream_type;
ts_es_data_type_t data_type;
int i_data_size;
int i_data_gathered;
block_t *p_data;
block_t **pp_last;
bool b_always_receive;
ts_sections_processor_t *p_sections_proc;
block_t * p_prepcr_outqueue;
/* SL AU */
struct
{
block_t *p_data;
block_t **pp_last;
} sl;
};
struct ts_psi_t
{
/* for special PAT/SDT case */
dvbpsi_t *handle; /* PAT/SDT/EIT */
int i_version;
};
struct ts_psip_t
{
dvbpsi_t *handle;
int i_version;
DECL_ARRAY(ts_pid_t *) eit;
};
#endif
...@@ -494,6 +494,7 @@ modules/demux/mpeg/mpgv.c ...@@ -494,6 +494,7 @@ modules/demux/mpeg/mpgv.c
modules/demux/mpeg/ps.c modules/demux/mpeg/ps.c
modules/demux/mpeg/ps.h modules/demux/mpeg/ps.h
modules/demux/mpeg/ts.c modules/demux/mpeg/ts.c
modules/demux/mpeg/ts_psi.c
modules/demux/nsc.c modules/demux/nsc.c
modules/demux/nsv.c modules/demux/nsv.c
modules/demux/nuv.c modules/demux/nuv.c
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment