kopia lustrzana https://github.com/F5OEO/tstools
Add a new tsfilter utility to filter transport streams by their pids;
this is useful for extracting programmes from a multiplex.issue20
rodzic
dbb3ce681d
commit
1c8447e611
12
Makefile
12
Makefile
|
@ -134,7 +134,8 @@ PROG_OBJS = \
|
|||
$(OBJDIR)/tsserve.o \
|
||||
$(OBJDIR)/ts_packet_insert.o \
|
||||
$(OBJDIR)/m2ts2ts.o \
|
||||
$(OBJDIR)/pcapreport.o
|
||||
$(OBJDIR)/pcapreport.o \
|
||||
$(OBJDIR)/tsfilter.o
|
||||
#\
|
||||
# $(OBJDIR)/test_ps.o
|
||||
|
||||
|
@ -175,7 +176,8 @@ PROGS = \
|
|||
$(BINDIR)/tsserve \
|
||||
$(BINDIR)/ts_packet_insert \
|
||||
$(BINDIR)/m2ts2ts \
|
||||
$(BINDIR)/pcapreport
|
||||
$(BINDIR)/pcapreport \
|
||||
$(BINDIR)/tsfilter
|
||||
#\
|
||||
# $(BINDIR)/test_ps
|
||||
|
||||
|
@ -269,6 +271,9 @@ $(BINDIR)/m2ts2ts: $(OBJDIR)/m2ts2ts.o $(STATIC_LIB)
|
|||
$(BINDIR)/pcapreport: $(OBJDIR)/pcapreport.o $(STATIC_LIB)
|
||||
$(CC) $< -o $(BINDIR)/pcapreport $(LDFLAGS) $(LIBOPTS)
|
||||
|
||||
$(BINDIR)/tsfilter: $(OBJDIR)/tsfilter.o $(STATIC_LIB)
|
||||
$(CC) $< -o $(BINDIR)/tsfilter $(LDFLAGS) $(LIBOPTS)
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -354,6 +359,9 @@ $(OBJDIR)/m2ts2ts.o: m2ts2ts.c $(TS_H) misc_fns.h version.h
|
|||
$(OBJDIR)/pcapreport.o: pcapreport.c pcap.h version.h misc_fns.h
|
||||
$(CC) -c $< -o $@ $(CFLAGS)
|
||||
|
||||
$(OBJDIR)/tsfilter.o: tsfilter.c version.h misc_fns.h
|
||||
$(CC) -c $< -o $@ $(CFLAGS)
|
||||
|
||||
$(OBJDIR)/test_pes.o: test_pes.c $(TS_H) $(PS_H) $(ES_H) misc_fns.h $(PES_H) version.h
|
||||
$(CC) -c $< -o $@ $(CFLAGS)
|
||||
$(OBJDIR)/test_printing.o: test_printing.c $(TS_H) $(PS_H) $(ES_H) version.h
|
||||
|
|
1
ts.c
1
ts.c
|
@ -1400,6 +1400,7 @@ static int read_next_TS_packets(TS_reader_p tsreader,
|
|||
length = read(tsreader->file,
|
||||
&(tsreader->read_ahead[total]),
|
||||
TS_READ_AHEAD_BYTES - total);
|
||||
|
||||
if (length == 0) // EOF - no more data to read
|
||||
break;
|
||||
else if (length == -1)
|
||||
|
|
|
@ -0,0 +1,247 @@
|
|||
/*
|
||||
* Filter a transport stream by a list of pids.
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the MPEG TS, PS and ES tools.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Amino Communications Ltd.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Amino Communications Ltd, Swavesey, Cambridge UK
|
||||
*
|
||||
* ***** END LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <stddef.h>
|
||||
#else // _WIN32
|
||||
#include <unistd.h>
|
||||
#endif // _WIN32
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "compat.h"
|
||||
#include "ts_fns.h"
|
||||
#include "misc_fns.h"
|
||||
#include "printing_fns.h"
|
||||
#include "pidint_fns.h"
|
||||
#include "version.h"
|
||||
#include "tswrite_defns.h"
|
||||
#include "tswrite_fns.h"
|
||||
|
||||
/** List of PIDs to filter in */
|
||||
int *pidList = NULL;
|
||||
int pidListAlloc = 0, pidListUsed = 0;
|
||||
|
||||
static void print_usage(void);
|
||||
|
||||
void ensurePidList(int nr)
|
||||
{
|
||||
if (pidListAlloc > nr) { return; }
|
||||
pidListAlloc = nr;
|
||||
pidList = realloc(pidList, pidListAlloc * sizeof(int));
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argn, char *args[])
|
||||
{
|
||||
int ii = 1;
|
||||
int verbose = FALSE;
|
||||
const char *input_file = NULL, *output_file = NULL;
|
||||
|
||||
|
||||
if (argn < 2)
|
||||
{
|
||||
print_usage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
ensurePidList(1024);
|
||||
|
||||
while (ii < argn)
|
||||
{
|
||||
if (args[ii][0] == '-')
|
||||
{
|
||||
if (!strcmp("--help", args[ii]) || !strcmp("-h", args[ii]) ||
|
||||
!strcmp("-help", args[ii]))
|
||||
{
|
||||
print_usage();
|
||||
return 0;
|
||||
}
|
||||
else if (!strcmp("-verbose", args[ii]) || !strcmp("-v", args[ii]))
|
||||
{
|
||||
verbose = TRUE;
|
||||
}
|
||||
else if (!strcmp("-i", args[ii]) || !strcmp("-input", args[ii]))
|
||||
{
|
||||
if (argn <= ii)
|
||||
{
|
||||
fprint_err("### tsfilter: -input requires an argument\n");
|
||||
return 1;
|
||||
}
|
||||
input_file = args[ii+1];
|
||||
++ii;
|
||||
}
|
||||
else if (!strcmp("-o", args[ii]) || !strcmp("-output", args[ii]))
|
||||
{
|
||||
if (argn <= ii)
|
||||
{
|
||||
fprint_err("### tsfilter: -output requires an argument\n");
|
||||
return 1;
|
||||
}
|
||||
output_file = args[ii+1];
|
||||
++ii;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprint_err("### tsfilter: "
|
||||
"Unrecognised command line switch '%s'\n", args[ii]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char *p = NULL;
|
||||
// It's a pid.
|
||||
if (pidListUsed >= pidListAlloc)
|
||||
{
|
||||
ensurePidList(pidListAlloc + 1024);
|
||||
}
|
||||
|
||||
pidList[pidListUsed] = strtoul(args[ii], &p, 0);
|
||||
if (!(p && *p == '\0'))
|
||||
{
|
||||
fprint_err("### tsfilter: '%s' wasn't a valid number. \n",
|
||||
args[ii]);
|
||||
return 1;
|
||||
}
|
||||
++pidListUsed;
|
||||
}
|
||||
++ii;
|
||||
}
|
||||
|
||||
if (!pidListUsed)
|
||||
{
|
||||
fprint_err("### tsfilter: No pids to filter. \n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Now ..
|
||||
{
|
||||
int err;
|
||||
TS_reader_p tsreader;
|
||||
TS_writer_p tswriter;
|
||||
byte *pkt = NULL;
|
||||
|
||||
unsigned int pid;
|
||||
int pusi, adapt_len, payload_len;
|
||||
byte *adapt, *payload;
|
||||
|
||||
|
||||
err = open_file_for_TS_read((char *)input_file, &tsreader);
|
||||
if (err)
|
||||
{
|
||||
fprint_err("## tsfilter: Unable to open stdin for reading TS.\n");
|
||||
return 1;
|
||||
}
|
||||
if (output_file)
|
||||
{
|
||||
err = tswrite_open(TS_W_FILE, (char *)output_file, NULL, 0, 1, &tswriter);
|
||||
}
|
||||
else
|
||||
{
|
||||
err = tswrite_open(TS_W_STDOUT, NULL, NULL, 0, 1, &tswriter);
|
||||
}
|
||||
if (err)
|
||||
{
|
||||
fprint_err("## tsfilter: Unable to open stdout for writing TS. \n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
err = read_next_TS_packet(tsreader, &pkt);
|
||||
if (err == EOF)
|
||||
{
|
||||
/* We're done */
|
||||
break;
|
||||
}
|
||||
|
||||
err = split_TS_packet(pkt, &pid, &pusi, &adapt, &adapt_len, &payload,
|
||||
&payload_len);
|
||||
if (err)
|
||||
{
|
||||
fprint_err("### Error splitting TS packet - continuing. \n");
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
int found = 0;
|
||||
|
||||
for (i = 0 ;i < pidListUsed; ++i)
|
||||
{
|
||||
if (pid == pidList[i])
|
||||
{
|
||||
++found; // Yes!
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
// Write it out.
|
||||
err = tswrite_write(tswriter,
|
||||
pkt,
|
||||
pid,
|
||||
0, 0);
|
||||
|
||||
if (err)
|
||||
{
|
||||
fprint_err("### Error writing output - %d \n", err);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// It's the end!
|
||||
tswrite_close(tswriter, 1);
|
||||
close_TS_reader(&tsreader);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void print_usage(void)
|
||||
{
|
||||
print_msg(
|
||||
"Usage: tsfilter [switches] <pid> <pid> <pid> ... \n"
|
||||
"\n");
|
||||
REPORT_VERSION("tsfilter");
|
||||
print_msg(
|
||||
"\n"
|
||||
" Filter the given pids out of stdin and write the result on stdout.\n"
|
||||
"\n"
|
||||
"Switches:\n"
|
||||
" -i <infile> Take input from this file and not stdin.\n"
|
||||
" -o <outfile> Send output to this file and not stdout.\n"
|
||||
" -verbose, -v Be verbose.\n"
|
||||
);
|
||||
}
|
||||
|
||||
/* End file */
|
||||
|
Ładowanie…
Reference in New Issue