FFmpegfs Fuse Multi Media Filesystem 2.16
vcdchapter.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 2017-2024 Norbert Schlia (nschlia@oblivion-software.de)
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
30#include "ffmpegfs.h"
31#include "vcdchapter.h"
32#include "vcdutils.h"
33#include "ffmpeg_utils.h"
34
35#include <climits>
36
38 m_is_svcd(is_svcd),
39 m_track_no(0),
40 m_min(0),
41 m_sec(0),
42 m_frame(0),
43 m_duration(0),
44 m_start_pos(0),
45 m_end_pos(0)
46{
47
48}
49
51 m_is_svcd(is_svcd),
52 m_track_no(VcdChapter.m_track_no),
53 m_min(BCD2DEC(VcdChapter.m_msf.m_min)),
54 m_sec(BCD2DEC(VcdChapter.m_msf.m_sec)),
55 m_frame(BCD2DEC(VcdChapter.m_msf.m_frame)),
56 m_duration(0),
57 m_start_pos(0),
58 m_end_pos(0)
59{
60
61}
62
63VcdChapter::VcdChapter(int track_no, int min, int sec, int frame, bool is_svcd, int64_t duration) :
64 m_is_svcd(is_svcd),
65 m_track_no(track_no),
66 m_min(min),
67 m_sec(sec),
68 m_frame(frame),
69 m_duration(duration),
70 m_start_pos(0),
71 m_end_pos(0)
72{
73
74}
75
76int VcdChapter::readio(FILE *fpi, int track_no)
77{
78 VCDMSF msf;
79 std::array<char, SYNC.size()> buffer;
80
81 // Read first sync
82 if (fread(&buffer, 1, buffer.size(), fpi) != buffer.size())
83 {
84 return ferror(fpi);
85 }
86
87 // Validate sync
88 if (buffer != SYNC)
89 {
90 return EIO;
91 }
92
93 // Read position block
94 std::memset(&msf, 0, sizeof(msf));
95
96 if (fread(reinterpret_cast<char *>(&msf), 1, sizeof(msf), fpi) != sizeof(msf))
97 {
98 return ferror(fpi);
99 }
100
101 m_track_no = track_no;
102 m_min = BCD2DEC(msf.m_min);
103 m_sec = BCD2DEC(msf.m_sec);
104 m_frame = BCD2DEC(msf.m_frame);
105
106 return 0;
107}
108
110{
111 return m_is_svcd;
112}
113
115{
116 return m_track_no;
117}
118
120{
121 return m_min;
122}
123
125{
126 return m_sec;
127}
128
130{
131 return m_frame;
132}
133
135{
136 return m_duration;
137}
138
139std::string VcdChapter::get_filename() const
140{
141 std::string buffer;
142
143 if (m_is_svcd)
144 {
145 strsprintf(&buffer, "MPEG2/AVSEQ%02i.MPG", m_track_no - 1);
146 }
147 else
148 {
149 strsprintf(&buffer, "MPEGAV/AVSEQ%02i.DAT", m_track_no - 1);
150 }
151 return buffer;
152}
153
155{
156 return m_start_pos;
157}
158
160{
161 return m_end_pos;
162}
163
164uint64_t VcdChapter::get_size() const
165{
166 return (m_end_pos - m_start_pos);
167}
168
170{
171 // MSF format: minutes, seconds, and fractional seconds called frames. Each timecode frame is one seventy-fifth of a second.
172 return static_cast<int64_t>(m_min * 60 + m_sec) * AV_TIME_BASE + (static_cast<int64_t>(m_frame) * AV_TIME_BASE / 75);
173}
174
175//Conversion from MSF to LBA
176//--------------------------
177//As from Red book because there are 75 frames in 1 second, so,
178//LBA = Minute * 60 * 75 + Second * 75 + Frame - 150
179//The minus 150 is the 2 second pregap that is recorded on every CD.
180
181//Conversion from LBA to MSF
182//--------------------------
183//Minute = Int((LBA + 150) / (60 * 75))
184//Second = Int(LBA + 150 - Minute * 60 * 75) / 75)
185//Frame = LBA + 150 - Minute * 60 * 75 - Second * 75
186//Where Int() is a function that truncates the fractional part giving only the whole number part.
187
189{
190 return m_frame + (m_sec + m_min * 60) * 75;
191}
192
194{
195 if (this != & other) //oder if (*this != rhs)
196 {
197 m_is_svcd = other.m_is_svcd;
198 m_track_no = other.m_track_no;
199 m_min = other.m_min;
200 m_sec = other.m_sec;
201 m_frame = other.m_frame;
202 m_start_pos = other.m_start_pos;
203 m_end_pos = other.m_end_pos;
204 m_duration = other.m_duration;
205 }
206
207 return *this; //Referenz auf das Objekt selbst zurückgeben
208}
209
210int VcdChapter::operator==(const VcdChapter & other) const
211{
212 return (m_track_no == other.m_track_no &&
213 m_min == other.m_min &&
214 m_sec == other.m_sec &&
215 m_frame == other.m_frame);
216}
217
218int VcdChapter::operator<(const VcdChapter & other) const
219{
220 int res;
221
222 res = (m_track_no - other.m_track_no);
223
224 if (res < 0)
225 {
226 return 1;
227 }
228
229 if (res > 0)
230 {
231 return 0;
232 }
233
234 res = (m_min - other.m_min);
235
236 if (res < 0)
237 {
238 return 1;
239 }
240
241 if (res > 0)
242 {
243 return 0;
244 }
245
246 res = (m_sec - other.m_sec);
247
248 if (res < 0)
249 {
250 return 1;
251 }
252
253 if (res > 0)
254 {
255 return 0;
256 }
257
258 res = (m_frame - other.m_frame);
259
260 if (res < 0)
261 {
262 return 1;
263 }
264
265 return 0;
266}
267
268int VcdChapter::operator<=(const VcdChapter & other) const
269{
270 if (*this == other)
271 {
272 return 1;
273 }
274
275 return (*this < other);
276}
277
278int VcdChapter::operator>(const VcdChapter & other) const
279{
280 int res;
281 res = (m_track_no - other.m_track_no);
282
283 if (res > 0)
284 {
285 return 1;
286 }
287
288 if (res < 0)
289 {
290 return 0;
291 }
292
293 res = (m_min - other.m_min);
294
295 if (res > 0)
296 {
297 return 1;
298 }
299
300 if (res < 0)
301 {
302 return 0;
303 }
304
305 res = (m_sec - other.m_sec);
306
307 if (res > 0)
308 {
309 return 1;
310 }
311
312 if (res < 0)
313 {
314 return 0;
315 }
316
317 res = (m_frame - other.m_frame);
318
319 if (res > 0)
320 {
321 return 1;
322 }
323
324 //if (res <= 0)
325 return 0;
326}
327
328int VcdChapter::operator>=(const VcdChapter & other) const
329{
330 if (*this == other)
331 {
332 return 1;
333 }
334
335 return (*this > other);
336}
337
338int VcdChapter::operator!=(const VcdChapter & other) const
339{
340 return (m_track_no != other.m_track_no &&
341 m_min != other.m_min &&
342 m_sec != other.m_sec &&
343 m_frame != other.m_frame);
344}
Video CD chapter.
Definition: vcdchapter.h:62
int get_track_no() const
Get the track number of this chapter.
Definition: vcdchapter.cc:114
uint64_t get_size() const
Get the size of this chapter in bytes.
Definition: vcdchapter.cc:164
int operator>=(const VcdChapter &other) const
Comparison operator >=.
Definition: vcdchapter.cc:328
int64_t m_duration
Chapter duration, in AV_TIME_BASE fractional seconds.
Definition: vcdchapter.h:216
int get_min() const
Get MSF (minutes, seconds, and fractional seconds/frames) minute.
Definition: vcdchapter.cc:119
int get_sec() const
Get MSF (minutes, seconds, and fractional seconds/frames) second.
Definition: vcdchapter.cc:124
bool m_is_svcd
true for SVCD, false for VCD
Definition: vcdchapter.h:211
int operator!=(const VcdChapter &other) const
Comparison operator !=.
Definition: vcdchapter.cc:338
int operator<=(const VcdChapter &other) const
Comparison operator <=.
Definition: vcdchapter.cc:268
int m_track_no
Track no.
Definition: vcdchapter.h:212
uint64_t m_start_pos
Start offset in bytes.
Definition: vcdchapter.h:217
int64_t get_start_time() const
Get start position of chapter in AV_TIME_BASE units.
Definition: vcdchapter.cc:169
int get_lba() const
Get LBA (large block address) of chapter.
Definition: vcdchapter.cc:188
int operator>(const VcdChapter &other) const
Comparison operator >
Definition: vcdchapter.cc:278
uint64_t get_start_pos() const
Get file position of chapter in bytes.
Definition: vcdchapter.cc:154
int m_sec
MSF second.
Definition: vcdchapter.h:214
uint64_t get_end_pos() const
Get end position of chapter in bytes.
Definition: vcdchapter.cc:159
int m_frame
MSF frame.
Definition: vcdchapter.h:215
int operator<(const VcdChapter &other) const
Comparison operator <.
Definition: vcdchapter.cc:218
bool get_is_svcd() const
Check if this is a Super Video CD.
Definition: vcdchapter.cc:109
int get_frame() const
Get MSF (minutes, seconds, and fractional seconds/frames) frame.
Definition: vcdchapter.cc:129
uint64_t m_end_pos
End offset in bytes (not including this byte)
Definition: vcdchapter.h:218
std::string get_filename() const
Get file name and path of source file (e.g. MPEG/AVSEQ##.MPG).
Definition: vcdchapter.cc:139
int operator==(const VcdChapter &other) const
Comparison operator ==.
Definition: vcdchapter.cc:210
VcdChapter & operator=(VcdChapter const &other)
Assignment operator =.
Definition: vcdchapter.cc:193
int readio(FILE *fpi, int track_no)
Read file from disk.
Definition: vcdchapter.cc:76
int64_t get_duration() const
Get chapter duration, in AV_TIME_BASE fractional seconds.
Definition: vcdchapter.cc:134
VcdChapter(bool is_svcd)
Construct VcdChapter object.
Definition: vcdchapter.cc:37
int m_min
MSF minute.
Definition: vcdchapter.h:213
Various FFmpegfs utility functions.
const std::string & strsprintf(std::string *str, const std::string &format, Args ... args)
Format a std::string sprintf-like.
Definition: ffmpeg_utils.h:737
Main include for FFmpegfs project.
Video CD chapter.
Definition: vcdutils.h:66
Video CD MSF time format.
Definition: vcdutils.h:55
uint8_t m_min
Minute in BCD code.
Definition: vcdutils.h:56
uint8_t m_frame
Number of frames, for a 25 frames per second movie 0...24.
Definition: vcdutils.h:58
uint8_t m_sec
Second in BCD code.
Definition: vcdutils.h:57
S/VCD VcdChapter class.
const std::array< char, 12 > SYNC
Chapter synchronisation in S/VCD mpeg/dat files (12 byte: 0x00FFFFFFFFFFFFFFFFFFFF00)
Definition: vcdentries.cc:44
S/VCD utility functions.
#define BCD2DEC(hex)
Definition: vcdutils.h:40