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

📄 nav.c

📁 基于linux的DVD播放器程序
💻 C
📖 第 1 页 / 共 3 页
字号:
	res |= (p_uops.go_up ? 0 : UOP_FLAG_GoUp);	res |= (p_uops.time_or_chapter_search ? 0 : UOP_FLAG_TimeOrChapterSearch);	res |= (p_uops.prev_or_top_pg_search ? 0 : UOP_FLAG_PrevOrTopPGSearch);	res |= (p_uops.next_pg_search ? 0 : UOP_FLAG_NextPGSearch);	res |= (p_uops.title_menu_call ? 0 : UOP_FLAG_TitleMenuCall);	res |= (p_uops.root_menu_call ? 0 : UOP_FLAG_RootMenuCall);	res |= (p_uops.subpic_menu_call ? 0 : UOP_FLAG_SubPicMenuCall);	res |= (p_uops.audio_menu_call ? 0 : UOP_FLAG_AudioMenuCall);	res |= (p_uops.angle_menu_call ? 0 : UOP_FLAG_AngleMenuCall);	res |= (p_uops.chapter_menu_call ? 0 : UOP_FLAG_ChapterMenuCall);	     	res |= (p_uops.resume ? 0 : UOP_FLAG_Resume);	res |= (p_uops.button_select_or_activate ? 0 : UOP_FLAG_ButtonSelectOrActivate);	res |= (p_uops.still_off ? 0 : UOP_FLAG_StillOff);	res |= (p_uops.pause_on ? 0 : UOP_FLAG_PauseOn);	res |= (p_uops.audio_stream_change ? 0 : UOP_FLAG_AudioStreamChange);	res |= (p_uops.subpic_stream_change ? 0 : UOP_FLAG_SubPicStreamChange);	res |= (p_uops.angle_change ? 0 : UOP_FLAG_AngleChange);	res |= (p_uops.karaoke_audio_pres_mode_change ? 0 : UOP_FLAG_KaraokeAudioPresModeChange);	res |= (p_uops.video_pres_mode_change ? 0 : UOP_FLAG_VideoPresModeChange);      }      send_ev.dvdctrl.cmd.currentuops.uops = res;      MsgSendEvent(msgq, ev.any.client, &send_ev, 0);    }    break;  case DVDCtrlGetAudioAttributes: // FIXME XXX $$$ Not done    {      MsgEvent_t send_ev;      int streamN = ev.dvdctrl.cmd.audioattributes.streamnr;      send_ev.type = MsgEventQDVDCtrl;      send_ev.dvdctrl.cmd.type = DVDCtrlAudioAttributes;      send_ev.dvdctrl.cmd.audioattributes.streamnr = streamN;      {	DVDAudioFormat_t af = DVD_AUDIO_FORMAT_Other;	audio_attr_t attr = vm_get_audio_attr(streamN);	memset(&send_ev.dvdctrl.cmd.audioattributes.attr, 0, 	       sizeof(DVDAudioAttributes_t)); //TBD	switch(attr.audio_format) {	case 0:	  af = DVD_AUDIO_FORMAT_AC3;	  break;	case 2:	  af = DVD_AUDIO_FORMAT_MPEG1;	  break;	case 3:	  af = DVD_AUDIO_FORMAT_MPEG2;	  break;	case 4:	  af = DVD_AUDIO_FORMAT_LPCM;	  break;	case 6:	  af = DVD_AUDIO_FORMAT_DTS;	  break;	default:	  NOTE("please send a bug report, unknown Audio format %d!", 	       attr.audio_format);	  break;	}	send_ev.dvdctrl.cmd.audioattributes.attr.AudioFormat 	  = af;	send_ev.dvdctrl.cmd.audioattributes.attr.AppMode 	  = attr.application_mode;	send_ev.dvdctrl.cmd.audioattributes.attr.LanguageExtension	  = attr.lang_extension;	send_ev.dvdctrl.cmd.audioattributes.attr.Language 	  = attr.lang_code;      }      MsgSendEvent(msgq, ev.any.client, &send_ev, 0);	        }    break;  case DVDCtrlGetCurrentSubpicture:    {      MsgEvent_t send_ev;      int nS, cS;      vm_get_subp_info(&nS, &cS);      send_ev.type = MsgEventQDVDCtrl;      send_ev.dvdctrl.cmd.type = DVDCtrlCurrentSubpicture;      send_ev.dvdctrl.cmd.currentsubpicture.nrofstreams = nS;      send_ev.dvdctrl.cmd.currentsubpicture.currentstream = cS & ~0x40;      send_ev.dvdctrl.cmd.currentsubpicture.display 	= (cS & 0x40) ? DVDTrue : DVDFalse;      MsgSendEvent(msgq, ev.any.client, &send_ev, 0);    }    break;  case DVDCtrlIsSubpictureStreamEnabled:    {      MsgEvent_t send_ev;      int streamN = ev.dvdctrl.cmd.subpicturestreamenabled.streamnr;      send_ev.type = MsgEventQDVDCtrl;      send_ev.dvdctrl.cmd.type = DVDCtrlSubpictureStreamEnabled;      send_ev.dvdctrl.cmd.subpicturestreamenabled.streamnr = streamN;      send_ev.dvdctrl.cmd.subpicturestreamenabled.enabled =	(vm_get_subp_stream(streamN) != -1) ? DVDTrue : DVDFalse;      MsgSendEvent(msgq, ev.any.client, &send_ev, 0);	        }    break;  case DVDCtrlGetSubpictureAttributes: // FIXME XXX $$$ Not done    {      MsgEvent_t send_ev;      int streamN = ev.dvdctrl.cmd.subpictureattributes.streamnr;      send_ev.type = MsgEventQDVDCtrl;      send_ev.dvdctrl.cmd.type = DVDCtrlSubpictureAttributes;      send_ev.dvdctrl.cmd.subpictureattributes.streamnr = streamN;      {	subp_attr_t attr = vm_get_subp_attr(streamN);	memset(&send_ev.dvdctrl.cmd.subpictureattributes.attr, 0, 	       sizeof(DVDSubpictureAttributes_t)); //TBD	send_ev.dvdctrl.cmd.subpictureattributes.attr.Language 	  = attr.lang_code;      }      MsgSendEvent(msgq, ev.any.client, &send_ev, 0);    }	      break;  case DVDCtrlGetCurrentAngle:    {      MsgEvent_t send_ev;      int nS, cS;      vm_get_angle_info(&nS, &cS);      send_ev.type = MsgEventQDVDCtrl;      send_ev.dvdctrl.cmd.type = DVDCtrlCurrentAngle;      send_ev.dvdctrl.cmd.currentangle.anglesavailable = nS;      send_ev.dvdctrl.cmd.currentangle.anglenr = cS;      MsgSendEvent(msgq, ev.any.client, &send_ev, 0);    }    break;  case DVDCtrlGetState:    {      MsgEvent_t send_ev;      char *state_str;      DVDCtrlLongStateEvent_t *state_ev;      state_str = vm_get_state_str(block);            send_ev.type = MsgEventQDVDCtrlLong;      send_ev.dvdctrllong.cmd.type = DVDCtrlLongState;      state_ev = &(send_ev.dvdctrllong.cmd.state);      if(state_str != NULL) {	strncpy(state_ev->xmlstr, state_str, sizeof(state_ev->xmlstr));	state_ev->xmlstr[sizeof(state_ev->xmlstr)-1] = '\0';	      } else {	state_ev->xmlstr[0] = '\0';      }            MsgSendEvent(msgq, ev.any.client, &send_ev, 0);            free(state_str);    }    break;  case DVDCtrlGetDiscID:    {      MsgEvent_t send_ev;      send_ev.type = MsgEventQDVDCtrl;      send_ev.dvdctrl.cmd.type = DVDCtrlDiscID;      memcpy(send_ev.dvdctrl.cmd.discid.id, discid, sizeof(discid));      MsgSendEvent(msgq, ev.any.client, &send_ev, 0);    }    break;  case DVDCtrlGetVolIds:    {      MsgEvent_t send_ev;      int voltype;      DVDCtrlLongVolIdsEvent_t *ids;      send_ev.type = MsgEventQDVDCtrlLong;      send_ev.dvdctrllong.cmd.type = DVDCtrlLongVolIds;            ids = &(send_ev.dvdctrllong.cmd.volids);            voltype = ev.dvdctrl.cmd.volids.voltype;      ids->voltype = 0;      if(voltype == 0) {	if(vm_get_udf_volids(ids->volid, sizeof(ids->volid),			     ids->volsetid, sizeof(ids->volsetid)) == 0) {	  ids->voltype = 1;	} else if(vm_get_iso_volids(ids->volid, sizeof(ids->volid),				    ids->volsetid, 				    sizeof(ids->volsetid)) == 0) {	  ids->voltype = 2;	}      } else if(voltype == 1) {	if(vm_get_udf_volids(ids->volid, sizeof(ids->volid),			     ids->volsetid, sizeof(ids->volsetid)) == 0) {	  ids->voltype = 1;	}      } else if(voltype == 2) {	if(vm_get_iso_volids(ids->volid, sizeof(ids->volid),			     ids->volsetid, sizeof(ids->volsetid)) == 0) {	  ids->voltype = 2;	}      } 	      MsgSendEvent(msgq, ev.any.client, &send_ev, 0);    }    break;  default:    DNOTE("unknown (not handled) DVDCtrlEvent %d\n",	  ev.dvdctrl.cmd.type);    break;  }  return res;}int process_long_user_data(MsgEvent_t ev, pci_t *pci, cell_playback_t *cell,			   int block, int *still_time){  int res = 0;        //fprintf(stderr, "nav: User input, MsgEvent.type: %d\n", ev.type);    switch(ev.dvdctrllong.cmd.type) {  case DVDCtrlLongSetState:    res = vm_set_state_str(ev.dvdctrllong.cmd.state.xmlstr);    break;  default:    DNOTE("unknown (not handled) DVDCtrlLongEvent %d\n",	  ev.dvdctrllong.cmd.type);    break;  }  return res;}static int block;static int still_time;static cell_playback_t *cell;static int pending_lbn;#define INF_STILL_TIME (10 * 0xff)static void do_init_cell(int flush) {    cell = &state.pgc->cell_playback[state.cellN - 1];  still_time = 10 * cell->still_time;  block = state.blockN;  assert(cell->first_sector + block <= cell->last_vobu_start_sector);  // FIXME XXX $$$ Only send when needed, and do send even if not playing  // from start? (should we do pre_commands when jumping to say part 3?)  /* Send the palette to the spu. */  send_spu_palette(state.pgc->palette);    /* Get the pci/dsi data */  if(flush)    send_demux_sectors(cell->first_sector + block, 1, FlowCtrlFlush);  else    send_demux_sectors(cell->first_sector + block, 1, FlowCtrlNone);    pending_lbn = cell->first_sector + block;}static void do_run(void) {  pci_t pci;  dsi_t dsi;    vm_start(); // see hack in main  do_init_cell(0);  pci.pci_gi.nv_pck_lbn = -1;  dsi.dsi_gi.nv_pck_lbn = -1;    while(1) {    MsgEvent_t ev;    int got_data;        // For now.. later use the time instead..    /* Have we read the last dsi packet we asked for? Then request the next. */    if(pending_lbn == dsi.dsi_gi.nv_pck_lbn       && cell->first_sector + block <= cell->last_vobu_start_sector) {      int complete_video;            /* If there is video data in this vobu, but not in the next. Then this 	 data must be a complete image, so let the decoder know this. */      if((dsi.vobu_sri.next_vobu & 0x80000000) == 0 	 && dsi.dsi_gi.vobu_1stref_ea != 0 /* there is video in this */) {	complete_video = FlowCtrlCompleteVideoUnit;	//DNOTE("FlowCtrlCompleteVideoUnit = 1;\n");      } else {	complete_video = FlowCtrlNone;      }            /* Demux/play the content of this vobu. */      if(dsi.dsi_gi.vobu_ea != 0) {	send_demux_sectors(cell->first_sector + block + 1, 			   dsi.dsi_gi.vobu_ea, complete_video);      }            /* VOBU still ? */      /* if(cell->playback_mode) .. */      /* need to defer the playing of the next VOBU untill the still       * is interrupted.  */	 /* start - get_next_vobu() */     	       /* The next vobu is where... (make this a function?) */      /* angle change points are at next ILVU, not sure if 	 one VOBU = one ILVU */       if(0 /*angle && change_angle*/) {	/* if( seamless )	   else // non seamless	*/	;      } else {	/* .. top two bits are flags */  	block += dsi.vobu_sri.next_vobu & 0x3fffffff;      }                  /* TODO XXX $$$ Test earlier and merge the requests if posible? */      /* If there is more data in this cell to demux, then get the       * next nav pack. */      if(cell->first_sector + block <= cell->last_vobu_start_sector) {	send_demux_sectors(cell->first_sector + block, 1, FlowCtrlNone);	pending_lbn = cell->first_sector + block;      } else {	//DNOTE("end of cell\n");	; // end of cell!	if(still_time == INF_STILL_TIME) // Inf. still time	  NOTE("%s", "Still picture select an item to continue.\n");	else if(still_time != 0)	  NOTE("Pause for %d seconds,\n", still_time/10);#if 0 	/* TODO XXX $$$ This should only be done at the correct time */	/* Handle forced activate button here */	if(pci.hli.hl_gi.foac_btnn != 0 && 	   (pci.hli.hl_gi.hli_ss & 0x03) != 0) {	  uint16_t button_nr = state.HL_BTNN_REG >> 10;	  /* Forced action 0x3f means selected button, 	     otherwise use the specified button */	  if(pci.hli.hl_gi.foac_btnn != 0x3f)	    button_nr = pci.hli.hl_gi.foac_btnn;	  if(button_nr > pci.hli.hl_gi.btn_ns)	    ; // error selected but out of range...	  state.HL_BTNN_REG = button_nr << 10;	  	  if(vm_eval_cmd(&pci.hli.btnit[button_nr - 1].cmd)) {	    do_init_cell(/* ?? */ 0);	    dsi.dsi_gi.nv_pck_lbn = -1;	  }	}#endif      }    }            // Wait for data/input or for cell still time to end    {      if(cell->first_sector + block <= cell->last_vobu_start_sector) {	got_data = wait_q(msgq, &ev); // Wait for a data packet or a message            } else { 	/* Handle cell still time here */	got_data = 0;	if(still_time == INF_STILL_TIME) // Inf. still time	  MsgNextEvent(msgq, &ev);	else	  while(still_time && MsgCheckEvent(msgq, &ev)) {	    struct timespec req = {0, 100000000}; // 0.1s 	    nanosleep(&req, NULL);	    still_time--;	  }		if(!still_time) // No more still time (or there never was any..)	  if(MsgCheckEvent(msgq, &ev)) { // and no more messages	    // Let the vm run and give us a new cell to play	    vm_get_next_cell();	    do_init_cell(/* No jump */ 0);	    dsi.dsi_gi.nv_pck_lbn = -1;	  }      }    }    /* If we are here we either have a message or an available data packet */             /* User input events */    if(!got_data) { // Then it must be a message (or error?)      int res = 0;            switch(ev.type) {      case MsgEventQDVDCtrl:	/* Do user input processing. Like audio change, 	 * subpicture change and answer attribute query requests.	 * access menus, pause, play, jump forward/backward...	 */	res = process_user_data(ev, &pci, &dsi, cell, block, &still_time);	break;      case MsgEventQDVDCtrlLong:	res = process_long_user_data(ev, &pci, cell, block, &still_time);	break;	      default:	handle_events(msgq, &ev);	/* If( new dvdroot ) {	   vm_reset(get_dvdroot());	   block = 0;	   res = 1;	   }	*/      }            if(res != 0) {/* a jump has occured */	do_init_cell(/* Flush streams */1);	dsi.dsi_gi.nv_pck_lbn = -1;      }          } else { // We got a data to read.      unsigned char buffer[2048];      int len;            len = get_q(msgq, &buffer[0]);            if(buffer[0] == PS2_PCI_SUBSTREAM_ID) {	navRead_PCI(&pci, &buffer[1]);	/* Is this the packet we are waiting for? */	if(pci.pci_gi.nv_pck_lbn != pending_lbn) {	  //fprintf(stdout, "nav: Droped PCI packet\n");	  pci.pci_gi.nv_pck_lbn = -1;	  continue;	}	//fprintf(stdout, "nav: Got PCI packet\n");	/*	if(pci.hli.hl_gi.hli_ss & 0x03) {	  fprintf(stdout, "nav: Menu detected\n");	  navPrint_PCI(&pci);	}	*/	/* Evaluate and Instantiate the new pci packet */	process_pci(&pci, &state.HL_BTNN_REG);              } else if(buffer[0] == PS2_DSI_SUBSTREAM_ID) {	navRead_DSI(&dsi, &buffer[1]);	if(dsi.dsi_gi.nv_pck_lbn != pending_lbn) {	  //fprintf(stdout, "nav: Droped DSI packet\n");	  dsi.dsi_gi.nv_pck_lbn = -1;	  continue;	}	//fprintf(stdout, "nav: Got DSI packet\n");	//navPrint_DSI(&dsi);      } else {	int i;	ERROR("Unknown NAV packet type (%02x)\n", buffer[0]);	for(i=0;i<20;i++)	  printf("%02x ", buffer[i]);      }    }      }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -