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
e272e3b1
authored
Jun 29, 2021
by
kimvde
Committed by
Ian Baker
Jul 16, 2021
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Improve support for Ogg truncated content
Issue:#7608 PiperOrigin-RevId: 382081687
parent
ff5694a0
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
230 additions
and
45 deletions
RELEASENOTES.md
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/ExtractorUtil.java
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/ogg/DefaultOggSeeker.java
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/ogg/OggPacket.java
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/ogg/OggPageHeader.java
library/extractor/src/test/java/com/google/android/exoplayer2/extractor/ExtractorUtilTest.java
RELEASENOTES.md
View file @
e272e3b1
...
@@ -19,6 +19,8 @@
...
@@ -19,6 +19,8 @@
is set incorrectly
is set incorrectly
(
[
#4083
](
https://github.com/google/ExoPlayer/issues/4083
)
). Such content
(
[
#4083
](
https://github.com/google/ExoPlayer/issues/4083
)
). Such content
is malformed and should be re-encoded.
is malformed and should be re-encoded.
*
Improve support for truncated Ogg streams
(
[
#7608
](
https://github.com/google/ExoPlayer/issues/7608
)
).
*
HLS:
*
HLS:
*
Fix issue where playback of a live event could become stuck rather than
*
Fix issue where playback of a live event could become stuck rather than
transitioning to
`STATE_ENDED`
when the event ends
transitioning to
`STATE_ENDED`
when the event ends
...
...
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/ExtractorUtil.java
View file @
e272e3b1
...
@@ -16,10 +16,11 @@
...
@@ -16,10 +16,11 @@
package
com
.
google
.
android
.
exoplayer2
.
extractor
;
package
com
.
google
.
android
.
exoplayer2
.
extractor
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.C
;
import
java.io.EOFException
;
import
java.io.IOException
;
import
java.io.IOException
;
/** Extractor related utility methods. */
/** Extractor related utility methods. */
/* package */
final
class
ExtractorUtil
{
public
final
class
ExtractorUtil
{
/**
/**
* Peeks {@code length} bytes from the input peek position, or all the bytes to the end of the
* Peeks {@code length} bytes from the input peek position, or all the bytes to the end of the
...
@@ -47,5 +48,62 @@ import java.io.IOException;
...
@@ -47,5 +48,62 @@ import java.io.IOException;
return
totalBytesPeeked
;
return
totalBytesPeeked
;
}
}
/**
* Equivalent to {@link ExtractorInput#readFully(byte[], int, int)} except that it returns {@code
* false} instead of throwing an {@link EOFException} if the end of input is encountered without
* having fully satisfied the read.
*/
public
static
boolean
readFullyQuietly
(
ExtractorInput
input
,
byte
[]
output
,
int
offset
,
int
length
)
throws
IOException
{
try
{
input
.
readFully
(
output
,
offset
,
length
);
}
catch
(
EOFException
e
)
{
return
false
;
}
return
true
;
}
/**
* Equivalent to {@link ExtractorInput#skipFully(int)} except that it returns {@code false}
* instead of throwing an {@link EOFException} if the end of input is encountered without having
* fully satisfied the skip.
*/
public
static
boolean
skipFullyQuietly
(
ExtractorInput
input
,
int
length
)
throws
IOException
{
try
{
input
.
skipFully
(
length
);
}
catch
(
EOFException
e
)
{
return
false
;
}
return
true
;
}
/**
* Peeks data from {@code input}, respecting {@code allowEndOfInput}. Returns true if the peek is
* successful.
*
* <p>If {@code allowEndOfInput=false} then encountering the end of the input (whether before or
* after reading some data) will throw {@link EOFException}.
*
* <p>If {@code allowEndOfInput=true} then encountering the end of the input (even after reading
* some data) will return {@code false}.
*
* <p>This is slightly different to the behaviour of {@link ExtractorInput#peekFully(byte[], int,
* int, boolean)}, where {@code allowEndOfInput=true} only returns false (and suppresses the
* exception) if the end of the input is reached before reading any data.
*/
public
static
boolean
peekFullyQuietly
(
ExtractorInput
input
,
byte
[]
output
,
int
offset
,
int
length
,
boolean
allowEndOfInput
)
throws
IOException
{
try
{
return
input
.
peekFully
(
output
,
offset
,
length
,
/* allowEndOfInput= */
allowEndOfInput
);
}
catch
(
EOFException
e
)
{
if
(
allowEndOfInput
)
{
return
false
;
}
else
{
throw
e
;
}
}
}
private
ExtractorUtil
()
{}
private
ExtractorUtil
()
{}
}
}
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/ogg/DefaultOggSeeker.java
View file @
e272e3b1
...
@@ -15,6 +15,8 @@
...
@@ -15,6 +15,8 @@
*/
*/
package
com
.
google
.
android
.
exoplayer2
.
extractor
.
ogg
;
package
com
.
google
.
android
.
exoplayer2
.
extractor
.
ogg
;
import
static
com
.
google
.
android
.
exoplayer2
.
extractor
.
ExtractorUtil
.
skipFullyQuietly
;
import
androidx.annotation.Nullable
;
import
androidx.annotation.Nullable
;
import
androidx.annotation.VisibleForTesting
;
import
androidx.annotation.VisibleForTesting
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.C
;
...
@@ -229,13 +231,21 @@ import java.io.IOException;
...
@@ -229,13 +231,21 @@ import java.io.IOException;
if
(!
pageHeader
.
skipToNextPage
(
input
))
{
if
(!
pageHeader
.
skipToNextPage
(
input
))
{
throw
new
EOFException
();
throw
new
EOFException
();
}
}
do
{
pageHeader
.
populate
(
input
,
/* quiet= */
false
);
pageHeader
.
populate
(
input
,
/* quiet= */
false
);
input
.
skipFully
(
pageHeader
.
headerSize
+
pageHeader
.
bodySize
);
input
.
skipFully
(
pageHeader
.
headerSize
+
pageHeader
.
bodySize
);
}
while
((
pageHeader
.
type
&
0x04
)
!=
0x04
long
granulePosition
=
pageHeader
.
granulePosition
;
while
((
pageHeader
.
type
&
0x04
)
!=
0x04
&&
pageHeader
.
skipToNextPage
(
input
)
&&
pageHeader
.
skipToNextPage
(
input
)
&&
input
.
getPosition
()
<
payloadEndPosition
);
&&
input
.
getPosition
()
<
payloadEndPosition
)
{
return
pageHeader
.
granulePosition
;
boolean
hasPopulated
=
pageHeader
.
populate
(
input
,
/* quiet= */
true
);
if
(!
hasPopulated
||
!
skipFullyQuietly
(
input
,
pageHeader
.
headerSize
+
pageHeader
.
bodySize
))
{
// The input file contains a partial page at the end. Ignore it and return the granule
// position of the last complete page.
return
granulePosition
;
}
granulePosition
=
pageHeader
.
granulePosition
;
}
return
granulePosition
;
}
}
private
final
class
OggSeekMap
implements
SeekMap
{
private
final
class
OggSeekMap
implements
SeekMap
{
...
...
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/ogg/OggPacket.java
View file @
e272e3b1
...
@@ -15,6 +15,8 @@
...
@@ -15,6 +15,8 @@
*/
*/
package
com
.
google
.
android
.
exoplayer2
.
extractor
.
ogg
;
package
com
.
google
.
android
.
exoplayer2
.
extractor
.
ogg
;
import
static
com
.
google
.
android
.
exoplayer2
.
extractor
.
ExtractorUtil
.
readFullyQuietly
;
import
static
com
.
google
.
android
.
exoplayer2
.
extractor
.
ExtractorUtil
.
skipFullyQuietly
;
import
static
java
.
lang
.
Math
.
max
;
import
static
java
.
lang
.
Math
.
max
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.C
;
...
@@ -55,7 +57,7 @@ import java.util.Arrays;
...
@@ -55,7 +57,7 @@ import java.util.Arrays;
*
*
* @param input The {@link ExtractorInput} to read data from.
* @param input The {@link ExtractorInput} to read data from.
* @return {@code true} if the read was successful. The read fails if the end of the input is
* @return {@code true} if the read was successful. The read fails if the end of the input is
* encountered without reading
data
.
* encountered without reading
the whole packet
.
* @throws IOException If reading from the input fails.
* @throws IOException If reading from the input fails.
*/
*/
public
boolean
populate
(
ExtractorInput
input
)
throws
IOException
{
public
boolean
populate
(
ExtractorInput
input
)
throws
IOException
{
...
@@ -80,7 +82,9 @@ import java.util.Arrays;
...
@@ -80,7 +82,9 @@ import java.util.Arrays;
bytesToSkip
+=
calculatePacketSize
(
segmentIndex
);
bytesToSkip
+=
calculatePacketSize
(
segmentIndex
);
segmentIndex
+=
segmentCount
;
segmentIndex
+=
segmentCount
;
}
}
input
.
skipFully
(
bytesToSkip
);
if
(!
skipFullyQuietly
(
input
,
bytesToSkip
))
{
return
false
;
}
currentSegmentIndex
=
segmentIndex
;
currentSegmentIndex
=
segmentIndex
;
}
}
...
@@ -88,7 +92,9 @@ import java.util.Arrays;
...
@@ -88,7 +92,9 @@ import java.util.Arrays;
int
segmentIndex
=
currentSegmentIndex
+
segmentCount
;
int
segmentIndex
=
currentSegmentIndex
+
segmentCount
;
if
(
size
>
0
)
{
if
(
size
>
0
)
{
packetArray
.
ensureCapacity
(
packetArray
.
limit
()
+
size
);
packetArray
.
ensureCapacity
(
packetArray
.
limit
()
+
size
);
input
.
readFully
(
packetArray
.
getData
(),
packetArray
.
limit
(),
size
);
if
(!
readFullyQuietly
(
input
,
packetArray
.
getData
(),
packetArray
.
limit
(),
size
))
{
return
false
;
}
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/ogg/OggPageHeader.java
View file @
e272e3b1
...
@@ -15,12 +15,13 @@
...
@@ -15,12 +15,13 @@
*/
*/
package
com
.
google
.
android
.
exoplayer2
.
extractor
.
ogg
;
package
com
.
google
.
android
.
exoplayer2
.
extractor
.
ogg
;
import
static
com
.
google
.
android
.
exoplayer2
.
extractor
.
ExtractorUtil
.
peekFullyQuietly
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.ParserException
;
import
com.google.android.exoplayer2.ParserException
;
import
com.google.android.exoplayer2.extractor.ExtractorInput
;
import
com.google.android.exoplayer2.extractor.ExtractorInput
;
import
com.google.android.exoplayer2.util.Assertions
;
import
com.google.android.exoplayer2.util.Assertions
;
import
com.google.android.exoplayer2.util.ParsableByteArray
;
import
com.google.android.exoplayer2.util.ParsableByteArray
;
import
java.io.EOFException
;
import
java.io.IOException
;
import
java.io.IOException
;
/**
/**
...
@@ -106,7 +107,8 @@ import java.io.IOException;
...
@@ -106,7 +107,8 @@ import java.io.IOException;
Assertions
.
checkArgument
(
input
.
getPosition
()
==
input
.
getPeekPosition
());
Assertions
.
checkArgument
(
input
.
getPosition
()
==
input
.
getPeekPosition
());
scratch
.
reset
(
/* limit= */
CAPTURE_PATTERN_SIZE
);
scratch
.
reset
(
/* limit= */
CAPTURE_PATTERN_SIZE
);
while
((
limit
==
C
.
POSITION_UNSET
||
input
.
getPosition
()
+
CAPTURE_PATTERN_SIZE
<
limit
)
while
((
limit
==
C
.
POSITION_UNSET
||
input
.
getPosition
()
+
CAPTURE_PATTERN_SIZE
<
limit
)
&&
peekSafely
(
input
,
scratch
.
getData
(),
0
,
CAPTURE_PATTERN_SIZE
,
/* quiet= */
true
))
{
&&
peekFullyQuietly
(
input
,
scratch
.
getData
(),
0
,
CAPTURE_PATTERN_SIZE
,
/* allowEndOfInput= */
true
))
{
scratch
.
setPosition
(
0
);
scratch
.
setPosition
(
0
);
if
(
scratch
.
readUnsignedInt
()
==
CAPTURE_PATTERN
)
{
if
(
scratch
.
readUnsignedInt
()
==
CAPTURE_PATTERN
)
{
input
.
resetPeekPosition
();
input
.
resetPeekPosition
();
...
@@ -127,14 +129,13 @@ import java.io.IOException;
...
@@ -127,14 +129,13 @@ import java.io.IOException;
* @param input The {@link ExtractorInput} to read from.
* @param input The {@link ExtractorInput} to read from.
* @param quiet Whether to return {@code false} rather than throwing an exception if the header
* @param quiet Whether to return {@code false} rather than throwing an exception if the header
* cannot be populated.
* cannot be populated.
* @return Whether the read was successful. The read fails if the end of the input is encountered
* @return Whether the header was entirely populated.
* without reading data.
* @throws IOException If reading data fails or the stream is invalid.
* @throws IOException If reading data fails or the stream is invalid.
*/
*/
public
boolean
populate
(
ExtractorInput
input
,
boolean
quiet
)
throws
IOException
{
public
boolean
populate
(
ExtractorInput
input
,
boolean
quiet
)
throws
IOException
{
reset
();
reset
();
scratch
.
reset
(
/* limit= */
EMPTY_PAGE_HEADER_SIZE
);
scratch
.
reset
(
/* limit= */
EMPTY_PAGE_HEADER_SIZE
);
if
(!
peek
Safe
ly
(
input
,
scratch
.
getData
(),
0
,
EMPTY_PAGE_HEADER_SIZE
,
quiet
)
if
(!
peek
FullyQuiet
ly
(
input
,
scratch
.
getData
(),
0
,
EMPTY_PAGE_HEADER_SIZE
,
quiet
)
||
scratch
.
readUnsignedInt
()
!=
CAPTURE_PATTERN
)
{
||
scratch
.
readUnsignedInt
()
!=
CAPTURE_PATTERN
)
{
return
false
;
return
false
;
}
}
...
@@ -158,7 +159,9 @@ import java.io.IOException;
...
@@ -158,7 +159,9 @@ import java.io.IOException;
// calculate total size of header including laces
// calculate total size of header including laces
scratch
.
reset
(
/* limit= */
pageSegmentCount
);
scratch
.
reset
(
/* limit= */
pageSegmentCount
);
input
.
peekFully
(
scratch
.
getData
(),
0
,
pageSegmentCount
);
if
(!
peekFullyQuietly
(
input
,
scratch
.
getData
(),
0
,
pageSegmentCount
,
quiet
))
{
return
false
;
}
for
(
int
i
=
0
;
i
<
pageSegmentCount
;
i
++)
{
for
(
int
i
=
0
;
i
<
pageSegmentCount
;
i
++)
{
laces
[
i
]
=
scratch
.
readUnsignedByte
();
laces
[
i
]
=
scratch
.
readUnsignedByte
();
bodySize
+=
laces
[
i
];
bodySize
+=
laces
[
i
];
...
@@ -166,31 +169,4 @@ import java.io.IOException;
...
@@ -166,31 +169,4 @@ import java.io.IOException;
return
true
;
return
true
;
}
}
/**
* Peek data from {@code input}, respecting {@code quiet}. Return true if the peek is successful.
*
* <p>If {@code quiet=false} then encountering the end of the input (whether before or after
* reading some data) will throw {@link EOFException}.
*
* <p>If {@code quiet=true} then encountering the end of the input (even after reading some data)
* will return {@code false}.
*
* <p>This is slightly different to the behaviour of {@link ExtractorInput#peekFully(byte[], int,
* int, boolean)}, where {@code allowEndOfInput=true} only returns false (and suppresses the
* exception) if the end of the input is reached before reading any data.
*/
private
static
boolean
peekSafely
(
ExtractorInput
input
,
byte
[]
output
,
int
offset
,
int
length
,
boolean
quiet
)
throws
IOException
{
try
{
return
input
.
peekFully
(
output
,
offset
,
length
,
/* allowEndOfInput= */
quiet
);
}
catch
(
EOFException
e
)
{
if
(
quiet
)
{
return
false
;
}
else
{
throw
e
;
}
}
}
}
}
library/extractor/src/test/java/com/google/android/exoplayer2/extractor/ExtractorUtilTest.java
View file @
e272e3b1
...
@@ -16,12 +16,14 @@
...
@@ -16,12 +16,14 @@
package
com
.
google
.
android
.
exoplayer2
.
extractor
;
package
com
.
google
.
android
.
exoplayer2
.
extractor
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
import
static
org
.
junit
.
Assert
.
assertThrows
;
import
android.net.Uri
;
import
android.net.Uri
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.testutil.FakeDataSource
;
import
com.google.android.exoplayer2.testutil.FakeDataSource
;
import
com.google.android.exoplayer2.upstream.DataSpec
;
import
com.google.android.exoplayer2.upstream.DataSpec
;
import
java.io.EOFException
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
org.junit.Test
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.junit.runner.RunWith
;
...
@@ -34,12 +36,12 @@ public class ExtractorUtilTest {
...
@@ -34,12 +36,12 @@ public class ExtractorUtilTest {
private
static
final
byte
[]
TEST_DATA
=
new
byte
[]
{
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
};
private
static
final
byte
[]
TEST_DATA
=
new
byte
[]
{
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
};
@Test
@Test
public
void
peekToLength
E
ndNotReached
()
throws
Exception
{
public
void
peekToLength
_e
ndNotReached
()
throws
Exception
{
FakeDataSource
testDataSource
=
new
FakeDataSource
();
FakeDataSource
testDataSource
=
new
FakeDataSource
();
testDataSource
testDataSource
.
getDataSet
()
.
getDataSet
()
.
newDefaultData
()
.
newDefaultData
()
.
appendReadData
(
Arrays
.
copyOf
Range
(
TEST_DATA
,
0
,
3
))
.
appendReadData
(
Arrays
.
copyOf
(
TEST_DATA
,
3
))
.
appendReadData
(
Arrays
.
copyOfRange
(
TEST_DATA
,
3
,
6
))
.
appendReadData
(
Arrays
.
copyOfRange
(
TEST_DATA
,
3
,
6
))
.
appendReadData
(
Arrays
.
copyOfRange
(
TEST_DATA
,
6
,
9
));
.
appendReadData
(
Arrays
.
copyOfRange
(
TEST_DATA
,
6
,
9
));
testDataSource
.
open
(
new
DataSpec
(
Uri
.
parse
(
TEST_URI
)));
testDataSource
.
open
(
new
DataSpec
(
Uri
.
parse
(
TEST_URI
)));
...
@@ -57,12 +59,12 @@ public class ExtractorUtilTest {
...
@@ -57,12 +59,12 @@ public class ExtractorUtilTest {
}
}
@Test
@Test
public
void
peekToLength
E
ndReached
()
throws
Exception
{
public
void
peekToLength
_e
ndReached
()
throws
Exception
{
FakeDataSource
testDataSource
=
new
FakeDataSource
();
FakeDataSource
testDataSource
=
new
FakeDataSource
();
testDataSource
testDataSource
.
getDataSet
()
.
getDataSet
()
.
newDefaultData
()
.
newDefaultData
()
.
appendReadData
(
Arrays
.
copyOf
Range
(
TEST_DATA
,
0
,
3
))
.
appendReadData
(
Arrays
.
copyOf
(
TEST_DATA
,
3
))
.
appendReadData
(
Arrays
.
copyOfRange
(
TEST_DATA
,
3
,
6
))
.
appendReadData
(
Arrays
.
copyOfRange
(
TEST_DATA
,
3
,
6
))
.
appendReadData
(
Arrays
.
copyOfRange
(
TEST_DATA
,
6
,
9
));
.
appendReadData
(
Arrays
.
copyOfRange
(
TEST_DATA
,
6
,
9
));
testDataSource
.
open
(
new
DataSpec
(
Uri
.
parse
(
TEST_URI
)));
testDataSource
.
open
(
new
DataSpec
(
Uri
.
parse
(
TEST_URI
)));
...
@@ -77,4 +79,135 @@ public class ExtractorUtilTest {
...
@@ -77,4 +79,135 @@ public class ExtractorUtilTest {
assertThat
(
input
.
getPeekPosition
()).
isEqualTo
(
TEST_DATA
.
length
);
assertThat
(
input
.
getPeekPosition
()).
isEqualTo
(
TEST_DATA
.
length
);
assertThat
(
target
).
isEqualTo
(
TEST_DATA
);
assertThat
(
target
).
isEqualTo
(
TEST_DATA
);
}
}
@Test
public
void
readFullyQuietly_endNotReached_isTrueAndReadsData
()
throws
Exception
{
FakeDataSource
testDataSource
=
new
FakeDataSource
();
testDataSource
.
getDataSet
()
.
newDefaultData
()
.
appendReadData
(
Arrays
.
copyOf
(
TEST_DATA
,
3
))
.
appendReadData
(
Arrays
.
copyOfRange
(
TEST_DATA
,
3
,
6
))
.
appendReadData
(
Arrays
.
copyOfRange
(
TEST_DATA
,
6
,
9
));
testDataSource
.
open
(
new
DataSpec
(
Uri
.
parse
(
TEST_URI
)));
ExtractorInput
input
=
new
DefaultExtractorInput
(
testDataSource
,
0
,
C
.
LENGTH_UNSET
);
byte
[]
target
=
new
byte
[
TEST_DATA
.
length
];
int
offset
=
2
;
int
length
=
4
;
boolean
hasRead
=
ExtractorUtil
.
readFullyQuietly
(
input
,
target
,
offset
,
length
);
assertThat
(
hasRead
).
isTrue
();
assertThat
(
input
.
getPosition
()).
isEqualTo
(
length
);
assertThat
(
Arrays
.
copyOfRange
(
target
,
offset
,
offset
+
length
))
.
isEqualTo
(
Arrays
.
copyOf
(
TEST_DATA
,
length
));
}
@Test
public
void
readFullyQuietly_endReached_isFalse
()
throws
Exception
{
FakeDataSource
testDataSource
=
new
FakeDataSource
();
testDataSource
.
getDataSet
().
newDefaultData
().
appendReadData
(
Arrays
.
copyOf
(
TEST_DATA
,
3
));
testDataSource
.
open
(
new
DataSpec
(
Uri
.
parse
(
TEST_URI
)));
ExtractorInput
input
=
new
DefaultExtractorInput
(
testDataSource
,
0
,
C
.
LENGTH_UNSET
);
byte
[]
target
=
new
byte
[
TEST_DATA
.
length
];
int
offset
=
0
;
int
length
=
TEST_DATA
.
length
+
1
;
boolean
hasRead
=
ExtractorUtil
.
readFullyQuietly
(
input
,
target
,
offset
,
length
);
assertThat
(
hasRead
).
isFalse
();
assertThat
(
input
.
getPosition
()).
isEqualTo
(
0
);
}
@Test
public
void
skipFullyQuietly_endNotReached_isTrueAndSkipsData
()
throws
Exception
{
FakeDataSource
testDataSource
=
new
FakeDataSource
();
testDataSource
.
getDataSet
()
.
newDefaultData
()
.
appendReadData
(
Arrays
.
copyOf
(
TEST_DATA
,
3
))
.
appendReadData
(
Arrays
.
copyOfRange
(
TEST_DATA
,
3
,
6
))
.
appendReadData
(
Arrays
.
copyOfRange
(
TEST_DATA
,
6
,
9
));
testDataSource
.
open
(
new
DataSpec
(
Uri
.
parse
(
TEST_URI
)));
ExtractorInput
input
=
new
DefaultExtractorInput
(
testDataSource
,
0
,
C
.
LENGTH_UNSET
);
int
length
=
4
;
boolean
hasRead
=
ExtractorUtil
.
skipFullyQuietly
(
input
,
length
);
assertThat
(
hasRead
).
isTrue
();
assertThat
(
input
.
getPosition
()).
isEqualTo
(
length
);
}
@Test
public
void
skipFullyQuietly_endReached_isFalse
()
throws
Exception
{
FakeDataSource
testDataSource
=
new
FakeDataSource
();
testDataSource
.
getDataSet
().
newDefaultData
().
appendReadData
(
Arrays
.
copyOf
(
TEST_DATA
,
3
));
testDataSource
.
open
(
new
DataSpec
(
Uri
.
parse
(
TEST_URI
)));
ExtractorInput
input
=
new
DefaultExtractorInput
(
testDataSource
,
0
,
C
.
LENGTH_UNSET
);
int
length
=
TEST_DATA
.
length
+
1
;
boolean
hasRead
=
ExtractorUtil
.
skipFullyQuietly
(
input
,
length
);
assertThat
(
hasRead
).
isFalse
();
assertThat
(
input
.
getPosition
()).
isEqualTo
(
0
);
}
@Test
public
void
peekFullyQuietly_endNotReached_isTrueAndPeeksData
()
throws
Exception
{
FakeDataSource
testDataSource
=
new
FakeDataSource
();
testDataSource
.
getDataSet
()
.
newDefaultData
()
.
appendReadData
(
Arrays
.
copyOf
(
TEST_DATA
,
3
))
.
appendReadData
(
Arrays
.
copyOfRange
(
TEST_DATA
,
3
,
6
))
.
appendReadData
(
Arrays
.
copyOfRange
(
TEST_DATA
,
6
,
9
));
testDataSource
.
open
(
new
DataSpec
(
Uri
.
parse
(
TEST_URI
)));
ExtractorInput
input
=
new
DefaultExtractorInput
(
testDataSource
,
0
,
C
.
LENGTH_UNSET
);
byte
[]
target
=
new
byte
[
TEST_DATA
.
length
];
int
offset
=
2
;
int
length
=
4
;
boolean
hasRead
=
ExtractorUtil
.
peekFullyQuietly
(
input
,
target
,
offset
,
length
,
/* allowEndOfInput= */
false
);
assertThat
(
hasRead
).
isTrue
();
assertThat
(
input
.
getPeekPosition
()).
isEqualTo
(
length
);
assertThat
(
Arrays
.
copyOfRange
(
target
,
offset
,
offset
+
length
))
.
isEqualTo
(
Arrays
.
copyOf
(
TEST_DATA
,
length
));
}
@Test
public
void
peekFullyQuietly_endReachedWithEndOfInputAllowed_isFalse
()
throws
Exception
{
FakeDataSource
testDataSource
=
new
FakeDataSource
();
testDataSource
.
getDataSet
().
newDefaultData
().
appendReadData
(
Arrays
.
copyOf
(
TEST_DATA
,
3
));
testDataSource
.
open
(
new
DataSpec
(
Uri
.
parse
(
TEST_URI
)));
ExtractorInput
input
=
new
DefaultExtractorInput
(
testDataSource
,
0
,
C
.
LENGTH_UNSET
);
byte
[]
target
=
new
byte
[
TEST_DATA
.
length
];
int
offset
=
0
;
int
length
=
TEST_DATA
.
length
+
1
;
boolean
hasRead
=
ExtractorUtil
.
peekFullyQuietly
(
input
,
target
,
offset
,
length
,
/* allowEndOfInput= */
true
);
assertThat
(
hasRead
).
isFalse
();
assertThat
(
input
.
getPeekPosition
()).
isEqualTo
(
0
);
}
@Test
public
void
peekFullyQuietly_endReachedWithoutEndOfInputAllowed_throws
()
throws
Exception
{
FakeDataSource
testDataSource
=
new
FakeDataSource
();
testDataSource
.
getDataSet
().
newDefaultData
().
appendReadData
(
Arrays
.
copyOf
(
TEST_DATA
,
3
));
testDataSource
.
open
(
new
DataSpec
(
Uri
.
parse
(
TEST_URI
)));
ExtractorInput
input
=
new
DefaultExtractorInput
(
testDataSource
,
0
,
C
.
LENGTH_UNSET
);
byte
[]
target
=
new
byte
[
TEST_DATA
.
length
];
int
offset
=
0
;
int
length
=
TEST_DATA
.
length
+
1
;
assertThrows
(
EOFException
.
class
,
()
->
ExtractorUtil
.
peekFullyQuietly
(
input
,
target
,
offset
,
length
,
/* allowEndOfInput= */
false
));
assertThat
(
input
.
getPeekPosition
()).
isEqualTo
(
0
);
}
}
}
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