# HG changeset patch # User ben # Date 1278349486 0 # Node ID 9a590e7aac5716fd3ed134be313e6b732c72786b # Parent 480cdba9e4802703fa8548c7ed09b19209c89c93 Support for unencrypted Blu-ray playback through libbluray. Use it through: mplayer br:////path/to/disc diff -r 480cdba9e480 -r 9a590e7aac57 Changelog --- a/Changelog Sun Jul 04 07:13:18 2010 +0000 +++ b/Changelog Mon Jul 05 17:04:46 2010 +0000 @@ -41,6 +41,10 @@ * remove vf_yuy2, functionality is replaced by -vf format=yuv2 * remove vf_rgb2bgr, functionality is replaced by sws and vf_format + Streaming: + * Support for unencrypted Blu-ray playback through libbluray. + Use it through: mplayer br:////path/to/disc + Drivers: * -vo yuv4mpeg:interlaced no longer does its own interlaced RGB->YUV conversion. Use -vf scale=::1 to keep the same behavior and report diff -r 480cdba9e480 -r 9a590e7aac57 DOCS/man/en/mplayer.1 --- a/DOCS/man/en/mplayer.1 Sun Jul 04 07:13:18 2010 +0000 +++ b/DOCS/man/en/mplayer.1 Mon Jul 05 17:04:46 2010 +0000 @@ -61,6 +61,11 @@ . .br .B mplayer +[br]://[title][/device] +[options] +. +.br +.B mplayer [dvd|dvdnav]://[title|[start_title]\-end_title][/device] [options] . @@ -151,7 +156,7 @@ It plays most MPEG/\:VOB, AVI, ASF/\:WMA/\:WMV, RM, QT/\:MOV/\:MP4, Ogg/\:OGM, MKV, VIVO, FLI, NuppelVideo, yuv4mpeg, FILM and RoQ files, supported by many native and binary codecs. -You can watch VCD, SVCD, DVD, 3ivx, DivX 3/4/5, WMV and even H.264 movies, +You can watch VCD, SVCD, DVD, Blu\-ray, 3ivx, DivX 3/4/5, WMV and even H.264 movies, too. .PP MPlayer supports a wide range of video and audio output drivers. @@ -249,7 +254,7 @@ Mute sound. .IPs "_ (MPEG-TS, AVI and libavformat only)" Cycle through the available video tracks. -.IPs "# (DVD, MPEG, Matroska, AVI and libavformat only)" +.IPs "# (DVD, Blu-ray, MPEG, Matroska, AVI and libavformat only)" Cycle through the available audio tracks. .IPs "TAB (MPEG-TS and libavformat only)" Cycle through the available programs. @@ -940,8 +945,8 @@ Also prints more detailed information about subtitle and audio track languages and IDs. In some cases you can get more information by using \-msglevel identify=6. -For example, for a DVD it will list the chapters and time length of each title, -as well as a disk ID. +For example, for a DVD or Blu\-ray it will list the chapters and time length +of each title, as well as a disk ID. Combine this with \-frames 0 to suppress all video output. The wrapper script TOOLS/\:midentify.sh suppresses the other MPlayer output and (hopefully) shellescapes the filenames. @@ -1246,6 +1251,19 @@ bandwidth allowing faster cache filling and stream dumping. . .TP +.B \-bluray\-angle (Blu\-ray only) +Some Blu\-ray discs contain scenes that can be viewed from multiple angles. +Here you can tell MPlayer which angles to use (default: 1). +. +.TP +.B \-bluray\-chapter (Blu\-ray only) +Tells MPlayer which Blu\-ray chapter to start the current title from (default: 1). +. +.TP +.B \-bluray\-device (Blu\-ray only) +Specify the Blu\-ray disc location. Must be a directory with Blu\-ray structure. +. +.TP .B \-cache This option specifies how much memory (in kBytes) to use when precaching a file or URL. @@ -11492,6 +11510,13 @@ .SH EXAMPLES OF MPLAYER USAGE . .PP +.B Quickstart Blu\-ray playing: +.nf +mplayer br:////path/to/disc +mplayer br:// \-bluray\-device /path/to/disc +.fi +. +.PP .B Quickstart DVD playing: .nf mplayer dvd://1 diff -r 480cdba9e480 -r 9a590e7aac57 DOCS/tech/MAINTAINERS --- a/DOCS/tech/MAINTAINERS Sun Jul 04 07:13:18 2010 +0000 +++ b/DOCS/tech/MAINTAINERS Mon Jul 05 17:04:46 2010 +0000 @@ -127,6 +127,7 @@ * stream_dvb.c - Nico Sabbi * stream_dvd.c - Nico Sabbi * stream_dvdnav.c - Nico Sabbi and Benjamin Zores + * stream_bluray.c - Benjamin Zores codec support: * FFmpeg: Michael Niedermayer diff -r 480cdba9e480 -r 9a590e7aac57 Makefile --- a/Makefile Sun Jul 04 07:13:18 2010 +0000 +++ b/Makefile Mon Jul 05 17:04:46 2010 +0000 @@ -141,6 +141,7 @@ SRCS_COMMON-$(LIBAVFORMAT) += libmpdemux/demux_lavf.c \ stream/stream_ffmpeg.c \ +SRCS_COMMON-$(LIBBLURAY) += stream/stream_bluray.c SRCS_COMMON-$(LIBBS2B) += libaf/af_bs2b.c SRCS_COMMON-$(LIBDCA) += libmpcodecs/ad_libdca.c SRCS_COMMON-$(LIBDV) += libmpcodecs/ad_libdv.c \ diff -r 480cdba9e480 -r 9a590e7aac57 cfg-common.h --- a/cfg-common.h Sun Jul 04 07:13:18 2010 +0000 +++ b/cfg-common.h Mon Jul 05 17:04:46 2010 +0000 @@ -333,6 +333,15 @@ {"dvd-speed", "MPlayer was compiled without libdvdread support.\n", CONF_TYPE_PRINT, 0, 0, 0, NULL}, {"dvd", "MPlayer was compiled without libdvdread support.\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL}, #endif /* CONFIG_DVDREAD */ +#ifdef CONFIG_LIBBLURAY + {"bluray-device", &bluray_device, CONF_TYPE_STRING, 0, 0, 0, NULL}, + {"bluray-angle", &bluray_angle, CONF_TYPE_INT, CONF_RANGE, 0, 999, NULL}, + {"bluray-chapter", &bluray_chapter, CONF_TYPE_INT, CONF_RANGE, 0, 999, NULL}, +#else + {"bluray-device", "MPlayer was compiled without libbluray support.\n", CONF_TYPE_PRINT, 0, 0, 0, NULL}, + {"bluray-angle", "MPlayer was compiled without libbluray support.\n", CONF_TYPE_PRINT, 0, 0, 0, NULL}, + {"bluray-chapter", "MPlayer was compiled without libbluray support.\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL}, +#endif /* CONFIG_LIBBLURAY */ {"alang", &audio_lang, CONF_TYPE_STRING, 0, 0, 0, NULL}, {"slang", &dvdsub_lang, CONF_TYPE_STRING, 0, 0, 0, NULL}, diff -r 480cdba9e480 -r 9a590e7aac57 configure --- a/configure Sun Jul 04 07:13:18 2010 +0000 +++ b/configure Mon Jul 05 17:04:46 2010 +0000 @@ -280,6 +280,7 @@ --enable-nemesi enable Nemesi Streaming Media [autodetect] --enable-librtmp enable RTMPDump Streaming Media [autodetect] --disable-vcd disable VCD support [autodetect] + --disable-bluray disable Blu-ray support [autodetect] --disable-dvdnav disable libdvdnav [autodetect] --disable-dvdread disable libdvdread [autodetect] --disable-dvdread-internal disable internal libdvdread [autodetect] @@ -674,6 +675,7 @@ _libbs2b=auto _xmms=no _vcd=auto +_bluray=auto _dvdnav=auto _dvdnavconfig=dvdnav-config _dvdreadconfig=dvdread-config @@ -1088,6 +1090,8 @@ --disable-xmms) _xmms=no ;; --enable-vcd) _vcd=yes ;; --disable-vcd) _vcd=no ;; + --enable-bluray) _bluray=yes ;; + --disable-bluray) _bluray=no ;; --enable-dvdread) _dvdread=yes ;; --disable-dvdread) _dvdread=no ;; --enable-dvdread-internal) _dvdread_internal=yes ;; @@ -6038,6 +6042,30 @@ +echocheck "Blu-ray support" +if test "$_bluray" = auto ; then + _bluray=no + + cat > $TMPC << EOF +#include +#include +int main(void) { + BLURAY_TITLE_INFO *i = bd_get_title_info(NULL, 0); + return 0; +} +EOF + compile_check $TMPC -lbluray && _bluray=yes +fi +if test "$_bluray" = yes ; then + def_bluray='#define CONFIG_LIBBLURAY 1' + extra_ldflags="$extra_ldflags -lbluray" + inputmodules="bluray $inputmodules" +else + def_bluray='#undef CONFIG_LIBBLURAY' + noinputmodules="bluray $noinputmodules" +fi +echores "$_bluray" + echocheck "dvdread" if test "$_dvdread_internal" = auto ; then _dvdread_internal=no @@ -8579,6 +8607,7 @@ LIBA52 = $_liba52 LIBASS = $_ass LIBASS_INTERNAL = $ass_internal +LIBBLURAY = $_bluray LIBBS2B = $_libbs2b LIBDCA = $_libdca LIBDV = $_libdv @@ -8936,9 +8965,10 @@ $(ff_config_enable "$cpuexts_all" "$cpuexts" "HAVE") -/* DVD/VCD/CD */ +/* Blu-ray/DVD/VCD/CD */ #define DEFAULT_CDROM_DEVICE "$default_cdrom_device" #define DEFAULT_DVD_DEVICE "$default_dvd_device" +$def_bluray $def_bsdi_dvd $def_cddb $def_cdio diff -r 480cdba9e480 -r 9a590e7aac57 help/help_mp-en.h --- a/help/help_mp-en.h Sun Jul 04 07:13:18 2010 +0000 +++ b/help/help_mp-en.h Mon Jul 05 17:04:46 2010 +0000 @@ -1895,6 +1895,7 @@ #define MSGTR_SMBFileNotFound "Could not open from LAN: '%s'\n" #define MSGTR_SMBNotCompiled "MPlayer was not compiled with SMB reading support.\n" +#define MSGTR_CantOpenBluray "Couldn't open Blu-ray device: %s\n" #define MSGTR_CantOpenDVD "Couldn't open DVD device: %s (%s)\n" // stream_cdda.c @@ -1966,6 +1967,11 @@ #define MSGTR_DVDsubtitleLanguage "subtitle ( sid ): %d language: %s\n" #define MSGTR_DVDnumSubtitles "number of subtitles on disk: %d\n" +// stream_bluray.c +#define MSGTR_BlurayNoDevice "No Blu-ray device/location was specified ...\n" +#define MSGTR_BlurayNoTitles "Can't find any Blu-ray-compatible title here.\n" +#define MSGTR_BlurayOK "Blu-ray successfully opened.\n" + // stream_radio.c #define MSGTR_RADIO_ChannelNamesDetected "[radio] Radio channel names detected.\n" #define MSGTR_RADIO_FreqRange "[radio] Allowed frequency range is %.2f-%.2f MHz.\n" diff -r 480cdba9e480 -r 9a590e7aac57 stream/stream.c --- a/stream/stream.c Sun Jul 04 07:13:18 2010 +0000 +++ b/stream/stream.c Mon Jul 05 17:04:46 2010 +0000 @@ -79,6 +79,7 @@ extern const stream_info_t stream_info_file; extern const stream_info_t stream_info_ifo; extern const stream_info_t stream_info_dvd; +extern const stream_info_t stream_info_bluray; static const stream_info_t* const auto_open_streams[] = { #ifdef CONFIG_VCD @@ -130,6 +131,9 @@ #ifdef CONFIG_DVDNAV &stream_info_dvdnav, #endif +#ifdef CONFIG_LIBBLURAY + &stream_info_bluray, +#endif #ifdef CONFIG_LIBAVFORMAT &stream_info_ffmpeg, #endif diff -r 480cdba9e480 -r 9a590e7aac57 stream/stream.h --- a/stream/stream.h Sun Jul 04 07:13:18 2010 +0000 +++ b/stream/stream.h Mon Jul 05 17:04:46 2010 +0000 @@ -51,6 +51,7 @@ #define STREAMTYPE_TV 17 #define STREAMTYPE_MF 18 #define STREAMTYPE_RADIO 19 +#define STREAMTYPE_BLURAY 20 #define STREAM_BUFFER_SIZE 2048 @@ -330,6 +331,8 @@ /// wait for time milliseconds int stream_check_interrupt(int time); +extern int bluray_angle; +extern int bluray_chapter; extern int dvd_speed; extern int dvd_title; extern int dvd_chapter; @@ -337,6 +340,7 @@ extern int dvd_angle; extern int vcd_track; +extern char *bluray_device; extern char * audio_stream; extern char *cdrom_device; extern char *dvd_device; diff -r 480cdba9e480 -r 9a590e7aac57 stream/stream_bluray.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stream/stream_bluray.c Mon Jul 05 17:04:46 2010 +0000 @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2010 Benjamin Zores + * + * This file is part of MPlayer. + * + * MPlayer is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * MPlayer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * Blu-ray parser/reader using libbluray + * Use 'git clone git://git.videolan.org/libbluray' to get it. + * + * TODO: + * - Add libbdnav support for menus navigation + * - Add AACS/BD+ protection detection + * - Add descrambled keys database support (KEYDB.cfg) + * + */ + +#include + +#include "config.h" +#include "libavutil/common.h" +#include "libmpdemux/demuxer.h" +#include "mp_msg.h" +#include "help_mp.h" +#include "m_struct.h" +#include "m_option.h" +#include "stream.h" + +#define BLURAY_SECTOR_SIZE 6144 + +#define BLURAY_DEFAULT_ANGLE 0 +#define BLURAY_DEFAULT_CHAPTER 0 +#define BLURAY_DEFAULT_TITLE 0 + +char *bluray_device = NULL; +int bluray_angle = 0; +int bluray_chapter = 0; + +static struct stream_priv_s { + int title; + char *device; +} bluray_stream_priv_dflts = { + BLURAY_DEFAULT_TITLE, + NULL +}; + +#define ST_OFF(f) M_ST_OFF(struct stream_priv_s,f) +static const m_option_t bluray_stream_opts_fields[] = { + { "hostname", ST_OFF(title), CONF_TYPE_INT, M_OPT_RANGE, 0, 99999, NULL}, + { "filename", ST_OFF(device), CONF_TYPE_STRING, 0, 0 ,0, NULL}, + { NULL, NULL, 0, 0, 0, 0, NULL } +}; + +static const struct m_struct_st bluray_stream_opts = { + "bluray", + sizeof(struct stream_priv_s), + &bluray_stream_priv_dflts, + bluray_stream_opts_fields +}; + +static void bluray_stream_close(stream_t *s) +{ + bd_close(s->priv); + s->priv = NULL; +} + +static int bluray_stream_seek(stream_t *s, off_t pos) +{ + off_t p; + + p = bd_seek(s->priv, pos); + if (p == -1) + return 0; + + s->pos = p; + return 1; +} + +static int bluray_stream_fill_buffer(stream_t *s, char *buf, int len) +{ + return bd_read(s->priv, buf, len); +} + +static int bluray_stream_open(stream_t *s, int mode, + void *opts, int *file_format) +{ + struct stream_priv_s *p = opts; + BLURAY_TITLE_INFO *info = NULL; + BLURAY *bd; + + int title, title_guess, title_count; + uint64_t title_size; + + unsigned int chapter, angle; + uint64_t max_duration = 0; + int64_t chapter_pos = 0; + + char *device = NULL; + int i; + + /* find the requested device */ + if (p->device) + device = p->device; + else if (bluray_device) + device = bluray_device; + + if (!device) { + mp_msg(MSGT_OPEN, MSGL_ERR, MSGTR_BlurayNoDevice); + return STREAM_UNSUPPORTED; + } + + /* open device */ + bd = bd_open(device, NULL); + if (!bd) { + mp_msg(MSGT_OPEN, MSGL_ERR, MSGTR_CantOpenBluray, device); + return STREAM_UNSUPPORTED; + } + + /* check for available titles on disc */ + title_count = bd_get_titles(bd, TITLES_RELEVANT); + mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_BLURAY_TITLES=%d\n", title_count); + if (!title_count) { + mp_msg(MSGT_OPEN, MSGL_ERR, MSGTR_BlurayNoTitles); + bd_close(bd); + return STREAM_UNSUPPORTED; + } + + /* parse titles information */ + title_guess = BLURAY_DEFAULT_TITLE; + for (i = 0; i < title_count; i++) { + BLURAY_TITLE_INFO *ti; + int sec, msec; + + ti = bd_get_title_info(bd, i); + if (!ti) + continue; + + sec = ti->duration / 90000; + msec = (ti->duration - sec) % 1000; + + mp_msg(MSGT_IDENTIFY, MSGL_INFO, + "ID_BLURAY_TITLE_%d_CHAPTERS=%d\n", i + 1, ti->chapter_count); + mp_msg(MSGT_IDENTIFY, MSGL_INFO, + "ID_BLURAY_TITLE_%d_ANGLE=%d\n", i + 1, ti->angle_count); + mp_msg(MSGT_IDENTIFY, MSGL_V, + "ID_BLURAY_TITLE_%d_LENGTH=%d.%03d\n", i + 1, sec, msec); + + /* try to guess which title may contain the main movie */ + if (ti->duration > max_duration) { + max_duration = ti->duration; + title_guess = i; + } + + bd_free_title_info(ti); + } + + /* Select current title */ + title = p->title ? p->title - 1: title_guess; + title = FFMIN(title, title_count - 1); + + bd_select_title(bd, title); + + title_size = bd_get_title_size(bd); + mp_msg(MSGT_IDENTIFY, MSGL_INFO, + "ID_BLURAY_CURRENT_TITLE=%d\n", title + 1); + + /* Get current title information */ + info = bd_get_title_info(bd, title); + if (!info) + goto err_no_info; + + /* Select chapter */ + chapter = bluray_chapter ? bluray_chapter : BLURAY_DEFAULT_CHAPTER; + chapter = FFMIN(chapter, info->chapter_count); + + if (chapter) + chapter_pos = bd_chapter_pos(bd, chapter); + + mp_msg(MSGT_IDENTIFY, MSGL_INFO, + "ID_BLURAY_CURRENT_CHAPTER=%d\n", chapter + 1); + + /* Select angle */ + angle = bluray_angle ? bluray_angle : BLURAY_DEFAULT_ANGLE; + angle = FFMIN(angle, info->angle_count); + + if (angle) + bd_select_angle(bd, angle); + + mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_BLURAY_CURRENT_ANGLE=%d\n", angle + 1); + + bd_free_title_info(info); + +err_no_info: + s->fill_buffer = bluray_stream_fill_buffer; + s->seek = bluray_stream_seek; + s->close = bluray_stream_close; + + s->start_pos = chapter_pos; + s->end_pos = title_size; + s->sector_size = BLURAY_SECTOR_SIZE; + s->flags = mode | MP_STREAM_SEEK; + s->priv = bd; + s->type = STREAMTYPE_BLURAY; + s->url = strdup("br://"); + + mp_msg(MSGT_OPEN, MSGL_V, MSGTR_BlurayOK); + + return STREAM_OK; +} + +const stream_info_t stream_info_bluray = { + "Blu-ray Disc", + "bd", + "Benjamin Zores", + "Play Blu-ray discs through external libbluray", + bluray_stream_open, + { "br", "bluray", NULL }, + &bluray_stream_opts, + 1 +};