summaryrefslogtreecommitdiff
path: root/libdvbmpeg/cpptools.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libdvbmpeg/cpptools.cc')
-rw-r--r--libdvbmpeg/cpptools.cc946
1 files changed, 946 insertions, 0 deletions
diff --git a/libdvbmpeg/cpptools.cc b/libdvbmpeg/cpptools.cc
new file mode 100644
index 0000000..91808cc
--- /dev/null
+++ b/libdvbmpeg/cpptools.cc
@@ -0,0 +1,946 @@
+/*
+ * dvb-mpegtools for the Siemens Fujitsu DVB PCI card
+ *
+ * Copyright (C) 2000, 2001 Marcus Metzler
+ * for convergence integrated media GmbH
+ * Copyright (C) 2002 Marcus Metzler
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+
+ * The author can be reached at mocm@metzlerbros.de
+ */
+
+#include "cpptools.hh"
+
+#define HEX(N) "0x" << hex << setw(2) << setfill('0') \
+<< int(N) << " " << dec
+#define HHEX(N,M) "0x" << hex << setw(M) << setfill('0') \
+<< int(N) << " " << dec
+#define LHEX(N,M) "0x" << hex << setw(M) << setfill('0') \
+<< long(N) << " " << dec
+
+#define MAX_SEARCH 1024 * 1024
+
+ostream & operator << (ostream & stream, PES_Packet & x){
+
+ if (x.info){
+ cerr << "PES Packet: " ;
+ switch ( x.p.stream_id ) {
+
+ case PROG_STREAM_MAP:
+ cerr << "Program Stream Map";
+ break;
+ case PRIVATE_STREAM2:
+ cerr << "Private Stream 2";
+ break;
+ case PROG_STREAM_DIR:
+ cerr << "Program Stream Directory";
+ break;
+ case ECM_STREAM :
+ cerr << "ECM Stream";
+ break;
+ case EMM_STREAM :
+ cerr << "EMM Stream";
+ break;
+ case PADDING_STREAM :
+ cerr << "Padding Stream";
+ break;
+ case DSM_CC_STREAM :
+ cerr << "DSM Stream";
+ break;
+ case ISO13522_STREAM:
+ cerr << "ISO13522 Stream";
+ break;
+ case PRIVATE_STREAM1:
+ cerr << "Private Stream 1";
+ break;
+ case AUDIO_STREAM_S ... AUDIO_STREAM_E:
+ cerr << "Audio Stream " << HEX(x.p.stream_id);
+ break;
+ case VIDEO_STREAM_S ... VIDEO_STREAM_E:
+ cerr << "Video Stream " << HEX(x.p.stream_id);
+ break;
+
+ }
+ cerr << " MPEG" << x.p.mpeg << endl;
+ if ( x.p.mpeg == 2 ){
+ cerr << " FLAGS: ";
+
+ if (x.p.flags1 & SCRAMBLE_FLAGS){
+ cerr << " SCRAMBLE(";
+ cerr << ((x.p.flags1 & SCRAMBLE_FLAGS)>>4);
+ cerr << ")";
+ }
+ if (x.p.flags1 & PRIORITY_FLAG)
+ cerr << " PRIORITY";
+ if (x.p.flags1 & DATA_ALIGN_FLAG)
+ cerr << " DATA_ALIGN";
+ if (x.p.flags1 & COPYRIGHT_FLAG)
+ cerr << " COPYRIGHT";
+ if (x.p.flags1 & ORIGINAL_FLAG)
+ cerr << " ORIGINAL";
+
+ if (x.p.flags2 & PTS_DTS_FLAGS){
+ cerr << " PTS_DTS(";
+ cerr << ((x.p.flags2 & PTS_DTS_FLAGS)>>6);
+ cerr << ")";
+ }
+ if (x.p.flags2 & ESCR_FLAG)
+ cerr << " ESCR";
+ if (x.p.flags2 & ES_RATE_FLAG)
+ cerr << " ES_RATE";
+ if (x.p.flags2 & DSM_TRICK_FLAG)
+ cerr << " DSM_TRICK";
+ if (x.p.flags2 & ADD_CPY_FLAG)
+ cerr << " ADD_CPY";
+ if (x.p.flags2 & PES_CRC_FLAG)
+ cerr << " CRC";
+ if (x.p.flags2 & PES_EXT_FLAG)
+ cerr << " EXT";
+
+ cerr << endl;
+
+ if ((x.p.flags2 & PTS_DTS_FLAGS) == PTS_ONLY)
+ cerr << " PTS: "
+ << LHEX(ntohl(x.WPTS()),8)
+ << "(h" << int(x.high_pts()) << ")"
+ << endl;
+ else if ((x.p.flags2 & PTS_DTS_FLAGS) == PTS_DTS){
+ cerr << " PTS: "
+ << LHEX(ntohl(x.WPTS()),8)
+ << "(h" << int(x.high_pts()) << ")";
+ cerr << " DTS: "
+ << LHEX(ntohl(x.WDTS()),8)
+ << "(h" << int(x.high_dts()) << ")"
+ << endl;
+ }
+/*
+ if (x.p.flags2 & ESCR_FLAG)
+
+
+ if (x.p.flags2 & ES_RATE_FLAG)
+
+
+ if (x.p.flags2 & DSM_TRICK_FLAG)
+
+
+ if (x.p.flags2 & ADD_CPY_FLAG)
+
+
+ if (x.p.flags2 & PES_CRC_FLAG)
+
+
+ if (x.p.flags2 & PES_EXT_FLAG){
+
+ if (x.p.priv_flags & PRIVATE_DATA)
+ stream.write(x.p.pes_priv_data,16);
+
+ if (x.p.priv_flags & HEADER_FIELD){
+ stream.write(&x.p.pack_field_length,1);
+ x.p.pack_header = new
+ uint8_t[x.p.pack_field_length];
+ stream.write(x.p.pack_header,
+ x.p.pack_field_length);
+ }
+
+ if ( x.p.priv_flags & PACK_SEQ_CTR){
+ stream.write(&x.p.pck_sqnc_cntr,1);
+ stream.write(&x.p.org_stuff_length,1);
+ }
+
+ if ( x.p.priv_flags & P_STD_BUFFER)
+ stream.write(x.p.p_std,2);
+
+ if ( x.p.priv_flags & PES_EXT_FLAG2){
+ stream.write(&x.p.pes_ext_lngth,1);
+ x.p.pes_ext = new
+ uint8_t[x.p.pes_ext_lngth];
+ stream.write(x.p.pes_ext,
+ x.p.pes_ext_lngth);
+ }
+ }
+ } else {
+ if ((x.p.flags2 & PTS_DTS_FLAGS) == PTS_ONLY)
+ stream.write(x.p.pts,5);
+ else if ((x.p.flags2 & PTS_DTS_FLAGS) ==
+ PTS_DTS){
+ stream.write(x.p.pts,5);
+ stream.write(x.p.dts,5);
+ }
+*/
+ }
+ cerr << endl << endl;
+ return stream;
+ }
+
+ int l = x.p.length+x.p.pes_hlength+9;
+ uint8_t buf[l];
+ int length = cwrite_pes(buf,&(x.p),l);
+ stream.write((char *)buf,length);
+
+ return stream;
+}
+
+static unsigned int find_length(istream & stream){
+ streampos p = 0;
+ streampos start = 0;
+ streampos q = 0;
+ int found = 0;
+ uint8_t sync4[4];
+
+ start = stream.tellg();
+ start -=2;
+ stream.seekg(start);
+ while ( !stream.eof() && !found ){
+ p = stream.tellg();
+ stream.read((char *)&sync4,4);
+ if (sync4[0] == 0x00 && sync4[1] == 0x00 && sync4[2] == 0x01) {
+ switch ( sync4[3] ) {
+
+ case PROG_STREAM_MAP:
+ case PRIVATE_STREAM2:
+ case PROG_STREAM_DIR:
+ case ECM_STREAM :
+ case EMM_STREAM :
+ case PADDING_STREAM :
+ case DSM_CC_STREAM :
+ case ISO13522_STREAM:
+ case PRIVATE_STREAM1:
+ case AUDIO_STREAM_S ... AUDIO_STREAM_E:
+ case VIDEO_STREAM_S ... VIDEO_STREAM_E:
+ found = 1;
+ break;
+ default:
+ q = stream.tellg();
+ break;
+ }
+ }
+ }
+ q = stream.tellg();
+ stream.seekg(streampos(2)+start);
+ if (found) return (unsigned int)(q-start)-4-2;
+ else return (unsigned int)(q-start)-2;
+
+}
+
+istream & operator >> (istream & stream, PES_Packet & x){
+
+ uint8_t sync4[4];
+ int found=0;
+ int done=0;
+ streampos p = 0;
+
+ while (!stream.eof() && !found) {
+ p = stream.tellg();
+ stream.read((char *)&sync4,4);
+ if (sync4[0] == 0x00 && sync4[1] == 0x00 && sync4[2] == 0x01) {
+ x.p.stream_id = sync4[3];
+
+ switch ( sync4[3] ) {
+
+ case PROG_STREAM_MAP:
+ case PRIVATE_STREAM2:
+ case PROG_STREAM_DIR:
+ case ECM_STREAM :
+ case EMM_STREAM :
+ found = 1;
+ stream.read((char *)x.p.llength,2);
+ x.setlength();
+ if (!x.p.length){
+ x.p.length = find_length(stream);
+ x.Nlength();
+ }
+ stream.read((char *)x.p.pes_pckt_data,x.p.length);
+ done = 1;
+ break;
+ case PADDING_STREAM :
+ found = 1;
+ stream.read((char *)x.p.llength,2);
+ x.setlength();
+ if (!x.p.length){
+ x.p.length = find_length(stream);
+ x.Nlength();
+ }
+ x.p.padding = x.p.length;
+ stream.read((char *)x.p.pes_pckt_data,x.p.length);
+ done = 1;
+ break;
+
+ case DSM_CC_STREAM :
+ case ISO13522_STREAM:
+ case PRIVATE_STREAM1:
+ case AUDIO_STREAM_S ... AUDIO_STREAM_E:
+ case VIDEO_STREAM_S ... VIDEO_STREAM_E:
+ stream.read((char *)x.p.llength,2);
+ x.setlength();
+ if (!x.p.length){
+ x.p.length = find_length(stream);
+ x.Nlength();
+ }
+ found = 1;
+ break;
+
+ default:
+ stream.seekg(p+streampos(1));
+ break;
+ }
+ } else stream.seekg(p+streampos(1));
+ }
+
+ if ( found && !done) {
+ p = stream.tellg();
+ stream.read((char *)&x.p.flags1,1);
+ if ( (x.p.flags1 & 0xC0) == 0x80 )
+ x.p.mpeg = 2;
+ else
+ x.p.mpeg = 1;
+ if ( x.p.mpeg == 2 ){
+ stream.read((char *)&x.p.flags2,1);
+ stream.read((char *)&x.p.pes_hlength,1);
+
+ if ((int)x.p.length > x.p.pes_hlength+3)
+ x.p.length -=x.p.pes_hlength+3;
+ else
+ return stream;
+
+ uint8_t count = x.p.pes_hlength;
+
+ if ((x.p.flags2 & PTS_DTS_FLAGS) == PTS_ONLY){
+ stream.read((char *)x.p.pts,5);
+ count -=5;
+ } else
+ if ((x.p.flags2 & PTS_DTS_FLAGS) == PTS_DTS){
+ stream.read((char *)x.p.pts,5);
+ stream.read((char *)x.p.dts,5);
+ count -= 10;
+ }
+
+ if (x.p.flags2 & ESCR_FLAG){
+ stream.read((char *)x.p.escr,6);
+ count -= 6;
+ }
+
+ if (x.p.flags2 & ES_RATE_FLAG){
+ stream.read((char *)x.p.es_rate,3);
+ count -= 6;
+ }
+
+ if (x.p.flags2 & DSM_TRICK_FLAG){
+ stream.read((char *)&x.p.trick,1);
+ count -= 1;
+ }
+
+ if (x.p.flags2 & ADD_CPY_FLAG){
+ stream.read((char *)&x.p.add_cpy,1);
+ count -= 1;
+ }
+
+ if (x.p.flags2 & PES_CRC_FLAG){
+ stream.read((char *)x.p.prev_pes_crc,2);
+ count -= 2;
+ }
+
+ if (x.p.flags2 & PES_EXT_FLAG){
+ stream.read((char *)&x.p.priv_flags,1);
+ count -= 1;
+
+ if (x.p.priv_flags & PRIVATE_DATA){
+ stream.read((char *)x.p.pes_priv_data,16);
+ count -= 16;
+ }
+
+ if (x.p.priv_flags & HEADER_FIELD){
+ stream.read((char *)&x.p.pack_field_length,1);
+ x.p.pack_header = new
+ uint8_t[x.p.pack_field_length];
+ stream.read((char *)x.p.pack_header,
+ x.p.pack_field_length);
+ count -= 1+x.p.pack_field_length;
+ }
+
+ if ( x.p.priv_flags & PACK_SEQ_CTR){
+ stream.read((char *)&x.p.pck_sqnc_cntr,1);
+ stream.read((char *)&x.p.org_stuff_length,1);
+ count -= 2;
+ }
+
+ if ( x.p.priv_flags & P_STD_BUFFER){
+ stream.read((char *)x.p.p_std,2);
+ count -= 2;
+ }
+
+ if ( x.p.priv_flags & PES_EXT_FLAG2){
+ stream.read((char *)&x.p.pes_ext_lngth,1);
+ x.p.pes_ext = new
+ uint8_t[x.p.pes_ext_lngth];
+ stream.read((char *)x.p.pes_ext,
+ x.p.pes_ext_lngth);
+ count -= 1+x.p.pes_ext_lngth;
+ }
+ }
+ x.p.stuffing = count;
+ uint8_t dummy;
+ for(int i = 0; i< count ;i++)
+ stream.read((char *)&dummy,1);
+
+ } else {
+ uint8_t check;
+ x.p.mpeg1_pad = 1;
+ check = x.p.flags1;
+ while (check == 0xFF){
+ stream.read((char *)&check,1);
+ x.p.mpeg1_pad++;
+ }
+
+ if ( (check & 0xC0) == 0x40){
+ stream.read((char *)&check,1);
+ x.p.mpeg1_pad++;
+ stream.read((char *)&check,1);
+ x.p.mpeg1_pad++;
+ }
+ x.p.flags2 = 0;
+ x.p.length -= x.p.mpeg1_pad;
+
+ stream.seekg(p);
+ if ( (check & 0x30)){
+ x.p.length ++;
+ x.p.mpeg1_pad --;
+
+ if (check == x.p.flags1){
+ x.p.pes_hlength = 0;
+ } else {
+ x.p.mpeg1_headr =
+ new uint8_t[x.p.mpeg1_pad];
+ x.p.pes_hlength = x.p.mpeg1_pad;
+ stream.read((char *)x.p.mpeg1_headr,
+ x.p.mpeg1_pad);
+ }
+
+ x.p.flags2 = (check & 0xF0) << 2;
+ if ((x.p.flags2 & PTS_DTS_FLAGS) == PTS_ONLY){
+ stream.read((char *)x.p.pts,5);
+ x.p.length -= 5;
+ x.p.pes_hlength += 5;
+ }
+ else if ((x.p.flags2 & PTS_DTS_FLAGS) ==
+ PTS_DTS){
+ stream.read((char *)x.p.pts,5);
+ stream.read((char *)x.p.dts,5);
+ x.p.length -= 10;
+ x.p.pes_hlength += 10;
+ }
+ } else {
+ x.p.mpeg1_headr = new uint8_t[x.p.mpeg1_pad];
+ x.p.pes_hlength = x.p.mpeg1_pad;
+ stream.read((char *)x.p.mpeg1_headr,x.p.mpeg1_pad);
+ }
+ }
+ stream.read((char *)x.p.pes_pckt_data,x.p.length);
+ }
+ return stream;
+}
+
+ostream & operator << (ostream & stream, TS_Packet & x){
+
+ uint8_t buf[TS_SIZE];
+ int length = cwrite_ts(buf,&(x.p),TS_SIZE);
+ stream.write((char *)buf,length);
+
+ return stream;
+}
+
+istream & operator >> (istream & stream, TS_Packet & x){
+ uint8_t sync;
+ int found=0;
+ streampos p,q;
+
+ sync=0;
+ while (!stream.eof() && !found) {
+ stream.read((char *)&sync,1);
+ if (sync == 0x47)
+ found = 1;
+ }
+ stream.read((char *)x.p.pid,2);
+ stream.read((char *)&x.p.flags,1);
+ x.p.count = x.p.flags & COUNT_MASK;
+
+ if (!(x.p.flags & ADAPT_FIELD) && (x.p.flags & PAYLOAD)){
+ //no adapt. field only payload
+ stream.read((char *)x.p.data,184);
+ x.p.rest = 184;
+ return stream;
+ }
+
+ if ( x.p.flags & ADAPT_FIELD ) {
+ // adaption field
+ stream.read((char *)&x.p.adapt_length,1);
+ if (x.p.adapt_length){
+ p = stream.tellg();
+ stream.read((char *)&x.p.adapt_flags,1);
+
+ if ( x.p.adapt_flags & PCR_FLAG )
+ stream.read((char *) x.p.pcr,6);
+
+ if ( x.p.adapt_flags & OPCR_FLAG )
+ stream.read((char *) x.p.opcr,6);
+
+ if ( x.p.adapt_flags & SPLICE_FLAG )
+ stream.read((char *) &x.p.splice_count,1);
+
+ if( x.p.adapt_flags & TRANS_PRIV){
+ stream.read((char *)&x.p.priv_dat_len,1);
+ x.p.priv_dat = new uint8_t[x.p.priv_dat_len];
+ stream.read((char *)x.p.priv_dat,x.p.priv_dat_len);
+ }
+
+ if( x.p.adapt_flags & ADAP_EXT_FLAG){
+ stream.read((char *)&x.p.adapt_ext_len,1);
+ stream.read((char *)&x.p.adapt_eflags,1);
+ if( x.p.adapt_eflags & LTW_FLAG)
+ stream.read((char *)x.p.ltw,2);
+
+ if( x.p.adapt_eflags & PIECE_RATE)
+ stream.read((char *)x.p.piece_rate,3);
+
+ if( x.p.adapt_eflags & SEAM_SPLICE)
+ stream.read((char *)x.p.dts,5);
+ }
+ q = stream.tellg();
+ x.p.stuffing = x.p.adapt_length -(q-p);
+ x.p.rest = 183-x.p.adapt_length;
+ stream.seekg(q+streampos(x.p.stuffing));
+ if (x.p.flags & PAYLOAD) // payload
+ stream.read((char *)x.p.data,x.p.rest);
+ else
+ stream.seekg(q+streampos(x.p.rest));
+ } else {
+ x.p.rest = 182;
+ stream.read((char *)x.p.data, 183);
+ return stream;
+ }
+
+ }
+ return stream;
+}
+
+
+ostream & operator << (ostream & stream, PS_Packet & x){
+
+ uint8_t buf[PS_MAX];
+ int length = cwrite_ps(buf,&(x.p),PS_MAX);
+ stream.write((char *)buf,length);
+
+ return stream;
+}
+
+istream & operator >> (istream & stream, PS_Packet & x){
+ uint8_t headr[4];
+ int found=0;
+ streampos p = 0;
+ streampos q = 0;
+ int count = 0;
+
+ p = stream.tellg();
+ while (!stream.eof() && !found && count < MAX_SEARCH) {
+ stream.read((char *)&headr,4);
+ if (headr[0] == 0x00 && headr[1] == 0x00 && headr[2] == 0x01)
+ if ( headr[3] == 0xBA )
+ found = 1;
+ else if ( headr[3] == 0xB9 ) break;
+ else stream.seekg(p+streampos(1));
+ count++;
+ }
+
+ if (found){
+ stream.read((char *)x.p.scr,6);
+ if (x.p.scr[0] & 0x40)
+ x.p.mpeg = 2;
+ else
+ x.p.mpeg = 1;
+
+ if (x.p.mpeg == 2){
+ stream.read((char *)x.p.mux_rate,3);
+ stream.read((char *)&x.p.stuff_length,1);
+ p = stream.tellg();
+ stream.seekg(p+streampos(x.p.stuff_length & 3));
+ } else {
+ x.p.mux_rate[0] = x.p.scr[5]; //mpeg1 scr is only 5 bytes
+ stream.read((char *)x.p.mux_rate+1,2);
+ }
+
+ p=stream.tellg();
+ stream.read((char *)headr,4);
+ if (headr[0] == 0x00 && headr[1] == 0x00 &&
+ headr[2] == 0x01 && headr[3] == 0xBB ) {
+ stream.read((char *)x.p.sheader_llength,2);
+ x.setlength();
+ if (x.p.mpeg == 2){
+ stream.read((char *)x.p.rate_bound,3);
+ stream.read((char *)&x.p.audio_bound,1);
+ stream.read((char *)&x.p.video_bound,1);
+ stream.read((char *)&x.p.reserved,1);
+ }
+ stream.read((char *)x.p.data,x.p.sheader_length);
+ } else {
+ stream.seekg(p);
+ x.p.sheader_length = 0;
+ }
+
+ int i = 0;
+ int done = 0;
+ q = stream.tellg();
+ PES_Packet pes;
+ do {
+ p=stream.tellg();
+ stream.read((char *)headr,4);
+ stream.seekg(p);
+ if ( headr[0] == 0x00 && headr[1] == 0x00
+ && headr[2] == 0x01 && headr[3] != 0xBA){
+ pes.init();
+ stream >> pes;
+ i++;
+ } else done = 1;
+ } while (!stream.eof() && !done);
+ x.p.npes = i;
+ stream.seekg(q);
+ }
+ return stream;
+}
+
+void extract_audio_from_PES(istream &in, ostream &out){
+ PES_Packet pes;
+
+ while(!in.eof()){
+ pes.init();
+ in >> pes ;
+ if (pes.Stream_ID() == 0xC0)
+ out << pes;
+ }
+}
+
+void extract_video_from_PES(istream &in, ostream &out){
+ PES_Packet pes;
+
+ while(!in.eof()){
+ pes.init();
+ in >> pes ;
+ if (pes.Stream_ID() == 0xE0)
+ out << pes;
+ }
+}
+
+void extract_es_audio_from_PES(istream &in, ostream &out){
+ PES_Packet pes;
+
+ while(!in.eof()){
+ pes.init();
+ in >> pes ;
+ if (pes.Stream_ID() == 0xC0)
+ out.write((char *)pes.Data(),pes.Length());
+ }
+}
+
+void extract_es_video_from_PES(istream &in, ostream &out){
+ PES_Packet pes;
+
+ while(!in.eof()){
+ pes.init();
+ in >> pes ;
+ if (pes.Stream_ID() == 0xE0)
+ out.write((char *)pes.Data(),pes.Length());
+ }
+}
+
+
+
+#define MAX_PID 20
+int TS_PIDS(istream &in, ostream &out){
+ int pid[MAX_PID];
+ TS_Packet ts;
+ int npid=0;
+
+ for (int i=0 ; i<MAX_PID; i++)
+ pid[i] = -1;
+ while (!in.eof()) {
+ ts.init();
+ in >> ts;
+ int j;
+ int found = 0;
+ for (j=0;j<npid;j++){
+ if ( ts.PID() == pid[j] )
+ found = 1;
+ }
+ if (! found){
+ out << ts.PID() << " ";
+ pid[npid] = ts.PID();
+ npid++;
+ if (npid == MAX_PID) return -1;
+ }
+ }
+ out << endl;
+ return 0;
+}
+
+int tv_norm(istream &stream){
+ uint8_t headr[4];
+ int found=0;
+ streampos p = 0;
+ streampos q = 0;
+ int hsize,vsize;
+ int form= 0;
+
+ q = stream.tellg();
+ while (!stream.eof() && !found) {
+ p = stream.tellg();
+ stream.read((char *)headr,4);
+ if (headr[0] == 0x00 && headr[1] == 0x00 && headr[2] == 0x01)
+ if ( headr[3] == 0xB3 ){
+ found = 1;
+ }
+ if (! found) stream.seekg(p+streampos(1));
+ }
+ stream.read((char *)headr,4);
+
+ hsize = (headr[1] &0xF0) >> 4 | headr[0] << 4;
+ vsize = (headr[1] &0x0F) << 8 | headr[2];
+ cerr << "SIZE: " << hsize << "x" << vsize << endl;
+
+ switch(((headr[3]&0xF0) >>4)){
+ case 1:
+ cerr << "ASPECT: 1:1" << endl;
+ break;
+ case 2:
+ cerr << "ASPECT: 4:3" << endl;
+ break;
+ case 3:
+ cerr << "ASPECT: 16:9" << endl;
+ break;
+ case 4:
+ cerr << "ASPECT: 2.21:1" << endl;
+ break;
+ }
+
+ switch (int(headr[3]&0x0F)){
+ case 1:
+ cerr << "FRAMERATE: 23.976" << endl;
+ form = pDUNNO;
+ break;
+ case 2:
+ cerr << "FRAMERATE: 24" << endl;
+ form = pDUNNO;
+ break;
+ case 3:
+ cerr << "FRAMERATE: 25" << endl;
+ form = pPAL;
+ break;
+ case 4:
+ cerr << "FRAMERATE: 29.97" << endl;
+ form = pNTSC;
+ break;
+ case 5:
+ cerr << "FRAMERATE: 30" << endl;
+ form = pNTSC;
+ break;
+ case 6:
+ cerr << "FRAMERATE: 50" << endl;
+ form = pPAL;
+ break;
+ case 7:
+ cerr << "FRAMERATE: 59.94" << endl;
+ form = pNTSC;
+ break;
+ case 8:
+ cerr << "FRAMERATE: 60" << endl;
+ form = pNTSC;
+ break;
+ }
+
+ int mpeg = 0;
+ found = 0;
+ while (!stream.eof() && !found) {
+ p = stream.tellg();
+ stream.read((char *)headr,4);
+ if (headr[0] == 0x00 && headr[1] == 0x00 && headr[2] == 0x01)
+ if ( headr[3] == 0xB5 ){
+ char *profile[] = {"reserved", "High", "Spatially Scalable",
+ "SNR Scalable", "Main", "Simple", "undef",
+ "undef"};
+ char *level[] = {"res", "res", "res", "res",
+ "High","res", "High 1440", "res",
+ "Main","res", "Low", "res",
+ "res", "res", "res", "res"};
+ char *chroma[] = {"res", "4:2:0", "4:2:2", "4:4:4:"};
+ mpeg = 2;
+ stream.read((char *)headr,4);
+ cerr << "PROFILE: " << profile[headr[0] & 0x7] << endl;
+ cerr << "LEVEL: " << level[headr[1]>>4 & 0xF] << endl;
+ cerr << "CHROMA: " << chroma[headr[1]>>1 & 0x3] << endl;
+ found = 1;
+ } else {
+ mpeg = 1;
+ found = 1;
+ }
+ if (! found) stream.seekg(p+streampos(1));
+ }
+
+ stream.seekg(q);
+ return (form | mpeg << 4);
+}
+
+
+
+int stream_type(istream &fin){
+ uint8_t headr[4];
+ streampos p=fin.tellg();
+
+ TS_Packet ts;
+ fin >> ts;
+ fin.read((char *)headr,1);
+ fin.seekg(p);
+ if(fin && headr[0] == 0x47){
+ return TS_STREAM;
+ }
+
+ PS_Packet ps;
+ fin >> ps;
+ PES_Packet pes;
+ for(int j=0;j < ps.NPES();j++){
+ fin >> pes;
+ }
+ fin.read((char *)headr,4);
+ fin.seekg(p);
+ if (fin && headr[0] == 0x00 && headr[1] == 0x00
+ && headr[2] == 0x01 && headr[3] == 0xBA){
+ return PS_STREAM;
+ }
+
+ fin >> pes;
+ fin.read((char *)!headr,4);
+ fin.seekg(p);
+ if (fin && headr[0] == 0x00 && headr[1] == 0x00
+ && headr[2] == 0x01 ){
+ int found = 0;
+ switch ( headr[3] ) {
+
+ case PROG_STREAM_MAP:
+ case PRIVATE_STREAM2:
+ case PROG_STREAM_DIR:
+ case ECM_STREAM :
+ case EMM_STREAM :
+ case PADDING_STREAM :
+ case DSM_CC_STREAM :
+ case ISO13522_STREAM:
+ case PRIVATE_STREAM1:
+ case AUDIO_STREAM_S ... AUDIO_STREAM_E:
+ case VIDEO_STREAM_S ... VIDEO_STREAM_E:
+ found = 1;
+ break;
+ }
+ if (found){
+ return PES_STREAM;
+ }
+ }
+
+
+
+ return -1;
+}
+
+
+void analyze(istream &fin)
+{
+ PS_Packet ps;
+ PES_Packet pes;
+ int fc = 0;
+ char *frames[3] = {"I-Frame","P-Frame","B-Frame"};
+
+ while(fin){
+ uint32_t pts;
+ fin >> ps;
+ cerr << "SCR base: " << hex << setw(5)
+ << setfill('0') \
+ << ps.SCR_base() << " " << dec
+ << "ext : " << ps.SCR_ext();
+
+ cerr << " MUX rate: " << ps.MUX()*50*8/1000000.0
+ << " Mbit/s ";
+ cerr << "RATE bound: " << ps.Rate()*50*8/1000000.0
+ << " Mbit/s" << endl;
+ cerr << " Audio bound: "
+ << hex << "0x"
+ << int(ps.P()->audio_bound);
+ cerr << " Video bound: " << hex << "0x"
+ << int(ps.P()->video_bound)
+ << dec
+ << endl;
+ cerr << endl;
+
+ for (int i=0; i < ps.NPES(); i++){
+ pes.init();
+ fin >> pes;
+ pts2pts((uint8_t *)&pts,pes.PTS());
+ pes.Info() = 1;
+ cerr << pes;
+
+ uint8_t *buf = pes.P()->pes_pckt_data;
+ int c = 0;
+ int l;
+ switch (pes.P()->stream_id){
+ case VIDEO_STREAM_S ... VIDEO_STREAM_E:
+ l=pes.P()->length;
+ break;
+ default:
+ l = 0;
+ break;
+ }
+ while ( c < l - 6){
+ if (buf[c] == 0x00 &&
+ buf[c+1] == 0x00 &&
+ buf[c+2] == 0x01 &&
+ buf[c+3] == 0xB8) {
+ c += 4;
+ cerr << "TIME hours: "
+ << int((buf[c]>>2)& 0x1F)
+ << " minutes: "
+ << int(((buf[c]<<4)& 0x30)|
+ ((buf[c+1]>>4)& 0x0F))
+ << " seconds: "
+ << int(((buf[c+1]<<3)& 0x38)|
+ ((buf[c+2]>>5)& 0x0F))
+ << endl;
+ }
+
+ if ( buf[c] == 0x00 &&
+ buf[c+1] == 0x00 &&
+ buf[c+2] == 0x01 &&
+ buf[c+3] == 0x00) {
+ fc++;
+ c += 4;
+ cerr << "picture: "
+ << fc
+ << " ("
+ << frames[((buf[c+1]&0x38) >>3)-1]
+ << ")" << endl << endl;
+ } else c++;
+ }
+ }
+ }
+}
+
+