📄 info.c
字号:
*/static bool_vcdinfo_lid_get_pxd(const vcdinfo_obj_t *obj, PsdListDescriptor_t *pxd, uint16_t lid, bool ext) { CdioListNode *node; unsigned mult = obj->info.offset_mult; const uint8_t *psd = ext ? obj->psd_x : obj->psd; CdioList *offset_list = ext ? obj->offset_x_list : obj->offset_list; if (offset_list == NULL) return false; _CDIO_LIST_FOREACH (node, offset_list) { vcdinfo_offset_t *ofs = _cdio_list_node_data (node); unsigned _rofs = ofs->offset * mult; pxd->descriptor_type = psd[_rofs]; switch (pxd->descriptor_type) { case PSD_TYPE_PLAY_LIST: { pxd->pld = (PsdPlayListDescriptor_t *) (psd + _rofs); if (vcdinf_pld_get_lid(pxd->pld) == lid) { return true; } break; } case PSD_TYPE_EXT_SELECTION_LIST: case PSD_TYPE_SELECTION_LIST: { pxd->psd = (PsdSelectionListDescriptor_t *) (psd + _rofs); if (vcdinf_psd_get_lid(pxd->psd) == lid) { return true; } break; } default: ; } } return false;}/*! Get the PSD Selection List Descriptor for a given lid. False is returned if not found.*/boolvcdinfo_lid_get_pxd(const vcdinfo_obj_t *obj, PsdListDescriptor_t *pxd, uint16_t lid){ if (_vcdinfo_lid_get_pxd(obj, pxd, lid, true)) return true; return _vcdinfo_lid_get_pxd(obj, pxd, lid, false);}/** \fn vcdinfo_get_return_offset(const vcdinfo_obj_t *obj); \brief Get return offset for a given LID. \return VCDINFO_INVALID_OFFSET is returned on error or if LID has no "return" entry. Otherwise the LID offset is returned. */uint16_tvcdinfo_get_return_offset(const vcdinfo_obj_t *obj, lid_t lid){ if (NULL != obj) { PsdListDescriptor_t pxd; vcdinfo_lid_get_pxd(obj, &pxd, lid); switch (pxd.descriptor_type) { case PSD_TYPE_PLAY_LIST: return vcdinf_pld_get_return_offset(pxd.pld); case PSD_TYPE_SELECTION_LIST: case PSD_TYPE_EXT_SELECTION_LIST: return vcdinf_psd_get_return_offset(pxd.psd); break; case PSD_TYPE_END_LIST: case PSD_TYPE_COMMAND_LIST: break; } } return VCDINFO_INVALID_OFFSET;}/*! Return the audio type for a given segment. VCDINFO_INVALID_AUDIO_TYPE is returned on error.*/unsigned intvcdinfo_get_seg_audio_type(const vcdinfo_obj_t *obj, segnum_t seg_num){ if ( NULL == obj || NULL == &obj->info || seg_num >= vcdinfo_get_num_segments(obj) ) return VCDINFO_INVALID_AUDIO_TYPE; return(obj->info.spi_contents[seg_num].audio_type);}/*! Return true if this segment is supposed to continue to the next one, (is part of an "item" or listing in the ISO 9660 filesystem).*/boolvcdinfo_get_seg_continue(const vcdinfo_obj_t *obj, segnum_t seg_num){ if ( NULL == obj || NULL == &obj->info || seg_num >= vcdinfo_get_num_segments(obj) ) return false; return(obj->info.spi_contents[seg_num].item_cont);}/*! Return the starting LBA (logical block address) for segment entry_num in obj. VCDINFO_LBA_NULL is returned if there is no entry. Note first seg_num is 0.*/lba_tvcdinfo_get_seg_lba(const vcdinfo_obj_t *obj, segnum_t seg_num){ if (obj == NULL) return VCDINFO_NULL_LBA; return cdio_lsn_to_lba(vcdinfo_get_seg_lba(obj, seg_num));}/*! Return the starting LBA (logical block address) for segment entry_num in obj. VCDINFO_LSN_NULL is returned if there is no entry. Note first seg_num is 0.*/lsn_tvcdinfo_get_seg_lsn(const vcdinfo_obj_t *obj, segnum_t seg_num){ if (obj == NULL || seg_num >= vcdinfo_get_num_segments(obj)) return VCDINFO_NULL_LSN; return obj->first_segment_lsn + (VCDINFO_SEGMENT_SECTOR_SIZE * seg_num);}/*! Return the starting MSF (minutes/secs/frames) for segment entry_num in obj. NULL is returned if there is no entry. Note first seg_num is 0!*/const msf_t *vcdinfo_get_seg_msf(const vcdinfo_obj_t *obj, segnum_t seg_num){ if (obj == NULL || seg_num >= vcdinfo_get_num_segments(obj)) return NULL; else { lsn_t lsn = vcdinfo_get_seg_lsn(obj, seg_num); static msf_t msf; cdio_lsn_to_msf(lsn, &msf); return &msf; }}/*! Return the x-y resolution for a given segment. Note first i_seg is 0.*/voidvcdinfo_get_seg_resolution(const vcdinfo_obj_t *p_vcdinfo, segnum_t i_seg, /*out*/ uint16_t *max_x, /*out*/ uint16_t *max_y){ vcdinfo_video_segment_type_t segtype = vcdinfo_get_video_type(p_vcdinfo, i_seg); segnum_t i_segs = vcdinfo_get_num_segments(p_vcdinfo); if (i_seg >= i_segs) return; switch (segtype) { case VCDINFO_FILES_VIDEO_NTSC_STILL: *max_x = 704; *max_y = 480; break; case VCDINFO_FILES_VIDEO_NTSC_STILL2: *max_x = 352; *max_y = 240; break; case VCDINFO_FILES_VIDEO_PAL_STILL: *max_x = 704; *max_y = 576; break; case VCDINFO_FILES_VIDEO_PAL_STILL2: *max_x = 352; *max_y = 288; break; default: /* */ switch (vcdinfo_get_format_version(p_vcdinfo)) { case VCD_TYPE_VCD: *max_x = 352; *max_y = 240; break; case VCD_TYPE_VCD11: case VCD_TYPE_VCD2: *max_x = 352; switch(segtype) { case VCDINFO_FILES_VIDEO_NTSC_MOTION: *max_y = 240; break; case VCDINFO_FILES_VIDEO_PAL_MOTION: *max_y = 288; default: *max_y = 289; } break; default: ; } }}/*! Return the number of sectors for segment entry_num in obj. 0 is returned if there is no entry. Use this routine to figure out the actual number of bytes a physical region of a disk or CD takes up for a segment. If an item has been broken up into a number of "continued" segments, we will report the item size for the first segment and 0 for the remaining ones. We may revisit this decision later. */uint32_tvcdinfo_get_seg_sector_count(const vcdinfo_obj_t *obj, segnum_t seg_num){ if (obj == NULL || seg_num >= vcdinfo_get_num_segments(obj)) return 0; return obj->seg_sizes[seg_num];}/*! Return a string containing the VCD system id with trailing blanks removed, or NULL if there is some problem in getting this.*/const char *vcdinfo_get_system_id(const vcdinfo_obj_t *obj){ if ( NULL == obj || NULL == &obj->pvd ) return (NULL); return(iso9660_get_system_id(&obj->pvd));}/*! Return the track number for entry n in obj. In contrast to libcdio we start numbering at 0 which is the ISO9660 and metadata information for the Video CD. Thus track 1 is the first track the first complete MPEG track generally.*/track_tvcdinfo_get_track(const vcdinfo_obj_t *obj, const unsigned int entry_num){ const EntriesVcd_t *entries = &obj->entries; const unsigned int entry_count = vcdinf_get_num_entries(entries); /* Note entry_num is 0 origin. */ return entry_num < entry_count ? vcdinf_get_track(entries, entry_num)-1: VCDINFO_INVALID_TRACK;}/*! Return the audio type for a given track. VCDINFO_INVALID_AUDIO_TYPE is returned on error. Note: track 1 is usually the first track.*/unsigned intvcdinfo_get_track_audio_type(const vcdinfo_obj_t *obj, track_t track_num){ TracksSVD *tracks; TracksSVD2 *tracks2; if ( NULL == obj || NULL == &obj->info ) return VCDINFO_INVALID_AUDIO_TYPE; tracks = obj->tracks_buf; if ( NULL == tracks ) return 0; tracks2 = (TracksSVD2 *) &(tracks->playing_time[tracks->tracks]); return(tracks2->contents[track_num-1].audio);}/*! Return the highest track number in the current medium. Because we track start numbering at 0 (which is the ISO 9660 track containing Video CD naviagion and disk information), this is one less than the number of tracks. If there are no tracks, we return -1.*/unsigned intvcdinfo_get_num_tracks(const vcdinfo_obj_t *obj){ if (obj == NULL || obj->img == NULL) return 0; return cdio_get_num_tracks(obj->img)-1;}/*! Return the starting LBA (logical block address) for track number track_num in obj. The IS0-9660 filesystem track has number 0. Tracks associated with playable entries numbers start at 1. The "leadout" track is specified either by using track_num LEADOUT_TRACK or the total tracks+1. VCDINFO_NULL_LBA is returned on failure.*/lba_t vcdinfo_get_track_lba(const vcdinfo_obj_t *obj, track_t track_num){ if (NULL == obj || NULL == obj->img) return VCDINFO_NULL_LBA; /* CdIo tracks start at 1 rather than 0. */ return cdio_get_track_lba(obj->img, track_num+1);}/*! Return the starting LSN (logical sector number) for track number track_num in obj. The IS0-9660 filesystem track has number 0. Tracks associated with playable entries numbers start at 1. The "leadout" track is specified either by using track_num LEADOUT_TRACK or the total tracks+1. VCDINFO_NULL_LBA is returned on failure.*/lsn_t vcdinfo_get_track_lsn(const vcdinfo_obj_t *obj, track_t track_num){ if (NULL == obj || NULL == obj->img) return VCDINFO_NULL_LSN; /* CdIo tracks start at 1 rather than 0. */ return cdio_get_track_lsn(obj->img, track_num+1);}/*! Return the starting MSF (minutes/secs/frames) for track number track_num in obj. The IS0-9660 filesystem track has number 0. Tracks associated with playable entries numbers start at 1. The "leadout" track is specified either by using track_num LEADOUT_TRACK or the total tracks+1. VCDINFO_NULL_LBA is returned on failure.*/intvcdinfo_get_track_msf(const vcdinfo_obj_t *obj, track_t track_num, uint8_t *min, uint8_t *sec, uint8_t *frame){ msf_t msf; if (NULL == obj || NULL == obj->img) return 1; /* CdIo tracks start at 1 rather than 0. */ if (cdio_get_track_msf(obj->img, track_num+1, &msf)) { *min = cdio_from_bcd8(msf.m); *sec = cdio_from_bcd8(msf.s); *frame = cdio_from_bcd8(msf.f); return 0; } return 1;}/*! Return the size in sectors for track n. The IS0-9660 filesystem track has number 0. Tracks associated with playable entries numbers start at 1. FIXME: Whether we count the track pregap sectors is a bit haphazard. We should add a parameter to indicate whether this is wanted or not.*/unsigned intvcdinfo_get_track_sect_count(const vcdinfo_obj_t *obj, const track_t track_num){ if (NULL == obj || VCDINFO_INVALID_TRACK == track_num) return 0; { iso9660_stat_t *statbuf; const lsn_t lsn = vcdinfo_get_track_lsn(obj, track_num); /* Try to get the sector count from the ISO 9660 filesystem */ if (obj->has_xa && (statbuf = iso9660_find_fs_lsn(obj->img, lsn))) { unsigned int secsize = statbuf->secsize; free(statbuf); return secsize; } else { const lsn_t next_lsn=vcdinfo_get_track_lsn(obj, track_num+1); /* Failed on ISO 9660 filesystem. Use track information. */ return next_lsn > lsn ? next_lsn - lsn : 0; } } return 0;}/*! Return size in bytes for track number for entry n in obj. The IS0-9660 filesystem track has number 1. Tracks associated with playable entries numbers start at 2. FIXME: Whether we count the track pregap sectors is a bit haphazard. We should add a parameter to indicate whether this is wanted or not.*/unsigned intvcdinfo_get_track_size(const vcdinfo_obj_t *obj, track_t track_num){ if (NULL == obj || VCDINFO_INVALID_TRACK == track_num) return 0; { iso9660_stat_t statbuf; const lsn_t lsn = cdio_lba_to_lsn(vcdinfo_get_track_lba(obj, track_num)); /* Try to get the sector count from the ISO 9660 filesystem */ if (obj->has_xa && iso9660_find_fs_lsn(obj->img, lsn)) { return statbuf.size; } #if 0 else { /* Failed on ISO 9660 filesystem. Use track information. */ if (obj->img != NULL) return cdio_get_track_size(obj->img); }#endif } return 0;}/*! \brief Get the kind of video stream segment of segment seg_num in obj. \return VCDINFO_FILES_VIDEO_INVALID is returned if on error or obj is null. Otherwise the enumeration type. Note first seg_num is 0!*/vcdinfo_video_segment_type_tvcdinfo_get_video_type(const vcdinfo_obj_t *obj, segnum_t seg_num){ const InfoVcd_t *info; if (obj == NULL) return VCDINFO_FILES_VIDEO_INVALID; info = &obj->info; if (info == NULL) return VCDINFO_FILES_VIDEO_INVALID; return info->spi_contents[seg_num].video_type;}/*! \brief Get the kind of VCD that obj refers to.*/vcd_type_tvcdinfo_get_VCD_type(const vcdinfo_obj_t *obj) { if (NULL == obj) return VCD_TYPE_INVALID; return obj->vcd_type;} /*! Return the VCD volume count - the number of CD's in the collection. O is returned if there is some problem in getting this. */unsigned intvcdinfo_get_volume_count(const vcdinfo_obj_t *obj){ if ( NULL == obj ) return 0; return vcdinf_get_volume_count(&obj->info);}/*! Return the VCD ID. NULL is returned if there is some problem in getting this. */const char *vcdinfo_get_volume_id(const vcdinfo_obj_t *obj){ if ( NULL == obj || NULL == &obj->pvd ) return (NULL); return(iso9660_get_volume_id(&obj->pvd));}/*! Return the VCD volumeset ID. NULL is returned if there is some problem in getting this. */const char *vcdinfo_get_volumeset_id(const vcdinfo_obj_t *obj){ if ( NULL == obj || NULL == &obj->pvd ) return (NULL); return(vcdinfo_strip_trail(obj->pvd.volume_set_id, ISO_MAX_VOLUMESET_ID));}/*! Return the VCD volume num - the number of the CD in the collection. This is a number between 1 and the volume count. O is returned if there is some problem in getting this. */unsigned intvcdinfo_get_volume_num(const vcdinfo_obj_t *obj){ if ( NULL == obj ) return 0; return(uint16_from_be( obj->info.vol_id));}intvcdinfo_get_wait_time (uint16_t wtime){ /* Note: this doesn't agree exactly with _wtime */ if (wtime < 61) return wtime; else if (wtime < 255) return (wtime - 60) * 10 + 60; else return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -