From 8932c5212242dd5d9206d472149e751bfc09854f Mon Sep 17 00:00:00 2001 From: rohks Date: Wed, 30 Nov 2022 21:29:53 +0000 Subject: [PATCH] Parse and set bitrates in `Ac3Reader` PiperOrigin-RevId: 492003800 (cherry picked from commit c7aa54cb411e485c2c17e630779d9e27d758a550) --- .../androidx/media3/extractor/Ac3Util.java | 21 +++++++++++++++++-- .../media3/extractor/ts/Ac3Reader.java | 10 +++++++-- .../extractordumps/ts/sample.ac3.0.dump | 2 ++ .../ts/sample.ac3.unknown_length.dump | 2 ++ .../extractordumps/ts/sample.eac3.0.dump | 1 + .../ts/sample.eac3.unknown_length.dump | 1 + .../extractordumps/ts/sample_ac3.ps.0.dump | 2 ++ .../ts/sample_ac3.ps.unknown_length.dump | 2 ++ .../extractordumps/ts/sample_ac3.ts.0.dump | 2 ++ .../extractordumps/ts/sample_ac3.ts.1.dump | 2 ++ .../extractordumps/ts/sample_ac3.ts.2.dump | 2 ++ .../extractordumps/ts/sample_ac3.ts.3.dump | 2 ++ .../ts/sample_ac3.ts.unknown_length.dump | 2 ++ .../extractordumps/ts/sample_ait.ts.0.dump | 1 + .../ts/sample_ait.ts.unknown_length.dump | 1 + .../extractordumps/ts/sample_eac3.ts.0.dump | 1 + .../extractordumps/ts/sample_eac3.ts.1.dump | 1 + .../extractordumps/ts/sample_eac3.ts.2.dump | 1 + .../extractordumps/ts/sample_eac3.ts.3.dump | 1 + .../ts/sample_eac3.ts.unknown_length.dump | 1 + .../ts/sample_eac3joc.ec3.0.dump | 1 + .../ts/sample_eac3joc.ec3.unknown_length.dump | 1 + .../ts/sample_eac3joc.ts.0.dump | 1 + .../ts/sample_eac3joc.ts.1.dump | 1 + .../ts/sample_eac3joc.ts.2.dump | 1 + .../ts/sample_eac3joc.ts.3.dump | 1 + .../ts/sample_eac3joc.ts.unknown_length.dump | 1 + 27 files changed, 61 insertions(+), 4 deletions(-) diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/Ac3Util.java b/libraries/extractor/src/main/java/androidx/media3/extractor/Ac3Util.java index b9279635d8..9fe613aac2 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/Ac3Util.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/Ac3Util.java @@ -80,6 +80,8 @@ public final class Ac3Util { public final int frameSize; /** Number of audio samples in the frame. */ public final int sampleCount; + /** The bitrate of audio samples. */ + public final int bitrate; private SyncFrameInfo( @Nullable String mimeType, @@ -87,13 +89,15 @@ public final class Ac3Util { int channelCount, int sampleRate, int frameSize, - int sampleCount) { + int sampleCount, + int bitrate) { this.mimeType = mimeType; this.streamType = streamType; this.channelCount = channelCount; this.sampleRate = sampleRate; this.frameSize = frameSize; this.sampleCount = sampleCount; + this.bitrate = bitrate; } } @@ -261,6 +265,7 @@ public final class Ac3Util { int sampleCount; boolean lfeon; int channelCount; + int bitrate; if (isEac3) { // Subsection E.1.2. data.skipBits(16); // syncword @@ -293,6 +298,7 @@ public final class Ac3Util { sampleRate = SAMPLE_RATE_BY_FSCOD[fscod]; } sampleCount = AUDIO_SAMPLES_PER_AUDIO_BLOCK * audioBlocks; + bitrate = calculateEac3Bitrate(frameSize, sampleRate, audioBlocks); acmod = data.readBits(3); lfeon = data.readBit(); channelCount = CHANNEL_COUNT_BY_ACMOD[acmod] + (lfeon ? 1 : 0); @@ -448,6 +454,7 @@ public final class Ac3Util { mimeType = null; } int frmsizecod = data.readBits(6); + bitrate = BITRATE_BY_HALF_FRMSIZECOD[frmsizecod / 2] * 1000; frameSize = getAc3SyncframeSize(fscod, frmsizecod); data.skipBits(5 + 3); // bsid, bsmod acmod = data.readBits(3); @@ -467,7 +474,7 @@ public final class Ac3Util { channelCount = CHANNEL_COUNT_BY_ACMOD[acmod] + (lfeon ? 1 : 0); } return new SyncFrameInfo( - mimeType, streamType, channelCount, sampleRate, frameSize, sampleCount); + mimeType, streamType, channelCount, sampleRate, frameSize, sampleCount, bitrate); } /** @@ -589,5 +596,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() {} } diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac3Reader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac3Reader.java index 1d80fbca08..02d674c973 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac3Reader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac3Reader.java @@ -22,6 +22,7 @@ import androidx.annotation.IntDef; import androidx.annotation.Nullable; import androidx.media3.common.C; import androidx.media3.common.Format; +import androidx.media3.common.MimeTypes; import androidx.media3.common.util.Assertions; import androidx.media3.common.util.ParsableBitArray; import androidx.media3.common.util.ParsableByteArray; @@ -209,14 +210,19 @@ public final class Ac3Reader implements ElementaryStreamReader { || frameInfo.channelCount != format.channelCount || frameInfo.sampleRate != format.sampleRate || !Util.areEqual(frameInfo.mimeType, format.sampleMimeType)) { - format = + Format.Builder formatBuilder = new Format.Builder() .setId(formatId) .setSampleMimeType(frameInfo.mimeType) .setChannelCount(frameInfo.channelCount) .setSampleRate(frameInfo.sampleRate) .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); } sampleSize = frameInfo.frameSize; diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample.ac3.0.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample.ac3.0.dump index 3f582caedd..8aad7940f2 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample.ac3.0.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample.ac3.0.dump @@ -7,6 +7,8 @@ track 0: total output bytes = 13281 sample count = 8 format 0: + averageBitrate = 384000 + peakBitrate = 384000 id = 0 sampleMimeType = audio/ac3 channelCount = 6 diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample.ac3.unknown_length.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample.ac3.unknown_length.dump index 3f582caedd..8aad7940f2 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample.ac3.unknown_length.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample.ac3.unknown_length.dump @@ -7,6 +7,8 @@ track 0: total output bytes = 13281 sample count = 8 format 0: + averageBitrate = 384000 + peakBitrate = 384000 id = 0 sampleMimeType = audio/ac3 channelCount = 6 diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample.eac3.0.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample.eac3.0.dump index f3d9d3997d..f8be0e618c 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample.eac3.0.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample.eac3.0.dump @@ -7,6 +7,7 @@ track 0: total output bytes = 216000 sample count = 54 format 0: + peakBitrate = 6000000 id = 0 sampleMimeType = audio/eac3 channelCount = 6 diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample.eac3.unknown_length.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample.eac3.unknown_length.dump index f3d9d3997d..f8be0e618c 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample.eac3.unknown_length.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample.eac3.unknown_length.dump @@ -7,6 +7,7 @@ track 0: total output bytes = 216000 sample count = 54 format 0: + peakBitrate = 6000000 id = 0 sampleMimeType = audio/eac3 channelCount = 6 diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ps.0.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ps.0.dump index 27d0c450fd..143245058f 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ps.0.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ps.0.dump @@ -10,6 +10,8 @@ track 189: total output bytes = 1252 sample count = 3 format 0: + averageBitrate = 96000 + peakBitrate = 96000 id = 189 sampleMimeType = audio/ac3 channelCount = 1 diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ps.unknown_length.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ps.unknown_length.dump index 960882156b..62c215256f 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ps.unknown_length.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ps.unknown_length.dump @@ -7,6 +7,8 @@ track 189: total output bytes = 1252 sample count = 3 format 0: + averageBitrate = 96000 + peakBitrate = 96000 id = 189 sampleMimeType = audio/ac3 channelCount = 1 diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ts.0.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ts.0.dump index 561963e10c..f3ac4e2018 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ts.0.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ts.0.dump @@ -10,6 +10,8 @@ track 1900: total output bytes = 13281 sample count = 8 format 0: + averageBitrate = 384000 + peakBitrate = 384000 id = 1/1900 sampleMimeType = audio/ac3 channelCount = 6 diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ts.1.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ts.1.dump index d778af898d..9f141492b2 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ts.1.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ts.1.dump @@ -10,6 +10,8 @@ track 1900: total output bytes = 10209 sample count = 6 format 0: + averageBitrate = 384000 + peakBitrate = 384000 id = 1/1900 sampleMimeType = audio/ac3 channelCount = 6 diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ts.2.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ts.2.dump index f48ba43854..e6cea3993f 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ts.2.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ts.2.dump @@ -10,6 +10,8 @@ track 1900: total output bytes = 7137 sample count = 4 format 0: + averageBitrate = 384000 + peakBitrate = 384000 id = 1/1900 sampleMimeType = audio/ac3 channelCount = 6 diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ts.3.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ts.3.dump index 997d7a6b02..da9814ead3 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ts.3.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ts.3.dump @@ -10,6 +10,8 @@ track 1900: total output bytes = 0 sample count = 0 format 0: + averageBitrate = 384000 + peakBitrate = 384000 id = 1/1900 sampleMimeType = audio/ac3 channelCount = 6 diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ts.unknown_length.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ts.unknown_length.dump index a98cb798cb..f992ac64e8 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ts.unknown_length.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_ac3.ts.unknown_length.dump @@ -7,6 +7,8 @@ track 1900: total output bytes = 13281 sample count = 8 format 0: + averageBitrate = 384000 + peakBitrate = 384000 id = 1/1900 sampleMimeType = audio/ac3 channelCount = 6 diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_ait.ts.0.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_ait.ts.0.dump index 355b403293..3a305ed662 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample_ait.ts.0.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_ait.ts.0.dump @@ -7,6 +7,7 @@ track 330: total output bytes = 9928 sample count = 19 format 0: + peakBitrate = 128000 id = 1031/330 sampleMimeType = audio/eac3 channelCount = 2 diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_ait.ts.unknown_length.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_ait.ts.unknown_length.dump index 355b403293..3a305ed662 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample_ait.ts.unknown_length.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_ait.ts.unknown_length.dump @@ -7,6 +7,7 @@ track 330: total output bytes = 9928 sample count = 19 format 0: + peakBitrate = 128000 id = 1031/330 sampleMimeType = audio/eac3 channelCount = 2 diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3.ts.0.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3.ts.0.dump index dfc89c5f19..2ccaceef7f 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3.ts.0.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3.ts.0.dump @@ -10,6 +10,7 @@ track 1900: total output bytes = 216000 sample count = 54 format 0: + peakBitrate = 6000000 id = 1/1900 sampleMimeType = audio/eac3 channelCount = 6 diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3.ts.1.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3.ts.1.dump index c06294df2c..ccf162fc31 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3.ts.1.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3.ts.1.dump @@ -10,6 +10,7 @@ track 1900: total output bytes = 168000 sample count = 42 format 0: + peakBitrate = 6000000 id = 1/1900 sampleMimeType = audio/eac3 channelCount = 6 diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3.ts.2.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3.ts.2.dump index 9104607498..286fc25b16 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3.ts.2.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3.ts.2.dump @@ -10,6 +10,7 @@ track 1900: total output bytes = 96000 sample count = 24 format 0: + peakBitrate = 6000000 id = 1/1900 sampleMimeType = audio/eac3 channelCount = 6 diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3.ts.3.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3.ts.3.dump index c490b7eca8..cfbfae20b6 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3.ts.3.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3.ts.3.dump @@ -10,6 +10,7 @@ track 1900: total output bytes = 0 sample count = 0 format 0: + peakBitrate = 6000000 id = 1/1900 sampleMimeType = audio/eac3 channelCount = 6 diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3.ts.unknown_length.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3.ts.unknown_length.dump index 0aae4097a7..4bb8650d72 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3.ts.unknown_length.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3.ts.unknown_length.dump @@ -7,6 +7,7 @@ track 1900: total output bytes = 216000 sample count = 54 format 0: + peakBitrate = 6000000 id = 1/1900 sampleMimeType = audio/eac3 channelCount = 6 diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ec3.0.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ec3.0.dump index f8888698bd..5a8f918105 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ec3.0.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ec3.0.dump @@ -7,6 +7,7 @@ track 0: total output bytes = 163840 sample count = 64 format 0: + peakBitrate = 640000 id = 0 sampleMimeType = audio/eac3-joc channelCount = 6 diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ec3.unknown_length.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ec3.unknown_length.dump index f8888698bd..5a8f918105 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ec3.unknown_length.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ec3.unknown_length.dump @@ -7,6 +7,7 @@ track 0: total output bytes = 163840 sample count = 64 format 0: + peakBitrate = 640000 id = 0 sampleMimeType = audio/eac3-joc channelCount = 6 diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ts.0.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ts.0.dump index a3cf812691..2fc2f49280 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ts.0.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ts.0.dump @@ -10,6 +10,7 @@ track 1900: total output bytes = 163840 sample count = 64 format 0: + peakBitrate = 640000 id = 1/1900 sampleMimeType = audio/eac3-joc channelCount = 6 diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ts.1.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ts.1.dump index 77951bd767..771c5216c5 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ts.1.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ts.1.dump @@ -10,6 +10,7 @@ track 1900: total output bytes = 112640 sample count = 44 format 0: + peakBitrate = 640000 id = 1/1900 sampleMimeType = audio/eac3-joc channelCount = 6 diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ts.2.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ts.2.dump index 0354754df2..452d8eea13 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ts.2.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ts.2.dump @@ -10,6 +10,7 @@ track 1900: total output bytes = 56320 sample count = 22 format 0: + peakBitrate = 640000 id = 1/1900 sampleMimeType = audio/eac3-joc channelCount = 6 diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ts.3.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ts.3.dump index 742d87e271..8da152a79f 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ts.3.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ts.3.dump @@ -10,6 +10,7 @@ track 1900: total output bytes = 5120 sample count = 2 format 0: + peakBitrate = 640000 id = 1/1900 sampleMimeType = audio/eac3-joc channelCount = 6 diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ts.unknown_length.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ts.unknown_length.dump index 269dd63593..82ce1d24bb 100644 --- a/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ts.unknown_length.dump +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_eac3joc.ts.unknown_length.dump @@ -7,6 +7,7 @@ track 1900: total output bytes = 163840 sample count = 64 format 0: + peakBitrate = 640000 id = 1/1900 sampleMimeType = audio/eac3-joc channelCount = 6