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
b1e42830
authored
Nov 17, 2015
by
Oliver Woodman
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Some cleanup to TS H264/H265 readers.
parent
d96fe37c
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
89 additions
and
89 deletions
library/src/main/java/com/google/android/exoplayer/extractor/ts/H264Reader.java
library/src/main/java/com/google/android/exoplayer/extractor/ts/H265Reader.java
library/src/main/java/com/google/android/exoplayer/extractor/ts/H264Reader.java
View file @
b1e42830
...
...
@@ -102,56 +102,60 @@ import java.util.List;
output
.
sampleData
(
data
,
data
.
bytesLeft
());
// Scan the appended data, processing NAL units as they are encountered
while
(
offset
<
limit
)
{
int
nextNalUnitOffset
=
NalUnitUtil
.
findNalUnit
(
dataArray
,
offset
,
limit
,
prefixFlags
);
if
(
nextNalUnitOffset
<
limit
)
{
// We've seen the start of a NAL unit.
// This is the length to the start of the unit. It may be negative if the NAL unit
// actually started in previously consumed data.
int
lengthToNalUnit
=
nextNalUnitOffset
-
offset
;
if
(
lengthToNalUnit
>
0
)
{
feedNalUnitTargetBuffersData
(
dataArray
,
offset
,
nextNalUnitOffset
);
}
int
nalUnitType
=
NalUnitUtil
.
getNalUnitType
(
dataArray
,
nextNalUnitOffset
);
int
bytesWrittenPastNalUnit
=
limit
-
nextNalUnitOffset
;
switch
(
nalUnitType
)
{
case
NAL_UNIT_TYPE_IDR:
isKeyframe
=
true
;
break
;
case
NAL_UNIT_TYPE_AUD:
if
(
foundFirstSample
)
{
if
(
ifrParserBuffer
!=
null
&&
ifrParserBuffer
.
isCompleted
())
{
int
sliceType
=
ifrParserBuffer
.
getSliceType
();
isKeyframe
|=
(
sliceType
==
FRAME_TYPE_I
||
sliceType
==
FRAME_TYPE_ALL_I
);
ifrParserBuffer
.
reset
();
}
if
(
isKeyframe
&&
!
hasOutputFormat
&&
sps
.
isCompleted
()
&&
pps
.
isCompleted
())
{
parseMediaFormat
(
sps
,
pps
);
}
int
flags
=
isKeyframe
?
C
.
SAMPLE_FLAG_SYNC
:
0
;
int
size
=
(
int
)
(
totalBytesWritten
-
samplePosition
)
-
bytesWrittenPastNalUnit
;
output
.
sampleMetadata
(
sampleTimeUs
,
flags
,
size
,
bytesWrittenPastNalUnit
,
null
);
}
foundFirstSample
=
true
;
samplePosition
=
totalBytesWritten
-
bytesWrittenPastNalUnit
;
sampleTimeUs
=
pesTimeUs
;
isKeyframe
=
false
;
break
;
}
// If the length to the start of the unit is negative then we wrote too many bytes to the
// NAL buffers. Discard the excess bytes when notifying that the unit has ended.
feedNalUnitTargetEnd
(
pesTimeUs
,
lengthToNalUnit
<
0
?
-
lengthToNalUnit
:
0
);
// Notify the start of the next NAL unit.
feedNalUnitTargetBuffersStart
(
nalUnitType
);
// Continue scanning the data.
offset
=
nextNalUnitOffset
+
3
;
}
else
{
while
(
true
)
{
int
nalUnitOffset
=
NalUnitUtil
.
findNalUnit
(
dataArray
,
offset
,
limit
,
prefixFlags
);
if
(
nalUnitOffset
==
limit
)
{
// We've scanned to the end of the data without finding the start of another NAL unit.
feedNalUnitTargetBuffersData
(
dataArray
,
offset
,
limit
);
offset
=
limit
;
return
;
}
// We've seen the start of a NAL unit of the following type.
int
nalUnitType
=
NalUnitUtil
.
getNalUnitType
(
dataArray
,
nalUnitOffset
);
// This is the number of bytes from the current offset to the start of the next NAL unit.
// It may be negative if the NAL unit started in the previously consumed data.
int
lengthToNalUnit
=
nalUnitOffset
-
offset
;
if
(
lengthToNalUnit
>
0
)
{
feedNalUnitTargetBuffersData
(
dataArray
,
offset
,
nalUnitOffset
);
}
switch
(
nalUnitType
)
{
case
NAL_UNIT_TYPE_IDR:
isKeyframe
=
true
;
break
;
case
NAL_UNIT_TYPE_AUD:
int
bytesWrittenPastNalUnit
=
limit
-
nalUnitOffset
;
if
(
foundFirstSample
)
{
if
(
ifrParserBuffer
!=
null
&&
ifrParserBuffer
.
isCompleted
())
{
int
sliceType
=
ifrParserBuffer
.
getSliceType
();
isKeyframe
|=
(
sliceType
==
FRAME_TYPE_I
||
sliceType
==
FRAME_TYPE_ALL_I
);
ifrParserBuffer
.
reset
();
}
if
(
isKeyframe
&&
!
hasOutputFormat
&&
sps
.
isCompleted
()
&&
pps
.
isCompleted
())
{
output
.
format
(
parseMediaFormat
(
sps
,
pps
));
hasOutputFormat
=
true
;
}
int
flags
=
isKeyframe
?
C
.
SAMPLE_FLAG_SYNC
:
0
;
int
size
=
(
int
)
(
totalBytesWritten
-
samplePosition
)
-
bytesWrittenPastNalUnit
;
output
.
sampleMetadata
(
sampleTimeUs
,
flags
,
size
,
bytesWrittenPastNalUnit
,
null
);
}
foundFirstSample
=
true
;
samplePosition
=
totalBytesWritten
-
bytesWrittenPastNalUnit
;
sampleTimeUs
=
pesTimeUs
;
isKeyframe
=
false
;
break
;
}
// Indicate the end of the previous NAL unit. If the length to the start of the next unit
// is negative then we wrote too many bytes to the NAL buffers. Discard the excess bytes
// when notifying that the unit has ended.
feedNalUnitTargetEnd
(
pesTimeUs
,
lengthToNalUnit
<
0
?
-
lengthToNalUnit
:
0
);
// Indicate the start of the next NAL unit.
feedNalUnitTargetBuffersStart
(
nalUnitType
);
// Continue scanning the data.
offset
=
nalUnitOffset
+
3
;
}
}
}
...
...
@@ -194,14 +198,10 @@ import java.util.List;
}
}
private
void
parseMediaFormat
(
NalUnitTargetBuffer
sps
,
NalUnitTargetBuffer
pps
)
{
byte
[]
spsData
=
new
byte
[
sps
.
nalLength
];
byte
[]
ppsData
=
new
byte
[
pps
.
nalLength
];
System
.
arraycopy
(
sps
.
nalData
,
0
,
spsData
,
0
,
sps
.
nalLength
);
System
.
arraycopy
(
pps
.
nalData
,
0
,
ppsData
,
0
,
pps
.
nalLength
);
private
static
MediaFormat
parseMediaFormat
(
NalUnitTargetBuffer
sps
,
NalUnitTargetBuffer
pps
)
{
List
<
byte
[]>
initializationData
=
new
ArrayList
<>();
initializationData
.
add
(
spsData
);
initializationData
.
add
(
ppsData
);
initializationData
.
add
(
Arrays
.
copyOf
(
sps
.
nalData
,
sps
.
nalLength
)
);
initializationData
.
add
(
Arrays
.
copyOf
(
pps
.
nalData
,
pps
.
nalLength
)
);
// Unescape and parse the SPS unit.
NalUnitUtil
.
unescapeStream
(
sps
.
nalData
,
sps
.
nalLength
);
...
...
@@ -209,11 +209,9 @@ import java.util.List;
bitArray
.
skipBits
(
32
);
// NAL header
SpsData
parsedSpsData
=
CodecSpecificDataUtil
.
parseSpsNalUnit
(
bitArray
);
// Construct and output the format.
output
.
format
(
MediaFormat
.
createVideoFormat
(
null
,
MimeTypes
.
VIDEO_H264
,
MediaFormat
.
NO_VALUE
,
return
MediaFormat
.
createVideoFormat
(
null
,
MimeTypes
.
VIDEO_H264
,
MediaFormat
.
NO_VALUE
,
MediaFormat
.
NO_VALUE
,
C
.
UNKNOWN_TIME_US
,
parsedSpsData
.
width
,
parsedSpsData
.
height
,
initializationData
,
MediaFormat
.
NO_VALUE
,
parsedSpsData
.
pixelWidthAspectRatio
));
hasOutputFormat
=
true
;
initializationData
,
MediaFormat
.
NO_VALUE
,
parsedSpsData
.
pixelWidthAspectRatio
);
}
/**
...
...
library/src/main/java/com/google/android/exoplayer/extractor/ts/H265Reader.java
View file @
b1e42830
...
...
@@ -101,32 +101,34 @@ import java.util.Collections;
// Scan the appended data, processing NAL units as they are encountered
while
(
offset
<
limit
)
{
int
nalUnitOffset
=
NalUnitUtil
.
findNalUnit
(
dataArray
,
offset
,
limit
,
prefixFlags
);
if
(
nalUnitOffset
<
limit
)
{
// We've seen the start of a NAL unit.
// This is the length to the start of the unit. It may be negative if the NAL unit
// actually started in previously consumed data.
int
lengthToNalUnit
=
nalUnitOffset
-
offset
;
if
(
lengthToNalUnit
>
0
)
{
nalUnitData
(
dataArray
,
offset
,
nalUnitOffset
);
}
int
bytesWrittenPastPosition
=
limit
-
nalUnitOffset
;
long
absolutePosition
=
totalBytesWritten
-
bytesWrittenPastPosition
;
// Indicate the end of the previous NAL unit. If the length to the start of the next unit
// is negative then we wrote too many bytes to the NAL buffers. Discard the excess bytes
// when notifying that the unit has ended.
nalUnitEnd
(
absolutePosition
,
bytesWrittenPastPosition
,
lengthToNalUnit
<
0
?
-
lengthToNalUnit
:
0
,
pesTimeUs
);
// Indicate the start of the next NAL unit.
int
nalUnitType
=
NalUnitUtil
.
getH265NalUnitType
(
dataArray
,
nalUnitOffset
);
startNalUnit
(
absolutePosition
,
bytesWrittenPastPosition
,
nalUnitType
,
pesTimeUs
);
// Continue scanning the data.
offset
=
nalUnitOffset
+
3
;
}
else
{
if
(
nalUnitOffset
==
limit
)
{
// We've scanned to the end of the data without finding the start of another NAL unit.
nalUnitData
(
dataArray
,
offset
,
limit
);
offset
=
limit
;
return
;
}
// We've seen the start of a NAL unit of the following type.
int
nalUnitType
=
NalUnitUtil
.
getH265NalUnitType
(
dataArray
,
nalUnitOffset
);
// This is the number of bytes from the current offset to the start of the next NAL unit.
// It may be negative if the NAL unit started in the previously consumed data.
int
lengthToNalUnit
=
nalUnitOffset
-
offset
;
if
(
lengthToNalUnit
>
0
)
{
nalUnitData
(
dataArray
,
offset
,
nalUnitOffset
);
}
int
bytesWrittenPastPosition
=
limit
-
nalUnitOffset
;
long
absolutePosition
=
totalBytesWritten
-
bytesWrittenPastPosition
;
// Indicate the end of the previous NAL unit. If the length to the start of the next unit
// is negative then we wrote too many bytes to the NAL buffers. Discard the excess bytes
// when notifying that the unit has ended.
nalUnitEnd
(
absolutePosition
,
bytesWrittenPastPosition
,
lengthToNalUnit
<
0
?
-
lengthToNalUnit
:
0
,
pesTimeUs
);
// Indicate the start of the next NAL unit.
startNalUnit
(
absolutePosition
,
bytesWrittenPastPosition
,
nalUnitType
,
pesTimeUs
);
// Continue scanning the data.
offset
=
nalUnitOffset
+
3
;
}
}
}
...
...
@@ -167,7 +169,8 @@ import java.util.Collections;
sps
.
endNalUnit
(
discardPadding
);
pps
.
endNalUnit
(
discardPadding
);
if
(
vps
.
isCompleted
()
&&
sps
.
isCompleted
()
&&
pps
.
isCompleted
())
{
parseMediaFormat
(
vps
,
sps
,
pps
);
output
.
format
(
parseMediaFormat
(
vps
,
sps
,
pps
));
hasOutputFormat
=
true
;
}
}
if
(
prefixSei
.
endNalUnit
(
discardPadding
))
{
...
...
@@ -188,7 +191,7 @@ import java.util.Collections;
}
}
private
void
parseMediaFormat
(
NalUnitTargetBuffer
vps
,
NalUnitTargetBuffer
sps
,
private
static
MediaFormat
parseMediaFormat
(
NalUnitTargetBuffer
vps
,
NalUnitTargetBuffer
sps
,
NalUnitTargetBuffer
pps
)
{
// Build codec-specific data.
byte
[]
csd
=
new
byte
[
vps
.
nalLength
+
sps
.
nalLength
+
pps
.
nalLength
];
...
...
@@ -294,14 +297,13 @@ import java.util.Collections;
}
}
output
.
format
(
MediaFormat
.
createVideoFormat
(
null
,
MimeTypes
.
VIDEO_H265
,
MediaFormat
.
NO_VALUE
,
return
MediaFormat
.
createVideoFormat
(
null
,
MimeTypes
.
VIDEO_H265
,
MediaFormat
.
NO_VALUE
,
MediaFormat
.
NO_VALUE
,
C
.
UNKNOWN_TIME_US
,
picWidthInLumaSamples
,
picHeightInLumaSamples
,
Collections
.
singletonList
(
csd
),
MediaFormat
.
NO_VALUE
,
pixelWidthHeightRatio
));
hasOutputFormat
=
true
;
Collections
.
singletonList
(
csd
),
MediaFormat
.
NO_VALUE
,
pixelWidthHeightRatio
);
}
/** Skips scaling_list_data(). See H.265/HEVC (2014) 7.3.4. */
private
void
skipScalingList
(
ParsableBitArray
bitArray
)
{
private
static
void
skipScalingList
(
ParsableBitArray
bitArray
)
{
for
(
int
sizeId
=
0
;
sizeId
<
4
;
sizeId
++)
{
for
(
int
matrixId
=
0
;
matrixId
<
6
;
matrixId
+=
sizeId
==
3
?
3
:
1
)
{
if
(!
bitArray
.
readBit
())
{
// scaling_list_pred_mode_flag[sizeId][matrixId]
...
...
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