GNOME Bugzilla – Bug 707963
MD5 signature missing in FLAC encoding.
Last modified: 2021-05-17 16:06:54 UTC
When ripping CD tracks as FLAC files, the MD5 signature in the STREAMINFO metadata block (as per FLAC specification) is set to 0. This is an important piece of metadata when it comes to verifying the integrity of archived FLAC audio data.
Ah my bad, I have investigated this in RH bugzilla in https://bugzilla.redhat.com/show_bug.cgi?id=961881 before checking if this was filed upstream. I'll c&p my lengthy comments from there.
Christophe Fergeau 2014-04-07 13:51:33 EDT I've spent some time on this one. When it's done encoding the file, libflac calls update_metadata() in src/libFLAC/stream_encoder.c which tries to seek at the beginning of the encoded file to rewrite the STREAMINFO header with the computed md5 checksum. This calls gst_flac_enc_seek_callback() which starts by doing: /* try to seek to the beginning of the output */ query = gst_query_new_seeking (GST_FORMAT_BYTES); if (gst_pad_query (peerpad, query)) { GstFormat format; gst_query_parse_seeking (query, &format, &seekable, NULL, NULL); if (format != GST_FORMAT_BYTES) seekable = FALSE; } else { GST_LOG_OBJECT (flacenc, "SEEKING query not handled"); } gst_query_unref (query); sound-juicer is using giosink, which does not handle SEEKING queries: static gboolean gst_gio_base_sink_query (GstBaseSink * bsink, GstQuery * query) { GstGioBaseSink *sink = GST_GIO_BASE_SINK (bsink); GstFormat format; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: gst_query_parse_position (query, &format, NULL); switch (format) { case GST_FORMAT_BYTES: case GST_FORMAT_DEFAULT: gst_query_set_position (query, GST_FORMAT_BYTES, sink->position); return TRUE; default: return FALSE; } case GST_QUERY_FORMATS: gst_query_set_formats (query, 2, GST_FORMAT_DEFAULT, GST_FORMAT_BYTES); return TRUE; case GST_QUERY_URI: if (GST_IS_URI_HANDLER (sink)) { gchar *uri; uri = gst_uri_handler_get_uri (GST_URI_HANDLER (sink)); gst_query_set_uri (query, uri); g_free (uri); return TRUE; } return FALSE; default: return GST_BASE_SINK_CLASS (parent_class)->query (bsink, query); } } Compare with filesink which has in its gst_file_sink_query() method: case GST_QUERY_SEEKING: gst_query_parse_seeking (query, &format, NULL, NULL, NULL); if (format == GST_FORMAT_BYTES || format == GST_FORMAT_DEFAULT) { gst_query_set_seeking (query, GST_FORMAT_BYTES, self->seekable, 0, -1); } else { gst_query_set_seeking (query, format, FALSE, 0, -1); } res = TRUE; break; However, switching sound-juicer to using filesink is not enough to get the flac signature to be written :( gst-launch-1.0 filesrc ! flacparse ! flacdec ! flacenc !filesink does the right thing though, so I guess this is a bug related to flacenc being wrapped inside an encodebin. gst debug log has flacenc gstflacenc.c:974:gst_flac_enc_seek_callback: Seek to 26 succeeded gstflacenc.c:1154:gst_flac_enc_write_callback:<flacenc1> Fixing up headers at pos=26, size=16 but this does not seem to translate to an updated header in the encoded flac file :(
I've been able to reproduce this using (from gstreamer source) gst-plugins-base/tests/examples/encoding -f audio/x-flac -a audio/x-flac -o /home/teuf/output.flac file:///home/teuf/11k16bitpcm.wav (wav file came from http://www.nch.com.au/acm/11k16bitpcm.wav linked from https://en.wikipedia.org/wiki/WAV but any random file should do the trick). After that (metaflac comes with the 'flac' package) $ metaflac --list --block-number=0 /home/teuf/output.flac METADATA block #0 type: 0 (STREAMINFO) is last: false length: 34 minimum blocksize: 4608 samples maximum blocksize: 4608 samples minimum framesize: 0 bytes maximum framesize: 0 bytes sample_rate: 11025 Hz channels: 1 bits-per-sample: 16 total samples: 0 MD5 signature: 00000000000000000000000000000000 If instead I do things manually with: gst-launch-1.0 filesrc location=/home/teuf/11k16bitpcm.wav ! wavparse ! flacenc ! filesink location=/home/teuf/output.flac $ metaflac --list --block-number=0 /home/teuf/output.flac METADATA block #0 type: 0 (STREAMINFO) is last: false length: 34 minimum blocksize: 4608 samples maximum blocksize: 4608 samples minimum framesize: 214 bytes maximum framesize: 7700 bytes sample_rate: 11025 Hz channels: 1 bits-per-sample: 16 total samples: 152267 MD5 signature: 7ad725dd59f9d1f4bf6d50cf80aee75d I'll file a gstreamer bug for this tomorrow.
(In reply to Christophe Fergeau from comment #6) > sound-juicer is using giosink, which does not handle SEEKING queries: > [...] > Compare with filesink which has in its gst_file_sink_query() method: > [...] > However, switching sound-juicer to using filesink is not enough to get the > flac signature to be written :( > Rather than hardcoding the output sink, we probably can let gstreamer pick the 'best' one for us through: sink = gst_element_make_from_uri (GST_URI_SINK, outputuri, "sink", NULL); It seems to be picking filesink for local files, and hopefully will use a different sink for non file:// URIs.
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/sound-juicer/-/issues/159.