From d615a3a7406e4861209fc76249503b1f14a9d4d7 Mon Sep 17 00:00:00 2001 From: kimvde Date: Tue, 14 Jul 2020 08:21:34 +0100 Subject: [PATCH] Fix sample time of partially fragmented MP4s with tfdt box PiperOrigin-RevId: 321109232 --- .../extractor/mp4/FragmentedMp4Extractor.java | 7 +- .../extractor/mp4/TrackFragment.java | 11 +- .../sample_partially_fragmented.mp4.0.dump | 140 +++++++++--------- ...rtially_fragmented.mp4.unknown_length.dump | 140 +++++++++--------- 4 files changed, 155 insertions(+), 143 deletions(-) diff --git a/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java b/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java index 0f420a52ef..822a9cee90 100644 --- a/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java +++ b/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java @@ -716,13 +716,16 @@ public class FragmentedMp4Extractor implements Extractor { TrackFragment fragment = trackBundle.fragment; long fragmentDecodeTime = fragment.nextFragmentDecodeTime; + boolean fragmentDecodeTimeIncludesMoov = fragment.nextFragmentDecodeTimeIncludesMoov; trackBundle.reset(); trackBundle.currentlyInFragment = true; @Nullable LeafAtom tfdtAtom = traf.getLeafAtomOfType(Atom.TYPE_tfdt); if (tfdtAtom != null && (flags & FLAG_WORKAROUND_IGNORE_TFDT_BOX) == 0) { fragment.nextFragmentDecodeTime = parseTfdt(traf.getLeafAtomOfType(Atom.TYPE_tfdt).data); + fragment.nextFragmentDecodeTimeIncludesMoov = true; } else { fragment.nextFragmentDecodeTime = fragmentDecodeTime; + fragment.nextFragmentDecodeTimeIncludesMoov = fragmentDecodeTimeIncludesMoov; } parseTruns(traf, trackBundle, flags); @@ -1023,7 +1026,9 @@ public class FragmentedMp4Extractor implements Extractor { } sampleDecodingTimeUsTable[i] = Util.scaleLargeTimestamp(cumulativeTime, C.MICROS_PER_SECOND, timescale) - edtsOffsetUs; - sampleDecodingTimeUsTable[i] += trackBundle.moovSampleTable.durationUs; + if (!fragment.nextFragmentDecodeTimeIncludesMoov) { + sampleDecodingTimeUsTable[i] += trackBundle.moovSampleTable.durationUs; + } sampleSizeTable[i] = sampleSize; sampleIsSyncFrameTable[i] = ((sampleFlags >> 16) & 0x1) == 0 && (!workaroundEveryVideoFrameIsSyncFrame || i == 0); diff --git a/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mp4/TrackFragment.java b/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mp4/TrackFragment.java index c60d0686a7..74f46d1837 100644 --- a/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mp4/TrackFragment.java +++ b/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mp4/TrackFragment.java @@ -89,10 +89,16 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; */ public boolean sampleEncryptionDataNeedsFill; /** - * The duration of all samples defined in fragments up to and including this one. Samples defined - * in the moov box are not included. + * The duration of all the samples defined in the fragments up to and including this one, plus the + * duration of the samples defined in the moov atom if {@link #nextFragmentDecodeTimeIncludesMoov} + * is {@code true}. */ public long nextFragmentDecodeTime; + /** + * Whether {@link #nextFragmentDecodeTime} includes the duration of the samples referred to by the + * moov atom. + */ + public boolean nextFragmentDecodeTimeIncludesMoov; public TrackFragment() { trunDataPosition = new long[0]; @@ -115,6 +121,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; public void reset() { trunCount = 0; nextFragmentDecodeTime = 0; + nextFragmentDecodeTimeIncludesMoov = false; definesEncryptionData = false; sampleEncryptionDataNeedsFill = false; trackEncryptionBox = null; diff --git a/testdata/src/test/assets/mp4/sample_partially_fragmented.mp4.0.dump b/testdata/src/test/assets/mp4/sample_partially_fragmented.mp4.0.dump index 7ee9341b9c..b3d57a3868 100644 --- a/testdata/src/test/assets/mp4/sample_partially_fragmented.mp4.0.dump +++ b/testdata/src/test/assets/mp4/sample_partially_fragmented.mp4.0.dump @@ -31,107 +31,107 @@ track 0: flags = 536870912 data = length 5867, hash 56F9EE87 sample 4: - time = 400398 + time = 166832 flags = 0 data = length 570, hash 984421BD sample 5: - time = 500499 + time = 266933 flags = 0 data = length 3406, hash 9A33201E sample 6: - time = 467132 + time = 233566 flags = 0 data = length 476, hash C59620F3 sample 7: - time = 567232 + time = 333666 flags = 0 data = length 4310, hash 291E6161 sample 8: - time = 533865 + time = 300299 flags = 0 data = length 497, hash 398CBFAA sample 9: - time = 700699 + time = 467133 flags = 0 data = length 4449, hash 322CAA2B sample 10: - time = 633965 + time = 400399 flags = 0 data = length 1076, hash B479B634 sample 11: - time = 600599 + time = 367033 flags = 0 data = length 365, hash 68C7D4C2 sample 12: - time = 667332 + time = 433766 flags = 0 data = length 463, hash A85F9769 sample 13: - time = 834165 + time = 600599 flags = 0 data = length 5339, hash F232195D sample 14: - time = 767432 + time = 533866 flags = 0 data = length 1085, hash 47AFB6FE sample 15: - time = 734066 + time = 500500 flags = 0 data = length 689, hash 3EB753A3 sample 16: - time = 800798 + time = 567232 flags = 0 data = length 516, hash E6DF9C1C sample 17: - time = 967632 + time = 734066 flags = 0 data = length 4899, hash A9A8F4B7 sample 18: - time = 900899 + time = 667333 flags = 0 data = length 963, hash 684782FB sample 19: - time = 867532 + time = 633966 flags = 0 data = length 625, hash ED1C8EF1 sample 20: - time = 934265 + time = 700699 flags = 0 data = length 492, hash E6E066EA sample 21: - time = 1101099 + time = 867533 flags = 0 data = length 2973, hash A3C54C3B sample 22: - time = 1034365 + time = 800799 flags = 0 data = length 833, hash 41CA807D sample 23: - time = 1000999 + time = 767433 flags = 0 data = length 516, hash 5B21BB11 sample 24: - time = 1067732 + time = 834166 flags = 0 data = length 384, hash A0E8FA50 sample 25: - time = 1234565 + time = 1000999 flags = 0 data = length 1450, hash 92741C3B sample 26: - time = 1167832 + time = 934266 flags = 0 data = length 831, hash DDA0685B sample 27: - time = 1134466 + time = 900900 flags = 0 data = length 413, hash 886904C sample 28: - time = 1201198 + time = 967632 flags = 0 data = length 427, hash FC2FA8CC sample 29: - time = 1267932 + time = 1034366 flags = 0 data = length 626, hash DCE82342 track 1: @@ -151,179 +151,179 @@ track 1: flags = 536870913 data = length 21, hash D57A2CCC sample 1: - time = 267890 + time = 133945 flags = 1 data = length 6, hash 336D5819 sample 2: - time = 291110 + time = 157165 flags = 1 data = length 279, hash 6E3E48B0 sample 3: - time = 314330 + time = 180385 flags = 1 data = length 286, hash 5AABFF sample 4: - time = 337550 + time = 203605 flags = 1 data = length 275, hash D3109764 sample 5: - time = 360770 + time = 226825 flags = 1 data = length 284, hash 154B6E9 sample 6: - time = 383990 + time = 250045 flags = 1 data = length 273, hash 40C8A066 sample 7: - time = 407210 + time = 273265 flags = 1 data = length 272, hash 4211880F sample 8: - time = 430430 + time = 296485 flags = 1 data = length 281, hash 1F534130 sample 9: - time = 453650 + time = 319705 flags = 1 data = length 279, hash F5B3EE5F sample 10: - time = 476870 + time = 342925 flags = 1 data = length 282, hash 6CDF1B54 sample 11: - time = 500090 + time = 366145 flags = 1 data = length 291, hash 6EC03046 sample 12: - time = 523310 + time = 389365 flags = 1 data = length 296, hash 9C7F2E6A sample 13: - time = 546530 + time = 412585 flags = 1 data = length 282, hash 584ABD5E sample 14: - time = 569749 + time = 435804 flags = 1 data = length 283, hash 38CB1734 sample 15: - time = 592969 + time = 459024 flags = 1 data = length 274, hash 648EC8BD sample 16: - time = 616189 + time = 482244 flags = 1 data = length 274, hash E8FE0F68 sample 17: - time = 639409 + time = 505464 flags = 1 data = length 277, hash 2E1B8A11 sample 18: - time = 662629 + time = 528684 flags = 1 data = length 282, hash FB6ACCED sample 19: - time = 685849 + time = 551904 flags = 1 data = length 283, hash 152D69D sample 20: - time = 709069 + time = 575124 flags = 1 data = length 274, hash 45F44C4B sample 21: - time = 732289 + time = 598344 flags = 1 data = length 242, hash F9225BB7 sample 22: - time = 755509 + time = 621564 flags = 1 data = length 207, hash F5DFB6B2 sample 23: - time = 778729 + time = 644784 flags = 1 data = length 226, hash 41DC63E1 sample 24: - time = 801949 + time = 668004 flags = 1 data = length 218, hash A82772CF sample 25: - time = 825169 + time = 691224 flags = 1 data = length 223, hash 861AB80 sample 26: - time = 848389 + time = 714444 flags = 1 data = length 220, hash F1CBA15E sample 27: - time = 871609 + time = 737664 flags = 1 data = length 203, hash CB57EEF7 sample 28: - time = 894829 + time = 760884 flags = 1 data = length 206, hash 766F4D9E sample 29: - time = 918049 + time = 784104 flags = 1 data = length 210, hash FE2A2935 sample 30: - time = 941269 + time = 807324 flags = 1 data = length 207, hash A06A178D sample 31: - time = 964489 + time = 830544 flags = 1 data = length 206, hash 1ABD9A5F sample 32: - time = 987709 + time = 853764 flags = 1 data = length 209, hash 69D7E5F3 sample 33: - time = 1010929 + time = 876984 flags = 1 data = length 173, hash 7CE0FDCA sample 34: - time = 1034149 + time = 900204 flags = 1 data = length 208, hash 21D67E09 sample 35: - time = 1057369 + time = 923424 flags = 1 data = length 207, hash C7187D46 sample 36: - time = 1080588 + time = 946643 flags = 1 data = length 180, hash D17CFAF8 sample 37: - time = 1103808 + time = 969863 flags = 1 data = length 206, hash C58FD669 sample 38: - time = 1127028 + time = 993083 flags = 1 data = length 212, hash 27E2F2C4 sample 39: - time = 1150248 + time = 1016303 flags = 1 data = length 190, hash 534CC89E sample 40: - time = 1173468 + time = 1039523 flags = 1 data = length 180, hash 1C58DF95 sample 41: - time = 1196688 + time = 1062743 flags = 1 data = length 213, hash 24FBF10A sample 42: - time = 1219908 + time = 1085963 flags = 1 data = length 186, hash EFC31805 sample 43: - time = 1243128 + time = 1109183 flags = 1 data = length 208, hash 4A050A0D sample 44: - time = 1266348 + time = 1132403 flags = 1 data = length 13, hash 2555A7DC tracksEnded = true diff --git a/testdata/src/test/assets/mp4/sample_partially_fragmented.mp4.unknown_length.dump b/testdata/src/test/assets/mp4/sample_partially_fragmented.mp4.unknown_length.dump index 7ee9341b9c..b3d57a3868 100644 --- a/testdata/src/test/assets/mp4/sample_partially_fragmented.mp4.unknown_length.dump +++ b/testdata/src/test/assets/mp4/sample_partially_fragmented.mp4.unknown_length.dump @@ -31,107 +31,107 @@ track 0: flags = 536870912 data = length 5867, hash 56F9EE87 sample 4: - time = 400398 + time = 166832 flags = 0 data = length 570, hash 984421BD sample 5: - time = 500499 + time = 266933 flags = 0 data = length 3406, hash 9A33201E sample 6: - time = 467132 + time = 233566 flags = 0 data = length 476, hash C59620F3 sample 7: - time = 567232 + time = 333666 flags = 0 data = length 4310, hash 291E6161 sample 8: - time = 533865 + time = 300299 flags = 0 data = length 497, hash 398CBFAA sample 9: - time = 700699 + time = 467133 flags = 0 data = length 4449, hash 322CAA2B sample 10: - time = 633965 + time = 400399 flags = 0 data = length 1076, hash B479B634 sample 11: - time = 600599 + time = 367033 flags = 0 data = length 365, hash 68C7D4C2 sample 12: - time = 667332 + time = 433766 flags = 0 data = length 463, hash A85F9769 sample 13: - time = 834165 + time = 600599 flags = 0 data = length 5339, hash F232195D sample 14: - time = 767432 + time = 533866 flags = 0 data = length 1085, hash 47AFB6FE sample 15: - time = 734066 + time = 500500 flags = 0 data = length 689, hash 3EB753A3 sample 16: - time = 800798 + time = 567232 flags = 0 data = length 516, hash E6DF9C1C sample 17: - time = 967632 + time = 734066 flags = 0 data = length 4899, hash A9A8F4B7 sample 18: - time = 900899 + time = 667333 flags = 0 data = length 963, hash 684782FB sample 19: - time = 867532 + time = 633966 flags = 0 data = length 625, hash ED1C8EF1 sample 20: - time = 934265 + time = 700699 flags = 0 data = length 492, hash E6E066EA sample 21: - time = 1101099 + time = 867533 flags = 0 data = length 2973, hash A3C54C3B sample 22: - time = 1034365 + time = 800799 flags = 0 data = length 833, hash 41CA807D sample 23: - time = 1000999 + time = 767433 flags = 0 data = length 516, hash 5B21BB11 sample 24: - time = 1067732 + time = 834166 flags = 0 data = length 384, hash A0E8FA50 sample 25: - time = 1234565 + time = 1000999 flags = 0 data = length 1450, hash 92741C3B sample 26: - time = 1167832 + time = 934266 flags = 0 data = length 831, hash DDA0685B sample 27: - time = 1134466 + time = 900900 flags = 0 data = length 413, hash 886904C sample 28: - time = 1201198 + time = 967632 flags = 0 data = length 427, hash FC2FA8CC sample 29: - time = 1267932 + time = 1034366 flags = 0 data = length 626, hash DCE82342 track 1: @@ -151,179 +151,179 @@ track 1: flags = 536870913 data = length 21, hash D57A2CCC sample 1: - time = 267890 + time = 133945 flags = 1 data = length 6, hash 336D5819 sample 2: - time = 291110 + time = 157165 flags = 1 data = length 279, hash 6E3E48B0 sample 3: - time = 314330 + time = 180385 flags = 1 data = length 286, hash 5AABFF sample 4: - time = 337550 + time = 203605 flags = 1 data = length 275, hash D3109764 sample 5: - time = 360770 + time = 226825 flags = 1 data = length 284, hash 154B6E9 sample 6: - time = 383990 + time = 250045 flags = 1 data = length 273, hash 40C8A066 sample 7: - time = 407210 + time = 273265 flags = 1 data = length 272, hash 4211880F sample 8: - time = 430430 + time = 296485 flags = 1 data = length 281, hash 1F534130 sample 9: - time = 453650 + time = 319705 flags = 1 data = length 279, hash F5B3EE5F sample 10: - time = 476870 + time = 342925 flags = 1 data = length 282, hash 6CDF1B54 sample 11: - time = 500090 + time = 366145 flags = 1 data = length 291, hash 6EC03046 sample 12: - time = 523310 + time = 389365 flags = 1 data = length 296, hash 9C7F2E6A sample 13: - time = 546530 + time = 412585 flags = 1 data = length 282, hash 584ABD5E sample 14: - time = 569749 + time = 435804 flags = 1 data = length 283, hash 38CB1734 sample 15: - time = 592969 + time = 459024 flags = 1 data = length 274, hash 648EC8BD sample 16: - time = 616189 + time = 482244 flags = 1 data = length 274, hash E8FE0F68 sample 17: - time = 639409 + time = 505464 flags = 1 data = length 277, hash 2E1B8A11 sample 18: - time = 662629 + time = 528684 flags = 1 data = length 282, hash FB6ACCED sample 19: - time = 685849 + time = 551904 flags = 1 data = length 283, hash 152D69D sample 20: - time = 709069 + time = 575124 flags = 1 data = length 274, hash 45F44C4B sample 21: - time = 732289 + time = 598344 flags = 1 data = length 242, hash F9225BB7 sample 22: - time = 755509 + time = 621564 flags = 1 data = length 207, hash F5DFB6B2 sample 23: - time = 778729 + time = 644784 flags = 1 data = length 226, hash 41DC63E1 sample 24: - time = 801949 + time = 668004 flags = 1 data = length 218, hash A82772CF sample 25: - time = 825169 + time = 691224 flags = 1 data = length 223, hash 861AB80 sample 26: - time = 848389 + time = 714444 flags = 1 data = length 220, hash F1CBA15E sample 27: - time = 871609 + time = 737664 flags = 1 data = length 203, hash CB57EEF7 sample 28: - time = 894829 + time = 760884 flags = 1 data = length 206, hash 766F4D9E sample 29: - time = 918049 + time = 784104 flags = 1 data = length 210, hash FE2A2935 sample 30: - time = 941269 + time = 807324 flags = 1 data = length 207, hash A06A178D sample 31: - time = 964489 + time = 830544 flags = 1 data = length 206, hash 1ABD9A5F sample 32: - time = 987709 + time = 853764 flags = 1 data = length 209, hash 69D7E5F3 sample 33: - time = 1010929 + time = 876984 flags = 1 data = length 173, hash 7CE0FDCA sample 34: - time = 1034149 + time = 900204 flags = 1 data = length 208, hash 21D67E09 sample 35: - time = 1057369 + time = 923424 flags = 1 data = length 207, hash C7187D46 sample 36: - time = 1080588 + time = 946643 flags = 1 data = length 180, hash D17CFAF8 sample 37: - time = 1103808 + time = 969863 flags = 1 data = length 206, hash C58FD669 sample 38: - time = 1127028 + time = 993083 flags = 1 data = length 212, hash 27E2F2C4 sample 39: - time = 1150248 + time = 1016303 flags = 1 data = length 190, hash 534CC89E sample 40: - time = 1173468 + time = 1039523 flags = 1 data = length 180, hash 1C58DF95 sample 41: - time = 1196688 + time = 1062743 flags = 1 data = length 213, hash 24FBF10A sample 42: - time = 1219908 + time = 1085963 flags = 1 data = length 186, hash EFC31805 sample 43: - time = 1243128 + time = 1109183 flags = 1 data = length 208, hash 4A050A0D sample 44: - time = 1266348 + time = 1132403 flags = 1 data = length 13, hash 2555A7DC tracksEnded = true