39#include "libbluray/bluray.h"
40#include "libbluray/bluray-version.h"
43#include <libavutil/rational.h>
46static bool audio_stream_info(
const std::string &path, BLURAY_STREAM_INFO *ss,
int *channels,
int *sample_rate);
47static bool video_stream_info(
const std::string &path, BLURAY_STREAM_INFO *ss,
int *width,
int *height, AVRational *framerate,
bool *interleaved);
50static bool create_bluray_virtualfile(
BLURAY *bd,
const BLURAY_TITLE_INFO* ti,
const std::string & path,
const struct stat * statbuf,
void * buf, fuse_fill_dir_t filler,
bool is_main_title,
bool full_title, uint32_t title_idx, uint32_t chapter_idx);
51static int parse_bluray(
const std::string & path,
const struct stat *statbuf,
void *buf, fuse_fill_dir_t filler);
61static bool audio_stream_info(
const std::string & path, BLURAY_STREAM_INFO *ss,
int *channels,
int *sample_rate)
65 switch (ss->coding_type)
91 case BLURAY_AUDIO_FORMAT_MONO:
96 case BLURAY_AUDIO_FORMAT_STEREO:
101 case BLURAY_AUDIO_FORMAT_MULTI_CHAN:
106 case BLURAY_AUDIO_FORMAT_COMBO:
113 Logging::error(path,
"Unknown number of audio channels %1. Assuming 2 channel/stereo - may be totally wrong.", ss->format);
121 case BLURAY_AUDIO_RATE_48:
123 *sample_rate = 48000;
126 case BLURAY_AUDIO_RATE_96:
128 *sample_rate = 96000;
131 case BLURAY_AUDIO_RATE_192:
133 *sample_rate = 192000;
138 case BLURAY_AUDIO_RATE_192_COMBO:
145 case BLURAY_AUDIO_RATE_96_COMBO:
152 Logging::error(path,
"Unknown audio sample rate %1. Assuming 48 kHz - may be totally wrong.", ss->rate);
153 *sample_rate = 48000;
175 Logging::error(path,
"Unrecognised coding type %<02x>1.", ss->coding_type);
193static bool video_stream_info(
const std::string & path, BLURAY_STREAM_INFO *ss,
int *width,
int *height, AVRational *framerate,
bool *interleaved)
197 switch (ss->coding_type)
243 case BLURAY_VIDEO_FORMAT_480I:
250 case BLURAY_VIDEO_FORMAT_576I:
257 case BLURAY_VIDEO_FORMAT_480P:
261 *interleaved =
false;
264 case BLURAY_VIDEO_FORMAT_1080I:
271 case BLURAY_VIDEO_FORMAT_720P:
275 *interleaved =
false;
278 case BLURAY_VIDEO_FORMAT_1080P:
282 *interleaved =
false;
285 case BLURAY_VIDEO_FORMAT_576P:
289 *interleaved =
false;
294#if (BLURAY_VERSION_MAJOR > 1 || (BLURAY_VERSION_MAJOR == 1 && BLURAY_VERSION_MINOR >= 1))
295 case BLURAY_VIDEO_FORMAT_2160P:
299 *interleaved =
false;
305 Logging::error(path,
"Unknown video format %1. Assuming 1920x1080P - may be totally wrong.", ss->format);
308 *interleaved =
false;
315 case BLURAY_VIDEO_RATE_24000_1001:
317 *framerate = av_make_q(24000, 1001);
320 case BLURAY_VIDEO_RATE_24:
322 *framerate = av_make_q(24000, 1000);
325 case BLURAY_VIDEO_RATE_25:
327 *framerate = av_make_q(25000, 1000);
330 case BLURAY_VIDEO_RATE_30000_1001:
332 *framerate = av_make_q(30000, 1001);
335 case BLURAY_VIDEO_RATE_50:
337 *framerate = av_make_q(50000, 1000);
340 case BLURAY_VIDEO_RATE_60000_1001:
342 *framerate = av_make_q(60000, 1001);
347 Logging::error(path,
"Unknown video frame rate %1. Assuming 25 fps - may be totally wrong.", ss->rate);
348 *framerate = av_make_q(25000, 1000);
385 Logging::error(path,
"Unrecognised coding type %<02x>1.", ss->coding_type);
432static bool create_bluray_virtualfile(
BLURAY *bd,
const BLURAY_TITLE_INFO* ti,
const std::string & path,
const struct stat * statbuf,
void * buf, fuse_fill_dir_t filler,
bool is_main_title,
bool full_title, uint32_t title_idx, uint32_t chapter_idx)
434 BLURAY_CLIP_INFO *clip = &ti->clips[0];
435 BLURAY_TITLE_CHAPTER *chapter = &ti->chapters[chapter_idx];
436 std::string title_buf;
441 duration =
static_cast<int64_t
>(ti->duration) * AV_TIME_BASE / 90000;
443 if (duration < AV_TIME_BASE)
445 Logging::trace(path,
"Title %1: skipping empty title.", title_idx + 1);
449 strsprintf(&title_buf,
"%02u. Title [%s]%s.%s",
452 is_main_title ?
"+" :
"",
457 duration =
static_cast<int64_t
>(chapter->duration) * AV_TIME_BASE / 90000;
459 if (duration < AV_TIME_BASE)
461 Logging::trace(path,
"Title %1 Chapter %2: skipping empty chapter.", title_idx + 1, chapter_idx + 1);
465 strsprintf(&title_buf,
"%02u. Chapter %03u [%s]%s.%s",
469 is_main_title ?
"+" :
"",
484 if (virtualfile ==
nullptr)
486 Logging::error(path,
"Failed to create virtual path: %1", (path + title_buf).c_str());
507 BITRATE video_bit_rate = 29*1024*1024;
508 BITRATE audio_bit_rate = 256*1024;
512 bool interleaved =
false;
514 if (!bd_select_title(bd, title_idx))
516 Logging::error(path,
"The Blu-ray title %1 could not be opened.", title_idx);
521 uint64_t size = bd_get_title_size(bd);
532 video_bit_rate =
static_cast<BITRATE>(size * 8LL * AV_TIME_BASE /
static_cast<uint64_t
>(duration));
536 if (clip->audio_stream_count)
540 if (clip->video_stream_count)
551 transcoder_set_filesize(virtualfile, duration, audio_bit_rate, virtualfile->
m_channels, virtualfile->
m_sample_rate, AV_SAMPLE_FMT_NONE, video_bit_rate, virtualfile->
m_width, virtualfile->
m_height, interleaved, virtualfile->
m_framerate);
568static int parse_bluray(
const std::string & path,
const struct stat * statbuf,
void * buf, fuse_fill_dir_t filler)
571 uint32_t title_count;
573 unsigned int seconds = 0;
574 uint8_t flags = TITLES_RELEVANT;
575 const char *bd_dir =
nullptr;
578 bd_dir = path.c_str();
582 bd = bd_open(bd_dir,
nullptr);
584 title_count = bd_get_titles(bd, flags, seconds);
585 main_title = bd_get_main_title(bd);
591 for (uint32_t title_idx = 0; title_idx < title_count && success; title_idx++)
593 BLURAY_TITLE_INFO* ti = bd_get_title_info(bd, title_idx, 0);
594 bool is_main_title = (main_title >= 0 && title_idx ==
static_cast<uint32_t
>(main_title));
597 for (uint32_t chapter_idx = 0; chapter_idx < ti->chapter_count && success; chapter_idx++)
602 if (success && ti->chapter_count > 1)
608 bd_free_title_info(ti);
615 return static_cast<int>(title_count);
623int check_bluray(
const std::string & path,
void *buf, fuse_fill_dir_t filler)
625 std::string _path(path);
631 if (stat((_path +
"BDMV/index.bdmv").c_str(), &stbuf) == 0)
641 res =
load_path(_path, &stbuf, buf, filler);
struct bluray BLURAY
Forward declaration of libbluray handle.
int check_bluray(const std::string &path, void *buf, fuse_fill_dir_t filler)
Get number of titles on Blu-ray.
static bool create_bluray_virtualfile(BLURAY *bd, const BLURAY_TITLE_INFO *ti, const std::string &path, const struct stat *statbuf, void *buf, fuse_fill_dir_t filler, bool is_main_title, bool full_title, uint32_t title_idx, uint32_t chapter_idx)
Create a virtual file entry of a Blu-ray chapter or title.
static int parse_bluray(const std::string &path, const struct stat *statbuf, void *buf, fuse_fill_dir_t filler)
Parse Blu-ray directory and get all Blu-ray titles and chapters as virtual files.
static int parse_find_best_audio_stream()
Find best match audio stream.
static bool audio_stream_info(const std::string &path, BLURAY_STREAM_INFO *ss, int *channels, int *sample_rate)
Get information about Blu-ray stream.
static int parse_find_best_video_stream()
Find best match video stream.
static bool video_stream_info(const std::string &path, BLURAY_STREAM_INFO *ss, int *width, int *height, AVRational *framerate, bool *interleaved)
Get information about Blu-ray stream.
static void debug(const T filename, const std::string &format_string, Args &&...args)
Write debug level log entry.
static void trace(const T filename, const std::string &format_string, Args &&...args)
Write trace level log entry.
static void error(const T filename, const std::string &format_string, Args &&...args)
Write error level log entry.
std::string format_duration(int64_t value, uint32_t fracs)
Format a time in format HH:MM:SS.fract.
std::string format_samplerate(int value)
Format a samplerate.
std::string format_bitrate(BITRATE value)
Format a bit rate.
const std::string & append_sep(std::string *path)
Add / to the path if required.
std::string format_size(uint64_t value)
Format size.
std::string replace_all(std::string str, const std::string &from, const std::string &to)
Same as std::string replace(), but replaces all occurrences.
#define BITRATE
For FFmpeg bit rate is an int.
const std::string & strsprintf(std::string *str, const std::string &format, Args ... args)
Format a std::string sprintf-like.
@ VIDEO
FFmpegfs_Format info, 0: video file.
FFMPEGFS_FORMAT_ARR ffmpeg_format
Two FFmpegfs_Format infos, 0: video file, 1: audio file.
Main include for FFmpegfs project.
int add_dotdot(void *buf, fuse_fill_dir_t filler, const struct stat *stbuf, off_t off)
Make dot and double dot entries for a virtual directory.
LPVIRTUALFILE insert_dir(VIRTUALTYPE type, const std::string &virtdir, const struct stat *stbuf, int flags=VIRTUALFLAG_NONE)
Add new virtual directory to the internal list. If the file already exists, it will be updated.
int add_fuse_entry(void *buf, fuse_fill_dir_t filler, const std::string &name, const struct stat *stbuf, off_t off)
Wrapper to the Fuse filler function.
int load_path(const std::string &path, const struct stat *statbuf, void *buf, fuse_fill_dir_t filler)
Load a path with virtual files for FUSE.
bool check_path(const std::string &path)
Check if the path has already been parsed. Only useful if for DVD, Blu-ray or VCD where it is guarant...
LPVIRTUALFILE insert_file(VIRTUALTYPE type, const std::string &virtfile, const struct stat *stbuf, int flags=VIRTUALFLAG_NONE)
Add new virtual file to internal list.
@ BLURAY
Blu-ray disk file.
Provide various log facilities to stderr, disk or syslog.
unsigned m_chapter_no
Chapter number (1...n)
uint32_t m_title_no
Track number (1...n)
uint32_t m_playlist_no
Playlist number (1...n)
unsigned m_angle_no
Selected angle number (1...n)
int m_sample_rate
Audio sample rate - Filled in for the DVD/Blu-ray directory.
bool m_full_title
If true, ignore m_chapter_no and provide full track.
size_t m_predicted_size
Use this as the size instead of computing it over and over.
int m_width
Video width - Filled in for the DVD/Blu-ray directory.
int m_height
Video height - Filled in for the DVD/Blu-ray directory.
int m_channels
Audio channels - Filled in for the DVD/Blu-ray directory.
AVRational m_framerate
Video frame rate - Filled in for the DVD/Blu-ray directory.
struct stat m_st
stat structure with size etc.
struct VIRTUALFILE::BLURAY_CHAPTER m_bluray
Blu-ray title/chapter info.
size_t m_format_idx
Index into params.format[] array.
uint32_t m_video_frame_count
Number of frames in video or 0 if not a video.
int64_t m_duration
Track/chapter duration, in AV_TIME_BASE fractional seconds.
bool transcoder_set_filesize(LPVIRTUALFILE virtualfile, int64_t duration, BITRATE audio_bit_rate, int channels, int sample_rate, AVSampleFormat sample_format, BITRATE video_bit_rate, int width, int height, bool interleaved, const AVRational &framerate)
Set the file size.
bool transcoder_cached_filesize(LPVIRTUALFILE virtualfile, struct stat *stbuf)
Simply get encoded file size (do not create the whole encoder/decoder objects)
File transcoder interface (for use with by FUSE)