mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +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);
|
||||
|
||||
GST_BUFFER_OFFSET (buf) = offset;
|
||||
GST_BUFFER_OFFSET_END (buf) = offset + size;
|
||||
|
||||
data = GST_BUFFER_DATA (buf);
|
||||
|
||||
|
@ -507,6 +506,7 @@ gst_split_file_src_create (GstBaseSrc * basesrc, guint64 offset, guint size,
|
|||
|
||||
while (size > 0) {
|
||||
guint64 bytes_to_end_of_part;
|
||||
gsize read = 0;
|
||||
|
||||
/* we want the offset into the file part */
|
||||
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);
|
||||
|
||||
/* 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;
|
||||
|
||||
GST_LOG_OBJECT (src, "read %u bytes", to_read);
|
||||
GST_LOG_OBJECT (src, "read %u bytes", (guint) read);
|
||||
|
||||
data += to_read;
|
||||
size -= to_read;
|
||||
offset += to_read;
|
||||
data += read;
|
||||
size -= read;
|
||||
offset += read;
|
||||
|
||||
/* are we done? */
|
||||
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);
|
||||
|
||||
if (src->cur_part == src->num_parts - 1) {
|
||||
/* FIXME: at end, need to truncate buffer */
|
||||
break;
|
||||
/* corner case, this should never really happen (assuming basesrc clips
|
||||
* requests beyond the file size) */
|
||||
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;
|
||||
cur_part = src->parts[src->cur_part];
|
||||
}
|
||||
|
||||
GST_BUFFER_OFFSET_END (buf) = offset;
|
||||
|
||||
*buffer = buf;
|
||||
GST_LOG_OBJECT (src, "read %u bytes into buf %p", GST_BUFFER_SIZE (buf), buf);
|
||||
return GST_FLOW_OK;
|
||||
|
@ -583,6 +592,14 @@ read_failed:
|
|||
gst_buffer_unref (buf);
|
||||
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:
|
||||
{
|
||||
GST_DEBUG_OBJECT (src, "I/O operation cancelled from another thread");
|
||||
|
|
Loading…
Reference in a new issue