Esempio n. 1
0
int main(int argc, const char *argv[])
{
    BLURAY *bd;
    const BLURAY_DISC_INFO *info;

    if (argc != 2) {
        fprintf(stderr, "usage: %s <disc_root>\n", argv[0]);
        return 1;
    }

    bd = bd_open(argv[1], NULL);
    if (!bd) {
        fprintf(stderr, "error opening BD disc %s\n", argv[1]);
        return -1;
    }

    info = bd_get_disc_info(bd);

    if (!info->bluray_detected) {
        fprintf(stderr, "no BD disc detected in %s\n", argv[1]);
        bd_close(bd);
        return -1;
    }

    _indx_print(info);

    bd_close(bd);

    return 0;
}
int bd_check_file(FILE *fp, FileInfo *finfo)
{
	int nRet = 0;
	int count;
	parse_priv * par_priv = NULL;

	mp_msg("bd_check_file\n");
	BLURAY  *bd = bd_open(finfo->filepath, NULL);
	if (bd)
	{
		count = bd_get_titles(bd, TITLES_FILTER_DUP_CLIP);
		mp_msg("Get titles: %d\n", count);
		if (count > 0)
			nRet = 1;
		else 
			bd_close(bd);
	}

	if (nRet == 1)
	{
		par_priv = (parse_priv *)malloc(sizeof(parse_priv));
		par_priv->bd = bd;
		par_priv->title_num = count;
		finfo->priv = (void *)par_priv;
	}

	return nRet;
}
Esempio n. 3
0
bool BlurayMetadata::OpenDisc(void)
{
    QString keyfile = QString("%1/KEYDB.cfg").arg(GetConfDir());
    QByteArray keyarray = keyfile.toAscii();
    const char *keyfilepath = keyarray.data();

    m_bdnav = bd_open(m_path.toLatin1().data(), keyfilepath);

    if (!m_bdnav)
        return false;

    return true;
}
static bool BlurayMenuSupported(const cString& Path)
{
  bool result = false;
#ifdef HAVE_LIBBLURAY
  BLURAY *bdh = bd_open(Path, NULL);
  if (bdh) {
    const BLURAY_DISC_INFO *di = bd_get_disc_info(bdh);
    if (di->bluray_detected && !di->num_unsupported_titles)
      result = true;
    bd_close(bdh);
  }
#endif
  return result;
}
Esempio n. 5
0
/***********************************************************************
 * hb_bd_init
 ***********************************************************************
 *
 **********************************************************************/
hb_bd_t * hb_bd_init( hb_handle_t *h, char * path )
{
    hb_bd_t * d;
    int ii;

    d = calloc( sizeof( hb_bd_t ), 1 );
    d->h = h;

    /* Open device */
    d->bd = bd_open( path, NULL );
    if( d->bd == NULL )
    {
        /*
         * Not an error, may be a stream - which we'll try in a moment.
         */
        hb_log( "bd: not a bd - trying as a stream/file instead" );
        goto fail;
    }

    d->title_count = bd_get_titles( d->bd, TITLES_RELEVANT, 0 );
    if ( d->title_count == 0 )
    {
        hb_log( "bd: not a bd - trying as a stream/file instead" );
        goto fail;
    }
    d->title_info = calloc( sizeof( BLURAY_TITLE_INFO* ) , d->title_count );
    for ( ii = 0; ii < d->title_count; ii++ )
    {
        d->title_info[ii] = bd_get_title_info( d->bd, ii, 0 );
    }
    qsort(d->title_info, d->title_count, sizeof( BLURAY_TITLE_INFO* ), title_info_compare_mpls );
    d->path = strdup( path );

    return d;

fail:
    if( d->bd ) bd_close( d->bd );
    free( d );
    return NULL;
}
Esempio n. 6
0
/////////////////////////////////////////////////////////////////////////////
// Demuxer Functions
STDMETHODIMP CBDDemuxer::Open(LPCOLESTR pszFileName)
{
  CAutoLock lock(m_pLock);
  HRESULT hr = S_OK;

  int ret; // return code from C functions

  // Convert the filename from wchar to char for libbluray
  char fileName[4096];
  ret = WideCharToMultiByte(CP_UTF8, 0, pszFileName, -1, fileName, 4096, nullptr, nullptr);

  int iPlaylist = -1;

  DbgLog((LOG_TRACE, 10, L"Initializing BluRay Demuxer; Entry Point: %s", pszFileName));

  size_t len = strlen(fileName);
  if (len > 16) {
    char *bd_path = fileName;
    if(_strcmpi(bd_path+strlen(bd_path) - 16, "\\BDMV\\index.bdmv") == 0) {
      bd_path[strlen(bd_path) - 15] = 0;
    } else if (len > 22 && _strcmpi(bd_path+strlen(bd_path) - 22, "\\BDMV\\MovieObject.bdmv") == 0) {
      bd_path[strlen(bd_path) - 21] = 0;
    } else if (len > 25 && _strnicmp(bd_path+strlen(bd_path) - 25, "\\BDMV\\PLAYLIST\\", 15) == 0) {
      char *playlist = &bd_path[strlen(bd_path) - 10];
      bd_path[strlen(bd_path) - 24] = 0;

      playlist[5] = 0;
      iPlaylist = atoi(playlist);
    } else {
      return E_FAIL;
    }
    // Open BluRay
    BLURAY *bd = bd_open(bd_path, nullptr);
    if(!bd) {
      return E_FAIL;
    }
    m_pBD = bd;

    uint32_t timelimit = (iPlaylist != -1) ? 0 : 180;
    uint8_t flags = (iPlaylist != -1) ? TITLES_ALL : TITLES_RELEVANT;

    // Fetch titles
fetchtitles:
    m_nTitleCount = bd_get_titles(bd, flags, timelimit);

    if (m_nTitleCount <= 0) {
      if (timelimit > 0) {
        timelimit = 0;
        goto fetchtitles;
      }
      if (flags != TITLES_ALL) {
        flags = TITLES_ALL;
        goto fetchtitles;
      }
      return E_FAIL;
    }

    DbgLog((LOG_TRACE, 20, L"Found %d titles", m_nTitleCount));
    DbgLog((LOG_TRACE, 20, L" ------ Begin Title Listing ------"));

    uint64_t longest_duration = 0;
    uint32_t title_id = 0;
    boolean found = false;
    for(uint32_t i = 0; i < m_nTitleCount; i++) {
      BLURAY_TITLE_INFO *info = bd_get_title_info(bd, i, 0);
      if (info) {
        DbgLog((LOG_TRACE, 20, L"Title %u, Playlist %u (%u clips, %u chapters), Duration %I64u (%I64u seconds)", i, info->playlist, info->clip_count, info->chapter_count, info->duration, Convert90KhzToDSTime(info->duration) / DSHOW_TIME_BASE));
        if (iPlaylist != -1 && info->playlist == iPlaylist) {
          title_id = i;
          found = true;
        } else if (iPlaylist == -1 && info->duration > longest_duration) {
          title_id = i;
          longest_duration = info->duration;
        }
        bd_free_title_info(info);
      }
      if (found)
        break;
    }
    DbgLog((LOG_TRACE, 20, L" ------ End Title Listing ------"));

    hr = SetTitle(title_id);
  }

  return hr;
}
Esempio n. 7
0
bool BDRingBuffer::OpenFile(const QString &lfilename, uint retry_ms)
{
    filename = lfilename;

    VERBOSE(VB_IMPORTANT, LOC + QString("Opened BDRingBuffer device at %1")
            .arg(filename.toLatin1().data()));

    // Ask mythiowrapper to update this object on file open progress. Opening
    // a bluray disc can involve opening several hundred files which can take
    // several minutes when the disc structure is remote. The callback allows
    // us to 'kick' the main UI - as the 'please wait' widget is still visible
    // at this stage
    mythfile_open_register_callback(filename.toLatin1().data(), this,
                                    file_opened_callback);

    QMutexLocker locker(&m_infoLock);
    rwlock.lockForWrite();

    if (bdnav)
        close();

    QString keyfile = QString("%1/KEYDB.cfg").arg(GetConfDir());
    QByteArray keyarray = keyfile.toAscii();
    const char *keyfilepath = keyarray.data();

    bdnav = bd_open(filename.toLatin1().data(), keyfilepath);

    if (!bdnav)
    {
        rwlock.unlock();
        mythfile_open_register_callback(filename.toLatin1().data(), this, NULL);
        return false;
    }

    m_metaDiscLibrary = bd_get_meta(bdnav);

    if (m_metaDiscLibrary)
    {
        VERBOSE(VB_GENERAL, LOC + QString("Disc Title: %1 (%2)")
                    .arg(m_metaDiscLibrary->di_name)
                    .arg(m_metaDiscLibrary->language_code));
        VERBOSE(VB_GENERAL, LOC + QString("Alternative Title: %1")
                    .arg(m_metaDiscLibrary->di_alternative));
        VERBOSE(VB_GENERAL, LOC + QString("Disc Number: %1 of %2")
                    .arg(m_metaDiscLibrary->di_set_number)
                    .arg(m_metaDiscLibrary->di_num_sets));
    }

    // Check disc to see encryption status, menu and navigation types.
    m_topMenuSupported   = false;
    m_firstPlaySupported = false;
    const BLURAY_DISC_INFO *discinfo = bd_get_disc_info(bdnav);
    if (discinfo)
    {
        m_topMenuSupported   = discinfo->top_menu_supported;
        m_firstPlaySupported = discinfo->first_play_supported;

        VERBOSE(VB_PLAYBACK, LOC + QString("*** Blu-ray Disc Information ***"));
        VERBOSE(VB_PLAYBACK, LOC + QString("First Play Supported: %1")
                .arg(discinfo->first_play_supported ? "yes" : "no"));
        VERBOSE(VB_PLAYBACK, LOC + QString("Top Menu Supported: %1")
                .arg(discinfo->top_menu_supported ? "yes" : "no"));
        VERBOSE(VB_PLAYBACK, LOC + QString("Number of HDMV Titles: %1")
                .arg(discinfo->num_hdmv_titles));
        VERBOSE(VB_PLAYBACK, LOC + QString("Number of BD-J Titles: %1")
                .arg(discinfo->num_bdj_titles));
        VERBOSE(VB_PLAYBACK, LOC + QString("Number of Unsupported Titles: %1")
                .arg(discinfo->num_unsupported_titles));
        VERBOSE(VB_PLAYBACK, LOC + QString("AACS present on disc: %1")
                .arg(discinfo->aacs_detected ? "yes" : "no"));
        VERBOSE(VB_PLAYBACK, LOC + QString("libaacs used: %1")
                .arg(discinfo->libaacs_detected ? "yes" : "no"));
        VERBOSE(VB_PLAYBACK, LOC + QString("AACS handled: %1")
                .arg(discinfo->aacs_handled ? "yes" : "no"));
        VERBOSE(VB_PLAYBACK, LOC + QString("BD+ present on disc: %1")
                .arg(discinfo->bdplus_detected ? "yes" : "no"));
        VERBOSE(VB_PLAYBACK, LOC + QString("libbdplus used: %1")
                .arg(discinfo->libbdplus_detected ? "yes" : "no"));
        VERBOSE(VB_PLAYBACK, LOC + QString("BD+ handled: %1")
                .arg(discinfo->bdplus_handled ? "yes" : "no"));
    }

    // The following settings affect HDMV navigation
    // (default audio track selection,
    // parental controls, menu language, etc.  They are not yet used.

    // Set parental level "age" to 99 for now.  TODO: Add support for FE level
    bd_set_player_setting(bdnav, BLURAY_PLAYER_SETTING_PARENTAL, 99);

    // Set preferred language to FE guide language
    const char *langpref = gCoreContext->GetSetting(
        "ISO639Language0", "eng").toLatin1().data();
    QString QScountry  = gCoreContext->GetLocale()->GetCountryCode().toLower();
    const char *country = QScountry.toLatin1().data();
    bd_set_player_setting_str(
        bdnav, BLURAY_PLAYER_SETTING_AUDIO_LANG, langpref);

    // Set preferred presentation graphics language to the FE guide language
    bd_set_player_setting_str(bdnav, BLURAY_PLAYER_SETTING_PG_LANG, langpref);

    // Set preferred menu language to the FE guide language
    bd_set_player_setting_str(bdnav, BLURAY_PLAYER_SETTING_MENU_LANG, langpref);

    // Set player country code via MythLocale. (not a region setting)
    bd_set_player_setting_str(
        bdnav, BLURAY_PLAYER_SETTING_COUNTRY_CODE, country);

    int regioncode = 0;
    regioncode = gCoreContext->GetNumSetting("BlurayRegionCode");
    if (regioncode > 0)
        bd_set_player_setting(bdnav, BLURAY_PLAYER_SETTING_REGION_CODE, regioncode);

    VERBOSE(VB_IMPORTANT, LOC + QString("Using %1 as keyfile...")
            .arg(QString(keyfilepath)));

    // Return an index of relevant titles (excludes dupe clips + titles)
    VERBOSE(VB_GENERAL, LOC + QString("Retrieving title list (please wait)."));
    m_numTitles = bd_get_titles(bdnav, TITLES_RELEVANT);
    VERBOSE(VB_GENERAL, LOC + QString("Found %1 titles.").arg(m_numTitles));
    m_mainTitle = 0;
    m_currentTitleLength = 0;
    m_titlesize = 0;
    m_currentTime = 0;
    m_currentTitleInfo = NULL;
    m_currentTitleAngleCount = 0;

    // Mostly event-driven values below
    m_currentAngle = 0;
    m_currentTitle = 0;
    m_currentPlaylist = 0;
    m_currentPlayitem = 0;
    m_currentChapter = 0;
    m_currentAudioStream = 0;
    m_currentIGStream = 0;
    m_currentPGTextSTStream = 0;
    m_currentSecondaryAudioStream = 0;
    m_currentSecondaryVideoStream = 0;
    m_PGTextSTEnabled = false;
    m_secondaryAudioEnabled = false;
    m_secondaryVideoEnabled = false;
    m_secondaryVideoIsFullscreen = false;
    m_stillMode = BLURAY_STILL_NONE;
    m_stillTime = 0;
    m_inMenu = false;

    // First, attempt to initialize the disc in HDMV navigation mode.
    // If this fails, fall back to the traditional built-in title switching
    // mode.
    if (m_tryHDMVNavigation && m_firstPlaySupported && bd_play(bdnav))
    {
        VERBOSE(VB_IMPORTANT, LOC + QString("Using HDMV navigation mode."));
        m_isHDMVNavigation = true;

        // Register the Menu Overlay Callback
        bd_register_overlay_proc(bdnav, this, HandleOverlayCallback);
    }
    else
    {
        VERBOSE(VB_IMPORTANT, LOC + QString("Using title navigation mode."));

        // Loop through the relevant titles and find the longest
        uint64_t titleLength = 0;
        uint64_t margin      = 90000 << 4; // approx 30s
        BLURAY_TITLE_INFO *titleInfo = NULL;
        for( unsigned i = 0; i < m_numTitles; ++i)
        {
            titleInfo = GetTitleInfo(i);
            if (titleLength == 0 ||
                (titleInfo->duration > (titleLength + margin)))
            {
                m_mainTitle = titleInfo->idx;
                titleLength = titleInfo->duration;
            }
        }

        SwitchTitle(m_mainTitle);
    }

    readblocksize   = BD_BLOCK_SIZE * 62;
    setswitchtonext = false;
    ateof           = false;
    commserror      = false;
    numfailures     = 0;
    rawbitrate      = 8000;
    CalcReadAheadThresh();

    rwlock.unlock();

    mythfile_open_register_callback(filename.toLatin1().data(), this, NULL);
    return true;
}
Esempio n. 8
0
int main(int argc, char *argv[])
{
    int title = -1;
    int verbose = 0;
    int args = 0;

    /*
     * parse arguments
     */

    if (argc < 2) {
        printf("\nUsage:\n   %s [-v] [-t <title>] <media_path> [<keyfile_path>]\n\n", argv[0]);
        return -1;
    }

    if (!strcmp(argv[1+args], "-v")) {
        verbose = 1;
        args++;
    }

    if (!strcmp(argv[1+args], "-t")) {
        args++;
        title = atoi(argv[1+args]);
        args++;
        printf("Requested title %d\n", title);
    }

    if (verbose) {
        printf("Enabling verbose debug\n");
        bd_set_debug_mask(bd_get_debug_mask() | DBG_HDMV | DBG_BLURAY);
    }

    printf("\n");

    /*
     * open and setup
     */

    BLURAY  *bd = bd_open(argv[1+args], argv[2+args]);

    if (!bd) {
        printf("bd_open(\'%s\') failed\n", argv[1]);
        return -1;
    }

    bd_set_player_setting    (bd, BLURAY_PLAYER_SETTING_PARENTAL,     99);
    bd_set_player_setting_str(bd, BLURAY_PLAYER_SETTING_AUDIO_LANG,   "eng");
    bd_set_player_setting_str(bd, BLURAY_PLAYER_SETTING_PG_LANG,      "eng");
    bd_set_player_setting_str(bd, BLURAY_PLAYER_SETTING_MENU_LANG,    "eng");
    bd_set_player_setting_str(bd, BLURAY_PLAYER_SETTING_COUNTRY_CODE, NULL);

    /*
     * play
     */

    printf("Running first play movie object\n");

    fflush(stdout);
    bd_play(bd);

    _print_events(bd);

    printf("\n");

    /*
     * play title
     */

    if (title >= 0) {
        printf("Playing title %d\n", title);

        fflush(stdout);
        bd_play_title(bd, title);

        _print_events(bd);

        printf("\n");
    }

    /*
     * play playlist
     */

    _play_pl(bd);

    _play_pl(bd);

    _play_pl(bd);

    /*
     * clean up
     */

    bd_close(bd);

    return 0;
}
Esempio n. 9
0
int
main(int argc, char *argv[])
{
    int title_no = -1;
    int playlist = -1;
    int angle = 0;
    char *bdpath = NULL, *dest = NULL;
    FILE *out;
    int opt;
    int verbose = 0;
    int64_t total = 0;
    int64_t pos, end_pos = -1;
    size_t size, wrote;
    int bytes;
    int title_count;
    BLURAY *bd;
    int chapter_start = 0;
    int chapter_end = -1;
    uint8_t buf[BUF_SIZE];
    char *keyfile = NULL;
    BLURAY_TITLE_INFO *ti;

    do {
        opt = getopt(argc, argv, OPTS);
        switch (opt) {
            case -1:
                if (optind < argc && bdpath == NULL) {
                    bdpath = argv[optind];
                    optind++;
                    opt = 1;
                }
                else if (optind < argc && dest == NULL) {
                    dest = argv[optind];
                    optind++;
                    opt = 1;
                }
                break;

            case 'c': {
                int match;
                match = sscanf(optarg, "%d-%d", &chapter_start, &chapter_end);
                if (match == 1) {
                    chapter_end = chapter_start + 1;
                }
                chapter_start--;
                chapter_end--;
            } break;

            case 'k':
                keyfile = optarg;
                break;

            case 'a':
                angle = atoi(optarg);
                angle--;
                break;

            case 't':
                if (playlist >= 0) {
                    _usage(argv[0]);
                }
                title_no = atoi(optarg);
                title_no--;
                break;

            case 'p':
                if (title_no >= 0) {
                    _usage(argv[0]);
                }
                playlist = atoi(optarg);
                break;

            case 'v':
                verbose = 1;
                break;

            default:
                _usage(argv[0]);
                break;
        }
    } while (opt != -1);

    if (title_no < 0 && playlist < 0) {
        _usage(argv[0]);
    }
    if (optind < argc) {
        _usage(argv[0]);
    }

    bd = bd_open(bdpath, keyfile);
    if (bd == NULL) {
        fprintf(stderr, "Failed to open disc: %s\n", bdpath);
        return 1;
    }

    title_count = bd_get_titles(bd, TITLES_RELEVANT, 0);
    if (title_count <= 0) {
        fprintf(stderr, "No titles found: %s\n", bdpath);
        return 1;
    }

    if (title_no >= 0) {
        if (!bd_select_title(bd, title_no)) {
            fprintf(stderr, "Failed to open title: %d\n", title_no);
            return 1;
        }
        ti = bd_get_title_info(bd, title_no, angle);

    } else {
        if (!bd_select_playlist(bd, playlist)) {
            fprintf(stderr, "Failed to open playlist: %d\n", playlist);
            return 1;
        }
        ti = bd_get_playlist_info(bd, playlist, angle);
    }

    if (dest) {
        out = fopen(dest, "wb");
        if (out == NULL) {
            fprintf(stderr, "Failed to open destination: %s\n", dest);
            return 1;
        }
    } else {
        out = stdout;
    }

    if (angle >= (int)ti->angle_count) {
        fprintf(stderr, "Invalid angle %d > angle count %d. Using angle 1.\n", 
                angle+1, ti->angle_count);
        angle = 0;
    }
    bd_select_angle(bd, angle);

    if (chapter_start >= (int)ti->chapter_count) {
        fprintf(stderr, "First chapter %d > chapter count %d\n", 
                chapter_start+1, ti->chapter_count);
        return 1;
    }
    if (chapter_end >= (int)ti->chapter_count) {
        chapter_end = -1;
    }
    if (chapter_end >= 0) {
        end_pos = bd_chapter_pos(bd, chapter_end);
    }
    bd_free_title_info(ti);

    bd_seek_chapter(bd, chapter_start);
    pos = bd_tell(bd);
    while (end_pos < 0 || pos < end_pos) {
        size = BUF_SIZE;
        if (size > (size_t)(end_pos - pos)) {
            size = end_pos - pos;
        }
        bytes = bd_read(bd, buf, size);
        if (bytes <= 0) {
            break;
        }
        pos = bd_tell(bd);
        wrote = fwrite(buf, 1, bytes, out);
        if (wrote != (size_t)bytes) {
            fprintf(stderr, "read/write sizes do not match: %d/%zu\n", bytes, wrote);
        }
        if (wrote == 0) {
            if (ferror(out)) {
                perror("Write error");
            }
            break;
        }
        total += wrote;
    }
    if (verbose) {
        fprintf(stderr, "Wrote %"PRId64" bytes\n", total);
    }
    bd_close(bd);
    fclose(out);
    return 0;
}
Esempio n. 10
0
static void
bdmv_metadata_thread (GSimpleAsyncResult *result,
                      GObject *object,
                      GCancellable *cancellable)
{
  BLURAY *bd;
  META_DL *meta;
  GError *error;
  GFile *file;
  char *disc_root;
  char *icon;
  char *name;
  const char *lang;

  file = G_FILE (object);

  disc_root = g_file_get_path (file);
  bd = bd_open (disc_root, NULL);
  g_free (disc_root);

  if (bd == NULL)
    {
      error = g_error_new_literal (G_IO_ERROR,
                                   G_IO_ERROR_FAILED,
                                   "Device is not a Blu-Ray disc");
      goto error;
    }

  lang = get_iso_639_3_for_locale ();
  if (lang != NULL)
    bd_set_player_setting_str (bd, BLURAY_PLAYER_SETTING_MENU_LANG, lang);

  meta = bd_get_meta (bd);
  if (meta == NULL)
    {
      error = g_error_new_literal (G_IO_ERROR,
                                   G_IO_ERROR_FAILED,
                                   "Device is not a Blu-Ray disc, or has no metadata");
      bd_close (bd);
      goto error;
    }
  name = icon = NULL;

  if (meta != NULL)
    {
      if (meta->di_name && *meta->di_name)
        name = g_strdup (meta->di_name);
      icon = g_strdup (get_icon (meta));
    }

  /* We're missing either an icon, or the name */
  if (!name || !icon)
    {
      bd_set_player_setting_str (bd, BLURAY_PLAYER_SETTING_MENU_LANG, "eng");
      meta = bd_get_meta (bd);

      if (meta != NULL && name == NULL && meta->di_name && *meta->di_name)
        name = meta->di_name;

      if (meta != NULL && icon == NULL)
        icon = g_strdup (get_icon (meta));
    }

  /* Set the results */
  if (icon != NULL)
    {
      char *icon_path;
      GFile *icon_file;

      icon_path = g_strdup_printf ("BDMV/META/DL/%s", icon);
      g_free (icon);
      icon_file = g_file_resolve_relative_path (file, icon_path);
      g_free (icon_path);

      g_simple_async_result_set_op_res_gpointer (result,
                                                 g_file_icon_new (icon_file),
                                                 NULL);
    }
  else
    {
      g_simple_async_result_set_op_res_gpointer (result, NULL, NULL);
    }

  if (name != NULL)
    g_object_set_data_full (G_OBJECT (result), "name", name, g_free);

  bd_close (bd);

  return;

error:
  g_simple_async_result_set_from_error (result, error);
  g_simple_async_result_set_op_res_gpointer (result, NULL, NULL);
  g_error_free (error);
}
Esempio n. 11
0
static int bluray_stream_open(stream_t *s, int mode,
                              void *opts, int *file_format)
{
    struct stream_priv_s *p = opts;
    struct bluray_priv_s *b;

    BLURAY_TITLE_INFO *info = NULL;
    BLURAY *bd;

    int title, title_guess, title_count;
    uint64_t title_size;

    unsigned int angle = 0;
    uint64_t max_duration = 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, angle);
    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, angle);
        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);
        mp_msg(MSGT_IDENTIFY, MSGL_V,
               "ID_BLURAY_TITLE_%d_PLAYLIST=%05d\n", i + 1, ti->playlist);

        /* 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, angle);
    if (!info)
        goto err_no_info;

    /* 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->control     = bluray_stream_control;

    b                  = calloc(1, sizeof(struct bluray_priv_s));
    b->bd              = bd;
    b->current_angle   = angle;
    b->current_title   = title;

    s->end_pos     = title_size;
    s->sector_size = BLURAY_SECTOR_SIZE;
    s->flags       = mode | MP_STREAM_SEEK;
    s->priv        = b;
    s->type        = STREAMTYPE_BLURAY;
    s->url         = strdup("br://");

    mp_msg(MSGT_OPEN, MSGL_V, "Blu-ray successfully opened.\n");

    return STREAM_OK;
}
Esempio n. 12
0
int main(int argc, char *argv[])
{
    BLURAY *bd;
    int count, ii, opt;
    unsigned int seconds = 0;
    unsigned int flags = TITLES_RELEVANT;
    char *bd_dir = NULL;

    BD_DEBUG(DBG_BLURAY,"\nListing titles:\n");

    do
    {
        opt = getopt(argc, argv, OPTS);
        switch (opt)
        {
            case -1:
                if (optind < argc && bd_dir == NULL)
                {
                    bd_dir = argv[optind];
                    optind++;
                    opt = 1;
                }
                break;
            case 'a':
                flags = TITLES_ALL;
                break;
            case 's':
                seconds = strtol(optarg, NULL, 0);
                break;
            case 'h':
            default:
                _usage(argv[0]);
                break;
        }
    } while (opt != -1);

    if (bd_dir == NULL)
    {
        _usage(argv[0]);
    }
    bd = bd_open(bd_dir, NULL);

    count = bd_get_titles(bd, flags, seconds);
    for (ii = 0; ii < count; ii++)
    {
        BLURAY_TITLE_INFO* ti;
        ti = bd_get_title_info(bd, ii, 0);
        printf(
       "index: %d duration: %02"PRIu64":%02"PRIu64":%02"PRIu64" chapters: %3d angles: %2u clips: %3u (playlist: %05d.mpls) "
       "V:%d A:%-2d PG:%-2d IG:%-2d SV:%d SA:%d\n",
              ii + 1,
              (ti->duration / 90000) / (3600),
              ((ti->duration / 90000) % 3600) / 60,
              ((ti->duration / 90000) % 60),
              ti->chapter_count, ti->angle_count, ti->clip_count, ti->playlist,
              ti->clips[0].video_stream_count,
              ti->clips[0].audio_stream_count,
              ti->clips[0].pg_stream_count,
              ti->clips[0].ig_stream_count,
              ti->clips[0].sec_video_stream_count,
              ti->clips[0].sec_audio_stream_count
        );
        bd_free_title_info(ti);
    }
    bd_close(bd);
    return 0;
}
Esempio n. 13
0
bool BDRingBuffer::OpenFile(const QString &lfilename, uint retry_ms)
{
    VERBOSE(VB_IMPORTANT, LOC + QString("Opened BDRingBuffer device at %1")
            .arg(lfilename.toLatin1().data()));

    rwlock.lockForWrite();

    if (bdnav)
    {
        if (m_currentTitleInfo)
            bd_free_title_info(m_currentTitleInfo);
        bd_close(bdnav);
        bdnav = NULL;
    }

    filename = lfilename;

    QString keyfile = QString("%1/KEYDB.cfg").arg(GetConfDir());
    QByteArray keyarray = keyfile.toAscii();
    const char *keyfilepath = keyarray.data();

    bdnav = bd_open(lfilename.toLatin1().data(), keyfilepath);

    if (!bdnav)
    {
        rwlock.unlock();
        return false;
    }

    // Check disc to see encryption status, menu and navigation types.
    const BLURAY_DISC_INFO *discinfo = bd_get_disc_info(bdnav);
    if (discinfo)
    {
        VERBOSE(VB_PLAYBACK, QString(
                    "*** Blu-ray Disc Information ***\n"
                    "First Play Supported: %1\n"
                    "Top Menu Supported: %2\n"
                    "Number of HDMV Titles: %3\n"
                    "Number of BD-J Titles: %4\n"
                    "Number of Unsupported Titles: %5\n"
                    "AACS present on disc: %6\n"
                    "libaacs used: %7\n"
                    "AACS handled: %8\n"
                    "BD+ present on disc: %9\n"
                    "libbdplus used: %10\n"
                    "BD+ handled: %11")
                .arg(discinfo->first_play_supported ? "yes" : "no")
                .arg(discinfo->top_menu_supported ? "yes" : "no")
                .arg(discinfo->num_hdmv_titles)
                .arg(discinfo->num_bdj_titles)
                .arg(discinfo->num_unsupported_titles)
                .arg(discinfo->aacs_detected ? "yes" : "no")
                .arg(discinfo->libaacs_detected ? "yes" : "no")
                .arg(discinfo->aacs_handled ? "yes" : "no")
                .arg(discinfo->bdplus_detected ? "yes" : "no")
                .arg(discinfo->libbdplus_detected ? "yes" : "no")
                .arg(discinfo->bdplus_handled ? "yes" : "no"));
    }

    // The following settings affect HDMV navigation
    // (default audio track selection,
    // parental controls, menu language, etc.  They are not yet used.

    // Set parental level "age" to 99 for now.  TODO: Add support for FE level
    bd_set_player_setting(bdnav, BLURAY_PLAYER_SETTING_PARENTAL, 99);

    // Set preferred language to FE guide language
    const char *langpref = gCoreContext->GetSetting(
        "ISO639Language0", "eng").toLatin1().data();
    QString QScountry  = gCoreContext->GetLocale()->GetCountryCode().toLower();
    const char *country = QScountry.toLatin1().data();
    bd_set_player_setting_str(
        bdnav, BLURAY_PLAYER_SETTING_AUDIO_LANG, langpref);

    // Set preferred presentation graphics language to the FE guide language
    bd_set_player_setting_str(bdnav, BLURAY_PLAYER_SETTING_PG_LANG, langpref);

    // Set preferred menu language to the FE guide language
    bd_set_player_setting_str(bdnav, BLURAY_PLAYER_SETTING_MENU_LANG, langpref);

    // Set player country code via MythLocale. (not a region setting)
    bd_set_player_setting_str(
        bdnav, BLURAY_PLAYER_SETTING_COUNTRY_CODE, country);

    int regioncode = 0;
    regioncode = gCoreContext->GetNumSetting("BlurayRegionCode");
    if (regioncode > 0)
        bd_set_player_setting(bdnav, BLURAY_PLAYER_SETTING_REGION_CODE, regioncode);

    VERBOSE(VB_IMPORTANT, LOC + QString("Using %1 as keyfile...")
            .arg(QString(keyfilepath)));

    // Return an index of relevant titles (excludes dupe clips + titles)
    m_numTitles = bd_get_titles(bdnav, TITLES_RELEVANT);
    m_mainTitle = 0;
    m_currentTitleLength = 0;
    m_titlesize = 0;
    m_currentTime = 0;
    m_currentTitleInfo = NULL;
    m_currentTitleAngleCount = 0;

    // Mostly event-driven values below
    m_currentAngle = 0;
    m_currentTitle = 0;
    m_currentPlaylist = 0;
    m_currentPlayitem = 0;
    m_currentChapter = 0;
    m_currentAudioStream = 0;
    m_currentIGStream = 0;
    m_currentPGTextSTStream = 0;
    m_currentSecondaryAudioStream = 0;
    m_currentSecondaryVideoStream = 0;
    m_PGTextSTEnabled = false;
    m_secondaryAudioEnabled = false;
    m_secondaryVideoEnabled = false;
    m_secondaryVideoIsFullscreen = false;
    m_still = 0;
    m_inMenu = false;

    VERBOSE(VB_IMPORTANT, LOC + QString("Found %1 relevant titles.")
            .arg(m_numTitles));

    // Loop through the relevant titles and find the longest
    uint64_t titleLength = 0;
    uint64_t margin      = 90000 << 4; // approx 30s
    BLURAY_TITLE_INFO *titleInfo = NULL;
    for( unsigned i = 0; i < m_numTitles; ++i)
    {
        titleInfo = bd_get_title_info(bdnav, i);
        if (titleLength == 0 ||
            (titleInfo->duration > (titleLength + margin)))
        {
            m_mainTitle = titleInfo->idx;
            titleLength = titleInfo->duration;
        }
    }

    bd_free_title_info(titleInfo);

    SwitchTitle(m_mainTitle);

#if 0
    // First, attempt to initialize the disc in HDMV navigation mode.
    // If this fails, fall back to the traditional built-in title switching
    // mode.
    if (bd_play(bdnav))
    {
        m_is_hdmv_navigation = true;

        // Initialize the HDMV event queue
        HandleBDEvents();

        // Register the Menu Overlay Callback
        bd_register_overlay_proc(bdnav, this, HandleOverlayCallback);
    }
#endif

    readblocksize   = BD_BLOCK_SIZE * 62;
    setswitchtonext = false;
    ateof           = false;
    commserror      = false;
    numfailures     = 0;
    rawbitrate      = 8000;
    CalcReadAheadThresh();

    rwlock.unlock();

    return true;
}
Esempio n. 14
0
int BD_Parser(FILE *fp, FileInfo *finfo, int is_dir)
{
	int nRet = 0;
	int ii;
	int title_guess, title_count;
	uint64_t max_duration = 0;
	uint64_t max_duration2 = 0;
	MPLS_PL * pl = NULL, * pl2 = NULL, * def_pl;
	BLURAY  *bd = NULL;
	parse_priv * par_priv = NULL;
	BLURAY_TITLE_MAX_DUR *title_max = NULL;
	int title_id[2] = {-1};
	int mpls_id[2] = {-1};

	mp_msg("BD_Parser\n");
	if (finfo->priv != NULL)
	{
		par_priv = (parse_priv *)finfo->priv;
		bd = par_priv->bd;
		title_count = par_priv->title_num;
		free(par_priv);
		finfo->priv = NULL;
	} else {
		bd = bd_open(finfo->filepath, NULL);
		if (bd)
			title_count = bd_get_titles(bd, TITLES_RELEVANT);
	}
	//goto error_end;

	if (bd)
	{
		title_max = bd_get_title_max2_dur(bd);
		if (title_max != NULL)
		{
			pl = bd_title_filter(bd, title_max->dur_first_count, title_max->dur_first, is_dir, finfo->filepath, &title_id[0], &mpls_id[0]);
			if (title_max->dur_second_count > 0)
			{
				pl2 = bd_title_filter(bd, title_max->dur_second_count, title_max->dur_second, is_dir, finfo->filepath, &title_id[1], &mpls_id[1]);
			}
			mp_msg("title_id: %d %d, mpls_id: %d %d\n", title_id[0], title_id[1],
					mpls_id[0], mpls_id[1]);
			title_guess = title_id[0];

			bd_free_title_max2_dur(title_max);
		}

		def_pl = pl;
		//if (pl2 != NULL)
		if (pl2 != NULL && pl != NULL)
		{
			MPLS_PI *pi, *pi2;
			pi = &pl->play_item[0];
			pi2 = &pl2->play_item[0];
			mp_msg("playlist 1: c: %d, v: %d, a: %d, s: %d, d: %d\n", bd_get_chapters(pl),
					pi->stn.num_video, pi->stn.num_audio, pi->stn.num_pg, _pl_duration(pl)/45000);
			mp_msg("playlist 2: c: %d, v: %d, a: %d, s: %d, d: %d\n", bd_get_chapters(pl2),
					pi2->stn.num_video, pi2->stn.num_audio, pi2->stn.num_pg, _pl_duration(pl2)/45000);
			if ((bd_get_chapters(pl) < bd_get_chapters(pl2)) &&
					(pi->stn.num_audio <= pi2->stn.num_audio) )
			{
				// playlist 2 have more chapters and audio use it.
				def_pl = pl2;
				title_guess = title_id[1];
			} else {
				if ((pl->list_count > 0) && (pl2->list_count > 0))
				{
					if ( (pi2->stn.num_audio >= pi->stn.num_audio) &&
							(pi2->stn.num_pg > pi->stn.num_pg) &&
							(bd_get_chapters(pl2) >= bd_get_chapters(pl)) )	//Barry 2011-07-29 fix mantis: 5605
					{
						def_pl = pl2;
						title_guess = title_id[1];
					}
#if 1	//Barry 2011-07-13 fix mantis: 5192
					if ((_pl_duration(pl)/45000) > 60000)
					{
						def_pl = pl2;
						title_guess = title_id[1];
					}
#endif
				}
			}
		}
		else if (pl2 != NULL && pl == NULL)
		{
			// playlist 2 have more chapters and audio use it.
			def_pl = pl2;
			title_guess = title_id[1];
			//printf("***********  Switch to playlist 2 **********\n");
		}

		nRet = set_mpls_info(def_pl, finfo);
		if (nRet == 1)
		{
			MPLS_PI *pi;
			int chapters = bd_get_chapters(def_pl);
			((bd_priv_t *)finfo->priv)->chapter_num = chapters;
			((bd_priv_t *)finfo->priv)->title = title_guess;
			pi = &def_pl->play_item[0];
			if (pi != NULL)
				((bd_priv_t *)finfo->priv)->file_id = atoi(pi->clip[0].clip_id);
		}

error_end:
		if (pl != NULL) mpls_free(pl);
		if (pl2 != NULL) mpls_free(pl2);
		if (bd != NULL) bd_close(bd);
	}

	return nRet;
}