summaryrefslogtreecommitdiff
path: root/src/libspucc/xine_decoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libspucc/xine_decoder.c')
-rw-r--r--src/libspucc/xine_decoder.c131
1 files changed, 46 insertions, 85 deletions
diff --git a/src/libspucc/xine_decoder.c b/src/libspucc/xine_decoder.c
index 467b93369..8e3f88dea 100644
--- a/src/libspucc/xine_decoder.c
+++ b/src/libspucc/xine_decoder.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xine_decoder.c,v 1.29 2004/04/26 17:50:08 mroi Exp $
+ * $Id: xine_decoder.c,v 1.30 2004/05/05 17:36:48 mroi Exp $
*
* closed caption spu decoder. receive data by events.
*
@@ -47,20 +47,14 @@ typedef struct spucc_decoder_s {
int cc_open;
/* closed captioning decoder configuration and intrinsics */
- cc_config_t cc_cfg;
+ cc_state_t cc_state;
+ /* this is to detect configuration changes */
+ int config_version;
/* video dimensions captured in frame change events */
int video_width;
int video_height;
- /* big lock regulating access to the CC decoder, CC renderer, and
- configuration changes. For CC decoding, fine-grained locking is not
- necessary. Using just single lock for everything makes the code
- for configuraton changes *a lot* simpler, and *much* easier to
- debug and maintain.
- */
- pthread_mutex_t cc_mutex;
-
/* events will be sent here */
xine_event_queue_t *queue;
@@ -78,7 +72,6 @@ static void copy_str(char *d, const char *s, size_t maxbytes)
/*------------------- private methods --------------------------------------*/
-/* CAUTION: THIS FUNCTION ASSUMES THAT THE MUTEX IS ALREADY LOCKED! */
static void spucc_update_intrinsics(spucc_decoder_t *this)
{
#ifdef LOG_DEBUG
@@ -86,12 +79,10 @@ static void spucc_update_intrinsics(spucc_decoder_t *this)
#endif
if (this->cc_open)
- cc_renderer_update_cfg(this->cc_cfg.renderer, this->video_width,
+ cc_renderer_update_cfg(this->cc_state.renderer, this->video_width,
this->video_height);
}
-
-/* CAUTION: THIS FUNCTION ASSUMES THAT THE MUTEX IS ALREADY LOCKED! */
static void spucc_do_close(spucc_decoder_t *this)
{
if (this->cc_open) {
@@ -99,13 +90,11 @@ static void spucc_do_close(spucc_decoder_t *this)
printf("spucc: close\n");
#endif
cc_decoder_close(this->ccdec);
- cc_renderer_close(this->cc_cfg.renderer);
+ cc_renderer_close(this->cc_state.renderer);
this->cc_open = 0;
}
}
-
-/* CAUTION: THIS FUNCTION ASSUMES THAT THE MUTEX IS ALREADY LOCKED! */
static void spucc_do_init (spucc_decoder_t *this)
{
if (! this->cc_open) {
@@ -113,14 +102,14 @@ static void spucc_do_init (spucc_decoder_t *this)
printf("spucc: init\n");
#endif
/* initialize caption renderer */
- this->cc_cfg.renderer = cc_renderer_open(this->stream->osd_renderer,
- this->stream->metronom,
- &this->cc_cfg,
- this->video_width,
- this->video_height);
+ this->cc_state.renderer = cc_renderer_open(this->stream->osd_renderer,
+ this->stream->metronom,
+ &this->cc_state,
+ this->video_width,
+ this->video_height);
spucc_update_intrinsics(this);
/* initialize CC decoder */
- this->ccdec = cc_decoder_open(&this->cc_cfg);
+ this->ccdec = cc_decoder_open(&this->cc_state);
this->cc_open = 1;
}
}
@@ -130,47 +119,35 @@ static void spucc_do_init (spucc_decoder_t *this)
static void spucc_cfg_enable_change(void *this_gen, xine_cfg_entry_t *value)
{
- spucc_decoder_t *this = (spucc_decoder_t *) this_gen;
+ spucc_class_t *this = (spucc_class_t *) this_gen;
cc_config_t *cc_cfg = &this->cc_cfg;
- pthread_mutex_lock(&this->cc_mutex);
-
cc_cfg->cc_enabled = value->num_value;
- if (! cc_cfg->cc_enabled) {
- /* captions were just disabled? */
- spucc_do_close(this);
- }
- /* caption decoder is initialized on demand, so do nothing on open */
-
#ifdef LOG_DEBUG
printf("spucc: closed captions are now %s.\n", cc_cfg->cc_enabled?
"enabled" : "disabled");
#endif
-
- pthread_mutex_unlock(&this->cc_mutex);
+ cc_cfg->config_version++;
}
static void spucc_cfg_scheme_change(void *this_gen, xine_cfg_entry_t *value)
{
- spucc_decoder_t *this = (spucc_decoder_t *) this_gen;
+ spucc_class_t *this = (spucc_class_t *) this_gen;
cc_config_t *cc_cfg = &this->cc_cfg;
- pthread_mutex_lock(&this->cc_mutex);
-
cc_cfg->cc_scheme = value->num_value;
#ifdef LOG_DEBUG
printf("spucc: closed captioning scheme is now %s.\n",
cc_schemes[cc_cfg->cc_scheme]);
#endif
- spucc_update_intrinsics(this);
- pthread_mutex_unlock(&this->cc_mutex);
+ cc_cfg->config_version++;
}
static void spucc_font_change(void *this_gen, xine_cfg_entry_t *value)
{
- spucc_decoder_t *this = (spucc_decoder_t *) this_gen;
+ spucc_class_t *this = (spucc_class_t *) this_gen;
cc_config_t *cc_cfg = &this->cc_cfg;
char *font;
@@ -179,21 +156,17 @@ static void spucc_font_change(void *this_gen, xine_cfg_entry_t *value)
else
font = cc_cfg->italic_font;
- pthread_mutex_lock(&this->cc_mutex);
-
copy_str(font, value->str_value, CC_FONT_MAX);
- spucc_update_intrinsics(this);
#ifdef LOG_DEBUG
printf("spucc: changing %s to font %s\n", value->key, font);
#endif
-
- pthread_mutex_unlock(&this->cc_mutex);
+ cc_cfg->config_version++;
}
static void spucc_num_change(void *this_gen, xine_cfg_entry_t *value)
{
- spucc_decoder_t *this = (spucc_decoder_t *) this_gen;
+ spucc_class_t *this = (spucc_class_t *) this_gen;
cc_config_t *cc_cfg = &this->cc_cfg;
int *num;
@@ -202,26 +175,22 @@ static void spucc_num_change(void *this_gen, xine_cfg_entry_t *value)
else
num = &cc_cfg->center;
- pthread_mutex_lock(&this->cc_mutex);
-
*num = value->num_value;
- spucc_update_intrinsics(this);
#ifdef LOG_DEBUG
printf("spucc: changing %s to %d\n", value->key, *num);
#endif
-
- pthread_mutex_unlock(&this->cc_mutex);
+ cc_cfg->config_version++;
}
-static void spucc_register_cfg_vars(spucc_decoder_t *this,
+static void spucc_register_cfg_vars(spucc_class_t *this,
config_values_t *xine_cfg) {
cc_config_t *cc_vars = &this->cc_cfg;
cc_vars->cc_enabled = xine_cfg->register_bool(xine_cfg,
"misc.cc_enabled", 0,
_("display closed captions in MPEG-2 streams"),
- _("Closed captions are subtitles mostly meant "
+ _("Closed Captions are subtitles mostly meant "
"to help the hearing impaired."),
0, spucc_cfg_enable_change, this);
@@ -261,16 +230,6 @@ static void spucc_register_cfg_vars(spucc_decoder_t *this,
}
-static void spucc_unregister_cfg_callbacks(config_values_t *xine_cfg) {
- xine_cfg->unregister_callback(xine_cfg, "misc.cc_enabled");
- xine_cfg->unregister_callback(xine_cfg, "misc.cc_scheme");
- xine_cfg->unregister_callback(xine_cfg, "misc.cc_font");
- xine_cfg->unregister_callback(xine_cfg, "misc.cc_italic_font");
- xine_cfg->unregister_callback(xine_cfg, "misc.cc_font_size");
- xine_cfg->unregister_callback(xine_cfg, "misc.cc_center");
-}
-
-
/* called when the video frame size changes */
static void spucc_notify_frame_change(spucc_decoder_t *this,
int width, int height) {
@@ -278,11 +237,9 @@ static void spucc_notify_frame_change(spucc_decoder_t *this,
printf("spucc: new frame size: %dx%d\n", width, height);
#endif
- pthread_mutex_lock(&this->cc_mutex);
this->video_width = width;
this->video_height = height;
spucc_update_intrinsics(this);
- pthread_mutex_unlock(&this->cc_mutex);
}
@@ -292,7 +249,7 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
spucc_decoder_t *this = (spucc_decoder_t *) this_gen;
xine_event_t *event;
- if ((event = xine_event_get(this->queue))) {
+ while ((event = xine_event_get(this->queue))) {
switch (event->type) {
case XINE_EVENT_FRAME_FORMAT_CHANGE:
{
@@ -304,21 +261,27 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
}
break;
}
+ xine_event_free(event);
}
if (buf->decoder_flags & BUF_FLAG_PREVIEW) {
} else {
- pthread_mutex_lock(&this->cc_mutex);
- if (this->cc_cfg.cc_enabled) {
+
+ if (this->cc_state.cc_cfg->config_version > this->config_version) {
+ spucc_update_intrinsics(this);
+ if (!this->cc_state.cc_cfg->cc_enabled)
+ spucc_do_close(this);
+ this->config_version = this->cc_state.cc_cfg->config_version;
+ }
+
+ if (this->cc_state.cc_cfg->cc_enabled) {
if( !this->cc_open )
spucc_do_init (this);
-
- if(this->cc_cfg.can_cc) {
+ if(this->cc_state.can_cc) {
decode_cc(this->ccdec, buf->content, buf->size,
buf->pts);
}
}
- pthread_mutex_unlock(&this->cc_mutex);
}
}
@@ -331,13 +294,8 @@ static void spudec_discontinuity (spu_decoder_t *this_gen) {
static void spudec_dispose (spu_decoder_t *this_gen) {
spucc_decoder_t *this = (spucc_decoder_t *) this_gen;
- pthread_mutex_lock(&this->cc_mutex);
spucc_do_close(this);
- pthread_mutex_unlock(&this->cc_mutex);
-
- spucc_unregister_cfg_callbacks(this->stream->xine->config);
xine_event_dispose_queue(this->queue);
- pthread_mutex_destroy (&this->cc_mutex);
free (this);
}
@@ -357,10 +315,10 @@ static spu_decoder_t *spudec_open_plugin (spu_decoder_class_t *class, xine_strea
this->stream = stream;
this->queue = xine_event_new_queue(stream);
+ this->cc_state.cc_cfg = &((spucc_class_t *)class)->cc_cfg;
+ this->config_version = 0;
this->cc_open = 0;
- pthread_mutex_init(&this->cc_mutex, NULL);
- spucc_register_cfg_vars(this, stream->xine->config);
cc_decoder_init();
return &this->spu_decoder;
@@ -381,16 +339,19 @@ static void spudec_class_dispose(spu_decoder_class_t *class) {
static void *init_spu_decoder_plugin (xine_t *xine, void *data) {
- spu_decoder_class_t *this ;
+ spucc_class_t *this ;
- this = (spu_decoder_class_t *) xine_xmalloc (sizeof (spu_decoder_class_t));
+ this = (spucc_class_t *) xine_xmalloc (sizeof (spucc_class_t));
- this->open_plugin = spudec_open_plugin;
- this->get_identifier = spudec_get_identifier;
- this->get_description = spudec_get_description;
- this->dispose = spudec_class_dispose;
+ this->spu_class.open_plugin = spudec_open_plugin;
+ this->spu_class.get_identifier = spudec_get_identifier;
+ this->spu_class.get_description = spudec_get_description;
+ this->spu_class.dispose = spudec_class_dispose;
- return this;
+ spucc_register_cfg_vars(this, xine->config);
+ this->cc_cfg.config_version = 0;
+
+ return &this->spu_class;
}
/* plugin catalog information */