/*------------------------------------------------------------------------
*
* Copyright (c) 1997-1998 by Cornell University.
*
* See the file "license.txt" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* demux2.c
*
* Wei-Tsang Ooi weitsng@cs.cornell.edu
*
* Usage : demux2 mpegSystem streamId output
*
* Takes an MPEG-1 system stream, and an id of the stream to extract. This
* programs extract the stream and dumped it into a file.
*
*------------------------------------------------------------------------
*/
#include "dvmbasic.h"
#include "dvmmpeg.h"
int main(int argc, char *argv[])
{
BitParser *inbp;
BitStream *inbs, *outbs;
FILE *outf;
MpegPktHdr *pkthdr;
int sid, id, pktlen, len, currin, currout;
/*
* Parse arguments and open input file.
*/
if (argc < 4) {
fprintf(stderr, "usage : %s input streamId output", argv[0]);
exit(1);
}
id = atoi(argv[2]);
outf = fopen(argv[3], "wb");
if (outf == NULL) {
fprintf(stderr, "unable to open file %s for writing\n", argv[3]);
exit(1);
}
/*
* Initialize input and output bitstream and bitparser.
*/
inbp = BitParserNew();
inbs = BitStreamMmapReadNew(argv[1]);
BitParserWrap (inbp, inbs);
outbs = BitStreamNew(65536);
/*
* Allocate a new Packet header.
*/
pkthdr = MpegPktHdrNew();
currout = 0;
while (1) {
/*
* Find a packet by looking for its header.
* It not found then we are done.
*/
len = MpegPktHdrFind (inbp);
if (len == -1) {
break;
}
/*
* Parse the header and check for the stream id to see
* if this is the stream that we want.
*/
len = MpegPktHdrParse (inbp, pkthdr);
sid = MpegPktHdrGetStreamId (pkthdr);
/*
* The stream id in the header is shifted by 192, so we unshift
* it before compare with the input id.
*/
if (sid - 192 != id) {
continue;
}
/*
* Retrive the packet length field from the packet header.
* The tricky part : The packet length includes part of the
* length of the header :
*
* |<----- header ---->|<------ body ------>|
* +-----+---------+----+--------------------+
* | | length | | |
* +-----+---------+----+--------------------+
* |<-6->|<------------ length bytes ------->|
*
* So the number of bytes we actually going to dump
* is (total length) - (length of header)
* == (pktlen + 6) - len
*/
pktlen = MpegPktHdrGetLength (pkthdr);
len = pktlen + 6 - len;
currin = BitParserTell (inbp);
/*
* Check if the BitStream is going to be full. If yes
* we flush the data in BitStream to disk.
*
* Note : instead of flushing, we may do other things here,
* such as decoding the stream.
*/
if (currout + len > 65536) {
BitStreamFileWriteSegment (outbs, outf, 0, currout);
currout = 0;
}
BitStreamDump (inbs, currin, outbs, currout, len);
BitParserSeek (inbp, len + currin);
currout += len;
}
/*
* Flush what ever is left to the disk and cleanup.
*/
BitStreamFileWriteSegment (outbs, outf, 0, currout);
BitStreamMmapReadFree(inbs);
BitStreamFree(outbs);
BitParserFree(inbp);
MpegPktHdrFree(pkthdr);
fclose(outf);
return 0;
}