[libbluray-devel] Add bd_open_stream()
hpi1
git at videolan.org
Fri Mar 20 14:10:35 CET 2015
libbluray | branch: master | hpi1 <hpi1 at anonymous.org> | Fri Mar 20 14:46:46 2015 +0200| [e014d4548716b3300a7989fbe211405a15f9ebf5] | committer: hpi1
Add bd_open_stream()
> http://git.videolan.org/gitweb.cgi/libbluray.git/?a=commit;h=e014d4548716b3300a7989fbe211405a15f9ebf5
---
ChangeLog | 1 +
src/libbluray/bluray.c | 34 +++++++++++++++++++++-------
src/libbluray/bluray.h | 12 ++++++++++
src/libbluray/disc/disc.c | 6 +++--
src/libbluray/disc/disc.h | 2 ++
src/libbluray/disc/udf_fs.c | 52 +++++++++++++++++++++++++++++++++++++++++--
src/libbluray/disc/udf_fs.h | 4 +++-
7 files changed, 98 insertions(+), 13 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 7848838..9dc2029 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,6 @@
- Add support for UDF image files and unmounted discs.
- Add UDF volume identifier to DISC_INFO.
+- Add bd_init() and bd_open_disc() and bd_open_stream().
- Fix infinite loop with some broken HDMV menus.
- Emit BD_EVENT_PLAYLIST_STOP when playlist playback is stopped in middle.
- Accept directory name (without .jar file name) in LIBBLURAY_CP.
diff --git a/src/libbluray/bluray.c b/src/libbluray/bluray.c
index 738c0ec..3986ece 100644
--- a/src/libbluray/bluray.c
+++ b/src/libbluray/bluray.c
@@ -1303,25 +1303,22 @@ BLURAY *bd_init(void)
return bd;
}
-int bd_open_disc(BLURAY *bd, const char *device_path, const char *keyfile_path)
+static int _bd_open(BLURAY *bd,
+ const char *device_path, const char *keyfile_path,
+ void *read_blocks_handle,
+ int (*read_blocks)(void *handle, void *buf, int lba, int num_blocks))
{
BD_ENC_INFO enc_info;
if (!bd) {
return 0;
}
-
- if (!device_path) {
- BD_DEBUG(DBG_BLURAY | DBG_CRIT, "No device path provided!\n");
- return 0;
- }
-
if (bd->disc) {
BD_DEBUG(DBG_BLURAY | DBG_CRIT, "Disc already open\n");
return 0;
}
- bd->disc = disc_open(device_path,
+ bd->disc = disc_open(device_path, read_blocks_handle, read_blocks,
&enc_info, keyfile_path,
(void*)bd->regs, (void*)bd_psr_read, (void*)bd_psr_write);
@@ -1334,6 +1331,27 @@ int bd_open_disc(BLURAY *bd, const char *device_path, const char *keyfile_path)
return bd->disc_info.bluray_detected;
}
+int bd_open_disc(BLURAY *bd, const char *device_path, const char *keyfile_path)
+{
+ if (!device_path) {
+ BD_DEBUG(DBG_BLURAY | DBG_CRIT, "No device path provided!\n");
+ return 0;
+ }
+
+ return _bd_open(bd, device_path, keyfile_path, NULL, NULL);
+}
+
+int bd_open_stream(BLURAY *bd,
+ void *read_blocks_handle,
+ int (*read_blocks)(void *handle, void *buf, int lba, int num_blocks))
+{
+ if (!read_blocks) {
+ return 0;
+ }
+
+ return _bd_open(bd, NULL, NULL, read_blocks_handle, read_blocks);
+}
+
BLURAY *bd_open(const char *device_path, const char *keyfile_path)
{
BLURAY *bd;
diff --git a/src/libbluray/bluray.h b/src/libbluray/bluray.h
index c4e4b9d..3b71b8e 100644
--- a/src/libbluray/bluray.h
+++ b/src/libbluray/bluray.h
@@ -320,6 +320,18 @@ BLURAY *bd_init(void);
int bd_open_disc(BLURAY *bd, const char *device_path, const char *keyfile_path);
/**
+ * Open BluRay disc
+ *
+ * @param bd BLURAY object
+ * @param handle opaque handle for read_blocks
+ * @param read_blocks function used to read disc blocks
+ * @return 1 on success, 0 if error
+ */
+int bd_open_stream(BLURAY *bd,
+ void *read_blocks_handle,
+ int (*read_blocks)(void *handle, void *buf, int lba, int num_blocks));
+
+/**
* Close BluRay disc
*
* @param bd BLURAY object
diff --git a/src/libbluray/disc/disc.c b/src/libbluray/disc/disc.c
index 2c904d0..f6a6fda 100644
--- a/src/libbluray/disc/disc.c
+++ b/src/libbluray/disc/disc.c
@@ -231,6 +231,8 @@ static void _set_paths(BD_DISC *p, const char *device_path)
}
BD_DISC *disc_open(const char *device_path,
+ void *read_blocks_handle,
+ int (*read_blocks)(void *handle, void *buf, int lba, int num_blocks),
struct bd_enc_info *enc_info,
const char *keyfile_path,
void *regs, void *psr_read, void *psr_write)
@@ -242,9 +244,9 @@ BD_DISC *disc_open(const char *device_path,
#ifdef ENABLE_UDF
/* check if disc root directory can be opened. If not, treat it as device/image file. */
- BD_DIR_H *dp_img = dir_open(device_path);
+ BD_DIR_H *dp_img = device_path ? dir_open(device_path) : NULL;
if (!dp_img) {
- void *udf = udf_image_open(device_path);
+ void *udf = udf_image_open(device_path, read_blocks_handle, read_blocks);
if (!udf) {
BD_DEBUG(DBG_FILE | DBG_CRIT, "failed opening UDF image %s\n", device_path);
} else {
diff --git a/src/libbluray/disc/disc.h b/src/libbluray/disc/disc.h
index d1a0162..f005d82 100644
--- a/src/libbluray/disc/disc.h
+++ b/src/libbluray/disc/disc.h
@@ -38,6 +38,8 @@ struct bd_enc_info;
typedef struct bd_disc BD_DISC;
BD_PRIVATE BD_DISC *disc_open(const char *device_path,
+ void *read_blocks_handle,
+ int (*read_blocks)(void *handle, void *buf, int lba, int num_blocks),
struct bd_enc_info *enc_info,
const char *keyfile_path,
void *regs, void *psr_read, void *psr_write);
diff --git a/src/libbluray/disc/udf_fs.c b/src/libbluray/disc/udf_fs.c
index 12c54b5..1eec761 100644
--- a/src/libbluray/disc/udf_fs.c
+++ b/src/libbluray/disc/udf_fs.c
@@ -196,7 +196,43 @@ static struct udfread_block_input *_block_input(const char *img)
}
-void *udf_image_open(const char *img_path)
+typedef struct {
+ struct udfread_block_input i;
+ void *read_block_handle;
+ int (*read_blocks)(void *handle, void *buf, int lba, int num_blocks);
+} UDF_SI;
+
+static int _si_close(struct udfread_block_input *bi_gen)
+{
+ free(bi_gen);
+ return 0;
+}
+
+static int _si_read(struct udfread_block_input *bi_gen, uint32_t lba, void *buf, uint32_t nblocks, int flags)
+{
+ (void)flags;
+ UDF_SI *si = (UDF_SI *)bi_gen;
+ return si->read_blocks(si->read_block_handle, buf, lba, nblocks);
+}
+
+static struct udfread_block_input *_stream_input(void *read_block_handle,
+ int (*read_blocks)(void *handle, void *buf, int lba, int num_blocks))
+{
+ UDF_SI *si = calloc(1, sizeof(*si));
+ if (si) {
+ si->read_block_handle = read_block_handle;
+ si->read_blocks = read_blocks;
+ si->i.close = _si_close;
+ si->i.read = _si_read;
+ return &si->i;
+ }
+ return NULL;
+}
+
+
+void *udf_image_open(const char *img_path,
+ void *read_block_handle,
+ int (*read_blocks)(void *handle, void *buf, int lba, int num_blocks))
{
udfread *udf = udfread_init();
int result = -1;
@@ -205,8 +241,19 @@ void *udf_image_open(const char *img_path)
return NULL;
}
+ /* stream ? */
+ if (read_blocks) {
+ struct udfread_block_input *si = _stream_input(read_block_handle, read_blocks);
+ if (si) {
+ result = udfread_open_input(udf, si);
+ if (result < 0) {
+ si->close(si);
+ }
+ }
+ } else {
+
/* app handles file I/O ? */
- if (file_open != file_open_default()) {
+ if (result < 0 && file_open != file_open_default()) {
struct udfread_block_input *bi = _block_input(img_path);
if (bi) {
result = udfread_open_input(udf, bi);
@@ -219,6 +266,7 @@ void *udf_image_open(const char *img_path)
if (result < 0) {
result = udfread_open(udf, img_path);
}
+ }
if (result < 0) {
udfread_close(udf);
diff --git a/src/libbluray/disc/udf_fs.h b/src/libbluray/disc/udf_fs.h
index 4b40a27..87b17cf 100644
--- a/src/libbluray/disc/udf_fs.h
+++ b/src/libbluray/disc/udf_fs.h
@@ -25,7 +25,9 @@
struct bd_file_s;
struct bd_dir_s;
-BD_PRIVATE void *udf_image_open(const char *img_path);
+BD_PRIVATE void *udf_image_open(const char *img_path,
+ void *read_block_handle,
+ int (*read_blocks)(void *handle, void *buf, int lba, int num_blocks));
BD_PRIVATE void udf_image_close(void *udf);
BD_PRIVATE const char *udf_volume_id(void *udf);
More information about the libbluray-devel
mailing list