Skip to content

Commit

Permalink
bluray protocol
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
  • Loading branch information
hpi1 authored and michaelni committed Mar 3, 2012
1 parent 70b5583 commit 23a5bf9
Show file tree
Hide file tree
Showing 7 changed files with 273 additions and 0 deletions.
1 change: 1 addition & 0 deletions Changelog
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ version next:
- Sun Rasterfile Encoder
- ID3v2 attached pictures reading and writing
- WMA Lossless decoder
- bluray protocol


version 0.10:
Expand Down
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ Muxers/Demuxers:
wv.c Kostya Shishkov

Protocols:
bluray.c Petri Hintukainen
http.c Ronald S. Bultje
mms*.c Ronald S. Bultje
udp.c Luca Abeni
Expand Down
4 changes: 4 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ External library support:
--enable-gnutls enable gnutls [no]
--enable-libaacplus enable AAC+ encoding via libaacplus [no]
--enable-libass enable libass subtitles rendering [no]
--enable-libbluray enable BluRay reading using libbluray [no]
--enable-libcelt enable CELT decoding via libcelt [no]
--enable-libopencore-amrnb enable AMR-NB de/encoding via libopencore-amrnb [no]
--enable-libopencore-amrwb enable AMR-WB decoding via libopencore-amrwb [no]
Expand Down Expand Up @@ -1029,6 +1030,7 @@ CONFIG_LIST="
huffman
libaacplus
libass
libbluray
libcdio
libcelt
libdc1394
Expand Down Expand Up @@ -1633,6 +1635,7 @@ x11_grab_device_indev_deps="x11grab XShmCreateImage"
x11_grab_device_indev_extralibs="-lX11 -lXext -lXfixes"

# protocols
bluray_protocol_deps="libbluray"
gopher_protocol_deps="network"
httpproxy_protocol_deps="network"
httpproxy_protocol_select="tcp_protocol"
Expand Down Expand Up @@ -3140,6 +3143,7 @@ enabled frei0r && { check_header frei0r.h || die "ERROR: frei0r.h header not
enabled gnutls && require_pkg_config gnutls gnutls/gnutls.h gnutls_global_init
enabled libaacplus && require "libaacplus >= 2.0.0" aacplus.h aacplusEncOpen -laacplus
enabled libass && require_pkg_config libass ass/ass.h ass_library_init
enabled libbluray && require libbluray libbluray/bluray.h bd_open -lbluray
enabled libcelt && require libcelt celt/celt.h celt_decode -lcelt0 &&
{ check_lib celt/celt.h celt_decoder_create_custom -lcelt0 ||
die "ERROR: libcelt version must be >= 0.11.0."; }
Expand Down
30 changes: 30 additions & 0 deletions doc/protocols.texi
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,36 @@ supported protocols.

A description of the currently available protocols follows.

@section bluray

Read BluRay playlist.

The accepted options are:
@table @option

@item angle
BluRay angle

@item chapter
Start chapter (1...N)

@item playlist
Playlist to read (BDMV/PLAYLIST/?????.mpls)

@end table

Examples:

Read longest playlist from BluRay mounted to /mnt/bluray:
@example
bluray:/mnt/bluray
@end example

Read angle 2 of playlist 4 from BluRay mounted to /mnt/bluray, start from chapter 2:
@example
-playlist 4 -angle 2 -chapter 2 bluray:/mnt/bluray
@end example

@section concat

Physical concatenation protocol.
Expand Down
1 change: 1 addition & 0 deletions libavformat/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ OBJS-$(CONFIG_LIBRTMP) += librtmp.o
OBJS+= avio.o aviobuf.o

OBJS-$(CONFIG_APPLEHTTP_PROTOCOL) += hlsproto.o
OBJS-$(CONFIG_BLURAY_PROTOCOL) += bluray.o
OBJS-$(CONFIG_CACHE_PROTOCOL) += cache.o
OBJS-$(CONFIG_CONCAT_PROTOCOL) += concat.o
OBJS-$(CONFIG_CRYPTO_PROTOCOL) += crypto.o
Expand Down
1 change: 1 addition & 0 deletions libavformat/allformats.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ void av_register_all(void)
#if FF_API_APPLEHTTP_PROTO
REGISTER_PROTOCOL (APPLEHTTP, applehttp);
#endif
REGISTER_PROTOCOL (BLURAY, bluray);
REGISTER_PROTOCOL (CACHE, cache);
REGISTER_PROTOCOL (CONCAT, concat);
REGISTER_PROTOCOL (CRYPTO, crypto);
Expand Down
235 changes: 235 additions & 0 deletions libavformat/bluray.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
/*
* BluRay (libbluray) protocol
*
* Copyright (c) 2012 Petri Hintukainen <phintuka <at> users.sourceforge.net>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include <libbluray/bluray.h>

#include "libavutil/avstring.h"
#include "libavformat/avformat.h"
#include "libavformat/url.h"
#include "libavutil/opt.h"

#define BLURAY_PROTO_PREFIX "bluray:"
#define MIN_PLAYLIST_LENGTH 180 /* 3 min */

typedef struct {
const AVClass *class;

BLURAY *bd;

int playlist;
int angle;
int chapter;
/*int region;*/
} BlurayContext;

#define OFFSET(x) offsetof(BlurayContext, x)
static const AVOption options[] = {
{"playlist", "", OFFSET(playlist), AV_OPT_TYPE_INT, { .dbl=-1 }, -1, 99999, AV_OPT_FLAG_DECODING_PARAM },
{"angle", "", OFFSET(angle), AV_OPT_TYPE_INT, { .dbl=0 }, 0, 0xfe, AV_OPT_FLAG_DECODING_PARAM },
{"chapter", "", OFFSET(chapter), AV_OPT_TYPE_INT, { .dbl=1 }, 1, 0xfffe, AV_OPT_FLAG_DECODING_PARAM },
/*{"region", "bluray player region code (1 = region A, 2 = region B, 4 = region C)", OFFSET(region), AV_OPT_TYPE_INT, { .dbl=0 }, 0, 3, AV_OPT_FLAG_DECODING_PARAM },*/
{NULL}
};

static const AVClass bluray_context_class = {
.class_name = "bluray",
.item_name = av_default_item_name,
.option = options,
.version = LIBAVUTIL_VERSION_INT,
};


static int check_disc_info(URLContext *h)
{
BlurayContext *bd = h->priv_data;
const BLURAY_DISC_INFO *disc_info;

disc_info = bd_get_disc_info(bd->bd);
if (!disc_info) {
av_log(h, AV_LOG_ERROR, "bd_get_disc_info() failed\n");
return -1;
}

if (!disc_info->bluray_detected) {
av_log(h, AV_LOG_ERROR, "BluRay disc not detected\n");
return -1;
}

/* AACS */
if (disc_info->aacs_detected && !disc_info->aacs_handled) {
if (!disc_info->libaacs_detected) {
av_log(h, AV_LOG_ERROR,
"Media stream encrypted with AACS, install and configure libaacs\n");
} else {
av_log(h, AV_LOG_ERROR, "Your libaacs can't decrypt this media\n");
}
return -1;
}

/* BD+ */
if (disc_info->bdplus_detected && !disc_info->bdplus_handled) {
/*
if (!disc_info->libbdplus_detected) {
av_log(h, AV_LOG_ERROR,
"Media stream encrypted with BD+, install and configure libbdplus");
} else {
*/
av_log(h, AV_LOG_ERROR, "Unable to decrypt BD+ encrypted media");
/*}*/
return -1;
}

return 0;
}

static int bluray_close(URLContext *h)
{
BlurayContext *bd = h->priv_data;
if (bd->bd) {
bd_close(bd->bd);
}

return 0;
}

static int bluray_open(URLContext *h, const char *path, int flags)
{
BlurayContext *bd = h->priv_data;
int num_title_idx;
const char *diskname = path;

av_strstart(path, BLURAY_PROTO_PREFIX, &diskname);

bd->bd = bd_open(diskname, NULL);
if (!bd->bd) {
av_log(h, AV_LOG_ERROR, "bd_open() failed\n");
return AVERROR(EIO);
}

/* check if disc can be played */
if (check_disc_info(h) < 0) {
return AVERROR(EIO);
}

/* setup player registers */
/* region code has no effect without menus
if (bd->region > 0 && bd->region < 5) {
av_log(h, AV_LOG_INFO, "setting region code to %d (%c)\n", bd->region, 'A' + (bd->region - 1));
bd_set_player_setting(bd->bd, BLURAY_PLAYER_SETTING_REGION_CODE, bd->region);
}
*/

/* load title list */
num_title_idx = bd_get_titles(bd->bd, TITLES_RELEVANT, MIN_PLAYLIST_LENGTH);
av_log(h, AV_LOG_INFO, "%d usable playlists:\n", num_title_idx);
if (num_title_idx < 1) {
return AVERROR(EIO);
}

/* if playlist was not given, select longest playlist */
if (bd->playlist < 0) {
uint64_t duration = 0;
int i;
for (i = 0; i < num_title_idx; i++) {
BLURAY_TITLE_INFO *info = bd_get_title_info(bd->bd, i, 0);

av_log(h, AV_LOG_INFO, "playlist %05d.mpls (%d:%02d:%02d)\n",
info->playlist,
((int)(info->duration / 90000) / 3600),
((int)(info->duration / 90000) % 3600) / 60,
((int)(info->duration / 90000) % 60));

if (info->duration > duration) {
bd->playlist = info->playlist;
duration = info->duration;
}

bd_free_title_info(info);
}
av_log(h, AV_LOG_INFO, "selected %05d.mpls\n", bd->playlist);
}

/* select playlist */
if (bd_select_playlist(bd->bd, bd->playlist) <= 0) {
av_log(h, AV_LOG_ERROR, "bd_select_playlist(%05d.mpls) failed\n", bd->playlist);
return AVERROR(EIO);
}

/* select angle */
if (bd->angle >= 0) {
bd_select_angle(bd->bd, bd->angle);
}

/* select chapter */
if (bd->chapter > 1) {
bd_seek_chapter(bd->bd, bd->chapter - 1);
}

return 0;
}

static int bluray_read(URLContext *h, unsigned char *buf, int size)
{
BlurayContext *bd = h->priv_data;
int len;

if (!bd || !bd->bd) {
return AVERROR(EFAULT);
}

len = bd_read(bd->bd, buf, size);

return len;
}

static int64_t bluray_seek(URLContext *h, int64_t pos, int whence)
{
BlurayContext *bd = h->priv_data;

if (!bd || !bd->bd) {
return AVERROR(EFAULT);
}

switch (whence) {
case SEEK_SET:
case SEEK_CUR:
case SEEK_END:
return bd_seek(bd->bd, pos);

case AVSEEK_SIZE:
return bd_get_title_size(bd->bd);
}

av_log(h, AV_LOG_ERROR, "Unsupported whence operation %d\n", whence);
return AVERROR(EINVAL);
}


URLProtocol ff_bluray_protocol = {
.name = "bluray",
.url_close = bluray_close,
.url_open = bluray_open,
.url_read = bluray_read,
.url_seek = bluray_seek,
.priv_data_size = sizeof(BlurayContext),
.priv_data_class = &bluray_context_class,
};

0 comments on commit 23a5bf9

Please sign in to comment.