libbluray | branch: master | hpi1 <h...@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); _______________________________________________ libbluray-devel mailing list libbluray-devel@videolan.org https://mailman.videolan.org/listinfo/libbluray-devel