flacdec converts the src timestamp to a sample number, uses that internally, then reconverts the sample number to a timestamp for the output buffer. Unfortunately, sample numbers can't be represented in an integer number of nanoseconds, and the conversion process was truncating rather than rounding, resulting in sample numbers and output timestamps that were often off by a full sample.
This corrects the time->sample convesion
The libFLAC API is callback based, and we must only call it to
output data when we know we have enough input data. For this
reason, a single processing step is done when receiving a buffer.
However, if there were metadata buffers still pending, a step
intended for the first audio frame might end up writing that
leftover metadata. Since a single step is done per buffer, this
will cause every buffer to be written one step late.
This would add some latency (a bufferfull's worth), possibly
lose a buffer when seeking or the like, and also cause timestamp
and offset to be applied to the wrong buffer, as updates to
the "current" segment last_stop (from incoming buffer timestamp)
will be applied to an output buffer originating from the previous
incoming buffer.
This fixes the issue by ensuring that, upon receiving the first
audio frame, processing is done till all metadata is processed,
so the next "single step" done will be for the audio frame. After
this, we should keep to 1 input buffer -> 1 output buffer and so
avoid getting out of sync.
https://bugzilla.gnome.org/show_bug.cgi?id=650960
Instead only store them inside the flac metadata. There's
no point in storing them twice and the flac metadata is
still the official way to store image tags inside flac.
Unlike filesrc, flacenc outputs the flac blocks neatly aligned one in
each buffer. This means that when we switch from metadata mode to
audio data passthrough mode, there's no data left in the adapter to
push out at this point, so check if there's data in the adapter
before requesting buffers from it (also needed in case we get input
buffers of 0 size).
Fixes#615793.
Don't send another newsegment event if the upstream muxer/parser has already
sent one (otherwise the sink will wait for $duration before starting playback).
Fixes long delay until playback starts with flac-in-ogg files.
Fixes#610959.
If the FLAC decoder is flushed, its state will be set to frame-sync mode,
which will sync to the next *audio* frame and makes it ignore all headers.
This prevented tags and everything else to show up when using flacdec
in push mode.
Fixes bug #608843.
A seek in multi-sink pipeline typically leads to several seek events in a row,
which could lead to sending several newsegments in a row without intermediate
flushing. These would then accumulate, distort rendering times and as such
lead to 'hanging'.
For some reason flac doesn't call our metadata callback when we operate
in push mode with unframed input, but that's where we set up the
newsegment event (since that's where we'd get the duration from the
stream info header), so we didn't send a newsegment event at all in this
case. Hack around this by storing a generic newsegment event for now
which will be used if we don't replace it with a better one that
includes the duration.
gst_adapter_peek() will merge buffers as needed, which we can avoid
here since we're doing a memcpy anyway and then flush the copied
data from the adapter right away.
When seeking in a local flac file (ie. operating pull-based), the decoder
would often just error out after the loop function sees a DECODER_ABORTED
status. This, however, is the read callback's way of telling our loop
function that pull_range failed and streaming should stop, in this case
because of the flush-start event that the seek handler pushed upstream
from the seeking thread. Handle this slightly better by storing the last
flow return from pull_range, so the loop function can evaluate it properly
when it encounters a DECODER_ABORTED and take the right action.
Fixes#578612.
Let's be paranoid and make sure we never pass a number that takes up
more than 36 bits to _set_total_samples_estimate(), since libFLAC
expects all the other bits to be zero, and if this is not the case
neighbouring fields in the global stream info header may get messed
up inadvertently, so that flac -d refuses to decode the stream.
See #584455.
It was previously sending the bogus buffer which was returned from
the bufferalloc (required for reverse negotiation apparently) instead
of the pending buffer.
Store the offset and caps when allocating a buffer during seeking, and then
allocate a new buffer with buffer_alloc before we push it out. This ensures
that in all respects the first buffer decoded during seeking behaves like
all other buffers, including allowing downstream re-negotiation.
In the event handler, gst_flac_dec_sink_event(), two functions are called on
the FLAC stream without checking if it has been initialized:
FLAC__stream_decoder_flush()
FLAC__stream_decoder_process_until_end_of_stream()
Both these FLAC__*() functions modify the internal state of the FLAC stream.
Later, when the buffers start flowing, gst_flac_dec_chain() tries to initialize
the stream. the FLAC__stream_decoder_init_stream() call will fail because the
previous calls to FLAC__*() changed the stream state so it is no longer in the
initialized state.
The flacdec API calls the write callback when performing a seek. We cannot yet
push out a buffer at that time so we must keep it and push it out later.
Flush out the upstream part of the pipeline when doing a seek.
Fixes#574275.
Link to properties. Correct titles for examples. Document a few trivial cases. Keep lists in section file and docs/plugins/Makefile.am alphabetically ordered. Fix warnings that gtk-doc points out.
Original commit message from CVS:
* ext/flac/Makefile.am:
Include $(FLAC_CFLAGS) in CFLAGS to make sure to find the FLAC headers.
This fixes compilation if FLAC is installed in an uncommon location
that is not already handled by other CFLAGS. Fixes bug #558711.
Original commit message from CVS:
* ext/flac/gstflacdec.c (gst_flac_dec_read_stream):
* ext/flac/gstflacenc.c (gst_flac_enc_write_callback):
Cast some size_t arguments to guint to avoid compiler
warnings on 64-bit systems.
Original commit message from CVS:
* ext/flac/gstflacenc.c: (gst_flac_enc_class_init):
Make sure the desired default values are actually set, not only
registered as defaults (actual problem is that the stereo-specific
values are only updated if channels==2, which is not the case yet
when the object is created, so the default values for the
mid-side-stereo and loose-mid-side-stereo settings are never
set in _update_quality()). Makes flacenc create smaller files by
default (for stereo input), and fixes#550791.
Original commit message from CVS:
* ext/flac/gstflacenc.c: (gst_flac_enc_check_discont):
Actually provide the variables required for the format string.
Original commit message from CVS:
* ext/flac/gstflacenc.c: (gst_flac_enc_write_callback),
(gst_flac_enc_check_discont), (gst_flac_enc_chain),
(gst_flac_enc_change_state):
* ext/flac/gstflacenc.h:
Handle non-zero start timestamps correctly, mark header packets as
IN_CAPS and print a warning and suggest using audiorate if stream
discontinuities are detected. When FLAC supports flushing the encoder
somehow this should be done for discontinuities instead.
Remove some unused variables from the instance struct.
Original commit message from CVS:
* ext/flac/gstflacenc.c: (gst_flac_enc_seek_callback):
If seeking failed return the appropiate return value to FLAC.
Otherwise it thinks seeking was successfull and tries to rewrite
parts of the headers which then get appended to the output.
Original commit message from CVS:
Patch by: Frederic Crozat <fcrozat@mandriva.org>
* ext/esd/gstesd.c: (plugin_init):
* ext/flac/gstflac.c: (plugin_init):
* ext/shout2/gstshout2.c: (plugin_init):
* ext/wavpack/gstwavpack.c: (plugin_init):
* sys/oss/gstossaudio.c: (plugin_init):
* sys/v4l2/gstv4l2.c: (plugin_init):
Make sure gettext returns translations in UTF-8 encoding rather
than in the current locale encoding (#546822).
Original commit message from CVS:
* ext/flac/gstflacdec.c:
Add FIXME for 0.11 to simply output everything with width=32 as given
by FLAC and let audioconvert handle the conversions instead of doing
them in flacdec.
Original commit message from CVS:
Based on a patch by: Jonathan Matthew <notverysmart at gmail dot com>
* ext/flac/Makefile.am:
* ext/flac/gstflac.c: (plugin_init):
* ext/flac/gstflactag.c: (gst_flac_tag_setup_interfaces),
(gst_flac_tag_base_init), (gst_flac_tag_class_init),
(gst_flac_tag_dispose), (gst_flac_tag_init),
(gst_flac_tag_sink_setcaps), (gst_flac_tag_chain),
(gst_flac_tag_change_state):
* ext/flac/gstflactag.h:
Port flactag to 0.10, add documentation for it and clean it up a bit.
Fixes bug #413841.
* docs/plugins/Makefile.am:
* docs/plugins/gst-plugins-good-plugins-docs.sgml:
* docs/plugins/gst-plugins-good-plugins-sections.txt:
* docs/plugins/gst-plugins-good-plugins.hierarchy:
* docs/plugins/gst-plugins-good-plugins.interfaces:
* docs/plugins/gst-plugins-good-plugins.prerequisites:
* docs/plugins/inspect/plugin-flac.xml:
* ext/flac/gstflacdec.c: (gst_flac_dec_base_init):
* ext/flac/gstflacdec.h:
* ext/flac/gstflacenc.c: (gst_flac_enc_base_init):
* ext/flac/gstflacenc.h:
Add flactag and flacenc to the documentation and mark
the private parts of the flacdec instance structure as private.
Also use gst_element_class_set_details_simple() in flacdec and
flacenc.
Original commit message from CVS:
* ext/flac/gstflacenc.c: (gst_flac_enc_query_peer_total_samples),
(gst_flac_enc_sink_setcaps), (gst_flac_enc_write_callback):
Set an estimate for the total number of samples that will be encoded
if possible to help decoders if the streaminfo can't be rewritten
later (like when muxing into Ogg containers).
Add a warning if we get header packets after data packets as those
will get lost when muxing into Ogg, i.e. rewriting the headers doesn't
work.
Original commit message from CVS:
* ext/flac/gstflacdec.c: (gst_flac_dec_metadata_callback),
(gst_flac_dec_write):
Support decoding of all depths between 4 and 32 bits and read the
depth from the streaminfo header if needed. Also support all sampling
rates between 1 and 655350 Hz.
* ext/flac/gstflacenc.c:
(gst_flac_enc_caps_append_structure_with_widths),
(gst_flac_enc_sink_getcaps), (gst_flac_enc_sink_setcaps),
(gst_flac_enc_chain):
* ext/flac/gstflacenc.h:
Support encoding in all bit depths supported by the streamable
subformat (i.e. 8, 12, 16, 20 and 24 bits) and all sampling rates
between 1 Hz and 655350 Hz.
Original commit message from CVS:
* ext/flac/gstflacdec.c: (gst_flac_dec_setup_seekable_decoder),
(gst_flac_dec_setup_stream_decoder),
(gst_flac_dec_update_metadata):
Always post the audio-codec tag, not only if other tags are present.
Original commit message from CVS:
* ext/flac/gstflacdec.c: (gst_flac_extract_picture_buffer):
* gst/id3demux/id3v2frames.c: (parse_picture_frame):
Use new utility functions in libgsttag to process coverart (#512333).
Original commit message from CVS:
* ext/flac/gstflacdec.c: (gst_flac_dec_write):
We actually support left/side, right/side and mid/side files. The
conversion to normal, interleaved stereo is done by libflac.
Original commit message from CVS:
* ext/flac/Makefile.am:
* ext/flac/gstflacdec.c: (gst_flac_dec_write):
Set the channel layout when decoding FLAC files with more than 2
channels as defined by the FLAC spec. Fixes bug #534570.
Also don't try to decode left/side, right/side and mid/side files
as we don't support this at all.
Original commit message from CVS:
Patch by: John Millikin <jmillikin at gmail dot com>
* ext/flac/gstflacdec.c: (gst_flac_dec_scan_for_last_block),
(gst_flac_extract_picture_buffer), (gst_flac_dec_metadata_callback):
Fix extraction of picture blocks with newer libflac versions again:
FLAC__METADATA_TYPE_PICTURE is an enum, not a define (#513628).
Original commit message from CVS:
* ext/flac/gstflacdec.c:
Fix compilation against flac 1.1.2 (as on debian stable), where
the picture metadata defines and structs don't exist yet.
Fixes#509301.
Original commit message from CVS:
* ext/flac/gstflacdec.c: (gst_flac_extract_picture_buffer):
* gst/id3demux/id3v2frames.c: (parse_picture_frame):
Generate the image-type values correctly. Leave them out of the caps
when outputting a "preview image" tag, since it only makes sense
to have one of those - the type is irrelevant.
* sys/sunaudio/gstsunaudiomixerctrl.c:
(gst_sunaudiomixer_ctrl_open):
If we can, mark the mixer multiple open when we use it, in case
(for some reason) the process wants to open it again elsewhere.
Original commit message from CVS:
Patch by: John Millikin <jmillikin at gmail dot com>
* ext/flac/gstflacdec.c: (gst_flac_dec_setup_seekable_decoder),
(gst_flac_dec_setup_stream_decoder),
(gst_flac_normalize_picture_mime_type),
(gst_flac_extract_picture_buffer),
(gst_flac_dec_metadata_callback):
Emit metadata messages when a PICTURE block is encountered.
Fixes#506715.
Original commit message from CVS:
* ext/flac/gstflacdec.c: (gst_flac_dec_write):
Fix 'xyz may be used uninitialized' compiler warnings caused
by broken g_assert_not_reached() macro in GLib-2.15.x and don't
abort() in any case but properly report the error.
Original commit message from CVS:
* ext/flac/gstflacdec.c: (gst_flac_dec_reset_decoders),
(gst_flac_dec_update_metadata), (gst_flac_dec_metadata_callback),
(gst_flac_dec_write):
* ext/flac/gstflacdec.h:
Remove some unused vars.
Do more cleanup of leftover events and tags.
Output tags after the segment event. Fixes#504018.
Original commit message from CVS:
* ext/flac/gstflacdec.c: (gst_flac_dec_metadata_callback),
(gst_flac_dec_write):
* ext/flac/gstflacdec.h:
Send segments from the streaming thread. Fixes#502187.
Fix segment seeking and a bunch of other seeking cases.
Original commit message from CVS:
* ext/flac/gstflacenc.c:
* ext/flac/gstflacenc.h:
Save the flow return from the last gst_pad_push() and
make sure we pass the right flow return value upstream
in the case of failure; minor clean-ups.
Original commit message from CVS:
* ext/flac/gstflacenc.c: (gst_flac_enc_init),
(notgst_value_array_append_buffer),
(gst_flac_enc_process_stream_headers),
(gst_flac_enc_write_callback), (gst_flac_enc_chain),
(gst_flac_enc_change_state):
* ext/flac/gstflacenc.h:
Collect headers, add "streamheader" field to output caps and set
BUFFER_IN_CAPS flag on pushed header buffers. That way oggmux
produces output according to the official FLAC-to-Ogg mapping
instead of completely broken files. Fixes#426044.
Original commit message from CVS:
* ext/flac/gstflacenc.c: (gst_flac_enc_sink_setcaps),
(gst_flac_enc_chain):
Don't crash in chain function if setcaps hasn't been called.
Original commit message from CVS:
* ext/flac/gstflacdec.c: (gst_flac_dec_loop):
Correctly post an error on the bus if something went wrong in the loop
function. This fixes a few cases where the task was paused and nothing
happened anymore.
Original commit message from CVS:
* ext/flac/gstflacdec.c: (gst_flac_dec_scan_got_frame),
(gst_flac_dec_write), (gst_flac_dec_loop),
(gst_flac_dec_sink_event), (gst_flac_dec_chain),
(gst_flac_dec_src_query):
* ext/flac/gstflacdec.h:
Make flac-in-ogg work (#352100).
Original commit message from CVS:
* ext/flac/Makefile.am:
* ext/flac/flac_compat.h:
* ext/flac/gstflac.c:
* ext/flac/gstflacdec.c: (gst_flac_dec_init):
* ext/flac/gstflacenc.c:
Remove backwards compatibility cruft for dealing with FLAC API
changes in the 1.0.x series - we require 1.1.1 or newer these days.
Original commit message from CVS:
* ext/flac/gstflacdec.c: (gst_flac_dec_loop):
* ext/flac/gstflacdec.h:
Handle segment seeks that include the end of the file as stop point
properly: when the decoder hits EOS we want to send a SEGMENT_DONE
message instead of an EOS event in case we're in segment seek
mode (fixes#340699).
Original commit message from CVS:
* ext/flac/gstflacdec.c: (gst_flac_dec_loop),
(gst_flac_dec_handle_seek_event):
Add support for segment seeks (fixes#338290). Also demote
some recurring debug message from DEBUG to LOG level.
Original commit message from CVS:
* ext/flac/gstflacdec.c: (gst_flac_dec_handle_seek_event):
Don't try to seek beyond the end of the file (would
occasionally display error dialogs in totem when seeking
to the end) (#335869). Will still throw an error though
if the file is truncated and the total_samples value in
the stream header is wrong.
Original commit message from CVS:
* ext/flac/gstflacdec.c: (gst_flac_calculate_crc8),
(gst_flac_dec_scan_got_frame), (gst_flac_dec_scan_for_last_block),
(gst_flac_dec_metadata_callback):
* ext/flac/gstflacdec.h:
If the stream header doesn't contain the total number of samples,
search for the last flac frame at the end of the file and calculate
the total duration from that frame's offset (fixes#337609).
Original commit message from CVS:
* ext/flac/gstflacdec.c: (gst_flac_dec_handle_seek_event):
* ext/flac/gstflacdec.h:
* ext/flac/gstflacenc.h:
Spifify a bit.
Fix deadly lock order error in seeking code, STREAM_LOCK
cannot be taken within LOCK and the streaming variables are
protected with the STREAM_LOCK anyway.
Original commit message from CVS:
Reviewed by: Tim-Philipp Müller <tim at centricular dot net>
* ext/flac/gstflacdec.c: (gst_flac_dec_write),
(gst_flac_dec_convert_src), (gst_flac_dec_src_query),
(gst_flac_dec_change_state):
Don't g_assert() where we should just return FALSE; remove
unnecessary g_assert(); initialize some fields properly in
state change function (fixes#325504). Also, use
GST_DEBUG_OBJECT in two more places.
Original commit message from CVS:
* ext/flac/gstflacdec.c: (gst_flac_dec_base_init),
(gst_flac_dec_class_init), (gst_flac_dec_init),
(gst_flac_dec_metadata_callback), (gst_flac_dec_error_callback),
(gst_flac_dec_eof), (gst_flac_dec_write), (gst_flac_dec_loop),
(gst_flac_dec_convert_src), (gst_flac_dec_get_src_query_types),
(gst_flac_dec_src_query), (gst_flac_dec_send_newsegment),
(gst_flac_dec_handle_seek_event), (gst_flac_dec_src_event),
(gst_flac_dec_change_state):
* ext/flac/gstflacdec.h:
Rewrite flacdec a bit, so that even seeking might work now. Most
importantly, don't act upon any flow return values we get, just tell
the decoder everything's dandy and act on the flow return values
later on in the loop function. We don't want to mess up the internal
decoder state for non-fatal things like flushing pads etc. Other
than that, use GstSegment (segment seeks don't work yet though, but
should be easy to add), use boilerplate macros, drop the superfluous
'flacdec:' from debug messages, use gst_util_uint64_scale_int, and
lots of other things.
Original commit message from CVS:
* ext/flac/gstflacdec.c: (raw_caps_factory), (gst_flacdec_write):
Accept a wider range of flac files, more closely matching flac sp
Original commit message from CVS:
* ext/flac/gstflacenc.c: (gst_flacenc_base_init),
(gst_flacenc_init), (gst_flacenc_sink_setcaps),
(gst_flacenc_seek_callback), (gst_flacenc_write_callback),
(gst_flacenc_sink_event), (gst_flacenc_chain),
(gst_flacenc_set_property), (gst_flacenc_get_property),
(gst_flacenc_change_state):
* ext/flac/gstflacenc.h:
Fix seeking, so that flacenc can rewrite the header with the
correct duration and amount of samples and all that at EOS;
also set timestamps and granulepos on outgoing buffers; add
debug category; fix state change function.
Original commit message from CVS:
2005-10-03 Andy Wingo <wingo@pobox.com>
* ext/flac/gstflacdec.c (gst_flacdec_write): Deal with pad_alloc
error returns.
Original commit message from CVS:
2005-10-02 Andy Wingo <wingo@pobox.com>
* configure.ac (GST_PLUGIN_LDFLAGS): Change to be like -base.
* ext/flac/gstflacenc.c: Ported to 0.9.
* ext/flac/gstflacdec.c (gst_flacdec_loop): Handle errors better.
* ext/flac/Makefile.am: Add the GST_PLUGINS_BASE cflags and libs,
and link to gsttagedit. Enable flacenc.
* ext/flac/gstflacdec.c: Re-enable tag reading.