changeset 31574:1d31cd52aa08

Implement slave mode compatible stream controls for Blu-ray. Added stream controls: get/set for chapters and angles.
author ben
date Mon, 05 Jul 2010 20:52:47 +0000
parents 8104d7a99bda
children c90f270458ae
files stream/stream_bluray.c
diffstat 1 files changed, 119 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/stream/stream_bluray.c	Mon Jul 05 19:45:14 2010 +0000
+++ b/stream/stream_bluray.c	Mon Jul 05 20:52:47 2010 +0000
@@ -50,6 +50,13 @@
 int   bluray_angle   = 0;
 int   bluray_chapter = 0;
 
+struct bluray_priv_s {
+    BLURAY *bd;
+    int current_angle;
+    int current_chapter;
+    int current_title;
+};
+
 static struct stream_priv_s {
     int title;
     char *device;
@@ -74,15 +81,19 @@
 
 static void bluray_stream_close(stream_t *s)
 {
-    bd_close(s->priv);
-    s->priv = NULL;
+    struct bluray_priv_s *b = s->priv;
+
+    bd_close(b->bd);
+    b->bd = NULL;
+    free(b);
 }
 
 static int bluray_stream_seek(stream_t *s, off_t pos)
 {
+    struct bluray_priv_s *b = s->priv;
     off_t p;
 
-    p = bd_seek(s->priv, pos);
+    p = bd_seek(b->bd, pos);
     if (p == -1)
         return 0;
 
@@ -92,20 +103,115 @@
 
 static int bluray_stream_fill_buffer(stream_t *s, char *buf, int len)
 {
-    return bd_read(s->priv, buf, len);
+    struct bluray_priv_s *b = s->priv;
+
+    return bd_read(b->bd, buf, len);
+}
+
+static int bluray_stream_control(stream_t *s, int cmd, void *arg)
+{
+    struct bluray_priv_s *b = s->priv;
+
+    switch (cmd) {
+
+    case STREAM_CTRL_GET_NUM_CHAPTERS: {
+        BLURAY_TITLE_INFO *ti;
+
+        ti = bd_get_title_info(b->bd, b->current_title);
+        if (!ti)
+            return STREAM_UNSUPPORTED;
+
+        *((unsigned int *) arg) = ti->chapter_count;
+        bd_free_title_info(ti);
+
+        return 1;
+    }
+
+    case STREAM_CTRL_GET_CURRENT_CHAPTER: {
+        *((unsigned int *) arg) = b->current_chapter;
+        return 1;
+    }
+
+    case STREAM_CTRL_SEEK_TO_CHAPTER: {
+        BLURAY_TITLE_INFO *ti;
+        int chapter = *((unsigned int *) arg);
+        int64_t pos;
+        int r;
+
+        ti = bd_get_title_info(b->bd, b->current_title);
+        if (!ti)
+            return STREAM_UNSUPPORTED;
+
+        if (chapter < 0 || chapter > ti->chapter_count) {
+            bd_free_title_info(ti);
+            return STREAM_UNSUPPORTED;
+        }
+
+        pos = bd_chapter_pos(b->bd, chapter);
+        r = bluray_stream_seek(s, pos);
+        bd_free_title_info(ti);
+
+        return r ? 1 : STREAM_UNSUPPORTED;
+    }
+
+    case STREAM_CTRL_GET_NUM_ANGLES: {
+        BLURAY_TITLE_INFO *ti;
+
+        ti = bd_get_title_info(b->bd, b->current_title);
+        if (!ti)
+            return STREAM_UNSUPPORTED;
+
+        *((int *) arg) = ti->angle_count;
+        bd_free_title_info(ti);
+
+        return 1;
+    }
+
+    case STREAM_CTRL_GET_ANGLE: {
+        *((int *) arg) = b->current_angle;
+        return 1;
+    }
+
+    case STREAM_CTRL_SET_ANGLE: {
+        BLURAY_TITLE_INFO *ti;
+        int angle = *((int *) arg);
+
+        ti = bd_get_title_info(b->bd, b->current_title);
+        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;
+    }
+
+    default:
+        break;
+    }
+
+    return STREAM_UNSUPPORTED;
 }
 
 static int bluray_stream_open(stream_t *s, int mode,
                               void *opts, int *file_format)
 {
     struct stream_priv_s *p = opts;
+    struct bluray_priv_s *b;
+
     BLURAY_TITLE_INFO *info = NULL;
     BLURAY *bd;
 
     int title, title_guess, title_count;
     uint64_t title_size;
 
-    unsigned int chapter, angle;
+    unsigned int chapter = 0, angle = 0;
     uint64_t max_duration = 0;
     int64_t chapter_pos = 0;
 
@@ -208,12 +314,19 @@
     s->fill_buffer = bluray_stream_fill_buffer;
     s->seek        = bluray_stream_seek;
     s->close       = bluray_stream_close;
+    s->control     = bluray_stream_control;
+
+    b                  = calloc(1, sizeof(struct bluray_priv_s));
+    b->bd              = bd;
+    b->current_angle   = angle;
+    b->current_chapter = chapter;
+    b->current_title   = title;
 
     s->start_pos   = chapter_pos;
     s->end_pos     = title_size;
     s->sector_size = BLURAY_SECTOR_SIZE;
     s->flags       = mode | MP_STREAM_SEEK;
-    s->priv        = bd;
+    s->priv        = b;
     s->type        = STREAMTYPE_BLURAY;
     s->url         = strdup("br://");