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

📄 vm.c

📁 基于linux的DVD播放器程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Ogle - A video player * Copyright (C) 2000, 2001 H錵an Hjort * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful,  * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <inttypes.h>#include <assert.h>#include "ogle/dvd.h"#include "ogle/dvdevents.h"#include "ogle/msgevents.h"#include <dvdread/ifo_types.h>#include <dvdread/ifo_read.h>#include "decoder.h"#include "vmcmd.h"#include "vm.h"#include "vm_serialize.h"#include "debug_print.h"static dvd_reader_t *dvd;static ifo_handle_t *vmgi;static ifo_handle_t *vtsi;dvd_state_t state;unsigned char discid[16];/* Local prototypes */static void saveRSMinfo(int cellN, int blockN);static int update_PGN(void);static int next_PG(link_t *link_values);static int prev_PG(link_t *link_values);static link_t play_PGC(void);static link_t play_PG(void);static link_t play_Cell(void);static link_t play_Cell_post(void);static link_t play_PGC_post(void);static link_t process_command(link_t link_values);static void ifoOpenNewVTSI(dvd_reader_t *dvd, int vtsN);static pgcit_t* get_PGCIT(void);static int get_video_aspect(void);/* Can only be called when in VTS_DOMAIN */static int get_TT(int tt);static int get_VTS_TT(int vtsN, int vts_ttn);static int get_TT_PTT(int tt, int ptt);static int get_VTS_PTT(int vtsN, int vts_ttn, int part);/* Could add code so that it's callable in menus too... */static int get_cellN_for_vobu(uint32_t vobu_addr);static int get_MENU(int menu); // VTSM & VMGMstatic int get_FP_PGC(void); // FP/* Called in any domain */static int get_ID(int id);static int get_PGC(int pgcN);static int get_PGCN(void);char *vm_get_state_str(int blockN){  dvd_state_t save_state;  char *state_str = NULL;    save_state = state;  save_state.blockN = blockN;  save_state.pgcN = get_PGCN();  state_str = vm_serialize_dvd_state(&save_state);    return state_str;}int vm_set_state_str(char *state_str){  dvd_state_t save_state;    if(state_str == NULL) {    return 0;  }    if(!vm_deserialize_dvd_state(state_str, &save_state)) {    WARNING("%s", "state_str wrong\n");    return 0;  }    //reads: state.vtsN (if vtsN == state.vtsN) do nothing  //writes: state.vtsN  ifoOpenNewVTSI(dvd, save_state.vtsN);  // sets state.vtsN  state = save_state;  /* set state.domain before calling */  //calls get_pgcit()  //      needs state.domain and sprm[0] set  //      sets pgcit depending on state.domain  //writes: state.pgc  //        state.pgN  //        state.TT_PGCN_REG  get_PGC(save_state.pgcN);  save_state.pgc = state.pgc;  /* set the rest of state after the call */  state = save_state;  return 1;}int set_sprm(unsigned int nr, uint16_t val){  if(nr > 23) {    return 0;  }    state.registers.SPRM[nr] = val;  return 1;}int vm_reset(void) // , register_t regs){   // Setup State  memset(state.registers.SPRM, 0, sizeof(uint16_t)*24);  memset(state.registers.GPRM, 0, sizeof(state.registers.GPRM));  state.registers.SPRM[0] = ('e'<<8)|'n'; // Player Menu Languange code  state.AST_REG = 0; // 15 why?  state.SPST_REG = 0; // 62 why?  state.AGL_REG = 1;  state.TTN_REG = 1;  state.VTS_TTN_REG = 1;  //state.TT_PGCN_REG = 0  state.PTTN_REG = 1;  state.HL_BTNN_REG = 1 << 10;  state.PTL_REG = 15; // Parental Level  state.registers.SPRM[12] = ('U'<<8)|'S'; // Parental Management Country Code  state.registers.SPRM[16] = ('e'<<8)|'n'; // Initial Language Code for Audio  state.registers.SPRM[18] = ('e'<<8)|'n'; // Initial Language Code for Spu  state.registers.SPRM[20] = 1; // Player Regional Code (bit mask?)    state.pgN = 0;  state.cellN = 0;  state.domain = FP_DOMAIN;  state.rsm_vtsN = 0;  state.rsm_cellN = 0;  state.rsm_blockN = 0;    state.vtsN = -1;    state.mode = RESET_MODE;  return 0;}  int vm_init(char *dvdroot) // , register_t regs){  dvd = DVDOpen(dvdroot);  if(!dvd) {    ERROR("%s", "faild to open/read the DVD\n");    return -1;  }  if(DVDDiscID(dvd, discid) == -1) {    memset(discid, 0, sizeof(discid));  }    vmgi = ifoOpenVMGI(dvd);  if(!vmgi) {    ERROR("%s", "faild to read VIDEO_TS.IFO\n");    return -1;  }  if(!ifoRead_FP_PGC(vmgi)) {    ERROR("%s", "ifoRead_FP_PGC faild\n");    return -1;  }  if(!ifoRead_TT_SRPT(vmgi)) {    ERROR("%s", "ifoRead_TT_SRPT faild\n");    return -1;  }  if(!ifoRead_PGCI_UT(vmgi)) {    ERROR("%s", "ifoRead_PGCI_UT faild\n");    return -1;  }  if(!ifoRead_PTL_MAIT(vmgi)) {    ERROR("%s", "ifoRead_PTL_MAIT faild\n");    ; // return -1; Not really used for now..  }  if(!ifoRead_VTS_ATRT(vmgi)) {    ERROR("%s", "ifoRead_VTS_ATRT faild\n");    ; // return -1; Not really used for now..  }  //ifoRead_TXTDT_MGI(vmgi); Not implemented yet  return 0;}// FIXME TODO XXX $$$ Handle error condition too...int vm_start(void){  link_t link_values;  // Set pgc to FP pgc  get_FP_PGC();  link_values = play_PGC();   link_values = process_command(link_values);  assert(link_values.command == PlayThis);  state.blockN = link_values.data1;  return 0; //??}int vm_eval_cmd(vm_cmd_t *cmd){  link_t link_values;    if(vmEval_CMD(cmd, 1, &state.registers, &link_values)) {    link_values = process_command(link_values);    assert(link_values.command == PlayThis);    state.blockN = link_values.data1;    return 1; // Something changed, Jump  } else {    return 0; // It updated some state thats all...  }}int vm_get_next_cell(void){  link_t link_values;  link_values = play_Cell_post();  link_values = process_command(link_values);  assert(link_values.command == PlayThis);  state.blockN = link_values.data1;    return 0; // ??}int vm_top_pg(void){  link_t link_values;  link_values = play_PG();  link_values = process_command(link_values);  assert(link_values.command == PlayThis);  state.blockN = link_values.data1;    return 1; // Jump}int vm_next_pg(void){  link_t link_values;    if(next_PG(&link_values) == -1)    return 0; // do nothing   link_values = process_command(link_values);  assert(link_values.command == PlayThis);  state.blockN = link_values.data1;  return 1; // Jump}int vm_prev_pg(void){  link_t link_values;  if(prev_PG(&link_values) == -1)    return 0; // do nothing  link_values = process_command(link_values);  assert(link_values.command == PlayThis);  state.blockN = link_values.data1;  return 1; // Jump}int vm_goup_pgc(void){  link_t link_values;    if(get_PGC(state.pgc->goup_pgc_nr))    return 0;  // do nothing    link_values = play_PGC();  link_values = process_command(link_values);  assert(link_values.command == PlayThis);  state.blockN = link_values.data1;  return 1; // Jump}int vm_jump_ptt(int pttN){  link_t link_values;    //check domain!! should be only VTS Title domain    if(get_VTS_PTT(state.vtsN, state.VTS_TTN_REG, pttN) == -1)    return 0;    link_values = play_PGC();  link_values = process_command(link_values);  assert(link_values.command == PlayThis);  state.blockN = link_values.data1;  return 1; // Something changed, Jump}int vm_jump_title_ptt(int titleN, int pttN){  link_t link_values;    //check domain?!?  (VMGM & (Menu) Title & Stop)?    if(get_TT_PTT(titleN, pttN) == -1)    return 0;    link_values = play_PGC();  link_values = process_command(link_values);  assert(link_values.command == PlayThis);  state.blockN = link_values.data1;  return 1; // Something changed, Jump}int vm_jump_title(int titleN){  link_t link_values;    //check domain?  VMGM & (Menu) Title & Stop    if(get_TT(titleN) == -1)    return 0;    link_values = play_PGC();  link_values = process_command(link_values);  assert(link_values.command == PlayThis);  state.blockN = link_values.data1;  return 1; // Something changed, Jump}static domain_t menuid2domain(DVDMenuID_t menuid){  domain_t result = VTSM_DOMAIN; // Really shouldn't have to..    switch(menuid) {  case DVD_MENU_Title:    result = VMGM_DOMAIN;    break;  case DVD_MENU_Root:  case DVD_MENU_Subpicture:  case DVD_MENU_Audio:  case DVD_MENU_Angle:  case DVD_MENU_Part:    result = VTSM_DOMAIN;    break;  }    return result;}int vm_menu_call(DVDMenuID_t menuid, int block){  domain_t old_domain;  link_t link_values;    /* FIXME XXX $$$ How much state needs to be restored    * when we fail to find a menu? */    old_domain = state.domain;    switch(state.domain) {  case VTS_DOMAIN:    saveRSMinfo(0, block);    /* FALL THROUGH */  case VTSM_DOMAIN:    state.domain = menuid2domain(menuid);    /* FALL THROUGH */  case VMGM_DOMAIN: /* or should one be able to jump from vmgm to title dom? */    if(get_PGCIT() != NULL && get_MENU(menuid) != -1) {      link_values = play_PGC();      link_values = process_command(link_values);      assert(link_values.command == PlayThis);      state.blockN = link_values.data1;      return 1; // Jump    } else {      state.domain = old_domain;    }    break;  case FP_DOMAIN: /* FIXME XXX $$$ What should we do here? */    break;  }    return 0;}static int vm_resume_int(link_t *link_return){  int i;  link_t link_values;    if(state.domain == VTS_DOMAIN) { // Not allowed in the Titlte domain    return 0; // Fail  }    // Check and see if there is any rsm info!!  if(state.rsm_vtsN == 0) {    return 0; // Fail  }    state.domain = VTS_DOMAIN;  ifoOpenNewVTSI(dvd, state.rsm_vtsN); // FIXME check return value  get_PGC(state.rsm_pgcN); // FIXME check return value    /* These should never be set in SystemSpace and/or MenuSpace */   // state.TTN_REG = state.rsm_tt;  // state.TT_PGCN_REG = state.rsm_pgcN;  // state.HL_BTNN_REG = state.rsm_btnn; ??  for(i = 0; i < 5; i++) {    state.registers.SPRM[4 + i] = state.rsm_regs[i];  }  if(state.rsm_cellN == 0) {    assert(state.cellN); // Checking if this ever happens    /* assert( time/block/vobu is 0 ); */    state.pgN = 1;    link_values = play_PG();  } else {     /* assert( time/block/vobu is _not_ 0 ); */    /* play_Cell_at_time */    state.cellN = state.rsm_cellN;    state.blockN = state.rsm_blockN;    //state.pgN = ?? does this gets the righ value in play_Cell, no!    if(update_PGN()) {      /* Were at or past the end of the PGC, should not happen for a RSM */      assert(0);      link_values = play_PGC_post();    } else {      link_t do_nothing = { PlayThis, 0, 0, 0 };

⌨️ 快捷键说明

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