summaryrefslogtreecommitdiffstats
path: root/gst
diff options
context:
space:
mode:
Diffstat (limited to 'gst')
-rw-r--r--gst/aacparse/gstbaseparse.c89
-rw-r--r--gst/aacparse/gstbaseparse.h3
-rw-r--r--gst/amrparse/gstbaseparse.c89
-rw-r--r--gst/amrparse/gstbaseparse.h3
-rw-r--r--gst/camerabin/TODO31
-rw-r--r--gst/camerabin/camerabinimage.c8
-rw-r--r--gst/camerabin/camerabinpreview.c5
-rw-r--r--gst/camerabin/camerabinvideo.c9
-rw-r--r--gst/camerabin/gstcamerabin.c20
-rw-r--r--gst/debugutils/fpsdisplaysink.c5
-rw-r--r--gst/mpegdemux/gstmpegdemux.c73
-rw-r--r--gst/mpegdemux/gstmpegtsdemux.c48
-rw-r--r--gst/mpegdemux/gstpesfilter.c49
-rw-r--r--gst/mpegdemux/mpegtspacketizer.c10
-rw-r--r--gst/mpegdemux/mpegtsparse.c55
-rw-r--r--gst/mxf/mxfdemux.c55
-rw-r--r--gst/pcapparse/gstpcapparse.h7
-rw-r--r--gst/real/gstrealaudiodec.c14
-rw-r--r--gst/real/gstrealvideodec.c20
-rw-r--r--gst/rtpmanager/rtpsession.c3
-rw-r--r--gst/rtpmux/gstrtpmux.c68
21 files changed, 519 insertions, 145 deletions
diff --git a/gst/aacparse/gstbaseparse.c b/gst/aacparse/gstbaseparse.c
index 026b1341..b59319a5 100644
--- a/gst/aacparse/gstbaseparse.c
+++ b/gst/aacparse/gstbaseparse.c
@@ -735,7 +735,6 @@ gst_base_parse_handle_and_push_buffer (GstBaseParse * parse,
GstBaseParseClass * klass, GstBuffer * buffer)
{
GstFlowReturn ret;
- GstClockTime last_stop = GST_CLOCK_TIME_NONE;
if (parse->priv->discont) {
GST_DEBUG_OBJECT (parse, "marking DISCONT");
@@ -749,6 +748,46 @@ gst_base_parse_handle_and_push_buffer (GstBaseParse * parse,
* keep track of timestamp and calculate everything possible
* if not set already */
+ /* First buffers are dropped, this means that the subclass needs more
+ * frames to decide on the format and queues them internally */
+ if (ret == GST_BASE_PARSE_FLOW_DROPPED && !GST_PAD_CAPS (parse->srcpad)) {
+ gst_buffer_unref (buffer);
+ return GST_FLOW_OK;
+ }
+
+ /* convert internal flow to OK and mark discont for the next buffer. */
+ if (ret == GST_BASE_PARSE_FLOW_DROPPED) {
+ parse->priv->discont = TRUE;
+ ret = GST_FLOW_OK;
+
+ gst_buffer_unref (buffer);
+
+ return ret;
+ } else if (ret != GST_FLOW_OK) {
+ return ret;
+ }
+
+ return gst_base_parse_push_buffer (parse, buffer);
+}
+
+/**
+ * gst_base_parse_push_buffer:
+ * @parse: #GstBaseParse.
+ * @buffer: #GstBuffer.
+ *
+ * Pushes the buffer downstream, sends any pending events and
+ * does some timestamp and segment handling.
+ *
+ * This must be called with srcpad STREAM_LOCK held.
+ *
+ * Returns: #GstFlowReturn
+ */
+GstFlowReturn
+gst_base_parse_push_buffer (GstBaseParse * parse, GstBuffer * buffer)
+{
+ GstFlowReturn ret = GST_FLOW_OK;
+ GstClockTime last_stop = GST_CLOCK_TIME_NONE;
+
if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
last_stop = GST_BUFFER_TIMESTAMP (buffer);
if (last_stop != GST_CLOCK_TIME_NONE && GST_BUFFER_DURATION_IS_VALID (buffer))
@@ -792,39 +831,30 @@ gst_base_parse_handle_and_push_buffer (GstBaseParse * parse,
/* TODO: Add to seek table */
- if (ret == GST_FLOW_OK) {
- if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
- GST_CLOCK_TIME_IS_VALID (parse->segment.stop) &&
- GST_BUFFER_TIMESTAMP (buffer) > parse->segment.stop) {
- GST_LOG_OBJECT (parse, "Dropped frame, after segment");
- gst_buffer_unref (buffer);
- } else if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
- GST_BUFFER_DURATION_IS_VALID (buffer) &&
- GST_CLOCK_TIME_IS_VALID (parse->segment.start) &&
- GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer)
- < parse->segment.start) {
- /* FIXME: subclass needs way to override the start as downstream might
- * need frames before for proper decoding */
- GST_LOG_OBJECT (parse, "Dropped frame, before segment");
- gst_buffer_unref (buffer);
- } else {
- ret = gst_pad_push (parse->srcpad, buffer);
- GST_LOG_OBJECT (parse, "frame (%d bytes) pushed: %d",
- GST_BUFFER_SIZE (buffer), ret);
- }
- } else {
+ if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
+ GST_CLOCK_TIME_IS_VALID (parse->segment.stop) &&
+ GST_BUFFER_TIMESTAMP (buffer) > parse->segment.stop) {
+ GST_LOG_OBJECT (parse, "Dropped frame, after segment");
gst_buffer_unref (buffer);
+ } else if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
+ GST_BUFFER_DURATION_IS_VALID (buffer) &&
+ GST_CLOCK_TIME_IS_VALID (parse->segment.start) &&
+ GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer)
+ < parse->segment.start) {
+ /* FIXME: subclass needs way to override the start as downstream might
+ * need frames before for proper decoding */
+ GST_LOG_OBJECT (parse, "Dropped frame, before segment");
+ gst_buffer_unref (buffer);
+ } else {
+ ret = gst_pad_push (parse->srcpad, buffer);
+ GST_LOG_OBJECT (parse, "frame (%d bytes) pushed: %d",
+ GST_BUFFER_SIZE (buffer), ret);
}
/* Update current running segment position */
if (ret == GST_FLOW_OK && last_stop != GST_CLOCK_TIME_NONE)
gst_segment_set_last_stop (&parse->segment, GST_FORMAT_TIME, last_stop);
- /* convert internal flow to OK and mark discont for the next buffer. */
- if (ret == GST_BASE_PARSE_FLOW_DROPPED) {
- parse->priv->discont = TRUE;
- ret = GST_FLOW_OK;
- }
return ret;
}
@@ -1575,12 +1605,13 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
* it directly or fail. For TIME, try upstream, but do it ourselves if
* it fails upstream */
if (format != GST_FORMAT_TIME) {
- gst_event_ref (event);
return gst_pad_push_event (parse->sinkpad, event);
} else {
gst_event_ref (event);
- if (gst_pad_push_event (parse->sinkpad, event))
+ if (gst_pad_push_event (parse->sinkpad, event)) {
+ gst_event_unref (event);
return TRUE;
+ }
}
/* get flush flag */
diff --git a/gst/aacparse/gstbaseparse.h b/gst/aacparse/gstbaseparse.h
index a2856cc7..9d53f07b 100644
--- a/gst/aacparse/gstbaseparse.h
+++ b/gst/aacparse/gstbaseparse.h
@@ -225,6 +225,9 @@ struct _GstBaseParseClass {
GType gst_base_parse_get_type (void);
+GstFlowReturn gst_base_parse_push_buffer (GstBaseParse *parse,
+ GstBuffer *buffer);
+
void gst_base_parse_set_duration (GstBaseParse *parse,
GstFormat fmt,
gint64 duration);
diff --git a/gst/amrparse/gstbaseparse.c b/gst/amrparse/gstbaseparse.c
index ad963785..870492a8 100644
--- a/gst/amrparse/gstbaseparse.c
+++ b/gst/amrparse/gstbaseparse.c
@@ -735,7 +735,6 @@ gst_base_parse_handle_and_push_buffer (GstBaseParse * parse,
GstBaseParseClass * klass, GstBuffer * buffer)
{
GstFlowReturn ret;
- GstClockTime last_stop = GST_CLOCK_TIME_NONE;
if (parse->priv->discont) {
GST_DEBUG_OBJECT (parse, "marking DISCONT");
@@ -749,6 +748,46 @@ gst_base_parse_handle_and_push_buffer (GstBaseParse * parse,
* keep track of timestamp and calculate everything possible
* if not set already */
+ /* First buffers are dropped, this means that the subclass needs more
+ * frames to decide on the format and queues them internally */
+ if (ret == GST_BASE_PARSE_FLOW_DROPPED && !GST_PAD_CAPS (parse->srcpad)) {
+ gst_buffer_unref (buffer);
+ return GST_FLOW_OK;
+ }
+
+ /* convert internal flow to OK and mark discont for the next buffer. */
+ if (ret == GST_BASE_PARSE_FLOW_DROPPED) {
+ parse->priv->discont = TRUE;
+ ret = GST_FLOW_OK;
+
+ gst_buffer_unref (buffer);
+
+ return ret;
+ } else if (ret != GST_FLOW_OK) {
+ return ret;
+ }
+
+ return gst_base_parse_push_buffer (parse, buffer);
+}
+
+/**
+ * gst_base_parse_push_buffer:
+ * @parse: #GstBaseParse.
+ * @buffer: #GstBuffer.
+ *
+ * Pushes the buffer downstream, sends any pending events and
+ * does some timestamp and segment handling.
+ *
+ * This must be called with srcpad STREAM_LOCK held.
+ *
+ * Returns: #GstFlowReturn
+ */
+GstFlowReturn
+gst_base_parse_push_buffer (GstBaseParse * parse, GstBuffer * buffer)
+{
+ GstFlowReturn ret = GST_FLOW_OK;
+ GstClockTime last_stop = GST_CLOCK_TIME_NONE;
+
if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
last_stop = GST_BUFFER_TIMESTAMP (buffer);
if (last_stop != GST_CLOCK_TIME_NONE && GST_BUFFER_DURATION_IS_VALID (buffer))
@@ -792,39 +831,30 @@ gst_base_parse_handle_and_push_buffer (GstBaseParse * parse,
/* TODO: Add to seek table */
- if (ret == GST_FLOW_OK) {
- if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
- GST_CLOCK_TIME_IS_VALID (parse->segment.stop) &&
- GST_BUFFER_TIMESTAMP (buffer) > parse->segment.stop) {
- GST_LOG_OBJECT (parse, "Dropped frame, after segment");
- gst_buffer_unref (buffer);
- } else if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
- GST_BUFFER_DURATION_IS_VALID (buffer) &&
- GST_CLOCK_TIME_IS_VALID (parse->segment.start) &&
- GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer)
- < parse->segment.start) {
- /* FIXME: subclass needs way to override the start as downstream might
- * need frames before for proper decoding */
- GST_LOG_OBJECT (parse, "Dropped frame, before segment");
- gst_buffer_unref (buffer);
- } else {
- ret = gst_pad_push (parse->srcpad, buffer);
- GST_LOG_OBJECT (parse, "frame (%d bytes) pushed: %d",
- GST_BUFFER_SIZE (buffer), ret);
- }
- } else {
+ if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
+ GST_CLOCK_TIME_IS_VALID (parse->segment.stop) &&
+ GST_BUFFER_TIMESTAMP (buffer) > parse->segment.stop) {
+ GST_LOG_OBJECT (parse, "Dropped frame, after segment");
gst_buffer_unref (buffer);
+ } else if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
+ GST_BUFFER_DURATION_IS_VALID (buffer) &&
+ GST_CLOCK_TIME_IS_VALID (parse->segment.start) &&
+ GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer)
+ < parse->segment.start) {
+ /* FIXME: subclass needs way to override the start as downstream might
+ * need frames before for proper decoding */
+ GST_LOG_OBJECT (parse, "Dropped frame, before segment");
+ gst_buffer_unref (buffer);
+ } else {
+ ret = gst_pad_push (parse->srcpad, buffer);
+ GST_LOG_OBJECT (parse, "frame (%d bytes) pushed: %d",
+ GST_BUFFER_SIZE (buffer), ret);
}
/* Update current running segment position */
if (ret == GST_FLOW_OK && last_stop != GST_CLOCK_TIME_NONE)
gst_segment_set_last_stop (&parse->segment, GST_FORMAT_TIME, last_stop);
- /* convert internal flow to OK and mark discont for the next buffer. */
- if (ret == GST_BASE_PARSE_FLOW_DROPPED) {
- parse->priv->discont = TRUE;
- ret = GST_FLOW_OK;
- }
return ret;
}
@@ -1575,12 +1605,13 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
* it directly or fail. For TIME, try upstream, but do it ourselves if
* it fails upstream */
if (format != GST_FORMAT_TIME) {
- gst_event_ref (event);
return gst_pad_push_event (parse->sinkpad, event);
} else {
gst_event_ref (event);
- if (gst_pad_push_event (parse->sinkpad, event))
+ if (gst_pad_push_event (parse->sinkpad, event)) {
+ gst_event_unref (event);
return TRUE;
+ }
}
/* get flush flag */
diff --git a/gst/amrparse/gstbaseparse.h b/gst/amrparse/gstbaseparse.h
index a2856cc7..9d53f07b 100644
--- a/gst/amrparse/gstbaseparse.h
+++ b/gst/amrparse/gstbaseparse.h
@@ -225,6 +225,9 @@ struct _GstBaseParseClass {
GType gst_base_parse_get_type (void);
+GstFlowReturn gst_base_parse_push_buffer (GstBaseParse *parse,
+ GstBuffer *buffer);
+
void gst_base_parse_set_duration (GstBaseParse *parse,
GstFormat fmt,
gint64 duration);
diff --git a/gst/camerabin/TODO b/gst/camerabin/TODO
new file mode 100644
index 00000000..423c0628
--- /dev/null
+++ b/gst/camerabin/TODO
@@ -0,0 +1,31 @@
+= Cleanups =
+* often two g_object_set for same object one after the other
+* use GST_*_OBJECT () more often
+* there are two gst_element_set_state() one after each other
+
+= Renaming =
+* internal use of img->image, vid->video
+
+= Refactorisation =
+* gstcamerabin:gst_camerabin_rewrite_tags
+ - sounds fishy, should use normal tagsetter method
+ - gst_camerabin_rewrite_tags_to_bin(9 why don't we just send a tag-event?
+
+* file-name property
+ - supplying an already opened filedeskriptor would be more safe
+ - need to check what filesink does if the file exists and cannot be overwritten
+
+* imagbin
+ - we want async operation here (especialy for burst mode capture)
+ - right now, its a bit fragile as we muck with locked_state
+ - main problem is that the location for filesink can only be set in NULL/READY
+ and we need to do that sync'ed with the dataflow. we can't use multifilesink
+ as it does a file per pad_push
+ - one problem of the current approach is that we can't have an image in e.g,
+ postprocessing while anotherone is beeing saved
+ - we could use a pool of imagebins:
+ - configure one (set filename)
+ - push_buffer
+ - on eos, put it back to the pool
+ - for this we need to check that we can have multiple instances of e.g.
+ dsp jpeg encoders
diff --git a/gst/camerabin/camerabinimage.c b/gst/camerabin/camerabinimage.c
index 8eea8d91..25730ccd 100644
--- a/gst/camerabin/camerabinimage.c
+++ b/gst/camerabin/camerabinimage.c
@@ -463,15 +463,13 @@ gst_camerabin_image_create_elements (GstCameraBinImage * img)
g_object_set (G_OBJECT (img->meta_mux), "exif-byte-order", 1, NULL);
}
- /* Create file sink element */
+ /* Add sink element for storing the image */
if (!(img->sink =
gst_camerabin_create_and_add_element (imgbin, DEFAULT_SINK))) {
goto done;
}
-
- /* Set properties */
- g_object_set (G_OBJECT (img->sink), "location", img->filename->str, NULL);
- g_object_set (G_OBJECT (img->sink), "async", FALSE, NULL);
+ g_object_set (G_OBJECT (img->sink), "location", img->filename->str, "async", FALSE, "buffer-mode", 2, /* non buffered io */
+ NULL);
ret = TRUE;
diff --git a/gst/camerabin/camerabinpreview.c b/gst/camerabin/camerabinpreview.c
index 9b12bbac..b8e53389 100644
--- a/gst/camerabin/camerabinpreview.c
+++ b/gst/camerabin/camerabinpreview.c
@@ -95,6 +95,8 @@ gst_camerabin_preview_create_pipeline (GstCameraBin * camera)
gst_bin_add_many (GST_BIN (camera->preview_pipeline),
src, csp, filter, vscale, sink, NULL);
+ GST_DEBUG ("preview format is: %" GST_PTR_FORMAT, camera->preview_caps);
+
g_object_set (filter, "caps", camera->preview_caps, NULL);
g_object_set (sink, "preroll-queue-len", 1, "signal-handoffs", TRUE, NULL);
g_object_set (vscale, "method", 0, NULL);
@@ -195,7 +197,8 @@ gst_camerabin_preview_convert (GstCameraBin * camera, GstBuffer * buf)
bflags = GST_BUFFER_FLAGS (buf);
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_READONLY);
- GST_DEBUG ("running conversion pipeline");
+ GST_DEBUG ("running conversion pipeline, source is: %" GST_PTR_FORMAT,
+ GST_BUFFER_CAPS (buf));
gst_element_set_state (camera->preview_pipeline, GST_STATE_PLAYING);
g_signal_emit_by_name (src, "push-buffer", buf, &fret);
diff --git a/gst/camerabin/camerabinvideo.c b/gst/camerabin/camerabinvideo.c
index 4bbc5057..bc915243 100644
--- a/gst/camerabin/camerabinvideo.c
+++ b/gst/camerabin/camerabinvideo.c
@@ -553,7 +553,6 @@ gst_camerabin_video_create_elements (GstCameraBinVideo * vid)
gst_ghost_pad_set_target (GST_GHOST_PAD (vid->sinkpad), vid_sinkpad);
gst_object_unref (vid_sinkpad);
-
/* Add queue element for video */
vid->tee_video_srcpad = gst_element_get_request_pad (vid->tee, "src%d");
if (!(vid->video_queue =
@@ -565,7 +564,6 @@ gst_camerabin_video_create_elements (GstCameraBinVideo * vid)
gst_pad_add_buffer_probe (vid->tee_video_srcpad,
G_CALLBACK (camerabin_video_pad_tee_src0_have_buffer), vid);
-
#ifdef USE_TIMEOVERLAY
/* Add timeoverlay element to visualize elapsed time for debugging */
if (!(gst_camerabin_create_and_add_element (vidbin, "timeoverlay"))) {
@@ -600,8 +598,8 @@ gst_camerabin_video_create_elements (GstCameraBinVideo * vid)
gst_camerabin_create_and_add_element (vidbin, DEFAULT_SINK))) {
goto error;
}
- g_object_set (G_OBJECT (vid->sink), "location", vid->filename->str, NULL);
-
+ g_object_set (G_OBJECT (vid->sink), "location", vid->filename->str, "buffer-mode", 2, /* non buffered io */
+ NULL);
/* Add user set or default audio source element */
if (vid->user_aud_src) {
@@ -615,10 +613,9 @@ gst_camerabin_video_create_elements (GstCameraBinVideo * vid)
}
/* Add queue element for audio */
- if (!(queue = gst_camerabin_create_and_add_element (vidbin, "queue"))) {
+ if (!(gst_camerabin_create_and_add_element (vidbin, "queue"))) {
goto error;
}
- queue = NULL;
/* Add optional audio conversion and volume elements and
raise no errors if adding them fails */
diff --git a/gst/camerabin/gstcamerabin.c b/gst/camerabin/gstcamerabin.c
index 9d8a14cc..22a33477 100644
--- a/gst/camerabin/gstcamerabin.c
+++ b/gst/camerabin/gstcamerabin.c
@@ -954,7 +954,7 @@ gst_camerabin_change_mode (GstCameraBin * camera, gint mode)
camera->mode = mode;
if (camera->active_bin) {
GST_DEBUG_OBJECT (camera, "stopping active bin");
- gst_element_set_state (camera->active_bin, GST_STATE_NULL);
+ gst_element_set_state (camera->active_bin, GST_STATE_READY);
}
if (camera->mode == MODE_IMAGE) {
GstStateChangeReturn state_ret;
@@ -1031,6 +1031,10 @@ gst_camerabin_set_element_zoom (GstCameraBin * camera, gint zoom)
if (zoom != ZOOM_1X) {
w2_crop = (camera->width - (camera->width * ZOOM_1X / zoom)) / 2;
h2_crop = (camera->height - (camera->height * ZOOM_1X / zoom)) / 2;
+
+ /* force number of pixels cropped from left to be even, to avoid slow code
+ * path on videoscale */
+ w2_crop &= 0xFFFE;
}
pad_zoom_sink = gst_element_get_static_pad (camera->src_zoom_crop, "sink");
@@ -2862,12 +2866,8 @@ gst_camerabin_set_property (GObject * object, guint prop_id,
break;
case ARG_FILTER_CAPS:
GST_OBJECT_LOCK (camera);
- if (camera->view_finder_caps) {
- gst_caps_unref (camera->view_finder_caps);
- }
- /* just ref, we don't modify it inplace */
- camera->view_finder_caps =
- gst_caps_ref ((GstCaps *) gst_value_get_caps (value));
+ gst_caps_replace (&camera->view_finder_caps,
+ (GstCaps *) gst_value_get_caps (value));
GST_OBJECT_UNLOCK (camera);
if (GST_STATE (camera) != GST_STATE_NULL) {
gst_camerabin_set_capsfilter_caps (camera, camera->view_finder_caps);
@@ -2875,10 +2875,8 @@ gst_camerabin_set_property (GObject * object, guint prop_id,
break;
case ARG_PREVIEW_CAPS:
GST_OBJECT_LOCK (camera);
- if (camera->preview_caps) {
- gst_caps_unref (camera->preview_caps);
- }
- camera->preview_caps = gst_caps_copy (gst_value_get_caps (value));
+ gst_caps_replace (&camera->preview_caps,
+ (GstCaps *) gst_value_get_caps (value));
GST_OBJECT_UNLOCK (camera);
gst_camerabin_preview_create_pipeline (camera);
break;
diff --git a/gst/debugutils/fpsdisplaysink.c b/gst/debugutils/fpsdisplaysink.c
index 54f5cc54..ff3e0dfd 100644
--- a/gst/debugutils/fpsdisplaysink.c
+++ b/gst/debugutils/fpsdisplaysink.c
@@ -206,7 +206,10 @@ display_current_fps (gpointer data)
GstFPSDisplaySink *self = GST_FPS_DISPLAY_SINK (data);
gint64 current_ts;
- gst_element_query (self->video_sink, self->query);
+ /* if query failed try again on next timer tick */
+ if (!gst_element_query (self->video_sink, self->query))
+ return TRUE;
+
gst_query_parse_position (self->query, NULL, &current_ts);
if (GST_CLOCK_TIME_IS_VALID (self->last_ts)) {
diff --git a/gst/mpegdemux/gstmpegdemux.c b/gst/mpegdemux/gstmpegdemux.c
index ce1d0978..75d5960f 100644
--- a/gst/mpegdemux/gstmpegdemux.c
+++ b/gst/mpegdemux/gstmpegdemux.c
@@ -845,6 +845,7 @@ gst_flups_demux_close_segment (GstFluPSDemux * demux)
{
gint id;
GstEvent *event = NULL;
+ guint64 base_time;
#if POST_10_10
GST_INFO_OBJECT (demux, "closing running segment %" GST_SEGMENT_FORMAT,
@@ -855,14 +856,17 @@ gst_flups_demux_close_segment (GstFluPSDemux * demux)
* last_seg_start != clock_time_none, as that indicates a sparse-stream
* event was sent there */
+ if ((base_time = demux->base_time) == (guint64) - 1)
+ base_time = 0;
+
+
/* Close the current segment for a linear playback */
if (demux->src_segment.rate >= 0) {
/* for forward playback, we played from start to last_stop */
event = gst_event_new_new_segment (TRUE,
demux->src_segment.rate, demux->src_segment.format,
- demux->src_segment.start + demux->base_time,
- demux->src_segment.last_stop + demux->base_time,
- demux->src_segment.time);
+ demux->src_segment.start + base_time,
+ demux->src_segment.last_stop + base_time, demux->src_segment.time);
} else {
gint64 stop;
@@ -872,8 +876,8 @@ gst_flups_demux_close_segment (GstFluPSDemux * demux)
/* for reverse playback, we played from stop to last_stop. */
event = gst_event_new_new_segment (TRUE,
demux->src_segment.rate, demux->src_segment.format,
- demux->src_segment.last_stop + demux->base_time,
- stop + demux->base_time, demux->src_segment.last_stop);
+ demux->src_segment.last_stop + base_time,
+ stop + base_time, demux->src_segment.last_stop);
}
if (event) {
@@ -1383,11 +1387,66 @@ gst_flups_demux_src_query (GstPad * pad, GstQuery * query)
res = TRUE;
break;
}
+ case GST_QUERY_SEEKING:{
+ GstFormat fmt;
+
+ gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
+
+ res = TRUE;
+ if (demux->random_access) {
+ /* In pull mode we can seek in TIME format if we have the SCR */
+ if (fmt != GST_FORMAT_TIME || demux->scr_rate_n == G_MAXUINT64
+ || demux->scr_rate_d == G_MAXUINT64)
+ gst_query_set_seeking (query, fmt, FALSE, -1, -1);
+ else
+ gst_query_set_seeking (query, fmt, TRUE, 0, -1);
+ } else {
+ if (fmt == GST_FORMAT_BYTES) {
+ /* Seeking in BYTES format not supported at all */
+ gst_query_set_seeking (query, fmt, FALSE, -1, -1);
+ } else {
+ GstQuery *peerquery;
+ gboolean seekable;
+
+ /* Then ask upstream */
+ res = gst_pad_peer_query (demux->sinkpad, query);
+ if (res) {
+ /* If upstream can handle seeks we're done, if it
+ * can't we still have our TIME->BYTES conversion seek
+ */
+ gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL);
+ if (seekable || fmt != GST_FORMAT_TIME)
+ goto beach;
+ }
+
+ /* We can seek if upstream supports BYTES seeks and we
+ * have the SCR
+ */
+ peerquery = gst_query_new_seeking (GST_FORMAT_BYTES);
+ res = gst_pad_peer_query (demux->sinkpad, query);
+ if (!res || demux->scr_rate_n == G_MAXUINT64
+ || demux->scr_rate_d == G_MAXUINT64) {
+ gst_query_set_seeking (query, fmt, FALSE, -1, -1);
+ } else {
+ gst_query_parse_seeking (peerquery, NULL, &seekable, NULL, NULL);
+ if (seekable)
+ gst_query_set_seeking (query, GST_FORMAT_TIME, TRUE, 0, -1);
+ else
+ gst_query_set_seeking (query, fmt, FALSE, -1, -1);
+ }
+
+ gst_query_unref (peerquery);
+ res = TRUE;
+ }
+ }
+ break;
+ }
default:
res = gst_pad_query_default (pad, query);
break;
}
+beach:
gst_object_unref (demux);
return res;
@@ -2540,7 +2599,7 @@ gst_flups_demux_loop (GstPad * pad)
{
GstFluPSDemux *demux;
GstFlowReturn ret = GST_FLOW_OK;
- guint offset = 0;
+ guint64 offset = 0;
demux = GST_FLUPS_DEMUX (gst_pad_get_parent (pad));
@@ -2579,7 +2638,7 @@ gst_flups_demux_loop (GstPad * pad)
goto pause;
}
} else { /* Reverse playback */
- guint size = MIN (offset, BLOCK_SZ);
+ guint64 size = MIN (offset, BLOCK_SZ);
/* pull in data */
ret = gst_flups_demux_pull_block (pad, demux, offset - size, size);
diff --git a/gst/mpegdemux/gstmpegtsdemux.c b/gst/mpegdemux/gstmpegtsdemux.c
index cb082a2b..8de7cc75 100644
--- a/gst/mpegdemux/gstmpegtsdemux.c
+++ b/gst/mpegdemux/gstmpegtsdemux.c
@@ -1697,7 +1697,8 @@ gst_mpegts_demux_parse_adaptation_field (GstMpegTSStream * stream,
memset (pmts_checked, 0, sizeof (gboolean) * (MPEGTS_MAX_PID + 1));
for (j = 0; j < MPEGTS_MAX_PID + 1; j++) {
- if (demux->streams[j] && demux->streams[j]->PMT_pid) {
+ if (demux->streams[j]
+ && demux->streams[j]->PMT_pid <= MPEGTS_MAX_PID) {
if (!pmts_checked[demux->streams[j]->PMT_pid]) {
/* check if this is correct pcr for pmt */
if (demux->streams[demux->streams[j]->PMT_pid] &&
@@ -2777,9 +2778,54 @@ gst_mpegts_demux_src_pad_query (GstPad * pad, GstQuery * query)
}
break;
}
+ case GST_QUERY_SEEKING:{
+ GstFormat fmt;
+
+ gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
+ if (fmt == GST_FORMAT_BYTES) {
+ /* Seeking in BYTES format not supported at all */
+ gst_query_set_seeking (query, fmt, FALSE, -1, -1);
+ } else {
+ GstQuery *peerquery;
+ gboolean seekable;
+
+ /* Then ask upstream */
+ res = gst_pad_peer_query (demux->sinkpad, query);
+ if (res) {
+ /* If upstream can handle seeks we're done, if it
+ * can't we still have our TIME->BYTES conversion seek
+ */
+ gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL);
+ if (seekable || fmt != GST_FORMAT_TIME)
+ goto beach;
+ }
+
+ /* We can seek if upstream supports BYTES seeks and we
+ * have a bitrate
+ */
+ peerquery = gst_query_new_seeking (GST_FORMAT_BYTES);
+ res = gst_pad_peer_query (demux->sinkpad, query);
+ if (!res || demux->bitrate == -1) {
+ gst_query_set_seeking (query, fmt, FALSE, -1, -1);
+ } else {
+ gst_query_parse_seeking (peerquery, NULL, &seekable, NULL, NULL);
+ if (seekable)
+ gst_query_set_seeking (query, GST_FORMAT_TIME, TRUE, 0, -1);
+ else
+ gst_query_set_seeking (query, fmt, FALSE, -1, -1);
+ }
+
+ gst_query_unref (peerquery);
+ res = TRUE;
+ }
+ break;
+ }
default:
res = gst_pad_query_default (pad, query);
+ break;
}
+
+beach:
gst_object_unref (demux);
return res;
diff --git a/gst/mpegdemux/gstpesfilter.c b/gst/mpegdemux/gstpesfilter.c
index b520c766..736d4960 100644
--- a/gst/mpegdemux/gstpesfilter.c
+++ b/gst/mpegdemux/gstpesfilter.c
@@ -151,6 +151,7 @@ gst_pes_filter_parse (GstPESFilter * filter)
* to set the allow_unbounded flag if they want */
if (filter->length == 0 &&
((filter->start_code & 0xFFFFFFF0) == PACKET_VIDEO_START_CODE ||
+ filter->start_code == ID_EXTENDED_STREAM_ID ||
filter->allow_unbounded)) {
GST_DEBUG ("id 0x%02x, unbounded length", filter->id);
filter->unbounded_packet = TRUE;
@@ -389,9 +390,53 @@ gst_pes_filter_parse (GstPESFilter * filter)
}
/* PES_extension_flag */
if ((flags & 0x01)) {
- GST_DEBUG ("%x PES_extension", filter->id);
+ flags = *data++;
+ header_data_length -= 1;
+ datalen -= 1;
+ GST_DEBUG ("%x PES_extension, flags 0x%02x", filter->id, flags);
+ /* PES_private_data_flag */
+ if ((flags & 0x80)) {
+ GST_DEBUG ("%x PES_private_data_flag", filter->id);
+ data += 16;
+ header_data_length -= 16;
+ datalen -= 16;
+ }
+ /* pack_header_field_flag */
+ if ((flags & 0x40)) {
+ guint8 pack_field_length = *data;
+ GST_DEBUG ("%x pack_header_field_flag, pack_field_length %d",
+ filter->id, pack_field_length);
+ data += pack_field_length + 1;
+ header_data_length -= pack_field_length + 1;
+ datalen -= pack_field_length + 1;
+ }
+ /* program_packet_sequence_counter_flag */
+ if ((flags & 0x20)) {
+ GST_DEBUG ("%x program_packet_sequence_counter_flag", filter->id);
+ data += 2;
+ header_data_length -= 2;
+ datalen -= 2;
+ }
+ /* P-STD_buffer_flag */
+ if ((flags & 0x10)) {
+ GST_DEBUG ("%x P-STD_buffer_flag", filter->id);
+ data += 2;
+ header_data_length -= 2;
+ datalen -= 2;
+ }
+ /* PES_extension_flag_2 */
+ if ((flags & 0x01)) {
+ guint8 PES_extension_field_length = *data++;
+ GST_DEBUG ("%x PES_extension_flag_2, len %d",
+ filter->id, PES_extension_field_length & 0x7f);
+ if (PES_extension_field_length == 0x81) {
+ GST_DEBUG ("%x substream id 0x%02x", filter->id, *data);
+ }
+ data += PES_extension_field_length & 0x7f;
+ header_data_length -= (PES_extension_field_length & 0x7f) + 1;
+ datalen -= (PES_extension_field_length & 0x7f) + 1;
+ }
}
-
/* calculate the amount of real data in this PES packet */
data += header_data_length;
datalen -= header_data_length;
diff --git a/gst/mpegdemux/mpegtspacketizer.c b/gst/mpegdemux/mpegtspacketizer.c
index 5ed71f0c..da53a926 100644
--- a/gst/mpegdemux/mpegtspacketizer.c
+++ b/gst/mpegdemux/mpegtspacketizer.c
@@ -1749,7 +1749,9 @@ mpegts_packetizer_parse_eit (MpegTSPacketizer * packetizer,
break;
}
component = gst_structure_new ("video", "high-definition",
- G_TYPE_BOOLEAN, TRUE, "frequency", G_TYPE_INT, freq, NULL);
+ G_TYPE_BOOLEAN, TRUE, "frequency", G_TYPE_INT, freq,
+ "tag", G_TYPE_INT, DESC_DVB_COMPONENT_tag (comp_descriptor),
+ NULL);
if (widescreen == 0) {
gst_structure_set (component, "aspect-ratio",
G_TYPE_STRING, "4:3", NULL);
@@ -1787,7 +1789,8 @@ mpegts_packetizer_parse_eit (MpegTSPacketizer * packetizer,
break;
}
component = gst_structure_new ("audio", "type", G_TYPE_STRING,
- comptype, NULL);
+ comptype, "tag", G_TYPE_INT,
+ DESC_DVB_COMPONENT_tag (comp_descriptor), NULL);
break;
case 0x03: /* subtitles/teletext/vbi */
comptype = "reserved";
@@ -1827,7 +1830,8 @@ mpegts_packetizer_parse_eit (MpegTSPacketizer * packetizer,
break;
}
component = gst_structure_new ("teletext", "type", G_TYPE_STRING,
- comptype, NULL);
+ comptype, "tag", G_TYPE_INT,
+ DESC_DVB_COMPONENT_tag (comp_descriptor), NULL);
break;
}
if (component) {
diff --git a/gst/mpegdemux/mpegtsparse.c b/gst/mpegdemux/mpegtsparse.c
index 976935f2..90a8ea3b 100644
--- a/gst/mpegdemux/mpegtsparse.c
+++ b/gst/mpegdemux/mpegtsparse.c
@@ -553,6 +553,35 @@ mpegts_parse_program_remove_stream (MpegTSParse * parse,
g_hash_table_remove (program->streams, GINT_TO_POINTER ((gint) pid));
}
+static void
+mpegts_parse_deactivate_pmt (MpegTSParse * parse, MpegTSParseProgram * program)
+{
+ gint i;
+ guint pid;
+ guint stream_type;
+ GstStructure *stream;
+ const GValue *streams;
+ const GValue *value;
+
+ if (program->pmt_info) {
+ streams = gst_structure_get_value (program->pmt_info, "streams");
+
+ for (i = 0; i < gst_value_list_get_size (streams); ++i) {
+ value = gst_value_list_get_value (streams, i);
+ stream = g_value_get_boxed (value);
+ gst_structure_get_uint (stream, "pid", &pid);
+ gst_structure_get_uint (stream, "stream-type", &stream_type);
+ mpegts_parse_program_remove_stream (parse, program, (guint16) pid);
+ g_hash_table_remove (parse->pes_pids, GINT_TO_POINTER ((gint) pid));
+ }
+
+ /* remove pcr stream */
+ mpegts_parse_program_remove_stream (parse, program, program->pcr_pid);
+ g_hash_table_remove (parse->pes_pids,
+ GINT_TO_POINTER ((gint) program->pcr_pid));
+ }
+}
+
static MpegTSParsePad *
mpegts_parse_create_tspad (MpegTSParse * parse, const gchar * pad_name)
{
@@ -940,6 +969,7 @@ mpegts_parse_apply_pat (MpegTSParse * parse, GstStructure * pat_info)
parse->pads_to_remove = g_list_append (parse->pads_to_remove,
mpegts_parse_deactivate_program (parse, program));
+ mpegts_parse_deactivate_pmt (parse, program);
mpegts_parse_remove_program (parse, program_number);
g_hash_table_remove (parse->psi_pids, GINT_TO_POINTER ((gint) pid));
mpegts_packetizer_remove_stream (parse->packetizer, pid);
@@ -964,7 +994,6 @@ mpegts_parse_apply_pmt (MpegTSParse * parse,
guint stream_type;
GstStructure *stream;
gint i;
- const GValue *old_streams;
const GValue *new_streams;
const GValue *value;
@@ -975,27 +1004,11 @@ mpegts_parse_apply_pmt (MpegTSParse * parse,
GST_OBJECT_LOCK (parse);
program = mpegts_parse_get_program (parse, program_number);
if (program) {
- if (program->pmt_info) {
- /* deactivate old pmt */
- old_streams = gst_structure_get_value (program->pmt_info, "streams");
-
- for (i = 0; i < gst_value_list_get_size (old_streams); ++i) {
- value = gst_value_list_get_value (old_streams, i);
- stream = g_value_get_boxed (value);
- gst_structure_get_uint (stream, "pid", &pid);
- gst_structure_get_uint (stream, "stream-type", &stream_type);
- mpegts_parse_program_remove_stream (parse, program, (guint16) pid);
- g_hash_table_remove (parse->pes_pids, GINT_TO_POINTER ((gint) pid));
- }
-
- /* remove pcr stream */
- mpegts_parse_program_remove_stream (parse, program, program->pcr_pid);
- g_hash_table_remove (parse->pes_pids,
- GINT_TO_POINTER ((gint) program->pcr_pid));
-
+ /* deactivate old pmt */
+ mpegts_parse_deactivate_pmt (parse, program);
+ if (program->pmt_info)
gst_structure_free (program->pmt_info);
- program->pmt_info = NULL;
- }
+ program->pmt_info = NULL;
} else {
/* no PAT?? */
g_hash_table_insert (parse->psi_pids,
diff --git a/gst/mxf/mxfdemux.c b/gst/mxf/mxfdemux.c
index 5abd37ff..e646be8c 100644
--- a/gst/mxf/mxfdemux.c
+++ b/gst/mxf/mxfdemux.c
@@ -3453,6 +3453,7 @@ gst_mxf_demux_src_query_type (GstPad * pad)
static const GstQueryType types[] = {
GST_QUERY_POSITION,
GST_QUERY_DURATION,
+ GST_QUERY_SEEKING,
0
};
@@ -3545,6 +3546,33 @@ gst_mxf_demux_src_query (GstPad * pad, GstQuery * query)
ret = TRUE;
break;
}
+ case GST_QUERY_SEEKING:{
+ GstFormat fmt;
+
+ ret = TRUE;
+ gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
+ if (fmt != GST_FORMAT_TIME) {
+ gst_query_set_seeking (query, fmt, FALSE, -1, -1);
+ goto done;
+ }
+
+ if (demux->random_access) {
+ gst_query_set_seeking (query, GST_FORMAT_TIME, TRUE, 0, -1);
+ } else {
+ GstQuery *peerquery = gst_query_new_seeking (GST_FORMAT_BYTES);
+ gboolean seekable;
+
+ seekable = gst_pad_peer_query (demux->sinkpad, peerquery);
+ if (seekable)
+ gst_query_parse_seeking (peerquery, NULL, &seekable, NULL, NULL);
+ if (seekable)
+ gst_query_set_seeking (query, GST_FORMAT_TIME, TRUE, 0, -1);
+ else
+ gst_query_set_seeking (query, GST_FORMAT_TIME, FALSE, -1, -1);
+ }
+
+ break;
+ }
default:
/* else forward upstream */
ret = gst_pad_peer_query (demux->sinkpad, query);
@@ -3806,6 +3834,33 @@ gst_mxf_demux_query (GstElement * element, GstQuery * query)
ret = TRUE;
break;
}
+ case GST_QUERY_SEEKING:{
+ GstFormat fmt;
+
+ ret = TRUE;
+ gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
+ if (fmt != GST_FORMAT_TIME) {
+ gst_query_set_seeking (query, fmt, FALSE, -1, -1);
+ goto done;
+ }
+
+ if (demux->random_access) {
+ gst_query_set_seeking (query, GST_FORMAT_TIME, TRUE, 0, -1);
+ } else {
+ GstQuery *peerquery = gst_query_new_seeking (GST_FORMAT_BYTES);
+ gboolean seekable;
+
+ seekable = gst_pad_peer_query (demux->sinkpad, peerquery);
+ if (seekable)
+ gst_query_parse_seeking (peerquery, NULL, &seekable, NULL, NULL);
+ if (seekable)
+ gst_query_set_seeking (query, GST_FORMAT_TIME, TRUE, 0, -1);
+ else
+ gst_query_set_seeking (query, GST_FORMAT_TIME, FALSE, -1, -1);
+ }
+
+ break;
+ }
default:
/* else forward upstream */
ret = gst_pad_peer_query (demux->sinkpad, query);
diff --git a/gst/pcapparse/gstpcapparse.h b/gst/pcapparse/gstpcapparse.h
index 8e45f8b2..cc1b55f6 100644
--- a/gst/pcapparse/gstpcapparse.h
+++ b/gst/pcapparse/gstpcapparse.h
@@ -45,10 +45,17 @@ typedef enum
PCAP_PARSE_STATE_PARSING,
} GstPcapParseState;
+/**
+ * GstPcapParse:
+ *
+ * GstPcapParse element.
+ */
+
struct _GstPcapParse
{
GstElement element;
+ /*< private >*/
GstPad * sink_pad;
GstPad * src_pad;
diff --git a/gst/real/gstrealaudiodec.c b/gst/real/gstrealaudiodec.c
index 1a94a77b..5f5b900d 100644
--- a/gst/real/gstrealaudiodec.c
+++ b/gst/real/gstrealaudiodec.c
@@ -262,12 +262,20 @@ open_library (GstRealAudioDec * dec, gint version, GstRADecLibrary * lib)
GST_LOG_OBJECT (dec, "opening module %s", codec);
- lib->module = g_module_open (codec, G_MODULE_BIND_LAZY);
+ /* This is racy, but it doesn't matter here; would be nice if GModule
+ * gave us a GError instead of an error string, but it doesn't, so.. */
+ if (g_file_test (codec, G_FILE_TEST_EXISTS)) {
+ lib->module = g_module_open (codec, G_MODULE_BIND_LAZY);
+ if (lib->module == NULL) {
+ GST_ERROR_OBJECT (dec, "Could not open codec library '%s': %s",
+ codec, g_module_error ());
+ }
+ } else {
+ GST_DEBUG_OBJECT (dec, "%s does not exist", codec);
+ }
g_free (codec);
if (lib->module)
goto codec_search_done;
-
- GST_LOG_OBJECT (dec, "failure, try next one...");
}
}
diff --git a/gst/real/gstrealvideodec.c b/gst/real/gstrealvideodec.c
index 74cb6f5a..313a99f2 100644
--- a/gst/real/gstrealvideodec.c
+++ b/gst/real/gstrealvideodec.c
@@ -480,7 +480,17 @@ open_library (GstRealVideoDec * dec, GstRealVideoDecVersion version,
gchar *codec = g_strconcat (split_path[i], "/", split_names[j], NULL);
GST_DEBUG_OBJECT (dec, "trying %s", codec);
- module = g_module_open (codec, G_MODULE_BIND_LAZY);
+ /* This is racy, but it doesn't matter here; would be nice if GModule
+ * gave us a GError instead of an error string, but it doesn't, so.. */
+ if (g_file_test (codec, G_FILE_TEST_EXISTS)) {
+ module = g_module_open (codec, G_MODULE_BIND_LAZY);
+ if (module == NULL) {
+ GST_ERROR_OBJECT (dec, "Could not open codec library '%s': %s",
+ codec, g_module_error ());
+ }
+ } else {
+ GST_LOG_OBJECT (dec, "%s does not exist", codec);
+ }
g_free (codec);
if (module)
goto codec_search_done;
@@ -492,7 +502,7 @@ codec_search_done:
g_strfreev (split_names);
if (module == NULL)
- goto could_not_open;
+ return FALSE;
GST_DEBUG_OBJECT (dec, "module opened, finding symbols");
@@ -527,12 +537,6 @@ unknown_version:
GST_ERROR_OBJECT (dec, "Cannot handle version %i.", version);
return FALSE;
}
-could_not_open:
- {
- GST_ERROR_OBJECT (dec, "Could not open library '%s' in '%s': %s", names,
- path, g_module_error ());
- return FALSE;
- }
could_not_load:
{
close_library (dec, lib);
diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c
index fa46f501..d63d9d0e 100644
--- a/gst/rtpmanager/rtpsession.c
+++ b/gst/rtpmanager/rtpsession.c
@@ -369,6 +369,9 @@ rtp_session_finalize (GObject * object)
for (i = 0; i < 32; i++)
g_hash_table_destroy (sess->ssrcs[i]);
+ g_list_foreach (sess->conflicting_addresses, (GFunc) g_free, NULL);
+ g_list_free (sess->conflicting_addresses);
+
g_free (sess->bye_reason);
g_hash_table_destroy (sess->cnames);
diff --git a/gst/rtpmux/gstrtpmux.c b/gst/rtpmux/gstrtpmux.c
index 82d4b003..4c2bea09 100644
--- a/gst/rtpmux/gstrtpmux.c
+++ b/gst/rtpmux/gstrtpmux.c
@@ -87,6 +87,7 @@ static void gst_rtp_mux_finalize (GObject * object);
static GstPad *gst_rtp_mux_request_new_pad (GstElement * element,
GstPadTemplate * templ, const gchar * name);
+static void gst_rtp_mux_release_pad (GstElement * element, GstPad * pad);
static GstFlowReturn gst_rtp_mux_chain (GstPad * pad, GstBuffer * buffer);
static gboolean gst_rtp_mux_setcaps (GstPad * pad, GstCaps * caps);
static GstCaps *gst_rtp_mux_getcaps (GstPad * pad);
@@ -148,6 +149,7 @@ gst_rtp_mux_class_init (GstRTPMuxClass * klass)
gstelement_class->request_new_pad =
GST_DEBUG_FUNCPTR (gst_rtp_mux_request_new_pad);
+ gstelement_class->release_pad = GST_DEBUG_FUNCPTR (gst_rtp_mux_release_pad);
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_rtp_mux_change_state);
klass->chain_func = gst_rtp_mux_chain;
@@ -246,15 +248,6 @@ gst_rtp_mux_create_sinkpad (GstRTPMux * rtp_mux, GstPadTemplate * templ)
}
static void
-free_pad_private (gpointer data, GObject * where_the_object_was)
-{
- GstRTPMuxPadPrivate *padpriv = data;
-
- gst_caps_replace (&padpriv->out_caps, NULL);
- g_slice_free (GstRTPMuxPadPrivate, padpriv);
-}
-
-static void
gst_rtp_mux_setup_sinkpad (GstRTPMux * rtp_mux, GstPad * sinkpad)
{
GstRTPMuxClass *klass;
@@ -274,7 +267,6 @@ gst_rtp_mux_setup_sinkpad (GstRTPMux * rtp_mux, GstPad * sinkpad)
gst_pad_set_active (sinkpad, TRUE);
gst_pad_set_element_private (sinkpad, padpriv);
- g_object_weak_ref (G_OBJECT (sinkpad), free_pad_private, padpriv);
/* dd the pad to the element */
gst_element_add_pad (GST_ELEMENT (rtp_mux), sinkpad);
@@ -306,6 +298,24 @@ gst_rtp_mux_request_new_pad (GstElement * element,
return newpad;
}
+static void
+gst_rtp_mux_release_pad (GstElement * element, GstPad * pad)
+{
+ GstRTPMuxPadPrivate *padpriv;
+
+ GST_OBJECT_LOCK (element);
+ padpriv = gst_pad_get_element_private (pad);
+ gst_pad_set_element_private (pad, NULL);
+ GST_OBJECT_UNLOCK (element);
+
+ gst_element_remove_pad (element, pad);
+
+ if (padpriv) {
+ gst_caps_replace (&padpriv->out_caps, NULL);
+ g_slice_free (GstRTPMuxPadPrivate, padpriv);
+ }
+}
+
/* Put our own clock-base on the buffer */
static void
gst_rtp_mux_readjust_rtp_timestamp (GstRTPMux * rtp_mux, GstPad * pad,
@@ -313,10 +323,14 @@ gst_rtp_mux_readjust_rtp_timestamp (GstRTPMux * rtp_mux, GstPad * pad,
{
guint32 ts;
guint32 sink_ts_base = 0;
- GstRTPMuxPadPrivate *padpriv = gst_pad_get_element_private (pad);
+ GstRTPMuxPadPrivate *padpriv;
+
- if (padpriv->have_clock_base)
+ GST_OBJECT_LOCK (rtp_mux);
+ padpriv = gst_pad_get_element_private (pad);
+ if (padpriv && padpriv->have_clock_base)
sink_ts_base = padpriv->clock_base;
+ GST_OBJECT_UNLOCK (rtp_mux);
ts = gst_rtp_buffer_get_timestamp (buffer) - sink_ts_base + rtp_mux->ts_base;
GST_LOG_OBJECT (rtp_mux, "Re-adjusting RTP ts %u to %u",
@@ -329,7 +343,7 @@ gst_rtp_mux_chain (GstPad * pad, GstBuffer * buffer)
{
GstRTPMux *rtp_mux;
GstFlowReturn ret;
- GstRTPMuxPadPrivate *padpriv = gst_pad_get_element_private (pad);
+ GstRTPMuxPadPrivate *padpriv;
rtp_mux = GST_RTP_MUX (gst_pad_get_parent (pad));
@@ -344,6 +358,9 @@ gst_rtp_mux_chain (GstPad * pad, GstBuffer * buffer)
GST_OBJECT_LOCK (rtp_mux);
rtp_mux->seqnum++;
gst_rtp_buffer_set_seq (buffer, rtp_mux->seqnum);
+ padpriv = gst_pad_get_element_private (pad);
+ if (padpriv)
+ gst_buffer_set_caps (buffer, padpriv->out_caps);
GST_OBJECT_UNLOCK (rtp_mux);
gst_rtp_buffer_set_ssrc (buffer, rtp_mux->current_ssrc);
gst_rtp_mux_readjust_rtp_timestamp (rtp_mux, pad, buffer);
@@ -351,10 +368,16 @@ gst_rtp_mux_chain (GstPad * pad, GstBuffer * buffer)
GST_BUFFER_SIZE (buffer), rtp_mux->seqnum,
gst_rtp_buffer_get_timestamp (buffer));
- gst_buffer_set_caps (buffer, padpriv->out_caps);
+ if (!padpriv) {
+ ret = GST_FLOW_NOT_LINKED;
+ gst_buffer_unref (buffer);
+ goto out;
+ }
ret = gst_pad_push (rtp_mux->srcpad, buffer);
+out:
+
gst_object_unref (rtp_mux);
return ret;
}
@@ -365,7 +388,7 @@ gst_rtp_mux_setcaps (GstPad * pad, GstCaps * caps)
GstRTPMux *rtp_mux;
GstStructure *structure;
gboolean ret = FALSE;
- GstRTPMuxPadPrivate *padpriv = gst_pad_get_element_private (pad);
+ GstRTPMuxPadPrivate *padpriv;
rtp_mux = GST_RTP_MUX (gst_pad_get_parent (pad));
@@ -374,9 +397,13 @@ gst_rtp_mux_setcaps (GstPad * pad, GstCaps * caps)
if (!structure)
goto out;
- if (gst_structure_get_uint (structure, "clock-base", &padpriv->clock_base)) {
+ GST_OBJECT_LOCK (rtp_mux);
+ padpriv = gst_pad_get_element_private (pad);
+ if (padpriv &&
+ gst_structure_get_uint (structure, "clock-base", &padpriv->clock_base)) {
padpriv->have_clock_base = TRUE;
}
+ GST_OBJECT_UNLOCK (rtp_mux);
caps = gst_caps_copy (caps);
@@ -388,8 +415,13 @@ gst_rtp_mux_setcaps (GstPad * pad, GstCaps * caps)
"setting caps %" GST_PTR_FORMAT " on src pad..", caps);
ret = gst_pad_set_caps (rtp_mux->srcpad, caps);
- if (ret)
- gst_caps_replace (&padpriv->out_caps, caps);
+ if (ret) {
+ GST_OBJECT_LOCK (rtp_mux);
+ padpriv = gst_pad_get_element_private (pad);
+ if (padpriv)
+ gst_caps_replace (&padpriv->out_caps, caps);
+ GST_OBJECT_UNLOCK (rtp_mux);
+ }
gst_caps_unref (caps);
out: