mirror of
https://github.com/samsonjs/media.git
synced 2026-03-30 10:15:48 +00:00
Optimize NAL unit search.
I'm not really a fan of micro-optimizations, but given this method scans through every H264 frame in the HLS case, it seems worthwhile. The trick here is to examine the first 7 bits of the third byte first. If they're not all 0s, then we know that we haven't found a NAL unit, and also that we wont find one at the next two positions. This allows the loop to increment 3 bytes at a time. Speedup is around 60% on Art according to some ad-hoc benchmarking.
This commit is contained in:
parent
3568ecaf00
commit
f7fb4d4c35
1 changed files with 18 additions and 6 deletions
|
|
@ -102,6 +102,7 @@ public final class Mp4Util {
|
|||
/**
|
||||
* Like {@link #findNalUnit(byte[], int, int, int)} with {@code type == -1}.
|
||||
*
|
||||
* @param data The data to search.
|
||||
* @param startOffset The offset (inclusive) in the data to start the search.
|
||||
* @param endOffset The offset (exclusive) in the data to end the search.
|
||||
* @return The offset of the NAL unit, or {@code endOffset} if a NAL unit was not found.
|
||||
|
|
@ -116,17 +117,28 @@ public final class Mp4Util {
|
|||
* For a NAL unit to be found, its first four bytes must be contained within the part of the
|
||||
* array being searched.
|
||||
*
|
||||
* @param type The type of the NAL unit to search for, or -1 for any NAL unit.
|
||||
* @param data The data to search.
|
||||
* @param startOffset The offset (inclusive) in the data to start the search.
|
||||
* @param endOffset The offset (exclusive) in the data to end the search.
|
||||
* @param type The type of the NAL unit to search for, or -1 for any NAL unit.
|
||||
* @return The offset of the NAL unit, or {@code endOffset} if a NAL unit was not found.
|
||||
*/
|
||||
public static int findNalUnit(byte[] data, int startOffset, int endOffset, int type) {
|
||||
for (int i = startOffset; i < endOffset - 3; i++) {
|
||||
// Check for NAL unit start code prefix == 0x000001.
|
||||
if ((data[i] == 0 && data[i + 1] == 0 && data[i + 2] == 1)
|
||||
&& (type == -1 || (type == (data[i + 3] & 0x1F)))) {
|
||||
return i;
|
||||
int limit = endOffset - 2;
|
||||
// We're looking for the NAL unit start code prefix 0x000001, followed by a byte that matches
|
||||
// the specified type. The value of i tracks the index of the third byte in the four bytes
|
||||
// being examined.
|
||||
for (int i = startOffset + 2; i < limit; i += 3) {
|
||||
if ((data[i] & 0xFE) != 0) {
|
||||
// There isn't a NAL prefix here, or at the next two positions. Do nothing and let the
|
||||
// loop advance the index by three.
|
||||
} else if ((data[i - 2] == 0 && data[i - 1] == 0 && data[i] == 1)
|
||||
&& (type == -1 || (type == (data[i + 1] & 0x1F)))) {
|
||||
return i - 2;
|
||||
} else {
|
||||
// There isn't a NAL prefix here, but there might be at the next position. We should
|
||||
// only skip forward by one. The loop will skip forward by three, so subtract two here.
|
||||
i -= 2;
|
||||
}
|
||||
}
|
||||
return endOffset;
|
||||
|
|
|
|||
Loading…
Reference in a new issue