Martijn van Beurden
2024-Oct-14 07:11 UTC
[flac-dev] C API: How to get a seektable for very long files?
Op zo 13 okt 2024 om 22:33 schreef Stefan Oltmanns <stefan-oltmanns at gmx.net>:> > Is the seektable written at the beginning of the file in the metadata > block or can there also be a second metadata block at the end? >Only at the start of the file.> > If it's at the beginning, would it possible to reserve space for N seek > points and during encoding remember a seek point after X samples, > resulting in M seek points when encoding is finished. If M <= N all seek > points are written, otherwise only every 2nd, 3rd etc. > Is it possible to do that? The functions all expect a a total_samples > argument, which is not known at the beginning. >No, you can only provide a seek table template with specific sample numbers. There is no way to ask the encoder to add a seek point every so many samples.> > The signal is the FM-modulated video signal of video tapes (like VHS). > The idea is to capture the signal directly from the video head amplifier > in the VCR and later demodulate/decode it in software, providing higher > quality than traditional capture of analog video. See this project: > https://github.com/oyvindln/vhs-decode/ > I started to design a capture device, as there is no 40 MHz continuous > sampling hardware available at consumer prices: > https://github.com/Stefan-Olt/MISRC >I've seen similar uses before. Maybe this one can serve as some inspiration: https://www.youtube.com/watch?v=ZrEFU22C8l8 According to that guy, he used cheap hardware. Op ma 14 okt 2024 om 00:09 schreef Stefan Oltmanns <stefan-oltmanns at gmx.net>:> > I think there is another major issue for me: In > METADATA_BLOCK_STREAMINFO the field for the length is only 36 bit, > that's not even half an hour at 40 MHz sample rate, resulting in that > the encoder sets it to 0 for longer captures. In the seekpoint the > sample number is 64 bit, which is more than enough. > But how does the decoder handle the seektable when the total number of > samples is unknown? Or does the seektable override the info from > METADATA_BLOCK_STREAMINFO?When a suitable seektable is found, it overrides the information from streaminfo, yes.> > I used this functions now to add seekpoints, but all remain placeholders > according to metaflac: > > FLAC__metadata_object_new > FLAC__metadata_object_seektable_template_append_placeholders > FLAC__stream_encoder_set_metadata > (encoder init & loop) > FLAC__metadata_object_seektable_template_sort >Yes, that is correct, because you asked for placeholder points. You should ask for spaced points. I just tested what happens if you make a seek table template with a total_samples that is bigger than the eventual total_samples that is encoded, and found a bug in the encoder. It works, but the resulting seek table isn't valid. You could try to use that approach anyway in the meantime, perhaps it works just fine? I'd say, have your implementation prepare a seek table template for 5 hours of recording (I assume that is above the upper bound of such captures?), the stream encoder will fill in those seek points when it reaches them, and leaves the unused ones unfilled. I will work on a fix, so the stream encoder converts those unused points to placeholder points in the future. The stream encoder works pretty simple: you give it metadata to add to the start of the stream, it adds those verbatim. After encoding is finished, it will update streaminfo and seektable. There is no metadata at the end of the stream, and the metadata blocks should not be changed during encoding. I see the difficulty here now by the way: metaflac also refuses to write a seektable when the streaminfo metadata block specifies 0 total samples, which is unavoidable in your case.
Stefan Oltmanns
2024-Oct-14 14:06 UTC
[flac-dev] C API: How to get a seektable for very long files?
Am 14.10.24 um 09:11 schrieb Martijn van Beurden:> Op zo 13 okt 2024 om 22:33 schreef Stefan Oltmanns <stefan-oltmanns at gmx.net>: >> > >> >> The signal is the FM-modulated video signal of video tapes (like VHS). >> The idea is to capture the signal directly from the video head amplifier >> in the VCR and later demodulate/decode it in software, providing higher >> quality than traditional capture of analog video. See this project: >> https://github.com/oyvindln/vhs-decode/ >> I started to design a capture device, as there is no 40 MHz continuous >> sampling hardware available at consumer prices: >> https://github.com/Stefan-Olt/MISRC >> > > I've seen similar uses before. Maybe this one can serve as some > inspiration: https://www.youtube.com/watch?v=ZrEFU22C8l8 According to > that guy, he used cheap hardware.That's indeed an interesting device.> > Op ma 14 okt 2024 om 00:09 schreef Stefan Oltmanns <stefan-oltmanns at gmx.net>: >> >> I think there is another major issue for me: In >> METADATA_BLOCK_STREAMINFO the field for the length is only 36 bit, >> that's not even half an hour at 40 MHz sample rate, resulting in that >> the encoder sets it to 0 for longer captures. In the seekpoint the >> sample number is 64 bit, which is more than enough. >> But how does the decoder handle the seektable when the total number of >> samples is unknown? Or does the seektable override the info from >> METADATA_BLOCK_STREAMINFO? > > When a suitable seektable is found, it overrides the information from > streaminfo, yes.Unfortunately that doesn't seem to be the case. I just made a capture that is > 30 Minutes with total samples set to 0 and a seek table: All players I tried cannot seek in the file and cannot determine it's length: VLC, Celluloid and DeaDBeef I wondered why I can seek files I manually compressed with flac from raw: The total samples field is just wrong, the seek table is correct, having sample_numer values a lot higher than total samples. The players display the wrong length. Seems to be a bug in flac.> >> >> I used this functions now to add seekpoints, but all remain placeholders >> according to metaflac: >> >> FLAC__metadata_object_new >> FLAC__metadata_object_seektable_template_append_placeholders >> FLAC__stream_encoder_set_metadata >> (encoder init & loop) >> FLAC__metadata_object_seektable_template_sort >> > > Yes, that is correct, because you asked for placeholder points. You > should ask for spaced points. I just tested what happens if you make a > seek table template with a total_samples that is bigger than the > eventual total_samples that is encoded, and found a bug in the > encoder. It works, but the resulting seek table isn't valid. You could > try to use that approach anyway in the meantime, perhaps it works just > fine?I fixed that manually after calling FLAC__metadata_object_seektable_template_sort, according to metaflac everything is correct: for(int i = seektable->data.seek_table.num_points-1; i>=0; i--) { if (seektable->data.seek_table.points[i].stream_offset != 0) break; seektable->data.seek_table.points[i].sample_number 0xFFFFFFFFFFFFFFFF; }> > I'd say, have your implementation prepare a seek table template for 5 > hours of recording (I assume that is above the upper bound of such > captures?), the stream encoder will fill in those seek points when it > reaches them, and leaves the unused ones unfilled. I will work on a > fix, so the stream encoder converts those unused points to placeholder > points in the future.I have done that now, 2^18 seekpoints for a maximum length of 2^41 samples, that sould be enough.> > The stream encoder works pretty simple: you give it metadata to add to > the start of the stream, it adds those verbatim. After encoding is > finished, it will update streaminfo and seektable. There is no > metadata at the end of the stream, and the metadata blocks should not > be changed during encoding. > > I see the difficulty here now by the way: metaflac also refuses to > write a seektable when the streaminfo metadata block specifies 0 total > samples, which is unavoidable in your case.Just an idea: Of course the size of the total samples field cannot be changed, and a seektable currently doesn't seem to work with total samples = 0. Is it possible to extend the specification with full backward compatibility in a way like this? If total samples is 0, the last seek point in the seek table that is not a place holder can indicate the total number of samples: In case frame_samples is 0, stream_offset is pointing to the last frame and sample_number is the total number of samples. FLAC__stream_decoder_get_total_samples would check that and return the correct value. Not sure if that breaks any old versions / 3rd party decoder. Another option would be to use the first place holder, set stream_offset to the total samples and some magic value in frame_samples. That should definitly be backward compatible as these values are undefined for placeholders. Another option would of course be to add a new type of metadata, like METADATA_BLOCK_STREAMINFO2, but I don't know how backwards compatible that is. Best regards Stefan