mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Handle sample size mismatch in MP4 extractors
#minor-release PiperOrigin-RevId: 351756333
This commit is contained in:
parent
9b062053fa
commit
7d847a9552
3 changed files with 45 additions and 18 deletions
|
|
@ -106,6 +106,8 @@
|
||||||
* Populate codecs string for H.265/HEVC in MP4, Matroska and MPEG-TS
|
* Populate codecs string for H.265/HEVC in MP4, Matroska and MPEG-TS
|
||||||
streams to allow decoder capability checks based on codec profile/level
|
streams to allow decoder capability checks based on codec profile/level
|
||||||
([#8393](https://github.com/google/ExoPlayer/issues/8393)).
|
([#8393](https://github.com/google/ExoPlayer/issues/8393)).
|
||||||
|
* Handle sample size mismatches between raw audio PCM encoding and `stsz`
|
||||||
|
sample size in MP4 extractors.
|
||||||
* Track selection:
|
* Track selection:
|
||||||
* Allow parallel adaptation for video and audio
|
* Allow parallel adaptation for video and audio
|
||||||
([#5111](https://github.com/google/ExoPlayer/issues/5111)).
|
([#5111](https://github.com/google/ExoPlayer/issues/5111)).
|
||||||
|
|
|
||||||
|
|
@ -1673,6 +1673,31 @@ public final class Util {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the sample size for audio in the specified encoding.
|
||||||
|
*
|
||||||
|
* @param pcmEncoding The encoding of the audio data.
|
||||||
|
* @return The size of one audio sample in bytes.
|
||||||
|
*/
|
||||||
|
public static int getPcmSampleSize(@C.PcmEncoding int pcmEncoding) {
|
||||||
|
switch (pcmEncoding) {
|
||||||
|
case C.ENCODING_PCM_8BIT:
|
||||||
|
return 1;
|
||||||
|
case C.ENCODING_PCM_16BIT:
|
||||||
|
case C.ENCODING_PCM_16BIT_BIG_ENDIAN:
|
||||||
|
return 2;
|
||||||
|
case C.ENCODING_PCM_24BIT:
|
||||||
|
return 3;
|
||||||
|
case C.ENCODING_PCM_32BIT:
|
||||||
|
case C.ENCODING_PCM_FLOAT:
|
||||||
|
return 4;
|
||||||
|
case C.ENCODING_INVALID:
|
||||||
|
case Format.NO_VALUE:
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the frame size for audio with {@code channelCount} channels in the specified encoding.
|
* Returns the frame size for audio with {@code channelCount} channels in the specified encoding.
|
||||||
*
|
*
|
||||||
|
|
@ -1681,22 +1706,7 @@ public final class Util {
|
||||||
* @return The size of one audio frame in bytes.
|
* @return The size of one audio frame in bytes.
|
||||||
*/
|
*/
|
||||||
public static int getPcmFrameSize(@C.PcmEncoding int pcmEncoding, int channelCount) {
|
public static int getPcmFrameSize(@C.PcmEncoding int pcmEncoding, int channelCount) {
|
||||||
switch (pcmEncoding) {
|
return getPcmSampleSize(pcmEncoding) * channelCount;
|
||||||
case C.ENCODING_PCM_8BIT:
|
|
||||||
return channelCount;
|
|
||||||
case C.ENCODING_PCM_16BIT:
|
|
||||||
case C.ENCODING_PCM_16BIT_BIG_ENDIAN:
|
|
||||||
return channelCount * 2;
|
|
||||||
case C.ENCODING_PCM_24BIT:
|
|
||||||
return channelCount * 3;
|
|
||||||
case C.ENCODING_PCM_32BIT:
|
|
||||||
case C.ENCODING_PCM_FLOAT:
|
|
||||||
return channelCount * 4;
|
|
||||||
case C.ENCODING_INVALID:
|
|
||||||
case Format.NO_VALUE:
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -315,7 +315,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||||
SampleSizeBox sampleSizeBox;
|
SampleSizeBox sampleSizeBox;
|
||||||
@Nullable Atom.LeafAtom stszAtom = stblAtom.getLeafAtomOfType(Atom.TYPE_stsz);
|
@Nullable Atom.LeafAtom stszAtom = stblAtom.getLeafAtomOfType(Atom.TYPE_stsz);
|
||||||
if (stszAtom != null) {
|
if (stszAtom != null) {
|
||||||
sampleSizeBox = new StszSampleSizeBox(stszAtom);
|
sampleSizeBox = new StszSampleSizeBox(stszAtom, track.format);
|
||||||
} else {
|
} else {
|
||||||
@Nullable Atom.LeafAtom stz2Atom = stblAtom.getLeafAtomOfType(Atom.TYPE_stz2);
|
@Nullable Atom.LeafAtom stz2Atom = stblAtom.getLeafAtomOfType(Atom.TYPE_stz2);
|
||||||
if (stz2Atom == null) {
|
if (stz2Atom == null) {
|
||||||
|
|
@ -1720,10 +1720,25 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||||
private final int sampleCount;
|
private final int sampleCount;
|
||||||
private final ParsableByteArray data;
|
private final ParsableByteArray data;
|
||||||
|
|
||||||
public StszSampleSizeBox(Atom.LeafAtom stszAtom) {
|
public StszSampleSizeBox(Atom.LeafAtom stszAtom, Format trackFormat) {
|
||||||
data = stszAtom.data;
|
data = stszAtom.data;
|
||||||
data.setPosition(Atom.FULL_HEADER_SIZE);
|
data.setPosition(Atom.FULL_HEADER_SIZE);
|
||||||
int fixedSampleSize = data.readUnsignedIntToInt();
|
int fixedSampleSize = data.readUnsignedIntToInt();
|
||||||
|
if (MimeTypes.AUDIO_RAW.equals(trackFormat.sampleMimeType)) {
|
||||||
|
@C.PcmEncoding int pcmEncoding = trackFormat.pcmEncoding;
|
||||||
|
int pcmSampleSize = Util.getPcmSampleSize(pcmEncoding);
|
||||||
|
if (pcmSampleSize != fixedSampleSize) {
|
||||||
|
// The sample size from the stsz box is inconsistent with the PCM encoding derived from
|
||||||
|
// the stsd box. Choose the PCM encoding as source of truth [Internal ref: b/171627904].
|
||||||
|
Log.w(
|
||||||
|
TAG,
|
||||||
|
"Audio sample size mismatch. PCM encoding: "
|
||||||
|
+ pcmEncoding
|
||||||
|
+ ", stsz sample size = "
|
||||||
|
+ fixedSampleSize);
|
||||||
|
fixedSampleSize = pcmSampleSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
this.fixedSampleSize = fixedSampleSize == 0 ? C.LENGTH_UNSET : fixedSampleSize;
|
this.fixedSampleSize = fixedSampleSize == 0 ? C.LENGTH_UNSET : fixedSampleSize;
|
||||||
sampleCount = data.readUnsignedIntToInt();
|
sampleCount = data.readUnsignedIntToInt();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue