mirror of
https://github.com/androidx/media.git
synced 2025-05-07 15:40:37 +08:00
De-duplicate code for H264/H265 in MPEG-TS.
This commit is contained in:
parent
10efe7904d
commit
96c1e670c4
@ -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;
|
|||||||
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[] {
|
|
||||||
1f /* Unspecified. Assume square */,
|
|
||||||
1f,
|
|
||||||
12f / 11f,
|
|
||||||
10f / 11f,
|
|
||||||
16f / 11f,
|
|
||||||
40f / 33f,
|
|
||||||
24f / 11f,
|
|
||||||
20f / 11f,
|
|
||||||
32f / 11f,
|
|
||||||
80f / 33f,
|
|
||||||
18f / 11f,
|
|
||||||
15f / 11f,
|
|
||||||
64f / 33f,
|
|
||||||
160f / 99f,
|
|
||||||
4f / 3f,
|
|
||||||
3f / 2f,
|
|
||||||
2f
|
|
||||||
};
|
|
||||||
|
|
||||||
// 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;
|
|||||||
// 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;
|
|||||||
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);
|
||||||
}
|
}
|
||||||
@ -394,96 +373,6 @@ import java.util.List;
|
|||||||
return limit;
|
return limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
||||||
*/
|
*/
|
||||||
|
@ -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;
|
|||||||
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[] {
|
|
||||||
1f /* Unspecified. Assume square */,
|
|
||||||
1f,
|
|
||||||
12f / 11f,
|
|
||||||
10f / 11f,
|
|
||||||
16f / 11f,
|
|
||||||
40f / 33f,
|
|
||||||
24f / 11f,
|
|
||||||
20f / 11f,
|
|
||||||
32f / 11f,
|
|
||||||
80f / 33f,
|
|
||||||
18f / 11f,
|
|
||||||
15f / 11f,
|
|
||||||
64f / 33f,
|
|
||||||
160f / 99f,
|
|
||||||
4f / 3f,
|
|
||||||
3f / 2f,
|
|
||||||
2f
|
|
||||||
};
|
|
||||||
|
|
||||||
// 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;
|
|||||||
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;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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[] {
|
||||||
|
1f /* Unspecified. Assume square */,
|
||||||
|
1f,
|
||||||
|
12f / 11f,
|
||||||
|
10f / 11f,
|
||||||
|
16f / 11f,
|
||||||
|
40f / 33f,
|
||||||
|
24f / 11f,
|
||||||
|
20f / 11f,
|
||||||
|
32f / 11f,
|
||||||
|
80f / 33f,
|
||||||
|
18f / 11f,
|
||||||
|
15f / 11f,
|
||||||
|
64f / 33f,
|
||||||
|
160f / 99f,
|
||||||
|
4f / 3f,
|
||||||
|
3f / 2f,
|
||||||
|
2f
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 {
|
|||||||
/**
|
/**
|
||||||
* 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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|||||||
? (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 three bytes in the data seen so far are {0,0}.
|
// True if the last two 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user