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>
This commit is contained in:
Jan Alexander Steffens (heftig) 2020-06-29 19:46:53 +02:00 committed by GStreamer Merge Bot
parent 368c038ef0
commit 30b1187108
3 changed files with 61 additions and 15 deletions

View file

@ -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;

View file

@ -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;
}

View file

@ -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