mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 07:58:51 +00:00
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:
parent
368c038ef0
commit
30b1187108
3 changed files with 61 additions and 15 deletions
|
@ -44,6 +44,7 @@
|
||||||
#include "rtmp/amf.h"
|
#include "rtmp/amf.h"
|
||||||
#include "rtmp/rtmpclient.h"
|
#include "rtmp/rtmpclient.h"
|
||||||
#include "rtmp/rtmpmessage.h"
|
#include "rtmp/rtmpmessage.h"
|
||||||
|
#include "rtmp/rtmputils.h"
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/base/gstbasesink.h>
|
#include <gst/base/gstbasesink.h>
|
||||||
|
@ -587,10 +588,9 @@ static gboolean
|
||||||
buffer_to_message (GstRtmp2Sink * self, GstBuffer * buffer, GstBuffer ** outbuf)
|
buffer_to_message (GstRtmp2Sink * self, GstBuffer * buffer, GstBuffer ** outbuf)
|
||||||
{
|
{
|
||||||
GstBuffer *message;
|
GstBuffer *message;
|
||||||
gsize payload_offset, payload_size;
|
GstRtmpFlvTagHeader header;
|
||||||
guint64 timestamp;
|
guint64 timestamp;
|
||||||
guint32 cstream;
|
guint32 cstream;
|
||||||
GstRtmpMessageType type;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
GstMapInfo info;
|
GstMapInfo info;
|
||||||
|
@ -611,21 +611,22 @@ buffer_to_message (GstRtmp2Sink * self, GstBuffer * buffer, GstBuffer ** outbuf)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (G_UNLIKELY (info.size < 11 + 4)) {
|
if (!gst_rtmp_flv_tag_parse_header (&header, info.data, info.size)) {
|
||||||
GST_ERROR_OBJECT (self, "too small: %" GST_PTR_FORMAT, buffer);
|
GST_ERROR_OBJECT (self, "too small for tag header: %" GST_PTR_FORMAT,
|
||||||
|
buffer);
|
||||||
gst_buffer_unmap (buffer, &info);
|
gst_buffer_unmap (buffer, &info);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* payload between 11 byte header and 4 byte size footer */
|
if (info.size < header.total_size) {
|
||||||
payload_offset = 11;
|
GST_ERROR_OBJECT (self, "too small for tag body: buffer %" G_GSIZE_FORMAT
|
||||||
payload_size = info.size - 11 - 4;
|
", tag %" G_GSIZE_FORMAT, info.size, header.total_size);
|
||||||
|
gst_buffer_unmap (buffer, &info);
|
||||||
type = GST_READ_UINT8 (info.data);
|
return FALSE;
|
||||||
timestamp = GST_READ_UINT24_BE (info.data + 4);
|
}
|
||||||
timestamp |= (guint32) GST_READ_UINT8 (info.data + 7) << 24;
|
|
||||||
|
|
||||||
/* flvmux timestamps roll over after about 49 days */
|
/* flvmux timestamps roll over after about 49 days */
|
||||||
|
timestamp = header.timestamp;
|
||||||
if (timestamp + self->base_ts + G_MAXINT32 < self->last_ts) {
|
if (timestamp + self->base_ts + G_MAXINT32 < self->last_ts) {
|
||||||
GST_WARNING_OBJECT (self, "Timestamp regression %" G_GUINT64_FORMAT
|
GST_WARNING_OBJECT (self, "Timestamp regression %" G_GUINT64_FORMAT
|
||||||
" -> %" G_GUINT64_FORMAT "; assuming overflow", self->last_ts,
|
" -> %" 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);
|
gst_buffer_unmap (buffer, &info);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (header.type) {
|
||||||
case GST_RTMP_MESSAGE_TYPE_DATA_AMF0:
|
case GST_RTMP_MESSAGE_TYPE_DATA_AMF0:
|
||||||
cstream = 4;
|
cstream = 4;
|
||||||
break;
|
break;
|
||||||
|
@ -665,14 +666,14 @@ buffer_to_message (GstRtmp2Sink * self, GstBuffer * buffer, GstBuffer ** outbuf)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
GST_ERROR_OBJECT (self, "unknown tag type %d", type);
|
GST_ERROR_OBJECT (self, "unknown tag type %d", header.type);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* May not know stream ID yet; set later */
|
/* 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),
|
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;
|
GST_BUFFER_DTS (message) = timestamp * GST_MSECOND;
|
||||||
|
|
||||||
|
|
|
@ -347,3 +347,36 @@ gst_rtmp_string_print_escaped (GString * string, const gchar * data,
|
||||||
g_string_append_c (string, '"');
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
|
#include "rtmpmessage.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
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,
|
void gst_rtmp_string_print_escaped (GString * string, const gchar * data,
|
||||||
gssize size);
|
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
|
G_END_DECLS
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue