mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-18 20:25:25 +00:00
rtspconnection: Fixes for corrupt RTP packets in dispatch_write()
Fixes 2 problems: 1) Number of unmapped memories does not always match number of mmaped ones in dispatch_write(). 2) When dispatch_write() is dispatched second time after an incomplete write, already set offsets will not be taken into account, thus corrupt RTP data will be sent.
This commit is contained in:
parent
f90dac8d48
commit
87a9f2b92c
1 changed files with 20 additions and 21 deletions
|
@ -3747,7 +3747,7 @@ gst_rtsp_source_dispatch_write (GPollableOutputStream * stream,
|
||||||
guint *ids;
|
guint *ids;
|
||||||
gsize bytes_to_write, bytes_written;
|
gsize bytes_to_write, bytes_written;
|
||||||
guint n_vectors, n_memories, n_ids, drop_messages;
|
guint n_vectors, n_memories, n_ids, drop_messages;
|
||||||
gint i, j, k, l;
|
gint i, j, l, n_mmap;
|
||||||
GstRTSPSerializedMessage *msg;
|
GstRTSPSerializedMessage *msg;
|
||||||
|
|
||||||
/* if this connection was already closed, stop now */
|
/* if this connection was already closed, stop now */
|
||||||
|
@ -3821,7 +3821,8 @@ gst_rtsp_source_dispatch_write (GPollableOutputStream * stream,
|
||||||
if (ids)
|
if (ids)
|
||||||
memset (ids, 0, sizeof (guint) * (n_ids + 1));
|
memset (ids, 0, sizeof (guint) * (n_ids + 1));
|
||||||
|
|
||||||
for (i = 0, j = 0, k = 0, l = 0, bytes_to_write = 0; i < n_messages; i++) {
|
for (i = 0, j = 0, n_mmap = 0, l = 0, bytes_to_write = 0; i < n_messages;
|
||||||
|
i++) {
|
||||||
msg = gst_queue_array_peek_nth_struct (watch->messages, i);
|
msg = gst_queue_array_peek_nth_struct (watch->messages, i);
|
||||||
|
|
||||||
if (msg->data_offset < msg->data_size) {
|
if (msg->data_offset < msg->data_size) {
|
||||||
|
@ -3842,33 +3843,32 @@ gst_rtsp_source_dispatch_write (GPollableOutputStream * stream,
|
||||||
} else if (msg->body_buffer) {
|
} else if (msg->body_buffer) {
|
||||||
guint m, n;
|
guint m, n;
|
||||||
guint offset = 0;
|
guint offset = 0;
|
||||||
|
|
||||||
n = gst_buffer_n_memory (msg->body_buffer);
|
n = gst_buffer_n_memory (msg->body_buffer);
|
||||||
for (m = 0; m < n; m++) {
|
for (m = 0; m < n; m++) {
|
||||||
GstMemory *mem = gst_buffer_peek_memory (msg->body_buffer, m);
|
GstMemory *mem = gst_buffer_peek_memory (msg->body_buffer, m);
|
||||||
guint off;
|
guint off;
|
||||||
|
|
||||||
/* Skip all memories we already wrote */
|
/* Skip all memories we already wrote */
|
||||||
if (offset + mem->size < msg->body_offset) {
|
if (offset + mem->size <= msg->body_offset) {
|
||||||
offset += mem->size;
|
offset += mem->size;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset < msg->body_offset) {
|
if (offset < msg->body_offset)
|
||||||
off = msg->body_offset - offset;
|
off = msg->body_offset - offset;
|
||||||
} else {
|
else
|
||||||
offset += mem->size;
|
|
||||||
off = 0;
|
off = 0;
|
||||||
}
|
|
||||||
|
offset += mem->size;
|
||||||
|
|
||||||
g_assert (off < mem->size);
|
g_assert (off < mem->size);
|
||||||
|
|
||||||
gst_memory_map (mem, &map_infos[k], GST_MAP_READ);
|
gst_memory_map (mem, &map_infos[n_mmap], GST_MAP_READ);
|
||||||
vectors[j].buffer = map_infos[k].data + off;
|
vectors[j].buffer = map_infos[n_mmap].data + off;
|
||||||
vectors[j].size = map_infos[k].size - off;
|
vectors[j].size = map_infos[n_mmap].size - off;
|
||||||
bytes_to_write += vectors[j].size;
|
bytes_to_write += vectors[j].size;
|
||||||
|
|
||||||
k++;
|
n_mmap++;
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3882,8 +3882,8 @@ gst_rtsp_source_dispatch_write (GPollableOutputStream * stream,
|
||||||
/* First unmap all memories here, this simplifies the code below
|
/* First unmap all memories here, this simplifies the code below
|
||||||
* as we don't have to skip all memories that were already written
|
* as we don't have to skip all memories that were already written
|
||||||
* before */
|
* before */
|
||||||
for (k = 0; k < n_memories; k++) {
|
for (i = 0; i < n_mmap; i++) {
|
||||||
gst_memory_unmap (map_infos[k].memory, &map_infos[k]);
|
gst_memory_unmap (map_infos[i].memory, &map_infos[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytes_written == bytes_to_write) {
|
if (bytes_written == bytes_to_write) {
|
||||||
|
@ -3902,31 +3902,30 @@ gst_rtsp_source_dispatch_write (GPollableOutputStream * stream,
|
||||||
watch->messages_bytes -= bytes_written;
|
watch->messages_bytes -= bytes_written;
|
||||||
} else if (bytes_written > 0) {
|
} else if (bytes_written > 0) {
|
||||||
/* not done, let's skip all messages that were sent already and free them */
|
/* not done, let's skip all messages that were sent already and free them */
|
||||||
for (i = 0, k = 0, drop_messages = 0; i < n_messages; i++) {
|
for (i = 0, drop_messages = 0; i < n_messages; i++) {
|
||||||
msg = gst_queue_array_peek_nth_struct (watch->messages, i);
|
msg = gst_queue_array_peek_nth_struct (watch->messages, i);
|
||||||
|
|
||||||
if (bytes_written >= 0) {
|
if (bytes_written >= 0) {
|
||||||
if (bytes_written >= msg->data_size) {
|
if (bytes_written >= msg->data_size - msg->data_offset) {
|
||||||
guint body_size;
|
guint body_size;
|
||||||
|
|
||||||
/* all data of this message is sent, check body and otherwise
|
/* all data of this message is sent, check body and otherwise
|
||||||
* skip the whole message for next time */
|
* skip the whole message for next time */
|
||||||
|
bytes_written -= (msg->data_size - msg->data_offset);
|
||||||
msg->data_offset = msg->data_size;
|
msg->data_offset = msg->data_size;
|
||||||
bytes_written -= msg->data_size;
|
|
||||||
|
|
||||||
if (msg->body_data) {
|
if (msg->body_data) {
|
||||||
body_size = msg->body_data_size;
|
body_size = msg->body_data_size;
|
||||||
|
|
||||||
} else if (msg->body_buffer) {
|
} else if (msg->body_buffer) {
|
||||||
body_size = gst_buffer_get_size (msg->body_buffer);
|
body_size = gst_buffer_get_size (msg->body_buffer);
|
||||||
} else {
|
} else {
|
||||||
body_size = 0;
|
body_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytes_written >= body_size) {
|
if (bytes_written + msg->body_offset >= body_size) {
|
||||||
/* body written, drop this message */
|
/* body written, drop this message */
|
||||||
|
bytes_written -= body_size - msg->body_offset;
|
||||||
msg->body_offset = body_size;
|
msg->body_offset = body_size;
|
||||||
bytes_written -= body_size;
|
|
||||||
drop_messages++;
|
drop_messages++;
|
||||||
|
|
||||||
if (msg->id) {
|
if (msg->id) {
|
||||||
|
@ -3936,7 +3935,7 @@ gst_rtsp_source_dispatch_write (GPollableOutputStream * stream,
|
||||||
|
|
||||||
gst_rtsp_serialized_message_clear (msg);
|
gst_rtsp_serialized_message_clear (msg);
|
||||||
} else {
|
} else {
|
||||||
msg->body_offset = bytes_written;
|
msg->body_offset += bytes_written;
|
||||||
bytes_written = 0;
|
bytes_written = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue