[libbluray-devel] [Git][videolan/libbluray][master] 4 commits: Export chapter name metadata present on some discs

Petri Hintukainen (@hpi) gitlab at videolan.org
Tue Jul 14 17:32:56 UTC 2026



Petri Hintukainen pushed to branch master at VideoLAN / libbluray


Commits:
6129856e by hpi1 at 2026-07-14T18:03:47+03:00
Export chapter name metadata present on some discs

- - - - -
4bba86dc by Petri Hintukainen at 2026-07-14T18:03:49+03:00
Move uo restriction level enum to player_settings.h

(other player settings are there)

- - - - -
0cceceea by Petri Hintukainen at 2026-07-14T18:03:49+03:00
overlay: allocate slot for background plane

- - - - -
e215022d by Petri Hintukainen at 2026-07-14T20:29:56+03:00
Bump .so version

- - - - -


6 changed files:

- meson.build
- src/libbluray/bluray.c
- src/libbluray/bluray.h
- src/libbluray/decoders/overlay.h
- src/libbluray/player_settings.h
- src/tools/bd_list_titles.c


Changes:

=====================================
meson.build
=====================================
@@ -23,7 +23,7 @@ add_project_arguments('-DHAVE_CONFIG_H=1', language: 'c')
 libbluray_inc_dirs = [include_directories('.', 'src', 'src/libbluray', 'src/libbluray/disc')]
 
 # The version number for the shared library
-libbluray_soname_version = '3.1.0'
+libbluray_soname_version = '4.0.0'
 
 libbluray_version = meson.project_version()
 libbluray_version_split = libbluray_version.split('.')


=====================================
src/libbluray/bluray.c
=====================================
@@ -25,6 +25,7 @@
 
 #include "bluray-version.h"
 #include "bluray.h"
+#include "player_settings.h"
 #include "bluray_internal.h"
 #include "keys.h"
 #include "register.h"
@@ -2832,11 +2833,24 @@ static int _copy_streams(const NAV_CLIP *clip, BLURAY_STREAM_INFO **pstreams,
     return 1;
 }
 
-static BLURAY_TITLE_INFO* _fill_title_info(NAV_TITLE* title, uint32_t title_idx, uint32_t playlist)
+static BLURAY_TITLE_INFO* _fill_title_info(BLURAY *bd, NAV_TITLE* title, uint32_t title_idx, uint32_t playlist)
 {
+    const struct meta_tn *meta_tn = NULL;
     BLURAY_TITLE_INFO *title_info;
     unsigned int ii;
 
+    /* fetch optional chapter names */
+    if (bd->meta) {
+        uint32_t psr_menu_lang = bd_psr_read(bd->regs, PSR_MENU_LANG);
+        if (psr_menu_lang != 0 && psr_menu_lang != 0xffffff) {
+            const char language_code[] = {(psr_menu_lang >> 16) & 0xff, (psr_menu_lang >> 8) & 0xff, psr_menu_lang & 0xff, 0 };
+            meta_tn = meta_get_tn(bd->meta, language_code, playlist);
+        }
+        if (!meta_tn) {
+            meta_tn = meta_get_tn(bd->meta, NULL, playlist);
+        }
+    }
+
     title_info = calloc(1, sizeof(BLURAY_TITLE_INFO));
     if (!title_info) {
         goto error;
@@ -2857,6 +2871,9 @@ static BLURAY_TITLE_INFO* _fill_title_info(NAV_TITLE* title, uint32_t title_idx,
             title_info->chapters[ii].duration = (uint64_t)title->chap_list.mark[ii].duration * 2;
             title_info->chapters[ii].offset = (uint64_t)title->chap_list.mark[ii].title_pkt * 192L;
             title_info->chapters[ii].clip_ref = title->chap_list.mark[ii].clip_ref;
+            if (meta_tn && ii < meta_tn->num_chapter) {
+                title_info->chapters[ii].chapter_name = meta_tn->chapter_name[ii];
+            }
         }
     }
     title_info->mark_count = title->mark_list.count;
@@ -2938,10 +2955,17 @@ static BLURAY_TITLE_INFO *_get_mpls_info(BLURAY *bd, uint32_t title_idx, uint32_
         return NULL;
     }
 
+    /* fetch metadata for optional chapter names */
+    bd_mutex_lock(&bd->mutex);
+    if (!bd->meta) {
+        bd->meta = meta_parse(bd->disc);
+    }
+    bd_mutex_unlock(&bd->mutex);
+
     /* current title ? => no need to load mpls file */
     bd_mutex_lock(&bd->mutex);
     if (bd->title && bd->title->angle == angle && !strcmp(bd->title->name, mpls_name)) {
-        title_info = _fill_title_info(bd->title, title_idx, playlist);
+        title_info = _fill_title_info(bd, bd->title, title_idx, playlist);
         bd_mutex_unlock(&bd->mutex);
         return title_info;
     }
@@ -2953,7 +2977,7 @@ static BLURAY_TITLE_INFO *_get_mpls_info(BLURAY *bd, uint32_t title_idx, uint32_
         return NULL;
     }
 
-    title_info = _fill_title_info(title, title_idx, playlist);
+    title_info = _fill_title_info(bd, title, title_idx, playlist);
 
     nav_title_close(&title);
     return title_info;
@@ -4222,9 +4246,11 @@ const struct meta_dl *bd_get_meta(BLURAY *bd)
         return NULL;
     }
 
+    bd_mutex_lock(&bd->mutex);
     if (!bd->meta) {
         bd->meta = meta_parse(bd->disc);
     }
+    bd_mutex_unlock(&bd->mutex);
 
     uint32_t psr_menu_lang = bd_psr_read(bd->regs, PSR_MENU_LANG);
 


=====================================
src/libbluray/bluray.h
=====================================
@@ -292,6 +292,9 @@ typedef struct bd_chapter {
     uint64_t    duration;  /**< duration */
     uint64_t    offset;    /**< distance from title start, bytes */
     unsigned    clip_ref;  /**< Clip reference (index to playlist clips list) */
+
+    /** Chapter name in preferred language (optional, libbluray >= 1.5.0) */
+    const char *chapter_name;
 } BLURAY_TITLE_CHAPTER;
 
 /** Playmark information */
@@ -755,14 +758,6 @@ typedef enum {
     BLURAY_PLAYER_JAVA_HOME                    = 0x202, /**< Location of JRE. String. Default: NULL (autodetect). */
 } bd_player_setting;
 
-/** Player User Operation (UO) restriction mask enforcement level. */
-typedef enum {
-    BLURAY_PLAYER_SETTING_UO_RESTRICTION_DISABLED  =  0, /**< Executes all UOs unconditionally. May break the playback. */
-    BLURAY_PLAYER_SETTING_UO_RESTRICTION_RELAXED   =  5, /**< Allows most UOs, performs some sanity checks to reduce playback issues. */
-    BLURAY_PLAYER_SETTING_UO_RESTRICTION_SAFE      = 10, /**< Mostly compliant, however allows some UOs which should not cause playback issues. */
-    BLURAY_PLAYER_SETTING_UO_RESTRICTION_COMPLIANT = 20, /**< Compliant UO restriction enforcement. */
-} bd_player_setting_uo_restriction_level;
-
 /**
  *
  *  Update player setting


=====================================
src/libbluray/decoders/overlay.h
=====================================
@@ -1,6 +1,6 @@
 /*
  * This file is part of libbluray
- * Copyright (C) 2010-2017  Petri Hintukainen <phintuka at users.sourceforge.net>
+ * Copyright (C) 2010-2026  Petri Hintukainen <phintuka at users.sourceforge.net>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -38,7 +38,7 @@ extern "C" {
 #endif
 
 /** Version number of the interface described in this file. */
-#define BD_OVERLAY_INTERFACE_VERSION 2
+#define BD_OVERLAY_INTERFACE_VERSION 3
 
 /**
  * Overlay plane
@@ -46,6 +46,7 @@ extern "C" {
 typedef enum {
     BD_OVERLAY_PG = 0,  /**< Presentation Graphics plane */
     BD_OVERLAY_IG = 1,  /**< Interactive Graphics plane (on top of PG plane) */
+    BD_OVERLAY_BG = 2,  /**< Background Graphics plane (behind video). Since libbluray 1.5.0. */
 } bd_overlay_plane_e;
 
 /*
@@ -212,7 +213,7 @@ typedef struct bd_argb_buffer_s {
      * - buffer can be replaced in overlay callback or lock().
      */
 
-    uint32_t *buf[4]; /**< [0] - PG plane, [1] - IG plane. [2], [3] reserved for stereoscopic overlay. */
+    uint32_t *buf[6]; /**< [0] - PG plane, [1] - IG plane, [2] - Background plane. [3..5] reserved for stereoscopic overlay. */
 
     /* size of buffers
      * - Set by application
@@ -231,7 +232,7 @@ typedef struct bd_argb_buffer_s {
         uint16_t y0; /**< top-left y coordinate */
         uint16_t x1; /**< bottom-down x coordinate  */
         uint16_t y1; /**< bottom-down y coordinate */
-    } dirty[2]; /**< [0] - PG plane, [1] - IG plane */
+    } dirty[3]; /**< [0] - PG plane, [1] - IG plane, [2] - Background plane */
 
 } BD_ARGB_BUFFER;
 


=====================================
src/libbluray/player_settings.h
=====================================
@@ -192,4 +192,19 @@ enum {
     BLURAY_PERSISTENT_STORAGE_ENABLE  = 1,  /**< enable persistent storage */
 };
 
+/**
+ * BLURAY_PLAYER_SETTING_UO_RESTRICTION_LEVEL
+ *
+ * User Operations (UO) restriction mask enforcement level.
+ *
+ */
+
+typedef enum {
+    BLURAY_PLAYER_SETTING_UO_RESTRICTION_DISABLED  =  0, /**< Executes all UOs unconditionally. May break the playback. */
+    BLURAY_PLAYER_SETTING_UO_RESTRICTION_RELAXED   =  5, /**< Allows most UOs, performs some sanity checks to reduce playback issues. */
+    BLURAY_PLAYER_SETTING_UO_RESTRICTION_SAFE      = 10, /**< Mostly compliant, however allows some UOs which should not cause playback issues. */
+    BLURAY_PLAYER_SETTING_UO_RESTRICTION_COMPLIANT = 20, /**< Compliant UO restriction enforcement. */
+} bd_player_setting_uo_restriction_level;
+
+
 #endif /* BD_PLAYER_SETTINGS_H_ */


=====================================
src/tools/bd_list_titles.c
=====================================
@@ -24,7 +24,7 @@
 #include <inttypes.h>
 #include <unistd.h>
 
-#define OPTS "ahs:l"
+#define OPTS "achs:l"
 
 static void _usage(char *cmd)
 {
@@ -34,12 +34,23 @@ static void _usage(char *cmd)
 "   -s #    - Filter out titles shorter than # seconds\n"
 "   -a      - List all titles\n"
 "   -l      - Show language codes\n"
+"   -c      - Show optional chapter names\n"
 "   -h      - This message\n",
         cmd
     );
     exit(EXIT_FAILURE);
 }
 
+static void _dump_chap_names(const BLURAY_TITLE_INFO *ti)
+{
+    unsigned ii;
+    for (ii = 0; ii < ti->chapter_count; ii++) {
+        if (ti->chapters[ii].chapter_name) {
+            printf("\tChapter %2d: %s\n", ii + 1, ti->chapters[ii].chapter_name);
+        }
+    }
+}
+
 static void _print_langs(const char *tag, const BLURAY_STREAM_INFO *si, int count)
 {
     int ii;
@@ -64,7 +75,7 @@ int main(int argc, char *argv[])
 {
     BLURAY *bd;
     int count, ii, opt, main_title;
-    unsigned int seconds = 0, langs = 0;
+    unsigned int seconds = 0, langs = 0, chapter_names = 0;
     unsigned int flags = TITLES_RELEVANT;
     char *bd_dir = NULL;
 
@@ -90,6 +101,9 @@ int main(int argc, char *argv[])
             case 'l':
                 langs = 1;
                 break;
+            case 'c':
+                chapter_names = 1;
+                break;
             case 'h':
             default:
                 _usage(argv[0]);
@@ -134,6 +148,9 @@ int main(int argc, char *argv[])
         if (langs) {
             _dump_langs(&ti->clips[0]);
         }
+        if (chapter_names) {
+            _dump_chap_names(ti);
+        }
         bd_free_title_info(ti);
     }
     bd_close(bd);



View it on GitLab: https://code.videolan.org/videolan/libbluray/-/compare/8b4fb6e2562bb86601ea5a2c4140af6d8f3f1cf4...e215022df5375bbc5364ee30ee3222961c246021

-- 
View it on GitLab: https://code.videolan.org/videolan/libbluray/-/compare/8b4fb6e2562bb86601ea5a2c4140af6d8f3f1cf4...e215022df5375bbc5364ee30ee3222961c246021
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help




More information about the libbluray-devel mailing list