Exemple #1
0
static int d_open(demuxer_t *demuxer, enum demux_check check)
{
    struct priv *p = demuxer->priv = talloc_zero(demuxer, struct priv);

    if (check != DEMUX_CHECK_FORCE)
        return -1;

    char *demux = "+lavf";
    if (demuxer->stream->uncached_type == STREAMTYPE_CDDA)
        demux = "+rawaudio";

    char *t = NULL;
    stream_control(demuxer->stream, STREAM_CTRL_GET_DISC_NAME, &t);
    if (t) {
        mp_tags_set_bstr(demuxer->metadata, bstr0("TITLE"), bstr0(t));
        talloc_free(t);
    }

    // Initialize the playback time. We need to read _some_ data to get the
    // correct stream-layer time (at least with libdvdnav).
    stream_peek(demuxer->stream, 1);
    reset_pts(demuxer);

    p->slave = demux_open(demuxer->stream, demux, NULL, demuxer->global);
    if (!p->slave)
        return -1;

    // So that we don't miss initial packets of delayed subtitle streams.
    demux_set_stream_autoselect(p->slave, true);

    // Can be seekable even if the stream isn't.
    demuxer->seekable = true;

    // With cache enabled, the stream can be seekable. This causes demux_lavf.c
    // (actually libavformat/mpegts.c) to seek sometimes when reading a packet.
    // It does this to seek back a bit in case the current file position points
    // into the middle of a packet.
    demuxer->stream->seekable = false;

    add_dvd_streams(demuxer);
    add_streams(demuxer);
    add_stream_chapters(demuxer);

    return 0;
}
Exemple #2
0
static int d_open(demuxer_t *demuxer, enum demux_check check)
{
    struct priv *p = demuxer->priv = talloc_zero(demuxer, struct priv);

    if (check != DEMUX_CHECK_FORCE)
        return -1;

    struct demuxer_params params = {.force_format = "+lavf"};

    if (demuxer->stream->uncached_type == STREAMTYPE_CDDA)
        params.force_format = "+rawaudio";

    char *t = NULL;
    stream_control(demuxer->stream, STREAM_CTRL_GET_DISC_NAME, &t);
    if (t) {
        mp_tags_set_str(demuxer->metadata, "TITLE", t);
        talloc_free(t);
    }

    // Initialize the playback time. We need to read _some_ data to get the
    // correct stream-layer time (at least with libdvdnav).
    stream_peek(demuxer->stream, 1);
    reset_pts(demuxer);

    p->slave = demux_open(demuxer->stream, &params, demuxer->global);
    if (!p->slave)
        return -1;

    // So that we don't miss initial packets of delayed subtitle streams.
    demux_set_stream_autoselect(p->slave, true);

    // With cache enabled, the stream can be seekable. This causes demux_lavf.c
    // (actually libavformat/mpegts.c) to seek sometimes when reading a packet.
    // It does this to seek back a bit in case the current file position points
    // into the middle of a packet.
    if (demuxer->stream->uncached_type != STREAMTYPE_CDDA) {
        demuxer->stream->seekable = false;

        // Can be seekable even if the stream isn't.
        demuxer->seekable = true;

        demuxer->rel_seeks = true;
    }

    add_dvd_streams(demuxer);
    add_streams(demuxer);
    add_stream_chapters(demuxer);

    return 0;
}

static void d_close(demuxer_t *demuxer)
{
    struct priv *p = demuxer->priv;
    free_demuxer(p->slave);
}

static int d_control(demuxer_t *demuxer, int cmd, void *arg)
{
    struct priv *p = demuxer->priv;

    switch (cmd) {
    case DEMUXER_CTRL_GET_TIME_LENGTH: {
        double len;
        if (stream_control(demuxer->stream, STREAM_CTRL_GET_TIME_LENGTH, &len) < 1)
            break;
        *(double *)arg = len;
        return DEMUXER_CTRL_OK;
    }
    case DEMUXER_CTRL_RESYNC:
        demux_flush(p->slave);
        break; // relay to slave demuxer
    case DEMUXER_CTRL_SWITCHED_TRACKS:
        reselect_streams(demuxer);
        return DEMUXER_CTRL_OK;
    }
    return demux_control(p->slave, cmd, arg);
}

const demuxer_desc_t demuxer_desc_disc = {
    .name = "disc",
    .desc = "CD/DVD/BD wrapper",
    .fill_buffer = d_fill_buffer,
    .open = d_open,
    .close = d_close,
    .seek = d_seek,
    .control = d_control,
};