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

📄 vm.c

📁 linux下的MPEG1
💻 C
📖 第 1 页 / 共 4 页
字号:
      /* BUTTON number:data2 */      if(link_values.data2 != 0)	(vm->state).HL_BTNN_REG = link_values.data2 << 10;      /* Update any other state, pgN, PTTN perhaps? */      (vm->state).cellN = link_values.data1;      link_values = play_Cell(vm);      break;          case Exit:      vm->stopped = 1;      return 0;          case JumpTT:      /* Jump to VTS Title Domain */      /* Only allowed from the First Play domain(PGC) */      /* or the Video Manager domain (VMG) */      /* Stop SPRM9 Timer */      /* Set SPRM1 and SPRM2 */      assert((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN); /* ?? */      if(set_TT(vm, link_values.data1))        link_values = play_PGC(vm);      else	link_values.command = Exit;      break;    case JumpVTS_TT:      /* Jump to Title:data1 in same VTS Title Domain */      /* Only allowed from the VTS Menu Domain(VTSM) */      /* or the Video Title Set Domain(VTS) */      /* Stop SPRM9 Timer */      /* Set SPRM1 and SPRM2 */      assert((vm->state).domain == VTSM_DOMAIN || (vm->state).domain == VTS_DOMAIN); /* ?? */      if(!set_VTS_TT(vm, (vm->state).vtsN, link_values.data1))	assert(0);      link_values = play_PGC(vm);      break;    case JumpVTS_PTT:      /* Jump to Part:data2 of Title:data1 in same VTS Title Domain */      /* Only allowed from the VTS Menu Domain(VTSM) */      /* or the Video Title Set Domain(VTS) */      /* Stop SPRM9 Timer */      /* Set SPRM1 and SPRM2 */      assert((vm->state).domain == VTSM_DOMAIN || (vm->state).domain == VTS_DOMAIN); /* ?? */      if(!set_VTS_PTT(vm, (vm->state).vtsN, link_values.data1, link_values.data2))	assert(0);      link_values = play_PGC_PG(vm, (vm->state).pgN);      break;          case JumpSS_FP:      /* Jump to First Play Domain */      /* Only allowed from the VTS Menu Domain(VTSM) */      /* or the Video Manager domain (VMG) */      /* Stop SPRM9 Timer and any GPRM counters */      assert((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == VTSM_DOMAIN); /* ?? */      if (!set_FP_PGC(vm))	assert(0);      link_values = play_PGC(vm);      break;    case JumpSS_VMGM_MENU:      /* Jump to Video Manger domain - Title Menu:data1 or any PGC in VMG */      /* Allowed from anywhere except the VTS Title domain */      /* Stop SPRM9 Timer and any GPRM counters */      assert((vm->state).domain != VTS_DOMAIN); /* ?? */      (vm->state).domain = VMGM_DOMAIN;      if(!set_MENU(vm, link_values.data1))	assert(0);      link_values = play_PGC(vm);      break;    case JumpSS_VTSM:      /* Jump to a menu in Video Title domain, */      /* or to a Menu is the current VTS */      /* Stop SPRM9 Timer and any GPRM counters */      /* ifoOpenNewVTSI:data1 */      /* VTS_TTN_REG:data2 */      /* get_MENU:data3 */       if(link_values.data1 != 0) {	if (link_values.data1 != (vm->state).vtsN) {	  /* the normal case */	  assert((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN); /* ?? */	  (vm->state).domain = VTSM_DOMAIN;	  if (!ifoOpenNewVTSI(vm, vm->dvd, link_values.data1))  /* Also sets (vm->state).vtsN */	    assert(0);	} else {	  /* This happens on some discs like "Captain Scarlet & the Mysterons" or	   * the German RC2 of "Anatomie" in VTSM. */	  assert((vm->state).domain == VTSM_DOMAIN ||	    (vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN); /* ?? */	  (vm->state).domain = VTSM_DOMAIN;	}      } else {	/*  This happens on 'The Fifth Element' region 2. */	assert((vm->state).domain == VTSM_DOMAIN);      }      /*  I don't know what title is supposed to be used for. */      /*  Alien or Aliens has this != 1, I think. */      /* assert(link_values.data2 == 1); */      (vm->state).VTS_TTN_REG = link_values.data2;      /* TTN_REG (SPRM4), VTS_TTN_REG (SPRM5), TT_PGCN_REG (SPRM6) are linked, */      /* so if one changes, the others must change to match it. */      (vm->state).TTN_REG     = get_TT(vm, (vm->state).vtsN, (vm->state).VTS_TTN_REG);      if(!set_MENU(vm, link_values.data3))	assert(0);      link_values = play_PGC(vm);      break;    case JumpSS_VMGM_PGC:      /* set_PGCN:data1 */      /* Stop SPRM9 Timer and any GPRM counters */      assert((vm->state).domain != VTS_DOMAIN); /* ?? */      (vm->state).domain = VMGM_DOMAIN;      if(!set_PGCN(vm, link_values.data1))	assert(0);      link_values = play_PGC(vm);      break;          case CallSS_FP:      /* set_RSMinfo:data1 */      assert((vm->state).domain == VTS_DOMAIN); /* ?? */      /* Must be called before domain is changed */      set_RSMinfo(vm, link_values.data1, /* We dont have block info */ 0);      set_FP_PGC(vm);      link_values = play_PGC(vm);      break;    case CallSS_VMGM_MENU:      /* set_MENU:data1 */       /* set_RSMinfo:data2 */      assert((vm->state).domain == VTS_DOMAIN); /* ?? */      /* Must be called before domain is changed */      set_RSMinfo(vm, link_values.data2, /* We dont have block info */ 0);            (vm->state).domain = VMGM_DOMAIN;      if(!set_MENU(vm, link_values.data1))	assert(0);      link_values = play_PGC(vm);      break;    case CallSS_VTSM:      /* set_MENU:data1 */       /* set_RSMinfo:data2 */      assert((vm->state).domain == VTS_DOMAIN); /* ?? */      /* Must be called before domain is changed */      set_RSMinfo(vm, link_values.data2, /* We dont have block info */ 0);      (vm->state).domain = VTSM_DOMAIN;      if(!set_MENU(vm, link_values.data1))	assert(0);      link_values = play_PGC(vm);      break;    case CallSS_VMGM_PGC:      /* set_PGC:data1 */      /* set_RSMinfo:data2 */      assert((vm->state).domain == VTS_DOMAIN); /* ?? */      /* Must be called before domain is changed */      set_RSMinfo(vm, link_values.data2, /* We dont have block info */ 0);      (vm->state).domain = VMGM_DOMAIN;      if(!set_PGCN(vm, link_values.data1))	assert(0);      link_values = play_PGC(vm);      break;    case PlayThis:      /* Should never happen. */      assert(0);      break;    }#ifdef TRACE    fprintf(MSG_OUT, "libdvdnav: After printout starts:\n");    vm_print_current_domain_state(vm);    fprintf(MSG_OUT, "libdvdnav: After printout ends.\n");#endif      }  (vm->state).blockN = link_values.data1 | (link_values.data2 << 16);  return 1;}/* Set functions */static int set_TT(vm_t *vm, int tt) {    return set_PTT(vm, tt, 1);}static int set_PTT(vm_t *vm, int tt, int ptt) {  assert(tt <= vm->vmgi->tt_srpt->nr_of_srpts);  return set_VTS_PTT(vm, vm->vmgi->tt_srpt->title[tt - 1].title_set_nr,		     vm->vmgi->tt_srpt->title[tt - 1].vts_ttn, ptt);}static int set_VTS_TT(vm_t *vm, int vtsN, int vts_ttn) {  return set_VTS_PTT(vm, vtsN, vts_ttn, 1);}static int set_VTS_PTT(vm_t *vm, int vtsN, int vts_ttn, int part) {  int pgcN, pgN, res;    (vm->state).domain = VTS_DOMAIN;  if (vtsN != (vm->state).vtsN)    if (!ifoOpenNewVTSI(vm, vm->dvd, vtsN))  /* Also sets (vm->state).vtsN */      return 0;    if ((vts_ttn < 1) || (vts_ttn > vm->vtsi->vts_ptt_srpt->nr_of_srpts) ||      (part < 1) || (part > vm->vtsi->vts_ptt_srpt->title[vts_ttn - 1].nr_of_ptts) ) {    return 0;  }    pgcN = vm->vtsi->vts_ptt_srpt->title[vts_ttn - 1].ptt[part - 1].pgcn;  pgN = vm->vtsi->vts_ptt_srpt->title[vts_ttn - 1].ptt[part - 1].pgn;   (vm->state).TT_PGCN_REG = pgcN;  (vm->state).PTTN_REG    = part;  (vm->state).TTN_REG     = get_TT(vm, vtsN, vts_ttn);  assert( (vm->state.TTN_REG) != 0 );  (vm->state).VTS_TTN_REG = vts_ttn;  (vm->state).vtsN        = vtsN;  /* Not sure about this one. We can get to it easily from TTN_REG */  /* Any other registers? */    res = set_PGCN(vm, pgcN);   /* This clobber's state.pgN (sets it to 1), but we don't want clobbering here. */  (vm->state).pgN = pgN;  return res;}static int set_FP_PGC(vm_t *vm) {    (vm->state).domain = FP_DOMAIN;  if (!vm->vmgi->first_play_pgc) {    return set_PGCN(vm, 1);  }  (vm->state).pgc = vm->vmgi->first_play_pgc;  (vm->state).pgcN = vm->vmgi->vmgi_mat->first_play_pgc;  return 1;}static int set_MENU(vm_t *vm, int menu) {  assert((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == VTSM_DOMAIN);  return set_PGCN(vm, get_ID(vm, menu));}static int set_PGCN(vm_t *vm, int pgcN) {  pgcit_t *pgcit;    pgcit = get_PGCIT(vm);  assert(pgcit != NULL);  /* ?? Make this return -1 instead */  if(pgcN < 1 || pgcN > pgcit->nr_of_pgci_srp) {#ifdef TRACE    fprintf(MSG_OUT, "libdvdnav:  ** No such pgcN = %d\n", pgcN);#endif    return 0;  }    (vm->state).pgc = pgcit->pgci_srp[pgcN - 1].pgc;  (vm->state).pgcN = pgcN;  (vm->state).pgN = 1;   if((vm->state).domain == VTS_DOMAIN)    (vm->state).TT_PGCN_REG = pgcN;  return 1;}/* Figure out the correct pgN from the cell and update (vm->state). */ static int set_PGN(vm_t *vm) {  int new_pgN = 0;    while(new_pgN < (vm->state).pgc->nr_of_programs 	&& (vm->state).cellN >= (vm->state).pgc->program_map[new_pgN])    new_pgN++;    if(new_pgN == (vm->state).pgc->nr_of_programs) /* We are at the last program */    if((vm->state).cellN > (vm->state).pgc->nr_of_cells)      return 0; /* We are past the last cell */    (vm->state).pgN = new_pgN;    if((vm->state).domain == VTS_DOMAIN) {    playback_type_t *pb_ty;    if((vm->state).TTN_REG > vm->vmgi->tt_srpt->nr_of_srpts)      return 0; /* ?? */    pb_ty = &vm->vmgi->tt_srpt->title[(vm->state).TTN_REG - 1].pb_ty;    if(pb_ty->multi_or_random_pgc_title == /* One_Sequential_PGC_Title */ 0) {      int dummy, part;      vm_get_current_title_part(vm, &dummy, &part);      (vm->state).PTTN_REG = part;    } else {      /* FIXME: Handle RANDOM or SHUFFLE titles. */      fprintf(MSG_OUT, "libdvdnav: RANDOM or SHUFFLE titles are NOT handled yet.\n");    }  }  return 1;}/* Must be called before domain is changed (set_PGCN()) */static void set_RSMinfo(vm_t *vm, int cellN, int blockN) {  int i;    if(cellN) {    (vm->state).rsm_cellN = cellN;    (vm->state).rsm_blockN = blockN;  } else {    (vm->state).rsm_cellN = (vm->state).cellN;    (vm->state).rsm_blockN = blockN;  }  (vm->state).rsm_vtsN = (vm->state).vtsN;  (vm->state).rsm_pgcN = get_PGCN(vm);    /* assert((vm->state).rsm_pgcN == (vm->state).TT_PGCN_REG);  for VTS_DOMAIN */    for(i = 0; i < 5; i++) {    (vm->state).rsm_regs[i] = (vm->state).registers.SPRM[4 + i];  }}/* Get functions *//* Searches the TT tables, to find the current TT. * returns the current TT. * returns 0 if not found. */static int get_TT(vm_t *vm, int vtsN, int vts_ttn) {  int i;  int tt=0;  for(i = 1; i <= vm->vmgi->tt_srpt->nr_of_srpts; i++) {    if( vm->vmgi->tt_srpt->title[i - 1].title_set_nr == vtsN &&         vm->vmgi->tt_srpt->title[i - 1].vts_ttn == vts_ttn) {      tt=i;      break;    }  }  return tt;}/* Search for entry_id match of the PGC Category in the current VTS PGCIT table. * Return pgcN based on entry_id match. */static int get_ID(vm_t *vm, int id) {  int pgcN, i;  pgcit_t *pgcit;    /* Relies on state to get the correct pgcit. */  pgcit = get_PGCIT(vm);  assert(pgcit != NULL);#ifdef TRACE  fprintf(MSG_OUT, "libdvdnav: ** Searching for menu (0x%x) entry PGC\n", id);#endif  /* Force high bit set. */  id |=0x80;  /* Get menu/title */  for(i = 0; i < pgcit->nr_of_pgci_srp; i++) {    if( (pgcit->pgci_srp[i].entry_id) == id) {      pgcN = i + 1;#ifdef TRACE      fprintf(MSG_OUT, "libdvdnav: Found menu.\n");#endif      return pgcN;    }  }#ifdef TRACE  fprintf(MSG_OUT, "libdvdnav: ** No such id/menu (0x%02x) entry PGC\n", id & 0x7f);  for(i = 0; i < pgcit->nr_of_pgci_srp; i++) {    if ( (pgcit->pgci_srp[i].entry_id & 0x80) == 0x80) {      fprintf(MSG_OUT, "libdvdnav: Available menus: 0x%x\n",                     pgcit->pgci_srp[i].entry_id & 0x7f);    }  }#endif  return 0; /*  error */}/* FIXME: we have a pgcN member in the vm's state now, so this should be obsolete */static int get_PGCN(vm_t *vm) {  pgcit_t *pgcit;  int pgcN = 1;  pgcit = get_PGCIT(vm);    if (pgcit) {    while(pgcN <= pgcit->nr_of_pgci_srp) {      if(pgcit->pgci_srp[pgcN - 1].pgc == (vm->state).pgc) {	assert((vm->state).pgcN == pgcN);	return pgcN;      }      pgcN++;    }  }  fprintf(MSG_OUT, "libdvdnav: get_PGCN failed. Was trying to find pgcN in domain %d\n",          (vm->state).domain);  return 0; /*  error */}static pgcit_t* get_MENU_PGCIT(vm_t *vm, ifo_handle_t *h, uint16_t lang) {  int i;    if(h == NULL || h->pgci_ut == NULL) {    fprintf(MSG_OUT, "libdvdnav: *** pgci_ut handle is NULL ***\n");    return NULL; /*  error? */  }    i = 0;  while(i < h->pgci_ut->nr_of_lus	&& h->pgci_ut->lu[i].lang_code != lang)    i++;  if(i == h->pgci_ut->nr_of_lus) {    fprintf(MSG_OUT, "libdvdnav: Language '%c%c' not found, using '%c%c' instead\n",	    (char)(lang >> 8), (char)(lang & 0xff), 	    (char)(h->pgci_ut->lu[0].lang_code >> 8),	    (char)(h->pgci_ut->lu[0].lang_code & 0xff));    fprintf(MSG_OUT, "libdvdnav: Menu Languages available: ");    for(i = 0; i < h->pgci_ut->nr_of_lus; i++) {      fprintf(MSG_OUT, "%c%c ", 	    (char)(h->pgci_ut->lu[i].lang_code >> 8),	    (char)(h->pgci_ut->lu[i].lang_code & 0xff));    }    fprintf(MSG_OUT, "\n");    i = 0; /*  error? */  }    return h->pgci_ut->lu[i].pgcit;}/* Uses state to decide what to return */static pgcit_t* get_PGCIT(vm_t *vm) {  pgcit_t *pgcit;    switch ((vm->state).domain) {  case VTS_DOMAIN:    pgcit = vm->vtsi->vts_pgcit;    break;  case VTSM_DOMAIN:    pgcit = get_MENU_PGCIT(vm, vm->vtsi, (vm->state).registers.SPRM[0]);    break;  case VMGM_DOMAIN:  case FP_DOMAIN:    pgcit = get_MENU_PGCIT(vm, vm->vmgi, (vm->state).registers.SPRM[0]);    break;  default:    abort();  }    return pgcit;}/* Debug functions */#ifdef TRACEvoid vm_position_print(vm_t *vm, vm_position_t *position) {  fprintf(MSG_OUT, "libdvdnav: But=%x Spu=%x Aud=%x Ang=%x Hop=%x vts=%x dom=%x cell=%x cell_restart=%x cell_start=%x still=%x block=%x\n",  position->button,  position->spu_channel,  position->audio_channel,  position->angle_channel,  position->hop_channel,  position->vts,  position->domain,  position->cell,  position->cell_restart,  position->cell_start,  position->still,  position->block);}#endif

⌨️ 快捷键说明

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