37#define VCD_SECTOR_SIZE 2352                 
   38#define VCD_SECTOR_OFFS 24                   
   39#define VCD_SECTOR_DATA 2324                 
   44const std::array<char, 12> 
SYNC = { 
'\x00', 
'\xFF', 
'\xFF', 
'\xFF', 
'\xFF', 
'\xFF', 
'\xFF', 
'\xFF', 
'\xFF', 
'\xFF', 
'\xFF', 
'\x00' };
 
   89        uint32_t    num_entries = 0;
 
   91        fpi = fopen(fullname.c_str(), 
"rb");
 
   94            throw static_cast<int>(errno);
 
   97        if (fstat(fileno(fpi), &stbuf) != 0)
 
   99            throw static_cast<int>(ferror(fpi));
 
  104        std::memset(&vcdentry, 0, 
sizeof(vcdentry));
 
  106        if (fread(
reinterpret_cast<char *
>(&vcdentry), 1, 
sizeof(vcdentry), fpi) != 
sizeof(vcdentry))
 
  108            throw static_cast<int>(ferror(fpi));
 
  118        for (uint32_t chapter_no = 0, total = num_entries; chapter_no < total; chapter_no++)
 
  134        for (
size_t chapter_no = 0; chapter_no < 
m_chapters.size() - 1; chapter_no++)
 
  162    FILE *      fpi = 
nullptr;
 
  165    std::memset(&stbuf, 0, 
sizeof(stbuf));
 
  174        int         last_track_no = -1;
 
  175        int64_t     first_sync = -1;
 
  178        for (
size_t chapter_no = 0; chapter_no < 
m_chapters.size(); chapter_no++)
 
  180            if (last_track_no != 
m_chapters[chapter_no].get_track_no())
 
  182                std::string fullname;
 
  184                last_track_no = 
m_chapters[chapter_no].get_track_no();
 
  189                    throw static_cast<int>(orgerrno);
 
  194                    m_chapters[chapter_no - 1].m_end_pos = 
static_cast<uint64_t
>(stbuf.st_size);
 
  202                fpi = fopen(fullname.c_str(), 
"rb");
 
  206                    throw static_cast<int>(errno);
 
  209                if (fstat(fileno(fpi), &stbuf) != 0)
 
  211                    throw static_cast<int>(ferror(fpi));
 
  219                    throw static_cast<int>(EIO);
 
  222                first_sync = ftell(fpi) - 
static_cast<int64_t
>(
SYNC.size());
 
  227            int64_t last            = total_chunks - 1;
 
  228            int64_t middle          = (first + last) / 2;
 
  231            while (first <= last)
 
  234                long int file_pos = 
static_cast<long int>(first_sync + middle * 
VCD_SECTOR_SIZE);
 
  236                if (fseek(fpi, file_pos, SEEK_SET))
 
  238                    throw static_cast<int>(ferror(fpi));
 
  241                int orgerrno = buffer.
readio(fpi, last_track_no);
 
  244                    throw static_cast<int>(orgerrno);
 
  253                    m_chapters[chapter_no].m_start_pos = 
static_cast<uint64_t
>(file_pos);
 
  257                        m_chapters[chapter_no - 1].m_end_pos = 
static_cast<uint64_t
>(file_pos);
 
  266                middle = (first + last) / 2;
 
  275            if (fseek(fpi, 
static_cast<long int>(first_sync + (total_chunks - 1) * 
VCD_SECTOR_SIZE), SEEK_SET))
 
  277                throw static_cast<int>(ferror(fpi));
 
  280            int orgerrno = buffer.
readio(fpi, last_track_no);
 
  283                throw static_cast<int>(orgerrno);
 
  320    if (fread(&ch, 1, 1, fpi) != 1)
 
  325    for (
size_t n = 1; n <= sync.size(); n++)
 
  327        if (ch != sync[n - 1])
 
  339        if (n == sync.size())
 
  345        if (fread(&ch, 1, 1, fpi) != 1)
 
  395    return &
m_chapters[
static_cast<size_t>(chapter_idx)];
 
int64_t m_duration
Chapter duration, in AV_TIME_BASE fractional seconds.
 
int64_t get_start_time() const
Get start position of chapter in AV_TIME_BASE units.
 
int readio(FILE *fpi, int track_no)
Read file from disk.
 
VcdEntries()
Construct VcdEntries object.
 
time_t m_file_date
File date.
 
std::string m_disk_path
Path to this disk.
 
VCDTYPE get_type() const
Get disk type.
 
SEEKRES seek_sync(FILE *fpi, const std::array< char, 12 > &sync) const
Seek for sync bytes.
 
uint64_t get_size() const
Get disk size (DAT/MPEG only).
 
std::string m_id
ID of CD.
 
int get_number_of_chapters() const
Get number of chapters on this disk.
 
void clear()
Reset this object.
 
time_t get_file_date() const
Get date of disk (taken from INFO.VCD or SVD).
 
const std::string & get_disk_path() const
Get disk directory.
 
VCDPROFILETAG m_profile_tag
System profile tag.
 
VCDTYPE m_type
Type of CD.
 
int scan_chapters()
Scan the disk for chapters.
 
std::vector< VcdChapter > m_chapters
VCD chapters.
 
int load_file(const std::string &path)
Load VCD from path.
 
const VcdChapter * get_chapter(int chapter_idx) const
Get chapter object.
 
int64_t m_duration
Total disk duration, in AV_TIME_BASE fractional seconds.
 
@ NOTFOUND
Sync not found.
 
std::string get_type_str() const
Get disk type as string.
 
std::string get_profile_tag_str() const
Get disk profile tag as string.
 
int64_t get_duration() const
Get the total disk duration in AV_TIME_BASE fractional seconds.
 
const std::string & get_id() const
Get disk ID.
 
VCDPROFILETAG get_profile_tag() const
Get disk profile tag.
 
bool locate_file(const std::string &path, const std::string &filename, std::string &fullname, bool &is_vcd)
Check if path is a S/VCD.
 
int locate_video(const std::string &path, int track_no, std::string &fullname)
Locate AVSEQ*DAT/MPEG video file for track_no.
 
std::string convert_txt2string(const char *txt, int size, bool trimmed)
Non-zero terminated text is converted to std::string.
 
void get_directory(const std::string &fullname, std::string *directory)
Check if fullname is a directory. Remove the filename if necessary.
 
std::string get_type_str(VCDTYPE type)
Return disk type as a human readable string.
 
std::string get_profile_tag_str(VCDPROFILETAG tag)
Profile as a human readable string.
 
uint16_t m_num_entries
2 Bytes: 1 <= tracks <= 500
 
std::array< VCDCHAPTER, VCD_MAX_CHAPTERS > m_chapter
Chapters.
 
uint8_t m_type
1 Byte: CD type
 
std::array< char, 8 > m_ID
8 Bytes: ID "ENTRYVCD" or "ENTRYSVD"
 
uint8_t m_profile_tag
1 Byte: System Profile Tag.
 
@ UNKNOWN
unknown file tag
 
const std::array< char, 12 > SYNC
Chapter synchronisation in S/VCD mpeg/dat files (12 byte: 0x00FFFFFFFFFFFFFFFFFFFF00)
 
#define VCD_SECTOR_SIZE
Video CD sector size.