/*------------------------------------------------------------------------ * * 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; }