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

📄 info.c

📁 linux下的MPEG1
💻 C
📖 第 1 页 / 共 4 页
字号:
/*!  Return true is there is playback control. */boolvcdinfo_has_pbc (const vcdinfo_obj_t *obj) {  return (obj && obj->info.psd_size!=0);}  /*!   Return true if VCD has "extended attributes" (XA). Extended attributes  add meta-data attributes to a entries of file describing the file.  See also cdio_get_xa_attr_str() which returns a string similar to  a string you might get on a Unix filesystem listing ("ls").*/boolvcdinfo_has_xa(const vcdinfo_obj_t *obj) {  return obj->has_xa;}/*!  Add one to the MSF.*/voidvcdinfo_inc_msf (uint8_t *min, uint8_t *sec, int8_t *frame){  (*frame)++;  if (*frame>=CDIO_CD_FRAMES_PER_SEC) {    *frame = 0;    (*sec)++;    if (*sec>=CDIO_CD_SECS_PER_MIN) {      *sec = 0;      (*min)++;    }  }}/*!  Convert minutes, seconds and frame (MSF components) into a  logical block address (or LBA).   See also cdio_msf_to_lba which uses msf_t as its single parameter.*/lba_tvcdinfo_msf2lba (uint8_t min, uint8_t sec, int8_t frame){  return CDIO_CD_FRAMES_PER_SEC*(CDIO_CD_SECS_PER_MIN*min + sec) + frame;}/*!  Convert minutes, seconds and frame (MSF components) into a  logical block address (or LBA).   See also cdio_msf_to_lba which uses msf_t as its single parameter.*/void vcdinfo_lba2msf (lba_t lba, uint8_t *min, uint8_t *sec, uint8_t *frame) {  *min = lba / (60*75);  lba %= (60*75);  *sec = lba / 75;   *frame = lba % 75; }/*!  Convert minutes, seconds and frame (MSF components) into a  logical sector number (or LSN). */lsn_tvcdinfo_msf2lsn (uint8_t min, uint8_t sec, int8_t frame){  lba_t lba=75*(60*min + sec) + frame;  if (lba < CDIO_PREGAP_SECTORS) {    vcd_error ("lba (%u) less than pregap sector (%u)",                (unsigned int) lba, CDIO_PREGAP_SECTORS);    return lba;  }  return lba - CDIO_PREGAP_SECTORS;}const char *vcdinfo_ofs2str (const vcdinfo_obj_t *obj, unsigned int offset, bool ext){  vcdinfo_offset_t *ofs;  char *buf;  switch (offset) {  case PSD_OFS_DISABLED:    return "disabled";  case PSD_OFS_MULTI_DEF:    return "multi-default";  case PSD_OFS_MULTI_DEF_NO_NUM:    return "multi_def_no_num";  default: ;  }  buf = _getbuf ();  ofs = _vcdinfo_get_offset_t(obj, offset, ext);  if (ofs != NULL) {    if (ofs->lid)      snprintf (buf, BUF_SIZE, "LID[%d] @0x%4.4x",                 ofs->lid, ofs->offset);    else       snprintf (buf, BUF_SIZE, "PSD[?] @0x%4.4x",                 ofs->offset);  } else {    snprintf (buf, BUF_SIZE, "? @0x%4.4x", offset);  }  return buf;}boolvcdinfo_read_psd (vcdinfo_obj_t *obj){  unsigned psd_size = vcdinfo_get_psd_size (obj);  if (psd_size)    {      if (psd_size > 256*1024)        {          vcd_error ("weird psd size (%u) -- aborting", psd_size);          return false;        }      obj->lot = _vcd_malloc (ISO_BLOCKSIZE * LOT_VCD_SIZE);      obj->psd = _vcd_malloc (ISO_BLOCKSIZE * _vcd_len2blocks (psd_size,                                                                ISO_BLOCKSIZE));            if (cdio_read_mode2_sectors (obj->img, (void *) obj->lot, LOT_VCD_SECTOR,                                   false, LOT_VCD_SIZE))        return false;                if (cdio_read_mode2_sectors (obj->img, (void *) obj->psd, PSD_VCD_SECTOR,                                   false, _vcd_len2blocks (psd_size,                                                            ISO_BLOCKSIZE)))        return false;      } else {      return false;    }  return true;}/*!  Return the entry number for the given track.  */unsigned int vcdinfo_track_get_entry(const vcdinfo_obj_t *obj, track_t i_track) {  /* FIXME: Add structure to directly map track to first entry number.      Until then...   */  lsn_t lsn= vcdinfo_get_track_lsn(obj, i_track);  return vcdinfo_lsn_get_entry(obj, lsn);}  /*!   Calls recursive routine to populate obj->offset_list or obj->offset_x_list   by going through LOT.   Returns false if there was some error.*/boolvcdinfo_visit_lot (vcdinfo_obj_t *obj, bool extended){  struct _vcdinf_pbc_ctx pbc_ctx;  bool ret;  pbc_ctx.psd_size      = vcdinfo_get_psd_size (obj);  pbc_ctx.psd_x_size    = obj->psd_x_size;  pbc_ctx.offset_mult   = 8;  pbc_ctx.maximum_lid   = vcdinfo_get_num_LIDs(obj);  pbc_ctx.offset_x_list = NULL;  pbc_ctx.offset_list   = NULL;  pbc_ctx.psd           = obj->psd;  pbc_ctx.psd_x         = obj->psd_x;  pbc_ctx.lot           = obj->lot;  pbc_ctx.lot_x         = obj->lot_x;  pbc_ctx.extended      = extended;  ret = vcdinf_visit_lot(&pbc_ctx);  if (NULL != obj->offset_x_list)     _cdio_list_free(obj->offset_x_list, true);  obj->offset_x_list = pbc_ctx.offset_x_list;  if (NULL != obj->offset_list)     _cdio_list_free(obj->offset_list, true);  obj->offset_list   = pbc_ctx.offset_list;  return ret;}/*!   Change trailing blanks in str to nulls.  Str has a maximum size of   n characters.*/const char *vcdinfo_strip_trail (const char str[], size_t n){  static char buf[1025];  int j;  vcd_assert (n < 1024);  strncpy (buf, str, n);  buf[n] = '\0';  for (j = strlen (buf) - 1; j >= 0; j--)    {      if (buf[j] != ' ')        break;      buf[j] = '\0';    }  return buf;}/*! Return true if offset is "rejected". That is shouldn't be displayed in a list of entries.*/boolvcdinfo_is_rejected(uint16_t offset){  return (offset & VCDINFO_REJECTED_MASK) != 0;}/*!   Nulls/zeros vcdinfo_obj_t structures; The caller should have    ensured that obj != NULL.   routines using obj are called.*/static void_vcdinfo_zero(vcdinfo_obj_t *obj){  memset(obj, 0, sizeof(vcdinfo_obj_t));  obj->vcd_type = VCD_TYPE_INVALID;  obj->img = NULL;  obj->lot = NULL;  obj->source_name = NULL;  obj->seg_sizes = NULL;}/*!   Initialize the vcdinfo structure "obj". Should be done before other   routines using obj are called.*/bool vcdinfo_init(vcdinfo_obj_t *obj){  if (NULL == obj) return false;  _vcdinfo_zero(obj);  return cdio_init();}/*!   Set up vcdinfo structure "obj" for reading from a particular   medium. This should be done before after initialization but before   any routines that need to retrieve data.    source_name is the device or file to use for inspection, and   source_type indicates what driver to use or class of drivers in the   case of DRIVER_DEVICE.   access_mode gives the CD access method for reading should the driver   allow for more than one kind of access method (e.g. MMC versus ioctl   on GNU/Linux)       If source_name is NULL we'll fill in the appropriate default device   name for the given source_type. However if in addtion source_type is   DRIVER_UNKNOWN, then we'll scan for a drive containing a VCD.       VCDINFO_OPEN_VCD is returned if everything went okay;    VCDINFO_OPEN_ERROR if there was an error and VCDINFO_OPEN_OTHER if the   medium is something other than a VCD. */vcdinfo_open_return_tvcdinfo_open(vcdinfo_obj_t **obj_p, char *source_name[],              driver_id_t source_type, const char access_mode[]){  CdIo *img;  vcdinfo_obj_t *obj = _vcd_malloc(sizeof(vcdinfo_obj_t));  iso9660_stat_t *statbuf;  /* If we don't specify a driver_id or a source_name, scan the     system for a CD that contains a VCD.   */  if (NULL == *source_name && source_type == DRIVER_UNKNOWN) {    char **cd_drives=NULL;    cd_drives = cdio_get_devices_with_cap_ret(NULL,                 (CDIO_FS_ANAL_SVCD|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_VIDEOCD                |CDIO_FS_UNKNOWN),                                              true, &source_type);    if ( NULL == cd_drives || NULL == cd_drives[0] ) {      return VCDINFO_OPEN_ERROR;    }    *source_name = strdup(cd_drives[0]);    cdio_free_device_list(cd_drives);  }  img = cdio_open(*source_name, source_type);  if (NULL == img) {    return VCDINFO_OPEN_ERROR;  }  *obj_p = obj;    if (access_mode != NULL)     cdio_set_arg (img, "access-mode", access_mode);  if (NULL == *source_name) {    *source_name = cdio_get_default_device(img);    if (NULL == *source_name) return VCDINFO_OPEN_ERROR;  }      memset (obj, 0, sizeof (vcdinfo_obj_t));  obj->img = img;  /* Note we do this after the above wipeout! */  if (!iso9660_fs_read_pvd(obj->img, &(obj->pvd))) {    return VCDINFO_OPEN_ERROR;  }    /* Determine if VCD has XA attributes. */  {        iso9660_pvd_t const *pvd = &obj->pvd;        obj->has_xa = !strncmp ((char *) pvd + ISO_XA_MARKER_OFFSET,                             ISO_XA_MARKER_STRING,                            strlen (ISO_XA_MARKER_STRING));  }      if (!read_info(obj->img, &(obj->info), &(obj->vcd_type)) ||      vcdinfo_get_format_version (obj) == VCD_TYPE_INVALID ||      !read_entries(obj->img, &(obj->entries))) {    free (obj); /* match 0.7.23's behaviour */    return VCDINFO_OPEN_OTHER;  }    {    size_t len = strlen(*source_name)+1;    obj->source_name = (char *) malloc(len * sizeof(char));    strncpy(obj->source_name, *source_name, len);  }  if (obj->vcd_type == VCD_TYPE_SVCD || obj->vcd_type == VCD_TYPE_HQVCD) {    statbuf = iso9660_fs_stat (obj->img, "MPEGAV");        if (NULL != statbuf) {      vcd_warn ("non compliant /MPEGAV folder detected!");      free(statbuf);    }        statbuf = iso9660_fs_stat (obj->img, "SVCD/TRACKS.SVD;1");    if (NULL != statbuf) {      lsn_t lsn = statbuf->lsn;      if (statbuf->size != ISO_BLOCKSIZE)        vcd_warn ("TRACKS.SVD filesize != %d!", ISO_BLOCKSIZE);            obj->tracks_buf = _vcd_malloc (ISO_BLOCKSIZE);      free(statbuf);      if (cdio_read_mode2_sector (obj->img, obj->tracks_buf, lsn, false))        return VCDINFO_OPEN_ERROR;    }  }        _init_segments (obj);  switch (obj->vcd_type) {  case VCD_TYPE_VCD2: {    /* FIXME: Can reduce CD reads by using        iso9660_fs_readdir(img, "EXT", true) and then scanning for       the files listed below.    */    statbuf = iso9660_fs_stat (img, "EXT/PSD_X.VCD;1");    if (NULL != statbuf) {      lsn_t lsn        = statbuf->lsn;      uint32_t secsize = statbuf->secsize;      obj->psd_x       = _vcd_malloc (ISO_BLOCKSIZE * secsize);      obj->psd_x_size  = statbuf->size;            vcd_debug ("found /EXT/PSD_X.VCD at sector %lu",                  (long unsigned int) lsn);      free(statbuf);      if (cdio_read_mode2_sectors (img, obj->psd_x, lsn, false, secsize))        return VCDINFO_OPEN_ERROR;    }    statbuf = iso9660_fs_stat (img, "EXT/LOT_X.VCD;1");    if (NULL != statbuf) {      lsn_t lsn        = statbuf->lsn;      uint32_t secsize = statbuf->secsize;      obj->lot_x       = _vcd_malloc (ISO_BLOCKSIZE * secsize);            vcd_debug ("found /EXT/LOT_X.VCD at sector %lu",                  (unsigned long int) lsn);              if (statbuf->size != LOT_VCD_SIZE * ISO_BLOCKSIZE)        vcd_warn ("LOT_X.VCD size != 65535");      free(statbuf);      if (cdio_read_mode2_sectors (img, obj->lot_x, lsn, false, secsize))        return VCDINFO_OPEN_ERROR;          }    break;  }  case VCD_TYPE_SVCD:   case VCD_TYPE_HQVCD: {    /* FIXME: Can reduce CD reads by using        iso9660_fs_readdir(img, "SVCD", true) and then scanning for       the files listed below.    */    statbuf = iso9660_fs_stat (img, "MPEGAV");    if (NULL != statbuf) {      vcd_warn ("non compliant /MPEGAV folder detected!");      free(statbuf);    }        statbuf = iso9660_fs_stat (img, "SVCD/TRACKS.SVD;1");    if (NULL == statbuf)      vcd_warn ("mandatory /SVCD/TRACKS.SVD not found!");    else {      vcd_debug ("found TRACKS.SVD signature at sector %lu",                  (unsigned long int) statbuf->lsn);      free(statbuf);    }        statbuf = iso9660_fs_stat (img, "SVCD/SEARCH.DAT;1");    if (NULL == statbuf)      vcd_warn ("mandatory /SVCD/SEARCH.DAT not found!");    else {      lsn_t    lsn       = statbuf->lsn;      uint32_t secsize   = statbuf->secsize;      uint32_t stat_size = statbuf->size;      uint32_t size;      vcd_debug ("found SEARCH.DAT at sector %lu", (unsigned long int) lsn);            obj->search_buf = _vcd_malloc (ISO_BLOCKSIZE * secsize);            if (cdio_read_mode2_sectors (img, obj->search_buf, lsn, false, secsize))        return VCDINFO_OPEN_ERROR;            size = (3 * uint16_from_be (((SearchDat *)obj->search_buf)->scan_points))        + sizeof (SearchDat);      free(statbuf);      if (size > stat_size) {        vcd_warn ("number of scanpoints leads to bigger size than "                  "file size of SEARCH.DAT! -- rereading");                free (obj->search_buf);        obj->search_buf = _vcd_malloc (ISO_BLOCKSIZE                                        * _vcd_len2blocks(size, ISO_BLOCKSIZE));                if (cdio_read_mode2_sectors (img, obj->search_buf, lsn, false,                                      secsize))          return VCDINFO_OPEN_ERROR;      }    }    break;    }  default:    ;  }  statbuf = iso9660_fs_stat (img, "EXT/SCANDATA.DAT;1");  if (statbuf != NULL) {    lsn_t    lsn       = statbuf->lsn;    uint32_t secsize   = statbuf->secsize;    vcd_debug ("found /EXT/SCANDATA.DAT at sector %u", (unsigned int) lsn);        obj->scandata_buf = _vcd_malloc (ISO_BLOCKSIZE * secsize);    free(statbuf);    if (cdio_read_mode2_sectors (img, obj->scandata_buf, lsn, false, secsize))      return VCDINFO_OPEN_ERROR;  }  return VCDINFO_OPEN_VCD;  }/*! Dispose of any resources associated with vcdinfo structure "obj". Call this when "obj" it isn't needed anymore.  True is returned is everything went okay, and false if not.*/bool vcdinfo_close(vcdinfo_obj_t *obj){  if (obj != NULL) {    if (obj->offset_list != NULL)       _cdio_list_free(obj->offset_list, true);    if (obj->offset_x_list != NULL)       _cdio_list_free(obj->offset_x_list, true);    free(obj->seg_sizes);    free(obj->lot);    free(obj->lot_x);    if (obj->psd_x) free(obj->psd_x);    if (obj->psd)   free(obj->psd);    if (obj->scandata_buf) free(obj->scandata_buf);    free(obj->tracks_buf);    free(obj->search_buf);    free(obj->source_name);    if (obj->img != NULL) cdio_destroy (obj->img);    _vcdinfo_zero(obj);  }    free(obj);  return(true);}/*  * Local variables: *  c-file-style: "gnu" *  tab-width: 8 *  indent-tabs-mode: nil * End: */

⌨️ 快捷键说明

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