⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 programstream.c

📁 基于linux的DVD播放器程序
💻 C
📖 第 1 页 / 共 5 页
字号:
        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 + -