예제 #1
0
VideoPlayer::~VideoPlayer()
{
    makeCurrent();
    if(mpv_gl)
        mpv_opengl_cb_set_update_callback(mpv_gl, nullptr, nullptr);
    mpv_opengl_cb_uninit_gl(mpv_gl);
}
예제 #2
0
MpvWidget::~MpvWidget()
{
    makeCurrent();
    if (mpv_gl)
        mpv_opengl_cb_set_update_callback(mpv_gl, NULL, NULL);
    // Until this call is done, we need to make sure the player remains
    // alive. This is done implicitly with the mpv::qt::Handle instance
    // in this class.
    mpv_opengl_cb_uninit_gl(mpv_gl);
}
예제 #3
0
static void
finalise(GObject* obj)
{
    GtPlayerMpv* self = GT_PLAYER_MPV(obj);
    GtPlayerMpvPrivate* priv = gt_player_mpv_get_instance_private(self);

    gtk_gl_area_make_current(GTK_GL_AREA(priv->opengl_area));
    mpv_opengl_cb_uninit_gl(priv->mpv_opengl);

    G_OBJECT_CLASS(gt_player_mpv_parent_class)->finalize(obj);
}
static void
finalise(GObject* obj)
{
    GtPlayerBackendMpvOpenGL* self = GT_PLAYER_BACKEND_MPV_OPENGL(obj);
    GtPlayerBackendMpvOpenGLPrivate* priv = gt_player_backend_mpv_opengl_get_instance_private(self);

    MESSAGE("Finalise");

    if (priv->mpv_event_cb_id > 0) g_source_remove(priv->mpv_event_cb_id);

    mpv_set_wakeup_callback(priv->mpv, NULL, NULL);
    mpv_opengl_cb_set_update_callback(priv->mpv_opengl, NULL, NULL);
    mpv_opengl_cb_uninit_gl(priv->mpv_opengl);
    mpv_terminate_destroy(priv->mpv);

    g_clear_object(&priv->widget);

    g_free(priv->uri);

    G_OBJECT_CLASS(gt_player_backend_mpv_opengl_parent_class)->finalize(obj);
}
예제 #5
0
void gmpv_mpv_obj_quit(GmpvMpvObj *mpv)
{
	g_info("Terminating mpv");

	if(mpv->tmp_input_file)
	{
		g_unlink(mpv->tmp_input_file);
	}

	if(mpv->opengl_ctx)
	{
		g_debug("Uninitializing opengl-cb");
		mpv_opengl_cb_uninit_gl(mpv->opengl_ctx);

		mpv->opengl_ctx = NULL;
	}

	g_assert(mpv->mpv_ctx);
	mpv_terminate_destroy(mpv->mpv_ctx);

	mpv->mpv_ctx = NULL;
}
예제 #6
0
static void *render_thread_run(void *data) {
    struct render_thread *render_thread = data;

    EGLDisplay egl_display = NULL;
    EGLSurface egl_surface = NULL;
    EGLContext egl_context = NULL;
    // Gather egl params and bind to mpv opengl_cb
    {
        pthread_mutex_lock(&render_thread->lock);

        egl_display = render_thread->egl_display;
        egl_surface = render_thread->egl_surface;
        egl_context = render_thread->egl_context;

        eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context);
        eglSwapInterval(egl_display, 0);

        int res = mpv_opengl_cb_init_gl(render_thread->opengl_cb_context, NULL,
                                        mpv_get_proc_address, NULL);
        if (res < 0) {
            log_mpv_error("mpv_opengl_cb_init_gl failed", res);
        }

        mpv_opengl_cb_set_update_callback(render_thread->opengl_cb_context,
                                          update_callback, render_thread);

        // TODO: after the first uninit the video track is reset to 0 (none)
        // Setting this to 1 restarts the playback though and messes up the time the video
        // was playing at.
        uint64_t on = 1;
        mpv_set_property(render_thread->mpv, "vid", MPV_FORMAT_INT64, &on);

        render_thread->running = 1;
        pthread_cond_broadcast(&render_thread->ready);

        pthread_mutex_unlock(&render_thread->lock);
    }

    int64_t last_time = mpv_get_time_us(render_thread->mpv);
    int frames = 0;

    while (1) {
        // Wait for available frames
        {
            pthread_mutex_lock(&render_thread->frame_wait_lock);
            while (!render_thread->frame_available) {
                pthread_cond_wait(&render_thread->frame_wait, &render_thread->frame_wait_lock);
            }
            render_thread->frame_available = 0;
            pthread_mutex_unlock(&render_thread->frame_wait_lock);
        }

        // Check if still running
        int run, width, height;
        {
            pthread_mutex_lock(&render_thread->lock);
            run = render_thread->running;
            width = render_thread->width;
            height = render_thread->height;
            pthread_mutex_unlock(&render_thread->lock);
        }
        if (!run) {
            break;
        }

//        int64_t draw_start = mpv_get_time_us(render_thread->mpv);
        mpv_opengl_cb_draw(render_thread->opengl_cb_context, 0, width, -height);
//        LOGI("Render time %ld", (mpv_get_time_us(render_thread->mpv) - draw_start));
        if (!eglSwapBuffers(egl_display, egl_surface)) {
            LOGE("eglSwapBuffers failed %d", eglGetError());
        }
//        mpv_opengl_cb_report_flip(render_thread->opengl_cb_context, 0);

        frames++;

        int64_t now = mpv_get_time_us(render_thread->mpv);
        if (now - last_time >= 1000 * 1000) {
            // last_time += 1000 * 1000;
            last_time = now; // Don't play catch-up
            LOGI("Render fps %d", frames);
            frames = 0;
        }
    }

    // Release egl params and unbind from mpv opengl_cb
    {
        pthread_mutex_lock(&render_thread->lock);

        int res = mpv_opengl_cb_uninit_gl(render_thread->opengl_cb_context);
        if (res < 0) {
            log_mpv_error("mpv_opengl_cb_uninit_gl failed", res);
        }

        eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);

        pthread_mutex_unlock(&render_thread->lock);
    }

    return NULL;
}
PlayerRenderer::~PlayerRenderer()
{
  // Keep in mind that the m_mpv handle must be held until this is done.
  if (m_mpvGL)
    mpv_opengl_cb_uninit_gl(m_mpvGL);
}