Merge branch 'master' into 0.11

This commit is contained in:
Wim Taymans 2011-05-17 16:13:59 +02:00
commit e15651816e
5 changed files with 771 additions and 445 deletions

View file

@ -2808,6 +2808,7 @@ static GstFlowReturn
gst_matroska_parse_parse_info (GstMatroskaParse * parse, GstEbmlRead * ebml) gst_matroska_parse_parse_info (GstMatroskaParse * parse, GstEbmlRead * ebml)
{ {
GstFlowReturn ret = GST_FLOW_OK; GstFlowReturn ret = GST_FLOW_OK;
gdouble dur_f = -1.0;
guint32 id; guint32 id;
DEBUG_ELEMENT_START (parse, ebml, "SegmentInfo"); DEBUG_ELEMENT_START (parse, ebml, "SegmentInfo");
@ -2836,23 +2837,15 @@ gst_matroska_parse_parse_info (GstMatroskaParse * parse, GstEbmlRead * ebml)
} }
case GST_MATROSKA_ID_DURATION:{ case GST_MATROSKA_ID_DURATION:{
gdouble num; if ((ret = gst_ebml_read_float (ebml, &id, &dur_f)) != GST_FLOW_OK)
GstClockTime dur;
if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
break; break;
if (num <= 0.0) { if (dur_f <= 0.0) {
GST_WARNING_OBJECT (parse, "Invalid duration %lf", num); GST_WARNING_OBJECT (parse, "Invalid duration %lf", dur_f);
break; break;
} }
GST_DEBUG_OBJECT (parse, "Duration: %lf", num); GST_DEBUG_OBJECT (parse, "Duration: %lf", dur_f);
dur = gst_gdouble_to_guint64 (num *
gst_guint64_to_gdouble (parse->time_scale));
if (GST_CLOCK_TIME_IS_VALID (dur) && dur <= G_MAXINT64)
gst_segment_set_duration (&parse->segment, GST_FORMAT_TIME, dur);
break; break;
} }
@ -2923,6 +2916,15 @@ gst_matroska_parse_parse_info (GstMatroskaParse * parse, GstEbmlRead * ebml)
} }
} }
if (dur_f > 0.0) {
GstClockTime dur_u;
dur_u = gst_gdouble_to_guint64 (dur_f *
gst_guint64_to_gdouble (parse->time_scale));
if (GST_CLOCK_TIME_IS_VALID (dur_u) && dur_u <= G_MAXINT64)
gst_segment_set_duration (&parse->segment, GST_FORMAT_TIME, dur_u);
}
DEBUG_ELEMENT_STOP (parse, ebml, "SegmentInfo", ret); DEBUG_ELEMENT_STOP (parse, ebml, "SegmentInfo", ret);
parse->segmentinfo_parsed = TRUE; parse->segmentinfo_parsed = TRUE;

View file

@ -118,10 +118,13 @@ static GstFlowReturn gst_rtp_ssrc_demux_rtcp_chain (GstPad * pad,
GstBuffer * buf); GstBuffer * buf);
static gboolean gst_rtp_ssrc_demux_rtcp_sink_event (GstPad * pad, static gboolean gst_rtp_ssrc_demux_rtcp_sink_event (GstPad * pad,
GstEvent * event); GstEvent * event);
static GstIterator *gst_rtp_ssrc_demux_iterate_internal_links_sink (GstPad *
pad);
/* srcpad stuff */ /* srcpad stuff */
static gboolean gst_rtp_ssrc_demux_src_event (GstPad * pad, GstEvent * event); static gboolean gst_rtp_ssrc_demux_src_event (GstPad * pad, GstEvent * event);
static GstIterator *gst_rtp_ssrc_demux_iterate_internal_links (GstPad * pad); static GstIterator *gst_rtp_ssrc_demux_iterate_internal_links_src (GstPad *
pad);
static gboolean gst_rtp_ssrc_demux_src_query (GstPad * pad, GstQuery * query); static gboolean gst_rtp_ssrc_demux_src_query (GstPad * pad, GstQuery * query);
static guint gst_rtp_ssrc_demux_signals[LAST_SIGNAL] = { 0 }; static guint gst_rtp_ssrc_demux_signals[LAST_SIGNAL] = { 0 };
@ -153,10 +156,8 @@ find_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc)
return NULL; return NULL;
} }
/* with PAD_LOCK */
static GstRtpSsrcDemuxPad * static GstRtpSsrcDemuxPad *
create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc, find_or_create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc)
GstClockTime timestamp)
{ {
GstPad *rtp_pad, *rtcp_pad; GstPad *rtp_pad, *rtcp_pad;
GstElementClass *klass; GstElementClass *klass;
@ -166,6 +167,14 @@ create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc,
GST_DEBUG_OBJECT (demux, "creating pad for SSRC %08x", ssrc); GST_DEBUG_OBJECT (demux, "creating pad for SSRC %08x", ssrc);
GST_OBJECT_LOCK (demux);
demuxpad = find_demux_pad_for_ssrc (demux, ssrc);
if (demuxpad != NULL) {
GST_OBJECT_UNLOCK (demux);
return demuxpad;
}
klass = GST_ELEMENT_GET_CLASS (demux); klass = GST_ELEMENT_GET_CLASS (demux);
templ = gst_element_class_get_pad_template (klass, "src_%d"); templ = gst_element_class_get_pad_template (klass, "src_%d");
padname = g_strdup_printf ("src_%d", ssrc); padname = g_strdup_printf ("src_%d", ssrc);
@ -177,20 +186,12 @@ create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc,
rtcp_pad = gst_pad_new_from_template (templ, padname); rtcp_pad = gst_pad_new_from_template (templ, padname);
g_free (padname); g_free (padname);
/* we use the first timestamp received to calculate the difference between
* timestamps on all streams */
GST_DEBUG_OBJECT (demux, "SSRC %08x, first timestamp %" GST_TIME_FORMAT,
ssrc, GST_TIME_ARGS (timestamp));
/* wrap in structure and add to list */ /* wrap in structure and add to list */
demuxpad = g_new0 (GstRtpSsrcDemuxPad, 1); demuxpad = g_new0 (GstRtpSsrcDemuxPad, 1);
demuxpad->ssrc = ssrc; demuxpad->ssrc = ssrc;
demuxpad->rtp_pad = rtp_pad; demuxpad->rtp_pad = rtp_pad;
demuxpad->rtcp_pad = rtcp_pad; demuxpad->rtcp_pad = rtcp_pad;
GST_DEBUG_OBJECT (demux, "first timestamp %" GST_TIME_FORMAT,
GST_TIME_ARGS (timestamp));
gst_pad_set_element_private (rtp_pad, demuxpad); gst_pad_set_element_private (rtp_pad, demuxpad);
gst_pad_set_element_private (rtcp_pad, demuxpad); gst_pad_set_element_private (rtcp_pad, demuxpad);
@ -205,14 +206,16 @@ create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc,
gst_pad_set_event_function (rtp_pad, gst_rtp_ssrc_demux_src_event); gst_pad_set_event_function (rtp_pad, gst_rtp_ssrc_demux_src_event);
gst_pad_set_query_function (rtp_pad, gst_rtp_ssrc_demux_src_query); gst_pad_set_query_function (rtp_pad, gst_rtp_ssrc_demux_src_query);
gst_pad_set_iterate_internal_links_function (rtp_pad, gst_pad_set_iterate_internal_links_function (rtp_pad,
gst_rtp_ssrc_demux_iterate_internal_links); gst_rtp_ssrc_demux_iterate_internal_links_src);
gst_pad_set_active (rtp_pad, TRUE); gst_pad_set_active (rtp_pad, TRUE);
gst_pad_set_event_function (rtcp_pad, gst_rtp_ssrc_demux_src_event); gst_pad_set_event_function (rtcp_pad, gst_rtp_ssrc_demux_src_event);
gst_pad_set_iterate_internal_links_function (rtcp_pad, gst_pad_set_iterate_internal_links_function (rtcp_pad,
gst_rtp_ssrc_demux_iterate_internal_links); gst_rtp_ssrc_demux_iterate_internal_links_src);
gst_pad_set_active (rtcp_pad, TRUE); gst_pad_set_active (rtcp_pad, TRUE);
GST_OBJECT_UNLOCK (demux);
gst_element_add_pad (GST_ELEMENT_CAST (demux), rtp_pad); gst_element_add_pad (GST_ELEMENT_CAST (demux), rtp_pad);
gst_element_add_pad (GST_ELEMENT_CAST (demux), rtcp_pad); gst_element_add_pad (GST_ELEMENT_CAST (demux), rtcp_pad);
@ -319,6 +322,8 @@ gst_rtp_ssrc_demux_init (GstRtpSsrcDemux * demux,
"sink"), "sink"); "sink"), "sink");
gst_pad_set_chain_function (demux->rtp_sink, gst_rtp_ssrc_demux_chain); gst_pad_set_chain_function (demux->rtp_sink, gst_rtp_ssrc_demux_chain);
gst_pad_set_event_function (demux->rtp_sink, gst_rtp_ssrc_demux_sink_event); gst_pad_set_event_function (demux->rtp_sink, gst_rtp_ssrc_demux_sink_event);
gst_pad_set_iterate_internal_links_function (demux->rtp_sink,
gst_rtp_ssrc_demux_iterate_internal_links_sink);
gst_element_add_pad (GST_ELEMENT_CAST (demux), demux->rtp_sink); gst_element_add_pad (GST_ELEMENT_CAST (demux), demux->rtp_sink);
demux->rtcp_sink = demux->rtcp_sink =
@ -327,6 +332,8 @@ gst_rtp_ssrc_demux_init (GstRtpSsrcDemux * demux,
gst_pad_set_chain_function (demux->rtcp_sink, gst_rtp_ssrc_demux_rtcp_chain); gst_pad_set_chain_function (demux->rtcp_sink, gst_rtp_ssrc_demux_rtcp_chain);
gst_pad_set_event_function (demux->rtcp_sink, gst_pad_set_event_function (demux->rtcp_sink,
gst_rtp_ssrc_demux_rtcp_sink_event); gst_rtp_ssrc_demux_rtcp_sink_event);
gst_pad_set_iterate_internal_links_function (demux->rtcp_sink,
gst_rtp_ssrc_demux_iterate_internal_links_sink);
gst_element_add_pad (GST_ELEMENT_CAST (demux), demux->rtcp_sink); gst_element_add_pad (GST_ELEMENT_CAST (demux), demux->rtcp_sink);
demux->padlock = g_mutex_new (); demux->padlock = g_mutex_new ();
@ -521,15 +528,9 @@ gst_rtp_ssrc_demux_chain (GstPad * pad, GstBuffer * buf)
GST_DEBUG_OBJECT (demux, "received buffer of SSRC %08x", ssrc); GST_DEBUG_OBJECT (demux, "received buffer of SSRC %08x", ssrc);
GST_PAD_LOCK (demux); dpad = find_or_create_demux_pad_for_ssrc (demux, ssrc);
dpad = find_demux_pad_for_ssrc (demux, ssrc); if (dpad == NULL)
if (dpad == NULL) { goto create_failed;
if (!(dpad =
create_demux_pad_for_ssrc (demux, ssrc,
GST_BUFFER_TIMESTAMP (buf))))
goto create_failed;
}
GST_PAD_UNLOCK (demux);
/* push to srcpad */ /* push to srcpad */
ret = gst_pad_push (dpad->rtp_pad, buf); ret = gst_pad_push (dpad->rtp_pad, buf);
@ -549,7 +550,6 @@ create_failed:
{ {
GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL), GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
("Could not create new pad")); ("Could not create new pad"));
GST_PAD_UNLOCK (demux);
gst_buffer_unref (buf); gst_buffer_unref (buf);
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
} }
@ -585,14 +585,10 @@ gst_rtp_ssrc_demux_rtcp_chain (GstPad * pad, GstBuffer * buf)
GST_DEBUG_OBJECT (demux, "received RTCP of SSRC %08x", ssrc); GST_DEBUG_OBJECT (demux, "received RTCP of SSRC %08x", ssrc);
GST_PAD_LOCK (demux); dpad = find_or_create_demux_pad_for_ssrc (demux, ssrc);
dpad = find_demux_pad_for_ssrc (demux, ssrc); if (dpad == NULL)
if (dpad == NULL) { goto create_failed;
GST_DEBUG_OBJECT (demux, "creating pad for SSRC %08x", ssrc);
if (!(dpad = create_demux_pad_for_ssrc (demux, ssrc, -1)))
goto create_failed;
}
GST_PAD_UNLOCK (demux);
/* push to srcpad */ /* push to srcpad */
ret = gst_pad_push (dpad->rtcp_pad, buf); ret = gst_pad_push (dpad->rtcp_pad, buf);
@ -618,7 +614,6 @@ create_failed:
{ {
GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL), GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
("Could not create new pad")); ("Could not create new pad"));
GST_PAD_UNLOCK (demux);
gst_buffer_unref (buf); gst_buffer_unref (buf);
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
} }
@ -664,25 +659,23 @@ gst_rtp_ssrc_demux_src_event (GstPad * pad, GstEvent * event)
} }
static GstIterator * static GstIterator *
gst_rtp_ssrc_demux_iterate_internal_links (GstPad * pad) gst_rtp_ssrc_demux_iterate_internal_links_src (GstPad * pad)
{ {
GstRtpSsrcDemux *demux; GstRtpSsrcDemux *demux;
GstPad *otherpad = NULL; GstPad *otherpad = NULL;
GstIterator *it; GstIterator *it = NULL;
GSList *current; GSList *current;
demux = GST_RTP_SSRC_DEMUX (gst_pad_get_parent (pad)); demux = GST_RTP_SSRC_DEMUX (gst_pad_get_parent (pad));
if (!demux)
return NULL;
GST_PAD_LOCK (demux); GST_PAD_LOCK (demux);
for (current = demux->srcpads; current; current = g_slist_next (current)) { for (current = demux->srcpads; current; current = g_slist_next (current)) {
GstRtpSsrcDemuxPad *dpad = (GstRtpSsrcDemuxPad *) current->data; GstRtpSsrcDemuxPad *dpad = (GstRtpSsrcDemuxPad *) current->data;
if (pad == demux->rtp_sink) { if (pad == dpad->rtp_pad) {
otherpad = dpad->rtp_pad;
break;
} else if (pad == demux->rtcp_sink) {
otherpad = dpad->rtcp_pad;
} else if (pad == dpad->rtp_pad) {
otherpad = demux->rtp_sink; otherpad = demux->rtp_sink;
break; break;
} else if (pad == dpad->rtcp_pad) { } else if (pad == dpad->rtcp_pad) {
@ -698,6 +691,46 @@ gst_rtp_ssrc_demux_iterate_internal_links (GstPad * pad)
return it; return it;
} }
/* Should return 0 for elements to be included */
static gint
src_pad_compare_func (gconstpointer a, gconstpointer b)
{
GstPad *pad = GST_PAD (a);
const gchar *prefix = b;
gint res = 1;
GST_OBJECT_LOCK (pad);
res = !GST_PAD_NAME (pad) || g_str_has_prefix (GST_PAD_NAME (pad), prefix);
GST_OBJECT_UNLOCK (pad);
return res;
}
static GstIterator *
gst_rtp_ssrc_demux_iterate_internal_links_sink (GstPad * pad)
{
GstRtpSsrcDemux *demux;
GstIterator *it = NULL;
const gchar *prefix = NULL;
demux = GST_RTP_SSRC_DEMUX (gst_pad_get_parent (pad));
if (!demux)
return NULL;
if (pad == demux->rtp_sink)
prefix = "src_";
else if (pad == demux->rtcp_sink)
prefix = "rtcp_src_";
else
g_assert_not_reached ();
it = gst_element_iterate_src_pads (GST_ELEMENT (demux));
return gst_iterator_filter (it, src_pad_compare_func, (gpointer) prefix);
}
static gboolean static gboolean
gst_rtp_ssrc_demux_src_query (GstPad * pad, GstQuery * query) gst_rtp_ssrc_demux_src_query (GstPad * pad, GstQuery * query)
{ {

File diff suppressed because it is too large Load diff

View file

@ -79,10 +79,6 @@ typedef struct _GstRTSPSrcClass GstRTSPSrcClass;
#define GST_RTSP_STREAM_LOCK(rtsp) (g_static_rec_mutex_lock (GST_RTSP_STREAM_GET_LOCK(rtsp))) #define GST_RTSP_STREAM_LOCK(rtsp) (g_static_rec_mutex_lock (GST_RTSP_STREAM_GET_LOCK(rtsp)))
#define GST_RTSP_STREAM_UNLOCK(rtsp) (g_static_rec_mutex_unlock (GST_RTSP_STREAM_GET_LOCK(rtsp))) #define GST_RTSP_STREAM_UNLOCK(rtsp) (g_static_rec_mutex_unlock (GST_RTSP_STREAM_GET_LOCK(rtsp)))
#define GST_RTSP_CONN_GET_LOCK(rtsp) (GST_RTSPSRC_CAST(rtsp)->conn_rec_lock)
#define GST_RTSP_CONN_LOCK(rtsp) (g_static_rec_mutex_lock (GST_RTSP_CONN_GET_LOCK(rtsp)))
#define GST_RTSP_CONN_UNLOCK(rtsp) (g_static_rec_mutex_unlock (GST_RTSP_CONN_GET_LOCK(rtsp)))
typedef struct _GstRTSPConnInfo GstRTSPConnInfo; typedef struct _GstRTSPConnInfo GstRTSPConnInfo;
struct _GstRTSPConnInfo { struct _GstRTSPConnInfo {
@ -131,7 +127,7 @@ struct _GstRTSPStream {
gboolean container; gboolean container;
/* original control url */ /* original control url */
gchar *control_url; gchar *control_url;
guint32 ssrc; guint32 ssrc;
guint32 seqbase; guint32 seqbase;
guint64 timebase; guint64 timebase;
@ -184,13 +180,12 @@ struct _GstRTSPSrc {
/* UDP mode loop */ /* UDP mode loop */
gint loop_cmd; gint loop_cmd;
gboolean ignore_timeout; gboolean ignore_timeout;
gboolean waiting;
gboolean open_error;
/* mutex for protecting state changes */ /* mutex for protecting state changes */
GStaticRecMutex *state_rec_lock; GStaticRecMutex *state_rec_lock;
/* mutex for protecting the connection */
GStaticRecMutex *conn_rec_lock;
GstSDPMessage *sdp; GstSDPMessage *sdp;
gboolean from_sdp; gboolean from_sdp;
gint numstreams; gint numstreams;
@ -201,7 +196,7 @@ struct _GstRTSPSrc {
/* properties */ /* properties */
GstRTSPLowerTrans protocols; GstRTSPLowerTrans protocols;
gboolean debug; gboolean debug;
guint retry; guint retry;
guint64 udp_timeout; guint64 udp_timeout;
GTimeVal tcp_timeout; GTimeVal tcp_timeout;
GTimeVal *ptcp_timeout; GTimeVal *ptcp_timeout;

View file

@ -2049,7 +2049,9 @@ gst_v4l2_object_set_format (GstV4l2Object * v4l2object, guint32 pixelformat,
GST_V4L2_CHECK_OPEN (v4l2object); GST_V4L2_CHECK_OPEN (v4l2object);
GST_V4L2_CHECK_NOT_ACTIVE (v4l2object); GST_V4L2_CHECK_NOT_ACTIVE (v4l2object);
if (pixelformat == GST_MAKE_FOURCC ('M', 'P', 'E', 'G')) /* Only unconditionally accept mpegts for sources */
if ((v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
(pixelformat == GST_MAKE_FOURCC ('M', 'P', 'E', 'G')))
return TRUE; return TRUE;
memset (&format, 0x00, sizeof (struct v4l2_format)); memset (&format, 0x00, sizeof (struct v4l2_format));