mirror of https://github.com/mpv-player/mpv
stream_bluray: allow opening BDMV directories directly
Similar as the previous commits. Most of the code is actually copied from the stream_dvdnav.c code, but I'd rather prefer to duplicate it, than to entangle them. The latter would probably result in terrible things in a few years.
This commit is contained in:
parent
c3f7773138
commit
d6c27855d7
|
@ -68,6 +68,7 @@ extern const stream_info_t stream_info_ifo;
|
||||||
extern const stream_info_t stream_info_ifo_dvdnav;
|
extern const stream_info_t stream_info_ifo_dvdnav;
|
||||||
extern const stream_info_t stream_info_dvd;
|
extern const stream_info_t stream_info_dvd;
|
||||||
extern const stream_info_t stream_info_dvdnav;
|
extern const stream_info_t stream_info_dvdnav;
|
||||||
|
extern const stream_info_t stream_info_bdmv_dir;
|
||||||
extern const stream_info_t stream_info_bluray;
|
extern const stream_info_t stream_info_bluray;
|
||||||
extern const stream_info_t stream_info_bdnav;
|
extern const stream_info_t stream_info_bdnav;
|
||||||
extern const stream_info_t stream_info_rar_filter;
|
extern const stream_info_t stream_info_rar_filter;
|
||||||
|
@ -102,6 +103,7 @@ static const stream_info_t *const stream_list[] = {
|
||||||
&stream_info_dvdnav,
|
&stream_info_dvdnav,
|
||||||
#endif
|
#endif
|
||||||
#if HAVE_LIBBLURAY
|
#if HAVE_LIBBLURAY
|
||||||
|
&stream_info_bdmv_dir,
|
||||||
&stream_info_bluray,
|
&stream_info_bluray,
|
||||||
&stream_info_bdnav,
|
&stream_info_bdnav,
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include <libbluray/bluray.h>
|
#include <libbluray/bluray.h>
|
||||||
|
@ -43,6 +44,7 @@
|
||||||
#include "common/msg.h"
|
#include "common/msg.h"
|
||||||
#include "options/m_option.h"
|
#include "options/m_option.h"
|
||||||
#include "options/options.h"
|
#include "options/options.h"
|
||||||
|
#include "options/path.h"
|
||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
#include "osdep/timer.h"
|
#include "osdep/timer.h"
|
||||||
#include "discnav.h"
|
#include "discnav.h"
|
||||||
|
@ -829,3 +831,87 @@ const stream_info_t stream_info_bdnav = {
|
||||||
NULL
|
NULL
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool check_bdmv(const char *path)
|
||||||
|
{
|
||||||
|
if (strcasecmp(mp_basename(path), "MovieObject.bdmv"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
FILE *temp = fopen(path, "rb");
|
||||||
|
if (!temp)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool r = false;
|
||||||
|
|
||||||
|
const char *sig = "MOBJ020";
|
||||||
|
char data[50];
|
||||||
|
|
||||||
|
if (fread(data, 50, 1, temp) == 1) {
|
||||||
|
if (memcmp(data, sig, strlen(sig)) == 0)
|
||||||
|
r = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(temp);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destructively remove the current trailing path component.
|
||||||
|
static void remove_prefix(char *path)
|
||||||
|
{
|
||||||
|
size_t len = strlen(path);
|
||||||
|
#if HAVE_DOS_PATHS
|
||||||
|
const char *seps = "/\\";
|
||||||
|
#else
|
||||||
|
const char *seps = "/";
|
||||||
|
#endif
|
||||||
|
while (len > 0 && !strchr(seps, path[len - 1]))
|
||||||
|
len--;
|
||||||
|
while (len > 0 && strchr(seps, path[len - 1]))
|
||||||
|
len--;
|
||||||
|
path[len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bdmv_dir_stream_open(stream_t *stream)
|
||||||
|
{
|
||||||
|
struct bluray_priv_s *priv = talloc_ptrtype(stream, priv);
|
||||||
|
stream->priv = priv;
|
||||||
|
*priv = bluray_stream_priv_dflts;
|
||||||
|
|
||||||
|
char *path = mp_file_get_path(priv, bstr0(stream->url));
|
||||||
|
if (!path)
|
||||||
|
goto unsupported;
|
||||||
|
|
||||||
|
// We allow the path to point to a directory containing BDMV/, a
|
||||||
|
// directory containing MovieObject.bdmv, or that file itself.
|
||||||
|
if (!check_bdmv(path)) {
|
||||||
|
// On UNIX, just assume the filename has always this case.
|
||||||
|
char *npath = mp_path_join(priv, bstr0(path), bstr0("MovieObject.bdmv"));
|
||||||
|
if (!check_bdmv(npath)) {
|
||||||
|
npath = mp_path_join(priv, bstr0(path), bstr0("BDMV/MovieObject.bdmv"));
|
||||||
|
if (!check_bdmv(npath))
|
||||||
|
goto unsupported;
|
||||||
|
}
|
||||||
|
path = npath;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go up by 2 levels.
|
||||||
|
remove_prefix(path);
|
||||||
|
remove_prefix(path);
|
||||||
|
priv->cfg_device = path;
|
||||||
|
if (strlen(priv->cfg_device) <= 1)
|
||||||
|
goto unsupported;
|
||||||
|
|
||||||
|
MP_INFO(stream, "BDMV detected. Redirecting to bluray://\n");
|
||||||
|
return bluray_stream_open(stream);
|
||||||
|
|
||||||
|
unsupported:
|
||||||
|
talloc_free(priv);
|
||||||
|
stream->priv = NULL;
|
||||||
|
return STREAM_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
const stream_info_t stream_info_bdmv_dir = {
|
||||||
|
.name = "bdmv/bluray",
|
||||||
|
.open = bdmv_dir_stream_open,
|
||||||
|
.protocols = (const char*const[]){ "file", "", NULL },
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue