mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 07:58:51 +00:00
Implement seekability-only-if-available
Original commit message from CVS: Implement seekability-only-if-available
This commit is contained in:
parent
2e7fa817e4
commit
5a26d2f709
2 changed files with 78 additions and 22 deletions
|
@ -29,6 +29,9 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "gstfilesink.h"
|
#include "gstfilesink.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY (gst_filesink_debug);
|
GST_DEBUG_CATEGORY (gst_filesink_debug);
|
||||||
#define GST_CAT_DEFAULT gst_filesink_debug
|
#define GST_CAT_DEFAULT gst_filesink_debug
|
||||||
|
@ -56,15 +59,6 @@ enum {
|
||||||
ARG_LOCATION
|
ARG_LOCATION
|
||||||
};
|
};
|
||||||
|
|
||||||
GST_PAD_EVENT_MASK_FUNCTION (gst_filesink_get_event_mask,
|
|
||||||
{ GST_EVENT_SEEK, GST_SEEK_METHOD_CUR |
|
|
||||||
GST_SEEK_METHOD_SET |
|
|
||||||
GST_SEEK_METHOD_END |
|
|
||||||
GST_SEEK_FLAG_FLUSH },
|
|
||||||
{ GST_EVENT_FLUSH, 0 },
|
|
||||||
{ GST_EVENT_DISCONTINUOUS, 0 }
|
|
||||||
)
|
|
||||||
|
|
||||||
GST_PAD_QUERY_TYPE_FUNCTION (gst_filesink_get_query_types,
|
GST_PAD_QUERY_TYPE_FUNCTION (gst_filesink_get_query_types,
|
||||||
GST_QUERY_TOTAL,
|
GST_QUERY_TOTAL,
|
||||||
GST_QUERY_POSITION
|
GST_QUERY_POSITION
|
||||||
|
@ -86,6 +80,9 @@ static void gst_filesink_get_property (GObject *object, guint prop_id,
|
||||||
static gboolean gst_filesink_open_file (GstFileSink *sink);
|
static gboolean gst_filesink_open_file (GstFileSink *sink);
|
||||||
static void gst_filesink_close_file (GstFileSink *sink);
|
static void gst_filesink_close_file (GstFileSink *sink);
|
||||||
|
|
||||||
|
static const GstEventMask *
|
||||||
|
gst_filesink_get_event_mask (GstPad *pad);
|
||||||
|
|
||||||
static gboolean gst_filesink_handle_event (GstPad *pad, GstEvent *event);
|
static gboolean gst_filesink_handle_event (GstPad *pad, GstEvent *event);
|
||||||
static gboolean gst_filesink_pad_query (GstPad *pad, GstQueryType type,
|
static gboolean gst_filesink_pad_query (GstPad *pad, GstQueryType type,
|
||||||
GstFormat *format, gint64 *value);
|
GstFormat *format, gint64 *value);
|
||||||
|
@ -291,6 +288,37 @@ gst_filesink_pad_query (GstPad *pad, GstQueryType type,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* supported events */
|
||||||
|
static const GstEventMask *
|
||||||
|
gst_filesink_get_event_mask (GstPad *pad)
|
||||||
|
{
|
||||||
|
GstFileSink *filesink = GST_FILESINK (gst_pad_get_parent (pad));
|
||||||
|
struct stat filestat;
|
||||||
|
static const GstEventMask seek_masks[] = {
|
||||||
|
{ GST_EVENT_SEEK, GST_SEEK_METHOD_CUR |
|
||||||
|
GST_SEEK_METHOD_SET |
|
||||||
|
GST_SEEK_METHOD_END |
|
||||||
|
GST_SEEK_FLAG_FLUSH },
|
||||||
|
{ GST_EVENT_FLUSH, 0 },
|
||||||
|
{ GST_EVENT_DISCONTINUOUS, 0 },
|
||||||
|
{ 0, 0 }
|
||||||
|
}, noseek_masks[] = {
|
||||||
|
{ GST_EVENT_FLUSH, 0 },
|
||||||
|
{ 0, 0 }
|
||||||
|
}, *selected = seek_masks;
|
||||||
|
|
||||||
|
if (filesink->file != NULL) {
|
||||||
|
if (fstat (fileno (filesink->file), &filestat) == 0) {
|
||||||
|
if (S_ISFIFO (filestat.st_mode) ||
|
||||||
|
S_ISSOCK (filestat.st_mode)) {
|
||||||
|
selected = noseek_masks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return selected;
|
||||||
|
}
|
||||||
|
|
||||||
/* handle events (search) */
|
/* handle events (search) */
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_filesink_handle_event (GstPad *pad, GstEvent *event)
|
gst_filesink_handle_event (GstPad *pad, GstEvent *event)
|
||||||
|
@ -390,7 +418,7 @@ gst_filesink_chain (GstPad *pad, GstBuffer *buf)
|
||||||
guint bytes_written = 0, back_pending = 0;
|
guint bytes_written = 0, back_pending = 0;
|
||||||
if (ftell(filesink->file) < filesink->data_written)
|
if (ftell(filesink->file) < filesink->data_written)
|
||||||
back_pending = filesink->data_written - ftell(filesink->file);
|
back_pending = filesink->data_written - ftell(filesink->file);
|
||||||
do {
|
while (bytes_written < GST_BUFFER_SIZE (buf)) {
|
||||||
size_t wrote = fwrite (GST_BUFFER_DATA (buf) + bytes_written, 1,
|
size_t wrote = fwrite (GST_BUFFER_DATA (buf) + bytes_written, 1,
|
||||||
GST_BUFFER_SIZE (buf) - bytes_written,
|
GST_BUFFER_SIZE (buf) - bytes_written,
|
||||||
filesink->file);
|
filesink->file);
|
||||||
|
@ -402,7 +430,7 @@ gst_filesink_chain (GstPad *pad, GstBuffer *buf)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bytes_written += wrote;
|
bytes_written += wrote;
|
||||||
} while (bytes_written < GST_BUFFER_SIZE (buf));
|
}
|
||||||
|
|
||||||
filesink->data_written += bytes_written - back_pending;
|
filesink->data_written += bytes_written - back_pending;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,9 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "gstfilesink.h"
|
#include "gstfilesink.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY (gst_filesink_debug);
|
GST_DEBUG_CATEGORY (gst_filesink_debug);
|
||||||
#define GST_CAT_DEFAULT gst_filesink_debug
|
#define GST_CAT_DEFAULT gst_filesink_debug
|
||||||
|
@ -56,15 +59,6 @@ enum {
|
||||||
ARG_LOCATION
|
ARG_LOCATION
|
||||||
};
|
};
|
||||||
|
|
||||||
GST_PAD_EVENT_MASK_FUNCTION (gst_filesink_get_event_mask,
|
|
||||||
{ GST_EVENT_SEEK, GST_SEEK_METHOD_CUR |
|
|
||||||
GST_SEEK_METHOD_SET |
|
|
||||||
GST_SEEK_METHOD_END |
|
|
||||||
GST_SEEK_FLAG_FLUSH },
|
|
||||||
{ GST_EVENT_FLUSH, 0 },
|
|
||||||
{ GST_EVENT_DISCONTINUOUS, 0 }
|
|
||||||
)
|
|
||||||
|
|
||||||
GST_PAD_QUERY_TYPE_FUNCTION (gst_filesink_get_query_types,
|
GST_PAD_QUERY_TYPE_FUNCTION (gst_filesink_get_query_types,
|
||||||
GST_QUERY_TOTAL,
|
GST_QUERY_TOTAL,
|
||||||
GST_QUERY_POSITION
|
GST_QUERY_POSITION
|
||||||
|
@ -86,6 +80,9 @@ static void gst_filesink_get_property (GObject *object, guint prop_id,
|
||||||
static gboolean gst_filesink_open_file (GstFileSink *sink);
|
static gboolean gst_filesink_open_file (GstFileSink *sink);
|
||||||
static void gst_filesink_close_file (GstFileSink *sink);
|
static void gst_filesink_close_file (GstFileSink *sink);
|
||||||
|
|
||||||
|
static const GstEventMask *
|
||||||
|
gst_filesink_get_event_mask (GstPad *pad);
|
||||||
|
|
||||||
static gboolean gst_filesink_handle_event (GstPad *pad, GstEvent *event);
|
static gboolean gst_filesink_handle_event (GstPad *pad, GstEvent *event);
|
||||||
static gboolean gst_filesink_pad_query (GstPad *pad, GstQueryType type,
|
static gboolean gst_filesink_pad_query (GstPad *pad, GstQueryType type,
|
||||||
GstFormat *format, gint64 *value);
|
GstFormat *format, gint64 *value);
|
||||||
|
@ -291,6 +288,37 @@ gst_filesink_pad_query (GstPad *pad, GstQueryType type,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* supported events */
|
||||||
|
static const GstEventMask *
|
||||||
|
gst_filesink_get_event_mask (GstPad *pad)
|
||||||
|
{
|
||||||
|
GstFileSink *filesink = GST_FILESINK (gst_pad_get_parent (pad));
|
||||||
|
struct stat filestat;
|
||||||
|
static const GstEventMask seek_masks[] = {
|
||||||
|
{ GST_EVENT_SEEK, GST_SEEK_METHOD_CUR |
|
||||||
|
GST_SEEK_METHOD_SET |
|
||||||
|
GST_SEEK_METHOD_END |
|
||||||
|
GST_SEEK_FLAG_FLUSH },
|
||||||
|
{ GST_EVENT_FLUSH, 0 },
|
||||||
|
{ GST_EVENT_DISCONTINUOUS, 0 },
|
||||||
|
{ 0, 0 }
|
||||||
|
}, noseek_masks[] = {
|
||||||
|
{ GST_EVENT_FLUSH, 0 },
|
||||||
|
{ 0, 0 }
|
||||||
|
}, *selected = seek_masks;
|
||||||
|
|
||||||
|
if (filesink->file != NULL) {
|
||||||
|
if (fstat (fileno (filesink->file), &filestat) == 0) {
|
||||||
|
if (S_ISFIFO (filestat.st_mode) ||
|
||||||
|
S_ISSOCK (filestat.st_mode)) {
|
||||||
|
selected = noseek_masks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return selected;
|
||||||
|
}
|
||||||
|
|
||||||
/* handle events (search) */
|
/* handle events (search) */
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_filesink_handle_event (GstPad *pad, GstEvent *event)
|
gst_filesink_handle_event (GstPad *pad, GstEvent *event)
|
||||||
|
@ -390,7 +418,7 @@ gst_filesink_chain (GstPad *pad, GstBuffer *buf)
|
||||||
guint bytes_written = 0, back_pending = 0;
|
guint bytes_written = 0, back_pending = 0;
|
||||||
if (ftell(filesink->file) < filesink->data_written)
|
if (ftell(filesink->file) < filesink->data_written)
|
||||||
back_pending = filesink->data_written - ftell(filesink->file);
|
back_pending = filesink->data_written - ftell(filesink->file);
|
||||||
do {
|
while (bytes_written < GST_BUFFER_SIZE (buf)) {
|
||||||
size_t wrote = fwrite (GST_BUFFER_DATA (buf) + bytes_written, 1,
|
size_t wrote = fwrite (GST_BUFFER_DATA (buf) + bytes_written, 1,
|
||||||
GST_BUFFER_SIZE (buf) - bytes_written,
|
GST_BUFFER_SIZE (buf) - bytes_written,
|
||||||
filesink->file);
|
filesink->file);
|
||||||
|
@ -402,7 +430,7 @@ gst_filesink_chain (GstPad *pad, GstBuffer *buf)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bytes_written += wrote;
|
bytes_written += wrote;
|
||||||
} while (bytes_written < GST_BUFFER_SIZE (buf));
|
}
|
||||||
|
|
||||||
filesink->data_written += bytes_written - back_pending;
|
filesink->data_written += bytes_written - back_pending;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue