?? mpeg2demux.cc
字號:
return 1;}int Mpeg2Demux::get_adaptation_field(){ adaptation_fields++; int length=getbits8(); // get adaptation field length// int discontinuity_indicator=(nextbits8() >> 7);// int random_access_indicator=(nextbits8() >> 6) & 1;// int elem_prio_indicator=(nextbits8() >> 5) & 1; // not used at this point; int pcr_flag=(getbits8() >> 4) & 1; // get first byte if (pcr_flag){ unsigned long clk_ref_base=getbits32(); unsigned int clk_ref_ext=getbits16(); if (clk_ref_base>0x7fffffff){ // correct for invalid numbers clk_ref_base=0; // ie. longer than 32 bits when multiplied by 2 clk_ref_ext=0; // multiplied by 2 corresponds to shift left 1 (<<=1) } else { clk_ref_base<<=1; // Create space for bit clk_ref_base|=(clk_ref_ext >> 15); // Take bit clk_ref_ext&=0x01ff; // Only lower 9 bits } double time=clk_ref_base + clk_ref_ext/300; TRACER("Time: " << dtoa(time)); if (sync) sync->put(time); // id=0, Timer if (length) skipbytes(length - 7); } else skipbytes(length - 1); return 1;}int Mpeg2Demux::get_payload(){ if (payload_unit_start_indicator){ if (pid==0) get_program_association_table(); else if (nextbits24()==Packet_start_code_prefix) get_pes_packet(); else skipbytes(MPEG2_TS_Packet_size - bytecount); // get_psi_packet(); } else { if (pid==audio_pid) get_audio_data(); else if (pid==video_pid) get_video_data(); else skipbytes(MPEG2_TS_Packet_size - bytecount); } return 1;}int Mpeg2Demux::get_program_association_table(){ program_association_tables++; table_id=getbits8(); section_length=getbits16() & 0xfff; // last 12 bits transport_stream_id=getbits16(); skipbytes(MPEG2_TS_Packet_size-bytecount);/* for (int i=0; i<section_length-9; i+=4) getbits32(); i-=4; if ((i+9)>(MPEG2_TS_Packet_size-4)) error("too many bytes in program association table");*/ return 1;}int Mpeg2Demux::get_pes_packet_data(int stream_id){ unsigned long pts(0), dts(0); if ((stream_id >> 4)==12 || (stream_id >> 4)==13){ // Just pick the first available stream if no ID is set if (astream==-1) astream=(stream_id & 0x0f); if ((stream_id & 0x0f)==astream && audio_on){ if (sync && pes_audio_bytes){ TRACER("AudioTime: " << dtoa(pes_audio_time) << " " << itoa(pes_audio_bytes)); sync->put(2, pes_audio_time, pes_audio_bytes); // id=2, Audio pes_audio_time=0; pes_audio_bytes=0; } get_pes_packet_header(pts, dts); pes_audio_time=pts; audio_pid=pid; return get_audio_data(); } } else if ((stream_id >> 4)==14){ // Just pick the first available stream if no ID is set if (vstream==-1) vstream=(stream_id & 0x0f); if ((stream_id & 0x0f)==vstream && video_on){ if (sync && pes_video_bytes){ TRACER("VideoTime: " << dtoa(pes_video_time) << " " << itoa(pes_video_bytes)); sync->put(1, pes_video_time, pes_video_bytes); // id=1, Video pes_video_time=0; pes_video_bytes=0; } get_pes_packet_header(pts, dts); pes_video_time=pts; video_pid=pid; return get_video_data(); } } else { return get_unknown_data(); } skipbytes(MPEG2_TS_Packet_size - bytecount); return 1;}int Mpeg2Demux::get_pes_packet_header(unsigned long& pts, unsigned long& dts){ unsigned int pes_header_bytes(0); getbits8(); // drop first 8 bits short PTS_DTS_flags=(getbits8() >> 6) & 0x3; int PES_header_data_length=getbits8(); // Get Presentation Time stamps and Decoding Time Stamps if (PTS_DTS_flags==2){ pts=(getbits8() >> 1) & 7; // Only low 4 bits (7==1111) pts<<=15; pts|=(getbits16() >> 1); pts<<=15; pts|=(getbits16() >> 1); pes_header_bytes+=5; } else if (PTS_DTS_flags==3){ pts=(getbits8() >> 1) & 7; // Only low 4 bits (7==1111) pts<<=15; pts|=(getbits16() >> 1); pts<<=15; pts|=(getbits16() >> 1); dts=(getbits8() >> 1) & 7; // Only low 4 bits (7==1111) dts<<=15; dts|=(getbits16() >> 1); dts<<=15; dts|=(getbits16() >> 1); pes_header_bytes+=10; } // extract other stuff here! skipbytes(PES_header_data_length - pes_header_bytes); return 1;}int Mpeg2Demux::get_pes_packet(){ pes_packets++; getbits24(); // skip startcode unsigned int stream_id=getbits8();// int pes_packet_length= // Not used at this point; just drop getbits16(); if (stream_id!=Private_stream_2 && stream_id!=Padding_stream){ return get_pes_packet_data(stream_id); } else if (stream_id==Private_stream_2){ // Dump private data! error("private stream"); skipbytes(MPEG2_TS_Packet_size - bytecount); } else if (stream_id==Padding_stream){ skipbytes(MPEG2_TS_Packet_size - bytecount); // Nothing; the next search for a sync byte will just skip the stuffing bytes } else { error("unknown stream_id in pes packet"); skipbytes(MPEG2_TS_Packet_size - bytecount); } return 1;}int Mpeg2Demux::get_psi_packet(){ psi_packets++; table_id=getbits8(); section_length=getbits16() & 0x0fff; skipbytes(MPEG2_TS_Packet_size - bytecount); return 1;}int Mpeg2Demux::get_audio_data(){ audio_packets++; pes_audio_bytes+=copybytes(audio_buffer, MPEG2_TS_Packet_size - bytecount); return 1;}int Mpeg2Demux::get_video_data(){ video_packets++; pes_video_bytes+=copybytes(video_buffer, MPEG2_TS_Packet_size - bytecount); return 1;}int Mpeg2Demux::get_unknown_data(){ warning("unknown data in PSI or PES packet"); return skipbytes(MPEG2_TS_Packet_size - bytecount);}/* * * MPEG Program Stream * */int Mpeg2Demux::program_stream(){ if (!get_program_pack()){ error("failure in programm pack"); return 0; } audio_buffer->close(); video_buffer->close(); return 1;}int Mpeg2Demux::get_program_pack(){static unsigned int header; header = getbits32(); while (1) { if (header == Pack_start_code) { get_pack_header(&header); } else if ((header >> 8) == Packet_start_code_prefix) { counter++; get_ps_pes_packet(&header); } else { return 0; } if (!quiet){ if ((counter % 100)==0) msg("."); if ((counter % 5000)==0){ message(itoa(counter)); } } if (terminate){// if ((!sync || sync->stop()) && (!audio && audio->stop()) && (!video && video->stop())) break; } } return 1;}int Mpeg2Demux::get_ps_pes_packet(unsigned int *header){ static unsigned long pts(0),dts(0); int PES_header_data_length; pes_packets++; int stream_id=*header & 0xff; unsigned int pes_packet_length=getbits16(); if (stream_id!=(int)Private_stream_2 && stream_id!=(int)Padding_stream){pts = 0; if ((nextbits8() & 0xc0) == 0x40) { pes_packet_length -= 12; skipbytes(12); } else { int pes_header_bytes=0; int scrambling = (getbits8() >> 4 ) & 3;// if (scrambling) {// message("scrambled data");// skip_ps_bytes(header); // return 1;// } int PTS_DTS_flags=(getbits8() >> 6) & 0x3; PES_header_data_length=getbits8(); // Get Presentation Time stamps and Decoding Time Stamps if (PTS_DTS_flags==2){ pts=(getbits8() >> 1) & 7; // Only low 4 bits (7==1111) pts<<=15; pts|=(getbits16() >> 1); pts<<=15; pts|=(getbits16() >> 1); pes_header_bytes+=5; } else if (PTS_DTS_flags==3){ pts=(getbits8() >> 1) & 7; // Only low 4 bits (7==1111) pts<<=15; pts|=(getbits16() >> 1); pts<<=15; pts|=(getbits16() >> 1); dts=(getbits8() >> 1) & 7; // Only low 4 bits (7==1111) dts<<=15; dts|=(getbits16() >> 1); dts<<=15; dts|=(getbits16() >> 1); pes_header_bytes+=10; } // extract other stuff here! pes_packet_length -=3; if (PES_header_data_length) { pes_packet_length -= PES_header_data_length; skipbytes (PES_header_data_length - pes_header_bytes); } } if ((stream_id >> 4)==12 || (stream_id >> 4)==13){ if ((stream_id & 0x0f)== astream && audio_on==1){ if (sync && pes_audio_bytes && pts ){ TRACER("AudioTime: " << dtoa(pes_audio_time)); sync->put(2, pes_audio_time, pes_audio_bytes); // id=2, Audio pes_audio_time=0; pes_audio_bytes=0; } if (pts) pes_audio_time=pts; pes_audio_bytes+=pes_packet_length; copy_ps_bytes(audio_buffer, header,pes_packet_length); } else { skip_ps_bytes(header); } } else if ((stream_id >> 4)==14){ if ((stream_id & 0x0f)== vstream && video_on){ if (sync && pes_video_bytes && pts){ TRACER("VideoTime: " << dtoa(pes_video_time) << " " << itoa(pes_video_bytes)); sync->put(1, pes_video_time,pes_video_bytes); // id=1, Video pes_video_time=0; pes_video_bytes=0; } if (pts) pes_video_time=pts; pes_video_bytes += pes_packet_length; copy_ps_bytes(video_buffer, header,pes_packet_length); } else { skip_ps_bytes(header); } } else if (stream_id == 0xbd){ if ( (*byteptr == (0x80+astream) ) && audio_on==2){ /* AC-3 Data */ if (sync && pes_audio_bytes && pts){ TRACER("AudioTime: " << dtoa(pes_audio_time) << " " << itoa(pes_audio_bytes)); sync->put(2, pes_audio_time, pes_audio_bytes); // id=2, Audio pes_audio_time=0; pes_audio_bytes=0; } if (pts) pes_audio_time=pts; pes_audio_bytes+=pes_packet_length-4; skipbytes(4); copy_ps_bytes(audio_buffer, header,pes_packet_length-4); } else { skip_ps_bytes(header); } } else if (stream_id == 0xbc){ skip_ps_bytes(header); } else { skip_ps_bytes(header); } } else if (stream_id==(int)Private_stream_2){ skip_ps_bytes(header); } else if (stream_id == (int)Padding_stream){ skip_ps_bytes(header); } else error("unknown stream_id in pes packet"); return 1;}int Mpeg2Demux::get_pack_header(unsigned int *header){static double old_time = 0.0;unsigned long i,j;unsigned long clock_ref,clock_ref_ext; i = getbits32(); j = getbits16(); if (i & 0x40000000) { clock_ref = ((i & 0x31000000) << 3); clock_ref |= ((i & 0x03fff800) << 4); clock_ref |= ((i & 0x000003ff) << 5); clock_ref |= ((j & 0xf800) >> 11); clock_ref_ext = (j >> 1) & 0x1ff; double time=clock_ref + clock_ref_ext/300; TRACER("Time: " << dtoa(time)); if (sync && (old_time + 6000 < time)) { sync->put(time); // id=0, Timer old_time = time; } skipbytes(3); i = getbits8() & 0x7; while (i--) getbits8(); // stuffing } else skipbytes(2); *header = getbits32(); if (*header == System_start_code) { get_system_header(); *header = getbits32(); } return 1;}int Mpeg2Demux::get_system_header(){int i; i = getbits16(); // get length while (i--) getbits8(); return 1;}/* * Packetized Elementary Stream (PES) */int Mpeg2Demux::pes_stream_audio(){ do { counter++; get_audio_data(); if (!quiet){ if ((counter % 100)==0) msg("."); if ((counter % 5000)==0){ message(itoa(counter)); } } } while (nextpacket()); audio_buffer->close(); return 1;} int Mpeg2Demux::pes_stream_video(){ do { counter++; get_video_data(); if (!quiet){ if ((counter % 100)==0) msg("."); if ((counter % 5000)==0){ message(itoa(counter)); } } } while (nextpacket()); video_buffer->close(); return 1;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -