📄 programstream.c
字号:
return; } } DPRINTF(debuglevel, "[illegal stream_id]\n");#else#endif}typedef enum { CMD_CTRL, CMD_FILE} cmd_type_t;typedef struct { MsgEventType_t cmd_type; union { MsgQPlayCtrlEvent_t ctrl; char *file; } cmd;} demux_q_t;static MsgEvent_t demux_q[5];static int demux_q_start = 0;static int demux_q_len = 0;void get_next_demux_q(void){ MsgEvent_t ev; MsgEvent_t *q_ev; int new_demux_range = 0; if(id_stat(0xe0, 0) == STREAM_DECODE) { if(demux_cmd & FlowCtrlCompleteVideoUnit) { put_in_q(id_qaddr(0xe0, 0), 0, 0, 0, 0, 0, 0, demux_cmd, 0, 0); } } while(!new_demux_range) { while(!demux_q_len) { if(MsgNextEvent(msgq, &ev) != -1) { switch(ev.type) { default: handle_events(&ev); //fprintf(stderr, "demux: unrecognized command\n"); break; } } } q_ev = &demux_q[demux_q_start]; switch(q_ev->type) { case MsgEventQPlayCtrl: switch(q_ev->playctrl.cmd) { case PlayCtrlCmdPlayFromTo: off_from = q_ev->playctrl.from; off_to = q_ev->playctrl.to; demux_cmd = q_ev->playctrl.flowcmd; new_demux_range = 1; break; default: fprintf(stderr, "demux: playctrl cmd not handled\n"); } break; case MsgEventQChangeFile: loadinputfile(q_ev->changefile.filename); //free(q_ev->cmd.file); break; case MsgEventQDemuxDVD: fill_buffer(q_ev->demuxdvd.titlenum, q_ev->demuxdvd.domain, q_ev->demuxdvd.block_offset, q_ev->demuxdvd.block_count); new_demux_range = 1; demux_cmd = q_ev->demuxdvd.flowcmd; break; case MsgEventQDemuxDVDRoot: dvd_open_root(q_ev->demuxdvdroot.path); break; default: fprintf(stderr, "demux: that's not possible\n"); break; } demux_q_start = (demux_q_start+1)%5; demux_q_len--; }}void add_to_demux_q(MsgEvent_t *ev){ int pos; if(demux_q_len < 5) { pos = (demux_q_start + demux_q_len)%5; memcpy(&demux_q[pos], ev, sizeof(MsgEvent_t)); demux_q_len++; } else { fprintf(stderr, "**demux: add_to_demux_q: q full\n"); } }/* demuxer state */int system_header_set = 0;int stream_open = 0;void system_header(void){ uint16_t header_length; uint32_t rate_bound; uint8_t audio_bound; uint8_t fixed_flag; uint8_t CSPS_flag; uint8_t system_audio_lock_flag; uint8_t system_video_lock_flag; uint8_t video_bound; uint8_t stream_id; uint8_t P_STD_buffer_bound_scale; uint16_t P_STD_buffer_size_bound; int min_bufsize = 0; DPRINTF(1, "system_header()\n"); GETBITS(32, "system_header_start_code"); header_length = GETBITS(16,"header_length"); marker_bit(); rate_bound = GETBITS(22,"rate_bound"); marker_bit(); audio_bound = GETBITS(6,"audio_bound"); fixed_flag = GETBITS(1,"fixed_flag"); CSPS_flag = GETBITS(1,"CSPS_flag"); system_audio_lock_flag = GETBITS(1,"system_audio_lock_flag"); system_video_lock_flag = GETBITS(1,"system_video_lock_flag"); marker_bit(); video_bound = GETBITS(5,"video_bound"); GETBITS(8, "reserved_byte"); DPRINTF(1, "header_length: %hu\n", header_length); DPRINTF(1, "rate_bound: %u [%u bits/s]\n", rate_bound, rate_bound*50*8); DPRINTF(1, "audio_bound: %u\n", audio_bound); DPRINTF(1, "fixed_flag: %u\n", fixed_flag); DPRINTF(1, "CSPS_flag: %u\n", CSPS_flag); DPRINTF(1, "system_audio_lock_flag: %u\n", system_audio_lock_flag); DPRINTF(1, "system_video_lock_flag: %u\n", system_video_lock_flag); DPRINTF(1, "video_bound: %u\n", video_bound); while(nextbits(1) == 1) { stream_id = GETBITS(8, "stream_id"); GETBITS(2, "11"); P_STD_buffer_bound_scale = GETBITS(1, "P_STD_buffer_bound_scale"); P_STD_buffer_size_bound = GETBITS(13, "P_STD_buffer_size_bound"); DPRINTF(1, "stream_id: "); dprintf_stream_id(1, stream_id); DPRINTF(1, "P-STD_buffer_bound_scale: %u\n", P_STD_buffer_bound_scale); DPRINTF(1, "P-STD_buffer_size_bound: %u [%u bytes]\n", P_STD_buffer_size_bound, P_STD_buffer_size_bound*(P_STD_buffer_bound_scale?1024:128)); min_bufsize+= P_STD_buffer_size_bound*(P_STD_buffer_bound_scale?1024:128); } if(!system_header_set) { system_header_set = 1; if(msgqid != -1) { // this is now allocated before we start reading //get_buffer(min_bufsize); } } }int pack_header(void){ uint64_t system_clock_reference; uint64_t system_clock_reference_base; uint16_t system_clock_reference_extension; uint32_t program_mux_rate; uint8_t pack_stuffing_length; int i; uint8_t fixed_bits; int version; static uint64_t prev_scr = 0; DPRINTF(2, "pack_header()\n"); GETBITS(32,"pack_start_code"); fixed_bits = nextbits(4); if(fixed_bits == 0x02) { version = MPEG1; } else if((fixed_bits >> 2) == 0x01) { version = MPEG2; } else { version = -1; fprintf(stderr, "demux: unknown MPEG version\n"); } switch(version) { case MPEG2: GETBITS(2, "01"); system_clock_reference_base = GETBITS(3,"system_clock_reference_base [32..30]") << 30; marker_bit(); system_clock_reference_base |= GETBITS(15, "system_clock_reference_base [29..15]") << 15; marker_bit(); system_clock_reference_base |= GETBITS(15, "system_clock_reference_base [14..0]"); marker_bit(); system_clock_reference_extension = GETBITS(9, "system_clock_reference_extension"); /* 2.5.2 or 2.5.3.4 (definition of system_clock_reference) */ system_clock_reference = system_clock_reference_base * 300 + system_clock_reference_extension; SCR_base = system_clock_reference_base; SCR_ext = system_clock_reference_extension; SCR_flags = 0x3; /* fprintf(stderr, "**** scr base %llx, ext %x, tot %llx\n", system_clock_reference_base, system_clock_reference_extension, system_clock_reference); */ marker_bit(); program_mux_rate = GETBITS(22, "program_mux_rate"); marker_bit(); marker_bit(); GETBITS(5, "reserved"); pack_stuffing_length = GETBITS(3, "pack_stuffing_length"); for(i=0;i<pack_stuffing_length;i++) { GETBITS(8 ,"stuffing_byte"); } DPRINTF(1, "system_clock_reference_base: %llu\n", system_clock_reference_base); DPRINTF(1, "system_clock_reference_extension: %u\n", system_clock_reference_extension); DPRINTF(1, "system_clock_reference: %llu [%6f s]\n", system_clock_reference, ((double)system_clock_reference)/27000000.0); if(system_clock_reference < prev_scr) { scr_discontinuity = 1; DNOTE("%s", "Backward scr discontinuity\n"); DNOTE("system_clock_reference: [%6f s]\n", ((double)system_clock_reference)/27000000.0); DNOTE("prev system_clock_reference: [%6f s]\n", ((double)prev_scr)/27000000.0); } else if((system_clock_reference - prev_scr) > 2700000*7) { scr_discontinuity = 1; DNOTE("%s", "Forward scr discontinuity\n"); DNOTE("system_clock_reference: [%6f s]\n", ((double)system_clock_reference)/27000000.0); DNOTE("prev system_clock_reference: [%6f s]\n", ((double)prev_scr)/27000000.0); } prev_scr = system_clock_reference; DPRINTF(1, "program_mux_rate: %u [%u bits/s]\n", program_mux_rate, program_mux_rate*50*8); DPRINTF(3, "pack_stuffing_length: %u\n", pack_stuffing_length); break; case MPEG1: GETBITS(4, "0010"); system_clock_reference_base = GETBITS(3,"system_clock_reference_base [32..30]") << 30; marker_bit(); system_clock_reference_base |= GETBITS(15, "system_clock_reference_base [29..15]") << 15; marker_bit(); system_clock_reference_base |= GETBITS(15, "system_clock_reference_base [14..0]"); marker_bit(); marker_bit(); program_mux_rate = GETBITS(22, "program_mux_rate"); marker_bit(); DPRINTF(2, "system_clock_reference_base: %llu\n", system_clock_reference_base); DPRINTF(2, "program_mux_rate: %u [%u bits/s]\n", program_mux_rate, program_mux_rate*50*8); // no extension in MPEG-1 ?? system_clock_reference = system_clock_reference_base * 300; SCR_base = system_clock_reference_base; SCR_flags = 0x1; DPRINTF(1, "system_clock_reference: %llu [%6f s]\n", system_clock_reference, ((double)system_clock_reference)/27000000.0); if(system_clock_reference < prev_scr) { scr_discontinuity = 1; DNOTE("%s", "*** Backward scr discontinuity ******\n"); DNOTE("system_clock_reference: [%6f s]\n", ((double)system_clock_reference)/27000000.0); DNOTE("prev system_clock_reference: [%6f s]\n", ((double)prev_scr)/27000000.0); } else if((system_clock_reference - prev_scr) > 2700000) { scr_discontinuity = 1; DNOTE("%s", "*** Forward scr discontinuity ******\n"); DNOTE("system_clock_reference: [%6f s]\n", ((double)system_clock_reference)/27000000.0); DNOTE("prev system_clock_reference: [%6f s]\n", ((double)prev_scr)/27000000.0); } prev_scr = system_clock_reference; break; } if(nextbits(32) == MPEG2_PS_SYSTEM_HEADER_START_CODE) { system_header(); } return version;}void push_stream_data(uint8_t stream_id, int len, uint8_t PTS_DTS_flags, uint64_t PTS, uint64_t DTS, PacketType_t packet_type, uint32_t packet_offs){ uint8_t *data = &disk_buf[offs-(bits_left/8)]; uint8_t subtype; uint32_t packet_data_offset = offs-(bits_left/8); // fprintf(stderr, "pack nr: %d, stream_id: %02x (%02x), offs: %d, len: %d", // packnr, stream_id, data[0], offs-(bits_left/8), len); // if(SCR_flags) { // fprintf(stderr, ", SCR_base: %llx", SCR_base); // } // if(PTS_DTS_flags & 0x2) { // fprintf(stderr, ", PTS: %llx", PTS); // } // fprintf(stderr, "\n"); //fprintf(stderr, "stream_id: %02x\n", stream_id);#ifdef STATS stat_n_packets++;#endif //STATS DPRINTF(5, "bitsleft: %d\n", bits_left); if(stream_id == MPEG2_PRIVATE_STREAM_1) { subtype = data[0]; } else { subtype = 0; } if((!id_registered(stream_id, subtype)) && system_header_set) { register_id(stream_id, subtype); } //fprintf(stderr, "Packet id: %02x, %02x\n", stream_id, subtype); if(id_stat(stream_id, subtype) == STREAM_DECODE) { if(!id_has_output(stream_id, subtype)) { id_get_output(stream_id, subtype); } // if(stream_id == MPEG2_PRIVATE_STREAM_1) { /* if((stream_id == 0xe0) || (stream_id == 0xc0) || ((stream_id == MPEG2_PRIVATE_STREAM_1) && (subtype == 0x80)) || (stream_id == MPEG2_PRIVATE_STREAM_2)) { */ //fprintf(stderr, "demux: put_in_q stream_id: %x %x\n", // stream_id, subtype); if(msgqid != -1) { int infile; int is_newfile; infile = id_infile(stream_id, subtype); if(infile != new_file) { id_setinfile(stream_id, subtype, new_file); is_newfile = 1; } else { is_newfile = 0; } if(stream_id == MPEG2_PRIVATE_STREAM_1) { if((subtype >= 0x80) && (subtype < 0x88)) { // ac3 /* p[0] is the substream id p[1] is the number of frames of audio which have a sync code in this pack p[2]<<8 | p[3] is the starting index of the frame for which the PTS value corresponds */ put_in_q(id_qaddr(stream_id, subtype), packet_data_offset, len, PTS_DTS_flags, PTS, DTS, is_newfile, 0, packet_type, packet_offs); } else if((subtype >= 0x88) && (subtype < 0x90)) { // dts put_in_q(id_qaddr(stream_id, subtype), packet_data_offset, len, PTS_DTS_flags, PTS, DTS, is_newfile, 0, packet_type, packet_offs); } else if((subtype >= 0xA0) && (subtype < 0xA8)) { // pcm put_in_q(id_qaddr(stream_id, subtype), packet_data_offset, len, PTS_DTS_flags, PTS, DTS, is_newfile, 0, packet_type, packet_offs); } else if((subtype >= 0x20) && (subtype < 0x40)) { // spu put_in_q(id_qaddr(stream_id, subtype), packet_data_offset, len, PTS_DTS_flags, PTS, DTS, is_newfile, 0, packet_type, packet_offs); } else { put_in_q(id_qaddr(stream_id, subtype), packet_data_offset, len, PTS_DTS_flags, PTS, DTS, is_newfile, 0, packet_type, packet_offs); } } else { put_in_q(id_qaddr(stream_id, subtype), packet_data_offset, len, PTS_DTS_flags, PTS, DTS, is_newfile, 0, packet_type, packet_offs); } } else { if(stream_id == MPEG2_PRIVATE_STREAM_1) { if((subtype >= 0x80) && (subtype < 0x88)) { // ac3#if 1 fwrite(&disk_buf[packet_data_offset+4], len-4, 1, id_file(stream_id, subtype));#else fwrite(&disk_buf[packet_data_offset], 4, 1, id_file(stream_id, subtype));#endif } else if((subtype >= 0x88) && (subtype < 0x90)) { // dts#if 1 fwrite(&disk_buf[packet_data_offset+1], len-1, 1, id_file(stream_id, subtype));#else fwrite(&disk_buf[packet_data_offset], 64, 1, id_file(stream_id, subtype));#endif } else if((subtype >= 0xA0) && (subtype < 0xA8)) { // pcm#if 0 fwrite(&disk_buf[packet_data_offset+1], len-1, 1, id_file(stream_id, subtype));#else if(!((unsigned int)(&disk_buf[packet_data_offset]) & 0x1)) { // should be odd address DNOTE("%s", "lpcm at even address\n"); } if(!PTS_DTS_flags) { DNOTE("%s", "lpcm without PTS\n"); } fwrite(&disk_buf[packet_data_offset], 8, 1, id_file(stream_id, subtype));#endif } else if((subtype >= 0x20) && (subtype < 0x40)) { // spu fwrite(&disk_buf[packet_data_offset+1], len-1, 1, id_file(stream_id, subtype)); } else { fwrite(&disk_buf[packet_data_offset], len, 1, id_file(stream_id, subtype)); } } else { fwrite(&disk_buf[packet_data_offset], len, 1, id_file(stream_id, subtype)); } } } drop_bytes(len); }void PES_packet(void){ uint16_t PES_packet_length; uint8_t stream_id; uint8_t PES_scrambling_control; uint8_t PES_priority; uint8_t data_alignment_indicator; uint8_t copyright; uint8_t original_or_copy; uint8_t PTS_DTS_flags = 0; uint8_t ESCR_flag; uint8_t ES_rate_flag; uint8_t DSM_trick_mode_flag; uint8_t additional_copy_info_flag; uint8_t PES_CRC_flag; uint8_t PES_extension_flag; uint8_t PES_header_data_length; uint64_t PTS = 0; uint64_t DTS = 0; uint64_t ESCR_base; uint32_t ESCR_extension; uint32_t ES_rate; uint8_t trick_mode_control; uint8_t field_id; uint8_t intra_slice_refresh; uint8_t frequency_truncation; uint8_t field_rep_cntrl; uint8_t additional_copy_info; uint16_t previous_PES_packet_CRC; uint8_t PES_private_data_flag = 0; uint8_t pack_header_field_flag = 0; uint8_t program_packet_sequence_counter_flag = 0; uint8_t program_packet_sequence_counter = 0; uint8_t P_STD_buffer_flag = 0; uint8_t PES_extension_field_flag = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -