kopia lustrzana https://github.com/F5OEO/tstools
288 wiersze
7.9 KiB
C
288 wiersze
7.9 KiB
C
/*
|
|
* 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;
|
|
int invert = 0;
|
|
unsigned int max_pkts = (unsigned int)-1;
|
|
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("-m", args[ii]) || !strcmp("-max", args[ii]))
|
|
{
|
|
if (argn <= ii)
|
|
{
|
|
fprint_err("### tsfilter: -max requires an argument\n");
|
|
return 1;
|
|
}
|
|
max_pkts = atoi(args[ii+1]);
|
|
++ii;
|
|
}
|
|
else if (!strcmp("-!", args[ii]) || !strcmp("-invert", args[ii]))
|
|
{
|
|
invert = 1;
|
|
}
|
|
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, pkt_num;
|
|
int pusi, adapt_len, payload_len;
|
|
byte *adapt, *payload;
|
|
|
|
|
|
pkt_num = 0;
|
|
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 (max_pkts != (unsigned int)-1 &&
|
|
pkt_num > max_pkts)
|
|
{
|
|
// We're done processing. If invert is on,
|
|
// copy the rest of the output, otherwise quit.
|
|
if (!invert) { break; } else { found = 0; }
|
|
}
|
|
|
|
// Invert the result, whatever it was.
|
|
if (invert)
|
|
{
|
|
found = !found;
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
++pkt_num;
|
|
}
|
|
}
|
|
|
|
// 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"
|
|
" -max <n>, -m <n> All packets after the nth are regarded as\n"
|
|
" not matching any pids.\n"
|
|
" -!, -invert Invert whatever your decision was before \n"
|
|
" applying it - the output contains only \n"
|
|
" pids not in the list up to max packets \n"
|
|
" and all packets in the input from then \n"
|
|
" on.\n"
|
|
);
|
|
}
|
|
|
|
/* End file */
|
|
|