예제 #1
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},
예제 #2
0
파일: af_drc.c 프로젝트: AppleNuts/mpv
  int i = 0;
  af->control=control;
  af->filter_frame = filter;
  af_drc_t *priv = af->priv;

  priv->mul = MUL_INIT;
  priv->lastavg = ((float)SHRT_MAX) * DEFAULT_TARGET;
  priv->idx = 0;
  for (i = 0; i < NSAMPLES; i++)
  {
     priv->mem[i].len = 0;
     priv->mem[i].avg = 0;
  }
  priv->mid_s16 = ((float)SHRT_MAX) * priv->mid_float;
  return AF_OK;
}

#define OPT_BASE_STRUCT af_drc_t
const struct af_info af_info_drc = {
    .info = "Dynamic range compression filter",
    .name = "drc",
    .flags = AF_FLAGS_NOT_REENTRANT,
    .open = af_open,
    .priv_size = sizeof(af_drc_t),
    .options = (const struct m_option[]) {
        OPT_INTRANGE("method", method, 0, 1, 2, OPTDEF_INT(1)),
        OPT_FLOAT("target", mid_float, 0, OPTDEF_FLOAT(DEFAULT_TARGET)),
        {0}
    },
};
예제 #3
0
    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;
}

#define OPT_BASE_STRUCT struct vf_priv_s
static const m_option_t vf_opts_fields[] = {
    OPT_STRING("file", cfg_file, M_OPT_FILE),
    OPT_INTRANGE("buffered-frames", cfg_maxbuffer, 0, 1, 9999, OPTDEF_INT(4)),
    OPT_CHOICE_OR_INT("concurrent-frames", cfg_maxrequests, 0, 1, 99,
                      ({"auto", -1}), OPTDEF_INT(-1)),
    {0}
};

#if HAVE_VAPOURSYNTH

#include <VSScript.h>

static int drv_vss_init(struct vf_instance *vf)
{
    if (!vsscript_init()) {
        MP_FATAL(vf, "Could not initialize VapourSynth scripting.\n");
        return -1;
    }
예제 #4
0
파일: vf_buffer.c 프로젝트: ThreeGe/mpv
        flush(vf);
        return CONTROL_OK;
    }
    return CONTROL_UNKNOWN;
}

static void uninit(vf_instance_t *vf)
{
    flush(vf);
}

static int vf_open(vf_instance_t *vf)
{
    vf->filter_ext = filter_ext;
    vf->control = control;
    vf->uninit = uninit;
    return 1;
}

#define OPT_BASE_STRUCT struct vf_priv_s
const vf_info_t vf_info_buffer = {
    .description = "buffer a number of frames",
    .name = "buffer",
    .open = vf_open,
    .priv_size = sizeof(struct vf_priv_s),
    .options = (const struct m_option[]){
        OPT_INTRANGE("num", cfg_num, 0, 1, MAX_Q, OPTDEF_INT(2)),
        {0}
    },
};
예제 #5
0
파일: demux_lavf.c 프로젝트: Aseeker/mpv
#define INITIAL_PROBE_SIZE STREAM_BUFFER_SIZE
#define PROBE_BUF_SIZE FFMIN(STREAM_MAX_BUFFER_SIZE, 2 * 1024 * 1024)

#define OPT_BASE_STRUCT struct MPOpts

// Should correspond to IO_BUFFER_SIZE in libavformat/aviobuf.c (not public)
// libavformat (almost) always reads data in blocks of this size.
#define BIO_BUFFER_SIZE 32768

const m_option_t lavfdopts_conf[] = {
    OPT_INTRANGE("probesize", lavfdopts.probesize, 0, 32, INT_MAX),
    OPT_STRING("format", lavfdopts.format, 0),
    OPT_FLOATRANGE("analyzeduration", lavfdopts.analyzeduration, 0, 0, 3600),
    OPT_INTRANGE("buffersize", lavfdopts.buffersize, 0, 1, 10 * 1024 * 1024,
                 OPTDEF_INT(BIO_BUFFER_SIZE)),
    OPT_FLAG("allow-mimetype", lavfdopts.allow_mimetype, 0),
    OPT_INTRANGE("probescore", lavfdopts.probescore, 0, 0, 100),
    OPT_STRING("cryptokey", lavfdopts.cryptokey, 0),
    OPT_CHOICE("genpts-mode", lavfdopts.genptsmode, 0,
               ({"lavf", 1}, {"no", 0})),
    OPT_STRING("o", lavfdopts.avopt, 0),
    {NULL, NULL, 0, 0, 0, 0, NULL}
};

#define MAX_PKT_QUEUE 50

typedef struct lavf_priv {
    char *filename;
    const struct format_hack *format_hack;
    AVInputFormat *avif;
예제 #6
0
파일: af_channels.c 프로젝트: Bilalh/mpv
            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;
}

#define OPT_BASE_STRUCT af_channels_t
struct af_info af_info_channels = {
    .info = "Insert or remove channels",
    .name = "channels",
    .open = af_open,
    .priv_size = sizeof(af_channels_t),
    .options = (const struct m_option[]) {
        OPT_INTRANGE("nch", nch, 0, 1, AF_NCH, OPTDEF_INT(2)),
        OPT_STRING("routes", routes, 0),
        {0}
    },
};
예제 #7
0
파일: af_export.c 프로젝트: AppleNuts/mpv
   af audio filter instance
   returns AF_OK or AF_ERROR
*/
static int af_open( struct af_instance* af )
{
  af->control = control;
  af->uninit  = uninit;
  af->filter_frame = filter;
  af_export_t *priv = af->priv;

  if (!priv->filename || !priv->filename[0]) {
      MP_FATAL(af, "no export filename given");
      return AF_ERROR;
  }

  return AF_OK;
}

#define OPT_BASE_STRUCT af_export_t
const struct af_info af_info_export = {
    .info = "Sound export filter",
    .name = "export",
    .open = af_open,
    .priv_size = sizeof(af_export_t),
    .options = (const struct m_option[]) {
        OPT_STRING("filename", filename, 0),
        OPT_INTRANGE("buffersamples", sz, 0, 1, 2048, OPTDEF_INT(DEF_SZ)),
        {0}
    },
};
예제 #8
0
static void VS_CC infiltInit(VSMap *in, VSMap *out, void **instanceData,
                             VSNode *node, VSCore *core, const VSAPI *vsapi)
{
    struct vf_instance *vf = *instanceData;
    struct vf_priv_s *p = vf->priv;

    // Note: this is called from createFilter, so no need for locking.

    VSVideoInfo fmt = {
        .format = p->vsapi->getFormatPreset(mp_to_vs(p->fmt_in.imgfmt), p->vscore),
        .width = p->fmt_in.w,
        .height = p->fmt_in.h,
    };
    if (!fmt.format) {
        p->vsapi->setError(out, "Unsupported input format.\n");
        return;
    }

    p->vsapi->setVideoInfo(&fmt, 1, node);
    p->in_node_active = true;
}

static const VSFrameRef *VS_CC infiltGetFrame(int frameno, int activationReason,
    void **instanceData, void **frameData,
    VSFrameContext *frameCtx, VSCore *core,
    const VSAPI *vsapi)
{
    struct vf_instance *vf = *instanceData;
    struct vf_priv_s *p = vf->priv;
    VSFrameRef *ret = NULL;

    pthread_mutex_lock(&p->lock);
    while (1) {
        if (p->shutdown)
            break;
        if (frameno < p->in_frameno) {
            p->vsapi->setFilterError("Requesting a frame too far in the past. "
                                     "Try increasing the maxbuffer suboption",
                                     frameCtx);
            break;
        }
        if (frameno >= p->in_frameno + MP_TALLOC_ELEMS(p->buffered)) {
            // Too far in the future. Remove frames, so that the main thread can
            // queue new frames.
            if (p->num_buffered) {
                drain_oldest_buffered_frame(p);
                pthread_cond_broadcast(&p->wakeup);
                continue;
            }
        }
        if (frameno < p->in_frameno + p->num_buffered) {
            struct mp_image *img = p->buffered[frameno - p->in_frameno];
            const VSFormat *vsfmt =
                vsapi->getFormatPreset(mp_to_vs(img->imgfmt), core);
            ret = vsapi->newVideoFrame(vsfmt, img->w, img->h, NULL, core);
            if (!ret) {
                p->vsapi->setFilterError("Could not allocate VS frame", frameCtx);
                break;
            }
            struct mp_image vsframe = map_vs_frame(p, ret, true);
            mp_image_copy(&vsframe, img);
            VSMap *map = p->vsapi->getFramePropsRW(ret);
            if (map) {
                int res = 1e6;
                int dur = img->pts * res + 0.5;
                p->vsapi->propSetInt(map, "_DurationNum", dur, 0);
                p->vsapi->propSetInt(map, "_DurationDen", res, 0);
                copy_mp_to_vs_frame_props(p, map, img);
            }
            break;
        }
        pthread_cond_wait(&p->wakeup, &p->lock);
    }
    pthread_mutex_unlock(&p->lock);
    return ret;
}

static void VS_CC infiltFree(void *instanceData, VSCore *core, const VSAPI *vsapi)
{
    struct vf_instance *vf = instanceData;
    struct vf_priv_s *p = vf->priv;

    pthread_mutex_lock(&p->lock);
    p->in_node_active = false;
    pthread_cond_broadcast(&p->wakeup);
    pthread_mutex_unlock(&p->lock);
}

static void destroy_vs(struct vf_instance *vf)
{
    struct vf_priv_s *p = vf->priv;

    // Wait until our frame callback returns.
    pthread_mutex_lock(&p->lock);
    p->shutdown = true;
    pthread_cond_broadcast(&p->wakeup);
    while (p->getting_frame)
        pthread_cond_wait(&p->wakeup, &p->lock);
    pthread_mutex_unlock(&p->lock);

    if (p->in_node)
        p->vsapi->freeNode(p->in_node);
    if (p->out_node)
        p->vsapi->freeNode(p->out_node);
    p->in_node = p->out_node = NULL;

    if (p->se)
        vsscript_freeScript(p->se);

    p->se = NULL;
    p->vsapi = NULL;
    p->vscore = NULL;

    assert(!p->in_node_active);

    p->shutdown = false;
    talloc_free(p->got_frame);
    p->got_frame = NULL;
    // Kill queued frames too
    for (int n = 0; n < p->num_buffered; n++)
        talloc_free(p->buffered[n]);
    p->num_buffered = 0;
    talloc_free(p->next_image);
    p->next_image = NULL;
    p->prev_pts = MP_NOPTS_VALUE;
    p->out_frameno = p->in_frameno = 0;
}

static int reinit_vs(struct vf_instance *vf)
{
    struct vf_priv_s *p = vf->priv;
    VSMap *vars = NULL, *in = NULL, *out = NULL;
    int res = -1;

    destroy_vs(vf);

    // First load an empty script to get a VSScript, so that we get the vsapi
    // and vscore.
    if (vsscript_evaluateScript(&p->se, "", NULL, 0))
        goto error;
    p->vsapi = vsscript_getVSApi();
    p->vscore = vsscript_getCore(p->se);
    if (!p->vsapi || !p->vscore)
        goto error;

    in = p->vsapi->createMap();
    out = p->vsapi->createMap();
    vars = p->vsapi->createMap();
    if (!in || !out || !vars)
        goto error;

    p->vsapi->createFilter(in, out, "Input", infiltInit, infiltGetFrame,
                           infiltFree, fmSerial, 0, vf, p->vscore);
    int vserr;
    p->in_node = p->vsapi->propGetNode(out, "clip", 0, &vserr);
    if (!p->in_node)
        goto error;

    if (p->vsapi->propSetNode(vars, "video_in", p->in_node, 0))
        goto error;

    vsscript_setVariable(p->se, vars);

    if (vsscript_evaluateFile(&p->se, p->cfg_file, 0)) {
        MP_FATAL(vf, "Script evaluation failed:\n%s\n", vsscript_getError(p->se));
        goto error;
    }
    p->out_node = vsscript_getOutput(p->se, 0);
    if (!p->out_node)
        goto error;

    const VSVideoInfo *vi = p->vsapi->getVideoInfo(p->out_node);
    if (!isConstantFormat(vi)) {
        MP_FATAL(vf, "Video format is required to be constant.\n");
        goto error;
    }

    res = 0;
error:
    if (p->vsapi) {
        p->vsapi->freeMap(in);
        p->vsapi->freeMap(out);
        p->vsapi->freeMap(vars);
    }
    if (res < 0)
        destroy_vs(vf);
    return res;
}

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,
    };

    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);
}

static int query_format(struct vf_instance *vf, unsigned int fmt)
{
    return mp_to_vs(fmt) != pfNone ? VFCAP_CSP_SUPPORTED : 0;
}

static int control(vf_instance_t *vf, int request, void *data)
{
    switch (request) {
    case VFCTRL_SEEK_RESET:
        if (reinit_vs(vf) < 0)
            return CONTROL_ERROR;
        return CONTROL_OK;
    }
    return CONTROL_UNKNOWN;
}

static void uninit(struct vf_instance *vf)
{
    struct vf_priv_s *p = vf->priv;

    destroy_vs(vf);
    vsscript_finalize();

    pthread_cond_destroy(&p->wakeup);
    pthread_mutex_destroy(&p->lock);
}

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;
    p->buffered = talloc_array(vf, struct mp_image *, p->cfg_maxbuffer);
    return 1;
}

#define OPT_BASE_STRUCT struct vf_priv_s
static const m_option_t vf_opts_fields[] = {
    OPT_STRING("file", cfg_file, 0),
    OPT_INTRANGE("maxbuffer", cfg_maxbuffer, 0, 1, 9999, OPTDEF_INT(5)),
    {0}
};

const vf_info_t vf_info_vapoursynth = {
    .description = "vapoursynth bridge",
    .name = "vapoursynth",
    .open = vf_open,
    .priv_size = sizeof(struct vf_priv_s),
    .options = vf_opts_fields,
};
예제 #9
0
    uninit(vo);
    return -1;
}

static int validate_backend_opt(const m_option_t *opt, struct bstr name,
                                struct bstr param)
{
    char s[20];
    snprintf(s, sizeof(s), "%.*s", BSTR_P(param));
    return mpgl_find_backend(s) >= -1 ? 1 : M_OPT_INVALID;
}

#define OPT_BASE_STRUCT struct gl_priv
const struct m_option options[] = {
    OPT_FLAG("glfinish", use_glFinish, 0),
    OPT_INT("swapinterval", swap_interval, 0, OPTDEF_INT(1)),
    OPT_FLAG("debug", use_gl_debug, 0),
    OPT_STRING_VALIDATE("backend", backend, 0, validate_backend_opt),
    OPT_FLAG("sw", allow_sw, 0),

    OPT_SUBSTRUCT("", renderer_opts, gl_video_conf, 0),
    OPT_SUBSTRUCT("", icc_opts, mp_icc_conf, 0),
    {0},
};

static const char help_text[];

const struct vo_driver video_out_opengl = {
    .info = &(const vo_info_t) {
        "Extended OpenGL Renderer",
        "opengl",
예제 #10
0
파일: af_center.c 프로젝트: Nikoli/mpv
  register int  i;

  // Run filter
  for(i=0;i<len;i+=nch){
    // Average left and right
    a[i+ch] = (a[i]/2) + (a[i+1]/2);
  }

  return 0;
}

// Allocate memory and set function pointers
static int af_open(struct af_instance* af){
  af->control=control;
  af->filter=filter;
  return AF_OK;
}

#define OPT_BASE_STRUCT af_center_t
struct af_info af_info_center = {
    .info = "Audio filter for adding a center channel",
    .name = "center",
    .flags = AF_FLAGS_NOT_REENTRANT,
    .open = af_open,
    .priv_size = sizeof(af_center_t),
    .options = (const struct m_option[]) {
        OPT_INTRANGE("channel", ch, 0, 0, AF_NCH - 1, OPTDEF_INT(1)),
        {0}
    },
};
예제 #11
0
파일: vf_vapoursynth.c 프로젝트: Nikoli/mpv
    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;
}

#define OPT_BASE_STRUCT struct vf_priv_s
static const m_option_t vf_opts_fields[] = {
    OPT_STRING("file", cfg_file, 0),
    OPT_INTRANGE("buffered-frames", cfg_maxbuffer, 0, 1, 9999, OPTDEF_INT(4)),
    OPT_INTRANGE("concurrent-frames", cfg_maxrequests, 0, 1, 99, OPTDEF_INT(2)),
    {0}
};

const vf_info_t vf_info_vapoursynth = {
    .description = "vapoursynth bridge",
    .name = "vapoursynth",
    .open = vf_open,
    .priv_size = sizeof(struct vf_priv_s),
    .options = vf_opts_fields,
};
예제 #12
0
    struct vo_priv *p = vo->priv;

    pthread_mutex_lock(&p->ctx->lock);
    forget_frames(p->ctx);
    p->ctx->img_params = *params;
    p->ctx->reconfigured = true;
    pthread_mutex_unlock(&p->ctx->lock);

    return 0;
}

// list of options which can be changed at runtime
#define OPT_BASE_STRUCT struct vo_priv
static const struct m_option change_opts[] = {
    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})),
    OPT_SUBSTRUCT("", renderer_opts, gl_video_conf, 0),
    {0}
};
#undef OPT_BASE_STRUCT

static bool reparse_cmdline(struct vo_priv *p, char *args)
{
    struct m_config *cfg = NULL;
    struct vo_priv *opts = NULL;
    int r = 0;

    pthread_mutex_lock(&p->ctx->lock);
예제 #13
0
파일: vf_rotate.c 프로젝트: Ionic/mpv
        MP_WARN(vf, "%s", VF_LW_REPLACE);

    if (vf_lw_set_graph(vf, p->lw_opts, NULL, "%s", rot[p->angle]) >= 0) {
        vf_lw_set_reconfig_cb(vf, lavfi_reconfig);
        return 1;
    }

    return 0;
}

#define OPT_BASE_STRUCT struct vf_priv_s
const vf_info_t vf_info_rotate = {
    .description = "rotate",
    .name = "rotate",
    .open = vf_open,
    .priv_size = sizeof(struct vf_priv_s),
    .options = (const struct m_option[]){
        OPT_CHOICE("angle", angle, 0,
                   ({"0", 0},
                    {"90", 1},
                    {"180", 2},
                    {"270", 3},
                    {"auto", 4})),
        OPT_FLAG("warn", warn, 0, OPTDEF_INT(1)),
        OPT_SUBSTRUCT("", lw_opts, vf_lw_conf, 0),
        {0}
    },
};

//===========================================================================//