Commit graph

197 commits

Author SHA1 Message Date
Thiago Santos
4ab1d9f21f hlsdemux: handle more error cases
Handle some more error cases:

1) When the source element fails to go to ready
2) When decryption fails
3) When there is no source to handle a specific URI
4) When the URI is invalid
2014-04-29 18:49:15 -03:00
Thiago Santos
4431388cab hlsdemux: handle errors from internal source
Set up a message handling function to catch errors from the internal
source and store the last return code to identify error situations
when returning from a fragment download.

Also moves the duration increase to after the download when we
know if it was successful or not
2014-04-29 18:49:15 -03:00
Thiago Santos
f16560c520 hlsdemux: Improve pad switching conditions
When using the internal source, hlsdemux doesn't know the caps of
the input before adding the pad, so remove the arguments that would
use that as it is always NULL.

And use an specific flag to signal when a pad switch is required.
Using the discont flag is a bad idea now because when a fragment
download fails it will lead to exposing a pad group without any
data, causing decodebin to abort.
2014-04-29 18:49:15 -03:00
Thiago Santos
587851ba10 hlsdemux: properly flush decryption status on seeks
Avoids mixing decryption of different fragments when seeking happens
and leading to broken stream output.
2014-04-29 18:49:15 -03:00
Thiago Santos
ff395a7565 hlsdemux: Track fragments duration
When receving EOS from the internal src, increase the current positon
by the fragment duration to allow correct restoring of download position
if the bitrate changes
2014-04-29 18:49:15 -03:00
Thiago Santos
2b73e86881 hlsdemux: properly stop tasks by stopping fragment download
Issue a signal to the fragment download cond to stop
the task earlier
2014-04-29 18:49:15 -03:00
Thiago Santos
60eec1443a hlsdemux: decrypt before typefinding
Make sure typefinding gets the decrypted content instead of
trying to typefind the encrypted data.
2014-04-29 18:49:15 -03:00
Thiago Santos
cc262b0923 hlsdemux: fix decryption function return
Correctly return the decrypted buffer when it succeeds and
return NULL otherwise
2014-04-29 18:49:15 -03:00
Thiago Santos
f6b0cae8b6 hlsdemux: keep connection alive between downloads
Use the same properties as uridownloader to keep connections alive
between consecutive fragments downloads.

1) set keep-alive property to true
2) keep the element in READY instead of in NULL
2014-04-29 18:17:07 -03:00
Thiago Santos
4b9d91d497 hlsdemux: create sources from uri
Instead of using always an http source, create it dynamically from
uri when needed. If not needed just replace the URI on the current
element
2014-04-29 18:17:07 -03:00
Thiago Santos
671f8c0e35 hlsdemux: do not try to run typefind again if caps is the same
Always reset the do_typefind flag if hls did typefind because
trying it on non-zero offsets doesn't make sense and will cause
assertions
2014-04-29 18:17:07 -03:00
Thiago Santos
cc033c7ca0 hlsdemux: enable download bitrate measure
Measure the download bitrate to be able to select
the best playlist.

As the buffers are directly pushed downstream and it
might block. The time is only measured from the download
until the pad push and it is started again after the push
returns.
2014-04-29 18:17:07 -03:00
Thiago Santos
c93c222786 hlsdemux: re-enable decryption after uridownloader removal
Now the decryption is done buffer by buffer instead of on the
whole fragment at once. As it expects multiples of 16 bytes a
GstAdapter was added to properly chunk the buffers.

Also the last buffer must be resized depending on the value of the
last byte of the fragment, so hlsdemux always keeps a pending buffer
as it doesn't know if it is the last one yet
2014-04-29 18:17:07 -03:00
Thiago Santos
3611759557 hlsdemux: replace uridownloader with a GstElement
The GstElement is directly linked into a ghost pad and
its buffers are pushed as received downstream. This way the
buffers are small enough and not a whole fragment that usually
causes extra latency and makes buffering harder
2014-04-29 18:17:07 -03:00
Sebastian Dröge
b47c92df82 hlsdemux: Set Referer in requests to the playlist URI 2014-04-28 10:04:28 +02:00
Tim-Philipp Müller
dbe6fdd6bf docs: remove outdated and pointless 'Last reviewed' lines from docs
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.
2014-04-27 00:36:32 +01:00
Sebastian Dröge
f82d9ec4a9 hlsdemux: Also update the sequence position when updating non-live playlists 2014-04-10 16:53:42 +02:00
Sebastian Dröge
a06d4ea408 hlsdemux: Try reloading the playlist first if downloading a fragment fails
But only add this for non-live playlists. For live playlists we already
have another thread that is periodically updating playlists.

Reason for this is that sometimes downloading a fragment can fail because
the URIs have changed or expired since last time.
2014-04-10 15:06:53 +02:00
Sebastian Dröge
864399f299 hlsdemux: When updating a non-live playlist make sure to find the current sequence by time
Sequence numbers in different playlists are not guaranteed to be the same for the
same position, e.g. fragments could have different durations in different playlists.

In theory we should do exactly the same for live playlists, but unfortunately we can't
because doing this kind of seeking requires the complete playlist since we started
playback. For live playlists the server is however dropping fragments in the beginning
over time and we have no absolute time references.
2014-04-10 15:06:53 +02:00
Vincent Penquerc'h
b3a18a2fcc hlssink: catch failure to write playlist file
Coverity 1139613
2014-04-09 18:44:38 +01:00
Vincent Penquerc'h
a78e516cbf hls: restore NULL test mistakenly removed
Thanks to tpm for point out I'm an idiot.
2014-04-08 17:10:27 +01:00
Vincent Penquerc'h
c319b1cc8f hls: only set DISCONT flag on a valid buffer
Recent refactoring causes this code to be called with either a NULL
fragment, or a non NULL fragment. In the former case, we don't have
a buffer. In the latter case, the original code dealing with DISCONT
assumed the buffer was valid. Testing for a NULL buffer here thus
does not seem to change the intent, and fixes:

Coverity 1195147
2014-04-08 16:56:04 +01:00
Vincent Penquerc'h
45b8225a02 hls: bring NULL test before dereference
Coverity 1195168
2014-04-08 16:46:56 +01:00
Sebastian Dröge
b86e502a8b hlsdemux: Handle errors when switching playlists properly 2014-03-30 19:22:25 +02:00
Sebastian Dröge
89ca4535eb hlsdemux: Go EOS if the end of the segment is reached 2014-03-30 19:22:25 +02:00
Sebastian Dröge
911023eb88 hlsdemux: Store buffer end position in segment.position 2014-03-30 19:22:24 +02:00
Sebastian Dröge
f701755b83 hlsdemux: Don't set the segment offset
It's causing wrong running times after seeks or bitrate
switches.
2014-03-29 10:33:45 +01:00
Sebastian Dröge
e11a99e26a hlsdemux: Set DISCONT flag on all buffers in reverse playback mode 2014-03-29 10:33:45 +01:00
Sebastian Dröge
8109ed8785 hlsdemux: Fix forwards and backwards searching in the files list 2014-03-29 10:33:45 +01:00
Sebastian Dröge
6039734f3e hlsdemux: Unset DTS of all buffers
We won't get a valid DTS from the source.
2014-03-29 10:33:45 +01:00
Sebastian Dröge
cad284e843 hlsdemux: Send flush start event before waiting for the tasks to finish
Otherwise we'll wait until buffers are completely processed downstream,
which might take quite some time.
2014-03-29 10:33:45 +01:00
Sebastian Dröge
91ec00a0c0 hlsdemux: Implement trick modes via I-frame variant lists 2014-03-29 10:33:45 +01:00
Sebastian Dröge
77231ab957 hlsdemux: Implement parsing of #EXT-X-I-FRAME-STREAM-INF
These are I-frame-only variant lists that can be used
for trick mode playback.
2014-03-29 10:33:45 +01:00
Sebastian Dröge
7ddd67baef hlsdemux: Always calculate the current download rate
Also take into account the last download rate when
calculating it.
2014-03-12 12:35:22 +01:00
Sebastian Dröge
bd54a212d3 hlsdemux: Fix comparison in bitrate selection 2014-03-09 20:50:44 +01:00
Sebastian Dröge
c9bb878fe5 m3u8: Fix off-by-one in the download range end 2014-03-07 16:24:19 +01:00
Sebastian Dröge
d2880dce68 hlsdemux: Implement proper segment handling
https://bugzilla.gnome.org/show_bug.cgi?id=695846
https://bugzilla.gnome.org/show_bug.cgi?id=723268
2014-03-06 23:16:56 +01:00
Sebastian Dröge
cd02546089 hlsdemux: Implement handling of byte ranges 2014-03-06 16:36:10 +01:00
Zallesov
7ed08a1326 hlsdemux: Fix seeking further than track duration
Don't fail the seek but instead send an EOS event from the streaming thread.
2014-03-06 09:39:22 +01:00
Sebastian Dröge
5d5ca5139e hlsdemux: Switch playlists after pushing the fragment
Makes sure we properly set the discont flag for the next buffer,
not the current one.
2014-03-05 20:44:02 +01:00
Sebastian Dröge
0a32c5f7a4 hlsdemux: Implement proper handling of discontinuities
It's not really correct yet for seeks but better than what
we had before.

See https://bugzilla.gnome.org/show_bug.cgi?id=695846
2014-03-01 17:15:54 +01:00
Alex Ashley
b7ef52c515 hlsdemux: Segfaults if playlist has no media files
hlsdemux causes a null pointer dereference if the media playlist
does not contain any media files. The gst_m3u8_client_get_duration
function assumes that demux->client->current->files is valid when
computing duration.

gst_m3u8_client_update needed to be modified to check for the
case of downloading an M3U8 file that doesn't contain any media
files, and returning an error to gsthlsdemux.c

This bug can be reproduced by creating a master m3u8 file that
contains one media playlist that points back to the master m3u8
file.  For example create a file called bug725134.m3u8:
  #EXTM3U
  #EXT-X-VERSION:4
  #EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=1251135, CODECS="avc1.42001f mp4a.40.2", RESOLUTION=640x352
  bug725134.m3u8

https://bugzilla.gnome.org/show_bug.cgi?id=725134
2014-03-01 16:34:59 +01:00
Sebastian Dröge
874af7db4e hlsdemux: Init and clear a mutex
GLib initialises automatically for us for some reason... but of course
does not clear the mutex once the demuxer is destroyed.
2014-02-27 15:50:12 +01:00
Sebastian Dröge
5f0a5c3594 hlsdemux: Unref seek events before returning from the seek handler
Otherwise we leak them all.
2014-02-27 15:41:30 +01:00
Alex Ashley
161254d7c0 hlsdemux: Fix parsing of CODECS and RESOLUTION
hlsdemux does not check for the '"' character in #EXT-X-STREAM-INF
attributes. The CODECS parameter is an example of an attribute
that might use the '"' symbol and might contain a ',' character
inside this quoted string.

For example: CODECS="avc1.77.30, mp4a.40.2"

hlsdemux does not correctly parse the RESOLUTION attribute, it
assumes that an '=' character is used to delineate the width
and height values, but the HLS RFC states that a 'x' character
must be used as the delimiter between width and height.

https://bugzilla.gnome.org/show_bug.cgi?id=725140
2014-02-26 09:23:22 +01:00
Alex Ashley
91775a1abd hlsdemux: Fix for URLs that contain a '/' in the query parameter
If the URL for the master manifest files contains a '/' character
in the query parameter (for example
http://example.net/1054559_h264_1500k.mp4/master.m3u8?acl=/*1054559_h264_1500k.mp4),
hlsdemux is incorrectly converting the relative URLs of the media
playlists in to absolute URLs. It is incorrectly using the last '/' it
finds in the URL. According to RFC3986 the '/' character is allowed in
the query part of the URL.

https://bugzilla.gnome.org/show_bug.cgi?id=725137
2014-02-26 09:20:58 +01:00
Sebastian Dröge
b3a7242910 hlsdemux: Keep track of timestamps by adding them up during playback
...instead of adding them from the start of playlist every time. This
among other things fixes timestamps for live streams, where the playlist
is some kind of ringbuffer of fragments and thus adding from the beginning
of the playlist will miss the past fragments.

https://bugzilla.gnome.org/show_bug.cgi?id=724983
2014-02-23 15:18:22 +01:00
Sebastian Dröge
090bf91974 hlsdemux: Deprecate fragments-cache property
The buffering/caching is handling completely different now and
outside of hlsdemux.
2014-02-23 11:01:57 +01:00
Sebastian Dröge
b47a4faf5f ext: Use Codec/Demuxer/Adaptive for the adaptive streaming demuxers 2014-02-23 00:11:04 +01:00
Sebastian Dröge
a51116add3 hlsdemux: Refactor threading and downloading
We now download fragments as fast as possible and push them downstream
while another thread is just responsible for updating live playlists
every now and then.

This simplifies the code a lot and together with the new buffering
mode for adaptive streams in multiqueue makes streams start much faster.

Also simplify threading a bit and hopefully make the GstTask usage safer.
2014-02-23 00:10:45 +01:00
Sebastian Dröge
76e74547c7 hlsdemux: Only switch pads if the caps are changing 2014-02-23 00:10:45 +01:00
Andoni Morales Alastruey
99feef2d08 hlsdemux: fix update interval with respect of the spec 2014-02-14 13:07:39 +01:00
Sebastian Dröge
e40b72bc9b hlsdemux: Ignore empty lines in the playlist
Based on a patch by Andoni Morales.
2014-02-12 18:50:09 +01:00
Sebastian Dröge
65c1faf553 hlsdemux: Make sure to ignore \r in line endings in every case 2014-02-12 18:47:45 +01:00
Sebastian Dröge
13997abbf9 hlsdemux: Give a proper name to the srcpads and remove it when resetting the element 2014-02-12 18:27:21 +01:00
Sebastian Dröge
adea24cdf8 hlsdemux: Stop leaking GErrors in some error paths 2014-02-12 16:46:31 +01:00
Gil Pedersen
62ddd34807 hlsdemux: don't pause task when it is stopped
This fixes a potential dead-lock situation from GstTask

https://bugzilla.gnome.org/show_bug.cgi?id=675869
2014-02-12 16:04:52 +01:00
Sebastian Dröge
281f2f3590 hlsdemux: Wait for the update task to finish when shutting down 2014-02-12 16:01:05 +01:00
Sebastian Dröge
4dcacc1773 hlsdemux: Prevent rounding errors due to division by using gst_util_uint64_scale() 2014-02-12 15:33:06 +01:00
Arnaud Vrac
6e54b8ee53 hlsdemux: schedule next update based on the fragment duration 2014-02-12 15:18:29 +01:00
Sebastian Dröge
05efcbf757 hlsdemux: Properly error out if caps can't be typefind instead of using NULL caps 2014-02-12 15:16:23 +01:00
Arnaud Vrac
63e18bb7bf hlsdemux: log fragment timestamp 2014-02-12 14:39:15 +01:00
Sebastian Dröge
dc45d236d2 hlsdemux: Use g_ascii_xdigit_value() instead of our own version of it 2014-02-12 14:10:02 +01:00
Sebastian Dröge
a84220a658 hlsdemux: Error out if the key is not 16 bytes large 2014-02-12 13:40:41 +01:00
Sebastian Dröge
8c3ef21a68 hlsdemux: Download playlists with compression, keys and fragments without 2014-02-12 13:13:30 +01:00
Sebastian Dröge
245a7d94f5 hlsdemux: Don't set the element private data on the srcpads
It's not used anyway.
2014-02-12 11:26:04 +01:00
Sebastian Dröge
60f1dadd1c hlsdemux: Use gst_pad_use_fixed_caps() on the srcpads 2014-02-12 11:25:41 +01:00
Sebastian Dröge
bc42a18f92 hlsdemux: Cache the key fragment instead of downloading it over and over again 2014-02-12 10:59:38 +01:00
Sebastian Dröge
792d1e0109 hlsdemux: Fix cleanup when decryption fails
First unmap buffers, then unref them. And also unref the
key fragment.
2014-02-12 10:58:45 +01:00
Sebastian Dröge
5e55bae14b hlsdemux: Don't try decryption if an unsupported method is found 2014-02-11 18:15:45 +01:00
Sebastian Dröge
56faad51bb hlsdemux: Properly parse IV from the playlist
Without this every fragment's first 16 bytes will be corrupted
if not the fallback IV is used by the playlist.
2014-02-11 18:15:07 +01:00
Sebastian Dröge
591598da48 hlsdemux: Propagate download errors properly and post error messages if they're fatal 2014-02-11 14:57:16 +01:00
Sebastian Dröge
3a5abc233d ext: Update for GstUriDownloader API changes 2014-02-11 14:18:32 +01:00
Sebastian Dröge
73d9a8b0c9 hlsdemux: Start downloading the next fragment immediately after caching the initial fragments
And only afterwards wait until a fragment was played. Otherwise we're keeping
our cache most of the time at "fragments-cache" fragments minus one.

Also allow setting "fragments-cache" to 1 now to start playback even faster.
2014-02-10 18:30:21 +01:00
Sebastian Dröge
4f04f3e68e hlsdemux: Start fetching new fragments whenever we have less fragments cached than given by the fragments-cache property
Waiting until our cache is empty before starting to fetch the next fragment
kind of defeats the purpose of caching multiple fragments.
2014-02-10 18:27:58 +01:00
Sebastian Dröge
89c592ccdd hlsdemux: Fix bitrate calculation
g_get_monotonic_time() returns microseconds, not nanoseconds.
2014-02-10 18:21:38 +01:00
Sebastian Dröge
a4847fd4db hlsdemux: Actually store doubles as such and don't truncate them to ints
Fixes broken duration reporting.
2014-02-10 17:27:10 +01:00
Sebastian Dröge
a5387eb372 hlsdemux: Use locale-independent int/float parsing functions from GLib 2014-02-10 17:27:10 +01:00
Sebastian Dröge
6799e3b879 hlsdemux: Prefer to use nettle for decryption but fall-back to libgcrypt
nettle is used by newer versions of gnutls, while older versions of gnutls
used libgcrypt. Support both for now as not every distro has nettle yet.

nettle is preferred as it is more efficient to use and much smaller.
2014-02-09 18:52:24 +01:00
Sebastian Dröge
6abed8da20 hlsdemux: Update to non-deprecated GLib thread API 2014-02-09 18:19:33 +01:00
Sebastian Dröge
e8befb7ce3 hlsdemux: Use libgcrypt directly instead of going through gnutls
gnutls is also just wrapping gcrypt, but we don't need any of
the TLS related functionality. We just need to be able to decrypt
AES128-CBC.
2014-02-09 18:09:36 +01:00
Thiago Santos
d59af97930 hlssink: do not lose ref to the multifilesink
It is needed to update location properties and it was being lost on
state changes, causing issues if the pipeline was to be reused
2013-11-07 12:50:55 -03:00
Thiago Santos
805e313cce hlssink: make sure it is handled as a sink
It only gets the sink flag set when it adds the multifilesink, that
happens in null->ready and it might be too late. Set the flag
explicitly on the constructor.

https://bugzilla.gnome.org/show_bug.cgi?id=711086
2013-11-07 12:50:55 -03:00
Alex Ashley
58072914fa hlsdemux: fix memory leak in gst_hls_demux_get_next_fragment
This patch fixes three memory leaks in hlsdemux, one that occurs
during normal operation and two that occur during error conditions.

The gst_hls_demux_get_next_fragment function calls
gst_fragment_get_buffer which increments the reference count
on the buffer but gst_hls_demux_get_next_fragment never calls unref on
the buffer. This means that the reference count for each downloaded
fragment never gets to zero and so its memory is never released.

This patch adds a call to gst_buffer_unref after the flags have been
updated on the buffer.

There is a leak-on-error in gst_hls_demux_decrypt_fragment if it fails
to download the key file. If the key fails to download, null is
returned without doing an unref on the encrypted fragment. The
semantics of gst_hls_demux_decrypt_fragment is that it takes ownership
of the encrypted fragment and releases it before returning.

There is a leak-on-error in gst_hls_src_buf_to_utf8_playlist in the
unlikely event that the gst_buffer_map fails. In the "happy path"
operation of gst_hls_src_buf_to_utf8_playlist the buffer gets an unref
before the function returns, therefore the error condition must do the
same.

https://bugzilla.gnome.org/show_bug.cgi?id=710881
2013-10-25 23:12:25 -03:00
Thiago Santos
9a50ca5fbc hlsdemux: Small improvement on always valid if condition
No need to check for !cancelled as the above if guarantees it
to be true
2013-10-03 09:15:37 -03:00
Thiago Santos
72e05dfd7c hlsdemux: Do not call _stop holding the updates lock
It will cause a deadlock and the calers for _get_next_fragment
will already call _stop if required when _get_next_fragment fails.

Fixes #690148
2013-10-03 09:15:37 -03:00
Javier Jardón
a1cc9ca4de hlssink: Use floats for the EXTINF duration values
https://bugzilla.gnome.org/show_bug.cgi?id=708851
2013-09-28 13:20:08 +02:00
Javier Jardón
203f527653 hlssink: Write EXT-X-VERSION tag in the playlist file
https://bugzilla.gnome.org/show_bug.cgi?id=708851
2013-09-28 13:20:08 +02:00
Alex Ashley
0bdf13c36a hlsdemux: Fix dereferencing of NULL pointer
On some live HLS streams, gst_hls_demux_switch_playlist causes
assertion failures because it tried to dereference a NULL fragment.
This is because g_queue_peek_tail sometimes was returning NULL and
this case was not being checked.

This patch does two things:
* move the g_queue_peek_tail inside the semaphore protection
* check if q_queue_peek_tail returns NULL

https://bugzilla.gnome.org/show_bug.cgi?id=708849
2013-09-28 13:14:01 +02:00
Olivier Crête
b92791d102 hlsdemux: Reset GstUriDownloader cancellation when restarting to play 2013-09-17 17:41:39 -04:00
Andoni Morales Alastruey
28609ca93c hlsdemux: add support for redirections 2013-08-12 16:41:52 +02:00
Sebastian Dröge
b9124cad88 hlsdemux: Implement pkcs7 unpadding
Every encrypted fragment will be a multiple of 128 bits, the last byte
contains the number of bytes that were added as padding in the end
and should be removed.

https://bugzilla.gnome.org/show_bug.cgi?id=701673
2013-07-23 13:30:52 +02:00
Sebastian Dröge
e63094abd5 hlsdemux: Add support for group-id in the stream-start event 2013-07-23 10:33:31 +02:00
Alex Ashley
ed16c9c560 hls: fix for assert failure when using encrypted HLS streams
When using an HLS encrypted stream, an assertion failure is thrown:
(gst-launch-1.0:31028): GLib-GObject-WARNING **: cannot register
existing type `GstFragment'

(gst-launch-1.0:31028): GLib-CRITICAL **: g_once_init_leave: assertion
`result != 0' failed

Eventually tracked this down to the call gst_fragment_new()
in function gst_hls_demux_decrypt_fragment.

The GstFragment class is defined in ext/hls/gstfragment.c and in
gst-libs/gst/uridownloader/gstfragment.c. Having two class definitions
with the same name causes the assert failure when trying to allocate
GstFragment. Deleting the version from hls and editing the
Makefile.am solves this assert failure.

https://bugzilla.gnome.org/show_bug.cgi?id=704555
2013-07-22 14:55:17 +01:00
Sebastian Dröge
1c16489af7 hls: Use GstURIDownloader from the library for now to keep everything in a usable state 2013-05-15 09:21:21 +02:00
Sebastian Dröge
e51cd4fe2f gst: Add better support for static plugins 2013-04-15 15:59:22 +02:00
Alessandro Decina
d2d6798087 Make the hls plugin depend on gnutls and move to ext/hls/
gnutls is used to implement AES decryption
2013-03-19 10:54:18 +01:00