Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-1.1
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-1.1
Commits
b879e009
Commit
b879e009
authored
Sep 15, 2005
by
Christophe Massiot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* modules/mux/mpeg/ts.c: Support for SDT and multiple PMTs, original
patch courtesy of Wallace Wadge (thanks!).
parent
b5a2c69e
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
343 additions
and
45 deletions
+343
-45
THANKS
THANKS
+1
-0
configure.ac
configure.ac
+1
-1
modules/mux/mpeg/ts.c
modules/mux/mpeg/ts.c
+341
-44
No files found.
THANKS
View file @
b879e009
...
@@ -108,6 +108,7 @@ Vicente Jimenez Aguilar <vice at v1ce.net> - Spanish translation
...
@@ -108,6 +108,7 @@ Vicente Jimenez Aguilar <vice at v1ce.net> - Spanish translation
Vitalijus Slavinskas <Vitalijus.Slavinskas at stud.ktu dot lt> - nsv patches
Vitalijus Slavinskas <Vitalijus.Slavinskas at stud.ktu dot lt> - nsv patches
Vladimir Chernyshov - MMX motion optimizations
Vladimir Chernyshov - MMX motion optimizations
Wade Majors <guru at startrek.com> - BeOS icon integration, debugging and fixes
Wade Majors <guru at startrek.com> - BeOS icon integration, debugging and fixes
Wallace Wadge <wwadge at gmail.com> - multiple programs TS mux
Watanabe Go <go at dsl.gr.jp> - fix for non-ASCII filenames
Watanabe Go <go at dsl.gr.jp> - fix for non-ASCII filenames
Xavier Maillard <zedek at fxgsproject.org> - audio converters
Xavier Maillard <zedek at fxgsproject.org> - audio converters
Xavier Marchesini <xav at alarue.net> - Win32 fixes
Xavier Marchesini <xav at alarue.net> - Win32 fixes
...
...
configure.ac
View file @
b879e009
...
@@ -325,7 +325,7 @@ CPPFLAGS_save="${CPPFLAGS_save} -DSYS_`echo ${SYS} | sed -e 's/-.*//' | tr 'abcd
...
@@ -325,7 +325,7 @@ CPPFLAGS_save="${CPPFLAGS_save} -DSYS_`echo ${SYS} | sed -e 's/-.*//' | tr 'abcd
dnl Check for system libs needed
dnl Check for system libs needed
need_libc=false
need_libc=false
AC_CHECK_FUNCS(gettimeofday select strerror strtod strtol strtof strtoll strtoull strsep isatty vasprintf asprintf swab sigrelse getpwuid memalign posix_memalign if_nametoindex atoll getenv putenv setenv gmtime_r ctime_r localtime_r lrintf daemon scandir fork)
AC_CHECK_FUNCS(gettimeofday select strerror strtod strtol strtof strtoll strtoull strsep isatty vasprintf asprintf swab sigrelse getpwuid memalign posix_memalign if_nametoindex atoll getenv putenv setenv gmtime_r ctime_r localtime_r lrintf daemon scandir fork
bsearch
)
dnl Check for usual libc functions
dnl Check for usual libc functions
AC_CHECK_FUNCS(strdup strndup atof)
AC_CHECK_FUNCS(strdup strndup atof)
...
...
modules/mux/mpeg/ts.c
View file @
b879e009
...
@@ -7,6 +7,7 @@
...
@@ -7,6 +7,7 @@
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org>
* Eric Petit <titer@videolan.org>
* Jean-Paul Saman <jpsaman #_at_# m2x.nl>
* Jean-Paul Saman <jpsaman #_at_# m2x.nl>
* Wallace Wadge <wwadge #_at_# gmail.com>
*
*
* This program is free software; you can redistribute it and/or modify
* 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
* it under the terms of the GNU General Public License as published by
...
@@ -40,16 +41,20 @@
...
@@ -40,16 +41,20 @@
#ifdef HAVE_DVBPSI_DR_H
#ifdef HAVE_DVBPSI_DR_H
# include <dvbpsi/dvbpsi.h>
# include <dvbpsi/dvbpsi.h>
# include <dvbpsi/demux.h>
# include <dvbpsi/descriptor.h>
# include <dvbpsi/descriptor.h>
# include <dvbpsi/pat.h>
# include <dvbpsi/pat.h>
# include <dvbpsi/pmt.h>
# include <dvbpsi/pmt.h>
# include <dvbpsi/sdt.h>
# include <dvbpsi/dr.h>
# include <dvbpsi/dr.h>
# include <dvbpsi/psi.h>
# include <dvbpsi/psi.h>
#else
#else
# include "dvbpsi.h"
# include "dvbpsi.h"
# include "demux.h"
# include "descriptor.h"
# include "descriptor.h"
# include "tables/pat.h"
# include "tables/pat.h"
# include "tables/pmt.h"
# include "tables/pmt.h"
# include "tables/sdt.h"
# include "descriptors/dr.h"
# include "descriptors/dr.h"
# include "psi.h"
# include "psi.h"
#endif
#endif
...
@@ -86,8 +91,15 @@ static void Close ( vlc_object_t * );
...
@@ -86,8 +91,15 @@ static void Close ( vlc_object_t * );
#define PMTPID_LONGTEXT N_("Assigns a fixed PID to the PMT")
#define PMTPID_LONGTEXT N_("Assigns a fixed PID to the PMT")
#define TSID_TEXT N_("TS ID")
#define TSID_TEXT N_("TS ID")
#define TSID_LONGTEXT N_("Assigns a fixed Transport Stream ID.")
#define TSID_LONGTEXT N_("Assigns a fixed Transport Stream ID.")
#define PMTPROG_TEXT N_("PMT Program number")
#define NETID_TEXT N_("NET ID")
#define PMTPROG_LONGTEXT N_("Assigns a program number to the PMT.")
#define NETID_LONGTEXT N_("Assigns a fixed Network ID (for SDT table)")
#define PMTPROG_TEXT N_("PMT Program numbers (requires --sout-ts-es-id-pid)")
#define PMTPROG_LONGTEXT N_("Assigns a program number to each PMT")
#define MUXPMT_TEXT N_("Mux PMT (requires --sout-ts-es-id-pid)")
#define MUXPMT_LONGTEXT N_("Defines the pids to add to each pmt." )
#define SDTDESC_TEXT N_("SDT Descriptors (requires --sout-ts-es-id-pid)")
#define SDTDESC_LONGTEXT N_("Defines the descriptors of each SDT" )
#define PID_TEXT N_("Set PID to id of ES")
#define PID_TEXT N_("Set PID to id of ES")
#define PID_LONGTEXT N_("set PID to id of es")
#define PID_LONGTEXT N_("set PID to id of es")
...
@@ -137,6 +149,12 @@ static void Close ( vlc_object_t * );
...
@@ -137,6 +149,12 @@ static void Close ( vlc_object_t * );
"encrypting. " )
"encrypting. " )
#define SOUT_CFG_PREFIX "sout-ts-"
#define SOUT_CFG_PREFIX "sout-ts-"
#ifdef HAVE_BSEARCH
# define MAX_PMT 64
/* Maximum number of programs. FIXME: I just chose an arbitary number. Where is the maximum in the spec? */
#else
# define MAX_PMT 1
#endif
#define MAX_PMT_PID 64
/* Maximum pids in each pmt. FIXME: I just chose an arbitary number. Where is the maximum in the spec? */
vlc_module_begin
();
vlc_module_begin
();
set_description
(
_
(
"TS muxer (libdvbpsi)"
)
);
set_description
(
_
(
"TS muxer (libdvbpsi)"
)
);
...
@@ -156,10 +174,14 @@ vlc_module_begin();
...
@@ -156,10 +174,14 @@ vlc_module_begin();
PMTPID_LONGTEXT
,
VLC_TRUE
);
PMTPID_LONGTEXT
,
VLC_TRUE
);
add_integer
(
SOUT_CFG_PREFIX
"tsid"
,
0
,
NULL
,
TSID_TEXT
,
add_integer
(
SOUT_CFG_PREFIX
"tsid"
,
0
,
NULL
,
TSID_TEXT
,
TSID_LONGTEXT
,
VLC_TRUE
);
TSID_LONGTEXT
,
VLC_TRUE
);
add_integer
(
SOUT_CFG_PREFIX
"program-pmt"
,
1
,
NULL
,
PMTPROG_TEXT
,
add_integer
(
SOUT_CFG_PREFIX
"netid"
,
0
,
NULL
,
NETID_TEXT
,
PMTPROG_LONGTEXT
,
VLC_TRUE
);
NETID_LONGTEXT
,
VLC_TRUE
);
add_string
(
SOUT_CFG_PREFIX
"program-pmt"
,
NULL
,
NULL
,
PMTPROG_TEXT
,
PMTPROG_LONGTEXT
,
VLC_TRUE
);
add_bool
(
SOUT_CFG_PREFIX
"es-id-pid"
,
0
,
NULL
,
PID_TEXT
,
PID_LONGTEXT
,
add_bool
(
SOUT_CFG_PREFIX
"es-id-pid"
,
0
,
NULL
,
PID_TEXT
,
PID_LONGTEXT
,
VLC_TRUE
);
VLC_TRUE
);
add_string
(
SOUT_CFG_PREFIX
"muxpmt"
,
NULL
,
NULL
,
MUXPMT_TEXT
,
MUXPMT_LONGTEXT
,
VLC_TRUE
);
add_string
(
SOUT_CFG_PREFIX
"sdtdesc"
,
NULL
,
NULL
,
SDTDESC_TEXT
,
SDTDESC_LONGTEXT
,
VLC_TRUE
);
add_integer
(
SOUT_CFG_PREFIX
"shaping"
,
200
,
NULL
,
SHAPING_TEXT
,
add_integer
(
SOUT_CFG_PREFIX
"shaping"
,
200
,
NULL
,
SHAPING_TEXT
,
SHAPING_LONGTEXT
,
VLC_TRUE
);
SHAPING_LONGTEXT
,
VLC_TRUE
);
...
@@ -191,12 +213,25 @@ vlc_module_end();
...
@@ -191,12 +213,25 @@ vlc_module_end();
* Local data structures
* Local data structures
*****************************************************************************/
*****************************************************************************/
static
const
char
*
ppsz_sout_options
[]
=
{
static
const
char
*
ppsz_sout_options
[]
=
{
"pid-video"
,
"pid-audio"
,
"pid-spu"
,
"pid-pmt"
,
"tsid"
,
"
program-pmt
"
,
"pid-video"
,
"pid-audio"
,
"pid-spu"
,
"pid-pmt"
,
"tsid"
,
"
netid
"
,
"es-id-pid"
,
"shaping"
,
"pcr"
,
"bmin"
,
"bmax"
,
"use-key-frames"
,
"es-id-pid"
,
"shaping"
,
"pcr"
,
"bmin"
,
"bmax"
,
"use-key-frames"
,
"dts-delay"
,
"csa-ck"
,
"csa-pkt"
,
"crypt-audio"
,
"crypt-video"
,
"dts-delay"
,
"csa-ck"
,
"csa-pkt"
,
"crypt-audio"
,
"crypt-video"
,
"muxpmt"
,
"sdtdesc"
,
"program-pmt"
,
NULL
NULL
};
};
typedef
struct
pmt_map_t
/* Holds the mapping between the pmt-pid/pmt table */
{
int
i_pid
;
unsigned
long
i_prog
;
}
pmt_map_t
;
typedef
struct
sdt_desc_t
{
char
*
psz_provider
;
char
*
psz_service_name
;
/* name of program */
}
sdt_desc_t
;
typedef
struct
typedef
struct
{
{
int
i_depth
;
int
i_depth
;
...
@@ -302,22 +337,30 @@ struct sout_mux_sys_t
...
@@ -302,22 +337,30 @@ struct sout_mux_sys_t
int
i_video_bound
;
int
i_video_bound
;
vlc_bool_t
b_es_id_pid
;
vlc_bool_t
b_es_id_pid
;
vlc_bool_t
b_sdt
;
int
i_pid_video
;
int
i_pid_video
;
int
i_pid_audio
;
int
i_pid_audio
;
int
i_pid_spu
;
int
i_pid_spu
;
int
i_pid_free
;
/* first usable pid */
int
i_pid_free
;
/* first usable pid */
int
i_tsid
;
int
i_tsid
;
int
i_netid
;
int
i_num_pmt
;
int
i_pmtslots
;
int
i_pat_version_number
;
int
i_pat_version_number
;
ts_stream_t
pat
;
ts_stream_t
pat
;
int
i_pmt_version_number
;
int
i_pmt_version_number
;
ts_stream_t
pmt
;
/* Up to now only one program */
ts_stream_t
pmt
[
MAX_PMT
];
int
i_pmt_program_number
;
pmt_map_t
pmtmap
[
MAX_PMT_PID
];
int
i_pmt_program_number
[
MAX_PMT
];
sdt_desc_t
sdt_descriptors
[
MAX_PMT
];
int
i_mpeg4_streams
;
int
i_mpeg4_streams
;
int
i_null_continuity_counter
;
/* Needed ? */
int
i_null_continuity_counter
;
/* Needed ? */
ts_stream_t
sdt
;
dvbpsi_pmt_t
*
dvbpmt
;
/* for TS building */
/* for TS building */
int64_t
i_bitrate_min
;
int64_t
i_bitrate_min
;
...
@@ -364,6 +407,26 @@ static int AllocatePID( sout_mux_sys_t *p_sys, int i_cat )
...
@@ -364,6 +407,26 @@ static int AllocatePID( sout_mux_sys_t *p_sys, int i_cat )
return
i_pid
;
return
i_pid
;
}
}
static
int
pmtcompare
(
const
void
*
pa
,
const
void
*
pb
)
{
if
(
((
pmt_map_t
*
)
pa
)
->
i_pid
<
((
pmt_map_t
*
)
pb
)
->
i_pid
)
return
-
1
;
else
if
(
((
pmt_map_t
*
)
pa
)
->
i_pid
>
((
pmt_map_t
*
)
pb
)
->
i_pid
)
return
1
;
else
return
0
;
}
static
int
intcompare
(
const
void
*
pa
,
const
void
*
pb
)
{
if
(
*
(
int
*
)
pa
<
*
(
int
*
)
pb
)
return
-
1
;
else
if
(
*
(
int
*
)
pa
>
*
(
int
*
)
pb
)
return
1
;
else
return
0
;
}
/*****************************************************************************
/*****************************************************************************
* Local prototypes
* Local prototypes
*****************************************************************************/
*****************************************************************************/
...
@@ -393,13 +456,17 @@ static int Open( vlc_object_t *p_this )
...
@@ -393,13 +456,17 @@ static int Open( vlc_object_t *p_this )
sout_mux_t
*
p_mux
=
(
sout_mux_t
*
)
p_this
;
sout_mux_t
*
p_mux
=
(
sout_mux_t
*
)
p_this
;
sout_mux_sys_t
*
p_sys
=
NULL
;
sout_mux_sys_t
*
p_sys
=
NULL
;
vlc_value_t
val
;
vlc_value_t
val
;
int
i
;
msg_Dbg
(
p_mux
,
"Open"
);
sout_CfgParse
(
p_mux
,
SOUT_CFG_PREFIX
,
ppsz_sout_options
,
p_mux
->
p_cfg
);
sout_CfgParse
(
p_mux
,
SOUT_CFG_PREFIX
,
ppsz_sout_options
,
p_mux
->
p_cfg
);
p_sys
=
malloc
(
sizeof
(
sout_mux_sys_t
)
);
p_sys
=
malloc
(
sizeof
(
sout_mux_sys_t
)
);
if
(
!
p_sys
)
if
(
!
p_sys
)
return
VLC_ENOMEM
;
return
VLC_ENOMEM
;
p_sys
->
i_pmtslots
=
p_sys
->
b_sdt
=
0
;
p_sys
->
i_num_pmt
=
1
;
p_sys
->
dvbpmt
=
NULL
;
memset
(
&
p_sys
->
pmtmap
,
0
,
sizeof
(
p_sys
->
pmtmap
)
);
p_mux
->
pf_control
=
Control
;
p_mux
->
pf_control
=
Control
;
p_mux
->
pf_addstream
=
AddStream
;
p_mux
->
pf_addstream
=
AddStream
;
...
@@ -408,10 +475,68 @@ static int Open( vlc_object_t *p_this )
...
@@ -408,10 +475,68 @@ static int Open( vlc_object_t *p_this )
p_mux
->
p_sys
=
p_sys
;
p_mux
->
p_sys
=
p_sys
;
srand
(
(
uint32_t
)
mdate
()
);
srand
(
(
uint32_t
)
mdate
()
);
for
(
i
=
0
;
i
<
MAX_PMT
;
i
++
)
p_sys
->
sdt_descriptors
[
i
].
psz_service_name
=
p_sys
->
sdt_descriptors
[
i
].
psz_provider
=
NULL
;
memset
(
p_sys
->
sdt_descriptors
,
0
,
sizeof
(
sdt_desc_t
)
);
p_sys
->
i_audio_bound
=
0
;
p_sys
->
i_audio_bound
=
0
;
p_sys
->
i_video_bound
=
0
;
p_sys
->
i_video_bound
=
0
;
var_Get
(
p_mux
,
SOUT_CFG_PREFIX
"es-id-pid"
,
&
val
);
p_sys
->
b_es_id_pid
=
val
.
b_bool
;
var_Get
(
p_mux
,
SOUT_CFG_PREFIX
"muxpmt"
,
&
val
);
/*
fetch string of pmts. Here's a sample: --sout-ts-muxpmt="0x451,0x200,0x28a,0x240,,0x450,0x201,0x28b,0x241,,0x452,0x202,0x28c,0x242"
This would mean 0x451, 0x200, 0x28a, 0x240 would fall under one pmt (program), 0x450,0x201,0x28b,0x241 would fall under another
*/
if
(
val
.
psz_string
!=
NULL
&&
*
val
.
psz_string
)
{
char
*
psz_next
;
char
*
psz
=
val
.
psz_string
;
uint16_t
i_pid
;
psz_next
=
psz
;
while
(
psz
!=
NULL
)
{
i_pid
=
strtoul
(
psz
,
&
psz_next
,
0
);
if
(
strlen
(
psz_next
)
>
0
)
psz
=
&
psz_next
[
1
];
if
(
i_pid
==
0
)
{
p_sys
->
i_num_pmt
++
;
if
(
p_sys
->
i_num_pmt
>
MAX_PMT
)
{
msg_Err
(
p_mux
,
"Number of PMTs greater than compiled maximum (%d)"
,
MAX_PMT
);
p_sys
->
i_num_pmt
=
MAX_PMT
;
}
}
else
{
p_sys
->
pmtmap
[
p_sys
->
i_pmtslots
].
i_pid
=
i_pid
;
p_sys
->
pmtmap
[
p_sys
->
i_pmtslots
].
i_prog
=
p_sys
->
i_num_pmt
-
1
;
p_sys
->
i_pmtslots
++
;
if
(
p_sys
->
i_pmtslots
>
MAX_PMT_PID
)
{
msg_Err
(
p_mux
,
"Number of pids in PMT greater than compiled maximum (%d)"
,
MAX_PMT_PID
);
p_sys
->
i_pmtslots
=
MAX_PMT_PID
;
}
}
/* Now sort according to pids for fast search later on */
qsort
(
(
void
*
)
p_sys
->
pmtmap
,
p_sys
->
i_pmtslots
,
sizeof
(
pmt_map_t
),
&
pmtcompare
);
if
(
!*
psz_next
)
psz
=
NULL
;
}
}
if
(
val
.
psz_string
!=
NULL
)
free
(
val
.
psz_string
);
p_sys
->
i_pat_version_number
=
rand
()
%
32
;
p_sys
->
i_pat_version_number
=
rand
()
%
32
;
p_sys
->
pat
.
i_pid
=
0
;
p_sys
->
pat
.
i_pid
=
0
;
p_sys
->
pat
.
i_continuity_counter
=
0
;
p_sys
->
pat
.
i_continuity_counter
=
0
;
...
@@ -421,33 +546,103 @@ static int Open( vlc_object_t *p_this )
...
@@ -421,33 +546,103 @@ static int Open( vlc_object_t *p_this )
p_sys
->
i_tsid
=
val
.
i_int
;
p_sys
->
i_tsid
=
val
.
i_int
;
else
else
p_sys
->
i_tsid
=
rand
()
%
65536
;
p_sys
->
i_tsid
=
rand
()
%
65536
;
var_Get
(
p_mux
,
SOUT_CFG_PREFIX
"netid"
,
&
val
);
if
(
val
.
i_int
)
p_sys
->
i_netid
=
val
.
i_int
;
else
p_sys
->
i_netid
=
rand
()
%
65536
;
p_sys
->
i_pmt_version_number
=
rand
()
%
32
;
p_sys
->
i_pmt_version_number
=
rand
()
%
32
;
p_sys
->
pmt
.
i_continuity_counter
=
0
;
p_sys
->
sdt
.
i_continuity_counter
=
0
;
for
(
i
=
0
;
i
<
p_sys
->
i_num_pmt
;
i
++
)
p_sys
->
pmt
[
i
].
i_continuity_counter
=
0
;
var_Get
(
p_mux
,
SOUT_CFG_PREFIX
"sdtdesc"
,
&
val
);
p_sys
->
b_sdt
=
val
.
psz_string
&&
*
val
.
psz_string
?
VLC_TRUE
:
VLC_FALSE
;
/* Syntax is provider_sdt1,service_name_sdt1,provider_sdt2,service_name_sdt2... */
if
(
val
.
psz_string
!=
NULL
&&
*
val
.
psz_string
)
{
char
*
psz
=
val
.
psz_string
;
char
*
psz_sdttoken
=
psz
;
i
=
0
;
while
(
psz_sdttoken
!=
NULL
)
{
char
*
psz_end
=
strchr
(
psz_sdttoken
,
','
);
if
(
psz_end
!=
NULL
)
{
*
psz_end
++
=
'\0'
;
}
if
(
!
(
i
%
2
)
)
{
p_sys
->
sdt_descriptors
[
i
/
2
].
psz_provider
=
strdup
(
psz_sdttoken
);
}
else
{
p_sys
->
sdt_descriptors
[
i
/
2
].
psz_service_name
=
strdup
(
psz_sdttoken
);
}
i
++
;
psz_sdttoken
=
psz_end
;
}
}
if
(
val
.
psz_string
!=
NULL
)
free
(
val
.
psz_string
);
var_Get
(
p_mux
,
SOUT_CFG_PREFIX
"program-pmt"
,
&
val
);
var_Get
(
p_mux
,
SOUT_CFG_PREFIX
"program-pmt"
,
&
val
);
if
(
val
.
i_int
)
if
(
val
.
psz_string
&&
*
val
.
psz_string
)
{
{
p_sys
->
i_pmt_program_number
=
val
.
i_int
;
char
*
psz_next
;
char
*
psz
=
val
.
psz_string
;
uint16_t
i_pid
;
psz_next
=
psz
;
i
=
0
;
while
(
psz
!=
NULL
)
{
i_pid
=
strtoul
(
psz
,
&
psz_next
,
0
);
if
(
strlen
(
psz_next
)
>
0
)
psz
=
&
psz_next
[
1
];
else
psz
=
NULL
;
if
(
i_pid
==
0
)
{
if
(
i
>
MAX_PMT
)
msg_Err
(
p_mux
,
"Number of PMTs > maximum (%d)"
,
MAX_PMT
);
}
else
{
p_sys
->
i_pmt_program_number
[
i
]
=
i_pid
;
i
++
;
}
}
}
}
else
else
{
{
p_sys
->
i_pmt_program_number
=
1
;
/* Option not specified, use 1, 2, 3... */
for
(
i
=
0
;
i
<
p_sys
->
i_num_pmt
;
i
++
)
p_sys
->
i_pmt_program_number
[
i
]
=
i
+
1
;
}
}
if
(
val
.
psz_string
!=
NULL
)
free
(
val
.
psz_string
);
var_Get
(
p_mux
,
SOUT_CFG_PREFIX
"pid-pmt"
,
&
val
);
var_Get
(
p_mux
,
SOUT_CFG_PREFIX
"pid-pmt"
,
&
val
);
if
(
val
.
i_int
)
if
(
val
.
i_int
)
{
{
p_sys
->
pmt
.
i_pid
=
val
.
i_int
;
for
(
i
=
0
;
i
<
p_sys
->
i_num_pmt
;
i
++
)
p_sys
->
pmt
[
i
].
i_pid
=
val
.
i_int
+
i
;
/* Does this make any sense? */
}
}
else
else
{
{
p_sys
->
pmt
.
i_pid
=
0x42
;
for
(
i
=
0
;
i
<
p_sys
->
i_num_pmt
;
i
++
)
p_sys
->
pmt
[
i
].
i_pid
=
0x42
+
i
;
}
}
p_sys
->
i_pid_free
=
p_sys
->
pmt
.
i_pid
+
1
;
p_sys
->
i_pid_free
=
p_sys
->
pmt
[
p_sys
->
i_num_pmt
-
1
].
i_pid
+
1
;
var_Get
(
p_mux
,
SOUT_CFG_PREFIX
"es-id-pid"
,
&
val
);
p_sys
->
b_es_id_pid
=
val
.
b_bool
;
var_Get
(
p_mux
,
SOUT_CFG_PREFIX
"pid-video"
,
&
val
);
var_Get
(
p_mux
,
SOUT_CFG_PREFIX
"pid-video"
,
&
val
);
p_sys
->
i_pid_video
=
val
.
i_int
;
p_sys
->
i_pid_video
=
val
.
i_int
;
...
@@ -597,12 +792,22 @@ static void Close( vlc_object_t * p_this )
...
@@ -597,12 +792,22 @@ static void Close( vlc_object_t * p_this )
{
{
sout_mux_t
*
p_mux
=
(
sout_mux_t
*
)
p_this
;
sout_mux_t
*
p_mux
=
(
sout_mux_t
*
)
p_this
;
sout_mux_sys_t
*
p_sys
=
p_mux
->
p_sys
;
sout_mux_sys_t
*
p_sys
=
p_mux
->
p_sys
;
int
i
;
msg_Dbg
(
p_mux
,
"Close"
);
if
(
p_sys
->
csa
)
if
(
p_sys
->
csa
)
{
{
csa_Delete
(
p_sys
->
csa
);
csa_Delete
(
p_sys
->
csa
);
}
}
for
(
i
=
0
;
i
<
MAX_PMT
;
i
++
)
{
if
(
p_sys
->
sdt_descriptors
[
i
].
psz_service_name
!=
NULL
)
free
(
p_sys
->
sdt_descriptors
[
i
].
psz_service_name
);
if
(
p_sys
->
sdt_descriptors
[
i
].
psz_provider
!=
NULL
)
free
(
p_sys
->
sdt_descriptors
[
i
].
psz_provider
);
}
if
(
p_sys
->
dvbpmt
!=
NULL
)
/* safety */
free
(
p_sys
->
dvbpmt
);
free
(
p_sys
);
free
(
p_sys
);
}
}
...
@@ -1880,16 +2085,18 @@ static void GetPAT( sout_mux_t *p_mux,
...
@@ -1880,16 +2085,18 @@ static void GetPAT( sout_mux_t *p_mux,
sout_buffer_chain_t
*
c
)
sout_buffer_chain_t
*
c
)
{
{
sout_mux_sys_t
*
p_sys
=
p_mux
->
p_sys
;
sout_mux_sys_t
*
p_sys
=
p_mux
->
p_sys
;
block_t
*
p_pat
;
block_t
*
p_pat
;
dvbpsi_pat_t
pat
;
dvbpsi_pat_t
pat
;
dvbpsi_psi_section_t
*
p_section
;
dvbpsi_psi_section_t
*
p_section
;
int
i
;
dvbpsi_InitPAT
(
&
pat
,
p_sys
->
i_tsid
,
p_sys
->
i_pat_version_number
,
dvbpsi_InitPAT
(
&
pat
,
p_sys
->
i_tsid
,
p_sys
->
i_pat_version_number
,
1
);
/* b_current_next */
1
);
/* b_current_next */
/* add all program (only one) */
/* add all programs */
dvbpsi_PATAddProgram
(
&
pat
,
for
(
i
=
0
;
i
<
p_sys
->
i_num_pmt
;
i
++
)
p_sys
->
i_pmt_program_number
,
/* i_number */
dvbpsi_PATAddProgram
(
&
pat
,
p_sys
->
pmt
.
i_pid
);
/* i_pid */
p_sys
->
i_pmt_program_number
[
i
],
p_sys
->
pmt
[
i
].
i_pid
);
p_section
=
dvbpsi_GenPATSections
(
&
pat
,
p_section
=
dvbpsi_GenPATSections
(
&
pat
,
0
);
/* max program per section */
0
);
/* max program per section */
...
@@ -1917,19 +2124,71 @@ static void GetPMT( sout_mux_t *p_mux,
...
@@ -1917,19 +2124,71 @@ static void GetPMT( sout_mux_t *p_mux,
sout_buffer_chain_t
*
c
)
sout_buffer_chain_t
*
c
)
{
{
sout_mux_sys_t
*
p_sys
=
p_mux
->
p_sys
;
sout_mux_sys_t
*
p_sys
=
p_mux
->
p_sys
;
block_t
*
p_pmt
;
block_t
*
p_pmt
[
MAX_PMT
];
block_t
*
p_sdt
;
dvbpsi_
pmt_t
pm
t
;
dvbpsi_
sdt_t
sd
t
;
dvbpsi_pmt_es_t
*
p_es
;
dvbpsi_pmt_es_t
*
p_es
;
dvbpsi_psi_section_t
*
p_section
;
dvbpsi_psi_section_t
*
p_section
[
MAX_PMT
],
*
p_section2
;
dvbpsi_sdt_service_t
*
p_service
;
char
*
psz_sdt_desc
;
int
i_pidinput
;
int
i_stream
;
int
i
;
int
*
p_usepid
=
NULL
;
int
i_stream
;
if
(
p_sys
->
dvbpmt
==
NULL
)
p_sys
->
dvbpmt
=
malloc
(
p_sys
->
i_num_pmt
*
sizeof
(
dvbpsi_pmt_t
)
);
if
(
p_sys
->
b_sdt
)
dvbpsi_InitSDT
(
&
sdt
,
p_sys
->
i_tsid
,
1
,
1
,
p_sys
->
i_netid
);
dvbpsi_InitPMT
(
&
pmt
,
for
(
i
=
0
;
i
<
p_sys
->
i_num_pmt
;
i
++
)
p_sys
->
i_pmt_program_number
,
/* program number */
{
p_sys
->
i_pmt_version_number
,
dvbpsi_InitPMT
(
&
p_sys
->
dvbpmt
[
i
],
1
,
/* b_current_next */
p_sys
->
i_pmt_program_number
[
i
],
/* program number */
p_sys
->
i_pcr_pid
);
p_sys
->
i_pmt_version_number
,
1
,
/* b_current_next */
p_sys
->
i_pcr_pid
);
if
(
p_sys
->
b_sdt
)
{
p_service
=
dvbpsi_SDTAddService
(
&
sdt
,
p_sys
->
i_pmt_program_number
[
i
],
/* service id */
0
,
/* eit schedule */
0
,
/* eit present */
4
,
/* running status ("4=RUNNING") */
0
);
/* free ca */
#define psz_sdtprov p_sys->sdt_descriptors[i].psz_provider
#define psz_sdtserv p_sys->sdt_descriptors[i].psz_service_name
/* FIXME: Ineffecient malloc's & ugly code...... */
if
(
psz_sdtprov
!=
NULL
&&
psz_sdtserv
!=
NULL
)
{
psz_sdt_desc
=
malloc
(
3
+
strlen
(
psz_sdtprov
)
+
strlen
(
psz_sdtserv
)
);
psz_sdt_desc
[
0
]
=
0x01
;
/* digital television service */
/* service provider name length */
psz_sdt_desc
[
1
]
=
(
char
)
strlen
(
psz_sdtprov
);
memcpy
(
&
psz_sdt_desc
[
2
],
psz_sdtprov
,
strlen
(
psz_sdtprov
)
);
/* service name length */
psz_sdt_desc
[
2
+
strlen
(
psz_sdtprov
)
]
=
(
char
)
strlen
(
psz_sdtserv
);
memcpy
(
&
psz_sdt_desc
[
3
+
strlen
(
psz_sdtprov
)],
psz_sdtserv
,
strlen
(
psz_sdtserv
)
);
dvbpsi_SDTServiceAddDescriptor
(
p_service
,
0x48
,
3
+
strlen
(
psz_sdtprov
)
+
strlen
(
psz_sdtserv
),
psz_sdt_desc
);
free
(
psz_sdt_desc
);
}
#undef psz_sdtprov
#undef psz_sdtserv
}
}
if
(
p_sys
->
i_mpeg4_streams
>
0
)
if
(
p_sys
->
i_mpeg4_streams
>
0
)
{
{
...
@@ -2065,7 +2324,23 @@ static void GetPMT( sout_mux_t *p_mux,
...
@@ -2065,7 +2324,23 @@ static void GetPMT( sout_mux_t *p_mux,
bits_write
(
&
bits_fix_IOD
,
24
,
bits_write
(
&
bits_fix_IOD
,
24
,
GetDescriptorLength24b
(
bits
.
i_data
-
GetDescriptorLength24b
(
bits
.
i_data
-
bits_fix_IOD
.
i_data
-
3
)
);
bits_fix_IOD
.
i_data
-
3
)
);
dvbpsi_PMTAddDescriptor
(
&
pmt
,
0x1d
,
bits
.
i_data
,
bits
.
p_data
);
#ifdef HAVE_BSEARCH
i_pidinput
=
((
es_format_t
*
)(
p_mux
->
pp_inputs
[
i
]
->
p_fmt
))
->
i_id
;
p_usepid
=
bsearch
(
&
i_pidinput
,
p_sys
->
pmtmap
,
p_sys
->
i_pmtslots
,
sizeof
(
pmt_map_t
),
intcompare
);
p_usepid
=
bsearch
(
&
p_usepid
,
p_sys
->
pmtmap
,
p_sys
->
i_num_pmt
,
sizeof
(
pmt_map_t
),
pmtcompare
);
if
(
p_usepid
!=
NULL
)
dvbpsi_PMTAddDescriptor
(
&
p_sys
->
dvbpmt
[((
pmt_map_t
*
)
p_usepid
)
->
i_prog
],
0x1d
,
bits
.
i_data
,
bits
.
p_data
);
else
msg_Err
(
p_mux
,
"Received an unmapped PID"
);
#else
dvbpsi_PMTAddDescriptor
(
&
p_sys
->
dvbpmt
[
0
],
0x1d
,
bits
.
i_data
,
bits
.
p_data
);
#endif
}
}
for
(
i_stream
=
0
;
i_stream
<
p_mux
->
i_nb_inputs
;
i_stream
++
)
for
(
i_stream
=
0
;
i_stream
<
p_mux
->
i_nb_inputs
;
i_stream
++
)
...
@@ -2073,9 +2348,21 @@ static void GetPMT( sout_mux_t *p_mux,
...
@@ -2073,9 +2348,21 @@ static void GetPMT( sout_mux_t *p_mux,
ts_stream_t
*
p_stream
;
ts_stream_t
*
p_stream
;
p_stream
=
(
ts_stream_t
*
)
p_mux
->
pp_inputs
[
i_stream
]
->
p_sys
;
p_stream
=
(
ts_stream_t
*
)
p_mux
->
pp_inputs
[
i_stream
]
->
p_sys
;
i_pidinput
=
((
es_format_t
*
)(
p_mux
->
pp_inputs
[
i_stream
]
->
p_fmt
))
->
i_id
;
p_usepid
=
bsearch
(
&
i_pidinput
,
p_sys
->
pmtmap
,
p_sys
->
i_pmtslots
,
sizeof
(
pmt_map_t
),
intcompare
);
#ifdef HAVE_BSEARCH
if
(
p_usepid
!=
NULL
)
p_es
=
dvbpsi_PMTAddES
(
&
p_sys
->
dvbpmt
[((
pmt_map_t
*
)
p_usepid
)
->
i_prog
],
p_stream
->
i_stream_type
,
p_stream
->
i_pid
);
else
/* If there's an error somewhere, dump it to the first pmt */
#endif
p_es
=
dvbpsi_PMTAddES
(
&
p_sys
->
dvbpmt
[
0
],
p_stream
->
i_stream_type
,
p_stream
->
i_pid
);
p_es
=
dvbpsi_PMTAddES
(
&
pmt
,
p_stream
->
i_stream_type
,
p_stream
->
i_pid
);
if
(
p_stream
->
i_stream_id
==
0xfa
||
p_stream
->
i_stream_id
==
0xfb
)
if
(
p_stream
->
i_stream_id
==
0xfa
||
p_stream
->
i_stream_id
==
0xfb
)
{
{
uint8_t
es_id
[
2
];
uint8_t
es_id
[
2
];
...
@@ -2166,12 +2453,22 @@ static void GetPMT( sout_mux_t *p_mux,
...
@@ -2166,12 +2453,22 @@ static void GetPMT( sout_mux_t *p_mux,
}
}
}
}
p_section
=
dvbpsi_GenPMTSections
(
&
pmt
);
for
(
i
=
0
;
i
<
p_sys
->
i_num_pmt
;
i
++
)
{
p_pmt
=
WritePSISection
(
p_mux
->
p_sout
,
p_section
);
p_section
[
i
]
=
dvbpsi_GenPMTSections
(
&
p_sys
->
dvbpmt
[
i
]
);
p_pmt
[
i
]
=
WritePSISection
(
p_mux
->
p_sout
,
p_section
[
i
]
);
PEStoTS
(
p_mux
->
p_sout
,
c
,
p_pmt
,
&
p_sys
->
pmt
);
PEStoTS
(
p_mux
->
p_sout
,
c
,
p_pmt
[
i
],
&
p_sys
->
pmt
[
i
]
);
dvbpsi_DeletePSISections
(
p_section
[
i
]
);
dvbpsi_EmptyPMT
(
&
p_sys
->
dvbpmt
[
i
]
);
}
dvbpsi_DeletePSISections
(
p_section
);
if
(
p_sys
->
b_sdt
)
dvbpsi_EmptyPMT
(
&
pmt
);
{
p_section2
=
dvbpsi_GenSDTSections
(
&
sdt
);
p_sdt
=
WritePSISection
(
p_mux
->
p_sout
,
p_section2
);
p_sys
->
sdt
.
i_pid
=
0x11
;
PEStoTS
(
p_mux
->
p_sout
,
c
,
p_sdt
,
&
p_sys
->
sdt
);
dvbpsi_DeletePSISections
(
p_section2
);
dvbpsi_EmptySDT
(
&
sdt
);
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment