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

📄 xineplug_inp_vcd.c

📁 linux下的MPEG1
💻 C
📖 第 1 页 / 共 5 页
字号:
  if (vcdinfo_get_lot(vcdplayer->vcd)) {    for (n=0; n<vcdplayer->i_lids; n++) {      uint16_t ofs = vcdinf_get_lot_offset(vcdinfo_get_lot(vcdplayer->vcd), n);      if (ofs != PSD_OFS_DISABLED || vcdplayer->show_rejected) {        memset(&mrl, 0, sizeof (mrl));        snprintf(mrl, sizeof(mrl), "%s%s@P%u%s", MRL_PREFIX, vcd_device, n+1,                 ofs == PSD_OFS_DISABLED ? "*" : "");        vcd_add_mrl_slot(class, mrl, 0, &i);        class->mrl_segment_offset++;      }    }  }  /* Record MRL's for segments */  {    segnum_t i_segments = vcdplayer->i_segments;    for (n=0; n<i_segments; n++) {      vcdinfo_video_segment_type_t segtype         = vcdinfo_get_video_type(p_vcdinfo, n);      char c='S';      switch (segtype) {        {        case VCDINFO_FILES_VIDEO_NTSC_STILL:        case VCDINFO_FILES_VIDEO_NTSC_STILL2:        case VCDINFO_FILES_VIDEO_NTSC_MOTION:          c='s';          break;        case VCDINFO_FILES_VIDEO_PAL_STILL:        case VCDINFO_FILES_VIDEO_PAL_STILL2:        case VCDINFO_FILES_VIDEO_PAL_MOTION:          c='S';          break;        default: ;        }      }      memset(&mrl, 0, sizeof (mrl));      snprintf(mrl, sizeof(mrl), "%s%s@%c%u", MRL_PREFIX, vcd_device, c, n);      vcd_add_mrl_slot(class, mrl, vcdplayer->segment[n].size, &i);    }  }    dbg_print(INPUT_DBG_MRL,             "offsets are track: %d, entry: %d, play: %d seg: %d\n",             class->mrl_track_offset, class->mrl_entry_offset,             class->mrl_play_offset,  class->mrl_segment_offset);  return true;}/*!  parses a MRL which has the format   vcd://[vcd_path][@[EPTS]?number]\*?   Examples    vcd://                    - Play (navigate) default device: /dev/cdrom    vcd://@                   - same as above    vcd:///dev/cdrom          - probably same as above    vcd:///dev/cdrom2         - Play (navigate) /dev/cdrom2    vcd:///dev/cdrom2@        - same as above    vcd:///dev/cdrom2@T1      - Play Track 1 from /dev/cdrom2    vcd:///dev/cdrom@S1       - Play selection id 1 from /dev/cdrom    vcd://dev/cdrom@E0        - Play Entry id 0 from default device    vcd://@P1                 - probably same as above.                                 If there is no playback control, MRL will  			         get converted into vcd://@E0    vcd://@P1*                - probably same as above.    vcd://@S0                 - Play segment 0 from default device    vcd://@3                  - Play track 3 from default device    vcd:///dev/cdrom2@1       - Play track 1 from /dev/cdrom2    vcd:///tmp/ntsc.bin@      - Play default item from /tmp/ntsc.bin    vcd:///tmp/ntsc.bin/@E0   - Play entry 0 of /tmp/ntsc.binparameters:   mrl               : mrl to parse  default_vcd_device: name of device to use when none given  auto_type         : type of selection (entry, track, LID) when none given  used_default      : true iff auto_type was used. */static boolvcd_parse_mrl(/*in*/ const char *default_vcd_device, /*in*/ char *mrl,               /*out*/ char *device_str, /*out*/ vcdinfo_itemid_t *itemid,              /*in */ vcdplayer_autoplay_t auto_type,               /*out*/ bool *used_default) {  char type_str[2];  int count;  char *p;  unsigned int num = 0;  dbg_print(INPUT_DBG_CALL, "called mrl %s\n", mrl);  type_str[0]   ='\0';  itemid->type  = (vcdinfo_item_enum_t) auto_type;  *used_default = false;  if ( NULL == mrl || strncasecmp(mrl, MRL_PREFIX, MRL_PREFIX_LEN) )    return false;  p = &mrl[MRL_PREFIX_LEN - 2];  while (*p == '/')    ++p;  device_str[0] = '/';  device_str[1] = 0;  count = sscanf (p, "%1023[^@]@%1[EePpSsTt]%u", 		  device_str + 1, type_str, &num);  itemid->num = num;    switch (count) {  case 1:    /* Matched device, but nothing beyond that */    if (strlen(device_str)!=0 && device_str[0] != ':') {      /* See if we have old-style MRL with no type specifier.          If so, we assume "track". */      count = sscanf (p, "%u", &num);      itemid->num = num;      if (1==count) {        type_str[0] = 'T';        if (default_vcd_device)          strncpy(device_str, default_vcd_device, MAX_DEVICE_LEN);        else          *device_str = 0;      }      else        _x_mrl_unescape (device_str);      break;    }  case 2 ... 9:    _x_mrl_unescape (device_str);  case 0:  case EOF:     {      /* No device/file given, so use the default device and try again. */      if (NULL == default_vcd_device) return false;      strncpy(device_str, default_vcd_device, MAX_DEVICE_LEN);      if (p[0] == '@') p++;      count = sscanf (p, "%1[EePpSsTt]%u", type_str, &num);      type_str[0] = toupper(type_str[0]);      itemid->num = num;            switch (count) {      case EOF:	/* Default PBC navigation. */        return true;      case 0:        /* See if we have old-style MRL with no type specifier.            If so, we assume "track". */        count = sscanf (p, "%u", &num);        if (1==count) {           type_str[0] = 'T';          break;        }	/* Default PBC navigation. */	return true;      case 1:        /* Type given, but no number. Entries start at 0, other things           start at 1 */	if (type_str[0] == 'P' || type_str[0] == 'T') itemid->num = 1;      }    }  }  /* We have some sort of track/selection/entry number */  switch (type_str[0]) {  case 'E':     itemid->type = VCDINFO_ITEM_TYPE_ENTRY;    break;  case '\0':     /* None specified, use config value. */    itemid->type = (vcdinfo_item_enum_t) auto_type;    *used_default = true;    break;  case 'P':     itemid->type = VCDINFO_ITEM_TYPE_LID;    break;  case 'S':     itemid->type = VCDINFO_ITEM_TYPE_SEGMENT;    break;  case 'T':     itemid->type = VCDINFO_ITEM_TYPE_TRACK;    break;  default: ;  }    if ( 0==itemid->num        && ( (VCDINFO_ITEM_TYPE_LID == itemid->type)             || (VCDINFO_ITEM_TYPE_TRACK == itemid->type) ) )    itemid->num = 1;  return true;}/*!   From xine plugin spec:  return capabilities of input source*/static uint32_t vcd_plugin_get_capabilities (input_plugin_t *this_gen){  uint32_t ret =     INPUT_CAP_AUDIOLANG | INPUT_CAP_BLOCK     |     INPUT_CAP_CHAPTERS  | INPUT_CAP_PREVIEW   |    (my_vcd.player.i_still ? 0: INPUT_CAP_SEEKABLE) |    INPUT_CAP_SPULANG;  dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT), "returning %d\n", ret);  vcd_handle_events();  return ret;}# if FINISHED/* If needed, will fill out later... */static void vcd_read_ahead_cb(void *this_gen, xine_cfg_entry_t *entry){   return;}#endifstatic void vcd_flush_buffers(void){  _x_demux_flush_engine(my_vcd.stream);}/*!  From xine plugin spec:  read nlen bytes, return number of bytes read.*/static off_t vcd_plugin_read (input_plugin_t *this_gen, char *buf, const off_t nlen){  dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT),             "Called with nlen %u\n", (unsigned int) nlen);  /* FIXME: Tricking the demux_mpeg_block plugin */  buf[0] = 0;  buf[1] = 0;  buf[2] = 0x01;  buf[3] = 0xba;  return (off_t) 1;}/* Allocate and return a no-op buffer. This signals the outside   to do nothing, but in contrast to returning NULL, it doesn't    mean the stream has ended. We use this say for still frames. */#define RETURN_NOOP_BUF                                    \  p_buf = fifo->buffer_pool_alloc (fifo);                  \  p_buf->type = BUF_CONTROL_NOP;                           \  return p_buf/* Handle keyboard events and if there were non which might affect   playback, then sleep a little bit and return; */#define SLEEP_AND_HANDLE_EVENTS                          \  xine_usec_sleep(50000);                                \  if (vcd_handle_events()) goto read_block;              \  RETURN_NOOP_BUF/*!  From xine plugin spec:  read one block, return newly allocated block (or NULL on failure)  for blocked input sources len must be == blocksize the fifo  parameter is only used to get access to the buffer_pool_alloc  function*/static buf_element_t *vcd_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo,                        const off_t i_len) {  vcd_input_plugin_t *vcd_input_plugin= (vcd_input_plugin_t *) this_gen;  vcdplayer_t   *p_vcdplayer = &my_vcd.player;  buf_element_t *p_buf;  uint8_t        data[M2F2_SECTOR_SIZE] = {0};  if (fifo == NULL) {    dbg_print(INPUT_DBG_CALL, "NULL fifo");    return NULL;  }  dbg_print(INPUT_DBG_CALL, "Called with i_len %u\n", (unsigned int) i_len);  /* Should we change this to <= instead of !=? */  if (i_len != M2F2_SECTOR_SIZE) return NULL;  /* If VCD isn't open, we need to open it now. */  if (!p_vcdplayer->b_opened) {    if (!vcdio_open(p_vcdplayer, my_vcd.player_device)) {      return NULL;    }  }  if (vcd_handle_events()) goto read_block;  if (p_vcdplayer->i_still > 0) {    if ( time(NULL) >= vcd_input_plugin->pause_end_time ) {      if (STILL_INDEFINITE_WAIT == p_vcdplayer->i_still) {        dbg_print(INPUT_DBG_STILL, "Continuing still indefinite wait time\n");        vcd_input_plugin->pause_end_time = time(NULL) + p_vcdplayer->i_still;        SLEEP_AND_HANDLE_EVENTS;      } else {        dbg_print(INPUT_DBG_STILL, "Still time ended\n");        p_vcdplayer->i_still = 0;      }    } else {      SLEEP_AND_HANDLE_EVENTS;    }  }   read_block:  switch (vcdplayer_read(p_vcdplayer, data, i_len)) {  case READ_END:    /* End reached. Return NULL to indicated this. */    return NULL;  case READ_ERROR:    /* Some sort of error. */    return NULL;  case READ_STILL_FRAME:     {      dbg_print(INPUT_DBG_STILL, "Handled still event wait time %u\n",                p_vcdplayer->i_still);      vcd_input_plugin->pause_end_time = time(NULL) + p_vcdplayer->i_still;      RETURN_NOOP_BUF;    }      default:  case READ_BLOCK:    /* Read buffer */    p_buf = fifo->buffer_pool_alloc (fifo);    p_buf->type = BUF_DEMUX_BLOCK;  }    p_buf->content = p_buf->mem;  if (STILL_READING == p_vcdplayer->i_still && 0 == my_vcd.i_old_still) {    my_vcd.i_old_deinterlace = xine_get_param(my_vcd.stream,                                               XINE_PARAM_VO_DEINTERLACE);    xine_set_param(my_vcd.stream, XINE_PARAM_VO_DEINTERLACE, 0);    dbg_print(INPUT_DBG_STILL, "going into still, saving deinterlace %d\n",               my_vcd.i_old_deinterlace);  } else if (0 == p_vcdplayer->i_still && 0 != my_vcd.i_old_still) {    dbg_print(INPUT_DBG_STILL,               "going out of still, restoring deinterlace\n");    xine_set_param(my_vcd.stream, XINE_PARAM_VO_DEINTERLACE,                   my_vcd.i_old_deinterlace);  }  my_vcd.i_old_still = p_vcdplayer->i_still;    /* Ideally this should probably be i_len.  */  memcpy (p_buf->mem, data, M2F2_SECTOR_SIZE);  return p_buf;}/*!  From xine plugin spec:  seek position, return new position   if seeking failed, -1 is returned*/static off_t vcd_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) {  return vcdio_seek (&my_vcd.player, offset, origin);}/*!  From xine plugin spec:  return length of input (-1 => unlimited, e.g. stream)  length size is bytes.*/static vcdinfo_itemid_t old_play_item = {VCDINFO_ITEM_TYPE_NOTFOUND, 0};static off_t old_get_length = 0;static vcdplayer_slider_length_t old_slider_length;/* This routine is called a bit. Make reasonably fast. */static off_t vcd_plugin_get_length (input_plugin_t *this_gen) {  vcd_input_plugin_t *ip= (vcd_input_plugin_t *) this_gen;  vcdplayer_t        *vcdplayer = &(ip->player);  int n = vcdplayer->play_item.num;  if (vcdplayer->play_item.num == old_play_item.num      && vcdplayer->play_item.type == old_play_item.type       && vcdplayer->slider_length == old_slider_length)    return old_get_length;  old_slider_length = vcdplayer->slider_length;  old_play_item     = vcdplayer->play_item;

⌨️ 快捷键说明

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