コード例 #1
0
ファイル: BDDemuxer.cpp プロジェクト: JERUKA9/LAVFilters
int64_t CBDDemuxer::BDByteStreamSeek(void *opaque,  int64_t offset, int whence)
{
  CBDDemuxer *demux = (CBDDemuxer *)opaque;
  BLURAY *bd = demux->m_pBD;

  int64_t pos = 0;
  if (whence == SEEK_SET) {
    pos = offset;
  } else if (whence == SEEK_CUR) {
    if (offset == 0)
      return bd_tell(bd);
    pos = bd_tell(bd) + offset;
  } else if (whence == SEEK_END) {
    pos = bd_get_title_size(bd) - offset;
  } else if (whence == AVSEEK_SIZE) {
    return bd_get_title_size(bd);
  } else
    return -1;
  if (pos < 0)
    pos = 0;
  int64_t achieved = bd_seek(bd, pos);
  if (pos > achieved) {
    offset = pos - achieved;
    DbgLog((LOG_TRACE, 10, L"BD Seek to %I64d, achieved %I64d, correcting target by %I64d", pos, achieved, offset));
    uint8_t *dump_buffer = (uint8_t *)CoTaskMemAlloc(6144);
    while (offset > 0) {
      bd_read(bd, dump_buffer, min(offset, 6144));
      offset -= 6144;
    }
    CoTaskMemFree(dump_buffer);
    achieved = bd_tell(bd);
  }
  return achieved;
}
コード例 #2
0
ファイル: BDDemuxer.cpp プロジェクト: betaking/LAVFilters
int64_t BDByteStreamSeek(void *opaque,  int64_t offset, int whence)
{
  BLURAY *bd = (BLURAY *)opaque;

  int64_t pos = 0;
  if (whence == SEEK_SET) {
    pos = offset;
  } else if (whence == SEEK_CUR) {
    if (offset == 0)
      return bd_tell(bd);
    pos = bd_tell(bd) + offset;
  } else if (whence == SEEK_END) {
    pos = bd_get_title_size(bd) - offset;
  } else if (whence == AVSEEK_SIZE) {
    return bd_get_title_size(bd);
  } else
    return -1;
  return bd_seek(bd, pos);
}
コード例 #3
0
ファイル: hdmv_test.c プロジェクト: flyingtime/boxee
static void _read_to_eof(BLURAY *bd)
{
    BD_EVENT ev;
    int      bytes;
    uint64_t total = 0;
    uint8_t  buf[6144];

    bd_seek(bd, bd_get_title_size(bd) - 6144);

    do {
        bytes = bd_read_ext(bd, buf, 6144, &ev);
        total += bytes < 0 ? 0 : bytes;
        _print_event(&ev);
    } while (bytes > 0);

    printf("_read_to_eof(): read %"PRIu64" bytes\n", total);
}
コード例 #4
0
bool BDRingBuffer::UpdateTitleInfo(uint32_t index)
{
    m_titleChanged = true;
    m_currentTitleLength = m_currentTitleInfo->duration;
    m_currentTitleAngleCount = m_currentTitleInfo->angle_count;
    m_currentAngle = 0;
    m_titlesize = bd_get_title_size(bdnav);
    uint32_t chapter_count = m_currentTitleInfo->chapter_count;
    VERBOSE(VB_IMPORTANT, LOC + QString("Selected title/playlist: index %1. "
                                        "Duration: %2 (%3 mins) "
                                        "Number of Chapters: %4 Number of Angles: %5 "
                                        "Title Size: %6")
                                        .arg(index)
                                        .arg(m_currentTitleLength)
                                        .arg(m_currentTitleLength / (90000 * 60))
                                        .arg(chapter_count)
                                        .arg(m_currentTitleAngleCount)
                                        .arg(m_titlesize));
    VERBOSE(VB_PLAYBACK, LOC + QString("Frame Rate: %1").arg(GetFrameRate()));
    if (chapter_count)
    {
        for (uint i = 0; i < chapter_count; i++)
        {
            uint64_t total_secs = GetChapterStartTime(i);
            uint64_t framenum   = GetChapterStartFrame(i);
            int hours = (int)total_secs / 60 / 60;
            int minutes = ((int)total_secs / 60) - (hours * 60);
            double secs = (double)total_secs - (double)(hours * 60 * 60 + minutes * 60);
            VERBOSE(VB_PLAYBACK, LOC + QString("Chapter %1 found @ [%2:%3:%4]->%5")
                    .arg(QString().sprintf("%02d", i + 1))
                    .arg(QString().sprintf("%02d", hours))
                    .arg(QString().sprintf("%02d", minutes))
                    .arg(QString().sprintf("%06.3f", secs))
                    .arg(framenum));
        }
    }
    return true;
}
コード例 #5
0
ファイル: bdringbuffer.cpp プロジェクト: DocOnDev/mythtv
uint64_t BDRingBuffer::GetTotalReadPosition(void)
{
    if (bdnav)
        return bd_get_title_size(bdnav);
    return 0;
}
コード例 #6
0
ファイル: bdringbuffer.cpp プロジェクト: DocOnDev/mythtv
bool BDRingBuffer::UpdateTitleInfo(void)
{
    QMutexLocker locker(&m_infoLock);
    if (!m_currentTitleInfo)
        return false;

    m_titleChanged = true;
    m_currentTitleLength = m_currentTitleInfo->duration;
    m_currentTitleAngleCount = m_currentTitleInfo->angle_count;
    m_currentAngle = 0;
    m_titlesize = bd_get_title_size(bdnav);
    uint32_t chapter_count = GetNumChapters();
    uint64_t total_secs = m_currentTitleLength / 90000;
    int hours = (int)total_secs / 60 / 60;
    int minutes = ((int)total_secs / 60) - (hours * 60);
    double secs = (double)total_secs - (double)(hours * 60 * 60 + minutes * 60);
    QString duration = QString("%1:%2:%3")
                        .arg(QString().sprintf("%02d", hours))
                        .arg(QString().sprintf("%02d", minutes))
                        .arg(QString().sprintf("%02.1f", secs));
    VERBOSE(VB_IMPORTANT, LOC +
        QString("New title info: Index %1 Playlist: %2 Duration: %3 Chapters: %5")
                .arg(m_currentTitleInfo->idx).arg(m_currentTitleInfo->playlist)
                .arg(duration).arg(chapter_count));
    VERBOSE(VB_IMPORTANT, LOC +
        QString("New title info: Clips: %6 Angles: %7 Title Size: %8 Frame Rate %9")
                .arg(m_currentTitleInfo->clip_count)
                .arg(m_currentTitleAngleCount).arg(m_titlesize)
                .arg(GetFrameRate()));

    if (chapter_count)
    {
        for (uint i = 0; i < chapter_count; i++)
        {
            uint64_t total_secs = GetChapterStartTime(i);
            uint64_t framenum   = GetChapterStartFrame(i);
            int hours = (int)total_secs / 60 / 60;
            int minutes = ((int)total_secs / 60) - (hours * 60);
            double secs = (double)total_secs - (double)(hours * 60 * 60 + minutes * 60);
            VERBOSE(VB_PLAYBACK, LOC + QString("Chapter %1 found @ [%2:%3:%4]->%5")
                    .arg(QString().sprintf("%02d", i + 1))
                    .arg(QString().sprintf("%02d", hours))
                    .arg(QString().sprintf("%02d", minutes))
                    .arg(QString().sprintf("%06.3f", secs))
                    .arg(framenum));
        }
    }

    int still = BLURAY_STILL_NONE;
    int time  = 0;
    if (m_currentTitleInfo->clip_count)
    {
        for (uint i = 0; i < m_currentTitleInfo->clip_count; i++)
        {
            VERBOSE(VB_PLAYBACK, LOC + QString("Clip %1 stillmode %2 "
                                               "stilltime %3 videostreams %4 "
                                               "audiostreams %5 igstreams %6")
                    .arg(i).arg(m_currentTitleInfo->clips[i].still_mode)
                    .arg(m_currentTitleInfo->clips[i].still_time)
                    .arg(m_currentTitleInfo->clips[i].video_stream_count)
                    .arg(m_currentTitleInfo->clips[i].audio_stream_count)
                    .arg(m_currentTitleInfo->clips[i].ig_stream_count));
            still |= m_currentTitleInfo->clips[i].still_mode;
            time = m_currentTitleInfo->clips[i].still_time;
        }
    }

    if (m_currentTitleInfo->clip_count > 1 && still != BLURAY_STILL_NONE)
        VERBOSE(VB_IMPORTANT, LOC + "Warning: more than 1 clip, following still"
                                    " frame analysis may be wrong");
    if (still == BLURAY_STILL_TIME)
    {
        VERBOSE(VB_PLAYBACK, LOC +
            QString("Entering still frame (%1 seconds) UNSUPPORTED").arg(time));
    }
    else if (still == BLURAY_STILL_INFINITE)
    {
        VERBOSE(VB_PLAYBACK, LOC + "Entering infinite still frame.");
    }

    m_stillMode = still;
    m_stillTime = time;

    return true;
}
コード例 #7
0
ファイル: stream_bluray.c プロジェクト: 0p1pp1/mplayer
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;
}
コード例 #8
0
ファイル: stream_bluray.c プロジェクト: 0p1pp1/mplayer
static int bluray_stream_control(stream_t *s, int cmd, void *arg)
{
    struct bluray_priv_s *b = s->priv;

    switch (cmd) {

    case STREAM_CTRL_GET_NUM_CHAPTERS: {
        BLURAY_TITLE_INFO *ti;

        ti = bd_get_title_info(b->bd, b->current_title, b->current_angle);
        if (!ti)
            return STREAM_UNSUPPORTED;

        *((unsigned int *) arg) = ti->chapter_count;
        bd_free_title_info(ti);

        return 1;
    }

    case STREAM_CTRL_GET_CURRENT_TITLE: {
        *((unsigned int *) arg) = b->current_title;
        return 1;
    }

    case STREAM_CTRL_GET_CURRENT_CHAPTER: {
        *((unsigned int *) arg) = bd_get_current_chapter(b->bd);
        return 1;
    }

    case STREAM_CTRL_SEEK_TO_CHAPTER: {
        BLURAY_TITLE_INFO *ti;
        int chapter = *((unsigned int *) arg);
        int64_t pos;
        int r;

        ti = bd_get_title_info(b->bd, b->current_title, b->current_angle);
        if (!ti)
            return STREAM_UNSUPPORTED;

        if (chapter < 0 || chapter > ti->chapter_count) {
            bd_free_title_info(ti);
            return STREAM_UNSUPPORTED;
        }

        pos = bd_chapter_pos(b->bd, chapter);
        r = bluray_stream_seek(s, pos);
        bd_free_title_info(ti);

        return r ? 1 : STREAM_UNSUPPORTED;
    }

    case STREAM_CTRL_GET_TIME_LENGTH: {
        BLURAY_TITLE_INFO *ti = bd_get_title_info(b->bd, b->current_title, b->current_angle);
        if (!ti)
            return STREAM_UNSUPPORTED;
        *(double *)arg = ti->duration / 90000.0;
        return STREAM_OK;
    }
    case STREAM_CTRL_GET_SIZE:
        *(uint64_t*)arg = bd_get_title_size(b->bd);
        return STREAM_OK;

    case STREAM_CTRL_GET_CURRENT_TIME:
        *(double *)arg = bd_tell_time(b->bd) / 90000.0;
        return STREAM_OK;
    case STREAM_CTRL_SEEK_TO_TIME: {
        int64_t res;
        double target = *(double*)arg * 90000.0;
        BLURAY_TITLE_INFO *ti = bd_get_title_info(b->bd, b->current_title, b->current_angle);
        // clamp to ensure that out-of-bounds seeks do not simply do nothing.
        target = FFMAX(target, 0);
        if (ti && ti->duration > 1)
            target = FFMIN(target, ti->duration - 1);
        res = bd_seek_time(b->bd, target);
        if (res < 0)
            return STREAM_ERROR;
        s->pos = res;
        return 1;
    }

    case STREAM_CTRL_GET_NUM_ANGLES: {
        BLURAY_TITLE_INFO *ti;

        ti = bd_get_title_info(b->bd, b->current_title, b->current_angle);
        if (!ti)
            return STREAM_UNSUPPORTED;

        *((int *) arg) = ti->angle_count;
        bd_free_title_info(ti);

        return 1;
    }

    case STREAM_CTRL_GET_ANGLE: {
        *((int *) arg) = b->current_angle;
        return 1;
    }

    case STREAM_CTRL_SET_ANGLE: {
        BLURAY_TITLE_INFO *ti;
        int angle = *((int *) arg);

        ti = bd_get_title_info(b->bd, b->current_title, b->current_angle);
        if (!ti)
            return STREAM_UNSUPPORTED;

        if (angle < 0 || angle > ti->angle_count) {
            bd_free_title_info(ti);
            return STREAM_UNSUPPORTED;
        }

        b->current_angle = angle;
        bd_seamless_angle_change(b->bd, angle);
        bd_free_title_info(ti);

        return 1;
    }

    case STREAM_CTRL_GET_LANG: {
        struct stream_lang_req *req = arg;
        const BLURAY_STREAM_INFO *si;
        int count;
        BLURAY_TITLE_INFO *ti = get_langs(b, req->type, &si, &count);
        while (count-- > 0) {
            if (si->pid == req->id) {
                memcpy(req->buf, si->lang, 4);
                req->buf[4] = 0;
                bd_free_title_info(ti);
                return STREAM_OK;
            }
            si++;
        }
        if (ti)
            bd_free_title_info(ti);
        return STREAM_ERROR;
    }

    default:
        break;
    }

    return STREAM_UNSUPPORTED;
}
コード例 #9
0
JNIEXPORT jlong JNICALL Java_org_videolan_Libbluray_getTitleSizeN(JNIEnv * env,
        jclass cls, jlong np) {
    BDJAVA* bdj = (BDJAVA*)(intptr_t)np;
    return bd_get_title_size(bdj->bd);
}