From 6c947c64a17c28eefe5179bd71ab077d6c2bbd0d Mon Sep 17 00:00:00 2001 From: xylosper Date: Thu, 27 Mar 2014 03:17:31 +0900 Subject: stream_bluray: cache current playback informations The cost of calling bd_get_title_info() is quite expensive and requires lots of CPU usage. Using BD_EVENT_PLAYLIST and BD_EVENT_TITLE, it's possible to cache BLURAY_TITLE_INFO object for current title and BD_EVENT_ANGLE handler caches current angle. In my test case, with this commit, CPU usage can be saved about 15-20%. --- stream/stream_bluray.c | 54 +++++++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 20 deletions(-) (limited to 'stream') diff --git a/stream/stream_bluray.c b/stream/stream_bluray.c index b694c71a8b..4430cef482 100644 --- a/stream/stream_bluray.c +++ b/stream/stream_bluray.c @@ -60,6 +60,7 @@ int bluray_angle = 0; struct bluray_priv_s { BLURAY *bd; + BLURAY_TITLE_INFO *title_info; int num_titles; int current_angle; int current_title; @@ -84,6 +85,8 @@ static void bluray_stream_close(stream_t *s) { struct bluray_priv_s *b = s->priv; + if (b->title_info) + bd_free_title_info(b->title_info); bd_close(b->bd); } @@ -101,7 +104,31 @@ static int bluray_stream_seek(stream_t *s, int64_t pos) static void handle_event(stream_t *s, const BD_EVENT *ev) { + struct bluray_priv_s *b = s->priv; switch (ev->event) { + case BD_EVENT_TITLE: + if (ev->param == BLURAY_TITLE_FIRST_PLAY) + b->current_title = bd_get_current_title(b->bd); + else + b->current_title = ev->param; + if (b->title_info) { + bd_free_title_info(b->title_info); + b->title_info = NULL; + } + b->title_info = bd_get_title_info(b->bd, b->current_title, + b->current_angle); + break; + case BD_EVENT_ANGLE: + b->current_angle = ev->param; + if (b->title_info) { + bd_free_title_info(b->title_info); + b->title_info = bd_get_title_info(b->bd, b->current_title, + b->current_angle); + } + break; + case BD_EVENT_IDLE: + mp_sleep_us(5000); + break; default: MP_TRACE(s, "Unhandled event: %d %d\n", ev->event, ev->param); break; @@ -125,31 +152,27 @@ static int bluray_stream_control(stream_t *s, int cmd, void *arg) switch (cmd) { case STREAM_CTRL_GET_NUM_CHAPTERS: { - BLURAY_TITLE_INFO *ti; + const BLURAY_TITLE_INFO *ti = b->title_info; - ti = bd_get_title_info(b->bd, b->current_title, b->current_angle); if (!ti) return STREAM_UNSUPPORTED; *((unsigned int *) arg) = ti->chapter_count; - bd_free_title_info(ti); return 1; } case STREAM_CTRL_GET_CHAPTER_TIME: { - BLURAY_TITLE_INFO *ti; + const BLURAY_TITLE_INFO *ti = b->title_info; int chapter = *(double *)arg; double time = MP_NOPTS_VALUE; - ti = bd_get_title_info(b->bd, b->current_title, b->current_angle); if (!ti) return STREAM_UNSUPPORTED; if (chapter >= 0 || chapter < ti->chapter_count) { time = BD_TIME_TO_MP(ti->chapters[chapter].start); } - bd_free_title_info(ti); if (time != MP_NOPTS_VALUE) { *(double *)arg = time; @@ -175,14 +198,12 @@ static int bluray_stream_control(stream_t *s, int cmd, void *arg) } case STREAM_CTRL_GET_TIME_LENGTH: { - BLURAY_TITLE_INFO *ti; + const BLURAY_TITLE_INFO *ti = b->title_info; - ti = bd_get_title_info(b->bd, b->current_title, b->current_angle); if (!ti) return STREAM_UNSUPPORTED; *((double *) arg) = BD_TIME_TO_MP(ti->duration); - bd_free_title_info(ti); return STREAM_OK; } @@ -201,14 +222,12 @@ static int bluray_stream_control(stream_t *s, int cmd, void *arg) } case STREAM_CTRL_GET_NUM_ANGLES: { - BLURAY_TITLE_INFO *ti; + const BLURAY_TITLE_INFO *ti = b->title_info; - ti = bd_get_title_info(b->bd, b->current_title, b->current_angle); if (!ti) return STREAM_UNSUPPORTED; *((int *) arg) = ti->angle_count; - bd_free_title_info(ti); return 1; } @@ -219,29 +238,26 @@ static int bluray_stream_control(stream_t *s, int cmd, void *arg) } case STREAM_CTRL_SET_ANGLE: { - BLURAY_TITLE_INFO *ti; + const BLURAY_TITLE_INFO *ti = b->title_info; int angle = *((int *) arg); - ti = bd_get_title_info(b->bd, b->current_title, b->current_angle); if (!ti) return STREAM_UNSUPPORTED; if (angle < 0 || angle > ti->angle_count) { - bd_free_title_info(ti); return STREAM_UNSUPPORTED; } b->current_angle = angle; bd_seamless_angle_change(b->bd, angle); - bd_free_title_info(ti); return 1; } case STREAM_CTRL_GET_LANG: { struct stream_lang_req *req = arg; - BLURAY_TITLE_INFO *ti = bd_get_title_info(b->bd, b->current_title, b->current_angle); - if (ti->clip_count) { + const BLURAY_TITLE_INFO *ti = b->title_info; + if (ti && ti->clip_count) { BLURAY_STREAM_INFO *si = NULL; int count = 0; switch (req->type) { @@ -258,12 +274,10 @@ static int bluray_stream_control(stream_t *s, int cmd, void *arg) BLURAY_STREAM_INFO *i = &si[n]; if (i->pid == req->id) { snprintf(req->name, sizeof(req->name), "%.4s", i->lang); - bd_free_title_info(ti); return STREAM_OK; } } } - bd_free_title_info(ti); return STREAM_ERROR; } case STREAM_CTRL_GET_START_TIME: -- cgit v1.2.3