Closed jleclanche closed 5 years ago
Starting at esds
, here's a dump of the chunk of the (good) file:
65 73 64 73 00 00 00 00 03 80 80 80 1B 00 02 00 04 80 80 80 0D 6B 15 00 00 00 00 00 BB 80 00 00 7C FE 06 80 80 80 01 02 00 09 56 68 73 74 74 73 00 00 00 00 00 01 2A CB 00 00 00 02 00 00 04 80 00 00 00 01 00 00 04 73 00 00 00 01 00 00 04 72 00 00 00 01 00 00 04 6E 00 00 00 01 00 00 04 5C 00 00 00 01 00 00 04 64 00 00 00 01 00 00 04 5F 00 00 00 02 00 00 04 5C 00 00 00 01 00 00 04 59 00 00 00 01 00 00 04 5B 00 00 00 02 00 00 04 5C 00 00 00 01 00 00 04 5D 00 00 00 01 00 00 04 60 00 00 00 01 00 00 04 62 00 00 00 01 00 00 04 63 00 00 00 01 00 00 04 6C 00 00 00 01 00 00 04 70 00 00 00 01 00 00 04 74 00 00 00 01 00 00 04 75 00 00 00 01 00 00 04 79 00 00 00 01 00 00 04 7C 00 00 00 01 00 00 04 7D 00
You can just comment out the section which creates the esds
decoder. This is codec.cpp:56-63.
But since libavcodec has trouble decoding your audio packet(s) the payload might be corrupt.
The other possibility is that untrunc did choose the wrong codec. If you upload the file somewhere I might take a look.
The good mp4 file is played correctly by ffmpeg / mpv. I've asked if I can upload the file but haven't gotten a response yet.
I can get you non-data chunks of the file for now if that helps at all.
I get a floating point exception if I comment out that portion of the code.
Info: reading ok3.mp4
Info: parsing healthy moov atom ...
start_ = 0
requests: 4 at offset : 0
length_ = 32
requests: 4 at offset : 4
name_ = ftyp
requests: 24 at offset : 8
start_ = 32
requests: 4 at offset : 32
length_ = 8
requests: 4 at offset : 36
name_ = free
requests: 0 at offset : 40
start_ = 40
requests: 4 at offset : 40
length_ = 505803065
requests: 4 at offset : 44
name_ = mdat
requests: 505803057 at offset : 48
reallocating the file buffer
start_ = 505803105
requests: 4 at offset : 0
length_ = 3126351
requests: 4 at offset : 4
name_ = moov
start_ = 505803113
requests: 4 at offset : 8
length_ = 108
requests: 4 at offset : 12
name_ = mvhd
requests: 100 at offset : 16
start_ = 505803221
requests: 4 at offset : 116
length_ = 1369773
requests: 4 at offset : 120
name_ = trak
start_ = 505803229
requests: 4 at offset : 124
length_ = 92
requests: 4 at offset : 128
name_ = tkhd
requests: 84 at offset : 132
start_ = 505803321
requests: 4 at offset : 216
length_ = 36
requests: 4 at offset : 220
name_ = edts
start_ = 505803329
requests: 4 at offset : 224
length_ = 28
requests: 4 at offset : 228
name_ = elst
requests: 20 at offset : 232
start_ = 505803357
requests: 4 at offset : 252
length_ = 1369637
requests: 4 at offset : 256
name_ = mdia
start_ = 505803365
requests: 4 at offset : 260
length_ = 32
requests: 4 at offset : 264
name_ = mdhd
requests: 24 at offset : 268
start_ = 505803397
requests: 4 at offset : 292
length_ = 45
requests: 4 at offset : 296
name_ = hdlr
requests: 37 at offset : 300
start_ = 505803442
requests: 4 at offset : 337
length_ = 1369552
requests: 4 at offset : 341
name_ = minf
start_ = 505803450
requests: 4 at offset : 345
length_ = 20
requests: 4 at offset : 349
name_ = vmhd
requests: 12 at offset : 353
start_ = 505803470
requests: 4 at offset : 365
length_ = 36
requests: 4 at offset : 369
name_ = dinf
start_ = 505803478
requests: 4 at offset : 373
length_ = 28
requests: 4 at offset : 377
name_ = dref
requests: 20 at offset : 381
start_ = 505803506
requests: 4 at offset : 401
length_ = 1369488
requests: 4 at offset : 405
name_ = stbl
start_ = 505803514
requests: 4 at offset : 409
length_ = 152
requests: 4 at offset : 413
name_ = stsd
requests: 144 at offset : 417
start_ = 505803666
requests: 4 at offset : 561
length_ = 24
requests: 4 at offset : 565
name_ = stts
requests: 16 at offset : 569
start_ = 505803690
requests: 4 at offset : 585
length_ = 1392
requests: 4 at offset : 589
name_ = stss
requests: 1384 at offset : 593
start_ = 505805082
requests: 4 at offset : 1977
length_ = 681384
requests: 4 at offset : 1981
name_ = ctts
requests: 681376 at offset : 1985
start_ = 506486466
requests: 4 at offset : 683361
length_ = 40
requests: 4 at offset : 683365
name_ = stsc
requests: 32 at offset : 683369
start_ = 506486506
requests: 4 at offset : 683401
length_ = 343248
requests: 4 at offset : 683405
name_ = stsz
requests: 343240 at offset : 683409
start_ = 506829754
requests: 4 at offset : 1026649
length_ = 343240
requests: 4 at offset : 1026653
name_ = stco
requests: 343232 at offset : 1026657
start_ = 507172994
requests: 4 at offset : 1369889
length_ = 1756365
requests: 4 at offset : 1369893
name_ = trak
start_ = 507173002
requests: 4 at offset : 1369897
length_ = 92
requests: 4 at offset : 1369901
name_ = tkhd
requests: 84 at offset : 1369905
start_ = 507173094
requests: 4 at offset : 1369989
length_ = 36
requests: 4 at offset : 1369993
name_ = edts
start_ = 507173102
requests: 4 at offset : 1369997
length_ = 28
requests: 4 at offset : 1370001
name_ = elst
requests: 20 at offset : 1370005
start_ = 507173130
requests: 4 at offset : 1370025
length_ = 1756229
requests: 4 at offset : 1370029
name_ = mdia
start_ = 507173138
requests: 4 at offset : 1370033
length_ = 32
requests: 4 at offset : 1370037
name_ = mdhd
requests: 24 at offset : 1370041
start_ = 507173170
requests: 4 at offset : 1370065
length_ = 45
requests: 4 at offset : 1370069
name_ = hdlr
requests: 37 at offset : 1370073
start_ = 507173215
requests: 4 at offset : 1370110
length_ = 1756144
requests: 4 at offset : 1370114
name_ = minf
start_ = 507173223
requests: 4 at offset : 1370118
length_ = 16
requests: 4 at offset : 1370122
name_ = smhd
requests: 8 at offset : 1370126
start_ = 507173239
requests: 4 at offset : 1370134
length_ = 36
requests: 4 at offset : 1370138
name_ = dinf
start_ = 507173247
requests: 4 at offset : 1370142
length_ = 28
requests: 4 at offset : 1370146
name_ = dref
requests: 20 at offset : 1370150
start_ = 507173275
requests: 4 at offset : 1370170
length_ = 1756084
requests: 4 at offset : 1370174
name_ = stbl
start_ = 507173283
requests: 4 at offset : 1370178
length_ = 96
requests: 4 at offset : 1370182
name_ = stsd
requests: 88 at offset : 1370186
start_ = 507173379
requests: 4 at offset : 1370274
length_ = 611944
requests: 4 at offset : 1370278
name_ = stts
requests: 611936 at offset : 1370282
start_ = 507785323
requests: 4 at offset : 1982218
length_ = 800776
requests: 4 at offset : 1982222
name_ = stsc
requests: 800768 at offset : 1982226
start_ = 508586099
requests: 4 at offset : 2782994
length_ = 20
requests: 4 at offset : 2782998
name_ = stsz
requests: 12 at offset : 2783002
start_ = 508586119
requests: 4 at offset : 2783014
length_ = 343240
requests: 4 at offset : 2783018
name_ = stco
requests: 343232 at offset : 2783022
start_ = 508929359
requests: 4 at offset : 3126254
length_ = 97
requests: 4 at offset : 3126258
name_ = udta
requests: 89 at offset : 3126262
Composition time offset atom found. Out of order samples possible.
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'ok3.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf54.6.100
Duration: 00:47:40.23, start: 0.000000, bitrate: 1423 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1024x576, 1382 kb/s, 30 fps, 30 tbr, 30 tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: mp3 (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 31 kb/s (default)
Metadata:
handler_name : SoundHandler
found avcC after: 102
remaining len:50
parsing avcC ...
len_sps: 25
decoding SPS ...
log2_max_frame_num: 4
Info: avcC got decoded
Info: parsing mdat from truncated file ...
start_ = 0
requests: 4 at offset : 0
length_ = 32
requests: 4 at offset : 4
name_ = ftyp
start_ = 32
requests: 4 at offset : 32
length_ = 8
requests: 4 at offset : 36
name_ = free
start_ = 40
requests: 4 at offset : 40
length_ = 0
requests: 4 at offset : 44
name_ = mdat
mdat->contentSize = 426751584
(reading element from mdat)
Offset: 0 8d020000 ffff0506
Track codec: mp4a
Failure because of NULL header
Track codec: avc1
avc1: Match with 0 header
sps_info (before): 1 4 5 0
sps_info (after): 1 4 5 0
---
Length: 657
Ref idc: 0
Nal type: 6
Partial avc1-length: 657
---
Length: 31889
Ref idc: 3
Nal type: 5
First mb: 0
pic paramter set id: 0
Frame num: 0
Poc lsb: 0
Partial avc1-length: 32546
---
Length: 14266
Ref idc: 2
Nal type: 1
First mb: 0
pic paramter set id: 0
Frame num: 1
Poc lsb: 2
Different frame number
frame-length: 32546
- found as avc1
(reading element from mdat)
Offset: 32546 b6370000 6c229a41
Track codec: mp4a
Failure because of NULL header
Track codec: avc1
avc1: Match with 0 header
---
Length: 14266
Ref idc: 2
Nal type: 1
First mb: 0
pic paramter set id: 0
Frame num: 1
Poc lsb: 2
Partial avc1-length: 14266
---
First byte expected 0
failed parsing nal-header
frame-length: 14266
- found as avc1
(reading element from mdat)
Offset: 46812 64c4fbff ddf10000
Track codec: mp4a
Success for no particular reason....
[mp3float @ 0x55c2c4f3b900] Multiple frames in a packet.
nb_samples: 1152
frame-length: 672
- found as mp4a
(reading element from mdat)
Offset: 47484 870f0000 79419e01
Track codec: mp4a
Failure because of NULL header
Track codec: avc1
avc1: Match with 0 header
---
Length: 3979
Ref idc: 0
Nal type: 1
First mb: 0
pic paramter set id: 0
Frame num: 2
Poc lsb: 1
Partial avc1-length: 3979
---
First byte expected 0
failed parsing nal-header
frame-length: 3979
- found as avc1
(reading element from mdat)
Offset: 51463 6494fbff f9f300df
Track codec: mp4a
Success for no particular reason....
[mp3float @ 0x55c2c4f3b900] Got unexpected packet size after a partial decode
nb_samples: 0
frame-length: -22
Error: Invalid length: -22. Wrong match in track: 0
Track codec: avc1
avc1: no match because of nal type: 31
Error: unable to find correct codec -> premature end
mdat->file_end: 51511
Info: Found 4 packets ( mp4a: 1 avc1: 3 avc1-keyframes: 1 )
Info: Duration of mp4a: 24ms (24 ms)
zsh: floating point exception (core dumped) ./untrunc -vv ok3.mp4 bad.mp4
gdb:
Program received signal SIGFPE, Arithmetic exception.
0x00005555555689b9 in Mp4::saveVideo(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
(gdb) bt
#0 0x00005555555689b9 in Mp4::saveVideo(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
#1 0x000055555556b545 in Mp4::repair(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
#2 0x000055555555df97 in main ()
Removing this piece of code gets past the float exc:
int hour, min, sec, msec;
int bmsec = track.duration_ / (track.timescale_ / 1000);
auto x = div(bmsec, 1000); msec = x.rem; sec = x.quot;
x = div(sec, 60); sec = x.rem; min = x.quot;
x = div(min, 60); min = x.rem; hour = x.quot;
string s_msec = (msec?to_string(msec)+"ms ":"");
string s_sec = (sec?to_string(sec)+"s ":"");
string s_min = (min?to_string(min)+"min ":"");
string s_hour = (hour?to_string(hour)+"h ":"");
logg(I, "Duration of ", track.codec_.name_, ": ", s_hour, s_min, s_sec, s_msec, " (", bmsec, " ms)\n");
Unfortunately, the fixed file is still 2 frames, just like in https://github.com/ponchio/untrunc/issues/140 :(
There is a -a
flag. It shows you weither untrunc would be able to repair the good file, and if not why not.
Do you have an idea why this code triggered a float exception? Devided by zero?
Possibly .. not sure, sounds like the duration might be wrong
I also see this:
avc1: no match because of nal type: 31
Error: unable to find correct codec -> premature end
mdat->file_end: 426751143
Info: Found 4 packets ( mp4a: 1 avc1: 3 avc1-keyframes: 1 )
Info: saving bad.mp4_fixed.mp4
Relevant code:
//TODO use the first byte of the nal: forbidden bit and type!
int nal_type = (start[4] & 0x1f);
//the other values are really uncommon on cameras...
if(nal_type > 21) {
// if(nal_type != 1 && nal_type != 5 && nal_type != 6 && nal_type != 7 &&
// nal_type != 8 && nal_type != 9 && nal_type != 10 && nal_type != 11 && nal_type != 12) {
logg(V, "avc1: no match because of nal type: ", nal_type, '\n');
return false;
}
//if nal is equal 7, the other fragments (starting with nal type 7)
//should be part of the same packet
//(we cannot recover time information, remember)
if(start[0] == 0) {
logg(V, "avc1: Match with 0 header\n");
return true;
}
logg(V, "avc1: failed for not particular reason\n");
return false;
Could have to do with it? It's finding 4 packets, which is an improvement over the 2 packets it was finding in the upstream version.
Running with -a over the good file, I get a bunch of output and then:
Track 1
Track codec: mp4a
Keyframes 0
0 Size: 96 offset 57678 begin: fffb1464 ff000 end: 55555555
[mp3float @ 0x5606dc933900] Multiple frames in a packet.
Length: 96 true length: 96
1 Size: 96 offset 58121 begin: fffb1464 1e0ff000 end: 55555555
[mp3float @ 0x5606dc933900] Got unexpected packet size after a partial decode
Length: -22 true length: 96
Here's the successful output past the floating point exception btw.
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'ok.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf54.6.100
Duration: 00:20:08.37, start: 0.000000, bitrate: 2680 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1024x576, 2585 kb/s, 30 fps, 30 tbr, 30 tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: mp3 (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 87 kb/s (default)
Metadata:
handler_name : SoundHandler
found avcC after: 102
remaining len:50
parsing avcC ...
len_sps: 25
decoding SPS ...
log2_max_frame_num: 4
Info: avcC got decoded
Info: parsing mdat from truncated file ...
start_ = 0
requests: 4 at offset : 0
length_ = 32
requests: 4 at offset : 4
name_ = ftyp
start_ = 32
requests: 4 at offset : 32
length_ = 8
requests: 4 at offset : 36
name_ = free
start_ = 40
requests: 4 at offset : 40
length_ = 0
requests: 4 at offset : 44
name_ = mdat
mdat->contentSize = 426751584
(reading element from mdat)
Offset: 0 8d020000 ffff0506
Track codec: mp4a
Failure because of NULL header
Track codec: avc1
avc1: Match with 0 header
sps_info (before): 1 4 5 0
sps_info (after): 1 4 5 0
---
Length: 657
Ref idc: 0
Nal type: 6
Partial avc1-length: 657
---
Length: 31889
Ref idc: 3
Nal type: 5
First mb: 0
pic paramter set id: 0
Frame num: 0
Poc lsb: 0
Partial avc1-length: 32546
---
Length: 14266
Ref idc: 2
Nal type: 1
First mb: 0
pic paramter set id: 0
Frame num: 1
Poc lsb: 2
Different frame number
frame-length: 32546
- found as avc1
(reading element from mdat)
Offset: 32546 b6370000 6c229a41
Track codec: mp4a
Failure because of NULL header
Track codec: avc1
avc1: Match with 0 header
---
Length: 14266
Ref idc: 2
Nal type: 1
First mb: 0
pic paramter set id: 0
Frame num: 1
Poc lsb: 2
Partial avc1-length: 14266
---
First byte expected 0
failed parsing nal-header
frame-length: 14266
- found as avc1
(reading element from mdat)
Offset: 46812 64c4fbff ddf10000
Track codec: mp4a
Success for no particular reason....
[mp3float @ 0x564dfe197380] Multiple frames in a packet.
nb_samples: 1152
frame-length: 672
- found as mp4a
(reading element from mdat)
Offset: 47484 870f0000 79419e01
Track codec: mp4a
Failure because of NULL header
Track codec: avc1
avc1: Match with 0 header
---
Length: 3979
Ref idc: 0
Nal type: 1
First mb: 0
pic paramter set id: 0
Frame num: 2
Poc lsb: 1
Partial avc1-length: 3979
---
First byte expected 0
failed parsing nal-header
frame-length: 3979
- found as avc1
(reading element from mdat)
Offset: 51463 6494fbff f9f300df
Track codec: mp4a
Success for no particular reason....
[mp3float @ 0x564dfe197380] Got unexpected packet size after a partial decode
nb_samples: 0
frame-length: -22
Error: Invalid length: -22. Wrong match in track: 0
Track codec: avc1
avc1: failed for not particular reason
Error: unable to find correct codec -> premature end
mdat->file_end: 51511
Info: Found 4 packets ( mp4a: 1 avc1: 3 avc1-keyframes: 1 )
Info: saving bad.mp4_fixed.mp4
requests: 51463 at offset : 48
This looks weird:
frame-length: -22
Error: Invalid length: -22. Wrong match in track: 0
I made some commits regarding Mp4::analyze
to the branch 'better_analyze'.
It is interesting how your packets always end with 55555555
. I dont think this is normal.
You could try to just make Codec::getLength()
return 96 whenever the codec is not avc1
. However it is new to me that audio packets have constant size.
It's dumping a ton of these:
(140) Size: 96 offset 742899 begin: fffb1464 e18ff000 end: 55555555
detected size: -558323010 true: 96
detected duration: 0 true: 1158
detected size or duration are wrong!
Getting another floating point exception, again duration-related:
Program received signal SIGFPE, Arithmetic exception.
0x000055555556d93c in Track::getDurationInMs() ()
(gdb) bt
#0 0x000055555556d93c in Track::getDurationInMs() ()
#1 0x000055555556ce63 in Mp4::repair(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
#2 0x000055555556954f in main ()
Ok, this makes sense, duration_ is zero. You should try to return 96 as your packet size if codec == mp4a/mp3. I made a new commit in case you also want to analyze avc1 without the "duration = 0" message all the time.
Yeah I just tried that. I had to change getDurationInMs() but it generates a 3.7M file with only a single readable frame. Let me see if I can play with it some more.
What should getDurationInMs() return?
mpv output for the 3.7M file: http://dpaste.com/3225SQ2.txt
I then removed the sound track using ffmpeg -i bad.mp4_fixed.mp4 -c copy -an nosound.mp4
. here's the mpv and vlc outputs:
http://dpaste.com/30XVA5Q.txt
In codec.cpp:216 set duration
to n, where n is the correct number of frames as reported by untrunc -i
in the "sample to decode time" aka stts
Atom section. Usually n is constant.
------stts "sample to decode time" [507173379, 611944]
Entries: 76491
samples: 2 for: 1152
samples: 1 for: 1139
samples: 1 for: 1138
samples: 1 for: 1134
samples: 1 for: 1116
samples: 1 for: 1124
samples: 1 for: 1119
samples: 2 for: 1116
samples: 1 for: 1113
samples: 1 for: 1115
samples: 2 for: 1116
samples: 1 for: 1117
samples: 1 for: 1120
samples: 1 for: 1122
samples: 1 for: 1123
samples: 1 for: 1132
samples: 1 for: 1136
samples: 1 for: 1140
samples: 1 for: 1141
samples: 1 for: 1145
samples: 1 for: 1148
samples: 1 for: 1149
samples: 1 for: 1152
samples: 1 for: 1154
samples: 1 for: 1155
samples: 1 for: 1156
samples: 1 for: 1158
samples: 1 for: 1161
samples: 3 for: 1160
samples: 1 for: 1161
That'd be eg. 1152
?
Edit: Still getting the getDurationInMs() exception if I set it to 1152.
Compile with '-g' and check with gdb. What does times_
look like in Track::fixTimes
?
Is this what you want? http://dpaste.com/26K4T5Q
I wonder why for mp4a times[i] is not constant, since you set it to 1152, did you? And I wonder why for avc1 times[i] = 1 ... Is that the output from the corrupt file? It says it found 12333 mp4a packets but only 22 avc1. So the codec matching seems to be wrong.
No this is after resetting the change to 1152. With the change it's constant.
This is the output from ./untrunc -vv ok.mp4 bad.mp4
.
BTW, it's very possible the audio is borked, but the file itself is supposed to be a ~40 min video so it sounds like 22 avc1 packets is not enough?
Yes, that is why I say the codec matching seems to fail. You could try to figure out why, using 'untrunc -a'. And paste the output of 'untrunc -a -n' somewhere. Use the master branch.
First 12M of ./untrunc -vv -a -n ok.mp4 bad.mp4 &> out
... afterwards it gets very slow and I don't know how long it'll take to finish.
Hmm... There it looks fine. Where is the audio track comming from? Try to run it again without '-v'. What do you mean with "gets very slow"? It doesn't print anything?
Have you tried to debug the floating point exception you said is related to the duration?
Not particularly. timescale_ is 48000 and duration looks ok too, so I don't know why it's throwing a fit.
And yes it does print but like 1-2 offset every second or so. It's the same without -vv, just with less text.
...
(318) Size: 336 offset 3028811 begin: fffb8464 fa00f531 end: 54422119
detected size: -558323010 true: 336
detected duration: 0 true: 1147
detected size or duration are wrong!
(319) Size: 336 offset 3029653 begin: fffb8464 ed00f4ef end: 44f7cd20
detected size: -558323010 true: 336
detected duration: 0 true: 1148
detected size or duration are wrong!
(320) Size: 384 offset 3029989 begin: fffb9464 e800f4f5 end: c3b321a8
^C
These definitely look wrong.
Track 1 codec: mp4a
(0) Size: 96 offset 49292 begin: fffb1464 000ff000 end: 04c07a60
[mp3float @ 0x55b4f605ae80] Multiple frames in a packet.
detected size: 96 true: 96
detected duration: 1152 true: 1152
(1) Size: 96 offset 49776 begin: fffb1464 1e0ff000 end: 689f8c50
[mp3float @ 0x55b4f605ae80] Got unexpected packet size after a partial decode
detected size: -22 true: 96
detected duration: 0 true: 1147
detected size or duration are wrong!
(2) Size: 96 offset 49872 begin: fffb1464 3c0ff000 end: 3b2f831a
[mp3float @ 0x55b4f605ae80] Header missing
detected size: -1094995529 true: 96
detected duration: 0 true: 1149
detected size or duration are wrong!
(3) Size: 576 offset 73716 begin: fffbb464 5a000000 end: 3ac88008
detected size: -558323010 true: 576
detected duration: 0 true: 1145
detected size or duration are wrong!
I don't really know how to use gdb, but if these are the actual values in the bt then that would cause a division by zero (30 / 1000 is 0 as int):
(gdb) p duration_
$22 = 3
(gdb) p timescale_
$23 = 30
Yes, but you can make getDurationInMs
return anything you want. This is just a symptom of a deeper issue. Again, I could help you if you'd upload the file somewhere. Maybe you can create a similar file where you dont have to ask for permission.
Does 3fdd868 fix the 'untrunc -a -n' getting slow issues?
In case you didn't know yet: gdb has a tui wich you can access by typing '-'. Use 'up'/'down' to go up/down the stackframe, aka. function calls. Try out 'info [local|args|...]'. For more check this
closing because inactive
Sorry for being inactive. This year has been busy. I'm catching up on old emails.
I gave untrunc another shot, looks like it got a lot of improvements. Sadly I'm still hitting the getDurationInMs issue:
…
Info: version '7f0a58c' using ffmpeg 'n4.2.1'
Info: reading files/ok.mp4
Info: parsing healthy moov atom ...
Composition time offset atom found. Out of order samples possible.
Info: reading mdat from truncated file ...
Info: Muted ffmpeg to reduce redundant warnings/errors. Use '-v' to see them.
Info: Found 128214 packets ( mp4a: 74541 avc1: 53673 avc1-keyframes: 217 )
Program received signal SIGFPE, Arithmetic exception.
0x000055555558da58 in HasHeaderAtom::getDurationInMs (this=0x55555565a270) at src/common.cpp:267
267 return duration_ / (timescale_ / 1000);
(gdb) bt
#0 0x000055555558da58 in HasHeaderAtom::getDurationInMs (this=0x55555565a270) at src/common.cpp:267
#1 0x000055555559216e in Mp4::chkStrechFactor (this=0x7fffffffd790) at src/mp4.cpp:222
#2 0x0000555555592677 in Mp4::saveVideo (this=0x7fffffffd790, filename="files/bad.mp4_fixed.mp4") at src/mp4.cpp:277
#3 0x0000555555599fee in Mp4::repair (this=0x7fffffffd790, filename="files/bad.mp4") at src/mp4.cpp:1269
#4 0x00005555555b40ab in main (argc=3, argv=0x7fffffffda28) at src/main.cpp:169
(gdb) p duration_
$1 = 53673
(gdb) p timescale_
$2 = 30
(timescale_ / 1000
is 0, hence the crash)
And now, here's the great news: Fixing that by returning 0 gets me a fixed video! Wow. Holy shit. The audio works, too.
Thank you. I'll PR the result.
Thank you, but timescale_ < 0
does not imply that the track has 0ms length.
I guess ce47b5a47 fixes this too?
I can't check right now, should be easy enough to test as you have the values now. But timescale_
was not < 0, it was 30, which meant timescale_ / 1000
was 0, which meant you were doing duration_ / 0
, which is a division by zero.
Sorry, I meant timescale_ < 1000
.
Your patch makes 30 / (30 / 1000) be 0, when it should be 1000 instead.
Oh I see. Should I early-return 1000 in my patch instead then? I think yours may still fail if timescale_
is 0.
Since timescale_
is read from the healthy file, and timescale_ == 0
is (AFAIK) an invalid value, we can assert that timescale_ > 0
.
I realized that casting to double is not needed, as multiplying with 1000 instead of dividing the dividend does the same thing. Multiplication should be done first though, for the sake of precision.
I have a file which is failing this assert. It goes straight to tag == 6.
If I just remove the assert I then get this: