It might happen that the timestamp is before the segment and the
check would succeed. In this case reducing the duration makes no
sense and would lead to broken results.
The previous code was setting keytarget to target
to make sure the keyframe found for each pad was
indeed before the target.
Then if target == keytarget, it assumed a keyframe had been
found, which was not the case if target was before the first frame
in the file.
This patch checks that a keyframe was indeed found, and if not
seeks to 0, without bisecting again.
Assuming default gst qa assets in $HOME/gst-validate
seek_before_first_frame.scenario:
description, seek=true, handles-states=true
pause, playback-time=0.0
seek, playback-time=0.0, start=0.0, flags=accurate+flush
seek, playback-time=0.0, start=0.01, flags=accurate+flush
seek, playback-time=0.0, start=0.1, flags=accurate+flush
GST_DEBUG=*theoradec*:2 gst-validate-1.0 playbin \
uri=file://$HOME/gst-validate/gst-qa-assets/medias/ogg/vorbis_theora.0.ogg \
--set-scenario seek_before_first_frame.scenario
https://bugzilla.gnome.org/show_bug.cgi?id=741097
Samples may be clipped at the end, and this is conveyed by a
granulepos that's smaller than it would otherwise be. Use the
segment stop time to detect this, and calculate the right
granulepos.
Setting segment.base in the segment sent from gst_ogg_demux_handle_page() is
enough to ensure that chained oggs are played corretly (see bgo#706569).
Tweaking the base in gst_ogg_pad_submit_packet() as well result in delays when
playing a file with start != -1.
https://bugzilla.gnome.org/show_bug.cgi?id=735808
Base time should be accumulated so non flushing seeks have the expected base.
Not accumulating result in segments appearing as "too late" and so are not
played by the sink.
https://bugzilla.gnome.org/show_bug.cgi?id=735509
This lets oggdemux determine they are not delta units, and removes
spurious per packet warnings about being unable to determine the
packet's keyframeness.
They are very confusing for people, and more often than not
also just not very accurate. Seeing 'last reviewed: 2005' in
your docs is not very confidence-inspiring. Let's just remove
those comments.
This should not cause any actual bug since Theora and Daala have
a maximum shift of 31, and a packet duration of 2^31 seems very
implausible. But it fixes:
Coverity 1139804, 1139803, 1139802
Add an extra function to the oggstream map to inform it about
the incoming buffers. This way oggmux can keep a count on the
vp8 invisible frames and calculate the granulepos correctly.
https://bugzilla.gnome.org/show_bug.cgi?id=722682
vp8 stream header shouldn't be assumed to be provided in caps always
as this would repeat the same code in all demuxers/encoders. Instead,
make oggmux generate them if they are not supplied.
https://bugzilla.gnome.org/show_bug.cgi?id=722682
When seeking back to original state after duration seeks, let
upstream know that we want the whole file, including the last
byte that wasn't requested on the duration seeks.
https://bugzilla.gnome.org/show_bug.cgi?id=724633
A change in gst_ogg_demux_do_seek caused oggdemux to wait for
a page for each of the streams, including a skeleton stream if
one was present. Since Skeleton only has header pages, that
was never going to end well.
Also, the code was skipping CMML streams when looking for pages,
so would also have broken on CMML streams.
Thus, we change the code to disregard Skeleton streams, as well
as discontinuous streams (such as CMML and Kate). While it may
be desirable to consider Kate streams too (in order to avoid
losing a subtitle starting near the seek point), this may be
a performance drag when seeking where no subtitles are. Maybe
one could add a "give up" threshold for such discontinuous
streams, so we'd get any page if there is one, but do not end
up reading preposterous amounts of data otherwise.
In any case, it is important that the code that determines
the amount of streams to look pages for remains consistent with
the "early out" conditions of the code that actually parses
the incoming pages, lest we never decrease the pending counter
to zero.
This fixes seeking on a file with a skeleton track reading all
the file on each seek.
https://bugzilla.gnome.org/show_bug.cgi?id=719615
Ogg data is read chunk by chunk, and the chunk size used was
originally taken from libvorbisfile. However, this value leads
to poor performance when used on an Ogg file with large pages
(Ogg pages can be close to 64 KB).
We can't just use a larger chunk size, since this will decrease
performance on small page streams, so we use an adaptive scheme
where the chunk size is twice the largest page size we've seen
so far in the stream. For "typical" Ogg/Vorbis, this gives us
almost the same chunk size (a bit lower), and this lets us get
better performance on streams with large pages.
Store the seek stop and seqnum and properly restore them when
receiving the corresponding Segment from upstream. Also fixes
seqnum for converted seek events.
When bisecting after an earliest time has been found, we need
to only consider the stream for which the earliest time was found.
Before, the following scenario could be and was encountered:
a) Find the earliest time for stream X
b) bisect and find a page which granuletime is indeed < target, but
contains another stream.
c) decide to seek at the wrong offset, sometimes inferior to
the real one, in which case the error was undected or
d) the offset was superior, and thus the actual target keyframe was
not processed, and packets were skipped waiting
for a granulepos.
https://bugzilla.gnome.org/show_bug.cgi?id=700537
The problem experienced is that the EOS was never emitted by oggmux during a
rendering with GES. The proposed patch checks if the pad is EOS before deciding
it's the "best pad".
https://bugzilla.gnome.org/show_bug.cgi?id=699792
If our previous flow return was NOT_LINKED, don't try to push on the pads some
more. If we get a RECONFIGURE event on the pad, try to push on it again.
Changed the check to a current_time equal to the stop will produce
EOS instead of the next one. Also, segment.start can't be NONE, so removing
this check.
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=696899
No need to copy buffers we put into the streamheader any more
now that we don't put caps on buffers any more, so there's no
danger of a refcount cycle.
Pick delta pad earlier during header parsing, and pick it based
on whether it's a video stream or not rather than some rather
byzantine signalling from theoraenc etc. which would set the delta
flag on header packets which oggmux would then pick up and determine
that this is a "delta-able" stream.
Since the new videodecoder-based theoraenc didn't do that any more,
we would only see the first delta flag on the second video packet,
which is after we've already muxed a few audio packets flagged as
key units, which trips up the unit test.
Fixes pipelines/oggmux unit test.
https://bugzilla.gnome.org/show_bug.cgi?id=679958
A crafted file with invalid pages will cause repeated searches from
earlier offsets in steps of 8500 bytes, but reading till the end of
the stream. Since we know the maximum size of an Ogg page, we can
bound the search for next page, to get a linear behavior (though
still not good enough as it will read the entire file backwards if
there's no valid page till then).
Take chain lock when accessing chains. Fall back gracefully
when there's no current chain Hopefully fixes crash when
seeking in Jamendo or Magnatune streams in Amarok.
https://bugzilla.gnome.org/show_bug.cgi?id=675609
They're hardly used, and probably more confusing than anything
else, and it's not clear that anyone would really need to be
able to tell them apart at the media type level.
This never really took off - it's hardly used anywhere
and deprecated in favour of Kate. Exposing pads just
leads to confusing 'you are missing a plug-in' messages
when people come across such streams. We could still post
the data on the bus for applications to parse.
In case many packets fit on a page, we may not see a granpos for
a while, and granpos interpolation can wrap the 'frames since last
keyframe' part of the granpos, generating a granpos which is smaller
than what it should be.
This is fixed by detecting keyframe packets (at least for Theora),
and updating the last keyframe granpos from this.
This may still be generating potentially wrong granpos for streams
which have a Theora like granpos (keyframes, a max keyframe distance
and a count of frames since last keyframe), and which allow implicit
granules on packets. For these streams, a custom keyframe detection
routine should be plugged into their GstOggStream mapper.
https://bugzilla.gnome.org/show_bug.cgi?id=669164
When I first implemented push mode seeking, I removed the chain
freeing there as it could be used later. The current code does not
seem to do that though, so I'm restoring the previous freeing,
which plugs the leak while apparently not reintroducing use of
freed data with chained and normal files, both with gst-launch
playbin2 and Totem.
This reverts commit 5df30c1b90.
I must have dreamt the Valgrind logs, reverting this reintroduces
no leak, and gets rid of the test failures it introduced :S
A first hang was happening when trying to locate a page backwards,
where we'd sync forever on the same page.
With that fixed, a second hang would happen after preparing an EOS
event, but with no chain created yet to send it to, the pipeline
would stay idle forever.
An element error is now emitted for this case.
Pads are initialized twice: when requesting pads and when
initializing collectpads. Avoid double initialization by
checking if collectpads are still going to be initialized when
creating request pads.
This prevents trying to seek and failing, then ending up unable
to stream because we can't get back at the headers.
A more robust way would be to find a good place to reinject the
headers when a seek fails, but I can't seem to get this to work.
Add private replacements for deprecated functions such as
g_mutex_new(), g_mutex_free(), g_cond_new() etc., mostly
to avoid the deprecation warnings. We'll change these
over to the new API once we depend on glib >= 2.32.
Replace g_thread_create() with g_thread_try_new().
If we already saw the keyframes that we need to find,
we do not need to bisect to find them.
This will always be the case for streams with audio only,
where each frame acts as a keyframe, but will occasionally
also happen for streams with video.
https://bugzilla.gnome.org/show_bug.cgi?id=662475