Commit 5e2214d3 authored by Jan Schmidt's avatar Jan Schmidt

splitmux: Implement new elements for splitting files at mux level.

Implement 2 new elements - splitmuxsink and splitmuxsrc.

splitmuxsink is a bin which wraps a muxer and takes 1 video stream,
plus audio/subtitle streams, and starts a new file
whenever necessary to avoid overrunning a threshold of either bytes
or time. New files are started at a keyframe, and corresponding audio
and subtitle streams are split at packet boundaries to match
video GOP timestamps.

splitmuxsrc is a corresponding source element which handles
the splitmux:// URL and plays back all component files,
reconstructing the original elementary streams as it goes.
parent 59431f66
......@@ -157,6 +157,8 @@ EXTRA_HFILES = \
$(top_srcdir)/gst/multifile/gstmultifilesink.h \
$(top_srcdir)/gst/multifile/gstmultifilesrc.h \
$(top_srcdir)/gst/multifile/gstsplitfilesrc.h \
$(top_srcdir)/gst/multifile/gstsplitmuxsrc.h \
$(top_srcdir)/gst/multifile/gstsplitmuxsink.h \
$(top_srcdir)/gst/multipart/multipartdemux.h \
$(top_srcdir)/gst/multipart/multipartmux.h \
$(top_srcdir)/gst/isomp4/qtdemux.h \
......
......@@ -162,6 +162,8 @@
<xi:include href="xml/element-speexenc.xml" />
<xi:include href="xml/element-speexdec.xml" />
<xi:include href="xml/element-splitfilesrc.xml" />
<xi:include href="xml/element-splitmuxsrc.xml" />
<xi:include href="xml/element-splitmuxsink.xml" />
<xi:include href="xml/element-streaktv.xml" />
<xi:include href="xml/element-taginject.xml" />
<xi:include href="xml/element-udpsrc.xml" />
......
......@@ -2013,6 +2013,34 @@ GST_TYPE_SPLIT_FILE_SRC
gst_split_file_src_get_type
</SECTION>
<SECTION>
<FILE>element-splitmuxsrc</FILE>
<TITLE>splitmuxsrc</TITLE>
GstSplitMuxSrc
<SUBSECTION Standard>
GstSplitMuxSrcClass
GST_SPLITMUX_SRC
GST_SPLITMUX_SRC_CLASS
GST_IS_SPLITMUX_SRC
GST_IS_SPLITMUX_SRC_CLASS
GST_TYPE_SPLITMUX_SRC
gst_split_mux_src_get_type
</SECTION>
<SECTION>
<FILE>element-splitmuxsink</FILE>
<TITLE>splitmuxsink</TITLE>
GstSplitMuxSink
<SUBSECTION Standard>
GstSplitMuxSinkClass
GST_SPLITMUX_SINK
GST_SPLITMUX_SINK_CLASS
GST_IS_SPLITMUX_SINK
GST_IS_SPLITMUX_SINK_CLASS
GST_TYPE_SPLITMUX_SINK
gst_split_mux_sink_get_type
</SECTION>
<SECTION>
<FILE>element-taginject</FILE>
<TITLE>taginject</TITLE>
......
......@@ -152,6 +152,8 @@ GObject
GstRTSPSrc
GstRgVolume
GstRtpBin
GstSplitMuxSink
GstSplitMuxSrc
GstCutter
GstDVDec
GstDVDemux
......
......@@ -71,6 +71,8 @@ GstSoupHTTPSrc GstURIHandler
GstSpeexEnc GstPreset GstTagSetter
GstSpeexEnc GstTagSetter GstPreset
GstSplitFileSrc GstURIHandler
GstSplitMuxSink GstChildProxy
GstSplitMuxSrc GstChildProxy GstURIHandler
GstSwitchSink GstChildProxy
GstSwitchSrc GstChildProxy
GstTagLibMux GstTagSetter
......
......@@ -6,14 +6,30 @@ libgstmultifile_la_SOURCES = \
gstmultifilesrc.c \
gstmultifile.c \
gstsplitfilesrc.c \
gstsplitmuxsink.c \
gstsplitmuxpartreader.c \
gstsplitmuxsrc.c \
gstsplitutils.c \
patternspec.c
libgstmultifile_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(GIO_CFLAGS)
libgstmultifile_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstvideo-@GST_API_VERSION@ $(GST_BASE_LIBS) $(GST_LIBS) $(GIO_LIBS)
libgstmultifile_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstmultifile_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
noinst_HEADERS = gstmultifilesrc.h gstmultifilesink.h gstsplitfilesrc.h patternspec.h
noinst_HEADERS = gstmultifilesrc.h gstmultifilesink.h gstsplitfilesrc.h gstsplitmuxsink.h \
gstsplitmuxsrc.h gstsplitmuxpartreader.h gstsplitutils.h patternspec.h
noinst_PROGRAMS = test-splitmux-part-reader
test_splitmux_part_reader_SOURCES = \
test-splitmuxpartreader.c \
gstsplitmuxpartreader.c \
gstsplitmuxsrc.c \
gstsplitutils.c \
patternspec.c
test_splitmux_part_reader_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(GIO_CFLAGS)
test_splitmux_part_reader_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstvideo-@GST_API_VERSION@ $(GST_BASE_LIBS) $(GST_LIBS) $(GIO_LIBS)
test_splitmux_part_reader_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
Android.mk: Makefile.am $(BUILT_SOURCES)
androgenizer \
......
......@@ -31,6 +31,8 @@
#include "gstmultifilesink.h"
#include "gstmultifilesrc.h"
#include "gstsplitfilesrc.h"
#include "gstsplitmuxsink.h"
#include "gstsplitmuxsrc.h"
static gboolean
plugin_init (GstPlugin * plugin)
......@@ -42,6 +44,12 @@ plugin_init (GstPlugin * plugin)
gst_element_register (plugin, "splitfilesrc", GST_RANK_NONE,
gst_split_file_src_get_type ());
if (!register_splitmuxsink (plugin))
return FALSE;
if (!register_splitmuxsrc (plugin))
return FALSE;
return TRUE;
}
......
......@@ -45,16 +45,10 @@
#endif
#include "gstsplitfilesrc.h"
#include "patternspec.h"
#include "gstsplitutils.h"
#include <string.h>
#ifdef G_OS_WIN32
#define DEFAULT_PATTERN_MATCH_MODE MATCH_MODE_UTF8
#else
#define DEFAULT_PATTERN_MATCH_MODE MATCH_MODE_AUTO
#endif
enum
{
PROP_LOCATION = 1
......@@ -237,84 +231,6 @@ gst_split_file_src_get_property (GObject * object, guint prop_id,
}
}
static int
gst_split_file_src_array_sortfunc (gchar ** a, gchar ** b)
{
return strcmp (*a, *b);
}
static gchar **
gst_split_file_src_find_files (GstSplitFileSrc * src, const gchar * dirname,
const gchar * basename, GError ** err)
{
PatternSpec *pspec;
GPtrArray *files;
const gchar *name;
GDir *dir;
if (dirname == NULL || basename == NULL)
goto invalid_location;
GST_INFO_OBJECT (src, "checking in directory '%s' for pattern '%s'",
dirname, basename);
dir = g_dir_open (dirname, 0, err);
if (dir == NULL)
return NULL;
if (DEFAULT_PATTERN_MATCH_MODE == MATCH_MODE_UTF8 &&
!g_utf8_validate (basename, -1, NULL)) {
goto not_utf8;
}
/* mode will be AUTO on linux/unix and UTF8 on win32 */
pspec = pattern_spec_new (basename, DEFAULT_PATTERN_MATCH_MODE);
files = g_ptr_array_new ();
while ((name = g_dir_read_name (dir))) {
GST_TRACE_OBJECT (src, "check: %s", name);
if (pattern_match_string (pspec, name)) {
GST_DEBUG_OBJECT (src, "match: %s", name);
g_ptr_array_add (files, g_build_filename (dirname, name, NULL));
}
}
if (files->len == 0)
goto no_matches;
g_ptr_array_sort (files, (GCompareFunc) gst_split_file_src_array_sortfunc);
g_ptr_array_add (files, NULL);
pattern_spec_free (pspec);
g_dir_close (dir);
return (gchar **) g_ptr_array_free (files, FALSE);
/* ERRORS */
invalid_location:
{
g_set_error_literal (err, G_FILE_ERROR, G_FILE_ERROR_INVAL,
"No filename specified.");
return NULL;
}
not_utf8:
{
g_dir_close (dir);
g_set_error_literal (err, G_FILE_ERROR, G_FILE_ERROR_INVAL,
"Filename pattern must be UTF-8 on Windows.");
return NULL;
}
no_matches:
{
pattern_spec_free (pspec);
g_dir_close (dir);
g_set_error_literal (err, G_FILE_ERROR, G_FILE_ERROR_NOENT,
"Found no files matching the pattern.");
return NULL;
}
}
static gboolean
gst_split_file_src_start (GstBaseSrc * basesrc)
{
......@@ -335,7 +251,7 @@ gst_split_file_src_start (GstBaseSrc * basesrc)
}
GST_OBJECT_UNLOCK (src);
files = gst_split_file_src_find_files (src, dirname, basename, &err);
files = gst_split_util_find_files (dirname, basename, &err);
if (files == NULL || *files == NULL)
goto no_files;
......
This diff is collapsed.
/* GStreamer Split Muxed File Source - Part reader
* Copyright (C) 2014 Jan Schmidt <jan@centricular.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_SPLITMUX_PART_READER_H__
#define __GST_SPLITMUX_PART_READER_H__
#include <gst/gst.h>
#include <gst/base/gstdataqueue.h>
G_BEGIN_DECLS
#define GST_TYPE_SPLITMUX_PART_READER \
(gst_splitmux_part_reader_get_type())
#define GST_SPLITMUX_PART_READER(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SPLITMUX_PART_READER,GstSplitMuxSrc))
#define GST_SPLITMUX_PART_READER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SPLITMUX_PART_READER,GstSplitMuxSrcClass))
#define GST_IS_SPLITMUX_PART_READER(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SPLITMUX_PART_READER))
#define GST_IS_SPLITMUX_PART_READER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SPLITMUX_PART_READER))
typedef struct _GstSplitMuxPartReader GstSplitMuxPartReader;
typedef struct _GstSplitMuxPartReaderClass GstSplitMuxPartReaderClass;
typedef struct _SplitMuxSrcPad SplitMuxSrcPad;
typedef struct _SplitMuxSrcPadClass SplitMuxSrcPadClass;
typedef enum
{
PART_STATE_NULL,
PART_STATE_PREPARING_COLLECT_STREAMS,
PART_STATE_PREPARING_MEASURE_STREAMS,
PART_STATE_PREPARING_RESET_FOR_READY,
PART_STATE_READY,
PART_STATE_FAILED,
} GstSplitMuxPartState;
typedef GstPad *(*GstSplitMuxPartReaderPadCb)(GstSplitMuxPartReader *reader, GstPad *src_pad, gpointer cb_data);
struct _GstSplitMuxPartReader
{
GstPipeline parent;
GstSplitMuxPartState prep_state;
gchar *path;
GstElement *src;
GstElement *typefind;
GstElement *demux;
gboolean active;
gboolean running;
gboolean prepared;
gboolean flushing;
gboolean no_more_pads;
GstClockTime duration;
GstClockTime start_offset;
GList *pads;
GCond inactive_cond;
GMutex lock;
GstSplitMuxPartReaderPadCb get_pad_cb;
gpointer cb_data;
};
struct _GstSplitMuxPartReaderClass
{
GstPipelineClass parent_class;
void (*prepared) (GstSplitMuxPartReader *reader);
void (*end_of_part) (GstSplitMuxPartReader *reader);
};
GType gst_splitmux_part_reader_get_type (void);
void gst_splitmux_part_reader_set_callbacks (GstSplitMuxPartReader *reader,
gpointer cb_data, GstSplitMuxPartReaderPadCb get_pad_cb);
gboolean gst_splitmux_part_reader_prepare (GstSplitMuxPartReader *part);
void gst_splitmux_part_reader_unprepare (GstSplitMuxPartReader *part);
void gst_splitmux_part_reader_set_location (GstSplitMuxPartReader *reader,
const gchar *path);
gboolean gst_splitmux_part_is_eos (GstSplitMuxPartReader *reader);
gboolean gst_splitmux_part_reader_activate (GstSplitMuxPartReader *part, GstSegment *seg);
void gst_splitmux_part_reader_deactivate (GstSplitMuxPartReader *part);
gboolean gst_splitmux_part_reader_src_query (GstSplitMuxPartReader *part, GstPad *src_pad, GstQuery * query);
void gst_splitmux_part_reader_set_start_offset (GstSplitMuxPartReader *part, GstClockTime offset);
GstClockTime gst_splitmux_part_reader_get_start_offset (GstSplitMuxPartReader *part);
GstClockTime gst_splitmux_part_reader_get_end_offset (GstSplitMuxPartReader *part);
GstClockTime gst_splitmux_part_reader_get_duration (GstSplitMuxPartReader * reader);
GstPad *gst_splitmux_part_reader_lookup_pad (GstSplitMuxPartReader *reader, GstPad *target);
GstFlowReturn gst_splitmux_part_reader_pop (GstSplitMuxPartReader *reader, GstPad *part_pad, GstDataQueueItem ** item);
G_END_DECLS
#endif
This diff is collapsed.
/* GStreamer split muxer bin
* Copyright (C) 2014 Jan Schmidt <jan@centricular.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_SPLITMUXSINK_H__
#define __GST_SPLITMUXSINK_H__
#include <gst/gst.h>
#include <gst/pbutils/pbutils.h>
G_BEGIN_DECLS
#define GST_TYPE_SPLITMUX_SINK (gst_splitmux_sink_get_type())
#define GST_SPLITMUX_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SPLITMUX_SINK,GstSplitMuxSink))
#define GST_SPLITMUX_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SPLITMUX_SINK,GstSplitMuxSinkClass))
#define GST_IS_SPLITMUX_SINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SPLITMUX_SINK))
#define GST_IS_SPLITMUX_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SPLITMUX_SINK))
typedef struct _GstSplitMuxSink GstSplitMuxSink;
typedef struct _GstSplitMuxSinkClass GstSplitMuxSinkClass;
GType gst_splitmux_sink_get_type(void);
gboolean register_splitmuxsink (GstPlugin * plugin);
typedef enum _SplitMuxState {
SPLITMUX_STATE_STOPPED,
SPLITMUX_STATE_COLLECTING_GOP_START,
SPLITMUX_STATE_WAITING_GOP_COMPLETE,
SPLITMUX_STATE_ENDING_FILE,
SPLITMUX_STATE_START_NEXT_FRAGMENT,
} SplitMuxState;
typedef struct _MqStreamBuf
{
gboolean keyframe;
GstClockTime run_ts;
gsize buf_size;
} MqStreamBuf;
typedef struct _MqStreamCtx
{
gint refcount;
GstSplitMuxSink *splitmux;
guint sink_pad_block_id;
guint src_pad_block_id;
gboolean is_video;
gboolean flushing;
gboolean in_eos;
gboolean out_eos;
GstSegment in_segment;
GstSegment out_segment;
GstClockTime in_running_time;
GstClockTime out_running_time;
gsize in_bytes;
GQueue queued_bufs;
GstPad *sinkpad;
GstPad *srcpad;
gboolean out_blocked;
} MqStreamCtx;
struct _GstSplitMuxSink {
GstBin parent;
GMutex lock;
GCond data_cond;
SplitMuxState state;
gdouble mux_overhead;
GstClockTime threshold_time;
guint64 threshold_bytes;
guint mq_max_buffers;
GstElement *mq;
GstElement *muxer;
GstElement *sink;
GstElement *provided_muxer;
GstElement *provided_sink;
GstElement *active_sink;
gchar *location;
guint fragment_id;
GList *contexts;
MqStreamCtx *video_ctx;
guint queued_gops;
GstClockTime max_in_running_time;
GstClockTime max_out_running_time;
GstClockTime muxed_out_time;
gsize muxed_out_bytes;
GstClockTime mux_start_time;
gsize mux_start_bytes;
};
struct _GstSplitMuxSinkClass {
GstBinClass parent_class;
};
G_END_DECLS
#endif /* __GST_SPLITMUXSINK_H__ */
This diff is collapsed.
/* GStreamer Split Muxed File Source
* Copyright (C) 2014 Jan Schmidt <jan@centricular.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_SPLITMUX_SRC_H__
#define __GST_SPLITMUX_SRC_H__
#include <gst/gst.h>
#include "gstsplitmuxpartreader.h"
G_BEGIN_DECLS
#define GST_TYPE_SPLITMUX_SRC \
(gst_splitmux_src_get_type())
#define GST_SPLITMUX_SRC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SPLITMUX_SRC,GstSplitMuxSrc))
#define GST_SPLITMUX_SRC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SPLITMUX_SRC,GstSplitMuxSrcClass))
#define GST_IS_SPLITMUX_SRC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SPLITMUX_SRC))
#define GST_IS_SPLITMUX_SRC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SPLITMUX_SRC))
typedef struct _GstSplitMuxSrc GstSplitMuxSrc;
typedef struct _GstSplitMuxSrcClass GstSplitMuxSrcClass;
struct _GstSplitMuxSrc
{
GstBin parent;
GMutex lock;
gboolean running;
gchar *location; /* OBJECT_LOCK */
GstSplitMuxPartReader **parts;
guint num_parts;
guint cur_part;
gboolean pads_complete;
GMutex pads_lock;
GList *pads; /* pads_lock */
GstClockTime total_duration;
GstSegment play_segment;
};
struct _GstSplitMuxSrcClass
{
GstBinClass parent_class;
};
GType splitmux_src_pad_get_type (void);
#define SPLITMUX_TYPE_SRC_PAD splitmux_src_pad_get_type()
#define SPLITMUX_SRC_PAD_CAST(p) ((SplitMuxSrcPad *)(p))
#define SPLITMUX_SRC_PAD(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),SPLITMUX_TYPE_SRC_PAD,SplitMuxSrcPad))
struct _SplitMuxSrcPad
{
GstPad parent;
guint cur_part;
GstSplitMuxPartReader *reader;
GstPad *part_pad;
GstSegment segment;
gboolean set_next_discont;
gboolean clear_next_discont;
gboolean sent_stream_start;
gboolean sent_caps;
gboolean sent_segment;
};
struct _SplitMuxSrcPadClass
{
GstPadClass parent;
};
GType gst_splitmux_src_get_type (void);
gboolean register_splitmuxsrc (GstPlugin * plugin);
#define SPLITMUX_SRC_LOCK(s) g_mutex_lock(&(s)->lock)
#define SPLITMUX_SRC_UNLOCK(s) g_mutex_unlock(&(s)->lock)
#define SPLITMUX_SRC_PADS_LOCK(s) g_mutex_lock(&(s)->pads_lock)
#define SPLITMUX_SRC_PADS_UNLOCK(s) g_mutex_unlock(&(s)->pads_lock)
G_END_DECLS
#endif /* __GST_SPLITMUX_SRC_H__ */
/* GStreamer Split Source Utility Functions
* Copyright (C) 2011 Collabora Ltd. <tim.muller@collabora.co.uk>
* Copyright (C) 2014 Jan Schmidt <jan@centricular.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.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <string.h>
#include "gstsplitutils.h"
#include "patternspec.h"
static int
gst_split_util_array_sortfunc (gchar ** a, gchar ** b)
{
return strcmp (*a, *b);
}
gchar **
gst_split_util_find_files (const gchar * dirname,
const gchar * basename, GError ** err)
{
PatternSpec *pspec;
GPtrArray *files;
const gchar *name;
GDir *dir;
if (dirname == NULL || basename == NULL)
goto invalid_location;
GST_INFO ("checking in directory '%s' for pattern '%s'", dirname, basename);
dir = g_dir_open (dirname, 0, err);
if (dir == NULL)
return NULL;
if (DEFAULT_PATTERN_MATCH_MODE == MATCH_MODE_UTF8 &&
!g_utf8_validate (basename, -1, NULL)) {
goto not_utf8;
}
/* mode will be AUTO on linux/unix and UTF8 on win32 */
pspec = pattern_spec_new (basename, DEFAULT_PATTERN_MATCH_MODE);
files = g_ptr_array_new ();
while ((name = g_dir_read_name (dir))) {
GST_TRACE ("check: %s", name);
if (pattern_match_string (pspec, name)) {
GST_DEBUG ("match: %s", name);
g_ptr_array_add (files, g_build_filename (dirname, name, NULL));
}
}
if (files->len == 0)
goto no_matches;
g_ptr_array_sort (files, (GCompareFunc) gst_split_util_array_sortfunc);
g_ptr_array_add (files, NULL);
pattern_spec_free (pspec);
g_dir_close (dir);
return (gchar **) g_ptr_array_free (files, FALSE);
/* ERRORS */
invalid_location:
{
g_set_error_literal (err, G_FILE_ERROR, G_FILE_ERROR_INVAL,
"No filename specified.");
return NULL;
}
not_utf8:
{
g_dir_close (dir);
g_set_error_literal (err, G_FILE_ERROR, G_FILE_ERROR_INVAL,
"Filename pattern must be UTF-8 on Windows.");
return NULL;
}
no_matches:
{
pattern_spec_free (pspec);
g_dir_close (dir);
g_set_error_literal (err, G_FILE_ERROR, G_FILE_ERROR_NOENT,
"Found no files matching the pattern.");
return NULL;
}
}
/* GStreamer Split Source Utility Functions
* Copyright (C) 2011 Collabora Ltd. <tim.muller@collabora.co.uk>
* Copyright (C) 2014 Jan Schmidt <jan@centricular.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_SPLITUTILS_H__
#define __GST_SPLITUTILS_H__
#include <gst/gst.h>
G_BEGIN_DECLS
#ifdef G_OS_WIN32
#define DEFAULT_PATTERN_MATCH_MODE MATCH_MODE_UTF8
#else
#define DEFAULT_PATTERN_MATCH_MODE MATCH_MODE_AUTO