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
2d727dea
authored
Feb 02, 2022
by
Dustin
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Found out RESULT_SEEK is a bad thing. Greatly improved Extractor efficiency.
(cherry picked from commit
1528b8b5
)
parent
30257b0e
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
59 additions
and
64 deletions
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/avi/AviExtractor.java
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/avi/StreamHeaderBox.java
library/extractor/src/test/java/com/google/android/exoplayer2/extractor/avi/AviExtractorRoboTest.java
library/extractor/src/test/java/com/google/android/exoplayer2/extractor/avi/AviExtractorTest.java
library/extractor/src/test/java/com/google/android/exoplayer2/extractor/avi/AviSeekMapTest.java
library/extractor/src/test/java/com/google/android/exoplayer2/extractor/avi/StreamHeaderBoxTest.java
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/avi/AviExtractor.java
View file @
2d727dea
...
@@ -72,15 +72,6 @@ public class AviExtractor implements Extractor {
...
@@ -72,15 +72,6 @@ public class AviExtractor implements Extractor {
}
}
}
}
static
int
alignPositionHolder
(
@NonNull
ExtractorInput
input
,
@NonNull
PositionHolder
seekPosition
)
{
final
long
position
=
input
.
getPosition
();
if
((
position
&
1
)
==
1
)
{
seekPosition
.
position
=
position
+
1
;
return
RESULT_SEEK
;
}
return
RESULT_CONTINUE
;
}
@NonNull
@NonNull
static
ByteBuffer
allocate
(
int
bytes
)
{
static
ByteBuffer
allocate
(
int
bytes
)
{
final
byte
[]
buffer
=
new
byte
[
bytes
];
final
byte
[]
buffer
=
new
byte
[
bytes
];
...
@@ -503,47 +494,56 @@ public class AviExtractor implements Extractor {
...
@@ -503,47 +494,56 @@ public class AviExtractor implements Extractor {
return
null
;
return
null
;
}
}
int
readSamples
(
@NonNull
ExtractorInput
input
,
@NonNull
PositionHolder
seekPosition
)
throws
IOException
{
int
readSamples
(
@NonNull
ExtractorInput
input
)
throws
IOException
{
if
(
chunkHandler
!=
null
)
{
if
(
chunkHandler
!=
null
)
{
if
(
chunkHandler
.
resume
(
input
))
{
if
(
chunkHandler
.
resume
(
input
))
{
chunkHandler
=
null
;
chunkHandler
=
null
;
return
alignPositionHolder
(
input
,
seekPosition
);
alignInput
(
input
);
}
}
}
else
{
}
else
{
ByteBuffer
byteBuffer
=
allocate
(
8
);
final
int
toRead
=
8
;
ByteBuffer
byteBuffer
=
allocate
(
toRead
);
final
byte
[]
bytes
=
byteBuffer
.
array
();
final
byte
[]
bytes
=
byteBuffer
.
array
();
alignInput
(
input
);
alignInput
(
input
);
input
.
readFully
(
bytes
,
0
,
1
);
input
.
readFully
(
bytes
,
0
,
toRead
);
//This is super inefficient, but should be rare
while
(
bytes
[
0
]
==
0
)
{
while
(
bytes
[
0
]
==
0
)
{
input
.
readFully
(
bytes
,
0
,
1
);
for
(
int
i
=
1
;
i
<
toRead
;
i
++)
{
}
bytes
[
i
-
1
]
=
bytes
[
i
];
if
(
input
.
getPosition
()
>=
moviEnd
)
{
}
return
RESULT_END_OF_INPUT
;
int
read
=
input
.
read
(
bytes
,
toRead
-
1
,
1
);
if
(
read
==
C
.
RESULT_END_OF_INPUT
)
{
return
RESULT_END_OF_INPUT
;
}
}
}
input
.
readFully
(
bytes
,
1
,
7
);
final
int
chunkId
=
byteBuffer
.
getInt
();
final
int
chunkId
=
byteBuffer
.
getInt
();
if
(
chunkId
==
ListBox
.
LIST
)
{
if
(
chunkId
==
ListBox
.
LIST
)
{
seekPosition
.
position
=
input
.
getPosition
()
+
8
;
input
.
skipFully
(
8
)
;
return
RESULT_
SEEK
;
return
RESULT_
CONTINUE
;
}
}
final
int
size
=
byteBuffer
.
getInt
();
final
int
size
=
byteBuffer
.
getInt
();
if
(
chunkId
==
JUNK
)
{
if
(
chunkId
==
JUNK
)
{
seekPosition
.
position
=
alignPosition
(
input
.
getPosition
()
+
size
);
input
.
skipFully
(
size
);
return
RESULT_SEEK
;
alignInput
(
input
);
return
RESULT_CONTINUE
;
}
}
final
AviTrack
aviTrack
=
getAviTrack
(
chunkId
);
final
AviTrack
aviTrack
=
getAviTrack
(
chunkId
);
if
(
aviTrack
==
null
)
{
if
(
aviTrack
==
null
)
{
seekPosition
.
position
=
alignPosition
(
input
.
getPosition
()
+
size
);
input
.
skipFully
(
size
);
alignInput
(
input
);
w
(
"Unknown tag="
+
toString
(
chunkId
)
+
" pos="
+
(
input
.
getPosition
()
-
8
)
w
(
"Unknown tag="
+
toString
(
chunkId
)
+
" pos="
+
(
input
.
getPosition
()
-
8
)
+
" size="
+
size
+
" moviEnd="
+
moviEnd
);
+
" size="
+
size
+
" moviEnd="
+
moviEnd
);
return
RESULT_
SEEK
;
return
RESULT_
CONTINUE
;
}
}
if
(
aviTrack
.
newChunk
(
chunkId
,
size
,
input
))
{
if
(
aviTrack
.
newChunk
(
chunkId
,
size
,
input
))
{
return
alignPositionHolder
(
input
,
seekPosition
);
alignInput
(
input
);
}
else
{
}
else
{
chunkHandler
=
aviTrack
;
chunkHandler
=
aviTrack
;
}
}
}
}
if
(
input
.
getPosition
()
==
input
.
getLength
())
{
return
C
.
RESULT_END_OF_INPUT
;
}
return
RESULT_CONTINUE
;
return
RESULT_CONTINUE
;
}
}
...
@@ -551,7 +551,7 @@ public class AviExtractor implements Extractor {
...
@@ -551,7 +551,7 @@ public class AviExtractor implements Extractor {
public
int
read
(
@NonNull
ExtractorInput
input
,
@NonNull
PositionHolder
seekPosition
)
throws
IOException
{
public
int
read
(
@NonNull
ExtractorInput
input
,
@NonNull
PositionHolder
seekPosition
)
throws
IOException
{
switch
(
state
)
{
switch
(
state
)
{
case
STATE_READ_SAMPLES:
case
STATE_READ_SAMPLES:
return
readSamples
(
input
,
seekPosition
);
return
readSamples
(
input
);
case
STATE_SEEK_START:
case
STATE_SEEK_START:
state
=
STATE_READ_SAMPLES
;
state
=
STATE_READ_SAMPLES
;
seekPosition
.
position
=
moviOffset
+
4
;
seekPosition
.
position
=
moviOffset
+
4
;
...
...
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/avi/StreamHeaderBox.java
View file @
2d727dea
...
@@ -15,6 +15,7 @@
...
@@ -15,6 +15,7 @@
*/
*/
package
com
.
google
.
android
.
exoplayer2
.
extractor
.
avi
;
package
com
.
google
.
android
.
exoplayer2
.
extractor
.
avi
;
import
com.google.android.exoplayer2.C
;
import
java.nio.ByteBuffer
;
import
java.nio.ByteBuffer
;
/**
/**
...
@@ -46,7 +47,7 @@ public class StreamHeaderBox extends ResidentBox {
...
@@ -46,7 +47,7 @@ public class StreamHeaderBox extends ResidentBox {
}
}
public
long
getDurationUs
()
{
public
long
getDurationUs
()
{
return
1_000_000L
*
getScale
()
*
getLength
()
/
getRate
();
return
C
.
MICROS_PER_SECOND
*
getScale
()
*
getLength
()
/
getRate
();
}
}
public
int
getSteamType
()
{
public
int
getSteamType
()
{
...
...
library/extractor/src/test/java/com/google/android/exoplayer2/extractor/avi/AviExtractorRoboTest.java
View file @
2d727dea
...
@@ -112,4 +112,22 @@ public class AviExtractorRoboTest {
...
@@ -112,4 +112,22 @@ public class AviExtractorRoboTest {
Assert
.
assertEquals
(
aviTrack
.
getClock
().
durationUs
,
streamHeaderBox
.
getDurationUs
());
Assert
.
assertEquals
(
aviTrack
.
getClock
().
durationUs
,
streamHeaderBox
.
getDurationUs
());
}
}
@Test
public
void
readSamples_fragmentedChunk
()
throws
IOException
{
AviExtractor
aviExtractor
=
AviExtractorTest
.
setupVideoAviExtractor
();
final
AviTrack
aviTrack
=
aviExtractor
.
getVideoTrack
();
final
int
size
=
24
+
16
;
final
ByteBuffer
byteBuffer
=
AviExtractor
.
allocate
(
size
+
8
);
byteBuffer
.
putInt
(
aviTrack
.
chunkId
);
byteBuffer
.
putInt
(
size
);
final
ExtractorInput
chunk
=
new
FakeExtractorInput
.
Builder
().
setData
(
byteBuffer
.
array
()).
setSimulatePartialReads
(
true
).
build
();
Assert
.
assertEquals
(
Extractor
.
RESULT_CONTINUE
,
aviExtractor
.
read
(
chunk
,
new
PositionHolder
()));
Assert
.
assertEquals
(
Extractor
.
RESULT_END_OF_INPUT
,
aviExtractor
.
read
(
chunk
,
new
PositionHolder
()));
final
FakeTrackOutput
fakeTrackOutput
=
(
FakeTrackOutput
)
aviTrack
.
trackOutput
;
Assert
.
assertEquals
(
size
,
fakeTrackOutput
.
getSampleData
(
0
).
length
);
}
}
}
library/extractor/src/test/java/com/google/android/exoplayer2/extractor/avi/AviExtractorTest.java
View file @
2d727dea
...
@@ -304,28 +304,6 @@ public class AviExtractorTest {
...
@@ -304,28 +304,6 @@ public class AviExtractorTest {
}
}
@Test
@Test
public
void
alignPositionHolder_givenOddPosition
()
{
final
FakeExtractorInput
fakeExtractorInput
=
new
FakeExtractorInput
.
Builder
().
setData
(
new
byte
[
4
]).
build
();
fakeExtractorInput
.
setPosition
(
1
);
final
PositionHolder
positionHolder
=
new
PositionHolder
();
final
int
result
=
AviExtractor
.
alignPositionHolder
(
fakeExtractorInput
,
positionHolder
);
Assert
.
assertEquals
(
Extractor
.
RESULT_SEEK
,
result
);
Assert
.
assertEquals
(
2
,
positionHolder
.
position
);
}
@Test
public
void
alignPositionHolder_givenEvenPosition
()
{
final
FakeExtractorInput
fakeExtractorInput
=
new
FakeExtractorInput
.
Builder
().
setData
(
new
byte
[
4
]).
build
();
fakeExtractorInput
.
setPosition
(
2
);
final
PositionHolder
positionHolder
=
new
PositionHolder
();
final
int
result
=
AviExtractor
.
alignPositionHolder
(
fakeExtractorInput
,
positionHolder
);
Assert
.
assertEquals
(
Extractor
.
RESULT_CONTINUE
,
result
);
}
@Test
public
void
readHeaderList_givenBadHeader
()
throws
IOException
{
public
void
readHeaderList_givenBadHeader
()
throws
IOException
{
final
FakeExtractorInput
input
=
new
FakeExtractorInput
.
Builder
().
setData
(
new
byte
[
32
]).
build
();
final
FakeExtractorInput
input
=
new
FakeExtractorInput
.
Builder
().
setData
(
new
byte
[
32
]).
build
();
Assert
.
assertNull
(
AviExtractor
.
readHeaderList
(
input
));
Assert
.
assertNull
(
AviExtractor
.
readHeaderList
(
input
));
...
@@ -405,7 +383,7 @@ public class AviExtractorTest {
...
@@ -405,7 +383,7 @@ public class AviExtractorTest {
Assert
.
assertEquals
(
64
*
1024
+
8
,
positionHolder
.
position
);
Assert
.
assertEquals
(
64
*
1024
+
8
,
positionHolder
.
position
);
}
}
private
AviExtractor
setupVideoAviExtractor
()
{
static
AviExtractor
setupVideoAviExtractor
()
{
final
AviExtractor
aviExtractor
=
new
AviExtractor
();
final
AviExtractor
aviExtractor
=
new
AviExtractor
();
aviExtractor
.
setAviHeader
(
DataHelper
.
createAviHeaderBox
());
aviExtractor
.
setAviHeader
(
DataHelper
.
createAviHeaderBox
());
final
FakeExtractorOutput
fakeExtractorOutput
=
new
FakeExtractorOutput
();
final
FakeExtractorOutput
fakeExtractorOutput
=
new
FakeExtractorOutput
();
...
@@ -444,31 +422,27 @@ public class AviExtractorTest {
...
@@ -444,31 +422,27 @@ public class AviExtractorTest {
final
ExtractorInput
input
=
new
FakeExtractorInput
.
Builder
().
setData
(
byteBuffer
.
array
())
final
ExtractorInput
input
=
new
FakeExtractorInput
.
Builder
().
setData
(
byteBuffer
.
array
())
.
build
();
.
build
();
Assert
.
assertEquals
(
Extractor
.
RESULT_
CONTINUE
,
aviExtractor
.
read
(
input
,
new
PositionHolder
()));
Assert
.
assertEquals
(
Extractor
.
RESULT_
END_OF_INPUT
,
aviExtractor
.
read
(
input
,
new
PositionHolder
()));
final
FakeTrackOutput
fakeTrackOutput
=
(
FakeTrackOutput
)
aviTrack
.
trackOutput
;
final
FakeTrackOutput
fakeTrackOutput
=
(
FakeTrackOutput
)
aviTrack
.
trackOutput
;
Assert
.
assertEquals
(
24
,
fakeTrackOutput
.
getSampleData
(
0
).
length
);
Assert
.
assertEquals
(
24
,
fakeTrackOutput
.
getSampleData
(
0
).
length
);
}
}
@Test
@Test
public
void
readSamples_
fragmentedChunk
()
throws
IOException
{
public
void
readSamples_
givenLeadingZeros
()
throws
IOException
{
AviExtractor
aviExtractor
=
setupVideoAviExtractor
();
AviExtractor
aviExtractor
=
setupVideoAviExtractor
();
final
AviTrack
aviTrack
=
aviExtractor
.
getVideoTrack
();
final
AviTrack
aviTrack
=
aviExtractor
.
getVideoTrack
();
final
int
size
=
24
+
16
;
final
ByteBuffer
byteBuffer
=
AviExtractor
.
allocate
(
48
)
;
final
ByteBuffer
byteBuffer
=
AviExtractor
.
allocate
(
32
);
byteBuffer
.
position
(
16
);
byteBuffer
.
putInt
(
aviTrack
.
chunkId
);
byteBuffer
.
putInt
(
aviTrack
.
chunkId
);
byteBuffer
.
putInt
(
size
);
byteBuffer
.
putInt
(
24
);
final
ExtractorInput
chunk0
=
new
FakeExtractorInput
.
Builder
().
setData
(
byteBuffer
.
array
())
.
build
();
Assert
.
assertEquals
(
Extractor
.
RESULT_CONTINUE
,
aviExtractor
.
read
(
chunk0
,
new
PositionHolder
()));
final
ExtractorInput
chunk1
=
new
FakeExtractorInput
.
Builder
().
setData
(
new
byte
[
16
]
)
final
ExtractorInput
input
=
new
FakeExtractorInput
.
Builder
().
setData
(
byteBuffer
.
array
()
)
.
build
();
.
build
();
Assert
.
assertEquals
(
Extractor
.
RESULT_
CONTINUE
,
aviExtractor
.
read
(
chunk1
,
new
PositionHolder
()));
Assert
.
assertEquals
(
Extractor
.
RESULT_
END_OF_INPUT
,
aviExtractor
.
read
(
input
,
new
PositionHolder
()));
final
FakeTrackOutput
fakeTrackOutput
=
(
FakeTrackOutput
)
aviTrack
.
trackOutput
;
final
FakeTrackOutput
fakeTrackOutput
=
(
FakeTrackOutput
)
aviTrack
.
trackOutput
;
Assert
.
assertEquals
(
size
,
fakeTrackOutput
.
getSampleData
(
0
).
length
);
Assert
.
assertEquals
(
24
,
fakeTrackOutput
.
getSampleData
(
0
).
length
);
}
}
@Test
@Test
...
...
library/extractor/src/test/java/com/google/android/exoplayer2/extractor/avi/AviSeekMapTest.java
View file @
2d727dea
...
@@ -15,6 +15,7 @@
...
@@ -15,6 +15,7 @@
*/
*/
package
com
.
google
.
android
.
exoplayer2
.
extractor
.
avi
;
package
com
.
google
.
android
.
exoplayer2
.
extractor
.
avi
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.extractor.SeekMap
;
import
com.google.android.exoplayer2.extractor.SeekMap
;
import
org.junit.Assert
;
import
org.junit.Assert
;
import
org.junit.Test
;
import
org.junit.Test
;
...
@@ -29,7 +30,7 @@ public class AviSeekMapTest {
...
@@ -29,7 +30,7 @@ public class AviSeekMapTest {
final
AviTrack
[]
aviTracks
=
new
AviTrack
[]{
DataHelper
.
getVideoAviTrack
(
secs
),
final
AviTrack
[]
aviTracks
=
new
AviTrack
[]{
DataHelper
.
getVideoAviTrack
(
secs
),
DataHelper
.
getAudioAviTrack
(
secs
)};
DataHelper
.
getAudioAviTrack
(
secs
)};
aviSeekMap
.
setFrames
(
position
,
1_000_000L
,
aviTracks
);
aviSeekMap
.
setFrames
(
position
,
C
.
MICROS_PER_SECOND
,
aviTracks
);
for
(
int
i
=
0
;
i
<
aviTracks
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
aviTracks
.
length
;
i
++)
{
Assert
.
assertEquals
(
aviSeekMap
.
seekIndexes
[
i
][
1
],
aviTracks
[
i
].
getClock
().
getIndex
());
Assert
.
assertEquals
(
aviSeekMap
.
seekIndexes
[
i
][
1
],
aviTracks
[
i
].
getClock
().
getIndex
());
}
}
...
@@ -41,7 +42,7 @@ public class AviSeekMapTest {
...
@@ -41,7 +42,7 @@ public class AviSeekMapTest {
final
AviTrack
[]
aviTracks
=
new
AviTrack
[
2
];
final
AviTrack
[]
aviTracks
=
new
AviTrack
[
2
];
try
{
try
{
aviSeekMap
.
setFrames
(
1L
,
1_000_000L
,
aviTracks
);
aviSeekMap
.
setFrames
(
1L
,
C
.
MICROS_PER_SECOND
,
aviTracks
);
Assert
.
fail
();
Assert
.
fail
();
}
catch
(
IllegalArgumentException
e
)
{
}
catch
(
IllegalArgumentException
e
)
{
//Intentionally blank
//Intentionally blank
...
...
library/extractor/src/test/java/com/google/android/exoplayer2/extractor/avi/StreamHeaderBoxTest.java
View file @
2d727dea
...
@@ -38,5 +38,6 @@ public class StreamHeaderBoxTest {
...
@@ -38,5 +38,6 @@ public class StreamHeaderBoxTest {
Assert
.
assertEquals
(
FPS24
,
streamHeaderBox
.
getFrameRate
(),
0.1
);
Assert
.
assertEquals
(
FPS24
,
streamHeaderBox
.
getFrameRate
(),
0.1
);
Assert
.
assertEquals
(
9
*
DataHelper
.
FPS
,
streamHeaderBox
.
getLength
());
Assert
.
assertEquals
(
9
*
DataHelper
.
FPS
,
streamHeaderBox
.
getLength
());
Assert
.
assertEquals
(
128
*
1024
,
streamHeaderBox
.
getSuggestedBufferSize
());
Assert
.
assertEquals
(
128
*
1024
,
streamHeaderBox
.
getSuggestedBufferSize
());
Assert
.
assertTrue
(
streamHeaderBox
.
toString
().
startsWith
(
"scale="
+
streamHeaderBox
.
getScale
()));
}
}
}
}
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