Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
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
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
Show 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
,
NETID_LONGTEXT
,
VLC_TRUE
);
add_string
(
SOUT_CFG_PREFIX
"program-pmt"
,
NULL
,
NULL
,
PMTPROG_TEXT
,
PMTPROG_LONGTEXT
,
VLC_TRUE
);
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
)
{
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
=
val
.
i_int
;
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
);
}
}
...
@@ -1883,13 +2088,15 @@ static void GetPAT( sout_mux_t *p_mux,
...
@@ -1883,13 +2088,15 @@ static void GetPAT( sout_mux_t *p_mux,
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 */
for
(
i
=
0
;
i
<
p_sys
->
i_num_pmt
;
i
++
)
dvbpsi_PATAddProgram
(
&
pat
,
dvbpsi_PATAddProgram
(
&
pat
,
p_sys
->
i_pmt_program_number
,
/* i_number */
p_sys
->
i_pmt_program_number
[
i
],
p_sys
->
pmt
.
i_pid
);
/* i_pid */
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,20 +2124,72 @@ static void GetPMT( sout_mux_t *p_mux,
...
@@ -1917,20 +2124,72 @@ 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_stream
;
int
i
;
int
*
p_usepid
=
NULL
;
dvbpsi_InitPMT
(
&
pmt
,
if
(
p_sys
->
dvbpmt
==
NULL
)
p_sys
->
i_pmt_program_number
,
/* program number */
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
);
for
(
i
=
0
;
i
<
p_sys
->
i_num_pmt
;
i
++
)
{
dvbpsi_InitPMT
(
&
p_sys
->
dvbpmt
[
i
],
p_sys
->
i_pmt_program_number
[
i
],
/* program number */
p_sys
->
i_pmt_version_number
,
p_sys
->
i_pmt_version_number
,
1
,
/* b_current_next */
1
,
/* b_current_next */
p_sys
->
i_pcr_pid
);
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
)
{
{
uint8_t
iod
[
4096
];
uint8_t
iod
[
4096
];
...
@@ -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_es
=
dvbpsi_PMTAddES
(
&
pmt
,
p_stream
->
i_stream_type
,
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_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