Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
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
Commits
59e5b9a5
Commit
59e5b9a5
authored
Jul 20, 2012
by
Denis Charmet
Committed by
Jean-Baptiste Kempf
Jul 22, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adding Cook support in mkv
Signed-off-by:
Jean-Baptiste Kempf
<
jb@videolan.org
>
parent
4d7dd6cf
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
232 additions
and
23 deletions
+232
-23
modules/demux/mkv/matroska_segment.cpp
modules/demux/mkv/matroska_segment.cpp
+37
-4
modules/demux/mkv/mkv.cpp
modules/demux/mkv/mkv.cpp
+21
-18
modules/demux/mkv/mkv.hpp
modules/demux/mkv/mkv.hpp
+10
-0
modules/demux/mkv/util.cpp
modules/demux/mkv/util.cpp
+106
-1
modules/demux/mkv/util.hpp
modules/demux/mkv/util.hpp
+58
-0
No files found.
modules/demux/mkv/matroska_segment.cpp
View file @
59e5b9a5
...
...
@@ -23,11 +23,9 @@
*****************************************************************************/
#include "matroska_segment.hpp"
#include "chapters.hpp"
#include "demux.hpp"
#include "util.hpp"
#include "Ebml_parser.hpp"
extern
"C"
{
...
...
@@ -87,6 +85,7 @@ matroska_segment_c::~matroska_segment_c()
{
delete
tracks
[
i_track
]
->
p_compression_data
;
es_format_Clean
(
&
tracks
[
i_track
]
->
fmt
);
delete
tracks
[
i_track
]
->
p_sys
;
free
(
tracks
[
i_track
]
->
p_extra_data
);
free
(
tracks
[
i_track
]
->
psz_codec
);
delete
tracks
[
i_track
];
...
...
@@ -696,6 +695,9 @@ void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_
int
i_cat
;
bool
b_has_key
=
false
;
for
(
size_t
i
=
0
;
i
<
tracks
.
size
();
i
++
)
tracks
[
i
]
->
i_last_dts
=
VLC_TS_INVALID
;
if
(
i_global_position
>=
0
)
{
/* Special case for seeking in files with no cues */
...
...
@@ -1286,14 +1288,45 @@ bool matroska_segment_c::Select( mtime_t i_start_time )
msg_Err
(
&
sys
.
demuxer
,
"Invalid Real ExtraData 0x%4.4s"
,
(
char
*
)
p
);
p_tk
->
fmt
.
i_codec
=
VLC_FOURCC
(
'u'
,
'n'
,
'd'
,
'f'
);
}
else
{
else
{
real_audio_private
*
priv
=
(
real_audio_private
*
)
p_tk
->
p_extra_data
;
if
(
!
strcmp
(
p_tk
->
psz_codec
,
"A_REAL/COOK"
)
)
{
p_tk
->
fmt
.
i_codec
=
VLC_CODEC_COOK
;
p_tk
->
fmt
.
audio
.
i_blockalign
=
hton16
(
priv
->
sub_packet_size
);
}
else
if
(
!
strcmp
(
p_tk
->
psz_codec
,
"A_REAL/ATRC"
)
)
p_tk
->
fmt
.
i_codec
=
VLC_CODEC_ATRAC3
;
else
if
(
!
strcmp
(
p_tk
->
psz_codec
,
"A_REAL/28_8"
)
)
p_tk
->
fmt
.
i_codec
=
VLC_CODEC_RA_288
;
/* FIXME RALF and SIPR */
uint16_t
version
=
(
uint16_t
)
hton16
(
priv
->
version
);
p_tk
->
p_sys
=
new
Cook_PrivateTrackData
(
hton16
(
priv
->
sub_packet_h
),
hton16
(
priv
->
frame_size
),
hton16
(
priv
->
sub_packet_size
));
if
(
unlikely
(
!
p_tk
->
p_sys
)
)
continue
;
if
(
unlikely
(
p_tk
->
p_sys
->
Init
()
)
)
continue
;
if
(
version
==
4
)
{
real_audio_private_v4
*
v4
=
(
real_audio_private_v4
*
)
priv
;
p_tk
->
fmt
.
audio
.
i_channels
=
hton16
(
v4
->
channels
);
p_tk
->
fmt
.
audio
.
i_bitspersample
=
hton16
(
v4
->
sample_size
);
p_tk
->
fmt
.
audio
.
i_rate
=
hton16
(
v4
->
sample_rate
);
}
else
if
(
version
==
5
)
{
real_audio_private_v5
*
v5
=
(
real_audio_private_v5
*
)
priv
;
p_tk
->
fmt
.
audio
.
i_channels
=
hton16
(
v5
->
channels
);
p_tk
->
fmt
.
audio
.
i_bitspersample
=
hton16
(
v5
->
sample_size
);
p_tk
->
fmt
.
audio
.
i_rate
=
hton16
(
v5
->
sample_rate
);
}
msg_Dbg
(
&
sys
.
demuxer
,
"%d channels %d bits %d Hz"
,
p_tk
->
fmt
.
audio
.
i_channels
,
p_tk
->
fmt
.
audio
.
i_bitspersample
,
p_tk
->
fmt
.
audio
.
i_rate
);
fill_extra_data
(
p_tk
,
p_tk
->
fmt
.
i_codec
==
VLC_CODEC_RA_288
?
0
:
78
);
}
...
...
modules/demux/mkv/mkv.cpp
View file @
59e5b9a5
...
...
@@ -468,20 +468,6 @@ static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, virtual_ch
p_vsegment
->
Seek
(
*
p_demux
,
i_date
,
i_time_offset
,
p_chapter
,
i_global_position
);
}
/* Utility function for BlockDecode */
static
block_t
*
MemToBlock
(
uint8_t
*
p_mem
,
size_t
i_mem
,
size_t
offset
)
{
if
(
unlikely
(
i_mem
>
SIZE_MAX
-
offset
)
)
return
NULL
;
block_t
*
p_block
=
block_New
(
p_demux
,
i_mem
+
offset
);
if
(
likely
(
p_block
!=
NULL
)
)
{
memcpy
(
p_block
->
p_buffer
+
offset
,
p_mem
,
i_mem
);
}
return
p_block
;
}
/* Needed by matroska_segment::Seek() and Seek */
void
BlockDecode
(
demux_t
*
p_demux
,
KaxBlock
*
block
,
KaxSimpleBlock
*
simpleblock
,
mtime_t
i_pts
,
mtime_t
i_duration
,
bool
f_mandatory
)
...
...
@@ -591,6 +577,17 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock
memcpy
(
p_block
->
p_buffer
,
tk
->
p_compression_data
->
GetBuffer
(),
tk
->
p_compression_data
->
GetSize
()
);
}
if
(
tk
->
fmt
.
i_codec
==
VLC_CODEC_COOK
||
tk
->
fmt
.
i_codec
==
VLC_CODEC_ATRAC3
)
{
handle_real_audio
(
p_demux
,
tk
,
p_block
,
i_pts
);
block_Release
(
p_block
);
i_pts
=
(
tk
->
i_default_duration
)
?
i_pts
+
(
mtime_t
)(
tk
->
i_default_duration
/
1000
)
:
VLC_TS_INVALID
;
continue
;
}
if
(
tk
->
fmt
.
i_cat
==
NAV_ES
)
{
// TODO handle the start/stop times of this packet
...
...
@@ -624,6 +621,7 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock
p_block
->
i_dts
=
min
(
i_pts
,
tk
->
i_last_dts
+
(
mtime_t
)(
tk
->
i_default_duration
/
1000
)
);
}
}
if
(
tk
->
fmt
.
i_cat
==
VIDEO_ES
||
tk
->
fmt
.
i_cat
==
AUDIO_ES
)
tk
->
i_last_dts
=
p_block
->
i_dts
;
#if 0
...
...
@@ -719,11 +717,16 @@ static int Demux( demux_t *p_demux)
else
p_sys
->
i_pts
=
p_sys
->
i_chapter_time
+
(
block
->
GlobalTimecode
()
/
(
mtime_t
)
1000
);
/* The blocks are in coding order so we can safely consider that only references are in chronological order */
if
(
p_sys
->
i_pts
>
p_sys
->
i_pcr
+
300000
)
mtime_t
i_pcr
=
VLC_TS_INVALID
;
for
(
size_t
i
=
0
;
i
<
p_segment
->
tracks
.
size
();
i
++
)
if
(
p_segment
->
tracks
[
i
]
->
i_last_dts
>
VLC_TS_INVALID
&&
(
p_segment
->
tracks
[
i
]
->
i_last_dts
<
i_pcr
||
i_pcr
==
VLC_TS_INVALID
))
i_pcr
=
p_segment
->
tracks
[
i
]
->
i_last_dts
;
if
(
i_pcr
>
p_sys
->
i_pcr
+
300000
)
{
es_out_Control
(
p_demux
->
out
,
ES_OUT_SET_PCR
,
VLC_TS_0
+
p_sys
->
i_pcr
);
p_sys
->
i_pcr
=
p_sys
->
i_pts
;
p_sys
->
i_pcr
=
i_pcr
;
}
if
(
p_sys
->
i_pts
>=
p_sys
->
i_start_pts
)
...
...
modules/demux/mkv/mkv.hpp
View file @
59e5b9a5
...
...
@@ -174,6 +174,13 @@ struct matroska_stream_c
/*****************************************************************************
* definitions of structures and functions used by this plugins
*****************************************************************************/
class
PrivateTrackData
{
public:
virtual
~
PrivateTrackData
()
{}
virtual
int32_t
Init
()
{
return
0
;
}
};
struct
mkv_track_t
{
// ~mkv_track_t();
...
...
@@ -202,6 +209,9 @@ struct mkv_track_t
/* audio */
unsigned
int
i_original_rate
;
/* Private track paramters */
PrivateTrackData
*
p_sys
;
bool
b_inited
;
/* data to be send first */
int
i_data_init
;
...
...
modules/demux/mkv/util.cpp
View file @
59e5b9a5
...
...
@@ -21,9 +21,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "util.hpp"
#include "demux.hpp"
#include <stdint.h>
/*****************************************************************************
* Local prototypes
*****************************************************************************/
...
...
@@ -78,4 +79,108 @@ block_t *block_zlib_decompress( vlc_object_t *p_this, block_t *p_in_block ) {
}
#endif
/* Utility function for BlockDecode */
block_t
*
MemToBlock
(
uint8_t
*
p_mem
,
size_t
i_mem
,
size_t
offset
)
{
if
(
unlikely
(
i_mem
>
SIZE_MAX
-
offset
)
)
return
NULL
;
block_t
*
p_block
=
block_New
(
p_demux
,
i_mem
+
offset
);
if
(
likely
(
p_block
!=
NULL
)
)
{
memcpy
(
p_block
->
p_buffer
+
offset
,
p_mem
,
i_mem
);
}
return
p_block
;
}
void
handle_real_audio
(
demux_t
*
p_demux
,
mkv_track_t
*
p_tk
,
block_t
*
p_blk
,
mtime_t
i_pts
)
{
uint8_t
*
p_frame
=
p_blk
->
p_buffer
;
Cook_PrivateTrackData
*
p_sys
=
(
Cook_PrivateTrackData
*
)
p_tk
->
p_sys
;
size_t
size
=
p_blk
->
i_buffer
;
if
(
p_tk
->
i_last_dts
==
VLC_TS_INVALID
)
{
for
(
size_t
i
=
0
;
i
<
p_sys
->
i_subpackets
;
i
++
)
if
(
p_sys
->
p_subpackets
[
i
]
)
{
block_Release
(
p_sys
->
p_subpackets
[
i
]);
p_sys
->
p_subpackets
[
i
]
=
NULL
;
}
p_sys
->
i_subpacket
=
0
;
}
if
(
p_tk
->
fmt
.
i_codec
==
VLC_CODEC_COOK
||
p_tk
->
fmt
.
i_codec
==
VLC_CODEC_ATRAC3
)
{
const
uint32_t
i_num
=
p_sys
->
i_frame_size
/
p_sys
->
i_subpacket_size
;
const
int
y
=
p_sys
->
i_subpacket
/
(
p_sys
->
i_frame_size
/
p_sys
->
i_subpacket_size
);
for
(
int
i
=
0
;
i
<
i_num
;
i
++
)
{
int
i_index
=
p_sys
->
i_sub_packet_h
*
i
+
((
p_sys
->
i_sub_packet_h
+
1
)
/
2
)
*
(
y
&
1
)
+
(
y
>>
1
);
if
(
i_index
>=
p_sys
->
i_subpackets
)
return
;
block_t
*
p_block
=
block_New
(
p_demux
,
p_sys
->
i_subpacket_size
);
if
(
!
p_block
)
return
;
if
(
size
<
p_sys
->
i_subpacket_size
)
return
;
memcpy
(
p_block
->
p_buffer
,
p_frame
,
p_sys
->
i_subpacket_size
);
p_block
->
i_dts
=
VLC_TS_INVALID
;
p_block
->
i_pts
=
VLC_TS_INVALID
;
if
(
!
p_sys
->
i_subpacket
)
{
p_tk
->
i_last_dts
=
p_block
->
i_pts
=
i_pts
+
VLC_TS_0
;
}
p_frame
+=
p_sys
->
i_subpacket_size
;
size
-=
p_sys
->
i_subpacket_size
;
p_sys
->
i_subpacket
++
;
p_sys
->
p_subpackets
[
i_index
]
=
p_block
;
}
}
else
{
/*TODO*/
}
if
(
p_sys
->
i_subpacket
==
p_sys
->
i_subpackets
)
{
for
(
size_t
i
=
0
;
i
<
p_sys
->
i_subpackets
;
i
++
)
{
es_out_Send
(
p_demux
->
out
,
p_tk
->
p_es
,
p_sys
->
p_subpackets
[
i
]);
p_sys
->
p_subpackets
[
i
]
=
NULL
;
}
p_sys
->
i_subpacket
=
0
;
}
}
int32_t
Cook_PrivateTrackData
::
Init
()
{
i_subpackets
=
(
size_t
)
i_sub_packet_h
*
(
size_t
)
i_frame_size
/
(
size_t
)
i_subpacket_size
;
p_subpackets
=
(
block_t
**
)
calloc
(
i_subpackets
,
sizeof
(
block_t
*
));
if
(
unlikely
(
!
p_subpackets
)
)
{
i_subpackets
=
0
;
return
1
;
}
return
0
;
}
Cook_PrivateTrackData
::~
Cook_PrivateTrackData
()
{
for
(
size_t
i
=
0
;
i
<
i_subpackets
;
i
++
)
if
(
p_subpackets
[
i
]
)
block_Release
(
p_subpackets
[
i
]
);
free
(
p_subpackets
);
}
modules/demux/mkv/util.hpp
View file @
59e5b9a5
...
...
@@ -26,3 +26,61 @@
#include "mkv.hpp"
block_t
*
block_zlib_decompress
(
vlc_object_t
*
p_this
,
block_t
*
p_in_block
);
block_t
*
MemToBlock
(
uint8_t
*
p_mem
,
size_t
i_mem
,
size_t
offset
);
void
handle_real_audio
(
demux_t
*
p_demux
,
mkv_track_t
*
p_tk
,
block_t
*
p_blk
,
mtime_t
i_pts
);
struct
real_audio_private
{
uint32_t
fourcc
;
uint16_t
version
;
uint16_t
unknown1
;
uint8_t
unknown2
[
12
];
uint16_t
unknown3
;
uint16_t
flavor
;
uint32_t
coded_frame_size
;
uint32_t
unknown4
[
3
];
uint16_t
sub_packet_h
;
uint16_t
frame_size
;
uint16_t
sub_packet_size
;
uint16_t
unknown5
;
};
struct
real_audio_private_v4
{
real_audio_private
header
;
uint16_t
sample_rate
;
uint16_t
unknown
;
uint16_t
sample_size
;
uint16_t
channels
;
};
struct
real_audio_private_v5
{
real_audio_private
header
;
uint32_t
unknown1
;
uint16_t
unknown2
;
uint16_t
sample_rate
;
uint16_t
unknown3
;
uint16_t
sample_size
;
uint16_t
channels
;
};
class
Cook_PrivateTrackData
:
public
PrivateTrackData
{
public:
Cook_PrivateTrackData
(
uint16_t
sph
,
uint16_t
fs
,
uint16_t
sps
)
:
i_sub_packet_h
(
sph
),
i_frame_size
(
fs
),
i_subpacket_size
(
sps
),
p_subpackets
(
NULL
),
i_subpackets
(
0
),
i_subpacket
(
0
){}
~
Cook_PrivateTrackData
();
int32_t
Init
();
uint16_t
i_sub_packet_h
;
uint16_t
i_frame_size
;
uint16_t
i_subpacket_size
;
block_t
**
p_subpackets
;
size_t
i_subpackets
;
size_t
i_subpacket
;
};
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