* to contain a valid header as well (and there is enough data to
* perform this check)
*/
- if (fsize &&
- (!GST_BASE_PARSE_LOST_SYNC (parse) || GST_BASE_PARSE_DRAINING (parse)
- || (dsize > fsize && (data[fsize] & 0x83) == 0))) {
- *framesize = fsize;
- ret = TRUE;
- goto done;
+ if (fsize) {
+ gboolean found = FALSE;
+
+ /* in sync, no further check */
+ if (!GST_BASE_PARSE_LOST_SYNC (parse)) {
+ found = TRUE;
+ } else if (dsize > fsize) {
+ /* enough data, check for next sync */
+ if ((data[fsize] & 0x83) == 0)
+ found = TRUE;
+ } else if (GST_BASE_PARSE_DRAINING (parse)) {
+ /* not enough, but draining, so ok */
+ found = TRUE;
+ } else {
+ /* indicate we need not skip, but need more data */
+ *skipsize = 0;
+ *framesize = fsize + 1;
+ }
+ if (found) {
+ *framesize = fsize;
+ return TRUE;
+ }
}
}
-
GST_LOG ("sync lost");
- return FALSE;
+
+done:
+ gst_buffer_unmap (buffer, data, size);
+
+ return ret;
}
return res;
}
- GstFormat fmt = GST_FORMAT_BYTES;
-
+ /* check for seekable upstream, above and beyond a mere query */
+ static void
+ gst_qtdemux_check_seekability (GstQTDemux * demux)
+ {
+ GstQuery *query;
+ gboolean seekable = FALSE;
+ gint64 start = -1, stop = -1;
+
+ if (demux->upstream_size)
+ return;
+
+ query = gst_query_new_seeking (GST_FORMAT_BYTES);
+ if (!gst_pad_peer_query (demux->sinkpad, query)) {
+ GST_DEBUG_OBJECT (demux, "seeking query failed");
+ goto done;
+ }
+
+ gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
+
+ /* try harder to query upstream size if we didn't get it the first time */
+ if (seekable && stop == -1) {
- gst_pad_query_peer_duration (demux->sinkpad, &fmt, &stop);
+ GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
++ gst_pad_query_peer_duration (demux->sinkpad, GST_FORMAT_BYTES, &stop);
+ }
+
+ /* if upstream doesn't know the size, it's likely that it's not seekable in
+ * practice even if it technically may be seekable */
+ if (seekable && (start != 0 || stop <= start)) {
+ GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
+ seekable = FALSE;
+ }
+
+ done:
+ gst_query_unref (query);
+
+ GST_DEBUG_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
+ G_GUINT64_FORMAT ")", seekable, start, stop);
+ demux->upstream_seekable = seekable;
+ demux->upstream_size = seekable ? stop : -1;
+ }
+
/* FIXME, unverified after edit list updates */
static GstFlowReturn
gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
guint32 fourcc;
guint64 size;
- data = gst_adapter_peek (demux->adapter, demux->neededbytes);
+ gst_qtdemux_check_seekability (demux);
+
+ data = gst_adapter_map (demux->adapter, demux->neededbytes);
/* get fourcc/length, set neededbytes */
extract_initial_length_and_fourcc ((guint8 *) data, demux->neededbytes,
gst_rtp_h263p_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
{
gboolean res;
- peercaps = gst_pad_peer_get_caps (GST_BASE_RTP_PAYLOAD_SRCPAD (payload));
+ GstCaps *peercaps;
+ gchar *encoding_name = NULL;
+
+ g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
+
++ peercaps =
++ gst_pad_peer_get_caps (GST_BASE_RTP_PAYLOAD_SRCPAD (payload), NULL);
+ if (peercaps) {
+ GstCaps *intersect = gst_caps_intersect (peercaps,
+ gst_pad_get_pad_template_caps (GST_BASE_RTP_PAYLOAD_SRCPAD (payload)));
+
+ gst_caps_unref (peercaps);
+ if (!gst_caps_is_empty (intersect)) {
+ GstStructure *s = gst_caps_get_structure (intersect, 0);
+ encoding_name = g_strdup (gst_structure_get_string (s, "encoding-name"));
+ }
+ gst_caps_unref (intersect);
+ }
+
+ if (!encoding_name)
+ encoding_name = g_strdup ("H263-1998");
- gst_basertppayload_set_options (payload, "video", TRUE, "H263-1998", 90000);
+ gst_basertppayload_set_options (payload, "video", TRUE,
+ (gchar *) encoding_name, 90000);
res = gst_basertppayload_set_outcaps (payload, NULL);
+ g_free (encoding_name);
return res;
}