Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,10 @@ Features:
- PES headers analyzer
- MPEG2 video and MPEG2/AC-3 audio ES header analyzer
- fatcaps DVB-H support

To Build:
autoreconf -fi
./configure
make
sudo make install

2 changes: 2 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ case "$host_os" in
build_mpe2sec=yes
;;
esac
build_mpe2sec=yes
AC_MSG_RESULT([$build_mpe2sec])

AM_CONDITIONAL([BUILD_MPE2SEC],[test x"$build_mpe2sec" = x"yes"])
Expand Down Expand Up @@ -77,6 +78,7 @@ tools/pesdata2ts/Makefile
tools/pesinfo/Makefile
tools/pesvideo2ts/Makefile
tools/sec2ts/Makefile
tools/sec2mpe/Makefile
tools/totsectionrestamp/Makefile
tools/ts2pes/Makefile
tools/ts2sec/Makefile
Expand Down
4 changes: 2 additions & 2 deletions tools/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
SUBDIRS = oc2sec sec2ts zpipe tsfilter tsloop tsmodder tsnullfiller \
SUBDIRS = oc2sec sec2ts sec2mpe zpipe tsfilter tsloop tsmodder tsnullfiller \
tsnullshaper tspcrmeasure tspidmapper esaudio2pes esaudioinfo \
esvideo2pes esvideoinfo pes2es pesaudio2ts pesvideo2ts pesinfo \
tsstamp ts2pes mpe2sec tscbrmuxer vbv tstdt i13942ts tsvbr2cbr \
tsstamp ts2pes ts2sec mpe2sec tscbrmuxer vbv tstdt i13942ts tsvbr2cbr \
tsfixcc tsudpreceive tsudpsend dsmcc-receive pesclock tspcrstamp \
tstcpreceive tstcpsend tstimeout tstimedwrite tsinputswitch \
tsdoubleoutput pes2txt tsoutputswitch totsectionrestamp tsccc \
Expand Down
3 changes: 3 additions & 0 deletions tools/sec2mpe/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
bin_PROGRAMS = sec2mpe

sec2mpe_SOURCES = sec2mpe.c
184 changes: 184 additions & 0 deletions tools/sec2mpe/sec2mpe.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include <errno.h>

#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/if.h>

#include <linux/if_tun.h>

/* pre 2.4.6 compatibility */
#define OTUNSETNOCSUM (('T'<< 8) | 200)
#define OTUNSETDEBUG (('T'<< 8) | 201)
#define OTUNSETIFF (('T'<< 8) | 202)
#define OTUNSETPERSIST (('T'<< 8) | 203)
#define OTUNSETOWNER (('T'<< 8) | 204)

static int persist = 0;
static char padding[184];
static char ip_device[IFNAMSIZ];
static char s[180];
static const char *Id = "$Id$";
const MPE_HEADER_LEN=12;
int tun_fd = -1;

// Opens up the tunnel!
int tun_open(char *dev)
{
// Stores all the interface data
struct ifreq ifr;
int fd;

// Open the tunnel, catch errors
if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
{
perror("open tun");
return -1;
}

memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TUN;

if (persist == 0)
{
ifr.ifr_flags |= IFF_NO_PI;
}

// Device name supplied as string
if (*dev)
{
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
}
else
{
fprintf(stderr, "device name not supplied\n");
return -1;
}

if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
if (errno == EBADFD)
{
/* Try old ioctl */
if (ioctl(fd, OTUNSETIFF, (void *) &ifr) < 0)
{
perror("new nor old ioctl worked\n");
close(fd);
return -1;
}
}
else
{
perror("other error\n");
close(fd);
return -1;
}
}

// Actual device name it got ??
strncpy(dev, ifr.ifr_name, IFNAMSIZ);
return fd;
}

// Tell the user how to use this
void usage(char **argv)
{
fprintf(stderr, "usage %s [-p] devname\n", argv[0]);
fprintf(stderr,
"Create a tun device, capture DVB/MPE DSM-CC sections on std in, output to IP tunnel.\n");
fprintf(stderr,
"-p don't create or configure the tun device\n");
fprintf(stderr,
"Code copied from project https://github.com/jcable/dvb-mpe-encode\n");
fprintf(stderr, "Example:\nts2sec 430 | %s dvb1\n", argv[0]);
exit(1);
}

// Close things up
void exit_program(int sig)
{
// Notify the user
fprintf(stderr, "stopping %s\n", ip_device);

// Close the tunnel if
sprintf(s, "ifdown %s", ip_device);
system(s);
close(tun_fd);
exit(0);
}

// Get things started, and process data
int main(int argc, char **argv)
{
int n = 1;

// Too many or too few number of args
if (argc < 2)
usage(argv);
if (argc > 3)
usage(argv);

// Catch flags
while(argv[n][0] == '-')
{
if (strcmp(argv[n], "-p") == 0)
persist = 1;
n++;
}

// Open the tunnel
strcpy(ip_device, argv[n]);
tun_fd = tun_open (ip_device);

// If error, notify user
if (tun_fd == -1)
{
usage(argv);
}

// Process signals from console
(void) signal(SIGINT, exit_program);
(void) signal(SIGQUIT, exit_program);

// Configure the tunnel device
if(persist==0)
{
sprintf(s, "ifup %s", ip_device);
system(s);
}

// Continuous loop to process received packets
while (1)
{
// First 3 bytes - ID information
// mpe 0x3e, table id, section length
unsigned char idbuf[3];
int n = read(0, idbuf, sizeof(idbuf));
int rem_len = ((idbuf[1] & 0xf) << 8) | idbuf[2]; // Includes the header, but not this id

// Header - 9 bytes - to the trash with this!
unsigned char headerbuf[9];
read(0, headerbuf, sizeof(headerbuf));
rem_len = rem_len - 9; // Read the header - decrement

// Rest of the packet
unsigned char databuf[4200];
unsigned int m = read(0, databuf, rem_len);

if (m != 0)
{
if (idbuf[0] != 0x3e)
{
fprintf(stderr, "Receive error! Not 0x3e (MPE)\n");
}

// Write the new packet to tunnel
write(tun_fd, databuf, m);
}
}
}
24 changes: 18 additions & 6 deletions tools/sec2ts/sec2ts.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,9 @@ int main(int argc, char *argv[])
if (pid < 8192) {
pid = htons(pid);
} else {
fprintf(stdout, "Usage: 'sec2ts pid [-s]', where pid is bounded from 1 to 8191 and as default is %d\n", DEFAULT_PID);
fprintf(stdout, "-s tells sec2ts to start sections on TS packet boundaries\n");
fprintf(stdout, "Sections come from stdin and ts packets will go out from stdout.\n");
fprintf(stderr, "Usage: 'sec2ts pid [-s]', where pid is bounded from 1 to 8191 and as default is %d\n", DEFAULT_PID);
fprintf(stderr, "-s tells sec2ts to start sections on TS packet boundaries\n");
fprintf(stderr, "Sections come from stdin and ts packets will go out from stdout.\n");
return 2;
}
} else {
Expand All @@ -147,6 +147,8 @@ int main(int argc, char *argv[])
ts_needtopad = 0;
ts_padded_did_not_output_next_header = 0;



/* Write the first TS valid packet header */
memcpy(ts_header + 1, &pid, 2); /* pid */
ts_header[1] |= 0x40; /* payload unit start indicator */
Expand All @@ -159,14 +161,21 @@ int main(int argc, char *argv[])

/* Start to process sections */
not_finished = 1;
section_next = get_section(&section_size_next, fd_in);

// printf("prepared to read a section");
// fflush(stdout);
//section_next = get_section(&section_size_next, fd_in);

while (not_finished) {

section_next = get_section(&section_size_next, fd_in);
//printf("read a section %d", section_next);
//fflush(stdout);

if (section_next != 0) {
memcpy(section_memory, section_next, SECTION_MAX_SIZE + 1);
section = section_memory;
section_size = section_size_next;
section_next = get_section(&section_size_next, fd_in);
} else {
section = 0;
section_size = 0;
Expand All @@ -179,6 +188,7 @@ int main(int argc, char *argv[])

if (ts_padded_did_not_output_next_header) {
fwrite(ts_header, 1, ts_header_size, fd_out);
fflush(fd_out);
ts_bytes = ts_header_size;
ts_padded_did_not_output_next_header = 0;
}
Expand All @@ -194,6 +204,7 @@ int main(int argc, char *argv[])
if (section_bytes < section_size) {
for (; ts_bytes < TS_PACKET_SIZE && section_bytes < section_size; ts_bytes++, section_bytes++)
fwrite(section + section_bytes, 1, 1, fd_out);
fflush(fd_out);
}

if (ts_bytes == TS_PACKET_SIZE) {
Expand All @@ -219,6 +230,7 @@ int main(int argc, char *argv[])
ts_header[3] = ts_continuity_counter | 0x10; /* continuity counter, no scrambling, only payload */
ts_continuity_counter = (ts_continuity_counter + 1) % 0x10; /* inc. continuity counter */
fwrite(ts_header, 1, ts_header_size, fd_out);
fflush(fd_out);
ts_bytes = ts_header_size;
}
}
Expand Down Expand Up @@ -250,7 +262,7 @@ int main(int argc, char *argv[])
ts_padded_did_not_output_next_header = 1;

}

fflush(fd_out);
}

return 0;
Expand Down
37 changes: 32 additions & 5 deletions tools/ts2sec/ts2sec.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,27 @@ int main(int argc, char *argv[])
unsigned short payload_pid;
unsigned char current_packet[TS_PACKET_SIZE];
int pusi = 0;
int pipe_input = 0;

/* Open ts file */
if (argc >= 3) {
fd_ts = open(argv[1], O_RDONLY);
// Pipe in from STDIN
if (*argv[1] != '-')
{
fd_ts = open(argv[1], O_RDONLY);
}
// File input
else
{
// STDIN
fd_ts = 0;
pipe_input = 1;
}
payload_pid = atoi(argv[2]);
} else {
fprintf(stderr, "Usage: 'ts2sec filename.ts payload_pid > sections'\n");
fprintf(stderr, "the tool manages corrupted ts, only complete sections are output\n");
fprintf(stderr, "replace filename.ts with '-' to receive input from STDIN\n");
return 2;
}
if (fd_ts < 0) {
Expand All @@ -128,14 +141,28 @@ int main(int argc, char *argv[])
if (payload_pid > MAX_PID-2) {
fprintf(stderr, "Invalid PID, range is [0..8190]\n");
}

/* Start to process the file */
byte_read = 1;
while(byte_read) {

/* read a ts packet */
byte_read = read(fd_ts, current_packet, TS_PACKET_SIZE);


// From pipe
if (pipe_input == 1) {
// No bytes received yet
byte_read = 0;

//Keep reading from STDIN until we get something
while (byte_read == 0) {
byte_read = read(fd_ts, current_packet, TS_PACKET_SIZE);
}
}
// File
else {
/* read a ts packet */
byte_read = read(fd_ts, current_packet, TS_PACKET_SIZE);
}

/* check packet pid */
memcpy(&pid, current_packet + 1, 2);
pid = ntohs(pid);
Expand Down