libbluray | branch: master | hpi1 <[email protected]> | 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; _______________________________________________ libbluray-devel mailing list [email protected] http://mailman.videolan.org/listinfo/libbluray-devel
