mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +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/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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue