summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2020-09-03 14:55:26 +0200
committerwm4 <wm4@nowhere>2020-09-03 14:55:26 +0200
commit829775865dbd69db9211cd4b6b6c9b1e5ad82953 (patch)
treec1c0e9f7c88303ac8326db0fc2827a52b1c931b0
parent9be9e0877cbfe1ec19d359464a9121db56f6b0ed (diff)
downloadmpv-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.md3
-rw-r--r--libmpv/ios/ViewController.h7
-rw-r--r--libmpv/ios/ViewController.m209
-rw-r--r--libmpv/qml_direct/main.cpp173
-rw-r--r--libmpv/qml_direct/main.h53
-rw-r--r--libmpv/qml_direct/main.qml62
-rw-r--r--libmpv/qml_direct/mpvtest.pro12
-rw-r--r--libmpv/qml_direct/mpvtest.qrc5
-rw-r--r--libmpv/qt_opengl/mpvwidget.cpp4
-rw-r--r--libmpv/wxwidgets_opengl/main.cpp342
-rw-r--r--libmpv/wxwidgets_opengl/main.h75
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();
-};