Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
libdvbpsi
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
libdvbpsi
Commits
03214137
Commit
03214137
authored
Aug 03, 2005
by
Jean-Paul Saman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
example tool for checking an MPEG2-TS stream.
parent
b76dabd5
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
747 additions
and
1 deletion
+747
-1
examples/Makefile.am
examples/Makefile.am
+4
-1
examples/connect.c
examples/connect.c
+111
-0
examples/connect.h
examples/connect.h
+38
-0
examples/decode_mpeg.c
examples/decode_mpeg.c
+594
-0
No files found.
examples/Makefile.am
View file @
03214137
## Process this file with automake to produce Makefile.in
noinst_PROGRAMS
=
decode_pat decode_pmt decode_sdt
noinst_PROGRAMS
=
decode_pat decode_pmt decode_sdt
decode_mpeg
decode_pat_SOURCES
=
decode_pat.c
decode_pat_LDFLAGS
=
-L
../src
-ldvbpsi
...
...
@@ -11,3 +11,6 @@ decode_pmt_LDFLAGS = -L../src -ldvbpsi -lm
decode_sdt_SOURCES
=
decode_sdt.c
decode_sdt_LDFLAGS
=
-L
../src
-ldvbpsi
decode_mpeg_SOURCES
=
connect.c decode_mpeg.c
decode_mpeg_LDFLAGS
=
-L
../src
-ldvbpsi
-lm
examples/connect.c
0 → 100644
View file @
03214137
/*****************************************************************************
* connect.c: Routines for establishing a network connection.
*----------------------------------------------------------------------------
* Copyright (c) 2005 M2X
* $Id: connect.c 104 2005-03-21 13:38:56Z massiot $
*
* Authors: Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*----------------------------------------------------------------------------
*
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <net/if.h>
#if defined(WIN32)
# include <netinet/if_ether.h>
#endif
#include <netdb.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <arpa/inet.h>
int
create_tcp_connection
(
const
char
*
ipaddress
,
int
port
)
{
struct
sockaddr_in
addr_ctl
;
int
s_ctl
=
-
1
;
int
result
=
-
1
;
if
(
!
ipaddress
)
return
-
1
;
s_ctl
=
socket
(
PF_INET
,
SOCK_STREAM
,
0
);
if
(
s_ctl
<=
0
)
{
perror
(
"tcp socket error"
);
return
-
1
;
}
addr_ctl
.
sin_family
=
AF_INET
;
addr_ctl
.
sin_addr
.
s_addr
=
inet_addr
(
ipaddress
);
addr_ctl
.
sin_port
=
htons
(
port
);
result
=
connect
(
s_ctl
,
(
struct
sockaddr
*
)
&
addr_ctl
,
sizeof
(
addr_ctl
)
);
if
(
result
<
0
)
{
perror
(
"tcp connect error"
);
return
-
1
;
}
return
s_ctl
;
}
int
close_connection
(
int
socket_fd
)
{
int
result
=
0
;
result
=
shutdown
(
socket_fd
,
2
);
if
(
result
<
0
)
perror
(
"shutdown error"
);
return
result
;
}
int
create_udp_connection
(
const
char
*
ipaddress
,
int
port
)
{
struct
sockaddr_in
addr_ctl
;
int
s_ctl
=
-
1
;
int
result
=
-
1
;
if
(
!
ipaddress
)
return
-
1
;
s_ctl
=
socket
(
PF_INET
,
SOCK_DGRAM
,
IPPROTO_UDP
);
if
(
s_ctl
<=
0
)
{
perror
(
"udp socket error"
);
return
-
1
;
}
addr_ctl
.
sin_family
=
AF_INET
;
addr_ctl
.
sin_addr
.
s_addr
=
inet_addr
(
ipaddress
);
addr_ctl
.
sin_port
=
htons
(
port
);
result
=
bind
(
s_ctl
,
(
struct
sockaddr
*
)
&
addr_ctl
,
sizeof
(
addr_ctl
));
if
(
result
<
0
)
{
perror
(
"udp bind error"
);
return
-
1
;
}
return
s_ctl
;
}
examples/connect.h
0 → 100644
View file @
03214137
/*****************************************************************************
* connect.h: Routines for establishing a network connection.
*----------------------------------------------------------------------------
* Copyright (c) 2005 M2X
* $Id: connect.c 104 2005-03-21 13:38:56Z massiot $
*
* Authors: Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*----------------------------------------------------------------------------
*
*****************************************************************************/
#if !defined(_CONNECT_H_)
#define _CONNECT_H_ 1
int
create_tcp_connection
(
const
char
*
ipaddress
,
int
port
);
int
create_udp_connection
(
const
char
*
ipaddress
,
int
port
);
int
close_connection
(
int
socket_fd
);
#define close_tcp_connection close_connection
#define close_udp_connection close_connection
#endif
examples/decode_mpeg.c
0 → 100644
View file @
03214137
/*****************************************************************************
* decode_mpeg.c: MPEG decoder example
*----------------------------------------------------------------------------
* (c)2001-2005 VideoLAN
* $Id: decode_mpeg.c 104 2005-03-21 13:38:56Z massiot $
*
* Authors: Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
* Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*----------------------------------------------------------------------------
*
*****************************************************************************/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <math.h>
#include <getopt.h>
#include "connect.h"
#if defined(HAVE_INTTYPES_H)
#include <inttypes.h>
#elif defined(HAVE_STDINT_H)
#include <stdint.h>
#endif
/* The libdvbpsi distribution defines DVBPSI_DIST */
#ifdef DVBPSI_DIST
#include "../src/dvbpsi.h"
#include "../src/psi.h"
#include "../src/tables/pat.h"
#include "../src/descriptor.h"
#include "../src/tables/pmt.h"
#include "../src/descriptors/dr.h"
#else
#include <dvbpsi/dvbpsi.h>
#include <dvbpsi/psi.h>
#include <dvbpsi/pat.h>
#include <dvbpsi/descriptor.h>
#include <dvbpsi/pmt.h>
#include <dvbpsi/dr.h>
#endif
#define SYSTEM_CLOCK_DR 0x0B
#define MAX_BITRATE_DR 0x0E
#define STREAM_IDENTIFIER_DR 0x52
#define SUBTITLING_DR 0x59
/*****************************************************************************
* General typdefs
*****************************************************************************/
typedef
int
vlc_bool_t
;
#define VLC_FALSE 0
#define VLC_TRUE 1
typedef
int64_t
mtime_t
;
/*****************************************************************************
* TS stream structures
*----------------------------------------------------------------------------
* PAT pid=0
* - refers to N PMT's with pids known PAT
* PMT 0 pid=X stream_type
* PMT 1 pid=Y stream_type
* PMT 2 pid=Z stream_type
* - a PMT refers to N program_streams with pids known from PMT
* PID A type audio
* PID B type audio
* PID C type audio .. etc
* PID D type video
* PID E type teletext
*****************************************************************************/
typedef
struct
{
dvbpsi_handle
handle
;
int
i_pat_version
;
int
i_ts_id
;
}
ts_pat_t
;
typedef
struct
ts_pid_s
{
int
i_pid
;
vlc_bool_t
b_seen
;
int
i_cc
;
/* countinuity counter */
vlc_bool_t
b_pcr
;
/* this PID is the PCR_PID */
mtime_t
i_pcr
;
/* last know PCR value */
}
ts_pid_t
;
typedef
struct
ts_pmt_s
{
dvbpsi_handle
handle
;
int
i_number
;
/* i_number = 0 is actually a NIT */
int
i_pmt_version
;
ts_pid_t
*
pid_pmt
;
ts_pid_t
*
pid_pcr
;
}
ts_pmt_t
;
typedef
struct
{
ts_pat_t
pat
;
int
i_pmt
;
ts_pmt_t
pmt
;
ts_pid_t
pid
[
8192
];
}
ts_stream_t
;
/*****************************************************************************
* Local prototypes
*****************************************************************************/
void
DumpPMT
(
void
*
p_data
,
dvbpsi_pmt_t
*
p_pmt
);
/*****************************************************************************
* ReadPacket
*****************************************************************************/
int
ReadPacket
(
int
i_fd
,
uint8_t
*
p_dst
)
{
int
i
=
187
;
int
i_rc
=
1
;
p_dst
[
0
]
=
0
;
while
((
p_dst
[
0
]
!=
0x47
)
&&
(
i_rc
>
0
))
{
i_rc
=
read
(
i_fd
,
p_dst
,
1
);
}
while
((
i
!=
0
)
&&
(
i_rc
>
0
))
{
i_rc
=
read
(
i_fd
,
p_dst
+
188
-
i
,
i
);
if
(
i_rc
>=
0
)
i
-=
i_rc
;
}
return
(
i
==
0
)
?
1
:
0
;
}
int
ReadPacketFromSocket
(
int
i_socket
,
uint8_t
*
p_dst
,
size_t
i_size
)
{
int
i_rc
=
-
1
;
memset
(
p_dst
,
0
,
i_size
);
i_rc
=
read
(
i_socket
,
p_dst
,
i_size
);
return
(
i_rc
<=
i_size
)
?
1
:
0
;
}
/*****************************************************************************
* DumpPAT
*****************************************************************************/
void
DumpPAT
(
void
*
p_data
,
dvbpsi_pat_t
*
p_pat
)
{
dvbpsi_pat_program_t
*
p_program
=
p_pat
->
p_first_program
;
ts_stream_t
*
p_stream
=
(
ts_stream_t
*
)
p_data
;
p_stream
->
pat
.
i_pat_version
=
p_pat
->
i_version
;
p_stream
->
pat
.
i_ts_id
=
p_pat
->
i_ts_id
;
printf
(
"
\n
"
);
printf
(
"New PAT
\n
"
);
printf
(
" transport_stream_id : %d
\n
"
,
p_pat
->
i_ts_id
);
printf
(
" version_number : %d
\n
"
,
p_pat
->
i_version
);
printf
(
" | program_number @ [NIT|PMT]_PID
\n
"
);
while
(
p_program
)
{
p_stream
->
i_pmt
++
;
p_stream
->
pmt
.
i_number
=
p_program
->
i_number
;
p_stream
->
pmt
.
pid_pmt
=
&
p_stream
->
pid
[
p_program
->
i_pid
];
p_stream
->
pmt
.
pid_pmt
->
i_pid
=
p_program
->
i_pid
;
p_stream
->
pmt
.
handle
=
dvbpsi_AttachPMT
(
p_program
->
i_number
,
DumpPMT
,
p_stream
);
printf
(
" | %14d @ 0x%x (%d)
\n
"
,
p_program
->
i_number
,
p_program
->
i_pid
,
p_program
->
i_pid
);
p_program
=
p_program
->
p_next
;
}
printf
(
" active : %d
\n
"
,
p_pat
->
b_current_next
);
dvbpsi_DeletePAT
(
p_pat
);
}
/*****************************************************************************
* GetTypeName
*****************************************************************************/
char
*
GetTypeName
(
uint8_t
type
)
{
switch
(
type
)
{
case
0x00
:
return
"Reserved"
;
case
0x01
:
return
"ISO/IEC 11172 Video"
;
case
0x02
:
return
"ISO/IEC 13818-2 Video"
;
case
0x03
:
return
"ISO/IEC 11172 Audio"
;
case
0x04
:
return
"ISO/IEC 13818-3 Audio"
;
case
0x05
:
return
"ISO/IEC 13818-1 Private Section"
;
case
0x06
:
return
"ISO/IEC 13818-1 Private PES data packets"
;
case
0x07
:
return
"ISO/IEC 13522 MHEG"
;
case
0x08
:
return
"ISO/IEC 13818-1 Annex A DSM CC"
;
case
0x09
:
return
"H222.1"
;
case
0x0A
:
return
"ISO/IEC 13818-6 type A"
;
case
0x0B
:
return
"ISO/IEC 13818-6 type B"
;
case
0x0C
:
return
"ISO/IEC 13818-6 type C"
;
case
0x0D
:
return
"ISO/IEC 13818-6 type D"
;
case
0x0E
:
return
"ISO/IEC 13818-1 auxillary"
;
default:
if
(
type
<
0x80
)
return
"ISO/IEC 13818-1 reserved"
;
else
return
"User Private"
;
}
}
/*****************************************************************************
* DumpMaxBitrateDescriptor
*****************************************************************************/
void
DumpMaxBitrateDescriptor
(
dvbpsi_max_bitrate_dr_t
*
bitrate_descriptor
)
{
printf
(
"Bitrate: %d
\n
"
,
bitrate_descriptor
->
i_max_bitrate
);
}
/*****************************************************************************
* DumpSystemClockDescriptor
*****************************************************************************/
void
DumpSystemClockDescriptor
(
dvbpsi_system_clock_dr_t
*
p_clock_descriptor
)
{
printf
(
"External clock: %s, Accuracy: %E
\n
"
,
p_clock_descriptor
->
b_external_clock_ref
?
"Yes"
:
"No"
,
p_clock_descriptor
->
i_clock_accuracy_integer
*
pow
(
10
,
p_clock_descriptor
->
i_clock_accuracy_exponent
));
}
/*****************************************************************************
* DumpStreamIdentifierDescriptor
*****************************************************************************/
void
DumpStreamIdentifierDescriptor
(
dvbpsi_stream_identifier_dr_t
*
p_si_descriptor
)
{
printf
(
"Component tag: %d
\n
"
,
p_si_descriptor
->
i_component_tag
);
}
/*****************************************************************************
* DumpSubtitleDescriptor
*****************************************************************************/
void
DumpSubtitleDescriptor
(
dvbpsi_subtitling_dr_t
*
p_subtitle_descriptor
)
{
int
a
;
printf
(
"%d subtitles,
\n
"
,
p_subtitle_descriptor
->
i_subtitles_number
);
for
(
a
=
0
;
a
<
p_subtitle_descriptor
->
i_subtitles_number
;
++
a
)
{
printf
(
" | %d - lang: %c%c%c, type: %d, cpid: %d, apid: %d
\n
"
,
a
,
p_subtitle_descriptor
->
p_subtitle
[
a
].
i_iso6392_language_code
[
0
],
p_subtitle_descriptor
->
p_subtitle
[
a
].
i_iso6392_language_code
[
1
],
p_subtitle_descriptor
->
p_subtitle
[
a
].
i_iso6392_language_code
[
2
],
p_subtitle_descriptor
->
p_subtitle
[
a
].
i_subtitling_type
,
p_subtitle_descriptor
->
p_subtitle
[
a
].
i_composition_page_id
,
p_subtitle_descriptor
->
p_subtitle
[
a
].
i_ancillary_page_id
);
}
}
/*****************************************************************************
* DumpDescriptors
*****************************************************************************/
void
DumpDescriptors
(
const
char
*
str
,
dvbpsi_descriptor_t
*
p_descriptor
)
{
int
i
;
while
(
p_descriptor
)
{
printf
(
"%s 0x%02x : "
,
str
,
p_descriptor
->
i_tag
);
switch
(
p_descriptor
->
i_tag
)
{
case
SYSTEM_CLOCK_DR
:
DumpSystemClockDescriptor
(
dvbpsi_DecodeSystemClockDr
(
p_descriptor
));
break
;
case
MAX_BITRATE_DR
:
DumpMaxBitrateDescriptor
(
dvbpsi_DecodeMaxBitrateDr
(
p_descriptor
));
break
;
case
STREAM_IDENTIFIER_DR
:
DumpStreamIdentifierDescriptor
(
dvbpsi_DecodeStreamIdentifierDr
(
p_descriptor
));
break
;
case
SUBTITLING_DR
:
DumpSubtitleDescriptor
(
dvbpsi_DecodeSubtitlingDr
(
p_descriptor
));
break
;
default:
printf
(
"
\"
"
);
for
(
i
=
0
;
i
<
p_descriptor
->
i_length
;
i
++
)
printf
(
"%c"
,
p_descriptor
->
p_data
[
i
]);
printf
(
"
\"\n
"
);
}
p_descriptor
=
p_descriptor
->
p_next
;
}
}
/*****************************************************************************
* DumpPMT
*****************************************************************************/
void
DumpPMT
(
void
*
p_data
,
dvbpsi_pmt_t
*
p_pmt
)
{
dvbpsi_pmt_es_t
*
p_es
=
p_pmt
->
p_first_es
;
ts_stream_t
*
p_stream
=
(
ts_stream_t
*
)
p_data
;
p_stream
->
pmt
.
i_pmt_version
=
p_pmt
->
i_version
;
p_stream
->
pmt
.
pid_pcr
=
&
p_stream
->
pid
[
p_pmt
->
i_pcr_pid
];
p_stream
->
pid
[
p_pmt
->
i_pcr_pid
].
b_pcr
=
VLC_TRUE
;
printf
(
"
\n
"
);
printf
(
"New active PMT
\n
"
);
printf
(
" program_number : %d
\n
"
,
p_pmt
->
i_program_number
);
printf
(
" version_number : %d
\n
"
,
p_pmt
->
i_version
);
printf
(
" PCR_PID : 0x%x (%d)
\n
"
,
p_pmt
->
i_pcr_pid
,
p_pmt
->
i_pcr_pid
);
DumpDescriptors
(
" ]"
,
p_pmt
->
p_first_descriptor
);
printf
(
" | type @ elementary_PID
\n
"
);
while
(
p_es
)
{
printf
(
" | 0x%02x (%s) @ 0x%x (%d)
\n
"
,
p_es
->
i_type
,
GetTypeName
(
p_es
->
i_type
),
p_es
->
i_pid
,
p_es
->
i_pid
);
DumpDescriptors
(
" | ]"
,
p_es
->
p_first_descriptor
);
p_es
=
p_es
->
p_next
;
}
dvbpsi_DeletePMT
(
p_pmt
);
}
/*****************************************************************************
* usage
*****************************************************************************/
void
usage
(
char
*
name
)
{
printf
(
"Usage: %s [--file <filename>|--udp <ipaddress> --port <port> -mtu <mtu>|--help]
\n
"
,
name
);
printf
(
" %s [-f <filename>|-u <ipaddress> -p <port> -m <mtu>|-h]
\n
"
,
name
);
printf
(
"
\n
"
);
printf
(
" %s --help
\n
"
,
name
);
printf
(
" %s --file <filename>
\n
"
,
name
);
printf
(
" %s --udp <ipaddres> --port <port> --mtu <mtu>
\n
"
,
name
);
printf
(
"Arguments:
\n
"
);
printf
(
"file : read MPEG2-TS stream from file
\n
"
);
printf
(
"udp : read MPEG2-TS stream from network using UDP protocol
\n
"
);
printf
(
"port : read MPEG2-TS stream from this port number
\n
"
);
printf
(
"mtu : read MPEG2-TS stream from network using maximum transfer unit (mtu) = 1316
\n
"
);
printf
(
"help : print this help message
\n
"
);
}
/*****************************************************************************
* main
*****************************************************************************/
int
main
(
int
i_argc
,
char
*
pa_argv
[])
{
const
char
*
const
short_options
=
"hf:m:p:u:"
;
const
struct
option
long_options
[]
=
{
{
"help"
,
0
,
NULL
,
'h'
},
{
"file"
,
0
,
NULL
,
'f'
},
{
"mtu"
,
0
,
NULL
,
'm'
},
{
"port"
,
0
,
NULL
,
'p'
},
{
"udp"
,
0
,
NULL
,
'u'
},
{
NULL
,
0
,
NULL
,
0
}
};
int
next_option
=
0
;
int
i_fd
=
-
1
;
int
i_port
=
0
;
int
i_mtu
=
1316
;
/* (7 * 188) = 1316 < 1500 network MTU */
char
*
ipaddress
=
NULL
;
char
*
filename
=
NULL
;
uint8_t
*
p_data
=
NULL
;
ts_stream_t
*
p_stream
=
NULL
;
int
b_ok
;
/* parser commandline arguments */
do
{
next_option
=
getopt_long
(
i_argc
,
pa_argv
,
short_options
,
long_options
,
NULL
);
switch
(
next_option
)
{
case
'f'
:
filename
=
strdup
(
optarg
);
break
;
case
'h'
:
usage
(
pa_argv
[
0
]
);
goto
error
;
break
;
case
'm'
:
i_mtu
=
atoi
(
optarg
);
if
(
i_mtu
<
0
)
i_mtu
=
1316
;
break
;
case
'p'
:
i_port
=
atoi
(
optarg
);
break
;
case
'u'
:
ipaddress
=
strdup
(
optarg
);
break
;
case
-
1
:
break
;
default:
usage
(
pa_argv
[
0
]
);
goto
error
;
}
}
while
(
next_option
!=
-
1
);
/* initialize */
if
(
filename
)
{
i_fd
=
open
(
pa_argv
[
1
],
0
);
p_data
=
(
uint8_t
*
)
malloc
(
sizeof
(
uint8_t
)
*
188
);
if
(
!
p_data
)
goto
out_of_memory
;
}
if
(
ipaddress
)
{
i_fd
=
create_udp_connection
(
ipaddress
,
i_port
);
p_data
=
(
uint8_t
*
)
malloc
(
sizeof
(
uint8_t
)
*
i_mtu
);
if
(
!
p_data
)
goto
out_of_memory
;
}
p_stream
=
(
ts_stream_t
*
)
malloc
(
sizeof
(
ts_stream_t
)
);
if
(
!
p_stream
)
goto
out_of_memory
;
memset
(
p_stream
,
0
,
sizeof
(
ts_stream_t
)
);
/* Read first packet */
if
(
filename
)
b_ok
=
ReadPacket
(
i_fd
,
p_data
);
else
b_ok
=
ReadPacketFromSocket
(
i_fd
,
p_data
,
i_mtu
);
/* Enter infinite loop */
p_stream
->
pat
.
handle
=
dvbpsi_AttachPAT
(
DumpPAT
,
p_stream
);
while
(
b_ok
)
{
int
i
=
0
;
for
(
i
=
0
;
i
<
i_mtu
;
i
+=
188
)
{
uint8_t
*
p_tmp
=
&
p_data
[
i
];
uint16_t
i_pid
=
((
uint16_t
)(
p_tmp
[
1
]
&
0x1f
)
<<
8
)
+
p_tmp
[
2
];
int
i_cc
=
(
p_tmp
[
3
]
&
0x0f
);
int
i_old_cc
;
vlc_bool_t
b_adaptation
=
(
p_tmp
[
3
]
&
0x20
);
/* adaptation field */
vlc_bool_t
b_discontinuity_seen
=
VLC_FALSE
;
if
(
i_pid
==
0x0
)
dvbpsi_PushPacket
(
p_stream
->
pat
.
handle
,
p_tmp
);
else
if
(
p_stream
->
pmt
.
pid_pmt
&&
i_pid
==
p_stream
->
pmt
.
pid_pmt
->
i_pid
)
dvbpsi_PushPacket
(
p_stream
->
pmt
.
handle
,
p_tmp
);
/* Remember PID */
if
(
!
p_stream
->
pid
[
i_pid
].
b_seen
)
{
p_stream
->
pid
[
i_pid
].
b_seen
=
VLC_TRUE
;
i_old_cc
=
i_cc
;
p_stream
->
pid
[
i_pid
].
i_cc
=
i_cc
;
}
else
{
/* Check continuity counter */
int
i_diff
=
0
;
i_diff
=
i_cc
-
(
p_stream
->
pid
[
i_pid
].
i_cc
+
1
)
%
16
;
b_discontinuity_seen
=
(
i_diff
!=
0
);
/* Update CC */
i_old_cc
=
p_stream
->
pid
[
i_pid
].
i_cc
;
p_stream
->
pid
[
i_pid
].
i_cc
=
i_cc
;
}
/* Other adaptation field */
if
(
b_adaptation
)
{
vlc_bool_t
b_discontinuity_indicator
=
(
p_tmp
[
5
]
&
0x80
);
vlc_bool_t
b_random_access_indicator
=
(
p_tmp
[
5
]
&
0x40
);
vlc_bool_t
b_pcr
=
(
p_tmp
[
5
]
&
0x10
);
/* PCR flag */
if
(
b_discontinuity_indicator
)
printf
(
"Discontinuity indicator pid %d
\n
"
,
i_pid
);
if
(
b_random_access_indicator
)
printf
(
"Random access indicator
\n
"
);
/* Dump PCR */
if
(
b_pcr
&&
(
p_tmp
[
4
]
>=
7
)
)
{
mtime_t
i_pcr
;
/* 33 bits */
i_pcr
=
(
(
mtime_t
)
p_tmp
[
6
]
<<
25
)
|
(
(
mtime_t
)
p_tmp
[
7
]
<<
17
)
|
(
(
mtime_t
)
p_tmp
[
8
]
<<
9
)
|
(
(
mtime_t
)
p_tmp
[
9
]
<<
1
)
|
(
(
mtime_t
)
p_tmp
[
10
]
>>
7
);
//printf( "New PCR pid %d delta %ld\n", i_pid, i_pcr - p_stream->pid[i_pid].i_pcr );
p_stream
->
pid
[
i_pid
].
i_pcr
=
i_pcr
;
//printf( "New PCR pid %d value %ld \n", i_pid, i_pcr );
}
}
/* Handle discontinuities if they occured,
* according to ISO/IEC 13818-1: DIS pages 20-22 */
if
(
b_adaptation
)
{
vlc_bool_t
b_discontinuity_indicator
=
(
p_tmp
[
5
]
&
0x80
);
vlc_bool_t
b_pcr
=
(
p_tmp
[
5
]
&
0x10
);
/* pcr flag */
if
(
b_discontinuity_indicator
)
{
if
(
b_pcr
)
printf
(
"New PCR pid %d value %ld
\n
"
,
i_pid
,
p_stream
->
pid
[
i_pid
].
i_pcr
);
if
(
b_discontinuity_seen
)
{
/* cc discontinuity is expected */
printf
(
"Server signalled the continuity counter discontinuity
\n
"
);
/* Discontinuity has been handled */
b_discontinuity_seen
=
VLC_FALSE
;
}
}
}
if
(
b_discontinuity_seen
)
{
printf
(
"Continuity counter discontinuity (pid %d found %d expected %d)
\n
"
,
i_pid
,
p_stream
->
pid
[
i_pid
].
i_cc
,
i_old_cc
+
1
);
/* Discontinuity has been handled */
b_discontinuity_seen
=
VLC_FALSE
;
}
}
/* Read next packet */
if
(
filename
)
b_ok
=
ReadPacket
(
i_fd
,
p_data
);
else
b_ok
=
ReadPacketFromSocket
(
i_fd
,
p_data
,
i_mtu
);
}
dvbpsi_DetachPMT
(
p_stream
->
pmt
.
handle
);
dvbpsi_DetachPAT
(
p_stream
->
pat
.
handle
);
/* clean up */
if
(
filename
)
close
(
i_fd
);
else
close_connection
(
i_fd
);
if
(
p_data
)
free
(
p_data
);
if
(
filename
)
free
(
filename
);
if
(
ipaddress
)
free
(
ipaddress
);
/* free other stuff first ;-)*/
if
(
p_stream
)
free
(
p_stream
);
return
EXIT_SUCCESS
;
out_of_memory:
fprintf
(
stderr
,
"Out of memory
\n
"
);
error:
if
(
p_data
)
free
(
p_data
);
if
(
filename
)
free
(
filename
);
if
(
ipaddress
)
free
(
ipaddress
);
/* free other stuff first ;-)*/
if
(
p_stream
)
free
(
p_stream
);
return
EXIT_FAILURE
;
}
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