winegstreamer: Properly clean up from failure in wg_parser_connect().
In particular, unset the sink_connected value, and make sure that subsequent wg_parser_get_read_request calls don't hang. Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
830efe873a
commit
721b1eb2eb
|
@ -1034,6 +1034,30 @@ static struct wg_parser_stream *create_stream(struct wg_parser *parser)
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void free_stream(struct wg_parser_stream *stream)
|
||||||
|
{
|
||||||
|
if (stream->their_src)
|
||||||
|
{
|
||||||
|
if (stream->post_sink)
|
||||||
|
{
|
||||||
|
gst_pad_unlink(stream->their_src, stream->post_sink);
|
||||||
|
gst_pad_unlink(stream->post_src, stream->my_sink);
|
||||||
|
gst_object_unref(stream->post_src);
|
||||||
|
gst_object_unref(stream->post_sink);
|
||||||
|
stream->post_src = stream->post_sink = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
gst_pad_unlink(stream->their_src, stream->my_sink);
|
||||||
|
gst_object_unref(stream->their_src);
|
||||||
|
}
|
||||||
|
gst_object_unref(stream->my_sink);
|
||||||
|
|
||||||
|
pthread_cond_destroy(&stream->event_cond);
|
||||||
|
pthread_cond_destroy(&stream->event_empty_cond);
|
||||||
|
|
||||||
|
free(stream);
|
||||||
|
}
|
||||||
|
|
||||||
static void pad_added_cb(GstElement *element, GstPad *pad, gpointer user)
|
static void pad_added_cb(GstElement *element, GstPad *pad, gpointer user)
|
||||||
{
|
{
|
||||||
struct wg_parser *parser = user;
|
struct wg_parser *parser = user;
|
||||||
|
@ -1520,14 +1544,14 @@ static HRESULT CDECL wg_parser_connect(struct wg_parser *parser, uint64_t file_s
|
||||||
parser->error = false;
|
parser->error = false;
|
||||||
|
|
||||||
if (!parser->init_gst(parser))
|
if (!parser->init_gst(parser))
|
||||||
return E_FAIL;
|
goto out;
|
||||||
|
|
||||||
gst_element_set_state(parser->container, GST_STATE_PAUSED);
|
gst_element_set_state(parser->container, GST_STATE_PAUSED);
|
||||||
ret = gst_element_get_state(parser->container, NULL, NULL, -1);
|
ret = gst_element_get_state(parser->container, NULL, NULL, -1);
|
||||||
if (ret == GST_STATE_CHANGE_FAILURE)
|
if (ret == GST_STATE_CHANGE_FAILURE)
|
||||||
{
|
{
|
||||||
GST_ERROR("Failed to play stream.\n");
|
GST_ERROR("Failed to play stream.\n");
|
||||||
return E_FAIL;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&parser->mutex);
|
pthread_mutex_lock(&parser->mutex);
|
||||||
|
@ -1537,7 +1561,7 @@ static HRESULT CDECL wg_parser_connect(struct wg_parser *parser, uint64_t file_s
|
||||||
if (parser->error)
|
if (parser->error)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(&parser->mutex);
|
pthread_mutex_unlock(&parser->mutex);
|
||||||
return E_FAIL;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < parser->stream_count; ++i)
|
for (i = 0; i < parser->stream_count; ++i)
|
||||||
|
@ -1577,7 +1601,7 @@ static HRESULT CDECL wg_parser_connect(struct wg_parser *parser, uint64_t file_s
|
||||||
if (parser->error)
|
if (parser->error)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(&parser->mutex);
|
pthread_mutex_unlock(&parser->mutex);
|
||||||
return E_FAIL;
|
goto out;
|
||||||
}
|
}
|
||||||
if (gst_pad_query_duration(stream->their_src, GST_FORMAT_TIME, &duration))
|
if (gst_pad_query_duration(stream->their_src, GST_FORMAT_TIME, &duration))
|
||||||
{
|
{
|
||||||
|
@ -1614,30 +1638,36 @@ static HRESULT CDECL wg_parser_connect(struct wg_parser *parser, uint64_t file_s
|
||||||
|
|
||||||
parser->next_offset = 0;
|
parser->next_offset = 0;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
|
||||||
|
|
||||||
static void free_stream(struct wg_parser_stream *stream)
|
out:
|
||||||
{
|
if (parser->container)
|
||||||
if (stream->their_src)
|
gst_element_set_state(parser->container, GST_STATE_NULL);
|
||||||
|
if (parser->their_sink)
|
||||||
{
|
{
|
||||||
if (stream->post_sink)
|
gst_pad_unlink(parser->my_src, parser->their_sink);
|
||||||
|
gst_object_unref(parser->their_sink);
|
||||||
|
parser->my_src = parser->their_sink = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < parser->stream_count; ++i)
|
||||||
|
free_stream(parser->streams[i]);
|
||||||
|
parser->stream_count = 0;
|
||||||
|
free(parser->streams);
|
||||||
|
parser->streams = NULL;
|
||||||
|
|
||||||
|
if (parser->container)
|
||||||
{
|
{
|
||||||
gst_pad_unlink(stream->their_src, stream->post_sink);
|
gst_element_set_bus(parser->container, NULL);
|
||||||
gst_pad_unlink(stream->post_src, stream->my_sink);
|
gst_object_unref(parser->container);
|
||||||
gst_object_unref(stream->post_src);
|
parser->container = NULL;
|
||||||
gst_object_unref(stream->post_sink);
|
|
||||||
stream->post_src = stream->post_sink = NULL;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
gst_pad_unlink(stream->their_src, stream->my_sink);
|
|
||||||
gst_object_unref(stream->their_src);
|
|
||||||
}
|
|
||||||
gst_object_unref(stream->my_sink);
|
|
||||||
|
|
||||||
pthread_cond_destroy(&stream->event_cond);
|
pthread_mutex_lock(&parser->mutex);
|
||||||
pthread_cond_destroy(&stream->event_empty_cond);
|
parser->sink_connected = false;
|
||||||
|
pthread_mutex_unlock(&parser->mutex);
|
||||||
|
pthread_cond_signal(&parser->read_cond);
|
||||||
|
|
||||||
free(stream);
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CDECL wg_parser_disconnect(struct wg_parser *parser)
|
static void CDECL wg_parser_disconnect(struct wg_parser *parser)
|
||||||
|
|
Loading…
Reference in New Issue