diff options
author | wm4 <wm4@nowhere> | 2020-09-03 14:55:26 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2020-09-03 14:55:26 +0200 |
commit | 829775865dbd69db9211cd4b6b6c9b1e5ad82953 (patch) | |
tree | c1c0e9f7c88303ac8326db0fc2827a52b1c931b0 | |
parent | 9be9e0877cbfe1ec19d359464a9121db56f6b0ed (diff) | |
download | mpv-examples-829775865dbd69db9211cd4b6b6c9b1e5ad82953.tar.bz2 mpv-examples-829775865dbd69db9211cd4b6b6c9b1e5ad82953.tar.xz |
Remove examples which use the old opengl_cb API
I made an attempt to convert some of them, but in the end, meh, I can't
be bothered. Do it yourself if you care, PRs to restore any of these
example by using the render API might be accepted.
The qt_opengl example was converted before; just fixing some old
comments in it.
Fixes: #38
-rw-r--r-- | libmpv/README.md | 3 | ||||
-rw-r--r-- | libmpv/ios/ViewController.h | 7 | ||||
-rw-r--r-- | libmpv/ios/ViewController.m | 209 | ||||
-rw-r--r-- | libmpv/qml_direct/main.cpp | 173 | ||||
-rw-r--r-- | libmpv/qml_direct/main.h | 53 | ||||
-rw-r--r-- | libmpv/qml_direct/main.qml | 62 | ||||
-rw-r--r-- | libmpv/qml_direct/mpvtest.pro | 12 | ||||
-rw-r--r-- | libmpv/qml_direct/mpvtest.qrc | 5 | ||||
-rw-r--r-- | libmpv/qt_opengl/mpvwidget.cpp | 4 | ||||
-rw-r--r-- | libmpv/wxwidgets_opengl/main.cpp | 342 | ||||
-rw-r--r-- | libmpv/wxwidgets_opengl/main.h | 75 |
11 files changed, 3 insertions, 942 deletions
diff --git a/libmpv/README.md b/libmpv/README.md index fd0b081..28f6dea 100644 --- a/libmpv/README.md +++ b/libmpv/README.md @@ -73,8 +73,7 @@ An older variant of the render API is called opengl-cb (in `libmpv/opengl_cb.h`) It is almost equivalent, but is hardcoded to OpenGL and has some other disadvantages. It is deprecated, and you should use `libmpv/render.h` instead. -Unfortunately, many examples still use he opengl-cb API. Changing to the new -render API is trivial, though. +The old API does not work anymore (as of mpv 0.33.0), and was deactivated. ### Which one to use? diff --git a/libmpv/ios/ViewController.h b/libmpv/ios/ViewController.h deleted file mode 100644 index a79652b..0000000 --- a/libmpv/ios/ViewController.h +++ /dev/null @@ -1,7 +0,0 @@ -#import <UIKit/UIKit.h> - -@interface ViewController : UIViewController - - -@end - diff --git a/libmpv/ios/ViewController.m b/libmpv/ios/ViewController.m deleted file mode 100644 index ddd71e7..0000000 --- a/libmpv/ios/ViewController.m +++ /dev/null @@ -1,209 +0,0 @@ -@import GLKit; -@import OpenGLES; - -#import "ViewController.h" - - -#import <mpv/client.h> -#import <mpv/opengl_cb.h> - -#import <stdio.h> -#import <stdlib.h> - - -static inline void check_error(int status) -{ - if (status < 0) { - printf("mpv API error: %s\n", mpv_error_string(status)); - exit(1); - } -} - -static void *get_proc_address(void *ctx, const char *name) -{ - CFStringRef symbolName = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingASCII); - void *addr = CFBundleGetFunctionPointerForName(CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengles")), symbolName); - CFRelease(symbolName); - return addr; -} - -static void glupdate(void *ctx); - -@interface MpvClientOGLView : GLKView - @property mpv_opengl_cb_context *mpvGL; -@end - -@implementation MpvClientOGLView { - GLint defaultFBO; -} - -- (void)awakeFromNib -{ - [super awakeFromNib]; - self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]; - [EAGLContext setCurrentContext:self.context]; - - // Configure renderbuffers created by the view - self.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888; - self.drawableDepthFormat = GLKViewDrawableDepthFormatNone; - self.drawableStencilFormat = GLKViewDrawableStencilFormatNone; - - defaultFBO = -1; -} - -- (void)fillBlack -{ - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT); -} - -- (void)drawRect -{ - if (defaultFBO == -1) - { - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); - } - - if (self.mpvGL) - { - mpv_opengl_cb_draw(self.mpvGL, - defaultFBO, - self.bounds.size.width * self.contentScaleFactor, - -self.bounds.size.height * self.contentScaleFactor); - } -} - -- (void)drawRect:(CGRect)rect -{ - [self drawRect]; -} - -@end - - - -static void wakeup(void *); - - -static void glupdate(void *ctx) -{ - MpvClientOGLView *glView = (__bridge MpvClientOGLView *)ctx; - // I'm still not sure what the best way to handle this is, but this - // works. - dispatch_async(dispatch_get_main_queue(), ^{ - [glView display]; - }); -} - - -@interface ViewController () - -@property (nonatomic) IBOutlet MpvClientOGLView *glView; -- (void) readEvents; - -@end - -static void wakeup(void *context) -{ - ViewController *a = (__bridge ViewController *) context; - [a readEvents]; -} - - - -@implementation ViewController { - mpv_handle *mpv; - dispatch_queue_t queue; -} - -- (void)viewDidLoad { - [super viewDidLoad]; - - // Do any additional setup after loading the view, typically from a nib. - - mpv = mpv_create(); - if (!mpv) { - printf("failed creating context\n"); - exit(1); - } - - // request important errors - NSString *logFile = [NSTemporaryDirectory() stringByAppendingPathComponent:@"mpv-log.txt"]; - NSLog(@"%@", logFile); - check_error(mpv_set_option_string(mpv, "log-file", logFile.UTF8String)); - check_error(mpv_request_log_messages(mpv, "warn")); - check_error(mpv_initialize(mpv)); - check_error(mpv_set_option_string(mpv, "vo", "opengl-cb")); - - mpv_opengl_cb_context *mpvGL = mpv_get_sub_api(mpv, MPV_SUB_API_OPENGL_CB); - if (!mpvGL) { - puts("libmpv does not have the opengl-cb sub-API."); - exit(1); - } - - [self.glView display]; - - // pass the mpvGL context to our view - self.glView.mpvGL = mpvGL; - int r = mpv_opengl_cb_init_gl(mpvGL, NULL, get_proc_address, NULL); - if (r < 0) { - puts("gl init has failed."); - exit(1); - } - mpv_opengl_cb_set_update_callback(mpvGL, glupdate, (__bridge void *)self.glView); - - // Deal with MPV in the background. - queue = dispatch_queue_create("mpv", DISPATCH_QUEUE_SERIAL); - dispatch_async(queue, ^{ - // Register to be woken up whenever mpv generates new events. - mpv_set_wakeup_callback(mpv, wakeup, (__bridge void *)self); - // Load the indicated file - - const char *cmd[] = {"loadfile", "http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_640x360.m4v", NULL}; - check_error(mpv_command(mpv, cmd)); - check_error(mpv_set_option_string(mpv, "loop", "inf")); - }); -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. -} - -- (void)handleEvent:(mpv_event *)event -{ - switch (event->event_id) { - case MPV_EVENT_SHUTDOWN: { - mpv_detach_destroy(mpv); - mpv_opengl_cb_uninit_gl(self.glView.mpvGL); - mpv = NULL; - printf("event: shutdown\n"); - break; - } - - case MPV_EVENT_LOG_MESSAGE: { - struct mpv_event_log_message *msg = (struct mpv_event_log_message *)event->data; - printf("[%s] %s: %s", msg->prefix, msg->level, msg->text); - } - - default: - printf("event: %s\n", mpv_event_name(event->event_id)); - } -} - -- (void)readEvents -{ - dispatch_async(queue, ^{ - while (mpv) { - mpv_event *event = mpv_wait_event(mpv, 0); - if (event->event_id == MPV_EVENT_NONE) - { - break; - } - [self handleEvent:event]; - } - }); -} - -@end diff --git a/libmpv/qml_direct/main.cpp b/libmpv/qml_direct/main.cpp deleted file mode 100644 index 7f7e22b..0000000 --- a/libmpv/qml_direct/main.cpp +++ /dev/null @@ -1,173 +0,0 @@ -#include "main.h" - -#include <stdexcept> -#include <clocale> - -#include <QObject> -#include <QtGlobal> -#include <QOpenGLContext> - -#include <QGuiApplication> -#include <QtQuick/QQuickWindow> -#include <QtQuick/QQuickView> - -static void *get_proc_address(void *ctx, const char *name) { - (void)ctx; - QOpenGLContext *glctx = QOpenGLContext::currentContext(); - if (!glctx) - return NULL; - return (void *)glctx->getProcAddress(QByteArray(name)); -} - -MpvRenderer::MpvRenderer(mpv::qt::Handle a_mpv, mpv_opengl_cb_context *a_mpv_gl) - : mpv(a_mpv), mpv_gl(a_mpv_gl), window(0), size() -{ - int r = mpv_opengl_cb_init_gl(mpv_gl, NULL, get_proc_address, NULL); - if (r < 0) - throw std::runtime_error("could not initialize OpenGL"); -} - -MpvRenderer::~MpvRenderer() -{ - // 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); -} - -void MpvRenderer::paint() -{ - window->resetOpenGLState(); - - // This uses 0 as framebuffer, which indicates that mpv will render directly - // to the frontbuffer. Note that mpv will always switch framebuffers - // explicitly. Some QWindow setups (such as using QQuickWidget) actually - // want you to render into a FBO in the beforeRendering() signal, and this - // code won't work there. - // The negation is used for rendering with OpenGL's flipped coordinates. - mpv_opengl_cb_draw(mpv_gl, 0, size.width(), -size.height()); - - window->resetOpenGLState(); -} - -MpvObject::MpvObject(QQuickItem * parent) - : QQuickItem(parent), mpv_gl(0), renderer(0), killOnce(false) -{ - mpv = mpv::qt::Handle::FromRawHandle(mpv_create()); - if (!mpv) - throw std::runtime_error("could not create mpv context"); - - mpv_set_option_string(mpv, "terminal", "yes"); - mpv_set_option_string(mpv, "msg-level", "all=v"); - - if (mpv_initialize(mpv) < 0) - throw std::runtime_error("could not initialize mpv context"); - - // Make use of the MPV_SUB_API_OPENGL_CB API. - mpv::qt::set_option_variant(mpv, "vo", "opengl-cb"); - - // Setup the callback that will make QtQuick update and redraw if there - // is a new video frame. Use a queued connection: this makes sure the - // doUpdate() function is run on the GUI thread. - mpv_gl = (mpv_opengl_cb_context *)mpv_get_sub_api(mpv, MPV_SUB_API_OPENGL_CB); - if (!mpv_gl) - throw std::runtime_error("OpenGL not compiled in"); - mpv_opengl_cb_set_update_callback(mpv_gl, MpvObject::on_update, (void *)this); - connect(this, &MpvObject::onUpdate, this, &MpvObject::doUpdate, - Qt::QueuedConnection); - - connect(this, &QQuickItem::windowChanged, - this, &MpvObject::handleWindowChanged); -} - -MpvObject::~MpvObject() -{ - if (mpv_gl) - mpv_opengl_cb_set_update_callback(mpv_gl, NULL, NULL); -} - -void MpvObject::handleWindowChanged(QQuickWindow *win) -{ - if (!win) - return; - connect(win, &QQuickWindow::beforeSynchronizing, - this, &MpvObject::sync, Qt::DirectConnection); - connect(win, &QQuickWindow::sceneGraphInvalidated, - this, &MpvObject::cleanup, Qt::DirectConnection); - connect(win, &QQuickWindow::frameSwapped, - this, &MpvObject::swapped, Qt::DirectConnection); - win->setClearBeforeRendering(false); -} - -void MpvObject::sync() -{ - if (killOnce) - cleanup(); - killOnce = false; - - if (!renderer) { - renderer = new MpvRenderer(mpv, mpv_gl); - connect(window(), &QQuickWindow::beforeRendering, - renderer, &MpvRenderer::paint, Qt::DirectConnection); - } - renderer->window = window(); - renderer->size = window()->size() * window()->devicePixelRatio(); -} - -void MpvObject::swapped() -{ - mpv_opengl_cb_report_flip(mpv_gl, 0); -} - -void MpvObject::cleanup() -{ - if (renderer) { - delete renderer; - renderer = 0; - } -} - -void MpvObject::on_update(void *ctx) -{ - MpvObject *self = (MpvObject *)ctx; - emit self->onUpdate(); -} - -// connected to onUpdate(); signal makes sure it runs on the GUI thread -void MpvObject::doUpdate() -{ - window()->update(); -} - -void MpvObject::command(const QVariant& params) -{ - mpv::qt::command_variant(mpv, params); -} - -void MpvObject::reinitRenderer() -{ - // Don't make it stop playback if the VO dies. - mpv_set_option_string(mpv, "stop-playback-on-init-failure", "no"); - // Make it recreate the renderer, which involves calling - // mpv_opengl_cb_uninit_gl() (which is the thing we want to test). - killOnce = true; - window()->update(); -} - -int main(int argc, char **argv) -{ - QGuiApplication app(argc, argv); - - // Qt sets the locale in the QGuiApplication constructor, but libmpv - // requires the LC_NUMERIC category to be set to "C", so change it back. - std::setlocale(LC_NUMERIC, "C"); - - qmlRegisterType<MpvObject>("mpvtest", 1, 0, "MpvObject"); - - QQuickView view; - view.setResizeMode(QQuickView::SizeRootObjectToView); - view.setSource(QUrl("qrc:///mpvtest/main.qml")); - view.show(); - - return app.exec(); -} diff --git a/libmpv/qml_direct/main.h b/libmpv/qml_direct/main.h deleted file mode 100644 index e73af34..0000000 --- a/libmpv/qml_direct/main.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef MPVRENDERER_H_ -#define MPVRENDERER_H_ - -#include <QtQuick/QQuickItem> - -#include <mpv/client.h> -#include <mpv/opengl_cb.h> -#include "../common/qthelper.hpp" - -class MpvRenderer : public QObject -{ - Q_OBJECT - mpv::qt::Handle mpv; - mpv_opengl_cb_context *mpv_gl; - QQuickWindow *window; - QSize size; - - friend class MpvObject; -public: - MpvRenderer(mpv::qt::Handle a_mpv, mpv_opengl_cb_context *a_mpv_gl); - virtual ~MpvRenderer(); -public slots: - void paint(); -}; - -class MpvObject : public QQuickItem -{ - Q_OBJECT - - mpv::qt::Handle mpv; - mpv_opengl_cb_context *mpv_gl; - MpvRenderer *renderer; - bool killOnce; - -public: - MpvObject(QQuickItem * parent = 0); - virtual ~MpvObject(); -public slots: - void command(const QVariant& params); - void sync(); - void swapped(); - void cleanup(); - void reinitRenderer(); -signals: - void onUpdate(); -private slots: - void doUpdate(); - void handleWindowChanged(QQuickWindow *win); -private: - static void on_update(void *ctx); -}; - -#endif diff --git a/libmpv/qml_direct/main.qml b/libmpv/qml_direct/main.qml deleted file mode 100644 index a8a68d5..0000000 --- a/libmpv/qml_direct/main.qml +++ /dev/null @@ -1,62 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 1.0 - -import mpvtest 1.0 - -Item { - width: 1280 - height: 720 - - MpvObject { - id: renderer - - // This object isn't real and not visible; it just renders into the - // background of the containing Window. - width: 0 - height: 0 - } - - MouseArea { - anchors.fill: parent - onClicked: renderer.command(["loadfile", "test.mkv"]) - } - - Rectangle { - id: labelFrame - anchors.margins: -50 - radius: 5 - color: "white" - border.color: "black" - opacity: 0.8 - anchors.fill: box - } - - Row { - id: box - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: 100 - - Text { - anchors.margins: 10 - wrapMode: Text.WordWrap - text: "QtQuick and mpv are both rendering stuff.\n - In this example, mpv is always in the background.\n - Click to load test.mkv" - } - - Column { - Button { - anchors.margins: 10 - text: "Reinit QQuickItem renderer (for testing opengl-cb uninit during playback)" - onClicked: renderer.reinitRenderer() - } - Button { - anchors.margins: 10 - text: "Cycle video" - onClicked: renderer.command(["cycle", "video"]) - } - } - } -} diff --git a/libmpv/qml_direct/mpvtest.pro b/libmpv/qml_direct/mpvtest.pro deleted file mode 100644 index 0b2e96f..0000000 --- a/libmpv/qml_direct/mpvtest.pro +++ /dev/null @@ -1,12 +0,0 @@ -QT += qml quick - -HEADERS += main.h -SOURCES += main.cpp - -QT_CONFIG -= no-pkg-config -CONFIG += link_pkgconfig debug -PKGCONFIG += mpv - -RESOURCES += mpvtest.qrc - -OTHER_FILES += main.qml diff --git a/libmpv/qml_direct/mpvtest.qrc b/libmpv/qml_direct/mpvtest.qrc deleted file mode 100644 index bb67265..0000000 --- a/libmpv/qml_direct/mpvtest.qrc +++ /dev/null @@ -1,5 +0,0 @@ -<RCC> - <qresource prefix="/mpvtest"> - <file>main.qml</file> - </qresource> -</RCC> diff --git a/libmpv/qt_opengl/mpvwidget.cpp b/libmpv/qt_opengl/mpvwidget.cpp index 16ee17e..c32a443 100644 --- a/libmpv/qt_opengl/mpvwidget.cpp +++ b/libmpv/qt_opengl/mpvwidget.cpp @@ -123,11 +123,11 @@ void MpvWidget::handle_mpv_event(mpv_event *event) } } -// Make Qt invoke mpv_opengl_cb_draw() to draw a new/updated video frame. +// Make Qt invoke mpv_render_context_render() to draw a new/updated video frame. void MpvWidget::maybeUpdate() { // If the Qt window is not visible, Qt's update() will just skip rendering. - // This confuses mpv's opengl-cb API, and may lead to small occasional + // This confuses mpv's render API, and may lead to small occasional // freezes due to video rendering timing out. // Handle this by manually redrawing. // Note: Qt doesn't seem to provide a way to query whether update() will diff --git a/libmpv/wxwidgets_opengl/main.cpp b/libmpv/wxwidgets_opengl/main.cpp deleted file mode 100644 index 603cf52..0000000 --- a/libmpv/wxwidgets_opengl/main.cpp +++ /dev/null @@ -1,342 +0,0 @@ -// Build with: g++ -o main main.cpp `wx-config --libs --cxxflags --gl_libs` -lmpv
-
-#include "main.h"
-
-#include <clocale>
-#include <string>
-
-#include <wx/dcbuffer.h>
-#include <wx/display.h>
-
-wxIMPLEMENT_APP(MpvApp);
-
-bool MpvApp::OnInit()
-{
- std::setlocale(LC_NUMERIC, "C");
- (new MpvFrame)->Show(true);
- return true;
-}
-
-wxBEGIN_EVENT_TABLE(MpvGLCanvas, wxGLCanvas)
- EVT_SIZE(MpvGLCanvas::OnSize)
- EVT_PAINT(MpvGLCanvas::OnPaint)
- EVT_ERASE_BACKGROUND(MpvGLCanvas::OnErase)
-wxEND_EVENT_TABLE()
-
-MpvGLCanvas::MpvGLCanvas(wxWindow *parent)
- : wxGLCanvas(parent)
-{
- SetBackgroundStyle(wxBG_STYLE_CUSTOM);
- glContext = new wxGLContext(this);
-}
-
-MpvGLCanvas::~MpvGLCanvas()
-{
- OnRender = nullptr;
- OnSwapBuffers = nullptr;
-
- if (glContext)
- delete glContext;
-}
-
-bool MpvGLCanvas::SetCurrent() const
-{
- if (!glContext)
- return false;
- return wxGLCanvas::SetCurrent(*glContext);
-}
-
-bool MpvGLCanvas::SwapBuffers()
-{
- bool result = wxGLCanvas::SwapBuffers();
- if (OnSwapBuffers)
- OnSwapBuffers(this);
- return result;
-}
-
-void MpvGLCanvas::OnSize(wxSizeEvent &)
-{
- Update();
-}
-
-void MpvGLCanvas::OnErase(wxEraseEvent &event)
-{
- // do nothing to skip erase
-}
-
-void MpvGLCanvas::Render()
-{
- wxClientDC(this);
- DoRender();
-}
-
-void MpvGLCanvas::OnPaint(wxPaintEvent &)
-{
- wxAutoBufferedPaintDC(this);
- DoRender();
-}
-
-void MpvGLCanvas::DoRender()
-{
- SetCurrent();
- if (OnRender)
- OnRender(this, GetSize().x, GetSize().y);
- SwapBuffers();
-}
-
-void *MpvGLCanvas::GetProcAddress(const char *name)
-{
- SetCurrent();
-
-#ifdef __WINDOWS__
- void *result = (void *)::wglGetProcAddress(name);
- if (!result) {
- HMODULE dll = ::LoadLibrary(wxT("opengl32.dll"));
- if (dll) {
- result = (void *)::GetProcAddress(dll, name);
- ::FreeLibrary(dll);
- }
- }
- return result;
-#else
- return (void *)::glxGetProcAddressARB(name);
-#endif
-}
-
-wxDECLARE_APP(MpvApp);
-
-wxDEFINE_EVENT(WX_MPV_WAKEUP, wxThreadEvent);
-wxDEFINE_EVENT(WX_MPV_REDRAW, wxThreadEvent);
-
-wxBEGIN_EVENT_TABLE(MpvFrame, wxFrame)
- EVT_SIZE(MpvFrame::OnSize)
- EVT_CHAR_HOOK(MpvFrame::OnKeyDown)
- EVT_DROP_FILES(MpvFrame::OnDropFiles)
-wxEND_EVENT_TABLE()
-
-MpvFrame::MpvFrame()
- : wxFrame(nullptr, wxID_ANY, "mpv")
-{
- SetBackgroundColour(wxColour(*wxBLACK));
- Center();
- DragAcceptFiles(true);
-
- glCanvas = new MpvGLCanvas(this);
- glCanvas->SetClientSize(GetClientSize());
- glCanvas->OnRender = std::bind(&MpvFrame::DoMpvDraw, this,
- std::placeholders::_2, std::placeholders::_3);
- glCanvas->OnSwapBuffers = std::bind(&MpvFrame::DoMpvFlip, this);
-
- MpvCreate();
-
- if (wxGetApp().argc == 2) {
- const std::string filepath(wxGetApp().argv[1].utf8_str().data());
- const char *cmd[] = { "loadfile", filepath.c_str(), nullptr };
- mpv_command(mpv, cmd);
- }
-}
-
-bool MpvFrame::Destroy()
-{
- MpvDestroy();
- return wxFrame::Destroy();
-}
-
-void MpvFrame::MpvCreate()
-{
- MpvDestroy();
-
- mpv = mpv_create();
- if (!mpv)
- throw std::runtime_error("failed to create mpv instance");
-
- if (mpv_initialize(mpv) < 0)
- throw std::runtime_error("failed to initialize mpv");
-
- mpv_gl = (mpv_opengl_cb_context *)mpv_get_sub_api(mpv, MPV_SUB_API_OPENGL_CB);
- if (!mpv_gl)
- throw std::runtime_error("failed to create mpv GL API handle");
-
- if (mpv_opengl_cb_init_gl(mpv_gl, nullptr, [](void *canvas, const char *name) {
- auto glCanvas = reinterpret_cast<MpvGLCanvas *>(canvas);
- return glCanvas ? glCanvas->GetProcAddress(name) : nullptr;
- }, glCanvas) < 0)
- throw std::runtime_error("failed to initialize mpv GL context");
-
- if (mpv_set_property_string(mpv, "vo", "opengl-cb") < 0)
- throw std::runtime_error("failed to set mpv VO");
-
- mpv_observe_property(mpv, 0, "media-title", MPV_FORMAT_NONE);
-
- Bind(WX_MPV_WAKEUP, &MpvFrame::OnMpvWakeupEvent, this);
- mpv_set_wakeup_callback(mpv, [](void *data) {
- auto window = reinterpret_cast<MpvFrame *>(data);
- if (window) {
- auto event = new wxThreadEvent(WX_MPV_WAKEUP);
- window->GetEventHandler()->QueueEvent(event);
- }
- }, this);
-
- Bind(WX_MPV_REDRAW, &MpvFrame::OnMpvRedrawEvent, this);
- mpv_opengl_cb_set_update_callback(mpv_gl, [](void *data) {
- auto window = reinterpret_cast<MpvFrame *>(data);
- if (window) {
- auto event = new wxThreadEvent(WX_MPV_REDRAW);
- window->GetEventHandler()->QueueEvent(event);
- }
- }, this);
-}
-
-void MpvFrame::MpvDestroy()
-{
- Unbind(WX_MPV_WAKEUP, &MpvFrame::OnMpvWakeupEvent, this);
- Unbind(WX_MPV_REDRAW, &MpvFrame::OnMpvRedrawEvent, this);
-
- if (mpv_gl) {
- mpv_opengl_cb_set_update_callback(mpv_gl, nullptr, nullptr);
- mpv_opengl_cb_uninit_gl(mpv_gl);
- mpv_gl = nullptr;
- }
-
- if (mpv) {
- mpv_terminate_destroy(mpv);
- mpv = nullptr;
- }
-}
-
-bool MpvFrame::Autofit(int percent, bool larger, bool smaller)
-{
- int64_t w, h;
- if (!mpv || mpv_get_property(mpv, "dwidth", MPV_FORMAT_INT64, &w) < 0 ||
- mpv_get_property(mpv, "dheight", MPV_FORMAT_INT64, &h) < 0 ||
- w <= 0 || h <= 0)
- return false;
-
- int screen_id = wxDisplay::GetFromWindow(this);
- if (screen_id == wxNOT_FOUND)
- return false;
-
- wxRect screen = wxDisplay(screen_id).GetClientArea();
- const int n_w = (int)(screen.width * percent * 0.01);
- const int n_h = (int)(screen.height * percent * 0.01);
-
- if ((larger && (w > n_w || h > n_h)) ||
- (smaller && (w < n_w || h < n_h)))
- {
- const float asp = w / (float)h;
- const float n_asp = n_w / (float)n_h;
- if (asp > n_asp) {
- w = n_w;
- h = (int)(n_w / asp);
- } else {
- w = (int)(n_h * asp);
- h = n_h;
- }
- }
-
- const wxRect rc = GetScreenRect();
- SetClientSize(w, h);
- const wxRect n_rc = GetScreenRect();
-
- Move(rc.x + rc.width / 2 - n_rc.width / 2,
- rc.y + rc.height / 2 - n_rc.height / 2);
- return true;
-}
-
-void MpvFrame::OnSize(wxSizeEvent &event)
-{
- if (glCanvas)
- glCanvas->SetClientSize(GetClientSize());
-}
-
-void MpvFrame::OnKeyDown(wxKeyEvent &event)
-{
- if (mpv && event.GetKeyCode() == WXK_SPACE)
- mpv_command_string(mpv, "cycle pause");
- event.Skip();
-}
-
-void MpvFrame::OnDropFiles(wxDropFilesEvent &event)
-{
- int size = event.GetNumberOfFiles();
- if (!size || !mpv)
- return;
-
- auto files = event.GetFiles();
- if (!files)
- return;
-
- for (int i = 0; i < size; ++i) {
- const std::string filepath(files[i].utf8_str().data());
- const char *cmd[] = {
- "loadfile",
- filepath.c_str(),
- i == 0 ? "replace" : "append-play",
- NULL
- };
- mpv_command_async(mpv, 0, cmd);
- }
-}
-
-void MpvFrame::OnMpvEvent(mpv_event &event)
-{
- if (!mpv)
- return;
-
- switch (event.event_id) {
- case MPV_EVENT_VIDEO_RECONFIG:
- // something like --autofit-larger=95%
- Autofit(95, true, false);
- break;
- case MPV_EVENT_PROPERTY_CHANGE: {
- mpv_event_property *prop = (mpv_event_property *)event.data;
- if (strcmp(prop->name, "media-title") == 0) {
- char *data = nullptr;
- if (mpv_get_property(mpv, prop->name, MPV_FORMAT_OSD_STRING, &data) < 0) {
- SetTitle("mpv");
- } else {
- wxString title = wxString::FromUTF8(data);
- if (!title.IsEmpty())
- title += " - ";
- title += "mpv";
- SetTitle(title);
- mpv_free(data);
- }
- }
- break;
- }
- case MPV_EVENT_SHUTDOWN:
- MpvDestroy();
- break;
- default:
- break;
- }
-}
-
-void MpvFrame::OnMpvWakeupEvent(wxThreadEvent &)
-{
- while (mpv) {
- mpv_event *e = mpv_wait_event(mpv, 0);
- if (e->event_id == MPV_EVENT_NONE)
- break;
- OnMpvEvent(*e);
- }
-}
-
-void MpvFrame::OnMpvRedrawEvent(wxThreadEvent &)
-{
- if (glCanvas)
- glCanvas->Render();
-}
-
-void MpvFrame::DoMpvDraw(int w, int h)
-{
- if (mpv_gl)
- mpv_opengl_cb_draw(mpv_gl, 0, w, -h);
-}
-
-void MpvFrame::DoMpvFlip()
-{
- if (mpv_gl)
- mpv_opengl_cb_report_flip(mpv_gl, 0);
-}
diff --git a/libmpv/wxwidgets_opengl/main.h b/libmpv/wxwidgets_opengl/main.h deleted file mode 100644 index 14628ed..0000000 --- a/libmpv/wxwidgets_opengl/main.h +++ /dev/null @@ -1,75 +0,0 @@ -#pragma once
-
-#include <functional>
-
-#include <wx/wxprec.h>
-#ifndef WX_PRECOMP
- #include <wx/wx.h>
-#endif
-
-#include <wx/glcanvas.h>
-
-#include <mpv/client.h>
-#include <mpv/opengl_cb.h>
-
-class MpvApp : public wxApp
-{
-public:
- bool OnInit() override;
-};
-
-class MpvGLCanvas : public wxGLCanvas
-{
-public:
- MpvGLCanvas(wxWindow *parent);
- ~MpvGLCanvas();
-
- void Render();
- bool SetCurrent() const;
- bool SwapBuffers() override;
- void *GetProcAddress(const char *name);
-
- std::function<void (wxGLCanvas *, int w, int h)> OnRender = nullptr;
- std::function<void (wxGLCanvas *)> OnSwapBuffers = nullptr;
-
-private:
- void OnSize(wxSizeEvent &event);
- void OnPaint(wxPaintEvent &event);
- void OnErase(wxEraseEvent &event);
-
- void DoRender();
-
- wxGLContext *glContext = nullptr;
-
- wxDECLARE_EVENT_TABLE();
-};
-
-class MpvFrame : public wxFrame
-{
-public:
- MpvFrame();
-
- bool Destroy() override;
- bool Autofit(int percent, bool larger = true, bool smaller = true);
-
-private:
- void MpvCreate();
- void MpvDestroy();
-
- void OnSize(wxSizeEvent &event);
- void OnKeyDown(wxKeyEvent &event);
- void OnDropFiles(wxDropFilesEvent &event);
-
- void OnMpvEvent(mpv_event &event);
- void OnMpvWakeupEvent(wxThreadEvent &event);
- void OnMpvRedrawEvent(wxThreadEvent &event);
-
- void DoMpvDraw(int w, int h);
- void DoMpvFlip();
-
- mpv_handle *mpv = nullptr;
- mpv_opengl_cb_context *mpv_gl = nullptr;
- MpvGLCanvas *glCanvas = nullptr;
-
- wxDECLARE_EVENT_TABLE();
-};
|