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
96c1e670
authored
Jun 05, 2015
by
Oliver Woodman
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
De-duplicate code for H264/H265 in MPEG-TS.
parent
10efe790
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
145 additions
and
235 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/NalUnitTargetBuffer.java
library/src/main/java/com/google/android/exoplayer/util/NalUnitUtil.java
library/src/main/java/com/google/android/exoplayer/extractor/ts/H264Reader.java
View file @
96c1e670
...
@@ -18,7 +18,6 @@ package com.google.android.exoplayer.extractor.ts;
...
@@ -18,7 +18,6 @@ package com.google.android.exoplayer.extractor.ts;
import
com.google.android.exoplayer.C
;
import
com.google.android.exoplayer.C
;
import
com.google.android.exoplayer.MediaFormat
;
import
com.google.android.exoplayer.MediaFormat
;
import
com.google.android.exoplayer.extractor.TrackOutput
;
import
com.google.android.exoplayer.extractor.TrackOutput
;
import
com.google.android.exoplayer.util.Assertions
;
import
com.google.android.exoplayer.util.MimeTypes
;
import
com.google.android.exoplayer.util.MimeTypes
;
import
com.google.android.exoplayer.util.NalUnitUtil
;
import
com.google.android.exoplayer.util.NalUnitUtil
;
import
com.google.android.exoplayer.util.ParsableBitArray
;
import
com.google.android.exoplayer.util.ParsableBitArray
;
...
@@ -46,26 +45,6 @@ import java.util.List;
...
@@ -46,26 +45,6 @@ import java.util.List;
private
static
final
int
NAL_UNIT_TYPE_SPS
=
7
;
// Sequence parameter set
private
static
final
int
NAL_UNIT_TYPE_SPS
=
7
;
// Sequence parameter set
private
static
final
int
NAL_UNIT_TYPE_PPS
=
8
;
// Picture parameter set
private
static
final
int
NAL_UNIT_TYPE_PPS
=
8
;
// Picture parameter set
private
static
final
int
NAL_UNIT_TYPE_AUD
=
9
;
// Access unit delimiter
private
static
final
int
NAL_UNIT_TYPE_AUD
=
9
;
// Access unit delimiter
private
static
final
int
EXTENDED_SAR
=
0xFF
;
private
static
final
float
[]
ASPECT_RATIO_IDC_VALUES
=
new
float
[]
{
1
f
/* Unspecified. Assume square */
,
1
f
,
12
f
/
11
f
,
10
f
/
11
f
,
16
f
/
11
f
,
40
f
/
33
f
,
24
f
/
11
f
,
20
f
/
11
f
,
32
f
/
11
f
,
80
f
/
33
f
,
18
f
/
11
f
,
15
f
/
11
f
,
64
f
/
33
f
,
160
f
/
99
f
,
4
f
/
3
f
,
3
f
/
2
f
,
2
f
};
// State that should not be reset on seek.
// State that should not be reset on seek.
private
boolean
hasOutputFormat
;
private
boolean
hasOutputFormat
;
...
@@ -172,7 +151,7 @@ import java.util.List;
...
@@ -172,7 +151,7 @@ import java.util.List;
// Notify the start of the next NAL unit.
// Notify the start of the next NAL unit.
feedNalUnitTargetBuffersStart
(
nalUnitType
);
feedNalUnitTargetBuffersStart
(
nalUnitType
);
// Continue scanning the data.
// Continue scanning the data.
offset
=
nextNalUnitOffset
+
4
;
offset
=
nextNalUnitOffset
+
3
;
}
else
{
}
else
{
feedNalUnitTargetBuffersData
(
dataArray
,
offset
,
limit
);
feedNalUnitTargetBuffersData
(
dataArray
,
offset
,
limit
);
offset
=
limit
;
offset
=
limit
;
...
@@ -312,14 +291,14 @@ import java.util.List;
...
@@ -312,14 +291,14 @@ import java.util.List;
boolean
aspectRatioInfoPresentFlag
=
bitArray
.
readBit
();
boolean
aspectRatioInfoPresentFlag
=
bitArray
.
readBit
();
if
(
aspectRatioInfoPresentFlag
)
{
if
(
aspectRatioInfoPresentFlag
)
{
int
aspectRatioIdc
=
bitArray
.
readBits
(
8
);
int
aspectRatioIdc
=
bitArray
.
readBits
(
8
);
if
(
aspectRatioIdc
==
EXTENDED_SAR
)
{
if
(
aspectRatioIdc
==
NalUnitUtil
.
EXTENDED_SAR
)
{
int
sarWidth
=
bitArray
.
readBits
(
16
);
int
sarWidth
=
bitArray
.
readBits
(
16
);
int
sarHeight
=
bitArray
.
readBits
(
16
);
int
sarHeight
=
bitArray
.
readBits
(
16
);
if
(
sarWidth
!=
0
&&
sarHeight
!=
0
)
{
if
(
sarWidth
!=
0
&&
sarHeight
!=
0
)
{
pixelWidthHeightRatio
=
(
float
)
sarWidth
/
sarHeight
;
pixelWidthHeightRatio
=
(
float
)
sarWidth
/
sarHeight
;
}
}
}
else
if
(
aspectRatioIdc
<
ASPECT_RATIO_IDC_VALUES
.
length
)
{
}
else
if
(
aspectRatioIdc
<
NalUnitUtil
.
ASPECT_RATIO_IDC_VALUES
.
length
)
{
pixelWidthHeightRatio
=
ASPECT_RATIO_IDC_VALUES
[
aspectRatioIdc
];
pixelWidthHeightRatio
=
NalUnitUtil
.
ASPECT_RATIO_IDC_VALUES
[
aspectRatioIdc
];
}
else
{
}
else
{
Log
.
w
(
TAG
,
"Unexpected aspect_ratio_idc value: "
+
aspectRatioIdc
);
Log
.
w
(
TAG
,
"Unexpected aspect_ratio_idc value: "
+
aspectRatioIdc
);
}
}
...
@@ -395,96 +374,6 @@ import java.util.List;
...
@@ -395,96 +374,6 @@ import java.util.List;
}
}
/**
/**
* A buffer that fills itself with data corresponding to a specific NAL unit, as it is
* encountered in the stream.
*/
private
static
final
class
NalUnitTargetBuffer
{
private
final
int
targetType
;
private
boolean
isFilling
;
private
boolean
isCompleted
;
public
byte
[]
nalData
;
public
int
nalLength
;
public
NalUnitTargetBuffer
(
int
targetType
,
int
initialCapacity
)
{
this
.
targetType
=
targetType
;
// Initialize data, writing the known NAL prefix into the first four bytes.
nalData
=
new
byte
[
4
+
initialCapacity
];
nalData
[
2
]
=
1
;
nalData
[
3
]
=
(
byte
)
targetType
;
}
/**
* Resets the buffer, clearing any data that it holds.
*/
public
void
reset
()
{
isFilling
=
false
;
isCompleted
=
false
;
}
/**
* True if the buffer currently holds a complete NAL unit of the target type.
*/
public
boolean
isCompleted
()
{
return
isCompleted
;
}
/**
* Invoked to indicate that a NAL unit has started.
*
* @param type The type of the NAL unit.
*/
public
void
startNalUnit
(
int
type
)
{
Assertions
.
checkState
(!
isFilling
);
isFilling
=
type
==
targetType
;
if
(
isFilling
)
{
// Length is initially the length of the NAL prefix.
nalLength
=
4
;
isCompleted
=
false
;
}
}
/**
* Invoked to pass stream data. The data passed should not include 4 byte NAL unit prefixes.
*
* @param data Holds the data being passed.
* @param offset The offset of the data in {@code data}.
* @param limit The limit (exclusive) of the data in {@code data}.
*/
public
void
appendToNalUnit
(
byte
[]
data
,
int
offset
,
int
limit
)
{
if
(!
isFilling
)
{
return
;
}
int
readLength
=
limit
-
offset
;
if
(
nalData
.
length
<
nalLength
+
readLength
)
{
nalData
=
Arrays
.
copyOf
(
nalData
,
(
nalLength
+
readLength
)
*
2
);
}
System
.
arraycopy
(
data
,
offset
,
nalData
,
nalLength
,
readLength
);
nalLength
+=
readLength
;
}
/**
* Invoked to indicate that a NAL unit has ended.
*
* @param discardPadding The number of excess bytes that were passed to
* {@link #appendToNalUnit(byte[], int, int)}, which should be discarded.
* @return True if the ended NAL unit is of the target type. False otherwise.
*/
public
boolean
endNalUnit
(
int
discardPadding
)
{
if
(!
isFilling
)
{
return
false
;
}
nalLength
-=
discardPadding
;
isFilling
=
false
;
isCompleted
=
true
;
return
true
;
}
}
/**
* A buffer specifically for IFR units that can be used to parse the IFR's slice type.
* A buffer specifically for IFR units that can be used to parse the IFR's slice type.
*/
*/
private
static
final
class
IfrParserBuffer
{
private
static
final
class
IfrParserBuffer
{
...
...
library/src/main/java/com/google/android/exoplayer/extractor/ts/H265Reader.java
View file @
96c1e670
...
@@ -18,7 +18,6 @@ package com.google.android.exoplayer.extractor.ts;
...
@@ -18,7 +18,6 @@ package com.google.android.exoplayer.extractor.ts;
import
com.google.android.exoplayer.C
;
import
com.google.android.exoplayer.C
;
import
com.google.android.exoplayer.MediaFormat
;
import
com.google.android.exoplayer.MediaFormat
;
import
com.google.android.exoplayer.extractor.TrackOutput
;
import
com.google.android.exoplayer.extractor.TrackOutput
;
import
com.google.android.exoplayer.util.Assertions
;
import
com.google.android.exoplayer.util.MimeTypes
;
import
com.google.android.exoplayer.util.MimeTypes
;
import
com.google.android.exoplayer.util.NalUnitUtil
;
import
com.google.android.exoplayer.util.NalUnitUtil
;
import
com.google.android.exoplayer.util.ParsableBitArray
;
import
com.google.android.exoplayer.util.ParsableBitArray
;
...
@@ -51,28 +50,6 @@ import java.util.Collections;
...
@@ -51,28 +50,6 @@ import java.util.Collections;
private
static
final
int
PREFIX_SEI_NUT
=
39
;
private
static
final
int
PREFIX_SEI_NUT
=
39
;
private
static
final
int
SUFFIX_SEI_NUT
=
40
;
private
static
final
int
SUFFIX_SEI_NUT
=
40
;
// TODO: Deduplicate with H264Reader.
private
static
final
int
EXTENDED_SAR
=
0xFF
;
private
static
final
float
[]
ASPECT_RATIO_IDC_VALUES
=
new
float
[]
{
1
f
/* Unspecified. Assume square */
,
1
f
,
12
f
/
11
f
,
10
f
/
11
f
,
16
f
/
11
f
,
40
f
/
33
f
,
24
f
/
11
f
,
20
f
/
11
f
,
32
f
/
11
f
,
80
f
/
33
f
,
18
f
/
11
f
,
15
f
/
11
f
,
64
f
/
33
f
,
160
f
/
99
f
,
4
f
/
3
f
,
3
f
/
2
f
,
2
f
};
// State that should not be reset on seek.
// State that should not be reset on seek.
private
boolean
hasOutputFormat
;
private
boolean
hasOutputFormat
;
...
@@ -321,14 +298,14 @@ import java.util.Collections;
...
@@ -321,14 +298,14 @@ import java.util.Collections;
if
(
bitArray
.
readBit
())
{
// vui_parameters_present_flag
if
(
bitArray
.
readBit
())
{
// vui_parameters_present_flag
if
(
bitArray
.
readBit
())
{
// aspect_ratio_info_present_flag
if
(
bitArray
.
readBit
())
{
// aspect_ratio_info_present_flag
int
aspectRatioIdc
=
bitArray
.
readBits
(
8
);
int
aspectRatioIdc
=
bitArray
.
readBits
(
8
);
if
(
aspectRatioIdc
==
EXTENDED_SAR
)
{
if
(
aspectRatioIdc
==
NalUnitUtil
.
EXTENDED_SAR
)
{
int
sarWidth
=
bitArray
.
readBits
(
16
);
int
sarWidth
=
bitArray
.
readBits
(
16
);
int
sarHeight
=
bitArray
.
readBits
(
16
);
int
sarHeight
=
bitArray
.
readBits
(
16
);
if
(
sarWidth
!=
0
&&
sarHeight
!=
0
)
{
if
(
sarWidth
!=
0
&&
sarHeight
!=
0
)
{
pixelWidthHeightRatio
=
(
float
)
sarWidth
/
sarHeight
;
pixelWidthHeightRatio
=
(
float
)
sarWidth
/
sarHeight
;
}
}
}
else
if
(
aspectRatioIdc
<
ASPECT_RATIO_IDC_VALUES
.
length
)
{
}
else
if
(
aspectRatioIdc
<
NalUnitUtil
.
ASPECT_RATIO_IDC_VALUES
.
length
)
{
pixelWidthHeightRatio
=
ASPECT_RATIO_IDC_VALUES
[
aspectRatioIdc
];
pixelWidthHeightRatio
=
NalUnitUtil
.
ASPECT_RATIO_IDC_VALUES
[
aspectRatioIdc
];
}
else
{
}
else
{
Log
.
w
(
TAG
,
"Unexpected aspect_ratio_idc value: "
+
aspectRatioIdc
);
Log
.
w
(
TAG
,
"Unexpected aspect_ratio_idc value: "
+
aspectRatioIdc
);
}
}
...
@@ -464,92 +441,4 @@ import java.util.Collections;
...
@@ -464,92 +441,4 @@ import java.util.Collections;
}
}
}
}
// TODO: Deduplicate with H264Reader.NalUnitTargetBuffer.
/**
* A buffer that fills itself with data corresponding to a specific NAL unit, as it is
* encountered in the stream.
*/
private
static
final
class
NalUnitTargetBuffer
{
private
final
int
targetType
;
private
boolean
isFilling
;
private
boolean
isCompleted
;
public
byte
[]
nalData
;
public
int
nalLength
;
public
NalUnitTargetBuffer
(
int
targetType
,
int
initialCapacity
)
{
this
.
targetType
=
targetType
;
nalData
=
new
byte
[
5
+
initialCapacity
];
nalData
[
2
]
=
1
;
}
/**
* Resets the buffer, clearing any data that it holds.
*/
public
void
reset
()
{
isFilling
=
false
;
isCompleted
=
false
;
}
/**
* True if the buffer currently holds a complete NAL unit of the target type.
*/
public
boolean
isCompleted
()
{
return
isCompleted
;
}
/**
* Invoked to indicate that a NAL unit has started.
*
* @param type The type of the NAL unit.
*/
public
void
startNalUnit
(
int
type
)
{
Assertions
.
checkState
(!
isFilling
);
isFilling
=
type
==
targetType
;
if
(
isFilling
)
{
nalLength
=
3
;
isCompleted
=
false
;
}
}
/**
* Invoked to pass stream data. The data passed should not include 4 byte NAL unit prefixes.
*
* @param data Holds the data being passed.
* @param offset The offset of the data in {@code data}.
* @param limit The limit (exclusive) of the data in {@code data}.
*/
public
void
appendToNalUnit
(
byte
[]
data
,
int
offset
,
int
limit
)
{
if
(!
isFilling
)
{
return
;
}
int
readLength
=
limit
-
offset
;
if
(
nalData
.
length
<
nalLength
+
readLength
)
{
nalData
=
Arrays
.
copyOf
(
nalData
,
(
nalLength
+
readLength
)
*
2
);
}
System
.
arraycopy
(
data
,
offset
,
nalData
,
nalLength
,
readLength
);
nalLength
+=
readLength
;
}
/**
* Invoked to indicate that a NAL unit has ended.
*
* @param discardPadding The number of excess bytes that were passed to
* {@link #appendToNalUnit(byte[], int, int)}, which should be discarded.
* @return True if the ended NAL unit is of the target type. False otherwise.
*/
public
boolean
endNalUnit
(
int
discardPadding
)
{
if
(!
isFilling
)
{
return
false
;
}
nalLength
-=
discardPadding
;
isFilling
=
false
;
isCompleted
=
true
;
return
true
;
}
}
}
}
library/src/main/java/com/google/android/exoplayer/extractor/ts/NalUnitTargetBuffer.java
0 → 100644
View file @
96c1e670
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
google
.
android
.
exoplayer
.
extractor
.
ts
;
import
com.google.android.exoplayer.util.Assertions
;
import
java.util.Arrays
;
/**
* A buffer that fills itself with data corresponding to a specific NAL unit, as it is
* encountered in the stream.
*/
/* package */
final
class
NalUnitTargetBuffer
{
private
final
int
targetType
;
private
boolean
isFilling
;
private
boolean
isCompleted
;
public
byte
[]
nalData
;
public
int
nalLength
;
public
NalUnitTargetBuffer
(
int
targetType
,
int
initialCapacity
)
{
this
.
targetType
=
targetType
;
// Initialize data with a start code in the first three bytes.
nalData
=
new
byte
[
3
+
initialCapacity
];
nalData
[
2
]
=
1
;
}
/**
* Resets the buffer, clearing any data that it holds.
*/
public
void
reset
()
{
isFilling
=
false
;
isCompleted
=
false
;
}
/**
* Returns whether the buffer currently holds a complete NAL unit of the target type.
*/
public
boolean
isCompleted
()
{
return
isCompleted
;
}
/**
* Invoked to indicate that a NAL unit has started.
*
* @param type The type of the NAL unit.
*/
public
void
startNalUnit
(
int
type
)
{
Assertions
.
checkState
(!
isFilling
);
isFilling
=
type
==
targetType
;
if
(
isFilling
)
{
// Skip the three byte start code when writing data.
nalLength
=
3
;
isCompleted
=
false
;
}
}
/**
* Invoked to pass stream data. The data passed should not include the 3 byte start code.
*
* @param data Holds the data being passed.
* @param offset The offset of the data in {@code data}.
* @param limit The limit (exclusive) of the data in {@code data}.
*/
public
void
appendToNalUnit
(
byte
[]
data
,
int
offset
,
int
limit
)
{
if
(!
isFilling
)
{
return
;
}
int
readLength
=
limit
-
offset
;
if
(
nalData
.
length
<
nalLength
+
readLength
)
{
nalData
=
Arrays
.
copyOf
(
nalData
,
(
nalLength
+
readLength
)
*
2
);
}
System
.
arraycopy
(
data
,
offset
,
nalData
,
nalLength
,
readLength
);
nalLength
+=
readLength
;
}
/**
* Invoked to indicate that a NAL unit has ended.
*
* @param discardPadding The number of excess bytes that were passed to
* {@link #appendToNalUnit(byte[], int, int)}, which should be discarded.
* @return True if the ended NAL unit is of the target type. False otherwise.
*/
public
boolean
endNalUnit
(
int
discardPadding
)
{
if
(!
isFilling
)
{
return
false
;
}
nalLength
-=
discardPadding
;
isFilling
=
false
;
isCompleted
=
true
;
return
true
;
}
}
library/src/main/java/com/google/android/exoplayer/util/NalUnitUtil.java
View file @
96c1e670
...
@@ -25,6 +25,29 @@ public final class NalUnitUtil {
...
@@ -25,6 +25,29 @@ public final class NalUnitUtil {
/** Four initial bytes that must prefix NAL units for decoding. */
/** Four initial bytes that must prefix NAL units for decoding. */
public
static
final
byte
[]
NAL_START_CODE
=
new
byte
[]
{
0
,
0
,
0
,
1
};
public
static
final
byte
[]
NAL_START_CODE
=
new
byte
[]
{
0
,
0
,
0
,
1
};
/** Value for aspect_ratio_idc indicating an extended aspect ratio, in H.264 and H.265 SPSs. */
public
static
final
int
EXTENDED_SAR
=
0xFF
;
/** Aspect ratios indexed by aspect_ratio_idc, in H.264 and H.265 SPSs. */
public
static
final
float
[]
ASPECT_RATIO_IDC_VALUES
=
new
float
[]
{
1
f
/* Unspecified. Assume square */
,
1
f
,
12
f
/
11
f
,
10
f
/
11
f
,
16
f
/
11
f
,
40
f
/
33
f
,
24
f
/
11
f
,
20
f
/
11
f
,
32
f
/
11
f
,
80
f
/
33
f
,
18
f
/
11
f
,
15
f
/
11
f
,
64
f
/
33
f
,
160
f
/
99
f
,
4
f
/
3
f
,
3
f
/
2
f
,
2
f
};
/**
/**
* Replaces length prefixes of NAL units in {@code buffer} with start code prefixes, within the
* Replaces length prefixes of NAL units in {@code buffer} with start code prefixes, within the
* {@code size} bytes preceding the buffer's position.
* {@code size} bytes preceding the buffer's position.
...
@@ -79,7 +102,7 @@ public final class NalUnitUtil {
...
@@ -79,7 +102,7 @@ public final class NalUnitUtil {
/**
/**
* Finds the first NAL unit in {@code data}.
* Finds the first NAL unit in {@code data}.
* <p>
* <p>
* If {@code prefixFlags} is null then the first
four
bytes of a NAL unit must be entirely
* If {@code prefixFlags} is null then the first
three
bytes of a NAL unit must be entirely
* contained within the part of the array being searched in order for it to be found.
* contained within the part of the array being searched in order for it to be found.
* <p>
* <p>
* When {@code prefixFlags} is non-null, this method supports finding NAL units whose first four
* When {@code prefixFlags} is non-null, this method supports finding NAL units whose first four
...
@@ -121,9 +144,8 @@ public final class NalUnitUtil {
...
@@ -121,9 +144,8 @@ public final class NalUnitUtil {
}
}
int
limit
=
endOffset
-
1
;
int
limit
=
endOffset
-
1
;
// We're looking for the NAL unit start code prefix 0x000001, followed by a byte that matches
// We're looking for the NAL unit start code prefix 0x000001. The value of i tracks the index of
// the specified type. The value of i tracks the index of the third byte in the four bytes
// the third byte.
// being examined.
for
(
int
i
=
startOffset
+
2
;
i
<
limit
;
i
+=
3
)
{
for
(
int
i
=
startOffset
+
2
;
i
<
limit
;
i
+=
3
)
{
if
((
data
[
i
]
&
0xFE
)
!=
0
)
{
if
((
data
[
i
]
&
0xFE
)
!=
0
)
{
// There isn't a NAL prefix here, or at the next two positions. Do nothing and let the
// There isn't a NAL prefix here, or at the next two positions. Do nothing and let the
...
@@ -146,10 +168,10 @@ public final class NalUnitUtil {
...
@@ -146,10 +168,10 @@ public final class NalUnitUtil {
?
(
data
[
endOffset
-
3
]
==
0
&&
data
[
endOffset
-
2
]
==
0
&&
data
[
endOffset
-
1
]
==
1
)
?
(
data
[
endOffset
-
3
]
==
0
&&
data
[
endOffset
-
2
]
==
0
&&
data
[
endOffset
-
1
]
==
1
)
:
length
==
2
?
(
prefixFlags
[
2
]
&&
data
[
endOffset
-
2
]
==
0
&&
data
[
endOffset
-
1
]
==
1
)
:
length
==
2
?
(
prefixFlags
[
2
]
&&
data
[
endOffset
-
2
]
==
0
&&
data
[
endOffset
-
1
]
==
1
)
:
(
prefixFlags
[
1
]
&&
data
[
endOffset
-
1
]
==
1
);
:
(
prefixFlags
[
1
]
&&
data
[
endOffset
-
1
]
==
1
);
// True if the last t
hree
bytes in the data seen so far are {0,0}.
// True if the last t
wo
bytes in the data seen so far are {0,0}.
prefixFlags
[
1
]
=
length
>
1
?
data
[
endOffset
-
2
]
==
0
&&
data
[
endOffset
-
1
]
==
0
prefixFlags
[
1
]
=
length
>
1
?
data
[
endOffset
-
2
]
==
0
&&
data
[
endOffset
-
1
]
==
0
:
prefixFlags
[
2
]
&&
data
[
endOffset
-
1
]
==
0
;
:
prefixFlags
[
2
]
&&
data
[
endOffset
-
1
]
==
0
;
// True if the last
three bytes in the data seen so far are
{0}.
// True if the last
byte in the data seen so far is
{0}.
prefixFlags
[
2
]
=
data
[
endOffset
-
1
]
==
0
;
prefixFlags
[
2
]
=
data
[
endOffset
-
1
]
==
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