summaryrefslogtreecommitdiffstats
path: root/stream
diff options
context:
space:
mode:
authorOliver Freyermuth <o.freyermuth@googlemail.com>2016-01-08 18:37:30 +0100
committerwm4 <wm4@nowhere>2016-01-14 00:36:53 +0100
commitc55b242b4ee89e91b4f9896e214c3bbe0ed46ea1 (patch)
tree49f7fa336fad5d906dc602d0465b95c2b0c04785 /stream
parent1e46bda0f86d9d58c38135c7b9ddbb6dbb7c3572 (diff)
downloadmpv-c55b242b4ee89e91b4f9896e214c3bbe0ed46ea1.tar.bz2
mpv-c55b242b4ee89e91b4f9896e214c3bbe0ed46ea1.tar.xz
stream_dvb: global protection mutex and usage bit for global_dvb_state.
The mutex is used in dvbin_open and dvbin_close only since these are the only entry / exit points to the stream. When opening, it is first checked (mutexed) whether the state already exists and is in use, then a STREAM_ERROR is returned, since there may be only one stream_dvb active at a time. State-creation itself is also protected by mutex. In dvbin_close, the usage-bit is set to false (mutexed) in case of channel switch. In case of stream-teardown, the state is destructed (also protected by mutex).
Diffstat (limited to 'stream')
-rw-r--r--stream/dvbin.h1
-rw-r--r--stream/stream_dvb.c21
2 files changed, 21 insertions, 1 deletions
diff --git a/stream/dvbin.h b/stream/dvbin.h
index cf0a41a502..e0688aa79e 100644
--- a/stream/dvbin.h
+++ b/stream/dvbin.h
@@ -103,6 +103,7 @@ typedef struct {
int timeout;
int last_freq;
bool switching_channel;
+ bool stream_used;
} dvb_state_t;
typedef struct dvb_params {
diff --git a/stream/stream_dvb.c b/stream/stream_dvb.c
index 3f13828a5f..450f8500d0 100644
--- a/stream/stream_dvb.c
+++ b/stream/stream_dvb.c
@@ -40,6 +40,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
+#include <pthread.h>
#include <libavutil/avstring.h>
@@ -63,6 +64,7 @@
#define OPT_BASE_STRUCT struct dvb_params
static dvb_state_t* global_dvb_state = NULL;
+static pthread_mutex_t global_dvb_state_lock = PTHREAD_MUTEX_INITIALIZER;
/// URL definition
static const m_option_t stream_params[] = {
@@ -820,9 +822,13 @@ static void dvbin_close(stream_t *stream)
{
dvb_priv_t *priv = (dvb_priv_t *) stream->priv;
dvb_state_t* state = priv->state;
+
if (state->switching_channel && state->is_on) {
// Prevent state destruction, reset channel-switch.
state->switching_channel = false;
+ pthread_mutex_lock(&global_dvb_state_lock);
+ global_dvb_state->stream_used = false;
+ pthread_mutex_unlock(&global_dvb_state_lock);
return;
}
@@ -838,8 +844,11 @@ static void dvbin_close(stream_t *stream)
state->fe_fd = state->dvr_fd = -1;
state->is_on = 0;
+
+ pthread_mutex_lock(&global_dvb_state_lock);
dvb_free_state(state);
global_dvb_state = NULL;
+ pthread_mutex_unlock(&global_dvb_state_lock);
}
static int dvb_streaming_start(stream_t *stream, int tuner_type, char *progname)
@@ -897,7 +906,17 @@ static int dvb_open(stream_t *stream)
char *progname;
int tuner_type = 0, i;
+ pthread_mutex_lock(&global_dvb_state_lock);
+ if (global_dvb_state && global_dvb_state->stream_used) {
+ MP_ERR(stream, "DVB stream already in use, only one DVB stream can exist at a time!");
+ pthread_mutex_unlock(&global_dvb_state_lock);
+ return STREAM_ERROR;
+ }
+
dvb_state_t* state = dvb_get_state(stream);
+ state->stream_used = true;
+ pthread_mutex_unlock(&global_dvb_state_lock);
+
priv->state = state;
if (state == NULL) {
MP_ERR(stream, "DVB CONFIGURATION IS EMPTY, exit\n");
@@ -982,6 +1001,7 @@ dvb_state_t *dvb_get_state(stream_t *stream)
state->count = 0;
state->switching_channel = false;
+ state->stream_used = true;
state->cards = NULL;
state->fe_fd = state->dvr_fd = -1;
for (int i = 0; i < MAX_CARDS; i++) {
@@ -1073,7 +1093,6 @@ dvb_state_t *dvb_get_state(stream_t *stream)
}
global_dvb_state = state;
-
return state;
}