Parse and set bitrates in Ac3Reader

PiperOrigin-RevId: 492003800
(cherry picked from commit 5f73984823b943d750f41519d431ad3b12dada65)
This commit is contained in:
rohks 2022-11-30 21:29:53 +00:00 committed by christosts
parent 2921cb76c5
commit 8246587b00
27 changed files with 61 additions and 4 deletions

View File

@ -78,6 +78,8 @@ public final class Ac3Util {
public final int frameSize; public final int frameSize;
/** Number of audio samples in the frame. */ /** Number of audio samples in the frame. */
public final int sampleCount; public final int sampleCount;
/** The bitrate of audio samples. */
public final int bitrate;
private SyncFrameInfo( private SyncFrameInfo(
@Nullable String mimeType, @Nullable String mimeType,
@ -85,13 +87,15 @@ public final class Ac3Util {
int channelCount, int channelCount,
int sampleRate, int sampleRate,
int frameSize, int frameSize,
int sampleCount) { int sampleCount,
int bitrate) {
this.mimeType = mimeType; this.mimeType = mimeType;
this.streamType = streamType; this.streamType = streamType;
this.channelCount = channelCount; this.channelCount = channelCount;
this.sampleRate = sampleRate; this.sampleRate = sampleRate;
this.frameSize = frameSize; this.frameSize = frameSize;
this.sampleCount = sampleCount; this.sampleCount = sampleCount;
this.bitrate = bitrate;
} }
} }
@ -259,6 +263,7 @@ public final class Ac3Util {
int sampleCount; int sampleCount;
boolean lfeon; boolean lfeon;
int channelCount; int channelCount;
int bitrate;
if (isEac3) { if (isEac3) {
// Subsection E.1.2. // Subsection E.1.2.
data.skipBits(16); // syncword data.skipBits(16); // syncword
@ -291,6 +296,7 @@ public final class Ac3Util {
sampleRate = SAMPLE_RATE_BY_FSCOD[fscod]; sampleRate = SAMPLE_RATE_BY_FSCOD[fscod];
} }
sampleCount = AUDIO_SAMPLES_PER_AUDIO_BLOCK * audioBlocks; sampleCount = AUDIO_SAMPLES_PER_AUDIO_BLOCK * audioBlocks;
bitrate = calculateEac3Bitrate(frameSize, sampleRate, audioBlocks);
acmod = data.readBits(3); acmod = data.readBits(3);
lfeon = data.readBit(); lfeon = data.readBit();
channelCount = CHANNEL_COUNT_BY_ACMOD[acmod] + (lfeon ? 1 : 0); channelCount = CHANNEL_COUNT_BY_ACMOD[acmod] + (lfeon ? 1 : 0);
@ -446,6 +452,7 @@ public final class Ac3Util {
mimeType = null; mimeType = null;
} }
int frmsizecod = data.readBits(6); int frmsizecod = data.readBits(6);
bitrate = BITRATE_BY_HALF_FRMSIZECOD[frmsizecod / 2] * 1000;
frameSize = getAc3SyncframeSize(fscod, frmsizecod); frameSize = getAc3SyncframeSize(fscod, frmsizecod);
data.skipBits(5 + 3); // bsid, bsmod data.skipBits(5 + 3); // bsid, bsmod
acmod = data.readBits(3); acmod = data.readBits(3);
@ -465,7 +472,7 @@ public final class Ac3Util {
channelCount = CHANNEL_COUNT_BY_ACMOD[acmod] + (lfeon ? 1 : 0); channelCount = CHANNEL_COUNT_BY_ACMOD[acmod] + (lfeon ? 1 : 0);
} }
return new SyncFrameInfo( return new SyncFrameInfo(
mimeType, streamType, channelCount, sampleRate, frameSize, sampleCount); mimeType, streamType, channelCount, sampleRate, frameSize, sampleCount, bitrate);
} }
/** /**
@ -587,5 +594,15 @@ public final class Ac3Util {
} }
} }
/**
* Derived from the formula defined in F.6.2.2 to calculate data_rate for the (E-)AC3 bitstream.
* Note: The formula is based on frmsiz read from the spec. We already do some modifications to it
* when deriving frameSize from the read value. The formula used here is adapted to accommodate
* that modification.
*/
private static int calculateEac3Bitrate(int frameSize, int sampleRate, int audioBlocks) {
return (frameSize * sampleRate) / (audioBlocks * 32);
}
private Ac3Util() {} private Ac3Util() {}
} }

View File

@ -28,6 +28,7 @@ import com.google.android.exoplayer2.extractor.ExtractorOutput;
import com.google.android.exoplayer2.extractor.TrackOutput; import com.google.android.exoplayer2.extractor.TrackOutput;
import com.google.android.exoplayer2.extractor.ts.TsPayloadReader.TrackIdGenerator; import com.google.android.exoplayer2.extractor.ts.TsPayloadReader.TrackIdGenerator;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.ParsableBitArray; import com.google.android.exoplayer2.util.ParsableBitArray;
import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
@ -207,14 +208,19 @@ public final class Ac3Reader implements ElementaryStreamReader {
|| frameInfo.channelCount != format.channelCount || frameInfo.channelCount != format.channelCount
|| frameInfo.sampleRate != format.sampleRate || frameInfo.sampleRate != format.sampleRate
|| !Util.areEqual(frameInfo.mimeType, format.sampleMimeType)) { || !Util.areEqual(frameInfo.mimeType, format.sampleMimeType)) {
format = Format.Builder formatBuilder =
new Format.Builder() new Format.Builder()
.setId(formatId) .setId(formatId)
.setSampleMimeType(frameInfo.mimeType) .setSampleMimeType(frameInfo.mimeType)
.setChannelCount(frameInfo.channelCount) .setChannelCount(frameInfo.channelCount)
.setSampleRate(frameInfo.sampleRate) .setSampleRate(frameInfo.sampleRate)
.setLanguage(language) .setLanguage(language)
.build(); .setPeakBitrate(frameInfo.bitrate);
// AC3 has constant bitrate, so averageBitrate = peakBitrate
if (MimeTypes.AUDIO_AC3.equals(frameInfo.mimeType)) {
formatBuilder.setAverageBitrate(frameInfo.bitrate);
}
format = formatBuilder.build();
output.format(format); output.format(format);
} }
sampleSize = frameInfo.frameSize; sampleSize = frameInfo.frameSize;

View File

@ -7,6 +7,8 @@ track 0:
total output bytes = 13281 total output bytes = 13281
sample count = 8 sample count = 8
format 0: format 0:
averageBitrate = 384000
peakBitrate = 384000
id = 0 id = 0
sampleMimeType = audio/ac3 sampleMimeType = audio/ac3
channelCount = 6 channelCount = 6

View File

@ -7,6 +7,8 @@ track 0:
total output bytes = 13281 total output bytes = 13281
sample count = 8 sample count = 8
format 0: format 0:
averageBitrate = 384000
peakBitrate = 384000
id = 0 id = 0
sampleMimeType = audio/ac3 sampleMimeType = audio/ac3
channelCount = 6 channelCount = 6

View File

@ -7,6 +7,7 @@ track 0:
total output bytes = 216000 total output bytes = 216000
sample count = 54 sample count = 54
format 0: format 0:
peakBitrate = 6000000
id = 0 id = 0
sampleMimeType = audio/eac3 sampleMimeType = audio/eac3
channelCount = 6 channelCount = 6

View File

@ -7,6 +7,7 @@ track 0:
total output bytes = 216000 total output bytes = 216000
sample count = 54 sample count = 54
format 0: format 0:
peakBitrate = 6000000
id = 0 id = 0
sampleMimeType = audio/eac3 sampleMimeType = audio/eac3
channelCount = 6 channelCount = 6

View File

@ -10,6 +10,8 @@ track 189:
total output bytes = 1252 total output bytes = 1252
sample count = 3 sample count = 3
format 0: format 0:
averageBitrate = 96000
peakBitrate = 96000
id = 189 id = 189
sampleMimeType = audio/ac3 sampleMimeType = audio/ac3
channelCount = 1 channelCount = 1

View File

@ -7,6 +7,8 @@ track 189:
total output bytes = 1252 total output bytes = 1252
sample count = 3 sample count = 3
format 0: format 0:
averageBitrate = 96000
peakBitrate = 96000
id = 189 id = 189
sampleMimeType = audio/ac3 sampleMimeType = audio/ac3
channelCount = 1 channelCount = 1

View File

@ -10,6 +10,8 @@ track 1900:
total output bytes = 13281 total output bytes = 13281
sample count = 8 sample count = 8
format 0: format 0:
averageBitrate = 384000
peakBitrate = 384000
id = 1/1900 id = 1/1900
sampleMimeType = audio/ac3 sampleMimeType = audio/ac3
channelCount = 6 channelCount = 6

View File

@ -10,6 +10,8 @@ track 1900:
total output bytes = 10209 total output bytes = 10209
sample count = 6 sample count = 6
format 0: format 0:
averageBitrate = 384000
peakBitrate = 384000
id = 1/1900 id = 1/1900
sampleMimeType = audio/ac3 sampleMimeType = audio/ac3
channelCount = 6 channelCount = 6

View File

@ -10,6 +10,8 @@ track 1900:
total output bytes = 7137 total output bytes = 7137
sample count = 4 sample count = 4
format 0: format 0:
averageBitrate = 384000
peakBitrate = 384000
id = 1/1900 id = 1/1900
sampleMimeType = audio/ac3 sampleMimeType = audio/ac3
channelCount = 6 channelCount = 6

View File

@ -10,6 +10,8 @@ track 1900:
total output bytes = 0 total output bytes = 0
sample count = 0 sample count = 0
format 0: format 0:
averageBitrate = 384000
peakBitrate = 384000
id = 1/1900 id = 1/1900
sampleMimeType = audio/ac3 sampleMimeType = audio/ac3
channelCount = 6 channelCount = 6

View File

@ -7,6 +7,8 @@ track 1900:
total output bytes = 13281 total output bytes = 13281
sample count = 8 sample count = 8
format 0: format 0:
averageBitrate = 384000
peakBitrate = 384000
id = 1/1900 id = 1/1900
sampleMimeType = audio/ac3 sampleMimeType = audio/ac3
channelCount = 6 channelCount = 6

View File

@ -7,6 +7,7 @@ track 330:
total output bytes = 9928 total output bytes = 9928
sample count = 19 sample count = 19
format 0: format 0:
peakBitrate = 128000
id = 1031/330 id = 1031/330
sampleMimeType = audio/eac3 sampleMimeType = audio/eac3
channelCount = 2 channelCount = 2

View File

@ -7,6 +7,7 @@ track 330:
total output bytes = 9928 total output bytes = 9928
sample count = 19 sample count = 19
format 0: format 0:
peakBitrate = 128000
id = 1031/330 id = 1031/330
sampleMimeType = audio/eac3 sampleMimeType = audio/eac3
channelCount = 2 channelCount = 2

View File

@ -10,6 +10,7 @@ track 1900:
total output bytes = 216000 total output bytes = 216000
sample count = 54 sample count = 54
format 0: format 0:
peakBitrate = 6000000
id = 1/1900 id = 1/1900
sampleMimeType = audio/eac3 sampleMimeType = audio/eac3
channelCount = 6 channelCount = 6

View File

@ -10,6 +10,7 @@ track 1900:
total output bytes = 168000 total output bytes = 168000
sample count = 42 sample count = 42
format 0: format 0:
peakBitrate = 6000000
id = 1/1900 id = 1/1900
sampleMimeType = audio/eac3 sampleMimeType = audio/eac3
channelCount = 6 channelCount = 6

View File

@ -10,6 +10,7 @@ track 1900:
total output bytes = 96000 total output bytes = 96000
sample count = 24 sample count = 24
format 0: format 0:
peakBitrate = 6000000
id = 1/1900 id = 1/1900
sampleMimeType = audio/eac3 sampleMimeType = audio/eac3
channelCount = 6 channelCount = 6

View File

@ -10,6 +10,7 @@ track 1900:
total output bytes = 0 total output bytes = 0
sample count = 0 sample count = 0
format 0: format 0:
peakBitrate = 6000000
id = 1/1900 id = 1/1900
sampleMimeType = audio/eac3 sampleMimeType = audio/eac3
channelCount = 6 channelCount = 6

View File

@ -7,6 +7,7 @@ track 1900:
total output bytes = 216000 total output bytes = 216000
sample count = 54 sample count = 54
format 0: format 0:
peakBitrate = 6000000
id = 1/1900 id = 1/1900
sampleMimeType = audio/eac3 sampleMimeType = audio/eac3
channelCount = 6 channelCount = 6

View File

@ -7,6 +7,7 @@ track 0:
total output bytes = 163840 total output bytes = 163840
sample count = 64 sample count = 64
format 0: format 0:
peakBitrate = 640000
id = 0 id = 0
sampleMimeType = audio/eac3-joc sampleMimeType = audio/eac3-joc
channelCount = 6 channelCount = 6

View File

@ -7,6 +7,7 @@ track 0:
total output bytes = 163840 total output bytes = 163840
sample count = 64 sample count = 64
format 0: format 0:
peakBitrate = 640000
id = 0 id = 0
sampleMimeType = audio/eac3-joc sampleMimeType = audio/eac3-joc
channelCount = 6 channelCount = 6

View File

@ -10,6 +10,7 @@ track 1900:
total output bytes = 163840 total output bytes = 163840
sample count = 64 sample count = 64
format 0: format 0:
peakBitrate = 640000
id = 1/1900 id = 1/1900
sampleMimeType = audio/eac3-joc sampleMimeType = audio/eac3-joc
channelCount = 6 channelCount = 6

View File

@ -10,6 +10,7 @@ track 1900:
total output bytes = 112640 total output bytes = 112640
sample count = 44 sample count = 44
format 0: format 0:
peakBitrate = 640000
id = 1/1900 id = 1/1900
sampleMimeType = audio/eac3-joc sampleMimeType = audio/eac3-joc
channelCount = 6 channelCount = 6

View File

@ -10,6 +10,7 @@ track 1900:
total output bytes = 56320 total output bytes = 56320
sample count = 22 sample count = 22
format 0: format 0:
peakBitrate = 640000
id = 1/1900 id = 1/1900
sampleMimeType = audio/eac3-joc sampleMimeType = audio/eac3-joc
channelCount = 6 channelCount = 6

View File

@ -10,6 +10,7 @@ track 1900:
total output bytes = 5120 total output bytes = 5120
sample count = 2 sample count = 2
format 0: format 0:
peakBitrate = 640000
id = 1/1900 id = 1/1900
sampleMimeType = audio/eac3-joc sampleMimeType = audio/eac3-joc
channelCount = 6 channelCount = 6

View File

@ -7,6 +7,7 @@ track 1900:
total output bytes = 163840 total output bytes = 163840
sample count = 64 sample count = 64
format 0: format 0:
peakBitrate = 640000
id = 1/1900 id = 1/1900
sampleMimeType = audio/eac3-joc sampleMimeType = audio/eac3-joc
channelCount = 6 channelCount = 6