39#include <dvdread/dvd_reader.h>
40#include <dvdread/nav_read.h>
44 , m_dvd_title(nullptr)
52 , m_goto_next_cell(false)
63 , m_duration(AV_NOPTS_VALUE)
91 vts_ptt_srpt_t *vts_ptt_srpt;
116 if (
m_dvd ==
nullptr)
133 Logging::trace(
path(),
"There are %1 titles on this DVD.",
static_cast<uint16_t
>(tt_srpt->nr_of_srpts));
135 if (m_title_idx < 0 || m_title_idx >= tt_srpt->nr_of_srpts)
144 Logging::trace(
nullptr,
"There are %1 chapters in this title.",
static_cast<uint16_t
>(tt_srpt->title[
m_title_idx].nr_of_ptts));
146 if (m_chapter_idx < 0 || m_chapter_idx >= tt_srpt->title[
m_title_idx].nr_of_ptts)
157 if (m_angle_idx < 0 || m_angle_idx >= tt_srpt->title[
m_title_idx].nr_of_angles)
178 pgc_id = vts_ptt_srpt->title[ttn - 1].ptt[
m_chapter_idx].pgcn;
183 if (pgn < m_cur_pgc->nr_of_programs)
209 while ((bytes_read =
readio(
nullptr, ULONG_MAX)) != 0 && !
eof())
222#define PS_STREAM_ID_END_STREAM 0xB9
223#define PS_STREAM_ID_PACK_HEADER 0xBA
224#define PS_STREAM_ID_SYSTEM_HEADER 0xBB
225#define PS_STREAM_ID_MAP 0xBC
226#define PS_STREAM_ID_PRIVATE_STREAM1 0xBD
227#define PS_STREAM_ID_PADDING 0xBE
228#define PS_STREAM_ID_PRIVATE 0xBF
229#define PS_STREAM_ID_AUDIO 0xC0
230#define PS_STREAM_ID_VIDEO 0xE0
231#define PS_STREAM_ID_EXTENDED 0xFD
232#define PS_STREAM_ID_DIRECTORY 0xFF
234#define PS_STREAM_ID 3
255 if (peek >= 14 && (p[4] >> 6) == 0x01)
257 *
size = 14 +
static_cast<size_t>(p[13] & 0x07);
260 else if (peek >= 12 && (p[4] >> 4) == 0x02)
275 *
size = (6 + ((
static_cast<unsigned int>(p[4]) << 8) | p[5]));
289 if (
size >= 9 &&
size >=
static_cast<unsigned int>(9 + buffer[8]))
291 const size_t start =
static_cast<size_t>(9 + buffer[8]);
292 sub_id = buffer[start];
294 if ((sub_id & 0xfe) == 0xa0 &&
296 (buffer[start + 5] >= 0xc0 ||
297 buffer[start + 6] != 0x80))
302 return (0xa000 | (sub_id & 0x01));
307 return (0xbd00 | sub_id);
311 (buffer[6] & 0xC0) == 0x80 &&
312 (buffer[7] & 0x01) == 0x01)
315 const uint8_t flags = buffer[7];
348 if (skip <
size && (buffer[skip] & 0x01))
350 const uint8_t flags2 = buffer[skip];
358 if ((flags2 & 0x40) && skip <
size)
360 skip +=
static_cast<size_t>(1 + buffer[skip]);
373 const int i_extension_field_length = buffer[skip] & 0x7f;
374 if (i_extension_field_length >=1)
376 int i_stream_id_extension_flag = (buffer[skip+1] >> 7) & 0x1;
377 if (i_stream_id_extension_flag == 0)
379 return (0xfd00 | (buffer[skip+1] & 0x7f));
411 std::memcpy(out, in, pktsize);
424 std::memcpy(out, in, pktsize);
441 dsi_t * dsi_pack =
reinterpret_cast<dsi_t*
>(_dsi_pack);
445 navRead_DSI(dsi_pack, &data[DSI_START_BYTE]);
450 *cur_output_size = dsi_pack->dsi_gi.vobu_ea;
458 *next_block =
m_cur_block + (dsi_pack->vobu_sri.next_vobu & 0x7fffffff);
459 end_of_cell = (dsi_pack->vobu_sri.next_vobu == SRI_END_OF_CELL || *next_block >=
m_cur_pgc->cell_playback[
m_cur_cell].last_sector);
463 switch ((dsi_pack->sml_pbi.category & 0xf000) >> 12)
472 if (dsi_pack->sml_pbi.ilvu_sa != 0 && dsi_pack->sml_pbi.ilvu_sa != 0xffffffff)
474 *next_block =
m_cur_block + dsi_pack->sml_pbi.ilvu_sa;
475 *cur_output_size = dsi_pack->sml_pbi.ilvu_ea;
479 *next_block =
m_cur_block + dsi_pack->dsi_gi.vobu_ea + 1;
489 *cur_output_size = dsi_pack->sml_pbi.ilvu_ea;
500 *next_block =
m_cur_block + (dsi_pack->vobu_sri.next_vobu & 0x7fffffff);
505 else if (end_of_cell)
533 if (
m_cur_pgc->cell_playback[
m_cur_cell].block_type ==
static_cast<unsigned int>(BLOCK_TYPE_ANGLE_BLOCK))
537 for (
int i = 0;; ++i)
539 if (
m_cur_pgc->cell_playback[
m_cur_cell + i].block_mode ==
static_cast<unsigned int>(BLOCK_MODE_LAST_CELL))
554 size_t cur_output_size;
555 size_t result_len = 0;
603 unsigned int next_block;
629 if (cur_output_size >= 1024)
641 if (maxlen !=
static_cast<int>(cur_output_size))
648 size_t netsize = cur_output_size * DVD_VIDEO_LB_LEN;
658 std::memcpy(data,
m_data.data(), result_len);
665 result_len = netsize;
667 std::memcpy(data,
m_data.data(), result_len);
678 result_len = netsize;
738 if (whence == SEEK_SET && !offset)
744 size_t cur_pos =
tell();
745 size_t abs_offset = 0;
750 abs_offset =
static_cast<size_t>(offset);
753 abs_offset += cur_pos;
756 abs_offset =
size() - abs_offset;
763 if (cur_pos == abs_offset)
766 return static_cast<int>(abs_offset);
769 if (cur_pos > abs_offset)
776 size_t total_read = 0;
778 while ((bytes_read =
readio(
nullptr, abs_offset - total_read - cur_pos)) != 0 && total_read < abs_offset && !
eof())
780 total_read += bytes_read;
785 return static_cast<int>(cur_pos + total_read);
805 if (vts_file !=
nullptr)
811 if (vmg_file !=
nullptr)
817 if (dvd_title !=
nullptr)
820 DVDCloseFile(dvd_title);
822 dvd_reader_t * dvd =
m_dvd;
853 if ((buffer[0x26] == 0x00 &&
854 buffer[0x27] == 0x00 &&
855 buffer[0x28] == 0x01 &&
856 buffer[0x29] == 0xbf &&
857 buffer[0x2c] == 0x00) &&
858 (buffer[0x400] == 0x00 &&
859 buffer[0x401] == 0x00 &&
860 buffer[0x402] == 0x01 &&
861 buffer[0x403] == 0xbf &&
862 buffer[0x406] == 0x01))
bool m_is_eof
true if at "end of file", i.e, end of chapter or title
bool get_packet_size(const uint8_t *p, size_t peek, size_t *size) const
return the size of the next packet
int m_cur_cell
Current cell.
int m_errno
errno of last operation
virtual VIRTUALTYPE type() const override
Get type of the virtual file.
bool m_goto_next_cell
If logc needs to go to next cell before next read.
bool m_full_title
If true, ignore m_chapter_no and provide full track.
void rewind()
Rewind to start of stream.
virtual int seek(int64_t offset, int whence) override
Seek to position in file.
virtual size_t size() const override
Get the file size.
size_t m_size
Size of virtual file.
DSITYPE handle_DSI(void *_dsi_pack, size_t *cur_output_size, unsigned int *next_block, uint8_t *data)
Handle DSI (Data Search Information) packet.
void pvt_close()
Close virtual file. Non-virtual version to be safely called from constructor/destructor.
ifo_handle_t * m_vmg_file
DVD video manager handle.
bool is_nav_pack(const unsigned char *buffer) const
Do a rough check if this is really a navigation packet.
std::array< unsigned char, 1024 *DVD_VIDEO_LB_LEN > m_buffer
Buffer for data extracted from VOB file.
size_t m_rest_size
Rest bytes in buffer.
int m_title_idx
Track index (track number - 1)
virtual void closeio() override
Close virtual file.
virtual size_t bufsize() const override
Get the ideal buffer size.
void next_cell()
Goto next DVD cell.
int64_t m_duration
Track/chapter duration, in AV_TIME_BASE fractional seconds.
DSITYPE
Type of a DSI block.
@ CONTINUE
Chapter continues.
@ EOF_CHAPTER
End of chapter.
DvdIO()
Create DvdIO object.
virtual int openio(LPVIRTUALFILE virtualfile) override
Open a virtual file.
int m_next_cell
Next cell to be processed.
int get_pes_id(const uint8_t *buffer, size_t size) const
return the id of a Packetized Elementary Stream (PES) (should be valid)
virtual bool eof() const override
Check if at end of file.
virtual size_t readio(void *data, size_t size) override
Read data from file.
virtual int error() const override
Get last error.
int m_chapter_idx
Chapter index (chapter number - 1)
size_t m_cur_pos
Current position in virtual file.
ifo_handle_t * m_vts_file
DVD video title stream handle.
dvd_reader_t * m_dvd
DVD reader handle.
pgc_t * m_cur_pgc
Current program chain.
dvd_file_t * m_dvd_title
DVD title handle.
virtual ~DvdIO()
Free DvdIO object.
int m_angle_idx
Selected angle index (angle number -1)
size_t m_rest_pos
Position in buffer.
unsigned int m_cur_block
Current processing block.
std::array< unsigned char, 1024 *DVD_VIDEO_LB_LEN > m_data
Buffer for readio() data.
int m_end_cell
End cell (of title)
int m_start_cell
Start cell.
virtual size_t tell() const override
Get current read position.
size_t demux_pes(uint8_t *out, const uint8_t *in, size_t len) const
Extract only the interesting portion of the VOB input stream.
virtual int64_t duration() const override
Get the duration of the file, in AV_TIME_BASE fractional seconds.
const std::string & path() const
Path to source file (without file name)
LPVIRTUALFILE virtualfile()
Get virtual file object.
void set_virtualfile(LPVIRTUALFILE virtualfile)
Set the virtual file object.
static void warning(const T filename, const std::string &format_string, Args &&...args)
Write warning level log entry.
static void debug(const T filename, const std::string &format_string, Args &&...args)
Write debug level log entry.
static void trace(const T filename, const std::string &format_string, Args &&...args)
Write trace level log entry.
static void error(const T filename, const std::string &format_string, Args &&...args)
Write error level log entry.
#define PS_STREAM_ID_MAP
???
#define PS_STREAM_ID_DIRECTORY
???
#define PS_STREAM_ID_AUDIO
0xDF MPEG-1 or MPEG-2 audio stream number (note: DVD allows only 8 audio streams)
#define PS_STREAM_ID_END_STREAM
???
#define PS_STREAM_ID_EXTENDED
???
#define PS_STREAM_ID_PRIVATE_STREAM1
Private stream 1 (non MPEG audio, subpictures)
#define PS_STREAM_ID_SYSTEM_HEADER
Program Stream System Header.
#define PS_STREAM_ID_PACK_HEADER
MPEG-2 Pack Header.
VIRTUALTYPE
Virtual file types enum.
Provide various log facilities to stderr, disk or syslog.
int m_angle_no
Selected angle number (1...n)
int m_title_no
Track number (1...n)
int m_chapter_no
Chapter number (1...n)
struct VIRTUALFILE::DVD_CHAPTER m_dvd
DVD title/chapter info.
bool m_full_title
If true, ignore m_chapter_no and provide full track.
int64_t m_duration
Track/chapter duration, in AV_TIME_BASE fractional seconds.