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

📄 vcdplayer.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
      return READ_STILL_FRAME;    }    /* Wait time has been processed; continue with next entry. */    vcdplayer_update_entry( p_access,                             vcdinf_pld_get_next_offset(p_vcdplayer->pxd.pld),                            &itemid.num, "next" );    itemid.type = VCDINFO_ITEM_TYPE_LID;    vcdplayer_play( p_access, itemid );    break;  }  case PSD_TYPE_SELECTION_LIST:     /* Selection List (+Ext. for SVCD) */  case PSD_TYPE_EXT_SELECTION_LIST: /* Extended Selection List (VCD2.0) */    {      uint16_t timeout_offs = vcdinf_get_timeout_offset(p_vcdplayer->pxd.psd);      uint16_t max_loop     = vcdinf_get_loop_count(p_vcdplayer->pxd.psd);      vcdinfo_offset_t *offset_timeout_LID =         vcdinfo_get_offset_t(p_vcdplayer->vcd, timeout_offs);            dbg_print(INPUT_DBG_PBC, "looped: %d, max_loop %d",                 p_vcdplayer->i_loop, max_loop);            /* Set up for caller process wait time given. */      if (p_vcdplayer->i_still) {	*wait_time = vcdinf_get_timeout_time(p_vcdplayer->pxd.psd);	dbg_print((INPUT_DBG_PBC|INPUT_DBG_STILL),		  "playlist wait_time: %d", *wait_time);	return READ_STILL_FRAME;      }             /* Wait time has been processed; continue with next entry. */      /* Handle any looping given. */      if ( max_loop == 0 || p_vcdplayer->i_loop < max_loop ) {        p_vcdplayer->i_loop++;        if (p_vcdplayer->i_loop == 0x7f) p_vcdplayer->i_loop = 0;        vcdplayer_play_single_item(p_access, p_vcdplayer->loop_item);        /* if (p_vcdplayer->i_still) p_vcdplayer->force_redisplay();*/        return READ_BLOCK;      }            /* Looping finished and wait finished. Move to timeout         entry or next entry, or handle still. */            if (NULL != offset_timeout_LID) {        /* Handle timeout_LID */        itemid.num  = offset_timeout_LID->lid;        itemid.type = VCDINFO_ITEM_TYPE_LID;        dbg_print(INPUT_DBG_PBC, "timeout to: %d", itemid.num);        vcdplayer_play( p_access, itemid );        return READ_BLOCK;      } else {        int i_selections = vcdinf_get_num_selections(p_vcdplayer->pxd.psd);        if (i_selections > 0) {          /* Pick a random selection. */          unsigned int bsn=vcdinf_get_bsn(p_vcdplayer->pxd.psd);          int rand_selection=bsn +            (int) ((i_selections+0.0)*rand()/(RAND_MAX+1.0));          lid_t rand_lid=vcdinfo_selection_get_lid (p_vcdplayer->vcd, 						    p_vcdplayer->i_lid, 						    rand_selection);          itemid.num = rand_lid;          itemid.type = VCDINFO_ITEM_TYPE_LID;          dbg_print(INPUT_DBG_PBC, "random selection %d, lid: %d",                     rand_selection - bsn, rand_lid);          vcdplayer_play( p_access, itemid );          return READ_BLOCK;        } else if (p_vcdplayer->i_still) {          /* Hack: Just go back and do still again */          msleep(1000);          return READ_STILL_FRAME;        }      }      break;    }  case VCDINFO_ITEM_TYPE_NOTFOUND:      LOG_ERR( "NOTFOUND in PBC -- not supposed to happen" );    break;  case VCDINFO_ITEM_TYPE_SPAREID2:      LOG_ERR( "SPAREID2 in PBC -- not supposed to happen" );    break;  case VCDINFO_ITEM_TYPE_LID:      LOG_ERR( "LID in PBC -- not supposed to happen" );    break;      default:    ;  }  /* FIXME: Should handle autowait ...  */  return READ_ERROR;}/*!  Read block into p_buf and return the status back.  This routine is a bit complicated because on reaching the end of   a track or entry we may automatically advance to the item, or   interpret the next item in the playback-control list.*/vcdplayer_read_status_tvcdplayer_read (access_t * p_access, uint8_t *p_buf){  /* p_access->handle_events (); */  uint8_t wait_time;  vcdplayer_t *p_vcdplayer= (vcdplayer_t *)p_access->p_sys;  if ( p_vcdplayer->i_lsn > p_vcdplayer->end_lsn ) {    vcdplayer_read_status_t read_status;        /* We've run off of the end of this entry. Do we continue or stop? */    dbg_print( (INPUT_DBG_LSN|INPUT_DBG_PBC),               "end reached, cur: %u, end: %u\n", p_vcdplayer->i_lsn, p_vcdplayer->end_lsn);  handle_item_continuation:    read_status = vcdplayer_pbc_is_on( p_vcdplayer )       ? vcdplayer_pbc_nav( p_access, &wait_time )       : vcdplayer_non_pbc_nav( p_access, &wait_time );    if (READ_STILL_FRAME == read_status) {      *p_buf = wait_time;      return READ_STILL_FRAME;    }    if (READ_BLOCK != read_status) return read_status;  }  /* Read the next block.          Important note: we probably speed things up by removing "data"    and the memcpy to it by extending vcd_image_source_read_mode2    to allow a mode to do what's below in addition to its     "raw" and "block" mode. It also would probably improve the modularity    a little bit as well.  */  {    CdIo *p_img = vcdinfo_get_cd_image(p_vcdplayer->vcd);    typedef struct {      uint8_t subheader [CDIO_CD_SUBHEADER_SIZE];      uint8_t data	[M2F2_SECTOR_SIZE];      uint8_t spare     [4];    } vcdsector_t;    vcdsector_t vcd_sector;    do {      if (cdio_read_mode2_sector(p_img, &vcd_sector, 				 p_vcdplayer->i_lsn, true)!=0) {        dbg_print(INPUT_DBG_LSN, "read error\n");	p_vcdplayer->i_lsn++;        return READ_ERROR;      }      p_vcdplayer->i_lsn++;      if ( p_vcdplayer->i_lsn >= p_vcdplayer->end_lsn ) {        /* We've run off of the end of this entry. Do we continue or stop? */        dbg_print( (INPUT_DBG_LSN|INPUT_DBG_PBC),                    "end reached in reading, cur: %u, end: %u\n",                    p_vcdplayer->i_lsn, p_vcdplayer->end_lsn);        break;      }            /* Check header ID for a padding sector and simply discard         these.  It is alleged that VCD's put these in to keep the         bitrate constant.      */    } while((vcd_sector.subheader[2]&~0x01)==0x60);    if ( p_vcdplayer->i_lsn >= p_vcdplayer->end_lsn )       /* We've run off of the end of this entry. Do we continue or stop? */      goto handle_item_continuation;          memcpy (p_buf, vcd_sector.data, M2F2_SECTOR_SIZE);    return READ_BLOCK;  }}/*!  Play item assocated with the "default" selection.  Return false if there was some problem.*/bool vcdplayer_play_default( access_t * p_access ){  vcdplayer_t *p_vcdplayer= (vcdplayer_t *)p_access->p_sys;  vcdinfo_itemid_t itemid;  if (!p_vcdplayer) {    dbg_print( (INPUT_DBG_CALL|INPUT_DBG_PBC), 	       "null p_vcdplayer" );    return VLC_EGENERIC;  }    dbg_print( (INPUT_DBG_CALL|INPUT_DBG_PBC), 	     "current: %d" , p_vcdplayer->play_item.num);  itemid.type = p_vcdplayer->play_item.type;  if  (vcdplayer_pbc_is_on(p_vcdplayer)) {#if defined(LIBVCD_VERSION)    lid_t lid=vcdinfo_get_multi_default_lid(p_vcdplayer->vcd, p_vcdplayer->i_lid,					    p_vcdplayer->i_lsn);    if (VCDINFO_INVALID_LID != lid) {      itemid.num  = lid;      itemid.type = VCDINFO_ITEM_TYPE_LID;      dbg_print(INPUT_DBG_PBC, "DEFAULT to %d", itemid.num);    } else {      dbg_print(INPUT_DBG_PBC, "no DEFAULT for LID %d", p_vcdplayer->i_lid);      return VLC_EGENERIC;    }#else     vcdinfo_lid_get_pxd(p_vcdplayer->vcd, &(p_vcdplayer->pxd), p_vcdplayer->i_lid);        switch (p_vcdplayer->pxd.descriptor_type) {    case PSD_TYPE_SELECTION_LIST:    case PSD_TYPE_EXT_SELECTION_LIST:      if (p_vcdplayer->pxd.psd == NULL) return false;      vcdplayer_update_entry( p_access, 			      vcdinfo_get_default_offset(p_vcdplayer->vcd, 							 p_vcdplayer->i_lid), 			      &itemid.num, "default");      break;    case PSD_TYPE_PLAY_LIST:     case PSD_TYPE_END_LIST:    case PSD_TYPE_COMMAND_LIST:      LOG_WARN( "There is no PBC 'default' selection here" );      return false;    }#endif /* LIBVCD_VERSION (< 0.7.21) */      } else {    /* PBC is not on. "default" selection beginning of current        selection . */      itemid.num = p_vcdplayer->play_item.num;      }  /** ??? p_vcdplayer->update_title(); ***/  vcdplayer_play( p_access, itemid );  return VLC_SUCCESS;}/*!  Play item assocated with the "next" selection.  Return false if there was some problem.*/bool vcdplayer_play_next( access_t * p_access ){  vcdplayer_t *p_vcdplayer= (vcdplayer_t *)p_access->p_sys;  vcdinfo_obj_t     *p_vcdinfo;  vcdinfo_itemid_t   itemid;  if (!p_vcdplayer) return false;  dbg_print( (INPUT_DBG_CALL|INPUT_DBG_PBC), 	     "current: %d" , p_vcdplayer->play_item.num);  p_vcdinfo = p_vcdplayer->vcd;  itemid = p_vcdplayer->play_item;  if  (vcdplayer_pbc_is_on(p_vcdplayer)) {    vcdinfo_lid_get_pxd(p_vcdinfo, &(p_vcdplayer->pxd), p_vcdplayer->i_lid);        switch (p_vcdplayer->pxd.descriptor_type) {    case PSD_TYPE_SELECTION_LIST:    case PSD_TYPE_EXT_SELECTION_LIST:      if (p_vcdplayer->pxd.psd == NULL) return false;      vcdplayer_update_entry( p_access, 			      vcdinf_psd_get_next_offset(p_vcdplayer->pxd.psd), 			      &itemid.num, "next");      itemid.type = VCDINFO_ITEM_TYPE_LID;      break;    case PSD_TYPE_PLAY_LIST:       if (p_vcdplayer->pxd.pld == NULL) return false;      vcdplayer_update_entry( p_access, 			      vcdinf_pld_get_next_offset(p_vcdplayer->pxd.pld), 			      &itemid.num, "next");      itemid.type = VCDINFO_ITEM_TYPE_LID;      break;          case PSD_TYPE_END_LIST:    case PSD_TYPE_COMMAND_LIST:      LOG_WARN( "There is no PBC 'next' selection here" );      return false;    }  } else {    /* PBC is not on. "Next" selection is play_item.num+1 if possible. */      int max_entry = 0;    switch (p_vcdplayer->play_item.type) {    case VCDINFO_ITEM_TYPE_ENTRY:     case VCDINFO_ITEM_TYPE_SEGMENT:     case VCDINFO_ITEM_TYPE_TRACK:             switch (p_vcdplayer->play_item.type) {      case VCDINFO_ITEM_TYPE_ENTRY: 	max_entry = p_vcdplayer->i_entries;	break;      case VCDINFO_ITEM_TYPE_SEGMENT: 	max_entry = p_vcdplayer->i_segments;	break;      case VCDINFO_ITEM_TYPE_TRACK: 	max_entry = p_vcdplayer->i_tracks;	break;      default: ; /* Handle exceptional cases below */      }            if (p_vcdplayer->play_item.num+1 < max_entry) {	itemid.num = p_vcdplayer->play_item.num+1;      } else {	LOG_WARN( "At the end - non-PBC 'next' not possible here" );	return false;      }            break;          case VCDINFO_ITEM_TYPE_LID:       {	/* Should have handled above. */	LOG_WARN( "Internal inconsistency - should not have gotten here." );	return false;      }    default:       return false;    }  }  /** ??? p_vcdplayer->update_title(); ***/  vcdplayer_play( p_access, itemid );  return VLC_SUCCESS;}/*!  Play item assocated with the "prev" selection.  Return false if there was some problem.*/bool vcdplayer_play_prev( access_t * p_access ){  vcdplayer_t      *p_vcdplayer= (vcdplayer_t *)p_access->p_sys;  vcdinfo_obj_t    *p_vcdinfo  = p_vcdplayer->vcd;  vcdinfo_itemid_t  itemid;  dbg_print( (INPUT_DBG_CALL|INPUT_DBG_PBC), 	     "current: %d" , p_vcdplayer->play_item.num);  itemid = p_vcdplayer->play_item;  if  (vcdplayer_pbc_is_on(p_vcdplayer)) {    vcdinfo_lid_get_pxd(p_vcdinfo, &(p_vcdplayer->pxd), p_vcdplayer->i_lid);        switch (p_vcdplayer->pxd.descriptor_type) {    case PSD_TYPE_SELECTION_LIST:    case PSD_TYPE_EXT_SELECTION_LIST:      if (p_vcdplayer->pxd.psd == NULL) return false;      vcdplayer_update_entry( p_access, 			      vcdinf_psd_get_prev_offset(p_vcdplayer->pxd.psd), 			      &itemid.num, "prev");      itemid.type = VCDINFO_ITEM_TYPE_LID;      break;    case PSD_TYPE_PLAY_LIST:       if (p_vcdplayer->pxd.pld == NULL) return false;      vcdplayer_update_entry( p_access, 			      vcdinf_pld_get_prev_offset(p_vcdplayer->pxd.pld), 			      &itemid.num, "prev");      itemid.type = VCDINFO_ITEM_TYPE_LID;      break;          case PSD_TYPE_END_LIST:    case PSD_TYPE_COMMAND_LIST:      LOG_WARN( "There is no PBC 'prev' selection here" );      return false;    }  } else {    /* PBC is not on. "Prev" selection is play_item.num-1 if possible. */      int min_entry = (VCDINFO_ITEM_TYPE_ENTRY == p_vcdplayer->play_item.type)       ? 0 : 1;        if (p_vcdplayer->play_item.num > min_entry) {      itemid.num = p_vcdplayer->play_item.num-1;    } else {      LOG_WARN( "At the beginning - non-PBC 'prev' not possible here" );      return false;    }        }  /** ??? p_vcdplayer->update_title(); ***/  vcdplayer_play( p_access, itemid );  return VLC_SUCCESS;}/*!  Play item assocated with the "return" selection.  Return false if there was some problem.*/bool vcdplayer_play_return( access_t * p_access ){  vcdplayer_t      *p_vcdplayer= (vcdplayer_t *)p_access->p_sys;  vcdinfo_obj_t    *p_vcdinfo  = p_vcdplayer->vcd;  vcdinfo_itemid_t  itemid;  dbg_print( (INPUT_DBG_CALL|INPUT_DBG_PBC), 	     "current: %d" , p_vcdplayer->play_item.num);  itemid = p_vcdplayer->play_item;  if  (vcdplayer_pbc_is_on(p_vcdplayer)) {    vcdinfo_lid_get_pxd(p_vcdinfo, &(p_vcdplayer->pxd), p_vcdplayer->i_lid);        switch (p_vcdplayer->pxd.descriptor_type) {    case PSD_TYPE_SELECTION_LIST:    case PSD_TYPE_EXT_SELECTION_LIST:      if (p_vcdplayer->pxd.psd == NULL) return false;      vcdplayer_update_entry( p_access, 			      vcdinf_psd_get_return_offset(p_vcdplayer->pxd.psd), 			      &itemid.num, "return");      itemid.type = VCDINFO_ITEM_TYPE_LID;      break;    case PSD_TYPE_PLAY_LIST:       if (p_vcdplayer->pxd.pld == NULL) return false;      vcdplayer_update_entry( p_access, 			      vcdinf_pld_get_return_offset(p_vcdplayer->pxd.pld), 			      &itemid.num, "return");      itemid.type = VCDINFO_ITEM_TYPE_LID;      break;          case PSD_TYPE_END_LIST:    case PSD_TYPE_COMMAND_LIST:      LOG_WARN( "There is no PBC 'return' selection here" );      return false;    }  } else {    /* PBC is not on. "Return" selection is min_entry if possible. */      p_vcdplayer->play_item.num =       (VCDINFO_ITEM_TYPE_ENTRY == p_vcdplayer->play_item.type)       ? 0 : 1;      }  /** ??? p_vcdplayer->update_title(); ***/  vcdplayer_play( p_access, itemid );  return VLC_SUCCESS;}/*  * Local variables: *  c-file-style: "gnu" *  tab-width: 8 *  indent-tabs-mode: nil * End: */

⌨️ 快捷键说明

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