#263 Seek fails (test case attached)

open-accepted
Josh Coalson
libFLAC (57)
8
2007-07-30
2007-03-20
Elegant Dice
No

Hi,

The attached file and source code demonstrates a rare but existing bug in libFLAC somewhere (note I use the libFLAC++ interface, but I assume the problem lies in the libFLAC code).

If you attempt to seek to sample #600000 (out of a total 720000 samples), it fails. I have made many other similar files and can seek to this point in those files... but this file does not work.

Note that the testing it with "flac -t" does not indicate any errors.

This is the result:

$ ./test_seek bad_seek_to_600000.flac
Total samples = 720000
Seeking to 600000
test_seek: regional_sdr/test_seek.cpp:25: void test_decoder::test_seek(): Assertion `seek_ok' failed.
Aborted
$

I have tested this with both 1.1.3 and 1.1.4, and both times it has failed.

thanks,
Paul

Discussion

  • Elegant Dice
    Elegant Dice
    2007-03-20

    Test source code

     
    Attachments
  • Elegant Dice
    Elegant Dice
    2007-03-20

    Flac test file 1/6

     
    Attachments
  • Elegant Dice
    Elegant Dice
    2007-03-20

    Logged In: YES
    user_id=1168070
    Originator: YES

    File Added: test_seek_flac.zip.1

     
  • Elegant Dice
    Elegant Dice
    2007-03-20

    Flac test file 2/6

     
    Attachments
  • Elegant Dice
    Elegant Dice
    2007-03-20

    Logged In: YES
    user_id=1168070
    Originator: YES

    File Added: test_seek_flac.zip.2

     
  • Elegant Dice
    Elegant Dice
    2007-03-20

    Flac test file 3/6

     
    Attachments
  • Elegant Dice
    Elegant Dice
    2007-03-20

    Logged In: YES
    user_id=1168070
    Originator: YES

    File Added: test_seek_flac.zip.3

     
  • Elegant Dice
    Elegant Dice
    2007-03-20

    Flac test file 4/6

     
    Attachments
  • Elegant Dice
    Elegant Dice
    2007-03-20

    Logged In: YES
    user_id=1168070
    Originator: YES

    File Added: test_seek_flac.zip.4

     
  • Elegant Dice
    Elegant Dice
    2007-03-20

    Flac test file 5/6

     
    Attachments
  • Elegant Dice
    Elegant Dice
    2007-03-20

    Logged In: YES
    user_id=1168070
    Originator: YES

    File Added: test_seek_flac.zip.5

     
  • Elegant Dice
    Elegant Dice
    2007-03-20

    Flac test file 6/6

     
    Attachments
  • Elegant Dice
    Elegant Dice
    2007-03-20

    Logged In: YES
    user_id=1168070
    Originator: YES

    cat test_seek_flac.zip.* > test_seek_flac.zip
    unzip -t test_seek_flac.zip
    unzip test_seek_flac.zip

    File Added: test_seek_flac.zip.6

     
  • Logged In: YES
    user_id=228356
    Originator: NO

    Well, this is pretty interesting. The file has a byte sequence that looks almost like a correct frame, crc8 of the header is correct, subframes are decoded, only the zero padding and crc16 don't match. Wondering what is the chance of having such file.

    The following patch fixes this particular case. A larger change is needed to have this fixed correctly, FLAC__stream_decoder_process_single should store the position in the stream and when an incomplete frame is read, search for next frame sync from the stored position. Also, the zeroed output signal should be produced only when a gap between two correctly decoded frames is detected.

    --- stream_decoder.c.orig 2007-02-06 04:32:39.000000000 +0100
    +++ stream_decoder.c 2007-03-24 14:15:34.262880885 +0100
    @@ -2035,6 +2035,8 @@
    }
    if(!read_zero_padding_(decoder))
    return false;
    + if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means bad sync or got corruption */
    + return true;

    /\*
     \* Read the frame CRC-16 from the footer and check
    

    @@ -2080,13 +2082,10 @@
    }
    }
    else {
    - /* Bad frame, emit error and zero the output signal */
    + /* Bad frame, emit error */
    send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH);
    - if(do_full_decode) {
    - for(channel = 0; channel < decoder->private_->frame.header.channels; channel++) {
    - memset(decoder->private_->output[channel], 0, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize);
    - }
    - }
    + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
    + return true;
    }

     
  • Josh Coalson
    Josh Coalson
    2007-07-26

    • priority: 5 --> 8
    • assigned_to: nobody --> jcoalson
     
  • Josh Coalson
    Josh Coalson
    2007-07-30

    • status: open --> open-accepted
     
  • Josh Coalson
    Josh Coalson
    2007-07-30

    Logged In: YES
    user_id=78173
    Originator: NO

    BTW thanks for the excellent test case Paul, otherwise this would have been pretty hard to find.

    this works with 1.2.0 but that is a fluke due to changes in the seek algorithm.

    I will work on the complete fix for flac-1.2.1

     
  • Josh Coalson
    Josh Coalson
    2007-09-10

    Logged In: YES
    user_id=78173
    Originator: NO

    a partial fix is in CVS now. the full fix is pretty tricky so it will go after 1.2.1