mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
splitfilesrc: check bytes actually read, just in case
Handle corner case where we try to read beyond the end of the last file part, in which case we want to return a short read. If we get fewer bytes than expected for any other file part, we should just error out, since something fishy's going on then.
This commit is contained in:
parent
a595df5daa
commit
e6c4979a42
1 changed files with 26 additions and 9 deletions
|
@ -499,7 +499,6 @@ gst_split_file_src_create (GstBaseSrc * basesrc, guint64 offset, guint size,
|
||||||
buf = gst_buffer_new_and_alloc (size);
|
buf = gst_buffer_new_and_alloc (size);
|
||||||
|
|
||||||
GST_BUFFER_OFFSET (buf) = offset;
|
GST_BUFFER_OFFSET (buf) = offset;
|
||||||
GST_BUFFER_OFFSET_END (buf) = offset + size;
|
|
||||||
|
|
||||||
data = GST_BUFFER_DATA (buf);
|
data = GST_BUFFER_DATA (buf);
|
||||||
|
|
||||||
|
@ -507,6 +506,7 @@ gst_split_file_src_create (GstBaseSrc * basesrc, guint64 offset, guint size,
|
||||||
|
|
||||||
while (size > 0) {
|
while (size > 0) {
|
||||||
guint64 bytes_to_end_of_part;
|
guint64 bytes_to_end_of_part;
|
||||||
|
gsize read = 0;
|
||||||
|
|
||||||
/* we want the offset into the file part */
|
/* we want the offset into the file part */
|
||||||
read_offset = offset - cur_part.start;
|
read_offset = offset - cur_part.start;
|
||||||
|
@ -530,14 +530,14 @@ gst_split_file_src_create (GstBaseSrc * basesrc, guint64 offset, guint size,
|
||||||
stream = G_INPUT_STREAM (cur_part.stream);
|
stream = G_INPUT_STREAM (cur_part.stream);
|
||||||
|
|
||||||
/* NB: we won't try to read beyond EOF */
|
/* NB: we won't try to read beyond EOF */
|
||||||
if (!g_input_stream_read_all (stream, data, to_read, NULL, cancel, &err))
|
if (!g_input_stream_read_all (stream, data, to_read, &read, cancel, &err))
|
||||||
goto read_failed;
|
goto read_failed;
|
||||||
|
|
||||||
GST_LOG_OBJECT (src, "read %u bytes", to_read);
|
GST_LOG_OBJECT (src, "read %u bytes", (guint) read);
|
||||||
|
|
||||||
data += to_read;
|
data += read;
|
||||||
size -= to_read;
|
size -= read;
|
||||||
offset += to_read;
|
offset += read;
|
||||||
|
|
||||||
/* are we done? */
|
/* are we done? */
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
|
@ -545,15 +545,24 @@ gst_split_file_src_create (GstBaseSrc * basesrc, guint64 offset, guint size,
|
||||||
|
|
||||||
GST_LOG_OBJECT (src, "%u bytes left to read for this chunk", size);
|
GST_LOG_OBJECT (src, "%u bytes left to read for this chunk", size);
|
||||||
|
|
||||||
if (src->cur_part == src->num_parts - 1) {
|
/* corner case, this should never really happen (assuming basesrc clips
|
||||||
/* FIXME: at end, need to truncate buffer */
|
* requests beyond the file size) */
|
||||||
break;
|
if (read < to_read) {
|
||||||
|
if (src->cur_part == src->num_parts - 1) {
|
||||||
|
/* last file part, stop reading and truncate buffer */
|
||||||
|
GST_BUFFER_SIZE (buf) = offset - GST_BUFFER_OFFSET (buf);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
goto file_part_changed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
++src->cur_part;
|
++src->cur_part;
|
||||||
cur_part = src->parts[src->cur_part];
|
cur_part = src->parts[src->cur_part];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GST_BUFFER_OFFSET_END (buf) = offset;
|
||||||
|
|
||||||
*buffer = buf;
|
*buffer = buf;
|
||||||
GST_LOG_OBJECT (src, "read %u bytes into buf %p", GST_BUFFER_SIZE (buf), buf);
|
GST_LOG_OBJECT (src, "read %u bytes into buf %p", GST_BUFFER_SIZE (buf), buf);
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
|
@ -583,6 +592,14 @@ read_failed:
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
file_part_changed:
|
||||||
|
{
|
||||||
|
GST_ELEMENT_ERROR (src, RESOURCE, READ,
|
||||||
|
("Read error while reading file part %s", cur_part.path),
|
||||||
|
("Short read in file part, file may have been modified since start"));
|
||||||
|
gst_buffer_unref (buf);
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
|
}
|
||||||
cancelled:
|
cancelled:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (src, "I/O operation cancelled from another thread");
|
GST_DEBUG_OBJECT (src, "I/O operation cancelled from another thread");
|
||||||
|
|
Loading…
Reference in a new issue