1
1
import { convertAudioOrVideoSampleToWebCodecsTimestamps } from '../../../convert-audio-or-video-sample' ;
2
2
import { getHasTracks } from '../../../get-tracks' ;
3
+ import { Log } from '../../../log' ;
3
4
import type { FetchMoreData , Skip } from '../../../skip' ;
4
5
import { makeFetchMoreData , makeSkip } from '../../../skip' ;
5
6
import type { FlatSample } from '../../../state/iso-base-media/cached-sample-positions' ;
6
7
import { calculateFlatSamples } from '../../../state/iso-base-media/cached-sample-positions' ;
8
+ import { getLastMoofBox } from '../../../state/iso-base-media/last-moof-box' ;
7
9
import { maySkipVideoData } from '../../../state/may-skip-video-data' ;
8
10
import type { ParserState } from '../../../state/parser-state' ;
9
11
import { getCurrentMediaSection } from '../../../state/video-section' ;
@@ -26,6 +28,22 @@ export const parseMdatSection = async (
26
28
27
29
// don't need mdat at all, can skip
28
30
if ( maySkipVideoData ( { state} ) ) {
31
+ const mfra = state . iso . mfra . getIfAlreadyLoaded ( ) ;
32
+
33
+ if ( mfra ) {
34
+ const lastMoof = getLastMoofBox ( mfra ) ;
35
+ if ( lastMoof && lastMoof > endOfMdat ) {
36
+ Log . verbose (
37
+ state . logLevel ,
38
+ 'Skipping to last moof' ,
39
+ lastMoof ,
40
+ 'end of mdat' ,
41
+ endOfMdat ,
42
+ ) ;
43
+ return makeSkip ( lastMoof ) ;
44
+ }
45
+ }
46
+
29
47
return makeSkip ( endOfMdat ) ;
30
48
}
31
49
@@ -47,7 +65,10 @@ export const parseMdatSection = async (
47
65
}
48
66
49
67
if ( ! state . iso . flatSamples . getSamples ( mediaSection . start ) ) {
50
- const flattedSamples = calculateFlatSamples ( state ) ;
68
+ const flattedSamples = calculateFlatSamples ( {
69
+ state,
70
+ mediaSectionStart : mediaSection . start ,
71
+ } ) ;
51
72
52
73
const calcedJumpMarks = calculateJumpMarks ( flattedSamples , endOfMdat ) ;
53
74
state . iso . flatSamples . setJumpMarks ( mediaSection . start , calcedJumpMarks ) ;
@@ -66,7 +87,6 @@ export const parseMdatSection = async (
66
87
const samplesWithIndex = flatSamples . find ( ( sample ) => {
67
88
return sample . samplePosition . offset === iterator . counter . getOffset ( ) ;
68
89
} ) ;
69
-
70
90
if ( ! samplesWithIndex ) {
71
91
// There are various reasons why in mdat we find weird stuff:
72
92
// - iphonevideo.hevc has a fake hoov atom which is not mapped
@@ -83,6 +103,14 @@ export const parseMdatSection = async (
83
103
84
104
// guess we reached the end!
85
105
// iphonevideo.mov has extra padding here, so let's make sure to jump ahead
106
+
107
+ Log . verbose (
108
+ state . logLevel ,
109
+ 'Could not find sample at offset' ,
110
+ iterator . counter . getOffset ( ) ,
111
+ 'skipping to end of mdat' ,
112
+ ) ;
113
+
86
114
return makeSkip ( endOfMdat ) ;
87
115
}
88
116
@@ -92,6 +120,14 @@ export const parseMdatSection = async (
92
120
samplesWithIndex . samplePosition . size >
93
121
state . contentLength
94
122
) {
123
+ Log . verbose (
124
+ state . logLevel ,
125
+ "Sample is beyond the end of the file. Don't process it." ,
126
+ samplesWithIndex . samplePosition . offset +
127
+ samplesWithIndex . samplePosition . size ,
128
+ endOfMdat ,
129
+ ) ;
130
+
95
131
return makeSkip ( endOfMdat ) ;
96
132
}
97
133
@@ -138,6 +174,7 @@ export const parseMdatSection = async (
138
174
// https://github.com/remotion-dev/remotion/issues/4680
139
175
// In Chrome, we may not treat recovery points as keyframes
140
176
// otherwise "a keyframe is required after flushing"
177
+
141
178
const nalUnitType = bytes [ 4 ] & 0b00011111 ;
142
179
let isRecoveryPoint = false ;
143
180
// SEI (Supplemental enhancement information)
@@ -169,6 +206,12 @@ export const parseMdatSection = async (
169
206
170
207
const jump = jumpMarks . find ( ( j ) => j . afterSampleWithOffset === offset ) ;
171
208
if ( jump ) {
209
+ Log . verbose (
210
+ state . logLevel ,
211
+ 'Found jump mark' ,
212
+ jump . jumpToOffset ,
213
+ 'skipping to jump mark' ,
214
+ ) ;
172
215
return makeSkip ( jump . jumpToOffset ) ;
173
216
}
174
217
0 commit comments