Exemplo n.º 1
0
/*****************************************************************************
 * Open: probe the decoder
 *****************************************************************************/
static int Open(vlc_object_t *p_this)
{
    decoder_t *dec = (decoder_t *)p_this;
    const struct vpx_codec_iface *iface;
    int vp_version;

    switch (dec->fmt_in.i_codec)
    {
#ifdef ENABLE_VP8_DECODER
    case VLC_CODEC_VP8:
        iface = &vpx_codec_vp8_dx_algo;
        vp_version = 8;
        break;
#endif
#ifdef ENABLE_VP9_DECODER
    case VLC_CODEC_VP9:
        iface = &vpx_codec_vp9_dx_algo;
        vp_version = 9;
        break;
#endif
    default:
        return VLC_EGENERIC;
    }

    decoder_sys_t *sys = malloc(sizeof(*sys));
    if (!sys)
        return VLC_ENOMEM;
    dec->p_sys = sys;

    struct vpx_codec_dec_cfg deccfg = {
        .threads = __MIN(vlc_GetCPUCount(), 16)
    };

    msg_Dbg(p_this, "VP%d: using libvpx version %s (build options %s)", 
        vp_version, vpx_codec_version_str(), vpx_codec_build_config());

    if (vpx_codec_dec_init(&sys->ctx, iface, &deccfg, 0) != VPX_CODEC_OK) {
        const char *error = vpx_codec_error(&sys->ctx);
        msg_Err(p_this, "Failed to initialize decoder: %s\n", error);
        free(sys);
        return VLC_EGENERIC;;
    }

    dec->pf_decode_video = Decode;

    dec->fmt_out.i_cat = VIDEO_ES;
    dec->fmt_out.video.i_width = dec->fmt_in.video.i_width;
    dec->fmt_out.video.i_height = dec->fmt_in.video.i_height;
    dec->fmt_out.i_codec = VLC_CODEC_I420;
    dec->b_need_packetized = true;

    return VLC_SUCCESS;
}

/*****************************************************************************
 * Close: decoder destruction
 *****************************************************************************/
static void Close(vlc_object_t *p_this)
{
    decoder_t *dec = (decoder_t *)p_this;
    decoder_sys_t *sys = dec->p_sys;

    /* Free our PTS */
    const void *iter = NULL;
    for (;;) {
        struct vpx_image *img = vpx_codec_get_frame(&sys->ctx, &iter);
        if (!img)
            break;
        free(img->user_priv);
    }

    vpx_codec_destroy(&sys->ctx);

    free(sys);
}
Exemplo n.º 2
0
/*
 * Open codec.
 */
static pj_status_t pj_vpx_codec_open(pjmedia_vid_codec *codec, pjmedia_vid_codec_param *attr) {
    vpx_private *vpx;
    pj_status_t status;

    PJ_ASSERT_RETURN(codec && attr, PJ_EINVAL);
    vpx = (vpx_private*) codec->codec_data;

    pj_memcpy(&vpx->param, attr, sizeof(*attr));

    /* Normalize encoding MTU in codec param */
    if (attr->enc_mtu > PJMEDIA_MAX_VID_PAYLOAD_SIZE) {
        attr->enc_mtu = PJMEDIA_MAX_VID_PAYLOAD_SIZE;
    }

    /* Init format info and apply-param of decoder */
    vpx->dec_vfi = pjmedia_get_video_format_info(NULL, vpx->param.dec_fmt.id);
    if (!vpx->dec_vfi) {
        status = PJ_EINVAL;
        goto on_error;
    }
    pj_bzero(&vpx->dec_vafp, sizeof(vpx->dec_vafp));
    vpx->dec_vafp.size = vpx->param.dec_fmt.det.vid.size;
    vpx->dec_vafp.buffer = NULL;
    status = (*vpx->dec_vfi->apply_fmt)(vpx->dec_vfi, &vpx->dec_vafp);
    if (status != PJ_SUCCESS) {
        goto on_error;
    }

    /* Init format info and apply-param of encoder */
    vpx->enc_vfi = pjmedia_get_video_format_info(NULL, vpx->param.dec_fmt.id);
    if (!vpx->enc_vfi) {
        status = PJ_EINVAL;
        goto on_error;
    }
    pj_bzero(&vpx->enc_vafp, sizeof(vpx->enc_vafp));
    vpx->enc_vafp.size = vpx->param.enc_fmt.det.vid.size;
    vpx->enc_vafp.buffer = NULL;
    status = (*vpx->enc_vfi->apply_fmt)(vpx->enc_vfi, &vpx->enc_vafp);
    if (status != PJ_SUCCESS) {
        goto on_error;
    }

    /* Open the encoder */
    TRACE_((THIS_FILE, "Open vpx version : %s build : %s", vpx_codec_version_str(), vpx_codec_build_config()));

    if (vpx->param.dir & PJMEDIA_DIR_ENCODING) {
        status = pj_vpx_encoder_open(vpx);
        if (status != PJ_SUCCESS) {
            goto on_error;
        }
    }
    if (vpx->param.dir & PJMEDIA_DIR_DECODING) {
        status = pj_vpx_decoder_open(vpx);
        if (status != PJ_SUCCESS) {
            goto on_error;
        }
    }


    /* Update codec attributes, e.g: encoding format may be changed by
     * SDP fmtp negotiation.
     */
    pj_memcpy(attr, &vpx->param, sizeof(*attr));

    return PJ_SUCCESS;

on_error:
    pj_vpx_codec_close(codec);
    return status;
}