Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid length -1 / unable to find correct codec #4

Closed
golimarrrr opened this issue Jul 9, 2018 · 9 comments
Closed

Invalid length -1 / unable to find correct codec #4

golimarrrr opened this issue Jul 9, 2018 · 9 comments

Comments

@golimarrrr
Copy link

I have a broken .3gp audio file whose codec is (I think) amr_wb. I tried to run untrunc with the broken file against two different correct files from the same phone (one shorter and another longer) and I get a 670-byte output file only.

Info: reading /tmp/ok2.3gp
Info: parsing healthy moov atom ... 
Info: parsing mdat from truncated file ... 
Error: Invalid length. -1. Wrong match in track: 0
Error: unable to find correct codec -> premature end
Info: Found 0 packets ( sawb: 0 )
Info: Duration of sawb = 0s
Info: saving /tmp/mal.3gp_fixed.mp4

I tried with the standard libav package and also compiling the latest libav from source, selecting both the default 'amr' codec and also the 'opencore amr' codec, but the output is the same.
Are audio-only files also supported?

@anthwlock
Copy link
Owner

They are, but your audio codec is currently not. Find a way to tell the length of a amr_wb packet and untrunc can work with your file. See Codec::getLength and Codec::getLength. Without an example I won't be able to help you.

@golimarrrr
Copy link
Author

This is the output from ffprobe for the reference file:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'ok.3gp':
  Metadata:
    major_brand     : 3gp4
    minor_version   : 0
    compatible_brands: isom3gp4
    creation_time   : 2018-02-23T19:43:39.000000Z
    com.android.version: 7.1.1
  Duration: 00:59:55.62, start: 0.000000, bitrate: 26 kb/s
    Stream #0:0(eng): Audio: amr_wb (sawb / 0x62776173), 16000 Hz, mono, flt, 24 kb/s (default)
    Metadata:
      creation_time   : 2018-02-23T19:43:39.000000Z
      handler_name    : SoundHandle

I think there is a mistake in your post, did you mean to specify two different methods?

@anthwlock
Copy link
Owner

Oh yes. I meant Codec::matchSample and Codec::getLength. You would have to add a else if(name_ == "sawb") branch there.

@golimarrrr
Copy link
Author

I tried some packet sizes as per the table in https://hal.archives-ouvertes.fr/hal-01319434/document and now the output file is not empty but the sound is garbled (it does slightly sound like voice though!). I guess the bitrate is variable and so the packet size, but I'm not sure.

I attach a sample of this format just in case anyone can help:
amrwb_sample.3gp.gz

@golimarrrr
Copy link
Author

I fixed it by hand like this:

  1. record another file created with the same app on the same phone, I got a bigger one but probably any length will work
  2. open both files in an hex editor
  3. replace the mdat section in the "ok" file with the mdat section in the "broken" file, without the header (i.e. copy only the bytes after 'mdat' header)
  4. it would probably already work like that, if not, the 4 bytes before 'mdat' specify the size of the mdat section, the current value will be the old size ("ok" file mdat section size), replace it with the new size ("broken" file mdat section size)

@golimarrrr
Copy link
Author

Also, this program should do the same procedure I mentioned above: https://github.com/golimarrrr/fix-3gp

@anthwlock
Copy link
Owner

anthwlock commented Jul 30, 2018

You are lucky that your two files have matching audio frames sizes. This allows you to simply replace the header.
This might be specific to the codec, or your recording device. For example in the sample you uploaded it looks like every frame is 61 bytes long.
I dont think your hack works if the corrupted file is longer than the healthy one, have you tried?

@anthwlock
Copy link
Owner

I looked at your file and apparently sawb uses 0x44 as identifier. For determining the length avcodec does the job.
It is satisfying how only one new line of code can add support for another codec.

@golimarrrr
Copy link
Author

I dont think your hack works if the corrupted file is longer than the healthy one, have you tried?

It works but the playing length of the fixed file will be too short (will be the same the healthy file)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants