winegstreamer: Use the size of the data read when allocating the read buffer.

Instead of the size of the data requested, which may be e.g. UINT_MAX.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52277
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2021-12-29 21:01:52 -06:00 committed by Alexandre Julliard
parent 5f0dcf7918
commit 4d2a628dfe
1 changed files with 39 additions and 28 deletions

View File

@ -80,11 +80,11 @@ struct wg_parser
pthread_cond_t read_cond, read_done_cond;
struct
{
void *data;
GstBuffer *buffer;
uint64_t offset;
uint32_t size;
bool done;
bool ret;
GstFlowReturn ret;
} read_request;
bool flushing, sink_connected;
@ -556,7 +556,7 @@ static NTSTATUS wg_parser_get_next_read_offset(void *args)
pthread_mutex_lock(&parser->mutex);
while (parser->sink_connected && !parser->read_request.data)
while (parser->sink_connected && !parser->read_request.size)
pthread_cond_wait(&parser->read_cond, &parser->mutex);
if (!parser->sink_connected)
@ -580,12 +580,35 @@ static NTSTATUS wg_parser_push_data(void *args)
uint32_t size = params->size;
pthread_mutex_lock(&parser->mutex);
parser->read_request.size = size;
parser->read_request.done = true;
parser->read_request.ret = !!data;
if (data)
memcpy(parser->read_request.data, data, size);
parser->read_request.data = NULL;
{
if (size)
{
GstMapInfo map_info;
/* Note that we don't allocate the buffer until we have a size.
* midiparse passes a NULL buffer and a size of UINT_MAX, in an
* apparent attempt to read the whole input stream at once. */
if (!parser->read_request.buffer)
parser->read_request.buffer = gst_buffer_new_and_alloc(size);
gst_buffer_map(parser->read_request.buffer, &map_info, GST_MAP_WRITE);
memcpy(map_info.data, data, size);
gst_buffer_unmap(parser->read_request.buffer, &map_info);
parser->read_request.ret = GST_FLOW_OK;
}
else
{
parser->read_request.ret = GST_FLOW_EOS;
}
}
else
{
parser->read_request.ret = GST_FLOW_ERROR;
}
parser->read_request.done = true;
parser->read_request.size = 0;
pthread_mutex_unlock(&parser->mutex);
pthread_cond_signal(&parser->read_done_cond);
@ -1279,9 +1302,7 @@ static GstFlowReturn src_getrange_cb(GstPad *pad, GstObject *parent,
guint64 offset, guint size, GstBuffer **buffer)
{
struct wg_parser *parser = gst_pad_get_element_private(pad);
GstBuffer *new_buffer = NULL;
GstMapInfo map_info;
bool ret;
GstFlowReturn ret;
GST_LOG("pad %p, offset %" G_GINT64_MODIFIER "u, size %u, buffer %p.", pad, offset, size, *buffer);
@ -1289,25 +1310,22 @@ static GstFlowReturn src_getrange_cb(GstPad *pad, GstObject *parent,
offset = parser->next_pull_offset;
parser->next_pull_offset = offset + size;
if (!*buffer)
*buffer = new_buffer = gst_buffer_new_and_alloc(size);
if (!size)
{
/* asfreader occasionally asks for zero bytes. gst_buffer_map() will
* return NULL in this case. Avoid confusing the read thread by asking
* it for zero bytes. */
if (!*buffer)
*buffer = gst_buffer_new_and_alloc(0);
gst_buffer_set_size(*buffer, 0);
GST_LOG("Returning empty buffer.");
return GST_FLOW_OK;
}
gst_buffer_map(*buffer, &map_info, GST_MAP_WRITE);
pthread_mutex_lock(&parser->mutex);
assert(!parser->read_request.data);
parser->read_request.data = map_info.data;
assert(!parser->read_request.size);
parser->read_request.buffer = *buffer;
parser->read_request.offset = offset;
parser->read_request.size = size;
parser->read_request.done = false;
@ -1320,21 +1338,14 @@ static GstFlowReturn src_getrange_cb(GstPad *pad, GstObject *parent,
while (!parser->read_request.done)
pthread_cond_wait(&parser->read_done_cond, &parser->mutex);
*buffer = parser->read_request.buffer;
ret = parser->read_request.ret;
gst_buffer_set_size(*buffer, parser->read_request.size);
pthread_mutex_unlock(&parser->mutex);
gst_buffer_unmap(*buffer, &map_info);
GST_LOG("Request returned %s.", gst_flow_get_name(ret));
GST_LOG("Request returned %d.", ret);
if ((!ret || !size) && new_buffer)
gst_buffer_unref(new_buffer);
if (ret)
return size ? GST_FLOW_OK : GST_FLOW_EOS;
return GST_FLOW_ERROR;
return ret;
}
static gboolean src_query_cb(GstPad *pad, GstObject *parent, GstQuery *query)