static gboolean gst_irtsp_parse_check_valid_frame (GstBaseParse * parse, GstBaseParseFrame * frame, guint * framesize, gint * skipsize) { GstIRTSPParse *IRTSPParse = GST_IRTSP_PARSE (parse); GstBuffer *buf = frame->buffer; GstByteReader reader = GST_BYTE_READER_INIT_FROM_BUFFER (buf); gint off; if (G_UNLIKELY (GST_BUFFER_SIZE (buf) < 4)) return FALSE; off = gst_byte_reader_masked_scan_uint32 (&reader, 0xffff0000, 0x24000000 + (IRTSPParse->channel_id << 16), 0, GST_BUFFER_SIZE (buf)); GST_LOG_OBJECT (parse, "possible sync at buffer offset %d", off); /* didn't find anything that looks like a sync word, skip */ if (off < 0) { *skipsize = GST_BUFFER_SIZE (buf) - 3; return FALSE; } /* possible frame header, but not at offset 0? skip bytes before sync */ if (off > 0) { *skipsize = off; return FALSE; } *framesize = GST_READ_UINT16_BE (GST_BUFFER_DATA (frame->buffer) + 2) + 4; GST_LOG_OBJECT (parse, "got frame size %d", *framesize); return TRUE; }
static gboolean gst_irtsp_parse_start (GstBaseParse * parse) { GstIRTSPParse *IRTSPParse = GST_IRTSP_PARSE (parse); GST_DEBUG_OBJECT (parse, "starting"); gst_irtsp_parse_reset (IRTSPParse); return TRUE; }
static void gst_irtsp_parse_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstIRTSPParse *IRTSPParse = GST_IRTSP_PARSE (object); switch (prop_id) { case PROP_CHANNEL_ID: g_value_set_int (value, IRTSPParse->channel_id); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static GstFlowReturn gst_irtsp_parse_handle_frame (GstBaseParse * parse, GstBaseParseFrame * frame, gint * skipsize) { GstIRTSPParse *IRTSPParse = GST_IRTSP_PARSE (parse); GstBuffer *buf = frame->buffer; GstByteReader reader; gint off; GstMapInfo map; gboolean ret = FALSE; guint framesize; gst_buffer_map (buf, &map, GST_MAP_READ); if (G_UNLIKELY (map.size < 4)) goto exit; gst_byte_reader_init (&reader, map.data, map.size); off = gst_byte_reader_masked_scan_uint32 (&reader, 0xffff0000, 0x24000000 + (IRTSPParse->channel_id << 16), 0, map.size); GST_LOG_OBJECT (parse, "possible sync at buffer offset %d", off); /* didn't find anything that looks like a sync word, skip */ if (off < 0) { *skipsize = map.size - 3; goto exit; } /* possible frame header, but not at offset 0? skip bytes before sync */ if (off > 0) { *skipsize = off; goto exit; } framesize = GST_READ_UINT16_BE (map.data + 2) + 4; GST_LOG_OBJECT (parse, "got frame size %d", framesize); ret = TRUE; if (!gst_pad_has_current_caps (GST_BASE_PARSE_SRC_PAD (parse))) { GstCaps *caps; caps = gst_caps_new_empty_simple ("application/x-rtp"); gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (parse), caps); gst_caps_unref (caps); } exit: gst_buffer_unmap (buf, &map); if (ret && framesize <= map.size) { /* HACK HACK skip header. * could also ask baseparse to skip this, * but that would give us a discontinuity for free * which is a bit too much to have on all our packets */ frame->out_buffer = gst_buffer_copy (frame->buffer); gst_buffer_resize (frame->out_buffer, 4, -1); GST_BUFFER_FLAG_UNSET (frame->out_buffer, GST_BUFFER_FLAG_DISCONT); return gst_base_parse_finish_frame (parse, frame, framesize); } return GST_FLOW_OK; }