summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Alexander Steffens (heftig) <jan.steffens@ltnglobal.com>2020-06-29 19:46:53 +0200
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>2020-07-01 18:33:42 +0000
commit30b118710857f4251950a28c5eeadb3234a5ecf5 (patch)
tree28b609550ad474acafa4061012b297edc4036e8b
parent368c038ef01346c72f7cdc427a40cf94ea40d71a (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.c31
-rw-r--r--gst/rtmp2/rtmp/rtmputils.c33
-rw-r--r--gst/rtmp2/rtmp/rtmputils.h12
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