Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
godot
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
community
godot
Commits
e71f1099
Commit
e71f1099
authored
Mar 09, 2018
by
ShyRed
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update libwebm
Update of libwebm. Up-to-date version of libwebm contains several bugfixes that allow playback of files that would crash Godot otherwise.
parent
b8423694
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
372 additions
and
110 deletions
+372
-110
SCsub
modules/webm/SCsub
+4
-0
README.libvpx
thirdparty/libsimplewebm/libwebm/README.libvpx
+1
-1
webmids.h
thirdparty/libsimplewebm/libwebm/common/webmids.h
+8
-0
mkvparser.cc
thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.cc
+324
-108
mkvparser.h
thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.h
+35
-1
No files found.
modules/webm/SCsub
View file @
e71f1099
...
...
@@ -18,6 +18,10 @@ thirdparty_libsimplewebm_sources = [thirdparty_libsimplewebm_dir + file for file
env_webm
.
add_source_files
(
env
.
modules_sources
,
thirdparty_libsimplewebm_sources
)
env_webm
.
Append
(
CPPPATH
=
[
thirdparty_libsimplewebm_dir
,
thirdparty_libsimplewebm_dir
+
"libwebm/"
])
# upstream uses c++11
if
(
not
env_webm
.
msvc
):
env_webm
.
Append
(
CCFLAGS
=
"-std=c++11"
)
# also requires libogg, libvorbis and libopus
if
env
[
'builtin_libogg'
]:
env_webm
.
Append
(
CPPPATH
=
[
"#thirdparty/libogg"
])
...
...
thirdparty/libsimplewebm/libwebm/README.libvpx
View file @
e71f1099
URL: https://chromium.googlesource.com/webm/libwebm
Version:
32d5ac49414a8914ec1e1f285f3f927c6e8ec29d
Version:
d7c62173ff6b4a5e0a2f86683a5b67db98cf09bf
License: BSD
License File: LICENSE.txt
...
...
thirdparty/libsimplewebm/libwebm/common/webmids.h
View file @
e71f1099
...
...
@@ -124,6 +124,14 @@ enum MkvId {
kMkvLuminanceMin
=
0x55DA
,
// end mastering metadata
// end colour
// projection
kMkvProjection
=
0x7670
,
kMkvProjectionType
=
0x7671
,
kMkvProjectionPrivate
=
0x7672
,
kMkvProjectionPoseYaw
=
0x7673
,
kMkvProjectionPosePitch
=
0x7674
,
kMkvProjectionPoseRoll
=
0x7675
,
// end projection
// audio
kMkvAudio
=
0xE1
,
kMkvSamplingFrequency
=
0xB5
,
...
...
thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.cc
View file @
e71f1099
...
...
@@ -12,51 +12,30 @@
#define MSC_COMPAT
#endif
#include <assert.h>
#include <float.h>
#include <limits.h>
#include <math.h>
#include <string.h>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstring>
#include <memory>
#include <new>
#include "common/webmids.h"
namespace
mkvparser
{
const
long
long
kStringElementSizeLimit
=
20
*
1000
*
1000
;
const
float
MasteringMetadata
::
kValueNotPresent
=
FLT_MAX
;
const
long
long
Colour
::
kValueNotPresent
=
LLONG_MAX
;
const
float
Projection
::
kValueNotPresent
=
FLT_MAX
;
#ifdef MSC_COMPAT
inline
bool
isnan
(
double
val
)
{
return
!!
_isnan
(
val
);
}
inline
bool
isinf
(
double
val
)
{
return
!
_finite
(
val
);
}
#else
inline
bool
isnan
(
double
val
)
{
return
std
::
isnan
(
val
);
}
inline
bool
isinf
(
double
val
)
{
return
std
::
isinf
(
val
);
}
#endif // MSC_COMPAT
template
<
typename
T
>
class
my_auto_ptr
{
my_auto_ptr
(
const
my_auto_ptr
&
);
T
*
operator
=
(
const
my_auto_ptr
&
);
T
*
m_ptr
;
public
:
my_auto_ptr
(
T
*
ptr
)
:
m_ptr
(
ptr
)
{}
my_auto_ptr
()
:
m_ptr
(
NULL
)
{}
~
my_auto_ptr
()
{
delete
m_ptr
;
}
T
*
release
()
{
T
*
ptr
=
m_ptr
;
m_ptr
=
NULL
;
return
ptr
;
}
T
*
operator
->
()
const
{
return
m_ptr
;
}
};
IMkvReader
::~
IMkvReader
()
{}
template
<
typename
Type
>
...
...
@@ -72,7 +51,7 @@ Type* SafeArrayAlloc(unsigned long long num_elements,
if
(
num_bytes
!=
static_cast
<
size_t
>
(
num_bytes
))
return
NULL
;
return
new
Type
[
static_cast
<
size_t
>
(
num_bytes
)];
return
new
(
std
::
nothrow
)
Type
[
static_cast
<
size_t
>
(
num_bytes
)];
}
void
GetVersion
(
int
&
major
,
int
&
minor
,
int
&
build
,
int
&
revision
)
{
...
...
@@ -304,7 +283,7 @@ long UnserializeFloat(IMkvReader* pReader, long long pos, long long size_,
result
=
d
;
}
if
(
isinf
(
result
)
||
isnan
(
result
))
if
(
mkvparser
::
isinf
(
result
)
||
mkvparser
::
isnan
(
result
))
return
E_FILE_FORMAT_INVALID
;
return
0
;
...
...
@@ -347,7 +326,7 @@ long UnserializeString(IMkvReader* pReader, long long pos, long long size,
delete
[]
str
;
str
=
NULL
;
if
(
size
>=
LONG_MAX
||
size
<
0
)
if
(
size
>=
LONG_MAX
||
size
<
0
||
size
>
kStringElementSizeLimit
)
return
E_FILE_FORMAT_INVALID
;
// +1 for '\0' terminator
...
...
@@ -818,7 +797,9 @@ long long Segment::CreateInstance(IMkvReader* pReader, long long pos,
else
if
((
pos
+
size
)
>
total
)
size
=
-
1
;
pSegment
=
new
Segment
(
pReader
,
idpos
,
pos
,
size
);
pSegment
=
new
(
std
::
nothrow
)
Segment
(
pReader
,
idpos
,
pos
,
size
);
if
(
pSegment
==
NULL
)
return
E_PARSE_FAILED
;
return
0
;
// success
}
...
...
@@ -954,7 +935,11 @@ long long Segment::ParseHeaders() {
if
(
m_pInfo
)
return
E_FILE_FORMAT_INVALID
;
m_pInfo
=
new
SegmentInfo
(
this
,
pos
,
size
,
element_start
,
element_size
);
m_pInfo
=
new
(
std
::
nothrow
)
SegmentInfo
(
this
,
pos
,
size
,
element_start
,
element_size
);
if
(
m_pInfo
==
NULL
)
return
-
1
;
const
long
status
=
m_pInfo
->
Parse
();
...
...
@@ -964,7 +949,11 @@ long long Segment::ParseHeaders() {
if
(
m_pTracks
)
return
E_FILE_FORMAT_INVALID
;
m_pTracks
=
new
Tracks
(
this
,
pos
,
size
,
element_start
,
element_size
);
m_pTracks
=
new
(
std
::
nothrow
)
Tracks
(
this
,
pos
,
size
,
element_start
,
element_size
);
if
(
m_pTracks
==
NULL
)
return
-
1
;
const
long
status
=
m_pTracks
->
Parse
();
...
...
@@ -972,11 +961,19 @@ long long Segment::ParseHeaders() {
return
status
;
}
else
if
(
id
==
libwebm
::
kMkvCues
)
{
if
(
m_pCues
==
NULL
)
{
m_pCues
=
new
Cues
(
this
,
pos
,
size
,
element_start
,
element_size
);
m_pCues
=
new
(
std
::
nothrow
)
Cues
(
this
,
pos
,
size
,
element_start
,
element_size
);
if
(
m_pCues
==
NULL
)
return
-
1
;
}
}
else
if
(
id
==
libwebm
::
kMkvSeekHead
)
{
if
(
m_pSeekHead
==
NULL
)
{
m_pSeekHead
=
new
SeekHead
(
this
,
pos
,
size
,
element_start
,
element_size
);
m_pSeekHead
=
new
(
std
::
nothrow
)
SeekHead
(
this
,
pos
,
size
,
element_start
,
element_size
);
if
(
m_pSeekHead
==
NULL
)
return
-
1
;
const
long
status
=
m_pSeekHead
->
Parse
();
...
...
@@ -985,7 +982,11 @@ long long Segment::ParseHeaders() {
}
}
else
if
(
id
==
libwebm
::
kMkvChapters
)
{
if
(
m_pChapters
==
NULL
)
{
m_pChapters
=
new
Chapters
(
this
,
pos
,
size
,
element_start
,
element_size
);
m_pChapters
=
new
(
std
::
nothrow
)
Chapters
(
this
,
pos
,
size
,
element_start
,
element_size
);
if
(
m_pChapters
==
NULL
)
return
-
1
;
const
long
status
=
m_pChapters
->
Parse
();
...
...
@@ -994,7 +995,11 @@ long long Segment::ParseHeaders() {
}
}
else
if
(
id
==
libwebm
::
kMkvTags
)
{
if
(
m_pTags
==
NULL
)
{
m_pTags
=
new
Tags
(
this
,
pos
,
size
,
element_start
,
element_size
);
m_pTags
=
new
(
std
::
nothrow
)
Tags
(
this
,
pos
,
size
,
element_start
,
element_size
);
if
(
m_pTags
==
NULL
)
return
-
1
;
const
long
status
=
m_pTags
->
Parse
();
...
...
@@ -1136,7 +1141,9 @@ long Segment::DoLoadCluster(long long& pos, long& len) {
if
(
m_pCues
==
NULL
)
{
const
long
long
element_size
=
(
pos
-
idpos
)
+
size
;
m_pCues
=
new
Cues
(
this
,
pos
,
size
,
idpos
,
element_size
);
m_pCues
=
new
(
std
::
nothrow
)
Cues
(
this
,
pos
,
size
,
idpos
,
element_size
);
if
(
m_pCues
==
NULL
)
return
-
1
;
}
m_pos
=
pos
+
size
;
// consume payload
...
...
@@ -1284,9 +1291,7 @@ long Segment::DoLoadCluster(long long& pos, long& len) {
pos
+=
cluster_size
;
m_pos
=
pos
;
// -- GODOT start --
delete
pCluster
;
// -- GODOT end --
if
(
segment_stop
>
0
&&
m_pos
>
segment_stop
)
return
E_FILE_FORMAT_INVALID
;
...
...
@@ -1344,7 +1349,9 @@ bool Segment::AppendCluster(Cluster* pCluster) {
if
(
count
>=
size
)
{
const
long
n
=
(
size
<=
0
)
?
2048
:
2
*
size
;
Cluster
**
const
qq
=
new
Cluster
*
[
n
];
Cluster
**
const
qq
=
new
(
std
::
nothrow
)
Cluster
*
[
n
];
if
(
qq
==
NULL
)
return
false
;
Cluster
**
q
=
qq
;
Cluster
**
p
=
m_clusters
;
...
...
@@ -1399,7 +1406,9 @@ bool Segment::PreloadCluster(Cluster* pCluster, ptrdiff_t idx) {
if
(
count
>=
size
)
{
const
long
n
=
(
size
<=
0
)
?
2048
:
2
*
size
;
Cluster
**
const
qq
=
new
Cluster
*
[
n
];
Cluster
**
const
qq
=
new
(
std
::
nothrow
)
Cluster
*
[
n
];
if
(
qq
==
NULL
)
return
false
;
Cluster
**
q
=
qq
;
Cluster
**
p
=
m_clusters
;
...
...
@@ -1468,6 +1477,8 @@ long Segment::Load() {
}
}
SeekHead
::
Entry
::
Entry
()
:
id
(
0
),
pos
(
0
),
element_start
(
0
),
element_size
(
0
)
{}
SeekHead
::
SeekHead
(
Segment
*
pSegment
,
long
long
start
,
long
long
size_
,
long
long
element_start
,
long
long
element_size
)
:
m_pSegment
(
pSegment
),
...
...
@@ -1518,9 +1529,19 @@ long SeekHead::Parse() {
if
(
pos
!=
stop
)
return
E_FILE_FORMAT_INVALID
;
m_entries
=
new
Entry
[
entry_count
];
if
(
entry_count
>
0
)
{
m_entries
=
new
(
std
::
nothrow
)
Entry
[
entry_count
];
if
(
m_entries
==
NULL
)
return
-
1
;
}
if
(
void_element_count
>
0
)
{
m_void_elements
=
new
(
std
::
nothrow
)
VoidElement
[
void_element_count
];
m_void_elements
=
new
VoidElement
[
void_element_count
];
if
(
m_void_elements
==
NULL
)
return
-
1
;
}
// now parse the entries and void elements
...
...
@@ -1539,14 +1560,14 @@ long SeekHead::Parse() {
if
(
status
<
0
)
// error
return
status
;
if
(
id
==
libwebm
::
kMkvSeek
)
{
if
(
id
==
libwebm
::
kMkvSeek
&&
entry_count
>
0
)
{
if
(
ParseEntry
(
pReader
,
pos
,
size
,
pEntry
))
{
Entry
&
e
=
*
pEntry
++
;
e
.
element_start
=
idpos
;
e
.
element_size
=
(
pos
+
size
)
-
idpos
;
}
}
else
if
(
id
==
libwebm
::
kMkvVoid
)
{
}
else
if
(
id
==
libwebm
::
kMkvVoid
&&
void_element_count
>
0
)
{
VoidElement
&
e
=
*
pVoidElement
++
;
e
.
element_start
=
idpos
;
...
...
@@ -1708,7 +1729,10 @@ long Segment::ParseCues(long long off, long long& pos, long& len) {
const
long
long
element_size
=
element_stop
-
element_start
;
m_pCues
=
new
Cues
(
this
,
pos
,
size
,
element_start
,
element_size
);
m_pCues
=
new
(
std
::
nothrow
)
Cues
(
this
,
pos
,
size
,
element_start
,
element_size
);
if
(
m_pCues
==
NULL
)
return
-
1
;
return
0
;
// success
}
...
...
@@ -1750,18 +1774,7 @@ bool SeekHead::ParseEntry(IMkvReader* pReader, long long start, long long size_,
if
((
pos
+
seekIdSize
)
>
stop
)
return
false
;
// Note that the SeekId payload really is serialized
// as a "Matroska integer", not as a plain binary value.
// In fact, Matroska requires that ID values in the
// stream exactly match the binary representation as listed
// in the Matroska specification.
//
// This parser is more liberal, and permits IDs to have
// any width. (This could make the representation in the stream
// different from what's in the spec, but it doesn't matter here,
// since we always normalize "Matroska integer" values.)
pEntry
->
id
=
ReadUInt
(
pReader
,
pos
,
len
);
// payload
pEntry
->
id
=
ReadID
(
pReader
,
pos
,
len
);
// payload
if
(
pEntry
->
id
<=
0
)
return
false
;
...
...
@@ -1900,7 +1913,9 @@ bool Cues::PreloadCuePoint(long& cue_points_size, long long pos) const {
if
(
m_preload_count
>=
cue_points_size
)
{
const
long
n
=
(
cue_points_size
<=
0
)
?
2048
:
2
*
cue_points_size
;
CuePoint
**
const
qq
=
new
CuePoint
*
[
n
];
CuePoint
**
const
qq
=
new
(
std
::
nothrow
)
CuePoint
*
[
n
];
if
(
qq
==
NULL
)
return
false
;
CuePoint
**
q
=
qq
;
// beginning of target
...
...
@@ -1916,7 +1931,9 @@ bool Cues::PreloadCuePoint(long& cue_points_size, long long pos) const {
cue_points_size
=
n
;
}
CuePoint
*
const
pCP
=
new
CuePoint
(
m_preload_count
,
pos
);
CuePoint
*
const
pCP
=
new
(
std
::
nothrow
)
CuePoint
(
m_preload_count
,
pos
);
if
(
pCP
==
NULL
)
return
false
;
m_cue_points
[
m_preload_count
++
]
=
pCP
;
return
true
;
...
...
@@ -2322,7 +2339,9 @@ bool CuePoint::Load(IMkvReader* pReader) {
// << " timecode=" << m_timecode
// << endl;
m_track_positions
=
new
TrackPosition
[
m_track_positions_count
];
m_track_positions
=
new
(
std
::
nothrow
)
TrackPosition
[
m_track_positions_count
];
if
(
m_track_positions
==
NULL
)
return
false
;
// Now parse track positions
...
...
@@ -2412,7 +2431,9 @@ bool CuePoint::TrackPosition::Parse(IMkvReader* pReader, long long start_,
}
const
CuePoint
::
TrackPosition
*
CuePoint
::
Find
(
const
Track
*
pTrack
)
const
{
assert
(
pTrack
);
if
(
pTrack
==
NULL
)
{
return
NULL
;
}
const
long
long
n
=
pTrack
->
GetNumber
();
...
...
@@ -2917,7 +2938,10 @@ long Segment::DoParseNext(const Cluster*& pResult, long long& pos, long& len) {
const
long
long
element_size
=
element_stop
-
element_start
;
if
(
m_pCues
==
NULL
)
{
m_pCues
=
new
Cues
(
this
,
pos
,
size
,
element_start
,
element_size
);
m_pCues
=
new
(
std
::
nothrow
)
Cues
(
this
,
pos
,
size
,
element_start
,
element_size
);
if
(
m_pCues
==
NULL
)
return
false
;
}
pos
+=
size
;
// consume payload
...
...
@@ -3268,7 +3292,10 @@ bool Chapters::ExpandEditionsArray() {
const
int
size
=
(
m_editions_size
==
0
)
?
1
:
2
*
m_editions_size
;
Edition
*
const
editions
=
new
Edition
[
size
];
Edition
*
const
editions
=
new
(
std
::
nothrow
)
Edition
[
size
];
if
(
editions
==
NULL
)
return
false
;
for
(
int
idx
=
0
;
idx
<
m_editions_count
;
++
idx
)
{
m_editions
[
idx
].
ShallowCopy
(
editions
[
idx
]);
...
...
@@ -3380,7 +3407,10 @@ bool Chapters::Edition::ExpandAtomsArray() {
const
int
size
=
(
m_atoms_size
==
0
)
?
1
:
2
*
m_atoms_size
;
Atom
*
const
atoms
=
new
Atom
[
size
];
Atom
*
const
atoms
=
new
(
std
::
nothrow
)
Atom
[
size
];
if
(
atoms
==
NULL
)
return
false
;
for
(
int
idx
=
0
;
idx
<
m_atoms_count
;
++
idx
)
{
m_atoms
[
idx
].
ShallowCopy
(
atoms
[
idx
]);
...
...
@@ -3565,7 +3595,10 @@ bool Chapters::Atom::ExpandDisplaysArray() {
const
int
size
=
(
m_displays_size
==
0
)
?
1
:
2
*
m_displays_size
;
Display
*
const
displays
=
new
Display
[
size
];
Display
*
const
displays
=
new
(
std
::
nothrow
)
Display
[
size
];
if
(
displays
==
NULL
)
return
false
;
for
(
int
idx
=
0
;
idx
<
m_displays_count
;
++
idx
)
{
m_displays
[
idx
].
ShallowCopy
(
displays
[
idx
]);
...
...
@@ -3725,7 +3758,10 @@ bool Tags::ExpandTagsArray() {
const
int
size
=
(
m_tags_size
==
0
)
?
1
:
2
*
m_tags_size
;
Tag
*
const
tags
=
new
Tag
[
size
];
Tag
*
const
tags
=
new
(
std
::
nothrow
)
Tag
[
size
];
if
(
tags
==
NULL
)
return
false
;
for
(
int
idx
=
0
;
idx
<
m_tags_count
;
++
idx
)
{
m_tags
[
idx
].
ShallowCopy
(
tags
[
idx
]);
...
...
@@ -3836,7 +3872,10 @@ bool Tags::Tag::ExpandSimpleTagsArray() {
const
int
size
=
(
m_simple_tags_size
==
0
)
?
1
:
2
*
m_simple_tags_size
;
SimpleTag
*
const
displays
=
new
SimpleTag
[
size
];
SimpleTag
*
const
displays
=
new
(
std
::
nothrow
)
SimpleTag
[
size
];
if
(
displays
==
NULL
)
return
false
;
for
(
int
idx
=
0
;
idx
<
m_simple_tags_count
;
++
idx
)
{
m_simple_tags
[
idx
].
ShallowCopy
(
displays
[
idx
]);
...
...
@@ -3994,7 +4033,7 @@ long SegmentInfo::Parse() {
}
const
double
rollover_check
=
m_duration
*
m_timecodeScale
;
if
(
rollover_check
>
LLONG_MAX
)
if
(
rollover_check
>
static_cast
<
double
>
(
LLONG_MAX
)
)
return
E_FILE_FORMAT_INVALID
;
if
(
pos
!=
stop
)
...
...
@@ -4085,7 +4124,7 @@ ContentEncoding::~ContentEncoding() {
}
const
ContentEncoding
::
ContentCompression
*
ContentEncoding
::
GetCompressionByIndex
(
unsigned
long
idx
)
const
{
ContentEncoding
::
GetCompressionByIndex
(
unsigned
long
idx
)
const
{
const
ptrdiff_t
count
=
compression_entries_end_
-
compression_entries_
;
assert
(
count
>=
0
);
...
...
@@ -4181,12 +4220,20 @@ long ContentEncoding::ParseContentEncodingEntry(long long start, long long size,
return
-
1
;
if
(
compression_count
>
0
)
{
compression_entries_
=
new
ContentCompression
*
[
compression_count
];
compression_entries_
=
new
(
std
::
nothrow
)
ContentCompression
*
[
compression_count
];
if
(
!
compression_entries_
)
return
-
1
;
compression_entries_end_
=
compression_entries_
;
}
if
(
encryption_count
>
0
)
{
encryption_entries_
=
new
ContentEncryption
*
[
encryption_count
];
encryption_entries_
=
new
(
std
::
nothrow
)
ContentEncryption
*
[
encryption_count
];
if
(
!
encryption_entries_
)
{
delete
[]
compression_entries_
;
return
-
1
;
}
encryption_entries_end_
=
encryption_entries_
;
}
...
...
@@ -4206,7 +4253,10 @@ long ContentEncoding::ParseContentEncodingEntry(long long start, long long size,
}
else
if
(
id
==
libwebm
::
kMkvContentEncodingType
)
{
encoding_type_
=
UnserializeUInt
(
pReader
,
pos
,
size
);
}
else
if
(
id
==
libwebm
::
kMkvContentCompression
)
{
ContentCompression
*
const
compression
=
new
ContentCompression
();
ContentCompression
*
const
compression
=
new
(
std
::
nothrow
)
ContentCompression
();
if
(
!
compression
)
return
-
1
;
status
=
ParseCompressionEntry
(
pos
,
size
,
pReader
,
compression
);
if
(
status
)
{
...
...
@@ -4215,7 +4265,10 @@ long ContentEncoding::ParseContentEncodingEntry(long long start, long long size,
}
*
compression_entries_end_
++
=
compression
;
}
else
if
(
id
==
libwebm
::
kMkvContentEncryption
)
{
ContentEncryption
*
const
encryption
=
new
ContentEncryption
();
ContentEncryption
*
const
encryption
=
new
(
std
::
nothrow
)
ContentEncryption
();
if
(
!
encryption
)
return
-
1
;
status
=
ParseEncryptionEntry
(
pos
,
size
,
pReader
,
encryption
);
if
(
status
)
{
...
...
@@ -4421,7 +4474,11 @@ long Track::Create(Segment* pSegment, const Info& info, long long element_start,
if
(
pResult
)
return
-
1
;
Track
*
const
pTrack
=
new
Track
(
pSegment
,
element_start
,
element_size
);
Track
*
const
pTrack
=
new
(
std
::
nothrow
)
Track
(
pSegment
,
element_start
,
element_size
);
if
(
pTrack
==
NULL
)
return
-
1
;
// generic error
const
int
status
=
info
.
Copy
(
pTrack
->
m_info
);
...
...
@@ -4873,7 +4930,10 @@ long Track::ParseContentEncodingsEntry(long long start, long long size) {
if
(
count
<=
0
)
return
-
1
;
content_encoding_entries_
=
new
ContentEncoding
*
[
count
];
content_encoding_entries_
=
new
(
std
::
nothrow
)
ContentEncoding
*
[
count
];
if
(
!
content_encoding_entries_
)
return
-
1
;
content_encoding_entries_end_
=
content_encoding_entries_
;
pos
=
start
;
...
...
@@ -4885,7 +4945,10 @@ long Track::ParseContentEncodingsEntry(long long start, long long size) {
// pos now designates start of element
if
(
id
==
libwebm
::
kMkvContentEncoding
)
{
ContentEncoding
*
const
content_encoding
=
new
ContentEncoding
();
ContentEncoding
*
const
content_encoding
=
new
(
std
::
nothrow
)
ContentEncoding
();
if
(
!
content_encoding
)
return
-
1
;
status
=
content_encoding
->
ParseContentEncodingEntry
(
pos
,
size
,
pReader
);
if
(
status
)
{
...
...
@@ -4919,20 +4982,27 @@ bool PrimaryChromaticity::Parse(IMkvReader* reader, long long read_pos,
if
(
!
reader
)
return
false
;
my_auto_ptr
<
PrimaryChromaticity
>
chromaticity_ptr
(
*
chromaticity
?
*
chromaticity
:
new
PrimaryChromaticity
());
if
(
!*
chromaticity
)
*
chromaticity
=
new
PrimaryChromaticity
();
float
*
value
=
is_x
?
&
chromaticity_ptr
->
x
:
&
chromaticity_ptr
->
y
;
if
(
!*
chromaticity
)
return
false
;
PrimaryChromaticity
*
pc
=
*
chromaticity
;
float
*
value
=
is_x
?
&
pc
->
x
:
&
pc
->
y
;
double
parser_value
=
0
;
const
long
long
value_
parse_status
=
const
long
long
parse_status
=
UnserializeFloat
(
reader
,
read_pos
,
value_size
,
parser_value
);
*
value
=
static_cast
<
float
>
(
parser_value
);
if
(
value_parse_status
<
0
||
*
value
<
0.0
||
*
value
>
1.0
)
// Valid range is [0, 1]. Make sure the double is representable as a float
// before casting.
if
(
parse_status
<
0
||
parser_value
<
0.0
||
parser_value
>
1.0
||
(
parser_value
>
0.0
&&
parser_value
<
FLT_MIN
))
return
false
;
*
chromaticity
=
chromaticity_ptr
.
release
();
*
value
=
static_cast
<
float
>
(
parser_value
);
return
true
;
}
...
...
@@ -4941,7 +5011,9 @@ bool MasteringMetadata::Parse(IMkvReader* reader, long long mm_start,
if
(
!
reader
||
*
mm
)
return
false
;
my_auto_ptr
<
MasteringMetadata
>
mm_ptr
(
new
MasteringMetadata
());
std
::
unique_ptr
<
MasteringMetadata
>
mm_ptr
(
new
MasteringMetadata
());
if
(
!
mm_ptr
.
get
())
return
false
;
const
long
long
mm_end
=
mm_start
+
mm_size
;
long
long
read_pos
=
mm_start
;
...
...
@@ -4959,6 +5031,10 @@ bool MasteringMetadata::Parse(IMkvReader* reader, long long mm_start,
double
value
=
0
;
const
long
long
value_parse_status
=
UnserializeFloat
(
reader
,
read_pos
,
child_size
,
value
);
if
(
value
<
-
FLT_MAX
||
value
>
FLT_MAX
||
(
value
>
0.0
&&
value
<
FLT_MIN
))
{
return
false
;
}
mm_ptr
->
luminance_max
=
static_cast
<
float
>
(
value
);
if
(
value_parse_status
<
0
||
mm_ptr
->
luminance_max
<
0.0
||
mm_ptr
->
luminance_max
>
9999.99
)
{
...
...
@@ -4968,6 +5044,10 @@ bool MasteringMetadata::Parse(IMkvReader* reader, long long mm_start,
double
value
=
0
;
const
long
long
value_parse_status
=
UnserializeFloat
(
reader
,
read_pos
,
child_size
,
value
);
if
(
value
<
-
FLT_MAX
||
value
>
FLT_MAX
||
(
value
>
0.0
&&
value
<
FLT_MIN
))
{
return
false
;
}
mm_ptr
->
luminance_min
=
static_cast
<
float
>
(
value
);
if
(
value_parse_status
<
0
||
mm_ptr
->
luminance_min
<
0.0
||
mm_ptr
->
luminance_min
>
999.9999
)
{
...
...
@@ -5020,7 +5100,9 @@ bool Colour::Parse(IMkvReader* reader, long long colour_start,
if
(
!
reader
||
*
colour
)
return
false
;
my_auto_ptr
<
Colour
>
colour_ptr
(
new
Colour
());
std
::
unique_ptr
<
Colour
>
colour_ptr
(
new
Colour
());
if
(
!
colour_ptr
.
get
())
return
false
;
const
long
long
colour_end
=
colour_start
+
colour_size
;
long
long
read_pos
=
colour_start
;
...
...
@@ -5111,11 +5193,94 @@ bool Colour::Parse(IMkvReader* reader, long long colour_start,
return
true
;
}
bool
Projection
::
Parse
(
IMkvReader
*
reader
,
long
long
start
,
long
long
size
,
Projection
**
projection
)
{
if
(
!
reader
||
*
projection
)
return
false
;
std
::
unique_ptr
<
Projection
>
projection_ptr
(
new
Projection
());
if
(
!
projection_ptr
.
get
())
return
false
;
const
long
long
end
=
start
+
size
;
long
long
read_pos
=
start
;
while
(
read_pos
<
end
)
{
long
long
child_id
=
0
;
long
long
child_size
=
0
;
const
long
long
status
=
ParseElementHeader
(
reader
,
read_pos
,
end
,
child_id
,
child_size
);
if
(
status
<
0
)
return
false
;
if
(
child_id
==
libwebm
::
kMkvProjectionType
)
{
long
long
projection_type
=
kTypeNotPresent
;
projection_type
=
UnserializeUInt
(
reader
,
read_pos
,
child_size
);
if
(
projection_type
<
0
)
return
false
;
projection_ptr
->
type
=
static_cast
<
ProjectionType
>
(
projection_type
);
}
else
if
(
child_id
==
libwebm
::
kMkvProjectionPrivate
)
{
unsigned
char
*
data
=
SafeArrayAlloc
<
unsigned
char
>
(
1
,
child_size
);
if
(
data
==
NULL
)
return
false
;
const
int
status
=
reader
->
Read
(
read_pos
,
static_cast
<
long
>
(
child_size
),
data
);
if
(
status
)
{
delete
[]
data
;
return
false
;
}
projection_ptr
->
private_data
=
data
;
projection_ptr
->
private_data_length
=
static_cast
<
size_t
>
(
child_size
);
}
else
{
double
value
=
0
;
const
long
long
value_parse_status
=
UnserializeFloat
(
reader
,
read_pos
,
child_size
,
value
);
// Make sure value is representable as a float before casting.
if
(
value_parse_status
<
0
||
value
<
-
FLT_MAX
||
value
>
FLT_MAX
||
(
value
>
0.0
&&
value
<
FLT_MIN
))
{
return
false
;
}
switch
(
child_id
)
{
case
libwebm
:
:
kMkvProjectionPoseYaw
:
projection_ptr
->
pose_yaw
=
static_cast
<
float
>
(
value
);
break
;
case
libwebm
:
:
kMkvProjectionPosePitch
:
projection_ptr
->
pose_pitch
=
static_cast
<
float
>
(
value
);
break
;
case
libwebm
:
:
kMkvProjectionPoseRoll
:
projection_ptr
->
pose_roll
=
static_cast
<
float
>
(
value
);
break
;
default
:
return
false
;
}
}
read_pos
+=
child_size
;
if
(
read_pos
>
end
)
return
false
;
}
*
projection
=
projection_ptr
.
release
();
return
true
;
}
VideoTrack
::
VideoTrack
(
Segment
*
pSegment
,
long
long
element_start
,
long
long
element_size
)
:
Track
(
pSegment
,
element_start
,
element_size
),
m_colour
(
NULL
)
{}
:
Track
(
pSegment
,
element_start
,
element_size
),
m_colour
(
NULL
),
m_projection
(
NULL
)
{}
VideoTrack
::~
VideoTrack
()
{
delete
m_colour
;
}
VideoTrack
::~
VideoTrack
()
{
delete
m_colour
;
delete
m_projection
;
}
long
VideoTrack
::
Parse
(
Segment
*
pSegment
,
const
Info
&
info
,
long
long
element_start
,
long
long
element_size
,
...
...
@@ -5147,6 +5312,7 @@ long VideoTrack::Parse(Segment* pSegment, const Info& info,
const
long
long
stop
=
pos
+
s
.
size
;
Colour
*
colour
=
NULL
;
Projection
*
projection
=
NULL
;
while
(
pos
<
stop
)
{
long
long
id
,
size
;
...
...
@@ -5197,6 +5363,9 @@ long VideoTrack::Parse(Segment* pSegment, const Info& info,
}
else
if
(
id
==
libwebm
::
kMkvColour
)
{
if
(
!
Colour
::
Parse
(
pReader
,
pos
,
size
,
&
colour
))
return
E_FILE_FORMAT_INVALID
;
}
else
if
(
id
==
libwebm
::
kMkvProjection
)
{
if
(
!
Projection
::
Parse
(
pReader
,
pos
,
size
,
&
projection
))
return
E_FILE_FORMAT_INVALID
;
}
pos
+=
size
;
// consume payload
...
...
@@ -5207,7 +5376,11 @@ long VideoTrack::Parse(Segment* pSegment, const Info& info,
if
(
pos
!=
stop
)
return
E_FILE_FORMAT_INVALID
;
VideoTrack
*
const
pTrack
=
new
VideoTrack
(
pSegment
,
element_start
,
element_size
);
VideoTrack
*
const
pTrack
=
new
(
std
::
nothrow
)
VideoTrack
(
pSegment
,
element_start
,
element_size
);
if
(
pTrack
==
NULL
)
return
-
1
;
// generic error
const
int
status
=
info
.
Copy
(
pTrack
->
m_info
);
...
...
@@ -5224,6 +5397,7 @@ long VideoTrack::Parse(Segment* pSegment, const Info& info,
pTrack
->
m_stereo_mode
=
stereo_mode
;
pTrack
->
m_rate
=
rate
;
pTrack
->
m_colour
=
colour
;
pTrack
->
m_projection
=
projection
;
pResult
=
pTrack
;
return
0
;
// success
...
...
@@ -5324,6 +5498,8 @@ long VideoTrack::Seek(long long time_ns, const BlockEntry*& pResult) const {
Colour
*
VideoTrack
::
GetColour
()
const
{
return
m_colour
;
}
Projection
*
VideoTrack
::
GetProjection
()
const
{
return
m_projection
;
}
long
long
VideoTrack
::
GetWidth
()
const
{
return
m_width
;
}
long
long
VideoTrack
::
GetHeight
()
const
{
return
m_height
;
}
...
...
@@ -5406,7 +5582,11 @@ long AudioTrack::Parse(Segment* pSegment, const Info& info,
if
(
pos
!=
stop
)
return
E_FILE_FORMAT_INVALID
;
AudioTrack
*
const
pTrack
=
new
AudioTrack
(
pSegment
,
element_start
,
element_size
);
AudioTrack
*
const
pTrack
=
new
(
std
::
nothrow
)
AudioTrack
(
pSegment
,
element_start
,
element_size
);
if
(
pTrack
==
NULL
)
return
-
1
;
// generic error
const
int
status
=
info
.
Copy
(
pTrack
->
m_info
);
...
...
@@ -5474,7 +5654,11 @@ long Tracks::Parse() {
if
(
count
<=
0
)
return
0
;
// success
m_trackEntries
=
new
Track
*
[
count
];
m_trackEntries
=
new
(
std
::
nothrow
)
Track
*
[
count
];
if
(
m_trackEntries
==
NULL
)
return
-
1
;
m_trackEntriesEnd
=
m_trackEntries
;
pos
=
m_start
;
...
...
@@ -6577,7 +6761,10 @@ Cluster* Cluster::Create(Segment* pSegment, long idx, long long off) {
const
long
long
element_start
=
pSegment
->
m_start
+
off
;
return
new
Cluster
(
pSegment
,
idx
,
element_start
);
Cluster
*
const
pCluster
=
new
(
std
::
nothrow
)
Cluster
(
pSegment
,
idx
,
element_start
);
return
pCluster
;
}
Cluster
::
Cluster
()
...
...
@@ -6606,8 +6793,10 @@ Cluster::Cluster(Segment* pSegment, long idx, long long element_start
{}
Cluster
::~
Cluster
()
{
if
(
m_entries_count
<=
0
)
if
(
m_entries_count
<=
0
)
{
delete
[]
m_entries
;
return
;
}
BlockEntry
**
i
=
m_entries
;
BlockEntry
**
const
j
=
m_entries
+
m_entries_count
;
...
...
@@ -6920,7 +7109,9 @@ long Cluster::CreateBlock(long long id,
assert
(
m_entries_size
==
0
);
m_entries_size
=
1024
;
m_entries
=
new
BlockEntry
*
[
m_entries_size
];
m_entries
=
new
(
std
::
nothrow
)
BlockEntry
*
[
m_entries_size
];
if
(
m_entries
==
NULL
)
return
-
1
;
m_entries_count
=
0
;
}
else
{
...
...
@@ -6931,7 +7122,9 @@ long Cluster::CreateBlock(long long id,
if
(
m_entries_count
>=
m_entries_size
)
{
const
long
entries_size
=
2
*
m_entries_size
;
BlockEntry
**
const
entries
=
new
BlockEntry
*
[
entries_size
];
BlockEntry
**
const
entries
=
new
(
std
::
nothrow
)
BlockEntry
*
[
entries_size
];
if
(
entries
==
NULL
)
return
-
1
;
BlockEntry
**
src
=
m_entries
;
BlockEntry
**
const
src_end
=
src
+
m_entries_count
;
...
...
@@ -7040,7 +7233,11 @@ long Cluster::CreateBlockGroup(long long start_offset, long long size,
BlockEntry
**
const
ppEntry
=
m_entries
+
idx
;
BlockEntry
*&
pEntry
=
*
ppEntry
;
pEntry
=
new
BlockGroup
(
this
,
idx
,
bpos
,
bsize
,
prev
,
next
,
duration
,
discard_padding
);
pEntry
=
new
(
std
::
nothrow
)
BlockGroup
(
this
,
idx
,
bpos
,
bsize
,
prev
,
next
,
duration
,
discard_padding
);
if
(
pEntry
==
NULL
)
return
-
1
;
// generic error
BlockGroup
*
const
p
=
static_cast
<
BlockGroup
*>
(
pEntry
);
...
...
@@ -7068,7 +7265,10 @@ long Cluster::CreateSimpleBlock(long long st, long long sz) {
BlockEntry
**
const
ppEntry
=
m_entries
+
idx
;
BlockEntry
*&
pEntry
=
*
ppEntry
;
pEntry
=
new
SimpleBlock
(
this
,
idx
,
st
,
sz
);
pEntry
=
new
(
std
::
nothrow
)
SimpleBlock
(
this
,
idx
,
st
,
sz
);
if
(
pEntry
==
NULL
)
return
-
1
;
// generic error
SimpleBlock
*
const
p
=
static_cast
<
SimpleBlock
*>
(
pEntry
);
...
...
@@ -7463,7 +7663,9 @@ long Block::Parse(const Cluster* pCluster) {
return
E_FILE_FORMAT_INVALID
;
m_frame_count
=
1
;
m_frames
=
new
Frame
[
m_frame_count
];
m_frames
=
new
(
std
::
nothrow
)
Frame
[
m_frame_count
];
if
(
m_frames
==
NULL
)
return
-
1
;
Frame
&
f
=
m_frames
[
0
];
f
.
pos
=
pos
;
...
...
@@ -7494,7 +7696,9 @@ long Block::Parse(const Cluster* pCluster) {
m_frame_count
=
int
(
biased_count
)
+
1
;
m_frames
=
new
Frame
[
m_frame_count
];
m_frames
=
new
(
std
::
nothrow
)
Frame
[
m_frame_count
];
if
(
m_frames
==
NULL
)
return
-
1
;
if
(
!
m_frames
)
return
E_FILE_FORMAT_INVALID
;
...
...
@@ -7703,6 +7907,10 @@ long Block::Parse(const Cluster* pCluster) {
return
E_FILE_FORMAT_INVALID
;
curr
.
len
=
static_cast
<
long
>
(
frame_size
);
// Check if size + curr.len could overflow.
if
(
size
>
LLONG_MAX
-
curr
.
len
)
{
return
E_FILE_FORMAT_INVALID
;
}
size
+=
curr
.
len
;
// contribution of this frame
--
frame_count
;
...
...
@@ -7743,7 +7951,6 @@ long Block::Parse(const Cluster* pCluster) {
pf
=
m_frames
;
while
(
pf
!=
pf_end
)
{
Frame
&
f
=
*
pf
++
;
assert
((
pos
+
f
.
len
)
<=
stop
);
if
((
pos
+
f
.
len
)
>
stop
)
return
E_FILE_FORMAT_INVALID
;
...
...
@@ -7765,6 +7972,11 @@ long long Block::GetTimeCode(const Cluster* pCluster) const {
const
long
long
tc0
=
pCluster
->
GetTimeCode
();
assert
(
tc0
>=
0
);
// Check if tc0 + m_timecode would overflow.
if
(
tc0
<
0
||
LLONG_MAX
-
tc0
<
m_timecode
)
{
return
-
1
;
}
const
long
long
tc
=
tc0
+
m_timecode
;
return
tc
;
// unscaled timecode units
...
...
@@ -7782,6 +7994,10 @@ long long Block::GetTime(const Cluster* pCluster) const {
const
long
long
scale
=
pInfo
->
GetTimeCodeScale
();
assert
(
scale
>=
1
);
// Check if tc * scale could overflow.
if
(
tc
!=
0
&&
scale
>
LLONG_MAX
/
tc
)
{
return
-
1
;
}
const
long
long
ns
=
tc
*
scale
;
return
ns
;
...
...
thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.h
View file @
e71f1099
...
...
@@ -8,7 +8,7 @@
#ifndef MKVPARSER_MKVPARSER_H_
#define MKVPARSER_MKVPARSER_H_
#include <
stddef.h
>
#include <
cstddef
>
namespace
mkvparser
{
...
...
@@ -21,6 +21,7 @@ class IMkvReader {
virtual
int
Read
(
long
long
pos
,
long
len
,
unsigned
char
*
buf
)
=
0
;
virtual
int
Length
(
long
long
*
total
,
long
long
*
available
)
=
0
;
public
:
virtual
~
IMkvReader
();
};
...
...
@@ -472,6 +473,34 @@ struct Colour {
MasteringMetadata
*
mastering_metadata
;
};
struct
Projection
{
enum
ProjectionType
{
kTypeNotPresent
=
-
1
,
kRectangular
=
0
,
kEquirectangular
=
1
,
kCubeMap
=
2
,
kMesh
=
3
,
};
static
const
float
kValueNotPresent
;
Projection
()
:
type
(
kTypeNotPresent
),
private_data
(
NULL
),
private_data_length
(
0
),
pose_yaw
(
kValueNotPresent
),
pose_pitch
(
kValueNotPresent
),
pose_roll
(
kValueNotPresent
)
{}
~
Projection
()
{
delete
[]
private_data
;
}
static
bool
Parse
(
IMkvReader
*
reader
,
long
long
element_start
,
long
long
element_size
,
Projection
**
projection
);
ProjectionType
type
;
unsigned
char
*
private_data
;
size_t
private_data_length
;
float
pose_yaw
;
float
pose_pitch
;
float
pose_roll
;
};
class
VideoTrack
:
public
Track
{
VideoTrack
(
const
VideoTrack
&
);
VideoTrack
&
operator
=
(
const
VideoTrack
&
);
...
...
@@ -496,6 +525,8 @@ class VideoTrack : public Track {
Colour
*
GetColour
()
const
;
Projection
*
GetProjection
()
const
;
private
:
long
long
m_width
;
long
long
m_height
;
...
...
@@ -507,6 +538,7 @@ class VideoTrack : public Track {
double
m_rate
;
Colour
*
m_colour
;
Projection
*
m_projection
;
};
class
AudioTrack
:
public
Track
{
...
...
@@ -812,6 +844,8 @@ class SeekHead {
long
Parse
();
struct
Entry
{
Entry
();
// the SeekHead entry payload
long
long
id
;
long
long
pos
;
...
...
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