summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2009-10-14 11:54:44 +0200
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2009-10-14 13:15:02 +0200
commite967767b27f633de25490489ceedf35f076a856b (patch)
tree3f8002cc7e9ad9432fedb638a300d2d54aaf4e3b
parent72af90ae31907964b31c368164ec17d0f72aa7bf (diff)
qtdemux: add GstIndex support
-rw-r--r--gst/qtdemux/qtdemux.c72
-rw-r--r--gst/qtdemux/qtdemux.h4
2 files changed, 72 insertions, 4 deletions
diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c
index 966d43bc..fa767f5c 100644
--- a/gst/qtdemux/qtdemux.c
+++ b/gst/qtdemux/qtdemux.c
@@ -305,6 +305,8 @@ static void gst_qtdemux_base_init (GstQTDemuxClass * klass);
static void gst_qtdemux_init (GstQTDemux * quicktime_demux);
static void gst_qtdemux_dispose (GObject * object);
+static void gst_qtdemux_set_index (GstElement * element, GstIndex * index);
+static GstIndex *gst_qtdemux_get_index (GstElement * element);
static GstStateChangeReturn gst_qtdemux_change_state (GstElement * element,
GstStateChange transition);
static gboolean qtdemux_sink_activate (GstPad * sinkpad);
@@ -385,7 +387,10 @@ gst_qtdemux_class_init (GstQTDemuxClass * klass)
gobject_class->dispose = gst_qtdemux_dispose;
- gstelement_class->change_state = gst_qtdemux_change_state;
+ gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_qtdemux_change_state);
+
+ gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_qtdemux_set_index);
+ gstelement_class->get_index = GST_DEBUG_FUNCPTR (gst_qtdemux_get_index);
}
static void
@@ -1378,6 +1383,42 @@ drop:
return res;
}
+static void
+gst_qtdemux_set_index (GstElement * element, GstIndex * index)
+{
+ GstQTDemux *demux = GST_QTDEMUX (element);
+
+ GST_OBJECT_LOCK (demux);
+ if (demux->element_index)
+ gst_object_unref (demux->element_index);
+ if (index) {
+ demux->element_index = gst_object_ref (index);
+ } else {
+ demux->element_index = NULL;
+ }
+ GST_OBJECT_UNLOCK (demux);
+ /* object lock might be taken again */
+ if (index)
+ gst_index_get_writer_id (index, GST_OBJECT (element), &demux->index_id);
+ GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT, demux->element_index);
+}
+
+static GstIndex *
+gst_qtdemux_get_index (GstElement * element)
+{
+ GstIndex *result = NULL;
+ GstQTDemux *demux = GST_QTDEMUX (element);
+
+ GST_OBJECT_LOCK (demux);
+ if (demux->element_index)
+ result = gst_object_ref (demux->element_index);
+ GST_OBJECT_UNLOCK (demux);
+
+ GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
+
+ return result;
+}
+
static GstStateChangeReturn
gst_qtdemux_change_state (GstElement * element, GstStateChange transition)
{
@@ -1412,6 +1453,9 @@ gst_qtdemux_change_state (GstElement * element, GstStateChange transition)
if (qtdemux->tag_list)
gst_tag_list_free (qtdemux->tag_list);
qtdemux->tag_list = NULL;
+ if (qtdemux->element_index)
+ gst_object_unref (qtdemux->element_index);
+ qtdemux->element_index = NULL;
gst_adapter_clear (qtdemux->adapter);
for (n = 0; n < qtdemux->n_streams; n++) {
QtDemuxStream *stream = qtdemux->streams[n];
@@ -2290,7 +2334,8 @@ gst_qtdemux_process_buffer (GstQTDemux * qtdemux, QtDemuxStream * stream,
static gboolean
gst_qtdemux_decorate_and_push_buffer (GstQTDemux * qtdemux,
QtDemuxStream * stream, GstBuffer * buf,
- guint64 timestamp, guint64 duration, gboolean keyframe, guint64 position)
+ guint64 timestamp, guint64 duration, gboolean keyframe, guint64 position,
+ guint64 byte_position)
{
GstFlowReturn ret = GST_FLOW_OK;
@@ -2353,6 +2398,20 @@ gst_qtdemux_decorate_and_push_buffer (GstQTDemux * qtdemux,
GST_BUFFER_SIZE (buf) -= stream->padding;
}
+ if (G_UNLIKELY (qtdemux->element_index)) {
+ GstClockTime stream_time;
+
+ stream_time = gst_segment_to_stream_time (&stream->segment, GST_FORMAT_TIME,
+ timestamp);
+ if (GST_CLOCK_TIME_IS_VALID (stream_time)) {
+ GST_LOG_OBJECT (qtdemux, "adding association %" GST_TIME_FORMAT "-> %"
+ G_GUINT64_FORMAT, GST_TIME_ARGS (stream_time), byte_position);
+ gst_index_add_association (qtdemux->element_index, qtdemux->index_id,
+ keyframe ? GST_ASSOCIATION_FLAG_KEY_UNIT : GST_ASSOCIATION_FLAG_NONE,
+ GST_FORMAT_TIME, stream_time, GST_FORMAT_BYTES, byte_position, NULL);
+ }
+ }
+
if (stream->need_clip)
buf = gst_qtdemux_clip_buffer (qtdemux, stream, buf);
@@ -2456,7 +2515,7 @@ gst_qtdemux_loop_state_movie (GstQTDemux * qtdemux)
goto beach;
ret = gst_qtdemux_decorate_and_push_buffer (qtdemux, stream, buf,
- timestamp, duration, keyframe, min_time);
+ timestamp, duration, keyframe, min_time, offset);
/* combine flows */
ret = gst_qtdemux_combine_flows (qtdemux, stream, ret);
@@ -2892,7 +2951,7 @@ gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
stream->samples[stream->sample_index].keyframe;
ret = gst_qtdemux_decorate_and_push_buffer (demux, stream, outbuf,
- timestamp, duration, keyframe, position);
+ timestamp, duration, keyframe, position, demux->offset);
/* combine flows */
ret = gst_qtdemux_combine_flows (demux, stream, ret);
@@ -3455,6 +3514,11 @@ gst_qtdemux_add_stream (GstQTDemux * qtdemux,
if (qtdemux->n_streams >= GST_QTDEMUX_MAX_STREAMS)
goto too_many_streams;
+ /* consistent default for push based mode */
+ gst_segment_init (&stream->segment, GST_FORMAT_TIME);
+ gst_segment_set_newsegment (&stream->segment, FALSE, 1.0, GST_FORMAT_TIME,
+ 0, GST_CLOCK_TIME_NONE, 0);
+
if (stream->subtype == FOURCC_vide) {
gchar *name = g_strdup_printf ("video_%02d", qtdemux->n_video_streams);
diff --git a/gst/qtdemux/qtdemux.h b/gst/qtdemux/qtdemux.h
index 6521dd21..10763633 100644
--- a/gst/qtdemux/qtdemux.h
+++ b/gst/qtdemux/qtdemux.h
@@ -93,6 +93,10 @@ struct _GstQTDemux {
GstSegment segment;
gboolean segment_running;
GstEvent *pending_newsegment;
+
+ /* gst index support */
+ GstIndex *element_index;
+ gint index_id;
};
struct _GstQTDemuxClass {