Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-gpu
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-gpu
Commits
72be09f0
Commit
72be09f0
authored
Mar 17, 2005
by
Steve Lhomme
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mkv.cpp: allow seamless transition between segments
parent
77a1a288
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
425 additions
and
390 deletions
+425
-390
modules/demux/mkv.cpp
modules/demux/mkv.cpp
+425
-390
No files found.
modules/demux/mkv.cpp
View file @
72be09f0
...
@@ -507,6 +507,8 @@ public:
...
@@ -507,6 +507,8 @@ public:
void
ParseTrackEntry
(
EbmlMaster
*
m
);
void
ParseTrackEntry
(
EbmlMaster
*
m
);
void
IndexAppendCluster
(
KaxCluster
*
cluster
);
void
IndexAppendCluster
(
KaxCluster
*
cluster
);
int
BlockGet
(
KaxBlock
**
pp_block
,
int64_t
*
pi_ref1
,
int64_t
*
pi_ref2
,
int64_t
*
pi_duration
);
int
BlockGet
(
KaxBlock
**
pp_block
,
int64_t
*
pi_ref1
,
int64_t
*
pi_ref2
,
int64_t
*
pi_duration
);
bool
Select
(
);
void
UnSelect
(
);
};
};
class
matroska_stream_t
class
matroska_stream_t
...
@@ -542,7 +544,7 @@ public:
...
@@ -542,7 +544,7 @@ public:
return
NULL
;
return
NULL
;
}
}
matroska_segment_t
*
FindSegment
(
EbmlBinary
&
uid
)
const
;
matroska_segment_t
*
FindSegment
(
const
EbmlBinary
&
uid
)
const
;
void
PreloadFamily
(
const
matroska_segment_t
&
segment
);
void
PreloadFamily
(
const
matroska_segment_t
&
segment
);
size_t
PreloadLinked
(
const
demux_sys_t
&
of_sys
);
size_t
PreloadLinked
(
const
demux_sys_t
&
of_sys
);
...
@@ -588,7 +590,7 @@ public:
...
@@ -588,7 +590,7 @@ public:
return
NULL
;
return
NULL
;
}
}
matroska_segment_t
*
FindSegment
(
EbmlBinary
&
uid
)
const
;
matroska_segment_t
*
FindSegment
(
const
EbmlBinary
&
uid
)
const
;
void
PreloadFamily
(
);
void
PreloadFamily
(
);
void
PreloadLinked
(
);
void
PreloadLinked
(
);
matroska_stream_t
*
AnalyseAllSegmentsFound
(
EbmlStream
*
p_estream
);
matroska_stream_t
*
AnalyseAllSegmentsFound
(
EbmlStream
*
p_estream
);
...
@@ -615,7 +617,6 @@ static int Open( vlc_object_t * p_this )
...
@@ -615,7 +617,6 @@ static int Open( vlc_object_t * p_this )
matroska_segment_t
*
p_segment
;
matroska_segment_t
*
p_segment
;
uint8_t
*
p_peek
;
uint8_t
*
p_peek
;
std
::
string
s_path
,
s_filename
;
std
::
string
s_path
,
s_filename
;
size_t
i_track
;
vlc_stream_io_callback
*
p_io_callback
;
vlc_stream_io_callback
*
p_io_callback
;
EbmlStream
*
p_io_stream
;
EbmlStream
*
p_io_stream
;
...
@@ -758,294 +759,12 @@ static int Open( vlc_object_t * p_this )
...
@@ -758,294 +759,12 @@ static int Open( vlc_object_t * p_this )
p_segment
->
b_cues
=
VLC_FALSE
;
p_segment
->
b_cues
=
VLC_FALSE
;
}
}
/* add all es */
if
(
!
p_segment
->
Select
()
)
msg_Dbg
(
p_demux
,
"found %d es"
,
p_segment
->
tracks
.
size
()
);
for
(
i_track
=
0
;
i_track
<
p_segment
->
tracks
.
size
();
i_track
++
)
{
{
#define tk p_segment->tracks[i_track]
msg_Err
(
p_demux
,
"cannot use the segment"
);
if
(
tk
->
fmt
.
i_cat
==
UNKNOWN_ES
)
goto
error
;
{
msg_Warn
(
p_demux
,
"invalid track[%d, n=%d]"
,
i_track
,
tk
->
i_number
);
tk
->
p_es
=
NULL
;
continue
;
}
if
(
!
strcmp
(
tk
->
psz_codec
,
"V_MS/VFW/FOURCC"
)
)
{
if
(
tk
->
i_extra_data
<
(
int
)
sizeof
(
BITMAPINFOHEADER
)
)
{
msg_Err
(
p_demux
,
"missing/invalid BITMAPINFOHEADER"
);
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'u'
,
'n'
,
'd'
,
'f'
);
}
else
{
BITMAPINFOHEADER
*
p_bih
=
(
BITMAPINFOHEADER
*
)
tk
->
p_extra_data
;
tk
->
fmt
.
video
.
i_width
=
GetDWLE
(
&
p_bih
->
biWidth
);
tk
->
fmt
.
video
.
i_height
=
GetDWLE
(
&
p_bih
->
biHeight
);
tk
->
fmt
.
i_codec
=
GetFOURCC
(
&
p_bih
->
biCompression
);
tk
->
fmt
.
i_extra
=
GetDWLE
(
&
p_bih
->
biSize
)
-
sizeof
(
BITMAPINFOHEADER
);
if
(
tk
->
fmt
.
i_extra
>
0
)
{
tk
->
fmt
.
p_extra
=
malloc
(
tk
->
fmt
.
i_extra
);
memcpy
(
tk
->
fmt
.
p_extra
,
&
p_bih
[
1
],
tk
->
fmt
.
i_extra
);
}
}
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"V_MPEG1"
)
||
!
strcmp
(
tk
->
psz_codec
,
"V_MPEG2"
)
)
{
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'm'
,
'p'
,
'g'
,
'v'
);
}
else
if
(
!
strncmp
(
tk
->
psz_codec
,
"V_MPEG4"
,
7
)
)
{
if
(
!
strcmp
(
tk
->
psz_codec
,
"V_MPEG4/MS/V3"
)
)
{
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'D'
,
'I'
,
'V'
,
'3'
);
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"V_MPEG4/ISO/AVC"
)
)
{
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'a'
,
'v'
,
'c'
,
'1'
);
tk
->
fmt
.
b_packetized
=
VLC_FALSE
;
tk
->
fmt
.
i_extra
=
tk
->
i_extra_data
;
tk
->
fmt
.
p_extra
=
malloc
(
tk
->
i_extra_data
);
memcpy
(
tk
->
fmt
.
p_extra
,
tk
->
p_extra_data
,
tk
->
i_extra_data
);
}
else
{
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'm'
,
'p'
,
'4'
,
'v'
);
}
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"V_QUICKTIME"
)
)
{
MP4_Box_t
*
p_box
=
(
MP4_Box_t
*
)
malloc
(
sizeof
(
MP4_Box_t
)
);
stream_t
*
p_mp4_stream
=
stream_MemoryNew
(
VLC_OBJECT
(
p_demux
),
tk
->
p_extra_data
,
tk
->
i_extra_data
);
MP4_ReadBoxCommon
(
p_mp4_stream
,
p_box
);
MP4_ReadBox_sample_vide
(
p_mp4_stream
,
p_box
);
tk
->
fmt
.
i_codec
=
p_box
->
i_type
;
tk
->
fmt
.
video
.
i_width
=
p_box
->
data
.
p_sample_vide
->
i_width
;
tk
->
fmt
.
video
.
i_height
=
p_box
->
data
.
p_sample_vide
->
i_height
;
tk
->
fmt
.
i_extra
=
p_box
->
data
.
p_sample_vide
->
i_qt_image_description
;
tk
->
fmt
.
p_extra
=
malloc
(
tk
->
fmt
.
i_extra
);
memcpy
(
tk
->
fmt
.
p_extra
,
p_box
->
data
.
p_sample_vide
->
p_qt_image_description
,
tk
->
fmt
.
i_extra
);
MP4_FreeBox_sample_vide
(
p_box
);
stream_MemoryDelete
(
p_mp4_stream
,
VLC_TRUE
);
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"A_MS/ACM"
)
)
{
if
(
tk
->
i_extra_data
<
(
int
)
sizeof
(
WAVEFORMATEX
)
)
{
msg_Err
(
p_demux
,
"missing/invalid WAVEFORMATEX"
);
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'u'
,
'n'
,
'd'
,
'f'
);
}
else
{
WAVEFORMATEX
*
p_wf
=
(
WAVEFORMATEX
*
)
tk
->
p_extra_data
;
wf_tag_to_fourcc
(
GetWLE
(
&
p_wf
->
wFormatTag
),
&
tk
->
fmt
.
i_codec
,
NULL
);
tk
->
fmt
.
audio
.
i_channels
=
GetWLE
(
&
p_wf
->
nChannels
);
tk
->
fmt
.
audio
.
i_rate
=
GetDWLE
(
&
p_wf
->
nSamplesPerSec
);
tk
->
fmt
.
i_bitrate
=
GetDWLE
(
&
p_wf
->
nAvgBytesPerSec
)
*
8
;
tk
->
fmt
.
audio
.
i_blockalign
=
GetWLE
(
&
p_wf
->
nBlockAlign
);;
tk
->
fmt
.
audio
.
i_bitspersample
=
GetWLE
(
&
p_wf
->
wBitsPerSample
);
tk
->
fmt
.
i_extra
=
GetWLE
(
&
p_wf
->
cbSize
);
if
(
tk
->
fmt
.
i_extra
>
0
)
{
tk
->
fmt
.
p_extra
=
malloc
(
tk
->
fmt
.
i_extra
);
memcpy
(
tk
->
fmt
.
p_extra
,
&
p_wf
[
1
],
tk
->
fmt
.
i_extra
);
}
}
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"A_MPEG/L3"
)
||
!
strcmp
(
tk
->
psz_codec
,
"A_MPEG/L2"
)
||
!
strcmp
(
tk
->
psz_codec
,
"A_MPEG/L1"
)
)
{
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'm'
,
'p'
,
'g'
,
'a'
);
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"A_AC3"
)
)
{
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'a'
,
'5'
,
'2'
,
' '
);
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"A_DTS"
)
)
{
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'd'
,
't'
,
's'
,
' '
);
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"A_FLAC"
)
)
{
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'f'
,
'l'
,
'a'
,
'c'
);
tk
->
fmt
.
i_extra
=
tk
->
i_extra_data
;
tk
->
fmt
.
p_extra
=
malloc
(
tk
->
i_extra_data
);
memcpy
(
tk
->
fmt
.
p_extra
,
tk
->
p_extra_data
,
tk
->
i_extra_data
);
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"A_VORBIS"
)
)
{
int
i
,
i_offset
=
1
,
i_size
[
3
],
i_extra
;
uint8_t
*
p_extra
;
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'v'
,
'o'
,
'r'
,
'b'
);
/* Split the 3 headers */
if
(
tk
->
p_extra_data
[
0
]
!=
0x02
)
msg_Err
(
p_demux
,
"invalid vorbis header"
);
for
(
i
=
0
;
i
<
2
;
i
++
)
{
i_size
[
i
]
=
0
;
while
(
i_offset
<
tk
->
i_extra_data
)
{
i_size
[
i
]
+=
tk
->
p_extra_data
[
i_offset
];
if
(
tk
->
p_extra_data
[
i_offset
++
]
!=
0xff
)
break
;
}
}
i_size
[
0
]
=
__MIN
(
i_size
[
0
],
tk
->
i_extra_data
-
i_offset
);
i_size
[
1
]
=
__MIN
(
i_size
[
1
],
tk
->
i_extra_data
-
i_offset
-
i_size
[
0
]);
i_size
[
2
]
=
tk
->
i_extra_data
-
i_offset
-
i_size
[
0
]
-
i_size
[
1
];
tk
->
fmt
.
i_extra
=
3
*
2
+
i_size
[
0
]
+
i_size
[
1
]
+
i_size
[
2
];
tk
->
fmt
.
p_extra
=
malloc
(
tk
->
fmt
.
i_extra
);
p_extra
=
(
uint8_t
*
)
tk
->
fmt
.
p_extra
;
i_extra
=
0
;
for
(
i
=
0
;
i
<
3
;
i
++
)
{
*
(
p_extra
++
)
=
i_size
[
i
]
>>
8
;
*
(
p_extra
++
)
=
i_size
[
i
]
&
0xFF
;
memcpy
(
p_extra
,
tk
->
p_extra_data
+
i_offset
+
i_extra
,
i_size
[
i
]
);
p_extra
+=
i_size
[
i
];
i_extra
+=
i_size
[
i
];
}
}
else
if
(
!
strncmp
(
tk
->
psz_codec
,
"A_AAC/MPEG2/"
,
strlen
(
"A_AAC/MPEG2/"
)
)
||
!
strncmp
(
tk
->
psz_codec
,
"A_AAC/MPEG4/"
,
strlen
(
"A_AAC/MPEG4/"
)
)
)
{
int
i_profile
,
i_srate
;
static
unsigned
int
i_sample_rates
[]
=
{
96000
,
88200
,
64000
,
48000
,
44100
,
32000
,
24000
,
22050
,
16000
,
12000
,
11025
,
8000
,
7350
,
0
,
0
,
0
};
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'm'
,
'p'
,
'4'
,
'a'
);
/* create data for faad (MP4DecSpecificDescrTag)*/
if
(
!
strcmp
(
&
tk
->
psz_codec
[
12
],
"MAIN"
)
)
{
i_profile
=
0
;
}
else
if
(
!
strcmp
(
&
tk
->
psz_codec
[
12
],
"LC"
)
)
{
i_profile
=
1
;
}
else
if
(
!
strcmp
(
&
tk
->
psz_codec
[
12
],
"SSR"
)
)
{
i_profile
=
2
;
}
else
{
i_profile
=
3
;
}
for
(
i_srate
=
0
;
i_srate
<
13
;
i_srate
++
)
{
if
(
i_sample_rates
[
i_srate
]
==
tk
->
fmt
.
audio
.
i_rate
)
{
break
;
}
}
msg_Dbg
(
p_demux
,
"profile=%d srate=%d"
,
i_profile
,
i_srate
);
tk
->
fmt
.
i_extra
=
2
;
tk
->
fmt
.
p_extra
=
malloc
(
tk
->
fmt
.
i_extra
);
((
uint8_t
*
)
tk
->
fmt
.
p_extra
)[
0
]
=
((
i_profile
+
1
)
<<
3
)
|
((
i_srate
&
0xe
)
>>
1
);
((
uint8_t
*
)
tk
->
fmt
.
p_extra
)[
1
]
=
((
i_srate
&
0x1
)
<<
7
)
|
(
tk
->
fmt
.
audio
.
i_channels
<<
3
);
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"A_PCM/INT/BIG"
)
||
!
strcmp
(
tk
->
psz_codec
,
"A_PCM/INT/LIT"
)
||
!
strcmp
(
tk
->
psz_codec
,
"A_PCM/FLOAT/IEEE"
)
)
{
if
(
!
strcmp
(
tk
->
psz_codec
,
"A_PCM/INT/BIG"
)
)
{
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
't'
,
'w'
,
'o'
,
's'
);
}
else
{
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'a'
,
'r'
,
'a'
,
'w'
);
}
tk
->
fmt
.
audio
.
i_blockalign
=
(
tk
->
fmt
.
audio
.
i_bitspersample
+
7
)
/
8
*
tk
->
fmt
.
audio
.
i_channels
;
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"A_TTA1"
)
)
{
/* FIXME: support this codec */
msg_Err
(
p_demux
,
"TTA not supported yet[%d, n=%d]"
,
i_track
,
tk
->
i_number
);
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'u'
,
'n'
,
'd'
,
'f'
);
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"A_WAVPACK4"
)
)
{
/* FIXME: support this codec */
msg_Err
(
p_demux
,
"Wavpack not supported yet[%d, n=%d]"
,
i_track
,
tk
->
i_number
);
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'u'
,
'n'
,
'd'
,
'f'
);
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"S_TEXT/UTF8"
)
)
{
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
's'
,
'u'
,
'b'
,
't'
);
tk
->
fmt
.
subs
.
psz_encoding
=
strdup
(
"UTF-8"
);
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"S_TEXT/SSA"
)
||
!
strcmp
(
tk
->
psz_codec
,
"S_TEXT/ASS"
)
||
!
strcmp
(
tk
->
psz_codec
,
"S_SSA"
)
||
!
strcmp
(
tk
->
psz_codec
,
"S_ASS"
))
{
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
's'
,
's'
,
'a'
,
' '
);
tk
->
fmt
.
subs
.
psz_encoding
=
strdup
(
"UTF-8"
);
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"S_VOBSUB"
)
)
{
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
's'
,
'p'
,
'u'
,
' '
);
if
(
tk
->
i_extra_data
)
{
char
*
p_start
;
char
*
p_buf
=
(
char
*
)
malloc
(
tk
->
i_extra_data
+
1
);
memcpy
(
p_buf
,
tk
->
p_extra_data
,
tk
->
i_extra_data
);
p_buf
[
tk
->
i_extra_data
]
=
'\0'
;
p_start
=
strstr
(
p_buf
,
"size:"
);
if
(
sscanf
(
p_start
,
"size: %dx%d"
,
&
tk
->
fmt
.
subs
.
spu
.
i_original_frame_width
,
&
tk
->
fmt
.
subs
.
spu
.
i_original_frame_height
)
==
2
)
{
msg_Dbg
(
p_demux
,
"original frame size vobsubs: %dx%d"
,
tk
->
fmt
.
subs
.
spu
.
i_original_frame_width
,
tk
->
fmt
.
subs
.
spu
.
i_original_frame_height
);
}
else
{
msg_Warn
(
p_demux
,
"reading original frame size for vobsub failed"
);
}
free
(
p_buf
);
}
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"B_VOBBTN"
)
)
{
/* FIXME: support this codec */
msg_Err
(
p_demux
,
"Vob Buttons not supported yet[%d, n=%d]"
,
i_track
,
tk
->
i_number
);
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'u'
,
'n'
,
'd'
,
'f'
);
}
else
{
msg_Err
(
p_demux
,
"unknow codec id=`%s'"
,
tk
->
psz_codec
);
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'u'
,
'n'
,
'd'
,
'f'
);
}
if
(
tk
->
b_default
)
{
tk
->
fmt
.
i_priority
=
1000
;
}
tk
->
p_es
=
es_out_Add
(
p_demux
->
out
,
&
tk
->
fmt
);
#undef tk
}
}
/* add information */
/* add information */
InformationCreate
(
p_demux
);
InformationCreate
(
p_demux
);
...
@@ -1381,135 +1100,446 @@ static void BlockDecode( demux_t *p_demux, KaxBlock *block, mtime_t i_pts,
...
@@ -1381,135 +1100,446 @@ static void BlockDecode( demux_t *p_demux, KaxBlock *block, mtime_t i_pts,
if
(
p_block
==
NULL
)
if
(
p_block
==
NULL
)
{
{
break
;
break
;
}
#if defined(HAVE_ZLIB_H)
if
(
tk
->
i_compression_type
)
{
p_block
=
block_zlib_decompress
(
VLC_OBJECT
(
p_demux
),
p_block
);
}
#endif
// TODO implement correct timestamping when B frames are used
if
(
tk
->
fmt
.
i_cat
!=
VIDEO_ES
)
{
p_block
->
i_dts
=
p_block
->
i_pts
=
i_pts
;
}
else
{
p_block
->
i_dts
=
i_pts
;
p_block
->
i_pts
=
0
;
}
if
(
tk
->
fmt
.
i_cat
==
SPU_ES
&&
strcmp
(
tk
->
psz_codec
,
"S_VOBSUB"
)
)
{
p_block
->
i_length
=
i_duration
*
1000
;
}
es_out_Send
(
p_demux
->
out
,
tk
->
p_es
,
p_block
);
/* use time stamp only for first block */
i_pts
=
0
;
}
#undef tk
}
matroska_stream_t
*
demux_sys_t
::
AnalyseAllSegmentsFound
(
EbmlStream
*
p_estream
)
{
int
i_upper_lvl
=
0
;
size_t
i
;
EbmlElement
*
p_l0
,
*
p_l1
,
*
p_l2
;
bool
b_keep_stream
=
false
,
b_keep_segment
;
// verify the EBML Header
p_l0
=
p_estream
->
FindNextID
(
EbmlHead
::
ClassInfos
,
0xFFFFFFFFL
);
if
(
p_l0
==
NULL
)
{
return
NULL
;
}
p_l0
->
SkipData
(
*
p_estream
,
EbmlHead_Context
);
delete
p_l0
;
// find all segments in this file
p_l0
=
p_estream
->
FindNextID
(
KaxSegment
::
ClassInfos
,
0xFFFFFFFFL
);
if
(
p_l0
==
NULL
)
{
return
NULL
;
}
matroska_stream_t
*
p_stream1
=
new
matroska_stream_t
(
*
this
);
while
(
p_l0
!=
0
)
{
if
(
EbmlId
(
*
p_l0
)
==
KaxSegment
::
ClassInfos
.
GlobalId
)
{
EbmlParser
*
ep
;
matroska_segment_t
*
p_segment1
=
new
matroska_segment_t
(
*
this
,
*
p_estream
);
b_keep_segment
=
false
;
ep
=
new
EbmlParser
(
p_estream
,
p_l0
);
p_segment1
->
ep
=
ep
;
p_segment1
->
segment
=
(
KaxSegment
*
)
p_l0
;
while
((
p_l1
=
ep
->
Get
()))
{
if
(
MKV_IS_ID
(
p_l1
,
KaxInfo
))
{
// find the families of this segment
KaxInfo
*
p_info
=
static_cast
<
KaxInfo
*>
(
p_l1
);
p_info
->
Read
(
*
p_estream
,
KaxInfo
::
ClassInfos
.
Context
,
i_upper_lvl
,
p_l2
,
true
);
for
(
i
=
0
;
i
<
p_info
->
ListSize
();
i
++
)
{
EbmlElement
*
l
=
(
*
p_info
)[
i
];
if
(
MKV_IS_ID
(
l
,
KaxSegmentUID
)
)
{
KaxSegmentUID
*
p_uid
=
static_cast
<
KaxSegmentUID
*>
(
l
);
b_keep_segment
=
(
FindSegment
(
*
p_uid
)
==
NULL
);
if
(
!
b_keep_segment
)
break
;
// this segment is already known
p_segment1
->
segment_uid
=
*
(
new
KaxSegmentUID
(
*
p_uid
)
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxPrevUID
)
)
{
p_segment1
->
prev_segment_uid
=
*
(
new
KaxPrevUID
(
*
static_cast
<
KaxPrevUID
*>
(
l
)
)
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxNextUID
)
)
{
p_segment1
->
next_segment_uid
=
*
(
new
KaxNextUID
(
*
static_cast
<
KaxNextUID
*>
(
l
)
)
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxSegmentFamily
)
)
{
KaxSegmentFamily
*
p_fam
=
new
KaxSegmentFamily
(
*
static_cast
<
KaxSegmentFamily
*>
(
l
)
);
std
::
vector
<
KaxSegmentFamily
>::
iterator
iter
;
p_segment1
->
families
.
push_back
(
*
p_fam
);
}
}
break
;
}
}
if
(
b_keep_segment
)
{
b_keep_stream
=
true
;
p_stream1
->
segments
.
push_back
(
p_segment1
);
}
else
delete
p_segment1
;
}
p_l0
->
SkipData
(
*
p_estream
,
EbmlHead_Context
);
p_l0
=
p_estream
->
FindNextID
(
KaxSegment
::
ClassInfos
,
0xFFFFFFFFL
);
}
if
(
!
b_keep_stream
)
{
delete
p_stream1
;
p_stream1
=
NULL
;
}
return
p_stream1
;
}
bool
matroska_segment_t
::
Select
(
)
{
size_t
i_track
;
/* add all es */
msg_Dbg
(
&
sys
.
demuxer
,
"found %d es"
,
tracks
.
size
()
);
for
(
i_track
=
0
;
i_track
<
tracks
.
size
();
i_track
++
)
{
#define tk tracks[i_track]
if
(
tk
->
fmt
.
i_cat
==
UNKNOWN_ES
)
{
msg_Warn
(
&
sys
.
demuxer
,
"invalid track[%d, n=%d]"
,
i_track
,
tk
->
i_number
);
tk
->
p_es
=
NULL
;
continue
;
}
if
(
!
strcmp
(
tk
->
psz_codec
,
"V_MS/VFW/FOURCC"
)
)
{
if
(
tk
->
i_extra_data
<
(
int
)
sizeof
(
BITMAPINFOHEADER
)
)
{
msg_Err
(
&
sys
.
demuxer
,
"missing/invalid BITMAPINFOHEADER"
);
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'u'
,
'n'
,
'd'
,
'f'
);
}
else
{
BITMAPINFOHEADER
*
p_bih
=
(
BITMAPINFOHEADER
*
)
tk
->
p_extra_data
;
tk
->
fmt
.
video
.
i_width
=
GetDWLE
(
&
p_bih
->
biWidth
);
tk
->
fmt
.
video
.
i_height
=
GetDWLE
(
&
p_bih
->
biHeight
);
tk
->
fmt
.
i_codec
=
GetFOURCC
(
&
p_bih
->
biCompression
);
tk
->
fmt
.
i_extra
=
GetDWLE
(
&
p_bih
->
biSize
)
-
sizeof
(
BITMAPINFOHEADER
);
if
(
tk
->
fmt
.
i_extra
>
0
)
{
tk
->
fmt
.
p_extra
=
malloc
(
tk
->
fmt
.
i_extra
);
memcpy
(
tk
->
fmt
.
p_extra
,
&
p_bih
[
1
],
tk
->
fmt
.
i_extra
);
}
}
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"V_MPEG1"
)
||
!
strcmp
(
tk
->
psz_codec
,
"V_MPEG2"
)
)
{
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'm'
,
'p'
,
'g'
,
'v'
);
}
else
if
(
!
strncmp
(
tk
->
psz_codec
,
"V_MPEG4"
,
7
)
)
{
if
(
!
strcmp
(
tk
->
psz_codec
,
"V_MPEG4/MS/V3"
)
)
{
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'D'
,
'I'
,
'V'
,
'3'
);
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"V_MPEG4/ISO/AVC"
)
)
{
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'a'
,
'v'
,
'c'
,
'1'
);
tk
->
fmt
.
b_packetized
=
VLC_FALSE
;
tk
->
fmt
.
i_extra
=
tk
->
i_extra_data
;
tk
->
fmt
.
p_extra
=
malloc
(
tk
->
i_extra_data
);
memcpy
(
tk
->
fmt
.
p_extra
,
tk
->
p_extra_data
,
tk
->
i_extra_data
);
}
else
{
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'm'
,
'p'
,
'4'
,
'v'
);
}
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"V_QUICKTIME"
)
)
{
MP4_Box_t
*
p_box
=
(
MP4_Box_t
*
)
malloc
(
sizeof
(
MP4_Box_t
)
);
stream_t
*
p_mp4_stream
=
stream_MemoryNew
(
VLC_OBJECT
(
&
sys
.
demuxer
),
tk
->
p_extra_data
,
tk
->
i_extra_data
);
MP4_ReadBoxCommon
(
p_mp4_stream
,
p_box
);
MP4_ReadBox_sample_vide
(
p_mp4_stream
,
p_box
);
tk
->
fmt
.
i_codec
=
p_box
->
i_type
;
tk
->
fmt
.
video
.
i_width
=
p_box
->
data
.
p_sample_vide
->
i_width
;
tk
->
fmt
.
video
.
i_height
=
p_box
->
data
.
p_sample_vide
->
i_height
;
tk
->
fmt
.
i_extra
=
p_box
->
data
.
p_sample_vide
->
i_qt_image_description
;
tk
->
fmt
.
p_extra
=
malloc
(
tk
->
fmt
.
i_extra
);
memcpy
(
tk
->
fmt
.
p_extra
,
p_box
->
data
.
p_sample_vide
->
p_qt_image_description
,
tk
->
fmt
.
i_extra
);
MP4_FreeBox_sample_vide
(
p_box
);
stream_MemoryDelete
(
p_mp4_stream
,
VLC_TRUE
);
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"A_MS/ACM"
)
)
{
if
(
tk
->
i_extra_data
<
(
int
)
sizeof
(
WAVEFORMATEX
)
)
{
msg_Err
(
&
sys
.
demuxer
,
"missing/invalid WAVEFORMATEX"
);
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'u'
,
'n'
,
'd'
,
'f'
);
}
else
{
WAVEFORMATEX
*
p_wf
=
(
WAVEFORMATEX
*
)
tk
->
p_extra_data
;
wf_tag_to_fourcc
(
GetWLE
(
&
p_wf
->
wFormatTag
),
&
tk
->
fmt
.
i_codec
,
NULL
);
tk
->
fmt
.
audio
.
i_channels
=
GetWLE
(
&
p_wf
->
nChannels
);
tk
->
fmt
.
audio
.
i_rate
=
GetDWLE
(
&
p_wf
->
nSamplesPerSec
);
tk
->
fmt
.
i_bitrate
=
GetDWLE
(
&
p_wf
->
nAvgBytesPerSec
)
*
8
;
tk
->
fmt
.
audio
.
i_blockalign
=
GetWLE
(
&
p_wf
->
nBlockAlign
);;
tk
->
fmt
.
audio
.
i_bitspersample
=
GetWLE
(
&
p_wf
->
wBitsPerSample
);
tk
->
fmt
.
i_extra
=
GetWLE
(
&
p_wf
->
cbSize
);
if
(
tk
->
fmt
.
i_extra
>
0
)
{
tk
->
fmt
.
p_extra
=
malloc
(
tk
->
fmt
.
i_extra
);
memcpy
(
tk
->
fmt
.
p_extra
,
&
p_wf
[
1
],
tk
->
fmt
.
i_extra
);
}
}
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"A_MPEG/L3"
)
||
!
strcmp
(
tk
->
psz_codec
,
"A_MPEG/L2"
)
||
!
strcmp
(
tk
->
psz_codec
,
"A_MPEG/L1"
)
)
{
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'm'
,
'p'
,
'g'
,
'a'
);
}
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"A_AC3"
)
)
#if defined(HAVE_ZLIB_H)
if
(
tk
->
i_compression_type
)
{
{
p_block
=
block_zlib_decompress
(
VLC_OBJECT
(
p_demux
),
p_block
);
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'a'
,
'5'
,
'2'
,
' '
);
}
}
#endif
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"A_DTS"
)
)
// TODO implement correct timestamping when B frames are used
if
(
tk
->
fmt
.
i_cat
!=
VIDEO_ES
)
{
{
p_block
->
i_dts
=
p_block
->
i_pts
=
i_pts
;
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'd'
,
't'
,
's'
,
' '
)
;
}
}
else
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"A_FLAC"
)
)
{
{
p_block
->
i_dts
=
i_pts
;
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'f'
,
'l'
,
'a'
,
'c'
);
p_block
->
i_pts
=
0
;
tk
->
fmt
.
i_extra
=
tk
->
i_extra_data
;
tk
->
fmt
.
p_extra
=
malloc
(
tk
->
i_extra_data
);
memcpy
(
tk
->
fmt
.
p_extra
,
tk
->
p_extra_data
,
tk
->
i_extra_data
);
}
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"A_VORBIS"
)
)
if
(
tk
->
fmt
.
i_cat
==
SPU_ES
&&
strcmp
(
tk
->
psz_codec
,
"S_VOBSUB"
)
)
{
{
p_block
->
i_length
=
i_duration
*
1000
;
int
i
,
i_offset
=
1
,
i_size
[
3
],
i_extra
;
}
uint8_t
*
p_extra
;
es_out_Send
(
p_demux
->
out
,
tk
->
p_es
,
p_block
);
/* use time stamp only for first block */
i_pts
=
0
;
}
#undef tk
}
matroska_stream_t
*
demux_sys_t
::
AnalyseAllSegmentsFound
(
EbmlStream
*
p_estream
)
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'v'
,
'o'
,
'r'
,
'b'
);
{
int
i_upper_lvl
=
0
;
size_t
i
;
EbmlElement
*
p_l0
,
*
p_l1
,
*
p_l2
;
bool
b_keep_stream
=
false
,
b_keep_segment
;
// verify the EBML Header
/* Split the 3 headers */
p_l0
=
p_estream
->
FindNextID
(
EbmlHead
::
ClassInfos
,
0xFFFFFFFFL
);
if
(
tk
->
p_extra_data
[
0
]
!=
0x02
)
if
(
p_l0
==
NULL
)
msg_Err
(
&
sys
.
demuxer
,
"invalid vorbis header"
);
{
return
NULL
;
}
p_l0
->
SkipData
(
*
p_estream
,
EbmlHead_Context
);
delete
p_l0
;
// find all segments in this file
for
(
i
=
0
;
i
<
2
;
i
++
)
p_l0
=
p_estream
->
FindNextID
(
KaxSegment
::
ClassInfos
,
0xFFFFFFFFL
);
{
if
(
p_l0
==
NULL
)
i_size
[
i
]
=
0
;
{
while
(
i_offset
<
tk
->
i_extra_data
)
return
NULL
;
{
}
i_size
[
i
]
+=
tk
->
p_extra_data
[
i_offset
];
if
(
tk
->
p_extra_data
[
i_offset
++
]
!=
0xff
)
break
;
}
}
matroska_stream_t
*
p_stream1
=
new
matroska_stream_t
(
*
this
);
i_size
[
0
]
=
__MIN
(
i_size
[
0
],
tk
->
i_extra_data
-
i_offset
);
i_size
[
1
]
=
__MIN
(
i_size
[
1
],
tk
->
i_extra_data
-
i_offset
-
i_size
[
0
]);
i_size
[
2
]
=
tk
->
i_extra_data
-
i_offset
-
i_size
[
0
]
-
i_size
[
1
];
while
(
p_l0
!=
0
)
tk
->
fmt
.
i_extra
=
3
*
2
+
i_size
[
0
]
+
i_size
[
1
]
+
i_size
[
2
];
{
tk
->
fmt
.
p_extra
=
malloc
(
tk
->
fmt
.
i_extra
);
if
(
EbmlId
(
*
p_l0
)
==
KaxSegment
::
ClassInfos
.
GlobalId
)
p_extra
=
(
uint8_t
*
)
tk
->
fmt
.
p_extra
;
i_extra
=
0
;
for
(
i
=
0
;
i
<
3
;
i
++
)
{
*
(
p_extra
++
)
=
i_size
[
i
]
>>
8
;
*
(
p_extra
++
)
=
i_size
[
i
]
&
0xFF
;
memcpy
(
p_extra
,
tk
->
p_extra_data
+
i_offset
+
i_extra
,
i_size
[
i
]
);
p_extra
+=
i_size
[
i
];
i_extra
+=
i_size
[
i
];
}
}
else
if
(
!
strncmp
(
tk
->
psz_codec
,
"A_AAC/MPEG2/"
,
strlen
(
"A_AAC/MPEG2/"
)
)
||
!
strncmp
(
tk
->
psz_codec
,
"A_AAC/MPEG4/"
,
strlen
(
"A_AAC/MPEG4/"
)
)
)
{
{
EbmlParser
*
ep
;
int
i_profile
,
i_srate
;
matroska_segment_t
*
p_segment1
=
new
matroska_segment_t
(
*
this
,
*
p_estream
);
static
unsigned
int
i_sample_rates
[]
=
b_keep_segment
=
false
;
{
96000
,
88200
,
64000
,
48000
,
44100
,
32000
,
24000
,
22050
,
16000
,
12000
,
11025
,
8000
,
7350
,
0
,
0
,
0
};
ep
=
new
EbmlParser
(
p_estream
,
p_l0
);
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'm'
,
'p'
,
'4'
,
'a'
);
p_segment1
->
ep
=
ep
;
/* create data for faad (MP4DecSpecificDescrTag)*/
p_segment1
->
segment
=
(
KaxSegment
*
)
p_l0
;
while
((
p_l1
=
ep
->
Get
())
)
if
(
!
strcmp
(
&
tk
->
psz_codec
[
12
],
"MAIN"
)
)
{
{
if
(
MKV_IS_ID
(
p_l1
,
KaxInfo
))
i_profile
=
0
;
{
}
// find the families of this segment
else
if
(
!
strcmp
(
&
tk
->
psz_codec
[
12
],
"LC"
)
)
KaxInfo
*
p_info
=
static_cast
<
KaxInfo
*>
(
p_l1
);
{
i_profile
=
1
;
p_info
->
Read
(
*
p_estream
,
KaxInfo
::
ClassInfos
.
Context
,
i_upper_lvl
,
p_l2
,
true
);
}
for
(
i
=
0
;
i
<
p_info
->
ListSize
();
i
++
)
else
if
(
!
strcmp
(
&
tk
->
psz_codec
[
12
],
"SSR"
)
)
{
{
EbmlElement
*
l
=
(
*
p_info
)[
i
];
i_profile
=
2
;
}
else
{
i_profile
=
3
;
}
if
(
MKV_IS_ID
(
l
,
KaxSegmentUID
)
)
for
(
i_srate
=
0
;
i_srate
<
13
;
i_srate
++
)
{
{
KaxSegmentUID
*
p_uid
=
static_cast
<
KaxSegmentUID
*>
(
l
);
if
(
i_sample_rates
[
i_srate
]
==
tk
->
fmt
.
audio
.
i_rate
)
b_keep_segment
=
(
FindSegment
(
*
p_uid
)
==
NULL
);
{
if
(
!
b_keep_segment
)
break
;
// this segment is already known
p_segment1
->
segment_uid
=
*
(
new
KaxSegmentUID
(
*
p_uid
)
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxPrevUID
)
)
{
p_segment1
->
prev_segment_uid
=
*
(
new
KaxPrevUID
(
*
static_cast
<
KaxPrevUID
*>
(
l
)
)
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxNextUID
)
)
{
p_segment1
->
next_segment_uid
=
*
(
new
KaxNextUID
(
*
static_cast
<
KaxNextUID
*>
(
l
)
)
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxSegmentFamily
)
)
{
KaxSegmentFamily
*
p_fam
=
new
KaxSegmentFamily
(
*
static_cast
<
KaxSegmentFamily
*>
(
l
)
);
std
::
vector
<
KaxSegmentFamily
>::
iterator
iter
;
p_segment1
->
families
.
push_back
(
*
p_fam
);
}
}
break
;
break
;
}
}
}
}
if
(
b_keep_segment
)
msg_Dbg
(
&
sys
.
demuxer
,
"profile=%d srate=%d"
,
i_profile
,
i_srate
);
tk
->
fmt
.
i_extra
=
2
;
tk
->
fmt
.
p_extra
=
malloc
(
tk
->
fmt
.
i_extra
);
((
uint8_t
*
)
tk
->
fmt
.
p_extra
)[
0
]
=
((
i_profile
+
1
)
<<
3
)
|
((
i_srate
&
0xe
)
>>
1
);
((
uint8_t
*
)
tk
->
fmt
.
p_extra
)[
1
]
=
((
i_srate
&
0x1
)
<<
7
)
|
(
tk
->
fmt
.
audio
.
i_channels
<<
3
);
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"A_PCM/INT/BIG"
)
||
!
strcmp
(
tk
->
psz_codec
,
"A_PCM/INT/LIT"
)
||
!
strcmp
(
tk
->
psz_codec
,
"A_PCM/FLOAT/IEEE"
)
)
{
if
(
!
strcmp
(
tk
->
psz_codec
,
"A_PCM/INT/BIG"
)
)
{
{
b_keep_stream
=
true
;
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
't'
,
'w'
,
'o'
,
's'
);
p_stream1
->
segments
.
push_back
(
p_segment1
);
}
}
else
else
delete
p_segment1
;
{
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'a'
,
'r'
,
'a'
,
'w'
);
}
tk
->
fmt
.
audio
.
i_blockalign
=
(
tk
->
fmt
.
audio
.
i_bitspersample
+
7
)
/
8
*
tk
->
fmt
.
audio
.
i_channels
;
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"A_TTA1"
)
)
{
/* FIXME: support this codec */
msg_Err
(
&
sys
.
demuxer
,
"TTA not supported yet[%d, n=%d]"
,
i_track
,
tk
->
i_number
);
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'u'
,
'n'
,
'd'
,
'f'
);
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"A_WAVPACK4"
)
)
{
/* FIXME: support this codec */
msg_Err
(
&
sys
.
demuxer
,
"Wavpack not supported yet[%d, n=%d]"
,
i_track
,
tk
->
i_number
);
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'u'
,
'n'
,
'd'
,
'f'
);
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"S_TEXT/UTF8"
)
)
{
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
's'
,
'u'
,
'b'
,
't'
);
tk
->
fmt
.
subs
.
psz_encoding
=
strdup
(
"UTF-8"
);
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"S_TEXT/SSA"
)
||
!
strcmp
(
tk
->
psz_codec
,
"S_TEXT/ASS"
)
||
!
strcmp
(
tk
->
psz_codec
,
"S_SSA"
)
||
!
strcmp
(
tk
->
psz_codec
,
"S_ASS"
))
{
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
's'
,
's'
,
'a'
,
' '
);
tk
->
fmt
.
subs
.
psz_encoding
=
strdup
(
"UTF-8"
);
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"S_VOBSUB"
)
)
{
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
's'
,
'p'
,
'u'
,
' '
);
if
(
tk
->
i_extra_data
)
{
char
*
p_start
;
char
*
p_buf
=
(
char
*
)
malloc
(
tk
->
i_extra_data
+
1
);
memcpy
(
p_buf
,
tk
->
p_extra_data
,
tk
->
i_extra_data
);
p_buf
[
tk
->
i_extra_data
]
=
'\0'
;
p_start
=
strstr
(
p_buf
,
"size:"
);
if
(
sscanf
(
p_start
,
"size: %dx%d"
,
&
tk
->
fmt
.
subs
.
spu
.
i_original_frame_width
,
&
tk
->
fmt
.
subs
.
spu
.
i_original_frame_height
)
==
2
)
{
msg_Dbg
(
&
sys
.
demuxer
,
"original frame size vobsubs: %dx%d"
,
tk
->
fmt
.
subs
.
spu
.
i_original_frame_width
,
tk
->
fmt
.
subs
.
spu
.
i_original_frame_height
);
}
else
{
msg_Warn
(
&
sys
.
demuxer
,
"reading original frame size for vobsub failed"
);
}
free
(
p_buf
);
}
}
else
if
(
!
strcmp
(
tk
->
psz_codec
,
"B_VOBBTN"
)
)
{
/* FIXME: support this codec */
msg_Err
(
&
sys
.
demuxer
,
"Vob Buttons not supported yet[%d, n=%d]"
,
i_track
,
tk
->
i_number
);
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'u'
,
'n'
,
'd'
,
'f'
);
}
else
{
msg_Err
(
&
sys
.
demuxer
,
"unknow codec id=`%s'"
,
tk
->
psz_codec
);
tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'u'
,
'n'
,
'd'
,
'f'
);
}
if
(
tk
->
b_default
)
{
tk
->
fmt
.
i_priority
=
1000
;
}
}
p_l0
->
SkipData
(
*
p_estream
,
EbmlHead_Context
);
tk
->
p_es
=
es_out_Add
(
sys
.
demuxer
.
out
,
&
tk
->
fmt
);
p_l0
=
p_estream
->
FindNextID
(
KaxSegment
::
ClassInfos
,
0xFFFFFFFFL
);
#undef tk
}
}
return
true
;
}
if
(
!
b_keep_stream
)
void
matroska_segment_t
::
UnSelect
(
)
{
size_t
i_track
;
for
(
i_track
=
0
;
i_track
<
tracks
.
size
();
i_track
++
)
{
{
delete
p_stream1
;
#define tk tracks[i_track]
p_stream1
=
NULL
;
if
(
tk
->
p_es
!=
NULL
)
{
es_out_Del
(
sys
.
demuxer
.
out
,
tk
->
p_es
);
tk
->
p_es
=
NULL
;
}
#undef tk
}
}
return
p_stream1
;
}
}
static
void
UpdateCurrentToChapter
(
demux_t
&
demux
)
static
void
UpdateCurrentToChapter
(
demux_t
&
demux
)
...
@@ -1767,8 +1797,13 @@ static int Demux( demux_t *p_demux)
...
@@ -1767,8 +1797,13 @@ static int Demux( demux_t *p_demux)
/* nothing left to read in this ordered edition */
/* nothing left to read in this ordered edition */
if
(
p_stream
->
i_current_segment
==
p_stream
->
segments
.
size
()
-
1
)
if
(
p_stream
->
i_current_segment
==
p_stream
->
segments
.
size
()
-
1
)
return
0
;
return
0
;
p_segment
->
UnSelect
(
);
/* switch to the next segment (TODO update the duration) */
/* switch to the next segment (TODO update the duration) */
p_stream
->
i_current_segment
++
;
p_stream
->
i_current_segment
++
;
p_segment
=
p_stream
->
Segment
();
if
(
!
p_segment
||
!
p_segment
->
Select
(
)
)
return
0
;
continue
;
continue
;
}
}
...
@@ -3441,7 +3476,7 @@ bool matroska_segment_t::Preload( )
...
@@ -3441,7 +3476,7 @@ bool matroska_segment_t::Preload( )
return
true
;
return
true
;
}
}
matroska_segment_t
*
demux_sys_t
::
FindSegment
(
EbmlBinary
&
uid
)
const
matroska_segment_t
*
demux_sys_t
::
FindSegment
(
const
EbmlBinary
&
uid
)
const
{
{
matroska_segment_t
*
p_segment
=
NULL
;
matroska_segment_t
*
p_segment
=
NULL
;
for
(
size_t
i
=
0
;
i
<
streams
.
size
()
&&
p_segment
==
NULL
;
i
++
)
for
(
size_t
i
=
0
;
i
<
streams
.
size
()
&&
p_segment
==
NULL
;
i
++
)
...
@@ -3451,7 +3486,7 @@ matroska_segment_t *demux_sys_t::FindSegment( EbmlBinary & uid ) const
...
@@ -3451,7 +3486,7 @@ matroska_segment_t *demux_sys_t::FindSegment( EbmlBinary & uid ) const
return
p_segment
;
return
p_segment
;
}
}
matroska_segment_t
*
matroska_stream_t
::
FindSegment
(
EbmlBinary
&
uid
)
const
matroska_segment_t
*
matroska_stream_t
::
FindSegment
(
const
EbmlBinary
&
uid
)
const
{
{
for
(
size_t
i
=
0
;
i
<
segments
.
size
();
i
++
)
for
(
size_t
i
=
0
;
i
<
segments
.
size
();
i
++
)
{
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment