[libbluray-devel] Updated xine plugin:
hpi1
git at videolan.org
Thu Jun 9 11:04:34 CEST 2011
libbluray | branch: master | hpi1 <hpi1 at anonymous.org> | Thu Jun 9 10:11:38 2011 +0300| [c66ab4b2b28d8720bdf59eb5d4b32d5e5147faa5] | committer: hpi1
Updated xine plugin:
Use _x_set_fine_speed() instead of xine_set_param()
Added mutex to protect title_info
Check if current_clip is in valid range before using it
Use _x_action_pending() instead of accessing stream->demux_action_pending directly
Check for palette != NULL and rle data != NULL
Check if title_info is NULL before dereferencing it
> http://git.videolan.org/gitweb.cgi/libbluray.git/?a=commit;h=c66ab4b2b28d8720bdf59eb5d4b32d5e5147faa5
---
player_wrappers/xine/input_bluray.c | 94 ++++++++++++++++++++++++-----------
1 files changed, 64 insertions(+), 30 deletions(-)
diff --git a/player_wrappers/xine/input_bluray.c b/player_wrappers/xine/input_bluray.c
index 4088b50..be67c4a 100644
--- a/player_wrappers/xine/input_bluray.c
+++ b/player_wrappers/xine/input_bluray.c
@@ -38,6 +38,7 @@
#include <string.h>
#include <errno.h>
#include <dlfcn.h>
+#include <pthread.h>
#include <libbluray/bluray.h>
#include <libbluray/keys.h>
@@ -51,7 +52,7 @@
#define LOGMSG(x...) xine_log (this->stream->xine, XINE_LOG_MSG, "input_bluray: " x);
-#define XINE_ENGINE_INTERNAL
+#define XINE_ENGINE_INTERNAL // stream->demux_plugin
#ifdef HAVE_CONFIG_H
# include "xine_internal.h"
@@ -117,7 +118,8 @@ typedef struct {
int num_titles; /* navigation mode, number of titles in disc index */
int current_title; /* navigation mode, title from disc index */
BLURAY_TITLE_INFO *title_info;
- int current_clip;
+ pthread_mutex_t title_info_mutex; /* lock this when accessing title_info outside of input/demux thread */
+ unsigned int current_clip;
int error;
int menu_open;
int pg_enable;
@@ -139,8 +141,6 @@ static void close_overlay(bluray_input_plugin_t *this)
static void overlay_proc(void *this_gen, const BD_OVERLAY * const ov)
{
bluray_input_plugin_t *this = (bluray_input_plugin_t *) this_gen;
- uint32_t color[256];
- uint8_t trans[256];
unsigned i;
if (!this) {
@@ -165,16 +165,19 @@ static void overlay_proc(void *this_gen, const BD_OVERLAY * const ov)
_x_select_spu_channel(this->stream, -1);
/* convert and set palette */
-
+ if (ov->palette) {
+ uint32_t color[256];
+ uint8_t trans[256];
for(i = 0; i < 256; i++) {
trans[i] = ov->palette[i].T;
color[i] = (ov->palette[i].Y << 16) | (ov->palette[i].Cr << 8) | ov->palette[i].Cb;
}
xine_osd_set_palette(this->osd, color, trans);
+ }
/* uncompress and draw bitmap */
-
+ if (ov->img) {
const BD_PG_RLE_ELEM *rlep = ov->img;
uint8_t *img = malloc(ov->w * ov->h);
unsigned pixels = ov->w * ov->h;
@@ -186,6 +189,7 @@ static void overlay_proc(void *this_gen, const BD_OVERLAY * const ov)
xine_osd_draw_bitmap(this->osd, img, ov->x, ov->y, ov->w, ov->h, NULL);
free(img);
+ }
/* display */
@@ -197,17 +201,20 @@ static void overlay_proc(void *this_gen, const BD_OVERLAY * const ov)
static void update_stream_info(bluray_input_plugin_t *this)
{
- /* set stream info */
-
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_DVD_ANGLE_COUNT, this->title_info->angle_count);
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_DVD_ANGLE_NUMBER, bd_get_current_angle(this->bdh));
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_CHAPTERS, this->title_info->chapter_count > 0);
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_DVD_CHAPTER_COUNT, this->title_info->chapter_count);
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_DVD_CHAPTER_NUMBER, bd_get_current_chapter(this->bdh) + 1);
+ if (this->title_info) {
+ /* set stream info */
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_DVD_ANGLE_COUNT, this->title_info->angle_count);
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_DVD_ANGLE_NUMBER, bd_get_current_angle(this->bdh));
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_CHAPTERS, this->title_info->chapter_count > 0);
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_DVD_CHAPTER_COUNT, this->title_info->chapter_count);
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_DVD_CHAPTER_NUMBER, bd_get_current_chapter(this->bdh) + 1);
+ }
}
static void update_title_info(bluray_input_plugin_t *this, int playlist_id)
{
+ pthread_mutex_lock(&this->title_info_mutex);
+
if (this->title_info)
bd_free_title_info(this->title_info);
@@ -216,6 +223,8 @@ static void update_title_info(bluray_input_plugin_t *this, int playlist_id)
else
this->title_info = bd_get_playlist_info(this->bdh, playlist_id);
+ pthread_mutex_unlock(&this->title_info_mutex);
+
if (!this->title_info) {
LOGMSG("bd_get_title_info(%d) failed\n", this->current_title_idx);
return;
@@ -305,7 +314,7 @@ static void stream_reset(bluray_input_plugin_t *this)
this->cap_seekable = 0;
- xine_set_param(this->stream, XINE_PARAM_FINE_SPEED, XINE_FINE_SPEED_NORMAL);
+ _x_set_fine_speed(this->stream, XINE_FINE_SPEED_NORMAL);
this->stream->demux_plugin->seek(this->stream->demux_plugin, 0, 0, 1);
_x_demux_control_start(this->stream);
@@ -333,7 +342,7 @@ static void wait_secs(bluray_input_plugin_t *this, unsigned seconds)
// wait until interrupted
int loops = seconds * 25; /* N * 40 ms */
- while (!this->stream->demux_action_pending && loops-- > 0) {
+ while (!_x_action_pending(this->stream) && loops-- > 0) {
xine_usec_sleep(40*1000);
}
@@ -427,10 +436,7 @@ static void handle_libbluray_event(bluray_input_plugin_t *this, BD_EVENT ev)
case BD_EVENT_PLAYITEM:
lprintf("BD_EVENT_PLAYITEM %d\n", ev.param);
- if (ev.param < this->title_info->clip_count)
- this->current_clip = ev.param;
- else
- this->current_clip = 0;
+ this->current_clip = ev.param;
break;
case BD_EVENT_CHAPTER:
@@ -663,7 +669,7 @@ static off_t bluray_plugin_read (input_plugin_t *this_gen, char *buf, off_t len)
if (result == 0) {
handle_events(this);
if (ev.event == BD_EVENT_NONE) {
- if (this->stream->demux_action_pending) {
+ if (_x_action_pending(this->stream)) {
break;
}
}
@@ -737,7 +743,7 @@ static off_t bluray_plugin_seek_time (input_plugin_t *this_gen, int time_offset,
{
bluray_input_plugin_t *this = (bluray_input_plugin_t *) this_gen;
- if (!this || !this->bdh || !this->title_info)
+ if (!this || !this->bdh)
return -1;
/* convert relative seeks to absolute */
@@ -746,11 +752,21 @@ static off_t bluray_plugin_seek_time (input_plugin_t *this_gen, int time_offset,
time_offset += this_gen->get_current_time(this_gen);
}
else if (origin == SEEK_END) {
+
+ pthread_mutex_lock(&this->title_info_mutex);
+
+ if (!this->title_info) {
+ pthread_mutex_unlock(&this->title_info_mutex);
+ return -1;
+ }
+
int duration = this->title_info->duration / 90;
if (time_offset < duration)
time_offset = duration - time_offset;
else
time_offset = 0;
+
+ pthread_mutex_unlock(&this->title_info_mutex);
}
lprintf("bluray_plugin_seek_time() seeking to %d.%03ds\n", time_offset / 1000, time_offset % 1000);
@@ -793,12 +809,9 @@ static const char* bluray_plugin_get_mrl (input_plugin_t *this_gen)
return this->mrl;
}
-static int bluray_plugin_get_optional_data (input_plugin_t *this_gen, void *data, int data_type)
+static int get_optional_data_impl (bluray_input_plugin_t *this, void *data, int data_type)
{
- bluray_input_plugin_t *this = (bluray_input_plugin_t *) this_gen;
-
- if (!this || !this->stream || !data)
- return INPUT_OPTIONAL_UNSUPPORTED;
+ unsigned int current_clip = this->current_clip;
switch (data_type) {
case INPUT_OPTIONAL_DATA_DEMUXER:
@@ -810,9 +823,9 @@ static int bluray_plugin_get_optional_data (input_plugin_t *this_gen, void *data
* - channel number can be mpeg-ts PID (0x1100 ... 0x11ff)
*/
case INPUT_OPTIONAL_DATA_AUDIOLANG:
- if (this->title_info) {
+ if (this->title_info && this->title_info->clip_count < current_clip) {
int channel = *((int *)data);
- BLURAY_CLIP_INFO *clip = &this->title_info->clips[this->current_clip];
+ BLURAY_CLIP_INFO *clip = &this->title_info->clips[current_clip];
if (channel >= 0 && channel < clip->audio_stream_count) {
memcpy(data, clip->audio_streams[channel].lang, 4);
@@ -840,9 +853,9 @@ static int bluray_plugin_get_optional_data (input_plugin_t *this_gen, void *data
* - channel number can be mpeg-ts PID (0x1200 ... 0x12ff)
*/
case INPUT_OPTIONAL_DATA_SPULANG:
- if (this->title_info) {
+ if (this->title_info && this->title_info->clip_count < current_clip) {
int channel = *((int *)data);
- BLURAY_CLIP_INFO *clip = &this->title_info->clips[this->current_clip];
+ BLURAY_CLIP_INFO *clip = &this->title_info->clips[current_clip];
if (channel >= 0 && channel < clip->pg_stream_count) {
memcpy(data, clip->pg_streams[channel].lang, 4);
@@ -872,6 +885,20 @@ static int bluray_plugin_get_optional_data (input_plugin_t *this_gen, void *data
return INPUT_OPTIONAL_UNSUPPORTED;
}
+static int bluray_plugin_get_optional_data (input_plugin_t *this_gen, void *data, int data_type)
+{
+ bluray_input_plugin_t *this = (bluray_input_plugin_t *) this_gen;
+ int r = INPUT_OPTIONAL_UNSUPPORTED;
+
+ if (this && this->stream && data) {
+ pthread_mutex_lock(&this->title_info_mutex);
+ r = get_optional_data_impl(this, data, data_type);
+ pthread_mutex_unlock(&this->title_info_mutex);
+ }
+
+ return r;
+}
+
static void bluray_plugin_dispose (input_plugin_t *this_gen)
{
bluray_input_plugin_t *this = (bluray_input_plugin_t *) this_gen;
@@ -884,8 +911,13 @@ static void bluray_plugin_dispose (input_plugin_t *this_gen)
if (this->event_queue)
xine_event_dispose_queue(this->event_queue);
+ pthread_mutex_lock(&this->title_info_mutex);
if (this->title_info)
bd_free_title_info(this->title_info);
+ this->title_info = NULL;
+ pthread_mutex_unlock(&this->title_info_mutex);
+
+ pthread_mutex_destroy(&this->title_info_mutex);
if (this->bdh)
bd_close(this->bdh);
@@ -1166,6 +1198,8 @@ static input_plugin_t *bluray_class_get_instance (input_class_t *cls_gen, xine_s
this->event_queue = xine_event_new_queue (this->stream);
+ pthread_mutex_init(&this->title_info_mutex, NULL);
+
this->pg_stream = -1;
return &this->input_plugin;
More information about the libbluray-devel
mailing list