Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
84a7ffc1
authored
Nov 30, 2020
by
ibaker
Committed by
Oliver Woodman
Dec 03, 2020
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Add ParsableByteArray#ensureCapacity() method that keeps data
#exofixit PiperOrigin-RevId: 344845328
parent
7e635d95
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
60 additions
and
25 deletions
library/common/src/main/java/com/google/android/exoplayer2/util/ParsableByteArray.java
library/common/src/main/java/com/google/android/exoplayer2/util/Util.java
library/common/src/test/java/com/google/android/exoplayer2/util/ParsableByteArrayTest.java
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/ogg/OggPacket.java
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/ts/SectionReader.java
library/common/src/main/java/com/google/android/exoplayer2/util/ParsableByteArray.java
View file @
84a7ffc1
...
@@ -19,6 +19,7 @@ import androidx.annotation.Nullable;
...
@@ -19,6 +19,7 @@ import androidx.annotation.Nullable;
import
com.google.common.base.Charsets
;
import
com.google.common.base.Charsets
;
import
java.nio.ByteBuffer
;
import
java.nio.ByteBuffer
;
import
java.nio.charset.Charset
;
import
java.nio.charset.Charset
;
import
java.util.Arrays
;
/**
/**
* Wraps a byte array, providing a set of methods for parsing data from it. Numerical values are
* Wraps a byte array, providing a set of methods for parsing data from it. Numerical values are
...
@@ -100,8 +101,21 @@ public final class ParsableByteArray {
...
@@ -100,8 +101,21 @@ public final class ParsableByteArray {
}
}
/**
/**
* Returns the number of bytes yet to be read.
* Ensures the backing array is at least {@code requiredCapacity} long.
*
* <p>{@link #getPosition() position}, {@link #limit() limit}, and all data in the underlying
* array (including that beyond {@link #limit()}) are preserved.
*
* <p>This might replace or wipe the {@link #getData() underlying array}, potentially invalidating
* any local references.
*/
*/
public
void
ensureCapacity
(
int
requiredCapacity
)
{
if
(
requiredCapacity
>
capacity
())
{
data
=
Arrays
.
copyOf
(
data
,
requiredCapacity
);
}
}
/** Returns the number of bytes yet to be read. */
public
int
bytesLeft
()
{
public
int
bytesLeft
()
{
return
limit
-
position
;
return
limit
-
position
;
}
}
...
@@ -148,8 +162,8 @@ public final class ParsableByteArray {
...
@@ -148,8 +162,8 @@ public final class ParsableByteArray {
*
*
* <p>Changes to this array are reflected in the results of the {@code read...()} methods.
* <p>Changes to this array are reflected in the results of the {@code read...()} methods.
*
*
* <p>This reference must be assumed to become invalid when {@link #reset}
is called (because the
* <p>This reference must be assumed to become invalid when {@link #reset}
or {@link
* array might get reallocated).
*
#ensureCapacity} are called (because the
array might get reallocated).
*/
*/
public
byte
[]
getData
()
{
public
byte
[]
getData
()
{
return
data
;
return
data
;
...
...
library/common/src/main/java/com/google/android/exoplayer2/util/Util.java
View file @
84a7ffc1
...
@@ -2214,9 +2214,8 @@ public final class Util {
...
@@ -2214,9 +2214,8 @@ public final class Util {
if
(
input
.
bytesLeft
()
<=
0
)
{
if
(
input
.
bytesLeft
()
<=
0
)
{
return
false
;
return
false
;
}
}
byte
[]
outputData
=
output
.
getData
();
if
(
output
.
capacity
()
<
input
.
bytesLeft
())
{
if
(
outputData
.
length
<
input
.
bytesLeft
())
{
output
.
ensureCapacity
(
2
*
input
.
bytesLeft
());
outputData
=
new
byte
[
2
*
input
.
bytesLeft
()];
}
}
if
(
inflater
==
null
)
{
if
(
inflater
==
null
)
{
inflater
=
new
Inflater
();
inflater
=
new
Inflater
();
...
@@ -2225,16 +2224,17 @@ public final class Util {
...
@@ -2225,16 +2224,17 @@ public final class Util {
try
{
try
{
int
outputSize
=
0
;
int
outputSize
=
0
;
while
(
true
)
{
while
(
true
)
{
outputSize
+=
inflater
.
inflate
(
outputData
,
outputSize
,
outputData
.
length
-
outputSize
);
outputSize
+=
inflater
.
inflate
(
output
.
getData
(),
outputSize
,
output
.
capacity
()
-
outputSize
);
if
(
inflater
.
finished
())
{
if
(
inflater
.
finished
())
{
output
.
reset
(
outputData
,
outputSize
);
output
.
setLimit
(
outputSize
);
return
true
;
return
true
;
}
}
if
(
inflater
.
needsDictionary
()
||
inflater
.
needsInput
())
{
if
(
inflater
.
needsDictionary
()
||
inflater
.
needsInput
())
{
return
false
;
return
false
;
}
}
if
(
outputSize
==
output
Data
.
length
)
{
if
(
outputSize
==
output
.
capacity
()
)
{
output
Data
=
Arrays
.
copyOf
(
outputData
,
outputData
.
length
*
2
);
output
.
ensureCapacity
(
output
.
capacity
()
*
2
);
}
}
}
}
}
catch
(
DataFormatException
e
)
{
}
catch
(
DataFormatException
e
)
{
...
...
library/common/src/test/java/com/google/android/exoplayer2/util/ParsableByteArrayTest.java
View file @
84a7ffc1
...
@@ -20,6 +20,7 @@ import static java.nio.charset.Charset.forName;
...
@@ -20,6 +20,7 @@ import static java.nio.charset.Charset.forName;
import
static
org
.
junit
.
Assert
.
fail
;
import
static
org
.
junit
.
Assert
.
fail
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
com.google.common.primitives.Bytes
;
import
java.nio.ByteBuffer
;
import
java.nio.ByteBuffer
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
org.junit.Test
;
import
org.junit.Test
;
...
@@ -39,6 +40,36 @@ public final class ParsableByteArrayTest {
...
@@ -39,6 +40,36 @@ public final class ParsableByteArrayTest {
}
}
@Test
@Test
public
void
ensureCapacity_doesntReallocateNeedlesslyAndPreservesPositionAndLimit
()
{
ParsableByteArray
array
=
getTestDataArray
();
byte
[]
dataBefore
=
array
.
getData
();
byte
[]
copyOfDataBefore
=
dataBefore
.
clone
();
array
.
setPosition
(
3
);
array
.
setLimit
(
4
);
array
.
ensureCapacity
(
array
.
capacity
()
-
1
);
assertThat
(
array
.
getData
()).
isSameInstanceAs
(
dataBefore
);
assertThat
(
array
.
getData
()).
isEqualTo
(
copyOfDataBefore
);
assertThat
(
array
.
getPosition
()).
isEqualTo
(
3
);
assertThat
(
array
.
limit
()).
isEqualTo
(
4
);
}
@Test
public
void
ensureCapacity_preservesDataPositionAndLimitWhenReallocating
()
{
ParsableByteArray
array
=
getTestDataArray
();
byte
[]
copyOfDataBefore
=
array
.
getData
().
clone
();
array
.
setPosition
(
3
);
array
.
setLimit
(
4
);
array
.
ensureCapacity
(
array
.
capacity
()
+
1
);
assertThat
(
array
.
getData
()).
isEqualTo
(
Bytes
.
concat
(
copyOfDataBefore
,
new
byte
[]
{
0
}));
assertThat
(
array
.
getPosition
()).
isEqualTo
(
3
);
assertThat
(
array
.
limit
()).
isEqualTo
(
4
);
}
@Test
public
void
readShort
()
{
public
void
readShort
()
{
testReadShort
((
short
)
-
1
);
testReadShort
((
short
)
-
1
);
testReadShort
((
short
)
0
);
testReadShort
((
short
)
0
);
...
...
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java
View file @
84a7ffc1
...
@@ -1341,9 +1341,7 @@ public class MatroskaExtractor implements Extractor {
...
@@ -1341,9 +1341,7 @@ public class MatroskaExtractor implements Extractor {
return
;
return
;
}
}
if
(
scratch
.
capacity
()
<
requiredLength
)
{
if
(
scratch
.
capacity
()
<
requiredLength
)
{
scratch
.
reset
(
scratch
.
ensureCapacity
(
max
(
scratch
.
capacity
()
*
2
,
requiredLength
));
Arrays
.
copyOf
(
scratch
.
getData
(),
max
(
scratch
.
getData
().
length
*
2
,
requiredLength
)),
scratch
.
limit
());
}
}
input
.
readFully
(
scratch
.
getData
(),
scratch
.
limit
(),
requiredLength
-
scratch
.
limit
());
input
.
readFully
(
scratch
.
getData
(),
scratch
.
limit
(),
requiredLength
-
scratch
.
limit
());
scratch
.
setLimit
(
requiredLength
);
scratch
.
setLimit
(
requiredLength
);
...
...
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/ogg/OggPacket.java
View file @
84a7ffc1
...
@@ -87,11 +87,7 @@ import java.util.Arrays;
...
@@ -87,11 +87,7 @@ import java.util.Arrays;
int
size
=
calculatePacketSize
(
currentSegmentIndex
);
int
size
=
calculatePacketSize
(
currentSegmentIndex
);
int
segmentIndex
=
currentSegmentIndex
+
segmentCount
;
int
segmentIndex
=
currentSegmentIndex
+
segmentCount
;
if
(
size
>
0
)
{
if
(
size
>
0
)
{
if
(
packetArray
.
capacity
()
<
packetArray
.
limit
()
+
size
)
{
packetArray
.
ensureCapacity
(
packetArray
.
limit
()
+
size
);
packetArray
.
reset
(
Arrays
.
copyOf
(
packetArray
.
getData
(),
packetArray
.
limit
()
+
size
),
/* limit= */
packetArray
.
limit
());
}
input
.
readFully
(
packetArray
.
getData
(),
packetArray
.
limit
(),
size
);
input
.
readFully
(
packetArray
.
getData
(),
packetArray
.
limit
(),
size
);
packetArray
.
setLimit
(
packetArray
.
limit
()
+
size
);
packetArray
.
setLimit
(
packetArray
.
limit
()
+
size
);
populated
=
pageHeader
.
laces
[
segmentIndex
-
1
]
!=
255
;
populated
=
pageHeader
.
laces
[
segmentIndex
-
1
]
!=
255
;
...
...
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/ts/SectionReader.java
View file @
84a7ffc1
...
@@ -23,7 +23,6 @@ import com.google.android.exoplayer2.extractor.ExtractorOutput;
...
@@ -23,7 +23,6 @@ import com.google.android.exoplayer2.extractor.ExtractorOutput;
import
com.google.android.exoplayer2.util.ParsableByteArray
;
import
com.google.android.exoplayer2.util.ParsableByteArray
;
import
com.google.android.exoplayer2.util.TimestampAdjuster
;
import
com.google.android.exoplayer2.util.TimestampAdjuster
;
import
com.google.android.exoplayer2.util.Util
;
import
com.google.android.exoplayer2.util.Util
;
import
java.util.Arrays
;
/**
/**
* Reads section data packets and feeds the whole sections to a given {@link SectionPayloadReader}.
* Reads section data packets and feeds the whole sections to a given {@link SectionPayloadReader}.
...
@@ -107,12 +106,9 @@ public final class SectionReader implements TsPayloadReader {
...
@@ -107,12 +106,9 @@ public final class SectionReader implements TsPayloadReader {
(((
secondHeaderByte
&
0x0F
)
<<
8
)
|
thirdHeaderByte
)
+
SECTION_HEADER_LENGTH
;
(((
secondHeaderByte
&
0x0F
)
<<
8
)
|
thirdHeaderByte
)
+
SECTION_HEADER_LENGTH
;
if
(
sectionData
.
capacity
()
<
totalSectionLength
)
{
if
(
sectionData
.
capacity
()
<
totalSectionLength
)
{
// Ensure there is enough space to keep the whole section.
// Ensure there is enough space to keep the whole section.
byte
[]
bytes
=
sectionData
.
getData
();
int
limit
=
int
limit
=
min
(
MAX_SECTION_LENGTH
,
max
(
totalSectionLength
,
bytes
.
length
*
2
));
min
(
MAX_SECTION_LENGTH
,
max
(
totalSectionLength
,
sectionData
.
capacity
()
*
2
));
if
(
limit
>
bytes
.
length
)
{
sectionData
.
ensureCapacity
(
limit
);
bytes
=
Arrays
.
copyOf
(
sectionData
.
getData
(),
limit
);
}
sectionData
.
reset
(
bytes
,
limit
);
}
}
}
}
}
else
{
}
else
{
...
...
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