From 30b118710857f4251950a28c5eeadb3234a5ecf5 Mon Sep 17 00:00:00 2001 From: "Jan Alexander Steffens (heftig)" Date: Mon, 29 Jun 2020 19:46:53 +0200 Subject: rtmp2: Move FLV tag header parsing into rtmputils.c To be shared with the AGGREGATE handling. Part-of: --- gst/rtmp2/gstrtmp2sink.c | 31 ++++++++++++++++--------------- gst/rtmp2/rtmp/rtmputils.c | 33 +++++++++++++++++++++++++++++++++ gst/rtmp2/rtmp/rtmputils.h | 12 ++++++++++++ 3 files changed, 61 insertions(+), 15 deletions(-) (limited to 'gst/rtmp2') diff --git a/gst/rtmp2/gstrtmp2sink.c b/gst/rtmp2/gstrtmp2sink.c index 7e67f8691..a5ee7acdd 100644 --- a/gst/rtmp2/gstrtmp2sink.c +++ b/gst/rtmp2/gstrtmp2sink.c @@ -44,6 +44,7 @@ #include "rtmp/amf.h" #include "rtmp/rtmpclient.h" #include "rtmp/rtmpmessage.h" +#include "rtmp/rtmputils.h" #include #include @@ -587,10 +588,9 @@ static gboolean buffer_to_message (GstRtmp2Sink * self, GstBuffer * buffer, GstBuffer ** outbuf) { GstBuffer *message; - gsize payload_offset, payload_size; + GstRtmpFlvTagHeader header; guint64 timestamp; guint32 cstream; - GstRtmpMessageType type; { GstMapInfo info; @@ -611,21 +611,22 @@ buffer_to_message (GstRtmp2Sink * self, GstBuffer * buffer, GstBuffer ** outbuf) return TRUE; } - if (G_UNLIKELY (info.size < 11 + 4)) { - GST_ERROR_OBJECT (self, "too small: %" GST_PTR_FORMAT, buffer); + if (!gst_rtmp_flv_tag_parse_header (&header, info.data, info.size)) { + GST_ERROR_OBJECT (self, "too small for tag header: %" GST_PTR_FORMAT, + buffer); gst_buffer_unmap (buffer, &info); return FALSE; } - /* payload between 11 byte header and 4 byte size footer */ - payload_offset = 11; - payload_size = info.size - 11 - 4; - - type = GST_READ_UINT8 (info.data); - timestamp = GST_READ_UINT24_BE (info.data + 4); - timestamp |= (guint32) GST_READ_UINT8 (info.data + 7) << 24; + if (info.size < header.total_size) { + GST_ERROR_OBJECT (self, "too small for tag body: buffer %" G_GSIZE_FORMAT + ", tag %" G_GSIZE_FORMAT, info.size, header.total_size); + gst_buffer_unmap (buffer, &info); + return FALSE; + } /* flvmux timestamps roll over after about 49 days */ + timestamp = header.timestamp; if (timestamp + self->base_ts + G_MAXINT32 < self->last_ts) { GST_WARNING_OBJECT (self, "Timestamp regression %" G_GUINT64_FORMAT " -> %" G_GUINT64_FORMAT "; assuming overflow", self->last_ts, @@ -651,7 +652,7 @@ buffer_to_message (GstRtmp2Sink * self, GstBuffer * buffer, GstBuffer ** outbuf) gst_buffer_unmap (buffer, &info); } - switch (type) { + switch (header.type) { case GST_RTMP_MESSAGE_TYPE_DATA_AMF0: cstream = 4; break; @@ -665,14 +666,14 @@ buffer_to_message (GstRtmp2Sink * self, GstBuffer * buffer, GstBuffer ** outbuf) break; default: - GST_ERROR_OBJECT (self, "unknown tag type %d", type); + GST_ERROR_OBJECT (self, "unknown tag type %d", header.type); return FALSE; } /* May not know stream ID yet; set later */ - message = gst_rtmp_message_new (type, cstream, 0); + message = gst_rtmp_message_new (header.type, cstream, 0); message = gst_buffer_append_region (message, gst_buffer_ref (buffer), - payload_offset, payload_size); + GST_RTMP_FLV_TAG_HEADER_SIZE, header.payload_size); GST_BUFFER_DTS (message) = timestamp * GST_MSECOND; diff --git a/gst/rtmp2/rtmp/rtmputils.c b/gst/rtmp2/rtmp/rtmputils.c index 5f64f2711..f0f0cac8e 100644 --- a/gst/rtmp2/rtmp/rtmputils.c +++ b/gst/rtmp2/rtmp/rtmputils.c @@ -347,3 +347,36 @@ gst_rtmp_string_print_escaped (GString * string, const gchar * data, g_string_append_c (string, '"'); } + +gboolean +gst_rtmp_flv_tag_parse_header (GstRtmpFlvTagHeader * header, + const guint8 * data, gsize size) +{ + g_return_val_if_fail (header, FALSE); + g_return_val_if_fail (data, FALSE); + + /* Parse FLVTAG header as described in + * video_file_format_spec_v10.pdf page 5 (page 9 of the PDF) */ + + if (size < GST_RTMP_FLV_TAG_HEADER_SIZE) { + return FALSE; + } + + /* TagType UI8 */ + header->type = GST_READ_UINT8 (data); + + /* DataSize UI24 */ + header->payload_size = GST_READ_UINT24_BE (data + 1); + + /* 4 bytes for the PreviousTagSize UI32 following every tag */ + header->total_size = GST_RTMP_FLV_TAG_HEADER_SIZE + header->payload_size + 4; + + /* Timestamp UI24 + TimestampExtended UI8 */ + header->timestamp = GST_READ_UINT24_BE (data + 4); + header->timestamp |= (guint32) GST_READ_UINT8 (data + 7) << 24; + + /* Skip StreamID UI24. It's "always 0" for FLV files and for aggregated RTMP + * messages we're supposed to use the Stream ID from the AGGREGATE. */ + + return TRUE; +} diff --git a/gst/rtmp2/rtmp/rtmputils.h b/gst/rtmp2/rtmp/rtmputils.h index 07c437f99..f36116a56 100644 --- a/gst/rtmp2/rtmp/rtmputils.h +++ b/gst/rtmp2/rtmp/rtmputils.h @@ -22,6 +22,7 @@ #include #include +#include "rtmpmessage.h" G_BEGIN_DECLS @@ -48,6 +49,17 @@ gboolean gst_rtmp_output_stream_write_all_buffer_finish (GOutputStream * stream, void gst_rtmp_string_print_escaped (GString * string, const gchar * data, gssize size); +#define GST_RTMP_FLV_TAG_HEADER_SIZE 11 + +typedef struct { + GstRtmpMessageType type; + gsize payload_size, total_size; + guint32 timestamp; +} GstRtmpFlvTagHeader; + +gboolean gst_rtmp_flv_tag_parse_header (GstRtmpFlvTagHeader *header, + const guint8 * data, gsize size); + G_END_DECLS #endif -- cgit v1.2.1