|
Packit |
0bbbb1 |
/*
|
|
Packit |
0bbbb1 |
* libiec61883 - Linux IEEE 1394 streaming media library.
|
|
Packit |
0bbbb1 |
* Copyright (C) 2004 Dan Dennedy
|
|
Packit |
0bbbb1 |
*
|
|
Packit |
0bbbb1 |
* This library is free software; you can redistribute it and/or
|
|
Packit |
0bbbb1 |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
0bbbb1 |
* License as published by the Free Software Foundation; either
|
|
Packit |
0bbbb1 |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
0bbbb1 |
*
|
|
Packit |
0bbbb1 |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
0bbbb1 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
0bbbb1 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
0bbbb1 |
* Lesser General Public License for more details.
|
|
Packit |
0bbbb1 |
*
|
|
Packit |
0bbbb1 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
0bbbb1 |
* License along with this library; if not, write to the Free Software
|
|
Packit |
0bbbb1 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
Packit |
0bbbb1 |
*/
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
0bbbb1 |
#include <config.h>
|
|
Packit |
0bbbb1 |
#endif
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
#include "../src/iec61883.h"
|
|
Packit |
0bbbb1 |
#include <stdio.h>
|
|
Packit |
0bbbb1 |
#include <sys/select.h>
|
|
Packit |
0bbbb1 |
#include <signal.h>
|
|
Packit |
0bbbb1 |
#include <string.h>
|
|
Packit |
0bbbb1 |
#include <stdlib.h>
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
static int g_done = 0;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
static int write_packet (unsigned char *data, int len, unsigned int dropped, void *callback_data)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
FILE *f = (FILE*) callback_data;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
if (dropped)
|
|
Packit |
0bbbb1 |
fprintf (stderr, "\a%d packets dropped!\n", dropped);
|
|
Packit |
0bbbb1 |
return (fwrite (data, len, 1, f) < 1) ? -1 : 0;
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
static int read_packet (unsigned char *data, int n_packets, unsigned int dropped, void *callback_data)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
FILE *f = (FILE*) callback_data;
|
|
Packit |
0bbbb1 |
return (fread (data, IEC61883_MPEG2_TSP_SIZE * n_packets, 1, f) < 1) ? -1 : 0;
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
static void sighandler (int sig)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
g_done = 1;
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
static void mpeg2_receive (raw1394handle_t handle, FILE *f, int channel)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
iec61883_mpeg2_t mpeg = iec61883_mpeg2_recv_init (handle, write_packet,
|
|
Packit |
0bbbb1 |
(void *)f );
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
if ( mpeg && iec61883_mpeg2_recv_start (mpeg, channel) == 0)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
int fd = raw1394_get_fd (handle);
|
|
Packit |
0bbbb1 |
struct timeval tv;
|
|
Packit |
0bbbb1 |
fd_set rfds;
|
|
Packit |
0bbbb1 |
int result = 0;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
signal (SIGINT, sighandler);
|
|
Packit |
0bbbb1 |
signal (SIGTERM, sighandler);
|
|
Packit |
0bbbb1 |
signal (SIGPIPE, sighandler);
|
|
Packit |
0bbbb1 |
fprintf (stderr, "Starting to receive\n");
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
do {
|
|
Packit |
0bbbb1 |
FD_ZERO (&rfds);
|
|
Packit |
0bbbb1 |
FD_SET (fd, &rfds);
|
|
Packit |
0bbbb1 |
tv.tv_sec = 0;
|
|
Packit |
0bbbb1 |
tv.tv_usec = 20000;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
if (select (fd + 1, &rfds, NULL, NULL, &tv) > 0)
|
|
Packit |
0bbbb1 |
result = raw1394_loop_iterate (handle);
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
} while (g_done == 0 && result == 0);
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
fprintf (stderr, "done.\n");
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
iec61883_mpeg2_close (mpeg);
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
static void mpeg2_transmit (raw1394handle_t handle, FILE *f, int pid, int channel)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
iec61883_mpeg2_t mpeg;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
mpeg = iec61883_mpeg2_xmit_init (handle, read_packet, (void *)f );
|
|
Packit |
0bbbb1 |
if ( mpeg && iec61883_mpeg2_xmit_start (mpeg, pid, channel) == 0)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
int fd = raw1394_get_fd (handle);
|
|
Packit |
0bbbb1 |
struct timeval tv;
|
|
Packit |
0bbbb1 |
fd_set rfds;
|
|
Packit |
0bbbb1 |
int result = 0;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
signal (SIGINT, sighandler);
|
|
Packit |
0bbbb1 |
signal (SIGTERM, sighandler);
|
|
Packit |
0bbbb1 |
signal (SIGPIPE, sighandler);
|
|
Packit |
0bbbb1 |
fprintf (stderr, "Starting to transmit\n");
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
do {
|
|
Packit |
0bbbb1 |
FD_ZERO (&rfds);
|
|
Packit |
0bbbb1 |
FD_SET (fd, &rfds);
|
|
Packit |
0bbbb1 |
tv.tv_sec = 0;
|
|
Packit |
0bbbb1 |
tv.tv_usec = 20000;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
if (select (fd + 1, &rfds, NULL, NULL, &tv) > 0)
|
|
Packit |
0bbbb1 |
result = raw1394_loop_iterate (handle);
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
} while (g_done == 0 && result == 0);
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
fprintf (stderr, "done.\n");
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
iec61883_mpeg2_close (mpeg);
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
int main (int argc, char *argv[])
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
raw1394handle_t handle = raw1394_new_handle_on_port (0);
|
|
Packit |
0bbbb1 |
nodeid_t node = 0xffc0;
|
|
Packit |
0bbbb1 |
FILE *f = NULL;
|
|
Packit |
0bbbb1 |
int is_transmit = 0;
|
|
Packit |
0bbbb1 |
int node_specified = 0;
|
|
Packit |
0bbbb1 |
int i;
|
|
Packit |
0bbbb1 |
int channel;
|
|
Packit |
0bbbb1 |
int bandwidth = -1;
|
|
Packit |
0bbbb1 |
int pid = -1;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
for (i = 1; i < argc; i++) {
|
|
Packit |
0bbbb1 |
if (strncmp (argv[i], "-h", 2) == 0 ||
|
|
Packit |
0bbbb1 |
strncmp (argv[i], "--h", 3) == 0)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
fprintf (stderr,
|
|
Packit |
0bbbb1 |
"usage: %s [[-r | -t] node-id] [-p pid] [- | file]\n"
|
|
Packit |
0bbbb1 |
" Use - to transmit MPEG2-TS from stdin, or\n"
|
|
Packit |
0bbbb1 |
" supply a filename to transmit from a MPEG2-TS file.\n"
|
|
Packit |
0bbbb1 |
" Otherwise, capture MPEG2-TS to stdout.\n"
|
|
Packit |
0bbbb1 |
" The default PID for transmit is -1 (use first found).\n",
|
|
Packit |
0bbbb1 |
argv[0]);
|
|
Packit |
0bbbb1 |
raw1394_destroy_handle (handle);
|
|
Packit |
0bbbb1 |
return 1;
|
|
Packit |
0bbbb1 |
} else if (strncmp (argv[i], "-t", 2) == 0) {
|
|
Packit |
0bbbb1 |
node |= atoi (argv[++i]);
|
|
Packit |
0bbbb1 |
is_transmit = 1;
|
|
Packit |
0bbbb1 |
node_specified = 1;
|
|
Packit |
0bbbb1 |
} else if (strncmp (argv[i], "-r", 2) == 0) {
|
|
Packit |
0bbbb1 |
node |= atoi (argv[++i]);
|
|
Packit |
0bbbb1 |
is_transmit = 0;
|
|
Packit |
0bbbb1 |
node_specified = 1;
|
|
Packit |
0bbbb1 |
} else if (strncmp (argv[i], "-p", 2) == 0) {
|
|
Packit |
0bbbb1 |
pid = atoi (argv[++i]);
|
|
Packit |
0bbbb1 |
is_transmit = 1;
|
|
Packit |
0bbbb1 |
} else if (strcmp (argv[i], "-") != 0) {
|
|
Packit |
0bbbb1 |
if (node_specified && !is_transmit)
|
|
Packit |
0bbbb1 |
f = fopen (argv[i], "wb");
|
|
Packit |
0bbbb1 |
else {
|
|
Packit |
0bbbb1 |
f = fopen (argv[i], "rb");
|
|
Packit |
0bbbb1 |
is_transmit = 1;
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
} else if (!node_specified) {
|
|
Packit |
0bbbb1 |
is_transmit = 1;
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
if (handle) {
|
|
Packit |
0bbbb1 |
int oplug = -1, iplug = -1;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
if (is_transmit) {
|
|
Packit |
0bbbb1 |
if (f == NULL)
|
|
Packit |
0bbbb1 |
f = stdin;
|
|
Packit |
0bbbb1 |
if (node_specified) {
|
|
Packit |
0bbbb1 |
channel = iec61883_cmp_connect (handle,
|
|
Packit |
0bbbb1 |
raw1394_get_local_id (handle), &oplug, node, &iplug,
|
|
Packit |
0bbbb1 |
&bandwidth);
|
|
Packit |
0bbbb1 |
if (channel > -1) {
|
|
Packit |
0bbbb1 |
mpeg2_transmit (handle, f, pid, channel);
|
|
Packit |
0bbbb1 |
iec61883_cmp_disconnect (handle,
|
|
Packit |
0bbbb1 |
raw1394_get_local_id (handle), oplug, node, iplug,
|
|
Packit |
0bbbb1 |
channel, bandwidth);
|
|
Packit |
0bbbb1 |
} else {
|
|
Packit |
0bbbb1 |
fprintf (stderr, "Connect failed, reverting to broadcast channel 63.\n");
|
|
Packit |
0bbbb1 |
mpeg2_transmit (handle, f, pid, 63);
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
} else {
|
|
Packit |
0bbbb1 |
mpeg2_transmit (handle, f, pid, 63);
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
if (f != stdin)
|
|
Packit |
0bbbb1 |
fclose (f);
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
} else {
|
|
Packit |
0bbbb1 |
if (f == NULL)
|
|
Packit |
0bbbb1 |
f = stdout;
|
|
Packit |
0bbbb1 |
if (node_specified) {
|
|
Packit |
0bbbb1 |
channel = iec61883_cmp_connect (handle, node, &oplug,
|
|
Packit |
0bbbb1 |
raw1394_get_local_id (handle), &iplug, &bandwidth);
|
|
Packit |
0bbbb1 |
if (channel > -1) {
|
|
Packit |
0bbbb1 |
mpeg2_receive (handle, f, channel);
|
|
Packit |
0bbbb1 |
iec61883_cmp_disconnect (handle, node, oplug,
|
|
Packit |
0bbbb1 |
raw1394_get_local_id (handle), iplug,
|
|
Packit |
0bbbb1 |
channel, bandwidth);
|
|
Packit |
0bbbb1 |
} else {
|
|
Packit |
0bbbb1 |
fprintf (stderr, "Connect failed, reverting to broadcast channel 63.\n");
|
|
Packit |
0bbbb1 |
mpeg2_receive (handle, f, 63);
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
} else {
|
|
Packit |
0bbbb1 |
mpeg2_receive (handle, f, 0);
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
if (f != stdout)
|
|
Packit |
0bbbb1 |
fclose (f);
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
raw1394_destroy_handle (handle);
|
|
Packit |
0bbbb1 |
} else {
|
|
Packit |
0bbbb1 |
fprintf (stderr, "Failed to get libraw1394 handle\n");
|
|
Packit |
0bbbb1 |
return -1;
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
return 0;
|
|
Packit |
0bbbb1 |
}
|