mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 18:21:04 +00:00
adaptivedemux: add adaptivedemux base class
https://bugzilla.gnome.org/show_bug.cgi?id=735848
This commit is contained in:
parent
83d9353d58
commit
9ec9f3f119
5 changed files with 2701 additions and 2 deletions
|
@ -3237,6 +3237,7 @@ gst/yadif/Makefile
|
|||
gst/compositor/Makefile
|
||||
gst-libs/Makefile
|
||||
gst-libs/gst/Makefile
|
||||
gst-libs/gst/adaptivedemux/Makefile
|
||||
gst-libs/gst/basecamerabinsrc/Makefile
|
||||
gst-libs/gst/gl/Makefile
|
||||
gst-libs/gst/gl/android/Makefile
|
||||
|
|
|
@ -10,9 +10,9 @@ if USE_WAYLAND
|
|||
WAYLAND_DIR=wayland
|
||||
endif
|
||||
|
||||
SUBDIRS = interfaces basecamerabinsrc codecparsers \
|
||||
SUBDIRS = adaptivedemux interfaces basecamerabinsrc codecparsers \
|
||||
insertbin uridownloader mpegts base video $(GL_DIR) $(WAYLAND_DIR)
|
||||
|
||||
noinst_HEADERS = gst-i18n-plugin.h gettext.h glib-compat-private.h
|
||||
DIST_SUBDIRS = interfaces gl basecamerabinsrc codecparsers \
|
||||
DIST_SUBDIRS = adaptivedemux interfaces gl basecamerabinsrc codecparsers \
|
||||
insertbin uridownloader mpegts wayland base video
|
||||
|
|
35
gst-libs/gst/adaptivedemux/Makefile.am
Normal file
35
gst-libs/gst/adaptivedemux/Makefile.am
Normal file
|
@ -0,0 +1,35 @@
|
|||
|
||||
lib_LTLIBRARIES = libgstadaptivedemux-@GST_API_VERSION@.la
|
||||
|
||||
CLEANFILES = $(BUILT_SOURCES)
|
||||
|
||||
libgstadaptivedemux_@GST_API_VERSION@_la_SOURCES = \
|
||||
gstadaptivedemux.c
|
||||
|
||||
libgstadaptivedemux_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/adaptivedemux
|
||||
|
||||
noinst_HEADERS = gstadaptivedemux.h
|
||||
|
||||
libgstadaptivedemux_@GST_API_VERSION@_la_CFLAGS = \
|
||||
$(GST_PLUGINS_BAD_CFLAGS) \
|
||||
$(GST_PLUGINS_BASE_CFLAGS) \
|
||||
-DGST_USE_UNSTABLE_API \
|
||||
$(GST_CFLAGS)
|
||||
libgstadaptivedemux_@GST_API_VERSION@_la_LIBADD = \
|
||||
-lgstapp-$(GST_API_VERSION) $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) $(GST_LIBS)
|
||||
|
||||
libgstadaptivedemux_@GST_API_VERSION@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) $(GST_LT_LDFLAGS)
|
||||
|
||||
Android.mk: Makefile.am
|
||||
androgenizer -:PROJECT libgstadaptivedemux -:STATIC libgstadaptivedemux-@GST_API_VERSION@ \
|
||||
-:TAGS eng debug \
|
||||
-:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
|
||||
-:SOURCES $(libgstadaptivedemux_@GST_API_VERSION@_la_SOURCES) \
|
||||
-:CFLAGS $(DEFS) $(libgstadaptivedemux_@GST_API_VERSION@_la_CFLAGS) \
|
||||
-:LDFLAGS $(libgstadaptivedemux_@GST_API_VERSION@_la_LDFLAGS) \
|
||||
$(libgstadaptivedemux_@GST_API_VERSION@_la_LIBADD) \
|
||||
-ldl \
|
||||
-:HEADER_TARGET gstreamer-@GST_API_VERSION@/gst/adaptivedemux \
|
||||
-:HEADERS $(libgstadaptivedemuxinclude_HEADERS) \
|
||||
-:PASSTHROUGH LOCAL_ARM_MODE:=arm \
|
||||
> $@
|
2291
gst-libs/gst/adaptivedemux/gstadaptivedemux.c
Normal file
2291
gst-libs/gst/adaptivedemux/gstadaptivedemux.c
Normal file
File diff suppressed because it is too large
Load diff
372
gst-libs/gst/adaptivedemux/gstadaptivedemux.h
Normal file
372
gst-libs/gst/adaptivedemux/gstadaptivedemux.h
Normal file
|
@ -0,0 +1,372 @@
|
|||
/* GStreamer
|
||||
*
|
||||
* Copyright (C) 2014 Samsung Electronics. All rights reserved.
|
||||
* Author: Thiago Santos <thiagoss@osg.samsung.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _GST_ADAPTIVE_DEMUX_H_
|
||||
#define _GST_ADAPTIVE_DEMUX_H_
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/base/gstadapter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_ADAPTIVE_DEMUX \
|
||||
(gst_adaptive_demux_get_type())
|
||||
#define GST_ADAPTIVE_DEMUX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ADAPTIVE_DEMUX,GstAdaptiveDemux))
|
||||
#define GST_ADAPTIVE_DEMUX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ADAPTIVE_DEMUX,GstAdaptiveDemuxClass))
|
||||
#define GST_ADAPTIVE_DEMUX_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_ADAPTIVE_DEMUX,GstAdaptiveDemuxClass))
|
||||
#define GST_IS_ADAPTIVE_DEMUX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ADAPTIVE_DEMUX))
|
||||
#define GST_IS_ADAPTIVE_DEMUX_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ADAPTIVE_DEMUX))
|
||||
#define GST_ADAPTIVE_DEMUX_CAST(obj) ((GstAdaptiveDemux *)obj)
|
||||
|
||||
#define GST_ADAPTIVE_DEMUX_STREAM_CAST(obj) ((GstAdaptiveDemuxStream *)obj)
|
||||
|
||||
/**
|
||||
* GST_ADAPTIVE_DEMUX_SINK_NAME:
|
||||
*
|
||||
* The name of the templates for the sink pad.
|
||||
*/
|
||||
#define GST_ADAPTIVE_DEMUX_SINK_NAME "sink"
|
||||
|
||||
/**
|
||||
* GST_ADAPTIVE_DEMUX_SINK_PAD:
|
||||
* @obj: a #GstAdaptiveDemux
|
||||
*
|
||||
* Gives the pointer to the sink #GstPad object of the element.
|
||||
*/
|
||||
#define GST_ADAPTIVE_DEMUX_SINK_PAD(obj) (((GstAdaptiveDemux *) (obj))->sinkpad)
|
||||
|
||||
#define GST_ADAPTIVE_DEMUX_STREAM_PAD(obj) (((GstAdaptiveDemuxStream *) (obj))->pad)
|
||||
|
||||
#define GST_ADAPTIVE_DEMUX_STREAM_NEED_HEADER(obj) (((GstAdaptiveDemuxStream *) (obj))->need_header)
|
||||
|
||||
#define STATISTICS_MESSAGE_NAME "adaptive-streaming-statistics"
|
||||
|
||||
#define GST_MANIFEST_GET_LOCK(d) (&(GST_ADAPTIVE_DEMUX_CAST(d)->manifest_lock))
|
||||
#define GST_MANIFEST_LOCK(d) (g_mutex_lock (GST_MANIFEST_GET_LOCK (d)))
|
||||
#define GST_MANIFEST_UNLOCK(d) (g_mutex_unlock (GST_MANIFEST_GET_LOCK (d)))
|
||||
|
||||
#define GST_ELEMENT_ERROR_FROM_ERROR(el, msg, err) G_STMT_START { \
|
||||
gchar *__dbg = g_strdup_printf ("%s: %s", msg, err->message); \
|
||||
GST_WARNING_OBJECT (el, "error: %s", __dbg); \
|
||||
gst_element_message_full (GST_ELEMENT(el), GST_MESSAGE_ERROR, \
|
||||
err->domain, err->code, \
|
||||
NULL, __dbg, __FILE__, GST_FUNCTION, __LINE__); \
|
||||
g_clear_error (&err); \
|
||||
} G_STMT_END
|
||||
|
||||
typedef struct _GstAdaptiveDemuxStreamFragment GstAdaptiveDemuxStreamFragment;
|
||||
typedef struct _GstAdaptiveDemuxStream GstAdaptiveDemuxStream;
|
||||
typedef struct _GstAdaptiveDemux GstAdaptiveDemux;
|
||||
typedef struct _GstAdaptiveDemuxClass GstAdaptiveDemuxClass;
|
||||
typedef struct _GstAdaptiveDemuxPrivate GstAdaptiveDemuxPrivate;
|
||||
|
||||
struct _GstAdaptiveDemuxStreamFragment
|
||||
{
|
||||
GstClockTime timestamp;
|
||||
GstClockTime duration;
|
||||
|
||||
gchar *uri;
|
||||
gint64 range_start;
|
||||
gint64 range_end;
|
||||
|
||||
/* when headers are needed */
|
||||
gchar *header_uri;
|
||||
gint64 header_range_start;
|
||||
gint64 header_range_end;
|
||||
|
||||
/* when index is needed */
|
||||
gchar *index_uri;
|
||||
gint64 index_range_start;
|
||||
gint64 index_range_end;
|
||||
};
|
||||
|
||||
struct _GstAdaptiveDemuxStream
|
||||
{
|
||||
GstPad *pad;
|
||||
|
||||
GstAdaptiveDemux *demux;
|
||||
|
||||
GstSegment segment;
|
||||
|
||||
GstCaps *pending_caps;
|
||||
GstEvent *pending_segment;
|
||||
GstTagList *pending_tags;
|
||||
gboolean need_header;
|
||||
|
||||
GstFlowReturn last_ret;
|
||||
GError *last_error;
|
||||
|
||||
GstTask *download_task;
|
||||
GRecMutex download_lock;
|
||||
|
||||
gboolean restart_download;
|
||||
gboolean discont;
|
||||
|
||||
/* download tooling */
|
||||
GstElement *src;
|
||||
GstPad *src_srcpad;
|
||||
GMutex fragment_download_lock;
|
||||
GCond fragment_download_cond;
|
||||
gboolean download_finished;
|
||||
gboolean starting_fragment;
|
||||
gboolean first_fragment_buffer;
|
||||
gint64 download_start_time;
|
||||
gint64 download_total_time;
|
||||
gint64 download_total_bytes;
|
||||
gint current_download_rate;
|
||||
|
||||
GstAdaptiveDemuxStreamFragment fragment;
|
||||
|
||||
guint download_error_count;
|
||||
|
||||
/* TODO check if used */
|
||||
gboolean eos;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstAdaptiveDemux:
|
||||
*
|
||||
* The opaque #GstAdaptiveDemux data structure.
|
||||
*/
|
||||
struct _GstAdaptiveDemux
|
||||
{
|
||||
/*< private >*/
|
||||
GstBin bin;
|
||||
|
||||
gsize stream_struct_size;
|
||||
|
||||
/*< protected >*/
|
||||
GstPad *sinkpad;
|
||||
|
||||
GstAdaptiveDemuxPrivate *priv;
|
||||
|
||||
GList *streams;
|
||||
GList *next_streams;
|
||||
|
||||
GstSegment segment;
|
||||
|
||||
gboolean cancelled;
|
||||
|
||||
GMutex manifest_lock;
|
||||
GCond manifest_cond;
|
||||
|
||||
gchar *manifest_uri;
|
||||
gchar *manifest_base_uri;
|
||||
|
||||
gboolean have_group_id;
|
||||
guint group_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstAdaptiveDemuxClass:
|
||||
*
|
||||
*/
|
||||
struct _GstAdaptiveDemuxClass
|
||||
{
|
||||
/*< private >*/
|
||||
GstBinClass bin_class;
|
||||
|
||||
/*< public >*/
|
||||
|
||||
/**
|
||||
* process_manifest: Parse the manifest
|
||||
* @demux: #GstAdaptiveDemux
|
||||
* @manifest: the manifest to be parsed
|
||||
*
|
||||
* Parse the manifest and add the created streams using
|
||||
* gst_adaptive_demux_stream_new()
|
||||
*
|
||||
* Returns: #TRUE if successful
|
||||
*/
|
||||
gboolean (*process_manifest) (GstAdaptiveDemux * demux, GstBuffer * manifest);
|
||||
|
||||
/**
|
||||
* get_manifest_update_interval:
|
||||
* @demux: #GstAdaptiveDemux
|
||||
*
|
||||
* Used during live streaming, the subclass should return the interval
|
||||
* between successive manifest updates
|
||||
*
|
||||
* Returns: the update interval in microseconds
|
||||
*/
|
||||
gint64 (*get_manifest_update_interval) (GstAdaptiveDemux * demux);
|
||||
/**
|
||||
* update_manifest:
|
||||
* @demux: #GstAdaptiveDemux
|
||||
* @buf: Downloaded manifest data
|
||||
*
|
||||
* During live streaming, this will be called for the subclass to update its
|
||||
* manifest with the new version
|
||||
*
|
||||
* Returns: #GST_FLOW_OK is all succeeded, #GST_FLOW_EOS if the stream ended
|
||||
* or #GST_FLOW_ERROR if an error happened
|
||||
*/
|
||||
GstFlowReturn (*update_manifest) (GstAdaptiveDemux * demux, GstBuffer * buf);
|
||||
|
||||
gboolean (*is_live) (GstAdaptiveDemux * demux);
|
||||
GstClockTime (*get_duration) (GstAdaptiveDemux * demux);
|
||||
|
||||
/**
|
||||
* reset:
|
||||
* @demux: #GstAdaptiveDemux
|
||||
*
|
||||
* Reset the internal state of the subclass, getting ready to restart with
|
||||
* a new stream afterwards
|
||||
*/
|
||||
void (*reset) (GstAdaptiveDemux * demux);
|
||||
|
||||
/**
|
||||
* seek:
|
||||
* @demux: #GstAdaptiveDemux
|
||||
* @seek: a seek #GstEvent
|
||||
*
|
||||
* The demuxer should seek on all its streams to the specified position
|
||||
* in the seek event
|
||||
*
|
||||
* Returns: #TRUE if successful
|
||||
*/
|
||||
gboolean (*seek) (GstAdaptiveDemux * demux, GstEvent * seek);
|
||||
|
||||
/**
|
||||
* has_next_period:
|
||||
* @demux: #GstAdaptiveDemux
|
||||
*
|
||||
* Checks if there is a next period following the current one.
|
||||
* DASH can have multiple medias chained in its manifest, when one finishes
|
||||
* this function is called to verify if there is a new period to be played
|
||||
* in sequence.
|
||||
*
|
||||
* Returns: #TRUE if there is another period
|
||||
*/
|
||||
gboolean (*has_next_period) (GstAdaptiveDemux * demux);
|
||||
/**
|
||||
* advance_period:
|
||||
* @demux: #GstAdaptiveDemux
|
||||
*
|
||||
* Advances the manifest to the next period. New streams should be created
|
||||
* using gst_adaptive_demux_stream_new().
|
||||
*/
|
||||
void (*advance_period) (GstAdaptiveDemux * demux);
|
||||
|
||||
void (*stream_free) (GstAdaptiveDemuxStream * stream);
|
||||
GstFlowReturn (*stream_seek) (GstAdaptiveDemuxStream * stream, GstClockTime ts);
|
||||
gboolean (*stream_has_next_fragment) (GstAdaptiveDemuxStream * stream);
|
||||
GstFlowReturn (*stream_advance_fragment) (GstAdaptiveDemuxStream * stream);
|
||||
/**
|
||||
* stream_update_fragment_info:
|
||||
* @stream: #GstAdaptiveDemuxStream
|
||||
*
|
||||
* Requests the stream to set the information about the current fragment to its
|
||||
* current fragment struct
|
||||
*
|
||||
* Returns: #GST_FLOW_OK in success, #GST_FLOW_ERROR on error and #GST_FLOW_EOS
|
||||
* if there is no fragment.
|
||||
*/
|
||||
GstFlowReturn (*stream_update_fragment_info) (GstAdaptiveDemuxStream * stream);
|
||||
/**
|
||||
* stream_select_bitrate:
|
||||
* @stream: #GstAdaptiveDemuxStream
|
||||
* @bitrate: the bitrate to select (in bytes per second)
|
||||
*
|
||||
* The stream should try to select the bitrate that is the greater, but not
|
||||
* greater than the requested bitrate. If it needs a codec change it should
|
||||
* create the new stream using gst_adaptive_demux_stream_new(). If it only
|
||||
* needs a caps change it should set the new caps using
|
||||
* gst_adaptive_demux_stream_set_caps().
|
||||
*
|
||||
* Returns: #TRUE if the stream changed bitrate, #FALSE otherwise
|
||||
*/
|
||||
gboolean (*stream_select_bitrate) (GstAdaptiveDemuxStream * stream, guint64 bitrate);
|
||||
/**
|
||||
* stream_get_fragment_waiting_time:
|
||||
* @stream: #GstAdaptiveDemuxStream
|
||||
*
|
||||
* For live streams, requests how much time should be waited before starting
|
||||
* to download the fragment. This is useful to avoid downloading a fragment that
|
||||
* isn't available yet.
|
||||
*
|
||||
* Returns: The waiting time in microsseconds
|
||||
*/
|
||||
gint64 (*stream_get_fragment_waiting_time) (GstAdaptiveDemuxStream * stream);
|
||||
|
||||
/**
|
||||
* start_fragment:
|
||||
* @demux: #GstAdaptiveDemux
|
||||
* @stream: #GstAdaptiveDemuxStream
|
||||
*
|
||||
* Notifies the subclass that the given stream is starting the download
|
||||
* of a new fragment. Can be used to reset/init internal state that is
|
||||
* needed before each fragment, like decryption engines.
|
||||
*
|
||||
* Returns: #TRUE if successful.
|
||||
*/
|
||||
gboolean (*start_fragment) (GstAdaptiveDemux * demux, GstAdaptiveDemuxStream * stream);
|
||||
/**
|
||||
* finish_fragment:
|
||||
* @demux: #GstAdaptiveDemux
|
||||
* @stream: #GstAdaptiveDemuxStream
|
||||
* @buffer: Pointer to store and pending data that should be pushed.
|
||||
*
|
||||
* Notifies the subclass that a fragment download was finished.
|
||||
* It can be used to cleanup internal state after a fragment and also
|
||||
* provides a pointer for the subclass to return some pending data
|
||||
* that should be pushed before starting the next fragment. This
|
||||
* covers the use case of finishing the decryption of the last chunk
|
||||
* of an encrypted fragment.
|
||||
*/
|
||||
void (*finish_fragment) (GstAdaptiveDemux * demux, GstAdaptiveDemuxStream * stream, GstBuffer ** buffer);
|
||||
/**
|
||||
* chunk_received:
|
||||
* @demux: #GstAdaptiveDemux
|
||||
* @stream: #GstAdaptiveDemuxStream
|
||||
* @buffer: Pointer containing the received chunk, also used to return modified data
|
||||
*
|
||||
* Notifies the subclass that a fragment chunk was downloaded. The subclass can
|
||||
* modify the buffer and return a new one if needed. Used for decryption.
|
||||
*
|
||||
* Returns: #GST_FLOW_OK if successful, #GST_FLOW_ERROR in case of error.
|
||||
*/
|
||||
GstFlowReturn (*chunk_received) (GstAdaptiveDemux * demux, GstAdaptiveDemuxStream * stream, GstBuffer ** buffer);
|
||||
};
|
||||
|
||||
GType gst_adaptive_demux_get_type (void);
|
||||
|
||||
void gst_adaptive_demux_set_stream_struct_size (GstAdaptiveDemux * demux,
|
||||
gsize struct_size);
|
||||
|
||||
|
||||
GstAdaptiveDemuxStream *gst_adaptive_demux_stream_new (GstAdaptiveDemux * demux,
|
||||
GstPad * pad);
|
||||
void gst_adaptive_demux_stream_set_caps (GstAdaptiveDemuxStream * stream,
|
||||
GstCaps * caps);
|
||||
void gst_adaptive_demux_stream_set_tags (GstAdaptiveDemuxStream * stream,
|
||||
GstTagList * tags);
|
||||
void gst_adaptive_demux_stream_fragment_clear (GstAdaptiveDemuxStreamFragment * f);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in a new issue