diff options
author | Jan Alexander Steffens (heftig) <jan.steffens@ltnglobal.com> | 2020-06-29 19:46:53 +0200 |
---|---|---|
committer | GStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org> | 2020-07-01 18:33:42 +0000 |
commit | 30b118710857f4251950a28c5eeadb3234a5ecf5 (patch) | |
tree | 28b609550ad474acafa4061012b297edc4036e8b | |
parent | 368c038ef01346c72f7cdc427a40cf94ea40d71a (diff) |
rtmp2: Move FLV tag header parsing into rtmputils.c
To be shared with the AGGREGATE handling.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1384>
-rw-r--r-- | gst/rtmp2/gstrtmp2sink.c | 31 | ||||
-rw-r--r-- | gst/rtmp2/rtmp/rtmputils.c | 33 | ||||
-rw-r--r-- | gst/rtmp2/rtmp/rtmputils.h | 12 |
3 files changed, 61 insertions, 15 deletions
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 <gst/gst.h> #include <gst/base/gstbasesink.h> @@ -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 <gst/gst.h> #include <gio/gio.h> +#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 |