Example #1
0
File: ao_openal.c Project: benf/mpv
static int init(struct ao *ao)
{
    float position[3] = {0, 0, 0};
    float direction[6] = {0, 0, 1, 0, -1, 0};
    ALCdevice *dev = NULL;
    ALCcontext *ctx = NULL;
    ALCint freq = 0;
    ALCint attribs[] = {ALC_FREQUENCY, ao->samplerate, 0, 0};
    int i;
    struct priv *p = ao->priv;
    if (ao_data) {
        MP_FATAL(ao, "Not reentrant!\n");
        return -1;
    }
    ao_data = ao;
    ao->no_persistent_volume = true;
    struct mp_chmap_sel sel = {0};
    for (i = 0; speaker_pos[i].id != -1; i++)
        mp_chmap_sel_add_speaker(&sel, speaker_pos[i].id);
    if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels))
        goto err_out;
    struct speaker speakers[MAX_CHANS];
    for (i = 0; i < ao->channels.num; i++) {
        speakers[i].id = -1;
        for (int n = 0; speaker_pos[n].id >= 0; n++) {
            if (speaker_pos[n].id == ao->channels.speaker[i])
                speakers[i] = speaker_pos[n];
        }
        if (speakers[i].id < 0) {
            MP_FATAL(ao, "Unknown channel layout\n");
            goto err_out;
        }
    }
    dev = alcOpenDevice(p->cfg_device && p->cfg_device[0] ? p->cfg_device : NULL);
    if (!dev) {
        MP_FATAL(ao, "could not open device\n");
        goto err_out;
    }
    ctx = alcCreateContext(dev, attribs);
    alcMakeContextCurrent(ctx);
    alListenerfv(AL_POSITION, position);
    alListenerfv(AL_ORIENTATION, direction);
    alGenSources(ao->channels.num, sources);
    for (i = 0; i < ao->channels.num; i++) {
        cur_buf[i] = 0;
        unqueue_buf[i] = 0;
        alGenBuffers(NUM_BUF, buffers[i]);
        alSourcefv(sources[i], AL_POSITION, speakers[i].pos);
        alSource3f(sources[i], AL_VELOCITY, 0, 0, 0);
    }
    alcGetIntegerv(dev, ALC_FREQUENCY, 1, &freq);
    if (alcGetError(dev) == ALC_NO_ERROR && freq)
        ao->samplerate = freq;
    ao->format = AF_FORMAT_S16_NE;
    tmpbuf = malloc(CHUNK_SIZE);
    return 0;

err_out:
    return -1;
}
Example #2
0
static int vf_open(vf_instance_t *vf)
{
    struct vf_priv_s *p = vf->priv;
    if (!vsscript_init()) {
        MP_FATAL(vf, "Could not initialize VapourSynth scripting.\n");
        return 0;
    }
    if (!p->cfg_file || !p->cfg_file[0]) {
        MP_FATAL(vf, "'file' parameter must be set.\n");
        return 0;
    }

    pthread_mutex_init(&p->lock, NULL);
    pthread_cond_init(&p->wakeup, NULL);
    vf->reconfig = NULL;
    vf->config = config;
    vf->filter_ext = filter_ext;
    vf->filter = NULL;
    vf->query_format = query_format;
    vf->control = control;
    vf->uninit = uninit;
    int maxbuffer = p->cfg_maxbuffer * p->cfg_maxrequests;
    p->buffered = talloc_array(vf, struct mp_image *, maxbuffer);
    p->max_requests = p->cfg_maxrequests;
    p->requested = talloc_zero_array(vf, struct mp_image *, p->max_requests);
    return 1;
}
Example #3
0
static int reconfig(struct vf_instance *vf, struct mp_image_params *in,
                    struct mp_image_params *out)
{
    struct vf_priv_s *p = vf->priv;

    *out = *in;
    p->fmt_in = *in;

    if (reinit_vs(vf) < 0)
        return -1;

    const VSVideoInfo *vi = p->vsapi->getVideoInfo(p->out_node);
    out->w = vi->width;
    out->h = vi->height;
    out->imgfmt = mp_from_vs(vi->format->id);
    if (!out->imgfmt) {
        MP_FATAL(vf, "Unsupported output format.\n");
        destroy_vs(vf);
        return -1;
    }

    struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(in->imgfmt);
    if (in->w % desc.align_x || in->h % desc.align_y) {
        MP_FATAL(vf, "VapourSynth does not allow unaligned/cropped video sizes.\n");
        destroy_vs(vf);
        return -1;
    }

    return 0;
}
Example #4
0
static bool create_context_egl(MPGLContext *ctx, EGLConfig config,
                               EGLNativeWindowType window, bool es)
{
    struct priv *p = ctx->priv;

    EGLint context_attributes[] = {
        // aka EGL_CONTEXT_MAJOR_VERSION_KHR
        EGL_CONTEXT_CLIENT_VERSION, es ? 2 : 3,
        EGL_NONE
    };

    p->egl_surface = eglCreateWindowSurface(p->egl_display, config, window, NULL);

    if (p->egl_surface == EGL_NO_SURFACE) {
        MP_FATAL(ctx->vo, "Could not create EGL surface!\n");
        return false;
    }

    p->egl_context = eglCreateContext(p->egl_display, config,
                                      EGL_NO_CONTEXT, context_attributes);

    if (p->egl_context == EGL_NO_CONTEXT) {
        MP_FATAL(ctx->vo, "Could not create EGL context!\n");
        return false;
    }

    eglMakeCurrent(p->egl_display, p->egl_surface, p->egl_surface,
                   p->egl_context);

    return true;
}
Example #5
0
static EGLConfig select_fb_config_egl(struct MPGLContext *ctx, bool es)
{
    struct priv *p = ctx->priv;
    const EGLint attributes[] = {
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_ALPHA_SIZE, 0,
        EGL_DEPTH_SIZE, 1,
        EGL_RENDERABLE_TYPE, es ? EGL_OPENGL_ES2_BIT : EGL_OPENGL_BIT,
        EGL_NONE
    };
    EGLint config_count;
    EGLConfig config;
    if (!eglChooseConfig(p->egl.display, attributes, &config, 1, &config_count)) {
        MP_FATAL(ctx->vo, "Failed to configure EGL.\n");
        return NULL;
    }
    if (!config_count) {
        MP_FATAL(ctx->vo, "Could not find EGL configuration!\n");
        return NULL;
    }
    return config;
}
Example #6
0
static void uninit(struct vo *vo)
{
    struct vo_priv *p = vo->priv;

    pthread_mutex_lock(&p->ctx->lock);
    mp_image_unrefp(&p->ctx->next_frame);
    mp_image_unrefp(&p->ctx->waiting_frame);
    p->ctx->img_params = (struct mp_image_params){0};
    p->ctx->reconfigured = true;
    p->ctx->active = NULL;
    pthread_mutex_unlock(&p->ctx->lock);
}

static int preinit(struct vo *vo)
{
    struct vo_priv *p = vo->priv;
    p->vo = vo;
    p->ctx = vo->extra.opengl_cb_context;
    if (!p->ctx) {
        MP_FATAL(vo, "No context set.\n");
        return -1;
    }

    pthread_mutex_lock(&p->ctx->lock);
    if (!p->ctx->initialized) {
        MP_FATAL(vo, "OpenGL context not initialized.\n");
        pthread_mutex_unlock(&p->ctx->lock);
        return -1;
    }
    p->ctx->active = vo;
    p->ctx->reconfigured = true;
    assert(vo->osd == p->ctx->osd);
    copy_vo_opts(vo);
    pthread_mutex_unlock(&p->ctx->lock);

    return 0;
}

#define OPT_BASE_STRUCT struct vo_priv
static const struct m_option options[] = {
    OPT_FLAG("debug", use_gl_debug, 0),
    OPT_SUBSTRUCT("", renderer_opts, gl_video_conf, 0),
    {0},
};

const struct vo_driver video_out_opengl_cb = {
    .description = "OpenGL Callbacks for libmpv",
    .name = "opengl-cb",
    .caps = VO_CAP_ROTATE90,
    .preinit = preinit,
    .query_format = query_format,
    .reconfig = reconfig,
    .control = control,
    .draw_image = draw_image,
    .flip_page = flip_page,
    .uninit = uninit,
    .priv_size = sizeof(struct vo_priv),
    .options = options,
};
Example #7
0
File: gl_rpi.c Project: jonntd/mpv
int mp_egl_rpi_init(struct mp_egl_rpi *p, DISPMANX_ELEMENT_HANDLE_T window,
                    int w, int h)
{
    p->egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (!eglInitialize(p->egl_display, NULL, NULL)) {
        MP_FATAL(p, "EGL failed to initialize.\n");
        goto fail;
    }

    eglBindAPI(EGL_OPENGL_ES_API);

    EGLConfig config = select_fb_config_egl(p);
    if (!config)
        goto fail;

    p->egl_window = (EGL_DISPMANX_WINDOW_T){
        .element = window,
        .width = w,
        .height = h,
    };
    p->egl_surface = eglCreateWindowSurface(p->egl_display, config,
                                            &p->egl_window, NULL);

    if (p->egl_surface == EGL_NO_SURFACE) {
        MP_FATAL(p, "Could not create EGL surface!\n");
        goto fail;
    }

    EGLint context_attributes[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };
    p->egl_context = eglCreateContext(p->egl_display, config,
                                      EGL_NO_CONTEXT, context_attributes);

    if (p->egl_context == EGL_NO_CONTEXT) {
        MP_FATAL(p, "Could not create EGL context!\n");
        goto fail;
    }

    eglMakeCurrent(p->egl_display, p->egl_surface, p->egl_surface,
                   p->egl_context);

    p->gl = talloc_zero(NULL, struct GL);

    const char *exts = eglQueryString(p->egl_display, EGL_EXTENSIONS);
    mpgl_load_functions(p->gl, get_proc_address, exts, p->log);

    if (!p->gl->version && !p->gl->es)
        goto fail;

    return 0;

fail:
    mp_egl_rpi_destroy(p);
    return -1;
}
Example #8
0
File: gl_x11.c Project: Bilalh/mpv
static bool create_context_x11_old(struct MPGLContext *ctx)
{
    struct glx_context *glx_ctx = ctx->priv;
    Display *display = ctx->vo->x11->display;
    struct vo *vo = ctx->vo;
    GL *gl = ctx->gl;

    if (glx_ctx->context)
        return true;

    GLXContext new_context = glXCreateContext(display, glx_ctx->vinfo, NULL,
                                              True);
    if (!new_context) {
        MP_FATAL(vo, "Could not create GLX context!\n");
        return false;
    }

    if (!glXMakeCurrent(display, ctx->vo->x11->window, new_context)) {
        MP_FATAL(vo, "Could not set GLX context!\n");
        glXDestroyContext(display, new_context);
        return false;
    }

    void *(*getProcAddress)(const GLubyte *);
    getProcAddress = mp_getdladdr("glXGetProcAddress");
    if (!getProcAddress)
        getProcAddress = mp_getdladdr("glXGetProcAddressARB");

    const char *glxstr = "";
    const char *(*glXExtStr)(Display *, int)
        = mp_getdladdr("glXQueryExtensionsString");
    if (glXExtStr)
        glxstr = glXExtStr(display, ctx->vo->x11->screen);

    mpgl_load_functions(gl, getProcAddress, glxstr, vo->log);
    if (!gl->GenPrograms && gl->GetString &&
        gl->version < MPGL_VER(3, 0) &&
        strstr(gl->GetString(GL_EXTENSIONS), "GL_ARB_vertex_program"))
    {
        MP_WARN(vo, "Broken glXGetProcAddress detected, trying workaround\n");
        mpgl_load_functions(gl, NULL, glxstr, vo->log);
    }

    glx_ctx->context = new_context;

    if (!glXIsDirect(vo->x11->display, new_context))
        ctx->gl->mpgl_caps &= ~MPGL_CAP_NO_SW;

    return true;
}
Example #9
0
struct lavc_conv *lavc_conv_create(struct mp_log *log, const char *codec_name,
                                   char *extradata, int extradata_len)
{
    struct lavc_conv *priv = talloc_zero(NULL, struct lavc_conv);
    priv->log = log;
    priv->cur_list = talloc_array(priv, char*, 0);
    priv->codec = talloc_strdup(priv, codec_name);
    AVCodecContext *avctx = NULL;
    const char *fmt = get_lavc_format(priv->codec);
    AVCodec *codec = avcodec_find_decoder(mp_codec_to_av_codec_id(fmt));
    if (!codec)
        goto error;
    avctx = avcodec_alloc_context3(codec);
    if (!avctx)
        goto error;
    avctx->extradata_size = extradata_len;
    avctx->extradata = talloc_memdup(priv, extradata, extradata_len);
    if (avcodec_open2(avctx, codec, NULL) < 0)
        goto error;
    // Documented as "set by libavcodec", but there is no other way
    avctx->time_base = (AVRational) {1, 1000};
    priv->avctx = avctx;
    priv->extradata = talloc_strndup(priv, avctx->subtitle_header,
                                     avctx->subtitle_header_size);
    disable_styles(bstr0(priv->extradata));
    return priv;

 error:
    MP_FATAL(priv, "Could not open libavcodec subtitle converter\n");
    av_free(avctx);
    talloc_free(priv);
    return NULL;
}
Example #10
0
static int control(struct af_instance *af, int cmd, void *arg)
{
    struct priv *p = af->priv;

    switch (cmd) {
    case AF_CONTROL_REINIT: {
        struct mp_audio *in = arg;
        struct mp_audio orig_in = *in;
        struct mp_audio *out = af->data;

        in->format = AF_FORMAT_FLOATP;
        mp_audio_copy_config(out, in);

        if (p->rubber)
            rubberband_delete(p->rubber);

        int opts = p->opt_transients | p->opt_detector | p->opt_phase |
                   p->opt_window | p->opt_smoothing | p->opt_formant |
                   p->opt_pitch | p-> opt_channels |
                   RubberBandOptionProcessRealTime;

        p->rubber = rubberband_new(in->rate, in->channels.num, opts, 1.0, 1.0);
        if (!p->rubber) {
            MP_FATAL(af, "librubberband initialization failed.\n");
            return AF_ERROR;
        }

        update_speed(af, p->speed);
        update_pitch(af, p->pitch);
        control(af, AF_CONTROL_RESET, NULL);

        return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE;
    }
    case AF_CONTROL_SET_PLAYBACK_SPEED: {
        update_speed(af, *(double *)arg);
        return AF_OK;
    }
    case AF_CONTROL_RESET:
        if (p->rubber)
            rubberband_reset(p->rubber);
        talloc_free(p->pending);
        p->pending = NULL;
        p->rubber_delay = 0;
        return AF_OK;
    case AF_CONTROL_COMMAND: {
        char **args = arg;
        if (!strcmp(args[0], "set-pitch")) {
            char *endptr;
            double pitch = strtod(args[1], &endptr);
            if (*endptr || pitch < 0.01 || pitch > 100.0)
                return CONTROL_ERROR;
            update_pitch(af, pitch);
            return CONTROL_OK;
        } else {
            return CONTROL_ERROR;
        }
    }
    }
    return AF_UNKNOWN;
}
Example #11
0
static int init(struct sd *sd)
{
    struct sd_lavc_priv *priv = talloc_zero(NULL, struct sd_lavc_priv);
    enum AVCodecID cid = mp_codec_to_av_codec_id(sd->codec);
    AVCodecContext *ctx = NULL;
    AVCodec *sub_codec = avcodec_find_decoder(cid);
    if (!sub_codec)
        goto error;
    ctx = avcodec_alloc_context3(sub_codec);
    if (!ctx)
        goto error;
    mp_lavc_set_extradata(ctx, sd->extradata, sd->extradata_len);
    if (avcodec_open2(ctx, sub_codec, NULL) < 0)
        goto error;
    priv->avctx = ctx;
    sd->priv = priv;
    priv->displayed_id = -1;
    return 0;

error:
    MP_FATAL(sd, "Could not open libavcodec subtitle decoder\n");
    av_free(ctx);
    talloc_free(priv);
    return -1;
}
Example #12
0
File: f_lavfi.c Project: Akemi/mpv
static void read_pad_input(struct lavfi *c, struct lavfi_pad *pad)
{
    assert(pad->dir == MP_PIN_IN);

    if (pad->pending.type || c->draining_recover)
        return;

    pad->pending = mp_pin_out_read(pad->pin);

    if (pad->pending.type && pad->pending.type != MP_FRAME_EOF &&
        pad->pending.type != pad->type)
    {
        MP_FATAL(c, "unknown frame %s\n", mp_frame_type_str(pad->pending.type));
        mp_frame_unref(&pad->pending);
    }

    if (mp_frame_is_data(pad->pending) && pad->in_fmt.type &&
        !is_format_ok(pad->pending, pad->in_fmt))
    {
        if (!c->draining_recover)
            MP_VERBOSE(c, "format change on %s\n", pad->name);
        c->draining_recover = true;
        if (c->initialized)
            send_global_eof(c);
    }
}
Example #13
0
static int config(struct vf_instance *vf, int width, int height,
                  int d_width, int d_height, unsigned int flags,
                  unsigned int fmt)
{
    struct vf_priv_s *p = vf->priv;

    p->fmt_in = (struct mp_image_params){
        .imgfmt = fmt,
        .w = width,
        .h = height,
        .d_w = d_width,
        .d_h = d_height,
    };

    if (reinit_vs(vf) < 0)
        return 0;

    const VSVideoInfo *vi = p->vsapi->getVideoInfo(p->out_node);
    fmt = mp_from_vs(vi->format->id);
    if (!fmt) {
        MP_FATAL(vf, "Unsupported output format.\n");
        destroy_vs(vf);
        return 0;
    }

    vf_rescale_dsize(&d_width, &d_height, width, height, vi->width, vi->height);

    return vf_next_config(vf, vi->width, vi->height, d_width, d_height, flags, fmt);
}
Example #14
0
static int open_f(stream_t *stream)
{
    stream->fill_buffer = fill_buffer;
    stream->seek = seek;
    stream->seekable = true;
    stream->control = control;
    stream->read_chunk = 1024 * 1024;

    struct priv *p = talloc_zero(stream, struct priv);
    stream->priv = p;

    // Initial data
    bstr data = bstr0(stream->url);
    bool use_hex = bstr_eatstart0(&data, "hex://");
    if (!use_hex)
        bstr_eatstart0(&data, "memory://");
    stream_control(stream, STREAM_CTRL_SET_CONTENTS, &data);

    if (use_hex && !bstr_decode_hex(stream, p->data, &p->data)) {
        MP_FATAL(stream, "Invalid data.\n");
        return STREAM_ERROR;
    }

    return STREAM_OK;
}
Example #15
0
static int init(struct sd *sd)
{
    struct sd_lavc_priv *priv = talloc_zero(NULL, struct sd_lavc_priv);
    AVCodecContext *avctx = NULL;
    const char *fmt = get_lavc_format(sd->codec);
    AVCodec *codec = avcodec_find_decoder(mp_codec_to_av_codec_id(fmt));
    if (!codec)
        goto error;
    avctx = avcodec_alloc_context3(codec);
    if (!avctx)
        goto error;
    avctx->extradata_size = sd->extradata_len;
    avctx->extradata = sd->extradata;
    if (avcodec_open2(avctx, codec, NULL) < 0)
        goto error;
    // Documented as "set by libavcodec", but there is no other way
    avctx->time_base = (AVRational) {1, 1000};
    priv->avctx = avctx;
    sd->priv = priv;
    sd->output_codec = "ssa";
    sd->output_extradata = avctx->subtitle_header;
    sd->output_extradata_len = avctx->subtitle_header_size;
    if (sd->output_extradata) {
        sd->output_extradata = talloc_memdup(sd, sd->output_extradata,
                                             sd->output_extradata_len);
        disable_styles((bstr){sd->output_extradata, sd->output_extradata_len});
    }
    return 0;

 error:
    MP_FATAL(sd, "Could not open libavcodec subtitle converter\n");
    av_free(avctx);
    talloc_free(priv);
    return -1;
}
Example #16
0
File: x11.c Project: madokama/mpv
static bool create_context_x11_gl3(struct MPGLContext *ctx, int vo_flags,
                                   int gl_version, bool es)
{
    struct glx_context *glx_ctx = ctx->priv;
    struct vo *vo = ctx->vo;

    if (glx_ctx->context)
        return true;

    glXCreateContextAttribsARBProc glXCreateContextAttribsARB =
        (glXCreateContextAttribsARBProc)
            glXGetProcAddressARB((const GLubyte *)"glXCreateContextAttribsARB");

    const char *glxstr =
        glXQueryExtensionsString(vo->x11->display, vo->x11->screen);
    bool have_ctx_ext = glxstr && !!strstr(glxstr, "GLX_ARB_create_context");

    if (!(have_ctx_ext && glXCreateContextAttribsARB)) {
        return false;
    }

    int ctx_flags = vo_flags & VOFLAG_GL_DEBUG ? GLX_CONTEXT_DEBUG_BIT_ARB : 0;
    int profile_mask = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;

    if (es) {
        profile_mask = GLX_CONTEXT_ES2_PROFILE_BIT_EXT;
        if (!(glxstr && strstr(glxstr, "GLX_EXT_create_context_es2_profile")))
            return false;
    }

    int context_attribs[] = {
        GLX_CONTEXT_MAJOR_VERSION_ARB, MPGL_VER_GET_MAJOR(gl_version),
        GLX_CONTEXT_MINOR_VERSION_ARB, MPGL_VER_GET_MINOR(gl_version),
        GLX_CONTEXT_PROFILE_MASK_ARB, profile_mask,
        GLX_CONTEXT_FLAGS_ARB, ctx_flags,
        None
    };
    vo_x11_silence_xlib(1);
    GLXContext context = glXCreateContextAttribsARB(vo->x11->display,
                                                    glx_ctx->fbc, 0, True,
                                                    context_attribs);
    vo_x11_silence_xlib(-1);
    if (!context) {
        MP_VERBOSE(vo, "Could not create GL3 context. Retrying with legacy context.\n");
        return false;
    }

    // set context
    if (!glXMakeCurrent(vo->x11->display, vo->x11->window, context)) {
        MP_FATAL(vo, "Could not set GLX context!\n");
        glXDestroyContext(vo->x11->display, context);
        return false;
    }

    glx_ctx->context = context;

    mpgl_load_functions(ctx->gl, (void *)glXGetProcAddressARB, glxstr, vo->log);

    return true;
}
Example #17
0
static int init(struct ao *ao)
{
    struct priv *priv = ao->priv;

    ao->untimed = priv->untimed;

    struct mp_chmap_sel sel = {.tmp = ao};
    if (priv->channel_layouts) {
        for (int n = 0; priv->channel_layouts[n]; n++) {
            struct mp_chmap map = {0};
            if (!mp_chmap_from_str(&map, bstr0(priv->channel_layouts[n]))) {
                MP_FATAL(ao, "Invalid channel map in option.\n");
                return -1;
            }
            mp_chmap_sel_add_map(&sel, &map);
        }
    } else {
        mp_chmap_sel_add_any(&sel);
    }
    if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels))
        mp_chmap_from_channels(&ao->channels, 2);

    priv->latency = priv->latency_sec * ao->samplerate;

    // A "buffer" for this many seconds of audio
    int bursts = (int)(ao->samplerate * priv->bufferlen + 1) / priv->outburst;
    priv->buffersize = priv->outburst * bursts + priv->latency;

    priv->last_time = mp_time_sec();

    return 0;
}
Example #18
0
// Allocate memory and set function pointers
static int af_open(struct af_instance* af){
    af->control=control;
    af->filter=filter;
    af_channels_t *s = af->priv;

    // If router scan commandline for routing pairs
    if(s->routes && s->routes[0]){
        char* cp = s->routes;
        int ch = 0;
        // Scan for pairs on commandline
        do {
            int n = 0;
            if (ch >= AF_NCH) {
                MP_FATAL(af, "[channels] Can't have more than %d routes.\n", AF_NCH);
                return AF_ERROR;
            }
            sscanf(cp, "%i-%i%n" ,&s->route[ch][FR], &s->route[ch][TO], &n);
            MP_VERBOSE(af, "[channels] Routing from channel %i to"
                " channel %i\n",s->route[ch][FR],s->route[ch][TO]);
            cp = &cp[n];
            ch++;
        } while(*cp == ',' && *(cp++));
        s->nr = ch;
        if (s->nr > 0)
            s->router = 1;
    }

    return AF_OK;
}
Example #19
0
static bool create_gl_context(struct MPGLContext *ctx)
{
    struct cgl_context *p = ctx->priv;
    CGLError err;

    CGLOpenGLProfile gl_versions[] = {
        kCGLOGLPVersion_3_2_Core,
        kCGLOGLPVersion_Legacy,
    };

    for (int n = 0; n < MP_ARRAY_SIZE(gl_versions); n++) {
        err = test_gl_version(ctx->vo, &p->ctx, &p->pix, gl_versions[n]);
        if (err == kCGLNoError)
            break;
    }

    if (err != kCGLNoError) {
        MP_FATAL(ctx->vo, "error creating CGL context: %s (%d)\n",
                 CGLErrorString(err), err);
        return false;
    }

    vo_cocoa_set_opengl_ctx(ctx->vo, p->ctx);
    CGLSetCurrentContext(p->ctx);

    ctx->depth_r = ctx->depth_g = ctx->depth_b = cgl_color_size(ctx);
    mpgl_load_functions(ctx->gl, (void *)cocoa_glgetaddr, NULL, ctx->vo->log);

    CGLReleasePixelFormat(p->pix);

    return true;
}
Example #20
0
static int vf_open(vf_instance_t *vf)
{
    struct vf_priv_s *p = vf->priv;

#if LIBAVFILTER_VERSION_MICRO >= 100
    const char *mode[] = {"send_frame", "send_field", "send_frame_nospatial",
                          "send_field_nospatial"};

    if (vf_lw_set_graph(vf, p->lw_opts, "yadif", "mode=%s:deint=%s", mode[p->mode],
                        p->interlaced_only ? "interlaced" : "all") >= 0)
    {
        return 1;
    }
#else
    // Libav numeric modes happen to match ours, but keep it explicit.
    const char *mode[] = {"0", "1", "2", "3"};
    if (vf_lw_set_graph(vf, p->lw_opts, "yadif", "mode=%s:auto=%d", mode[p->mode],
                        p->interlaced_only) >= 0)
    {
        return 1;
    }
#endif

    MP_FATAL(vf, "This version of libavfilter has no 'yadif' filter.\n");
    return 0;
}
Example #21
0
static int vf_open(vf_instance_t *vf)
{
    struct vf_priv_s *p = vf->priv;
    if (p->drv->init(vf) < 0)
        return 0;
    if (!p->cfg_file || !p->cfg_file[0]) {
        MP_FATAL(vf, "'file' parameter must be set.\n");
        return 0;
    }
    talloc_steal(vf, p->cfg_file);
    p->cfg_file = mp_get_user_path(vf, vf->chain->global, p->cfg_file);

    pthread_mutex_init(&p->lock, NULL);
    pthread_cond_init(&p->wakeup, NULL);
    vf->reconfig = reconfig;
    vf->filter_ext = filter_ext;
    vf->filter_out = filter_out;
    vf->needs_input = needs_input;
    vf->query_format = query_format;
    vf->control = control;
    vf->uninit = uninit;
    p->max_requests = p->cfg_maxrequests;
    if (p->max_requests < 0)
        p->max_requests = av_cpu_count();
    MP_VERBOSE(vf, "using %d concurrent requests.\n", p->max_requests);
    int maxbuffer = p->cfg_maxbuffer * p->max_requests;
    p->buffered = talloc_array(vf, struct mp_image *, maxbuffer);
    p->requested = talloc_zero_array(vf, struct mp_image *, p->max_requests);
    return 1;
}
Example #22
0
// Iterate entries. The first call establishes the first entry. Returns false
// if no entry found, otherwise returns true and sets mpa->entry/entry_filename.
bool mp_archive_next_entry(struct mp_archive *mpa)
{
    mpa->entry = NULL;
    talloc_free(mpa->entry_filename);
    mpa->entry_filename = NULL;

    while (!mp_cancel_test(mpa->primary_src->cancel)) {
        struct archive_entry *entry;
        int r = archive_read_next_header(mpa->arch, &entry);
        if (r == ARCHIVE_EOF)
            break;
        if (r < ARCHIVE_OK)
            MP_ERR(mpa, "%s\n", archive_error_string(mpa->arch));
        if (r < ARCHIVE_WARN) {
            MP_FATAL(mpa, "could not read archive entry\n");
            break;
        }
        if (archive_entry_filetype(entry) != AE_IFREG)
            continue;
        // Some archives may have no filenames, or libarchive won't return some.
        const char *fn = archive_entry_pathname(entry);
        char buf[64];
        if (!fn || bstr_validate_utf8(bstr0(fn)) < 0) {
            snprintf(buf, sizeof(buf), "mpv_unknown#%d", mpa->entry_num);
            fn = buf;
        }
        mpa->entry = entry;
        mpa->entry_filename = talloc_strdup(mpa, fn);
        mpa->entry_num += 1;
        return true;
    }

    return false;
}
Example #23
0
static int init(struct sd *sd)
{
    enum AVCodecID cid = mp_codec_to_av_codec_id(sd->codec->codec);

    // Supported codecs must be known to decode to paletted bitmaps
    switch (cid) {
    case AV_CODEC_ID_DVB_SUBTITLE:
    case AV_CODEC_ID_HDMV_PGS_SUBTITLE:
    case AV_CODEC_ID_XSUB:
    case AV_CODEC_ID_DVD_SUBTITLE:
        break;
    default:
        return -1;
    }

    struct sd_lavc_priv *priv = talloc_zero(NULL, struct sd_lavc_priv);
    AVCodecContext *ctx = NULL;
    AVCodec *sub_codec = avcodec_find_decoder(cid);
    if (!sub_codec)
        goto error;
    ctx = avcodec_alloc_context3(sub_codec);
    if (!ctx)
        goto error;
    mp_lavc_set_extradata(ctx, sd->codec->extradata, sd->codec->extradata_size);
#if LIBAVCODEC_VERSION_MICRO >= 100
    if (cid == AV_CODEC_ID_HDMV_PGS_SUBTITLE) {
        // We don't always want to set this, because the ridiculously shitty
        // libavcodec API will mess with certain fields (end_display_time)
        // when setting it. On the other hand, PGS in particular needs PTS
        // mangling. While the PGS decoder doesn't modify the timestamps (just
        // reorder it), the ridiculously shitty libavcodec wants a timebase
        // anyway and for no good reason. It always sets end_display_time to
        // UINT32_MAX (which is a broken and undocumented way to say "unknown"),
        // which coincidentally won't be overridden by the ridiculously shitty
        // pkt_timebase code. also, Libav doesn't have the pkt_timebase field,
        // because Libav tends to avoid _adding_ ridiculously shitty APIs.
        priv->pkt_timebase = (AVRational){1, AV_TIME_BASE};
        ctx->pkt_timebase = priv->pkt_timebase;
    } else {
        // But old ffmpeg releases have a buggy pkt_timebase check, because the
        // shit above wasn't bad enough!
        ctx->pkt_timebase = (AVRational){0, 0};
    }
#endif
    if (avcodec_open2(ctx, sub_codec, NULL) < 0)
        goto error;
    priv->avctx = ctx;
    sd->priv = priv;
    priv->displayed_id = -1;
    priv->current_pts = MP_NOPTS_VALUE;
    priv->packer = talloc_zero(priv, struct bitmap_packer);
    return 0;

 error:
    MP_FATAL(sd, "Could not open libavcodec subtitle decoder\n");
    av_free(ctx);
    talloc_free(priv);
    return -1;
}
Example #24
0
// Supposedly we're not allowed to continue reading on FATAL returns. Otherwise
// crashes and other UB is possible. Assume calling the close/free functions is
// still ok. Return true if it was fatal and the archive was closed.
static bool mp_archive_check_fatal(struct mp_archive *mpa, int r)
{
    if (r > ARCHIVE_FATAL)
        return false;
    MP_FATAL(mpa, "fatal error received - closing archive\n");
    mp_archive_close(mpa);
    return true;
}
Example #25
0
static int drv_vss_init(struct vf_instance *vf)
{
    if (!vsscript_init()) {
        MP_FATAL(vf, "Could not initialize VapourSynth scripting.\n");
        return -1;
    }
    return 0;
}
Example #26
0
static void uninit(struct vo *vo)
{
    struct vo_priv *p = vo->priv;

    pthread_mutex_lock(&p->ctx->lock);
    forget_frames(p->ctx, true);
    p->ctx->img_params = (struct mp_image_params){0};
    p->ctx->reconfigured = true;
    p->ctx->active = NULL;
    update(p);
    pthread_mutex_unlock(&p->ctx->lock);
}

static int preinit(struct vo *vo)
{
    struct vo_priv *p = vo->priv;
    p->vo = vo;
    p->ctx = vo->extra.opengl_cb_context;
    if (!p->ctx) {
        MP_FATAL(vo, "No context set.\n");
        return -1;
    }

    pthread_mutex_lock(&p->ctx->lock);
    if (!p->ctx->initialized) {
        MP_FATAL(vo, "OpenGL context not initialized.\n");
        pthread_mutex_unlock(&p->ctx->lock);
        return -1;
    }
    p->ctx->active = vo;
    p->ctx->reconfigured = true;
    p->ctx->update_new_opts = true;
    copy_vo_opts(vo);
    pthread_mutex_unlock(&p->ctx->lock);

    return 0;
}

#define OPT_BASE_STRUCT struct vo_priv
static const struct m_option options[] = {
    OPT_FLAG("debug", use_gl_debug, 0),
    OPT_INTRANGE("frame-queue-size", frame_queue_size, 0, 1, 100, OPTDEF_INT(2)),
    OPT_CHOICE("frame-drop-mode", frame_drop_mode, 0,
               ({"pop", FRAME_DROP_POP},
                {"clear", FRAME_DROP_CLEAR},
Example #27
0
int video_reconfig_filters(struct dec_video *d_video,
                           const struct mp_image_params *params)
{
    struct MPOpts *opts = d_video->opts;
    struct mp_image_params p = *params;
    struct sh_video *sh = d_video->header->video;

    // While mp_image_params normally always have to have d_w/d_h set, the
    // decoder signals unknown bitstream aspect ratio with both set to 0.
    float dec_aspect = p.d_w > 0 && p.d_h > 0 ? p.d_w / (float)p.d_h : 0;
    if (d_video->initial_decoder_aspect == 0)
        d_video->initial_decoder_aspect = dec_aspect;

    bool use_container = true;
    switch (opts->aspect_method) {
    case 0:
        // We normally prefer the container aspect, unless the decoder aspect
        // changes at least once.
        if (dec_aspect > 0 && d_video->initial_decoder_aspect != dec_aspect) {
            MP_VERBOSE(d_video, "Using bitstream aspect ratio.\n");
            // Even if the aspect switches back, don't use container aspect again.
            d_video->initial_decoder_aspect = -1;
            use_container = false;
        }
        break;
    case 1:
        use_container = false;
        break;
    }

    if (use_container && sh->aspect > 0) {
        MP_VERBOSE(d_video, "Using container aspect ratio.\n");
        vf_set_dar(&p.d_w, &p.d_h, p.w, p.h, sh->aspect);
    }

    float force_aspect = opts->movie_aspect;
    if (force_aspect >= 0.0) {
        MP_VERBOSE(d_video, "Forcing user-set aspect ratio.\n");
        vf_set_dar(&p.d_w, &p.d_h, p.w, p.h, force_aspect);
    }

    // Assume square pixels if no aspect ratio is set at all.
    if (p.d_w <= 0 || p.d_h <= 0) {
        p.d_w = p.w;
        p.d_h = p.h;
    }

    // Detect colorspace from resolution.
    mp_image_params_guess_csp(&p);

    if (vf_reconfig(d_video->vfilter, params, &p) < 0) {
        MP_FATAL(d_video, "Cannot initialize video filters.\n");
        return -1;
    }

    return 0;
}
Example #28
0
File: gl_x11.c Project: Bilalh/mpv
static bool create_context_x11_gl3(struct MPGLContext *ctx, bool debug)
{
    struct glx_context *glx_ctx = ctx->priv;
    struct vo *vo = ctx->vo;

    if (glx_ctx->context)
        return true;

    glXCreateContextAttribsARBProc glXCreateContextAttribsARB =
        (glXCreateContextAttribsARBProc)
            glXGetProcAddressARB((const GLubyte *)"glXCreateContextAttribsARB");

    const char *glxstr = "";
    const char *(*glXExtStr)(Display *, int)
        = mp_getdladdr("glXQueryExtensionsString");
    if (glXExtStr)
        glxstr = glXExtStr(vo->x11->display, vo->x11->screen);
    bool have_ctx_ext = glxstr && !!strstr(glxstr, "GLX_ARB_create_context");

    if (!(have_ctx_ext && glXCreateContextAttribsARB)) {
        return false;
    }

    int gl_version = ctx->requested_gl_version;
    int context_attribs[] = {
        GLX_CONTEXT_MAJOR_VERSION_ARB, MPGL_VER_GET_MAJOR(gl_version),
        GLX_CONTEXT_MINOR_VERSION_ARB, MPGL_VER_GET_MINOR(gl_version),
        GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
        GLX_CONTEXT_FLAGS_ARB, debug ? GLX_CONTEXT_DEBUG_BIT_ARB : 0,
        None
    };
    GLXContext context = glXCreateContextAttribsARB(vo->x11->display,
                                                    glx_ctx->fbc, 0, True,
                                                    context_attribs);
    if (!context) {
        MP_ERR(vo, "Could not create GL3 context. Retrying with legacy context.\n");
        return false;
    }

    // set context
    if (!glXMakeCurrent(vo->x11->display, vo->x11->window, context)) {
        MP_FATAL(vo, "Could not set GLX context!\n");
        glXDestroyContext(vo->x11->display, context);
        return false;
    }

    glx_ctx->context = context;

    mpgl_load_functions(ctx->gl, (void *)glXGetProcAddress, glxstr, vo->log);

    if (!glXIsDirect(vo->x11->display, context))
        ctx->gl->mpgl_caps &= ~MPGL_CAP_NO_SW;

    return true;
}
Example #29
0
// Returns true if more args, false if all parsed or an error occurred.
static bool split_opt(struct parse_state *p)
{
    int r = split_opt_silent(p);
    if (r >= 0)
        return r == 0;
    p->error = true;

    MP_FATAL(p->config, "Error parsing command line option '%.*s': %s\n",
             BSTR_P(p->arg), m_option_strerror(r));
    return false;
}
Example #30
0
// Initialization and runtime control
static int control(struct af_instance* af, int cmd, void* arg)
{
    af_delay_t* s = af->priv;
    switch(cmd) {
    case AF_CONTROL_REINIT: {
        int i;
        struct mp_audio *in = arg;

        if (in->bps != 1 && in->bps != 2 && in->bps != 4) {
            MP_FATAL(af, "Sample format not supported\n");
            return AF_ERROR;
        }

        // Free prevous delay queues
        for(i=0; i<af->data->nch; i++)
            free(s->q[i]);

        mp_audio_force_interleaved_format(in);
        mp_audio_copy_config(af->data, in);

        // Allocate new delay queues
        for(i=0; i<af->data->nch; i++) {
            s->q[i] = calloc(L,af->data->bps);
            if(NULL == s->q[i])
                MP_FATAL(af, "Out of memory\n");
        }

        if(AF_OK != af_from_ms(AF_NCH, s->d, s->wi, af->data->rate, 0.0, 1000.0))
            return AF_ERROR;
        s->ri = 0;
        for(i=0; i<AF_NCH; i++) {
            MP_DBG(af, "Channel %i delayed by %0.3fms\n",
                   i,MPCLAMP(s->d[i],0.0,1000.0));
            MP_TRACE(af, "Channel %i delayed by %i samples\n",
                     i,s->wi[i]);
        }
        return AF_OK;
    }
    }
    return AF_UNKNOWN;
}