After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 707963 - MD5 signature missing in FLAC encoding.
MD5 signature missing in FLAC encoding.
Status: RESOLVED OBSOLETE
Product: sound-juicer
Classification: Applications
Component: ripping
unspecified
Other Linux
: Normal major
: ---
Assigned To: Sound Juicer Maintainers
Sound Juicer Maintainers
Depends on: 727802
Blocks:
 
 
Reported: 2013-09-12 10:26 UTC by Trevor Mettam
Modified: 2021-05-17 16:06 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Trevor Mettam 2013-09-12 10:26:49 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.
Comment 1 Christophe Fergeau 2014-04-08 09:04:25 UTC
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.
Comment 2 Christophe Fergeau 2014-04-08 09:04:46 UTC
 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 :(
Comment 3 Christophe Fergeau 2014-04-08 09:05:00 UTC
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.
Comment 4 Christophe Fergeau 2014-04-08 09:05:11 UTC
(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.
Comment 5 GNOME Infrastructure Team 2021-05-17 16:06:54 UTC
-- 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.