Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2da6c95208 |
No files matched your search
+1
-2
@@ -14,6 +14,7 @@
|
||||
/input/input_conf.h
|
||||
/tags
|
||||
/TAGS
|
||||
/video/out/gl_video_shaders.h
|
||||
/video/out/x11_icon.inc
|
||||
/demux/ebml_defs.c
|
||||
/demux/ebml_types.h
|
||||
@@ -27,8 +28,6 @@
|
||||
/DOCS/man/mpv.toc
|
||||
|
||||
/waf
|
||||
/waf-*
|
||||
/waf3-*
|
||||
/build
|
||||
/.waf*
|
||||
/.lock-waf_*
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ notifications:
|
||||
email: false
|
||||
irc:
|
||||
channels:
|
||||
- "irc.freenode.org#mpv-devel"
|
||||
- "irc.freenode.org#mpv-player-dev"
|
||||
on_success: change
|
||||
on_failure: always
|
||||
|
||||
|
||||
@@ -25,28 +25,6 @@ API changes
|
||||
|
||||
::
|
||||
|
||||
--- mpv 0.9.0 is released ---
|
||||
1.17 - add MPV_FORMAT_BYTE_ARRAY
|
||||
1.16 - add mpv_opengl_cb_report_flip()
|
||||
- introduce mpv_opengl_cb_draw() and deprecate mpv_opengl_cb_render()
|
||||
1.15 - mpv_initialize() will now load config files. This requires setting
|
||||
the "config" and "config-dir" options. In particular, it will load
|
||||
mpv.conf.
|
||||
- minor backwards-compatible change to the "seek" and "screenshot"
|
||||
commands (new flag syntax, old additional args deprecated)
|
||||
--- mpv 0.8.0 is released ---
|
||||
1.14 - add mpv_wait_async_requests()
|
||||
- the --msg-level option changes its native type from a flat string to
|
||||
a key-value list (setting/reading the option as string still works)
|
||||
1.13 - add MPV_EVENT_QUEUE_OVERFLOW
|
||||
1.12 - add class Handle to qthelper.hpp
|
||||
- improve opengl_cb.h API uninitialization behavior, and fix the qml
|
||||
example
|
||||
- add mpv_create_client() function
|
||||
1.11 - add OpenGL rendering interop API - allows an application to combine
|
||||
its own and mpv's OpenGL rendering
|
||||
Warning: this API is not stable yet - anything in opengl_cb.h might
|
||||
be changed in completely incompatible ways in minor API bumps
|
||||
--- mpv 0.7.0 is released ---
|
||||
1.10 - deprecate/disable everything directly related to script_dispatch
|
||||
(most likely affects nobody)
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
All examples in this directory and its sub-directories are licensed
|
||||
under one of the following licenses:
|
||||
|
||||
WTFPL, ISC, Ms-PL, AGPLv3, BSD (any)
|
||||
|
||||
Pick any license of your liking, and disregard the others.
|
||||
|
||||
(The full text of each license is available on this website:
|
||||
http://opensource.org/licenses/alphabetical )
|
||||
|
||||
Additionally, you may consider the example code to be public domain.
|
||||
You are free to use any of the example code without further
|
||||
requirements or need for attribution.
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
Client API examples
|
||||
===================
|
||||
|
||||
All these examples use the mpv client API through libmpv.
|
||||
|
||||
cocoa
|
||||
-----
|
||||
|
||||
Shows how to embed the mpv video window in Objective-C/Cocoa.
|
||||
|
||||
qt
|
||||
--
|
||||
|
||||
Shows how to embed the mpv video window in Qt (using normal desktop widgets).
|
||||
|
||||
qml
|
||||
---
|
||||
|
||||
Shows how to use mpv's OpenGL video renderer in QtQuick2 with QML.
|
||||
|
||||
qml_direct
|
||||
----------
|
||||
|
||||
Alternative example, which typically avoids a FBO indirection. Might be
|
||||
slightly faster, but is less flexible and harder to use.
|
||||
|
||||
simple
|
||||
------
|
||||
|
||||
Very primitive terminal-only example. Shows some most basic API usage.
|
||||
+17
-47
@@ -3,20 +3,8 @@
|
||||
// but that's not quite ready yet.
|
||||
// You may need a basic Info.plist and MainMenu.xib to make this work.
|
||||
|
||||
// Build with: clang -o cocoabasic cocoabasic.m `pkg-config --libs --cflags mpv`
|
||||
|
||||
#include <mpv/client.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static inline void check_error(int status)
|
||||
{
|
||||
if (status < 0) {
|
||||
printf("mpv API error: %s\n", mpv_error_string(status));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
#include "../../libmpv/client.h"
|
||||
#include "shared.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@@ -33,7 +21,6 @@ static inline void check_error(int status)
|
||||
mpv_handle *mpv;
|
||||
dispatch_queue_t queue;
|
||||
NSWindow *w;
|
||||
NSView *wrapper;
|
||||
}
|
||||
@end
|
||||
|
||||
@@ -56,19 +43,11 @@ static void wakeup(void *);
|
||||
[self->w makeMainWindow];
|
||||
[self->w makeKeyAndOrderFront:nil];
|
||||
|
||||
NSRect frame = [[self->w contentView] bounds];
|
||||
self->wrapper = [[NSView alloc] initWithFrame:frame];
|
||||
[self->wrapper setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
|
||||
[[self->w contentView] addSubview:self->wrapper];
|
||||
[self->wrapper release];
|
||||
|
||||
NSMenu *m = [[NSMenu alloc] initWithTitle:@"AMainMenu"];
|
||||
NSMenuItem *item = [m addItemWithTitle:@"Apple" action:nil keyEquivalent:@""];
|
||||
NSMenu *sm = [[NSMenu alloc] initWithTitle:@"Apple"];
|
||||
[m setSubmenu:sm forItem:item];
|
||||
[sm addItemWithTitle: @"mpv_command('stop')" action:@selector(mpv_stop) keyEquivalent:@""];
|
||||
[sm addItemWithTitle: @"mpv_command('quit')" action:@selector(mpv_quit) keyEquivalent:@""];
|
||||
[sm addItemWithTitle: @"quit" action:@selector(terminate:) keyEquivalent:@"q"];
|
||||
[sm addItemWithTitle: @"Shutdown mpv" action:@selector(shutdown) keyEquivalent:@"s"];
|
||||
[NSApp setMenu:m];
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
}
|
||||
@@ -102,7 +81,7 @@ static void wakeup(void *);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int64_t wid = (intptr_t) self->wrapper;
|
||||
int64_t wid = (intptr_t) [self->w contentView];
|
||||
check_error(mpv_set_option(mpv, "wid", MPV_FORMAT_INT64, &wid));
|
||||
|
||||
// Maybe set some options here, like default key bindings.
|
||||
@@ -131,28 +110,24 @@ static void wakeup(void *);
|
||||
- (void) handleEvent:(mpv_event *)event
|
||||
{
|
||||
switch (event->event_id) {
|
||||
case MPV_EVENT_SHUTDOWN: {
|
||||
mpv_detach_destroy(mpv);
|
||||
case MPV_EVENT_SHUTDOWN:
|
||||
// Clean up and shut down.
|
||||
mpv_terminate_destroy(mpv);
|
||||
mpv = NULL;
|
||||
printf("event: shutdown\n");
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[[NSApplication sharedApplication] terminate:nil];
|
||||
});
|
||||
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);
|
||||
}
|
||||
|
||||
case MPV_EVENT_VIDEO_RECONFIG: {
|
||||
case MPV_EVENT_VIDEO_RECONFIG:
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSArray *subviews = [self->wrapper subviews];
|
||||
if ([subviews count] > 0) {
|
||||
// mpv's events view
|
||||
NSView *eview = [self->wrapper subviews][0];
|
||||
[self->w makeFirstResponder:eview];
|
||||
}
|
||||
[self->w selectNextKeyView:nil];
|
||||
});
|
||||
}
|
||||
|
||||
default:
|
||||
printf("event: %s\n", mpv_event_name(event->event_id));
|
||||
@@ -179,18 +154,13 @@ static void wakeup(void *context) {
|
||||
// Ostensibly, mpv's window would be hooked up to this.
|
||||
- (BOOL) windowShouldClose:(id)sender
|
||||
{
|
||||
return NO;
|
||||
[self shutdown];
|
||||
if (self->w)
|
||||
[self->w release];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) mpv_stop
|
||||
{
|
||||
if (mpv) {
|
||||
const char *args[] = {"stop", NULL};
|
||||
mpv_command(mpv, args);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) mpv_quit
|
||||
- (void) shutdown
|
||||
{
|
||||
if (mpv) {
|
||||
const char *args[] = {"quit", NULL};
|
||||
@@ -1,136 +0,0 @@
|
||||
#include "main.h"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <clocale>
|
||||
|
||||
#include <QObject>
|
||||
#include <QtGlobal>
|
||||
#include <QOpenGLContext>
|
||||
#include <QGuiApplication>
|
||||
|
||||
#include <QtGui/QOpenGLFramebufferObject>
|
||||
|
||||
#include <QtQuick/QQuickWindow>
|
||||
#include <QtQuick/QQuickView>
|
||||
|
||||
class MpvRenderer : public QQuickFramebufferObject::Renderer
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
mpv::qt::Handle mpv;
|
||||
QQuickWindow *window;
|
||||
mpv_opengl_cb_context *mpv_gl;
|
||||
public:
|
||||
MpvRenderer(const MpvObject *obj)
|
||||
: mpv(obj->mpv), window(obj->window()), mpv_gl(obj->mpv_gl)
|
||||
{
|
||||
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");
|
||||
}
|
||||
|
||||
virtual ~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 render()
|
||||
{
|
||||
QOpenGLFramebufferObject *fbo = framebufferObject();
|
||||
window->resetOpenGLState();
|
||||
mpv_opengl_cb_draw(mpv_gl, fbo->handle(), fbo->width(), fbo->height());
|
||||
window->resetOpenGLState();
|
||||
}
|
||||
};
|
||||
|
||||
MpvObject::MpvObject(QQuickItem * parent)
|
||||
: QQuickFramebufferObject(parent), mpv_gl(0)
|
||||
{
|
||||
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");
|
||||
|
||||
// Request hw decoding, just for testing.
|
||||
mpv::qt::set_option_variant(mpv, "hwdec", "auto");
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
MpvObject::~MpvObject()
|
||||
{
|
||||
if (mpv_gl)
|
||||
mpv_opengl_cb_set_update_callback(mpv_gl, NULL, NULL);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
void MpvObject::command(const QVariant& params)
|
||||
{
|
||||
mpv::qt::command_variant(mpv, params);
|
||||
}
|
||||
|
||||
void MpvObject::setProperty(const QString& name, const QVariant& value)
|
||||
{
|
||||
mpv::qt::set_property_variant(mpv, name, value);
|
||||
}
|
||||
|
||||
QQuickFramebufferObject::Renderer *MpvObject::createRenderer() const
|
||||
{
|
||||
window()->setPersistentOpenGLContext(true);
|
||||
window()->setPersistentSceneGraph(true);
|
||||
return new MpvRenderer(this);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
#ifndef MPVRENDERER_H_
|
||||
#define MPVRENDERER_H_
|
||||
|
||||
#include <QtQuick/QQuickFramebufferObject>
|
||||
|
||||
#include <mpv/client.h>
|
||||
#include <mpv/opengl_cb.h>
|
||||
#include <mpv/qthelper.hpp>
|
||||
|
||||
class MpvRenderer;
|
||||
|
||||
class MpvObject : public QQuickFramebufferObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
mpv::qt::Handle mpv;
|
||||
mpv_opengl_cb_context *mpv_gl;
|
||||
|
||||
friend class MpvRenderer;
|
||||
|
||||
public:
|
||||
MpvObject(QQuickItem * parent = 0);
|
||||
virtual ~MpvObject();
|
||||
virtual Renderer *createRenderer() const;
|
||||
public slots:
|
||||
void command(const QVariant& params);
|
||||
void setProperty(const QString& name, const QVariant& value);
|
||||
signals:
|
||||
void onUpdate();
|
||||
private slots:
|
||||
void doUpdate();
|
||||
private:
|
||||
static void on_update(void *ctx);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,71 +0,0 @@
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Controls 1.0
|
||||
|
||||
import mpvtest 1.0
|
||||
|
||||
Item {
|
||||
width: 1280
|
||||
height: 720
|
||||
|
||||
MpvObject {
|
||||
id: renderer
|
||||
anchors.fill: parent
|
||||
|
||||
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: renderer.bottom
|
||||
anchors.left: renderer.left
|
||||
anchors.right: renderer.right
|
||||
anchors.margins: 100
|
||||
|
||||
Text {
|
||||
anchors.margins: 10
|
||||
wrapMode: Text.WordWrap
|
||||
text: "QtQuick and mpv are both rendering stuff.\n
|
||||
Click to load ../../../test.mkv"
|
||||
}
|
||||
|
||||
// Don't take these controls too seriously. They're for testing.
|
||||
Column {
|
||||
CheckBox {
|
||||
id: checkbox
|
||||
anchors.margins: 10
|
||||
// Heavily filtered means good, right?
|
||||
text: "Make video look like on a Smart TV"
|
||||
onClicked: {
|
||||
if (checkbox.checked) {
|
||||
renderer.command(["vo_cmdline", "scale=sharpen3:scale-param1=5.0"])
|
||||
} else {
|
||||
renderer.command(["vo_cmdline", ""])
|
||||
}
|
||||
}
|
||||
}
|
||||
Slider {
|
||||
id: slider
|
||||
anchors.margins: 10
|
||||
anchors.left: checkbox.left
|
||||
anchors.right: checkbox.right
|
||||
minimumValue: -100
|
||||
maximumValue: 100
|
||||
value: 0
|
||||
onValueChanged: renderer.setProperty("gamma", slider.value | 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -1,5 +0,0 @@
|
||||
<RCC>
|
||||
<qresource prefix="/mpvtest">
|
||||
<file>main.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -1,159 +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)
|
||||
{
|
||||
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 (!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);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
#ifndef MPVRENDERER_H_
|
||||
#define MPVRENDERER_H_
|
||||
|
||||
#include <QtQuick/QQuickItem>
|
||||
|
||||
#include <mpv/client.h>
|
||||
#include <mpv/opengl_cb.h>
|
||||
#include <mpv/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;
|
||||
|
||||
public:
|
||||
MpvObject(QQuickItem * parent = 0);
|
||||
virtual ~MpvObject();
|
||||
public slots:
|
||||
void command(const QVariant& params);
|
||||
void sync();
|
||||
void swapped();
|
||||
void cleanup();
|
||||
signals:
|
||||
void onUpdate();
|
||||
private slots:
|
||||
void doUpdate();
|
||||
void handleWindowChanged(QQuickWindow *win);
|
||||
private:
|
||||
static void on_update(void *ctx);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,49 +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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -1,5 +0,0 @@
|
||||
<RCC>
|
||||
<qresource prefix="/mpvtest">
|
||||
<file>main.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
+20
-26
@@ -1,8 +1,9 @@
|
||||
// License: pick one of: public domain, WTFPL, ISC, Ms-PL, AGPLv3
|
||||
|
||||
// This example can be built with: qmake && make
|
||||
|
||||
#include <clocale>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QFileDialog>
|
||||
@@ -28,7 +29,7 @@ static void wakeup(void *ctx)
|
||||
// the Qt GUI thread to wake up (so that it can process events with
|
||||
// mpv_wait_event()), and return as quickly as possible.
|
||||
MainWindow *mainwindow = (MainWindow *)ctx;
|
||||
emit mainwindow->mpv_events();
|
||||
QCoreApplication::postEvent(mainwindow, new QEvent(QEvent::User));
|
||||
}
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
@@ -41,13 +42,9 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
QAction *on_open = new QAction(tr("&Open"), this);
|
||||
on_open->setShortcuts(QKeySequence::Open);
|
||||
on_open->setStatusTip(tr("Open a file"));
|
||||
connect(on_open, &QAction::triggered, this, &MainWindow::on_file_open);
|
||||
connect(on_open, SIGNAL(triggered()), this, SLOT(on_file_open()));
|
||||
menu->addAction(on_open);
|
||||
|
||||
QAction *on_new = new QAction(tr("&New window"), this);
|
||||
connect(on_new, &QAction::triggered, this, &MainWindow::on_new_window);
|
||||
menu->addAction(on_new);
|
||||
|
||||
statusBar();
|
||||
|
||||
QMainWindow *log_window = new QMainWindow(this);
|
||||
@@ -60,7 +57,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
|
||||
mpv = mpv_create();
|
||||
if (!mpv)
|
||||
throw std::runtime_error("can't create mpv instance");
|
||||
throw "can't create mpv instance";
|
||||
|
||||
// Create a video child window. Force Qt to create a native window, and
|
||||
// pass the window ID to the mpv wid option. Works on: X11, win32, Cocoa
|
||||
@@ -92,14 +89,12 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
mpv_request_log_messages(mpv, "info");
|
||||
|
||||
// From this point on, the wakeup function will be called. The callback
|
||||
// can come from any thread, so we use the QueuedConnection mechanism to
|
||||
// relay the wakeup in a thread-safe way.
|
||||
connect(this, &MainWindow::mpv_events, this, &MainWindow::on_mpv_events,
|
||||
Qt::QueuedConnection);
|
||||
// can come from any thread, so we use the Qt QEvent mechanism to relay
|
||||
// the wakeup in a thread-safe way.
|
||||
mpv_set_wakeup_callback(mpv, wakeup, this);
|
||||
|
||||
if (mpv_initialize(mpv) < 0)
|
||||
throw std::runtime_error("mpv failed to initialize");
|
||||
throw "mpv failed to initialize";
|
||||
}
|
||||
|
||||
void MainWindow::handle_mpv_event(mpv_event *event)
|
||||
@@ -169,16 +164,20 @@ void MainWindow::handle_mpv_event(mpv_event *event)
|
||||
}
|
||||
}
|
||||
|
||||
// This slot is invoked by wakeup() (through the mpv_events signal).
|
||||
void MainWindow::on_mpv_events()
|
||||
bool MainWindow::event(QEvent *event)
|
||||
{
|
||||
// Process all events, until the event queue is empty.
|
||||
while (mpv) {
|
||||
mpv_event *event = mpv_wait_event(mpv, 0);
|
||||
if (event->event_id == MPV_EVENT_NONE)
|
||||
break;
|
||||
handle_mpv_event(event);
|
||||
// QEvent::User is sent by wakeup().
|
||||
if (event->type() == QEvent::User) {
|
||||
// Process all events, until the event queue is empty.
|
||||
while (mpv) {
|
||||
mpv_event *event = mpv_wait_event(mpv, 0);
|
||||
if (event->event_id == MPV_EVENT_NONE)
|
||||
break;
|
||||
handle_mpv_event(event);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return QMainWindow::event(event);
|
||||
}
|
||||
|
||||
void MainWindow::on_file_open()
|
||||
@@ -191,11 +190,6 @@ void MainWindow::on_file_open()
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_new_window()
|
||||
{
|
||||
(new MainWindow())->show();
|
||||
}
|
||||
|
||||
void MainWindow::append_log(const QString &text)
|
||||
{
|
||||
QTextCursor cursor = log->textCursor();
|
||||
@@ -15,13 +15,11 @@ public:
|
||||
explicit MainWindow(QWidget *parent = 0);
|
||||
~MainWindow();
|
||||
|
||||
protected:
|
||||
virtual bool event(QEvent *event);
|
||||
|
||||
private slots:
|
||||
void on_file_open();
|
||||
void on_new_window();
|
||||
void on_mpv_events();
|
||||
|
||||
signals:
|
||||
void mpv_events();
|
||||
|
||||
private:
|
||||
QWidget *mpv_container;
|
||||
@@ -5,9 +5,8 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
TARGET = qtexample
|
||||
TEMPLATE = app
|
||||
|
||||
QT_CONFIG -= no-pkg-config
|
||||
CONFIG += link_pkgconfig debug
|
||||
PKGCONFIG += mpv
|
||||
PKGCONFIG = mpv
|
||||
|
||||
SOURCES += qtexample.cpp
|
||||
HEADERS += qtexample.h
|
||||
@@ -0,0 +1,10 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static inline void check_error(int status)
|
||||
{
|
||||
if (status < 0) {
|
||||
printf("mpv API error: %s\n", mpv_error_string(status));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,9 @@
|
||||
// Build with: gcc -o simple simple.c `pkg-config --libs --cflags mpv`
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <mpv/client.h>
|
||||
|
||||
static inline void check_error(int status)
|
||||
{
|
||||
if (status < 0) {
|
||||
printf("mpv API error: %s\n", mpv_error_string(status));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
#include "libmpv/client.h"
|
||||
#include "shared.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@@ -30,7 +21,7 @@ int main(int argc, char *argv[])
|
||||
// Enable default key bindings, so the user can actually interact with
|
||||
// the player (and e.g. close the window).
|
||||
check_error(mpv_set_option_string(ctx, "input-default-bindings", "yes"));
|
||||
mpv_set_option_string(ctx, "input-vo-keyboard", "yes");
|
||||
mpv_set_option_string(ctx, "input-x11-keyboard", "yes");
|
||||
int val = 1;
|
||||
check_error(mpv_set_option(ctx, "osc", MPV_FORMAT_FLAG, &val));
|
||||
|
||||
@@ -1,212 +0,0 @@
|
||||
Compiling for Windows
|
||||
=====================
|
||||
|
||||
Compiling for Windows is supported with MinGW-w64. This can be used to produce
|
||||
both 32-bit and 64-bit executables, and it works for building on Windows and
|
||||
cross-compiling from Linux and Cygwin. MinGW-w64 is available from:
|
||||
http://mingw-w64.sourceforge.net.
|
||||
|
||||
While building a complete MinGW-w64 toolchain yourself is possible, there are a
|
||||
few build environments and scripts to help ease the process, such as MSYS2 and
|
||||
MXE. Note that MinGW environments included in Linux distributions are often
|
||||
broken, outdated and useless, and usually don't use MinGW-w64.
|
||||
|
||||
**Warning**: the original MinGW (http://www.mingw.org) is unsupported.
|
||||
|
||||
Cross-compilation
|
||||
=================
|
||||
|
||||
When cross-compiling, you have to run mpv's configure with these arguments:
|
||||
|
||||
```bash
|
||||
DEST_OS=win32 TARGET=i686-w64-mingw32 ./waf configure
|
||||
```
|
||||
|
||||
[MXE](http://mxe.cc) makes it very easy to bootstrap a complete MingGW-w64
|
||||
environment from a Linux machine. See a working example below.
|
||||
|
||||
Alternatively, you can try [mingw-w64-cmake](https://github.com/lachs0r/mingw-w64-cmake),
|
||||
which bootstraps a MinGW-w64 environment and builds mpv and dependencies.
|
||||
|
||||
Example with MXE
|
||||
----------------
|
||||
|
||||
```bash
|
||||
# Before starting, make sure you install MXE prerequisites. MXE will download
|
||||
# and build all target dependencies, but no host dependencies. For example,
|
||||
# you need a working compiler, or MXE can't build the crosscompiler.
|
||||
#
|
||||
# Refer to
|
||||
#
|
||||
# http://mxe.cc/#requirements
|
||||
#
|
||||
# Scroll down for disto/OS-specific instructions to install them.
|
||||
|
||||
# Download MXE. Note that compiling the required packages requires about 1.4 GB
|
||||
# or more!
|
||||
|
||||
cd /opt
|
||||
git clone https://github.com/mxe/mxe mxe
|
||||
cd mxe
|
||||
|
||||
# Set build options.
|
||||
|
||||
# The JOBS environment variable controls threads to use when building. DO NOT
|
||||
# use the regular `make -j4` option with MXE as it will slow down the build.
|
||||
# Alternatively, you can set this in the make command by appending "JOBS=4"
|
||||
# to the end of command:
|
||||
echo "JOBS := 4" >> settings.mk
|
||||
|
||||
# The MXE_TARGET environment variable builds MinGW-w64 for 32 bit targets.
|
||||
# Alternatively, you can specify this in the make command by appending
|
||||
# "MXE_TARGETS=i686-w64-mingw32" to the end of command:
|
||||
echo "MXE_TARGETS := i686-w64-mingw32.static" >> settings.mk
|
||||
|
||||
# If you want to build 64 bit version, use this:
|
||||
# echo "MXE_TARGETS := x86_64-w64-mingw32.static" >> settings.mk
|
||||
|
||||
# Build required packages. The following provide a minimum required to build
|
||||
# a reasonable mpv binary (though not an absolute minimum).
|
||||
|
||||
make gcc ffmpeg libass jpeg pthreads lua
|
||||
|
||||
# Add MXE binaries to $PATH
|
||||
export PATH=/opt/mxe/usr/bin/:$PATH
|
||||
|
||||
# Build mpv. The target will be used to automatically select the name of the
|
||||
# build tools involved (e.g. it will use i686-w64-mingw32.static-gcc).
|
||||
|
||||
cd ..
|
||||
git clone https://github.com/mpv-player/mpv.git
|
||||
cd mpv
|
||||
python ./bootstrap.py
|
||||
DEST_OS=win32 TARGET=i686-w64-mingw32.static ./waf configure
|
||||
# Or, if 64 bit version,
|
||||
# DEST_OS=win32 TARGET=x86_64-w64-mingw32.static ./waf configure
|
||||
./waf build
|
||||
```
|
||||
|
||||
Native compilation with MSYS2
|
||||
=============================
|
||||
|
||||
For Windows developers looking to get started quickly, MSYS2 can be used to
|
||||
compile mpv natively on a Windows machine. The MSYS2 repositories have binary
|
||||
packages for most of mpv's dependencies, so the process should only involve
|
||||
building mpv itself.
|
||||
|
||||
To build 64-bit mpv on Windows:
|
||||
|
||||
Installing MSYS2
|
||||
----------------
|
||||
|
||||
1. Download an installer from https://msys2.github.io/
|
||||
|
||||
It doesn't matter whether the i686 or the x86_64 version is used. Both can
|
||||
build 32-bit and 64-bit binaries when running on a 64-bit version of Windows.
|
||||
|
||||
2. Add ``C:\msys64\mingw64\bin`` to your ``%PATH%``. mpv will depend on several
|
||||
DLLs in this folder.
|
||||
|
||||
3. Start a MinGW-w64 shell (``mingw64_shell.bat``). For a 32-bit build, use
|
||||
``mingw32_shell.bat``.
|
||||
|
||||
Updating MSYS2
|
||||
--------------
|
||||
|
||||
To prevent errors during post-install, ``msys2-runtime`` and ``pacman`` must be
|
||||
updated first.
|
||||
|
||||
```bash
|
||||
# Check for updates to msys2-runtime and pacman. If there were updates, restart
|
||||
# MSYS2 before continuing.
|
||||
pacman -Sy --needed msys2-runtime pacman
|
||||
|
||||
# Update everything else
|
||||
pacman -Su
|
||||
```
|
||||
|
||||
Installing mpv dependencies
|
||||
---------------------------
|
||||
|
||||
```bash
|
||||
# Install MSYS2 build dependencies and a MinGW-w64 compiler
|
||||
pacman -S git pkg-config python3 mingw-w64-x86_64-gcc
|
||||
|
||||
# Install the most important MinGW-w64 dependencies. libass, libbluray and
|
||||
# lcms2 are also pulled in as dependencies of ffmpeg.
|
||||
pacman -S mingw-w64-x86_64-ffmpeg mingw-w64-x86_64-libjpeg-turbo mingw-w64-x86_64-lua
|
||||
|
||||
# Install additional (optional) dependencies
|
||||
pacman -S mingw-w64-x86_64-libdvdnav mingw-w64-x86_64-mpg123 mingw-w64-x86_64-libguess
|
||||
```
|
||||
|
||||
For a 32-bit build, install ``mingw-w64-i686-*`` packages instead.
|
||||
|
||||
Building mpv
|
||||
------------
|
||||
|
||||
Clone the latest mpv from git and install waf:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/mpv-player/mpv.git && cd mpv
|
||||
./bootstrap.py
|
||||
```
|
||||
|
||||
Finally, compile and install mpv. Binaries will be installed to
|
||||
``/mingw64/bin``.
|
||||
|
||||
```bash
|
||||
# For a 32-bit build, use --prefix=/mingw32 instead
|
||||
./waf configure CC=gcc --prefix=/mingw64
|
||||
./waf install
|
||||
```
|
||||
|
||||
Or, compile and install both libmpv and mpv:
|
||||
|
||||
```bash
|
||||
./waf configure CC=gcc --enable-libmpv-shared --prefix=/mingw64
|
||||
./waf install
|
||||
|
||||
# waf installs libmpv to the wrong directory, so fix it up
|
||||
mv -f /mingw64/bin/pkgconfig/mpv.pc /mingw64/lib/pkgconfig/
|
||||
mv -f /mingw64/bin/libmpv.dll.a /mingw64/lib/
|
||||
sed -i 's_/mingw64/bin_/mingw64/lib_' /mingw64/lib/pkgconfig/mpv.pc
|
||||
rmdir /mingw64/bin/pkgconfig
|
||||
```
|
||||
|
||||
Additional dependencies
|
||||
=======================
|
||||
|
||||
pthreads
|
||||
--------
|
||||
|
||||
mpv will use a pthreads wrapper by default. Either pthreads-win32 or
|
||||
winpthreads should work. The latter is packaged with most MinGW-w64
|
||||
environments, including MSYS2, so it shouldn't be a problem. If you don't have
|
||||
a pthreads wrapper or you want to build mpv without one, configure with:
|
||||
|
||||
```bash
|
||||
./waf configure --enable-win32-internal-pthreads
|
||||
```
|
||||
|
||||
libwaio
|
||||
-------
|
||||
|
||||
If you want to use ``--input-file``, you need libwaio. It's available from
|
||||
git://midipix.org/waio
|
||||
|
||||
To compile libwaio in MSYS2, run:
|
||||
|
||||
```bash
|
||||
git clone git://midipix.org/waio && cd waio
|
||||
|
||||
# 32-bit build, run from mingw32_shell.bat
|
||||
./build-mingw-nt32 lib-static CC=gcc AR=ar
|
||||
cp -r include/waio /mingw32/include
|
||||
cp lib32/libwaio.a /mingw32/lib
|
||||
|
||||
# 64-bit build, run from mingw64_shell.bat
|
||||
./build-mingw-nt64 lib-static CC=gcc AR=ar
|
||||
cp -r include/waio /mingw64/include
|
||||
cp lib64/libwaio.a /mingw64/lib
|
||||
```
|
||||
+2
-7
@@ -4,8 +4,8 @@ How to contribute
|
||||
General
|
||||
-------
|
||||
|
||||
The main contact for mpv development is IRC, specifically #mpv
|
||||
and #mpv-devel on Freenode.
|
||||
The main contact for mpv development is IRC, specifically #mpv-player and
|
||||
#mpv-player-dev on Freenode.
|
||||
|
||||
Sending patches
|
||||
---------------
|
||||
@@ -14,9 +14,6 @@ Sending patches
|
||||
``git format-patch``. diffs posted as pastebins (especially if the http link
|
||||
returns HTML) just cause extra work for everyone, because they lack commit
|
||||
message and authorship information.
|
||||
- When creating pull requests, be sure to test your changes. If you didn't, please
|
||||
say so in the pull request message.
|
||||
|
||||
- Write informative commit messages. Use present tense to describe the
|
||||
situation with the patch applied, and past tense for the situation before
|
||||
the change.
|
||||
@@ -121,8 +118,6 @@ mpv uses C99 with K&R formatting, with some exceptions.
|
||||
very_long_condition_b)
|
||||
{
|
||||
code();
|
||||
} else {
|
||||
...
|
||||
}
|
||||
```
|
||||
- Remove any trailing whitespace.
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
Cross Compiling to Windows
|
||||
==========================
|
||||
|
||||
Cross compiling mpv to Windows is supported with MinGW-w64. This can be used to
|
||||
produce both 32 bit and 64 bit executables. MinGW-w64 is available from
|
||||
http://mingw-w64.sourceforge.net.
|
||||
|
||||
You have to run mpv's configure with these arguments:
|
||||
|
||||
```bash
|
||||
DEST_OS=win32 TARGET=i686-w64-mingw32 ./waf configure
|
||||
```
|
||||
|
||||
While building a complete MinGW-w64 toolchain yourself is possible, people have
|
||||
created scripts to help ease the process. These are the two recommended methods:
|
||||
|
||||
- Using [mingw-w64-cmake](https://github.com/lachs0r/mingw-w64-cmake) to setup
|
||||
a MinGW-w64 environment. We recommend you to try this first before MXE.
|
||||
mingw-w64-cmake will also build mpv and its dependencies.
|
||||
- Alternatively, you can use MXE: http://mxe.cc. With MXE, you have to manually
|
||||
set the target to MinGW-w64 (even if you compile to 32 bit). A working example
|
||||
below.
|
||||
|
||||
**Warning**: the original MinGW (http://www.mingw.org) is unsupported.
|
||||
|
||||
Note that MinGW environments included in Linux distributions are often broken,
|
||||
outdated and useless, and usually don't use MinGW-w64.
|
||||
|
||||
Additional dependencies
|
||||
-----------------------
|
||||
|
||||
You need a pthread wrapper. It must be interoperable with native Windows
|
||||
threads. pthreads-win32 or MinGW pthreads might work.
|
||||
|
||||
If you want ``--input-file=...`` to work, you need libwaio. It's available
|
||||
from: git://midipix.org/waio
|
||||
|
||||
Example with MXE
|
||||
----------------
|
||||
|
||||
```bash
|
||||
# Download MXE. Note that compiling the required packages requires about 1.4 GB
|
||||
# or more!
|
||||
|
||||
cd /opt
|
||||
git clone https://github.com/mxe/mxe mingw
|
||||
cd mingw
|
||||
|
||||
# Set build options.
|
||||
|
||||
# The JOBS environment variable controls threads to use when building. DO NOT
|
||||
# use the regular `make -j4` option with MXE as it will slow down the build.
|
||||
# Alternatively, you can set this in the make command by appending "JOBS=4"
|
||||
# to the end of command:
|
||||
echo "JOBS := 4" >> settings.mk
|
||||
|
||||
# The MXE_TARGET environment variable builds MinGW-w64 for 32 bit targets.
|
||||
# Alternatively, you can specify this in the make command by appending
|
||||
# "MXE_TARGETS=i686-w64-mingw32" to the end of command:
|
||||
echo "MXE_TARGETS := i686-w64-mingw32" >> settings.mk
|
||||
|
||||
# If you want to build 64 bit version, use this:
|
||||
# echo "MXE_TARGETS := x86_64-w64-mingw32" >> settings.mk
|
||||
|
||||
# Build required packages. The following provide a minimum required to build
|
||||
# mpv.
|
||||
|
||||
make gcc ffmpeg libass jpeg pthreads
|
||||
|
||||
# Add MXE binaries to $PATH
|
||||
export PATH=/opt/mingw/usr/bin/:$PATH
|
||||
|
||||
# Build mpv. The target will be used to automatically select the name of the
|
||||
# build tools involved (e.g. it will use i686-w64-mingw32-gcc).
|
||||
|
||||
cd ..
|
||||
git clone https://github.com/mpv-player/mpv.git
|
||||
cd mpv
|
||||
DEST_OS=win32 TARGET=i686-w64-mingw32 ./waf configure
|
||||
# Or, if 64 bit version,
|
||||
# DEST_OS=win32 TARGET=x86_64-w64-mingw32 ./waf configure
|
||||
./waf build
|
||||
```
|
||||
+21
-37
@@ -63,7 +63,7 @@ Available filters are:
|
||||
Set AVOptions on the SwrContext or AVAudioResampleContext. These should
|
||||
be documented by FFmpeg or Libav.
|
||||
|
||||
``lavcac3enc[=tospdif[:bitrate[:minch]]]``
|
||||
``lavcac3enc[=tospdif[:bitrate[:minchn]]]``
|
||||
Encode multi-channel audio to AC-3 at runtime using libavcodec. Supports
|
||||
16-bit native-endian input format, maximum 6 channels. The output is
|
||||
big-endian when outputting a raw AC-3 stream, native-endian when
|
||||
@@ -92,8 +92,8 @@ Available filters are:
|
||||
:5ch: 448
|
||||
:6ch: 448
|
||||
|
||||
``minch=<n>``
|
||||
If the input channel number is less than ``<minch>``, the filter will
|
||||
``minchn=<n>``
|
||||
If the input channel number is less than ``<minchn>``, the filter will
|
||||
detach itself (default: 3).
|
||||
|
||||
``sweep[=speed]``
|
||||
@@ -225,21 +225,14 @@ Available filters are:
|
||||
automatically up- and downmix standard channel layouts.
|
||||
|
||||
``format=format:srate:channels:out-format:out-srate:out-channels``
|
||||
Does not do any format conversion itself. Rather, it may cause the
|
||||
filter system to insert necessary conversion filters before or after this
|
||||
filter if needed. It is primarily useful for controlling the audio format
|
||||
going into other filters. To specify the format for audio output, see
|
||||
``--audio-format``, ``--audio-samplerate``, and ``--audio-channels``. This
|
||||
filter is able to force a particular format, whereas ``--audio-*``
|
||||
may be overridden by the ao based on output compatibility.
|
||||
Force a specific audio format/configuration without actually changing the
|
||||
audio data. Keep in mind that the filter system might auto-insert actual
|
||||
conversion filters before or after this filter if needed.
|
||||
|
||||
All parameters are optional. The first 3 parameters restrict what the filter
|
||||
accepts as input. They will therefore cause conversion filters to be
|
||||
inserted before this one. The ``out-`` parameters tell the filters or audio
|
||||
outputs following this filter how to interpret the data without actually
|
||||
doing a conversion. Setting these will probably just break things unless you
|
||||
really know you want this for some reason, such as testing or dealing with
|
||||
broken media.
|
||||
accepts as input. The ``out-`` parameters change the audio format, without
|
||||
actually doing a conversion. The data will be 'reinterpreted' by the
|
||||
filters or audio outputs following this filter.
|
||||
|
||||
``<format>``
|
||||
Force conversion to this format. Use ``--af=format=format=help`` to get
|
||||
@@ -259,9 +252,14 @@ Available filters are:
|
||||
|
||||
``<out-channels>``
|
||||
|
||||
*NOTE*: this filter used to be named ``force``. The old ``format`` filter
|
||||
used to do conversion itself, unlike this one which lets the filter system
|
||||
handle the conversion.
|
||||
See also ``--audio-format``, ``--audio-samplerate``, and
|
||||
``--audio-channels`` for related options. Keep in mind that
|
||||
``--audio-channels`` does not actually force the number of
|
||||
channels in most cases, while this filter can do this.
|
||||
|
||||
*NOTE*: this filter used to be named ``force``. Also, unlike the old
|
||||
``format`` filter, this does not do any actual conversion anymore.
|
||||
Conversion is done by other, automatically inserted filters.
|
||||
|
||||
``convert24``
|
||||
Filter for internal use only. Converts between 24-bit and 32-bit sample
|
||||
@@ -567,10 +565,9 @@ Available filters are:
|
||||
Scale tempo in sync with speed (default).
|
||||
pitch
|
||||
Reverses effect of filter. Scales pitch without altering tempo.
|
||||
Add this to your ``input.conf`` to step by musical semi-tones::
|
||||
|
||||
[ multiply speed 0.9438743126816935
|
||||
] multiply speed 1.059463094352953
|
||||
Add ``[ speed_mult 0.9438743126816935`` and ``] speed_mult
|
||||
1.059463094352953`` to your ``input.conf`` to step by musical
|
||||
semi-tones.
|
||||
|
||||
.. warning::
|
||||
|
||||
@@ -603,20 +600,6 @@ Available filters are:
|
||||
Changing playback speed would change pitch, leaving audio tempo at
|
||||
1.2x.
|
||||
|
||||
``rubberband``
|
||||
High quality pitch correction with librubberband. This can be used in place
|
||||
of ``scaletempo``, and will be used to adjust audio pitch when playing
|
||||
at speed different from normal.
|
||||
|
||||
This filter has a number of sub-options. You can list them with
|
||||
``mpv --af=rubberband=help``. This will also show the default values
|
||||
for each option. The options are not documented here, because they are
|
||||
merely passed to librubberband. Look at the librubberband documentation
|
||||
to learn what each option does:
|
||||
http://breakfastquay.com/rubberband/code-doc/classRubberBand_1_1RubberBandStretcher.html
|
||||
(The mapping of the mpv rubberband filter sub-option names and values to
|
||||
those of librubberband follows a simple pattern: ``"Option" + Name + Value``.)
|
||||
|
||||
``lavfi=graph``
|
||||
Filter audio using FFmpeg's libavfilter.
|
||||
|
||||
@@ -631,3 +614,4 @@ Available filters are:
|
||||
|
||||
``o=<string>``
|
||||
AVOptions.
|
||||
|
||||
+31
-72
@@ -28,8 +28,8 @@ normal driver parameters.
|
||||
.. admonition:: Examples
|
||||
|
||||
- ``--ao=alsa,oss,`` Try the ALSA driver, then the OSS driver, then others.
|
||||
- ``--ao=alsa:resample=yes:device=[plughw:0,3]`` Lets ALSA resample and
|
||||
sets the device-name as first card, fourth device.
|
||||
- ``--ao=alsa:no-block:device=[hw:0,3]`` Sets noblock-mode and the
|
||||
device-name as first card, fourth device.
|
||||
|
||||
Available audio output drivers are:
|
||||
|
||||
@@ -39,6 +39,8 @@ Available audio output drivers are:
|
||||
``device=<device>``
|
||||
Sets the device name. For ac3 output via S/PDIF, use an "iec958" or
|
||||
"spdif" device, unless you really know how to set it correctly.
|
||||
``no-block``
|
||||
Sets noblock-mode.
|
||||
``resample=yes``
|
||||
Enable ALSA resampling plugin. (This is disabled by default, because
|
||||
some drivers report incorrect audio delay in some cases.)
|
||||
@@ -55,14 +57,6 @@ Available audio output drivers are:
|
||||
Allow output of non-interleaved formats (if the audio decoder uses
|
||||
this format). Currently disabled by default, because some popular
|
||||
ALSA plugins are utterly broken with non-interleaved formats.
|
||||
``ingore-chmap``
|
||||
Don't read or set the channel map of the ALSA device - only request the
|
||||
required number of channels, and then pass the audio as-is to it. This
|
||||
option most likely should not be used. It can be useful for debugging,
|
||||
or for static setups with a specially engineered ALSA configuration (in
|
||||
this case you should always force the same layout with ``--audio-channels``,
|
||||
or it will work only for files which use the layout implicit to your
|
||||
ALSA device).
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -76,42 +70,6 @@ Available audio output drivers are:
|
||||
shells (like zsh), you have to quote the option string to prevent the
|
||||
shell from interpreting the brackets instead of passing them to mpv.
|
||||
|
||||
Actually, you should use the ``--audio-device`` option, instead of
|
||||
setting the device directly.
|
||||
|
||||
.. warning::
|
||||
|
||||
Handling of multichannel/surround audio changed in mpv 0.8.0 from the
|
||||
behavior in MPlayer/mplayer2 and older versions of mpv.
|
||||
|
||||
The old behavior is that the player always downmixed to stereo by
|
||||
default. The ``--audio-channels`` (or ``--channels`` before that) option
|
||||
had to be set to get multichannel audio. Then playing stereo would
|
||||
use the ``default`` device (which typically allows multiple programs
|
||||
to play audio at the same time via dmix), while playing anything with
|
||||
more channels would open one of the hardware devices, e.g. via the
|
||||
``surround51`` alias (typically with exclusive access). Whether the
|
||||
player would use exclusive access or not would depend on the file
|
||||
being played.
|
||||
|
||||
The new behavior since mpv 0.8.0 always enables multichannel audio,
|
||||
i.e. ``--audio-channels=auto`` is the default. However, since ALSA
|
||||
provides no good way to play multichannel audio in a non-exclusive
|
||||
way (without blocking other applications from using audio), the player
|
||||
is restricted to the capabilities of the ``default`` device by default,
|
||||
which means it supports only stereo and mono (at least with current
|
||||
typical ALSA configurations). But if a hardware device is selected,
|
||||
then multichannel audio will typically work.
|
||||
|
||||
The short story is: if you want multichannel audio with ALSA, use
|
||||
``--audio-device`` to select the device (use ``--audio-device=help``
|
||||
to get a list of all devices and their mpv name).
|
||||
|
||||
You can also try `using the upmix plugin <http://git.io/vfuAy>`_.
|
||||
This setup enables multichannel audio on the ``default`` device
|
||||
with automatic upmixing with shared access, so playing stereo
|
||||
and multichannel audio at the same time will work as expected.
|
||||
|
||||
``oss``
|
||||
OSS audio output driver
|
||||
|
||||
@@ -189,15 +147,23 @@ Available audio output drivers are:
|
||||
changes. Default: 250.
|
||||
|
||||
``latency-hacks=<yes|no>``
|
||||
Enable hacks to workaround PulseAudio timing bugs (default: no). If
|
||||
Enable hacks to workaround PulseAudio timing bugs (default: yes). If
|
||||
enabled, mpv will do elaborate latency calculations on its own. If
|
||||
disabled, it will use PulseAudio automatically updated timing
|
||||
information. Disabling this might help with e.g. networked audio or
|
||||
some plugins, while enabling it might help in some unknown situations
|
||||
(it used to be required to get good behavior on old PulseAudio versions).
|
||||
information. Disabling this might help with e.g. networked audio.
|
||||
|
||||
If you have stuttering video when using pulse, try to enable this
|
||||
option. (Or alternatively, try to update PulseAudio.)
|
||||
``portaudio``
|
||||
PortAudio audio output driver. This works on all platforms, and has
|
||||
extensive MS Windows support.
|
||||
|
||||
.. note:: This driver is not very useful. It was added in the hope of
|
||||
providing portable audio API across all platforms, but turned
|
||||
out semi-broken and underfeatured.
|
||||
|
||||
``device``
|
||||
Specify the subdevice to use. Giving ``help`` as device name lists all
|
||||
devices found by PortAudio. Devices can be given as numeric values,
|
||||
starting from ``1``.
|
||||
|
||||
``dsound`` (Windows only)
|
||||
DirectX DirectSound audio output driver
|
||||
@@ -257,9 +223,6 @@ Available audio output drivers are:
|
||||
Simulate broken audio drivers, which always add the fixed device
|
||||
latency to the reported audio playback position.
|
||||
|
||||
``broken-delay``
|
||||
Simulate broken audio drivers, which don't report latency correctly.
|
||||
|
||||
``pcm``
|
||||
Raw PCM/WAVE file writer audio output
|
||||
|
||||
@@ -270,10 +233,6 @@ Available audio output drivers are:
|
||||
Write the sound to ``<filename>`` instead of the default
|
||||
``audiodump.wav``. If ``no-waveheader`` is specified, the default is
|
||||
``audiodump.pcm``.
|
||||
``(no-)append``
|
||||
Append to the file, instead of overwriting it. Always use this with the
|
||||
``no-waveheader`` option - with ``waveheader`` it's broken, because
|
||||
it will write a WAVE header every time the file is opened.
|
||||
|
||||
``rsound``
|
||||
Audio output to an RSound daemon
|
||||
@@ -304,19 +263,19 @@ Available audio output drivers are:
|
||||
``wasapi``
|
||||
Audio output to the Windows Audio Session API.
|
||||
|
||||
``device=<id>``
|
||||
Uses the requested endpoint instead of the system's default audio
|
||||
endpoint. Both the number and the ID String are valid; the ID String
|
||||
is guaranteed to not change unless the driver is uninstalled.
|
||||
|
||||
Also supports searching active devices by name. If more than one
|
||||
device matches the name, refuses loading it.
|
||||
|
||||
To get a list of the valid devices, give ``help`` as the id. The
|
||||
list is the same as the ``list`` suboption, but stops the player
|
||||
initialization.
|
||||
``exclusive``
|
||||
Requests exclusive, direct hardware access. By definition prevents
|
||||
sound playback of any other program until mpv exits.
|
||||
``device=<id>``
|
||||
Uses the requested endpoint instead of the system's default audio
|
||||
endpoint. Both an ordinal number (0,1,2,...) and the GUID
|
||||
String are valid; the GUID string is guaranteed to not change
|
||||
unless the driver is uninstalled.
|
||||
|
||||
Also supports searching active devices by human readable name. If more
|
||||
than one device matches the name, refuses loading it.
|
||||
|
||||
This option is mostly deprecated in favour of the more general
|
||||
``--audio-device`` option. That said, ``--audio-device=help`` will give
|
||||
a list of valid device GUIDs (prefixed with ``wasapi/``), as well as
|
||||
their human readable names, which should work here.
|
||||
``list``
|
||||
Lists all audio endpoints (output devices) present in the system.
|
||||
+435
-10
@@ -1,13 +1,438 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
CHANGES FROM OTHER VERSIONS OF MPLAYER
|
||||
======================================
|
||||
|
||||
There is no real changelog, but you can look at the following things:
|
||||
**mpv** is based on mplayer2, which in turn is based on the original MPlayer
|
||||
(also called mplayer, mplayer-svn, mplayer1). Many changes have been made, a
|
||||
large part of which is incompatible or completely changes how the player
|
||||
behaves. Although there are still many similarities to its ancestors, **mpv**
|
||||
should generally be treated as a completely different program.
|
||||
|
||||
* The release changelog, which should contain most user-visible changes,
|
||||
including new features and bug fixes:
|
||||
.. note::
|
||||
These lists are incomplete.
|
||||
|
||||
https://github.com/mpv-player/mpv/releases
|
||||
* The git log, which is the "real" changelog
|
||||
* The file ``mplayer-changes.rst`` in the ``DOCS`` sub directory on the git
|
||||
repository, which used to be in place of this section. It documents some
|
||||
changes that happened since mplayer2 forked off MPlayer.
|
||||
General Changes from MPlayer to mpv
|
||||
-----------------------------------
|
||||
|
||||
This listing is about changes introduced by mplayer2 and mpv relatively to
|
||||
MPlayer.
|
||||
|
||||
Player
|
||||
~~~~~~
|
||||
|
||||
* New name for the binary (``mpv``). New location for config files (either
|
||||
``~/.config/mpv/mpv.conf``, or if you want, ``~/.mpv/config``).
|
||||
* Encoding functionality (replacement for MEncoder, see the `ENCODING`_ section).
|
||||
* Support for Lua scripting (see the `LUA SCRIPTING`_ section).
|
||||
* Better pause handling (e.g. do not unpause on a command).
|
||||
* Precise seeking support.
|
||||
* Improvements in audio/video sync handling.
|
||||
* Do not lose settings when playing a new file in the same player instance.
|
||||
* Slave mode compatibility broken (see below).
|
||||
* Re-enable screensaver while the player is paused.
|
||||
* Allow resuming playback at a later point with ``Shift+q``, also see the
|
||||
``quit_watch_later`` input command.
|
||||
* ``--keep-open`` option to stop the player from closing the window and
|
||||
exiting after playback ends.
|
||||
* A client API, that allows embedding **mpv** into applications
|
||||
(see ``libmpv/client.h`` in the sources).
|
||||
|
||||
Input
|
||||
~~~~~
|
||||
|
||||
* Improved default keybindings. MPlayer bindings are also available (see
|
||||
``etc/mplayer-input.conf`` in the source tree).
|
||||
* Improved responsiveness on user input.
|
||||
* Support for modifier keys (alt, shift, ctrl) in input.conf.
|
||||
* Allow customizing whether a key binding for seeking shows the video time, the
|
||||
OSD bar, or nothing (see the `Input Command Prefixes`_ section).
|
||||
* Support mapping multiple commands to one key.
|
||||
|
||||
Audio
|
||||
~~~~~
|
||||
|
||||
* Support for gapless audio (see the ``--gapless-audio`` option).
|
||||
* Support for OSS4 volume control.
|
||||
* Improved support for PulseAudio.
|
||||
* Make ``--softvol`` default (**mpv** is not a mixer control panel).
|
||||
* By default, do pitch correction if playback speed is increased.
|
||||
* Improved downmixing and output of surround audio:
|
||||
|
||||
- Instead of using hardcoded pan filters to do remixing, libavresample is used
|
||||
- Channel maps are used to identify the channel layout, so e.g. ``3.0`` and
|
||||
``2.1`` audio can be distinguished.
|
||||
|
||||
Video
|
||||
~~~~~
|
||||
|
||||
* Wayland support.
|
||||
* Native support for VAAPI and VDA. Improved VDPAU video output.
|
||||
* Improved OpenGL output (see the ``opengl-hq`` video output).
|
||||
* Make hardware decoding work with the ``opengl`` video output.
|
||||
* Support for libavfilter (for video->video and audio->audio). This allows
|
||||
using most of FFmpeg's filters, which improve greatly on the old MPlayer
|
||||
filters in features, performance, and correctness.
|
||||
* More correct color reproduction (color matrix generation).
|
||||
* Better subtitle rendering using libass by default.
|
||||
* Improvements when playing multiple files (``--fixed-vo`` is default, do not
|
||||
reset settings by default when playing a new file).
|
||||
* Replace image video outputs (``--vo=jpeg`` etc.) with ``--vo=image``.
|
||||
* Removal of ``--vo=gif89a``, ``--vo=md5sum``, ``--vo=yuv4mpeg``, as encoding
|
||||
can handle these use cases. For yuv4mpeg, for example, use::
|
||||
|
||||
mpv input.mkv -o output.y4m --no-audio --oautofps --oneverdrop
|
||||
|
||||
* Image subtitles (DVDs etc.) are rendered in color and use more correct
|
||||
positioning (color for image subs can be disabled with ``--sub-gray``).
|
||||
|
||||
OSD and terminal
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
* Cleaned up terminal output: nicer status line, less useless noise.
|
||||
* Improved OSD rendering using libass, with full Unicode support.
|
||||
* New OSD bar with chapter marks. Not positioned in the middle of the video
|
||||
(this can be customized with the ``--osd-bar-align-y`` option).
|
||||
* Display list of chapters and audio/subtitle tracks on OSD (see the
|
||||
`Properties`_ section).
|
||||
|
||||
Screenshots
|
||||
~~~~~~~~~~~
|
||||
|
||||
* Instant screenshots without 1-frame delay.
|
||||
* Support for taking screenshots even with hardware decoding.
|
||||
* Support for saving screenshots as JPEG or PNG.
|
||||
* Support for configurable file names.
|
||||
* Support for taking screenshots with or without subtitles.
|
||||
|
||||
Note that the ``screenshot`` video filter is not needed anymore, and should not
|
||||
be put into the mpv config file.
|
||||
|
||||
Miscellaneous
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
* Better MKV support (e.g. ordered chapters, 3D metadata).
|
||||
* Matroska edition switching at runtime.
|
||||
* Support for playing URLs of popular streaming sites directly.
|
||||
(e.g. ``mpv https://www.youtube.com/watch?v=...``).
|
||||
Requires a recent version of ``youtube-dl`` to be installed, and
|
||||
``ytdl=yes`` in the mpv config file.
|
||||
* Support for precise scrolling which scales the parameter of commands. If the
|
||||
input doesn't support precise scrolling the scale factor stays 1.
|
||||
* Allow changing/adjusting video filters at runtime. (This is also used to make
|
||||
the ``D`` key insert vf_yadif if deinterlacing is not supported otherwise).
|
||||
* Improved support for .cue files.
|
||||
|
||||
Mac OS X
|
||||
~~~~~~~~
|
||||
|
||||
* Native OpenGL backend.
|
||||
* Cocoa event loop is independent from MPlayer's event loop, so user
|
||||
actions like accessing menus and live resizing do not block the playback.
|
||||
* Apple Remote support.
|
||||
* Media Keys support.
|
||||
* VDA support using libavcodec hwaccel API instead of FFmpeg's decoder with up
|
||||
to 2-2.5x reduction in CPU usage.
|
||||
|
||||
Windows
|
||||
~~~~~~~
|
||||
|
||||
* Improved support for Unicode file names.
|
||||
* Improved window handling.
|
||||
* Do not block playback when moving the window.
|
||||
* Improved Direct3D video output.
|
||||
* Added WASAPI audio output.
|
||||
|
||||
Internal changes
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
* Switch to GPLv2+ (see ``Copyright`` file for details).
|
||||
* Removal of lots of cruft:
|
||||
|
||||
- Internal GUI (replaced by the OSC, see the `ON SCREEN CONTROLLER`_ section).
|
||||
- MEncoder (replaced by native encoding, see the `ENCODING`_ section).
|
||||
- OSD menu.
|
||||
- Kernel video drivers for Linux 2.4 (including VIDIX).
|
||||
- Teletext support.
|
||||
- Support for dead platforms.
|
||||
- Most built-in demuxers have been replaced by their libavformat counterparts.
|
||||
- Built-in network support has been replaced by libavformat's (which also
|
||||
supports https URLs).
|
||||
- Embedded copies of libraries (such as FFmpeg).
|
||||
|
||||
* General code cleanups (including refactoring or rewrites of many parts).
|
||||
* New build system.
|
||||
* Many bug fixes and removal of long-standing issues.
|
||||
* Generally preferring FFmpeg/Libav over internal demuxers, decoders, and
|
||||
filters.
|
||||
|
||||
Detailed Listing of User-visible Changes
|
||||
----------------------------------------
|
||||
|
||||
This listing is about changed command line switches, slave commands, and similar
|
||||
things. Completely removed features are not listed.
|
||||
|
||||
Command Line Switches
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* There is a new command line syntax, which is generally preferred over the old
|
||||
syntax. ``-optname optvalue`` becomes ``--optname=optvalue``.
|
||||
|
||||
The old syntax will not be removed. However, the new syntax is mentioned in
|
||||
all documentation and so on, and unlike the old syntax is not ambiguous,
|
||||
so it is a good thing to know about this change.
|
||||
* In general, negating switches like ``-noopt`` now have to be written as
|
||||
``-no-opt`` or ``--no-opt``.
|
||||
* Per-file options are not the default anymore. You can explicitly specify
|
||||
file-local options. See ``Usage`` section.
|
||||
* Many options have been renamed, removed or changed semantics. Some options
|
||||
that are required for a good playback experience with MPlayer are now
|
||||
superfluous or even worse than the defaults, so make sure to read the manual
|
||||
before trying to use your existing configuration with **mpv**.
|
||||
* Table of renamed/replaced switches:
|
||||
|
||||
=========================== ========================================
|
||||
Old New
|
||||
=========================== ========================================
|
||||
``-no<opt>`` ``--no-<opt>`` (add a dash)
|
||||
``-a52drc level`` ``--ad-lavc-ac3drc=level``
|
||||
``-ac spdifac3`` ``--ad=spdif:ac3`` (see ``--ad=help``)
|
||||
``-af volnorm`` ``--af=drc`` (renamed)
|
||||
``-afm hwac3`` ``--ad=spdif:ac3,spdif:dts``
|
||||
``-ao alsa:device=hw=0.3`` ``--ao=alsa:device=[hw:0,3]``
|
||||
``-aspect`` ``--video-aspect``
|
||||
``-ass-bottom-margin`` ``--vf=sub=bottom:top``
|
||||
``-ass`` ``--sub-ass``
|
||||
``-audiofile-cache`` (removed; the main cache settings are used)
|
||||
``-audiofile`` ``--audio-file``
|
||||
``-benchmark`` ``--untimed`` (no stats)
|
||||
``-capture`` ``--stream-capture=<filename>``
|
||||
``-channels`` ``--audio-channels`` (changed semantics)
|
||||
``-cursor-autohide-delay`` ``--cursor-autohide``
|
||||
``-delay`` ``--audio-delay``
|
||||
``-dumpstream`` ``--stream-dump=<filename>``
|
||||
``-dvdangle`` ``--dvd-angle``
|
||||
``-endpos`` ``--length``
|
||||
``-font`` ``--osd-font``
|
||||
``-forcedsubsonly`` ``--sub-forced-only``
|
||||
``-forceidx`` ``--index``
|
||||
``-format`` ``--audio-format``
|
||||
``-fsmode-dontuse`` (removed)
|
||||
``-fstype`` ``--x11-netwm`` (changed semantics)
|
||||
``-hardframedrop`` ``--framedrop=hard``
|
||||
``-identify`` (removed; use TOOLS/mpv_identify.sh)
|
||||
``-idx`` ``--index``
|
||||
``-lavdopts ...`` ``--vd-lavc-...``
|
||||
``-lavfdopts`` ``--demuxer-lavf-...``
|
||||
``-lircconf`` ``--input-lirc-conf``
|
||||
``-loop 0`` ``--loop=inf``
|
||||
``-mixer-channel`` AO suboptions (``alsa``, ``oss``)
|
||||
``-mixer`` AO suboptions (``alsa``, ``oss``)
|
||||
``-mouse-movements`` ``--input-cursor``
|
||||
``-msgcolor`` ``--msg-color``
|
||||
``-msglevel`` ``--msg-level`` (changed semantics)
|
||||
``-msgmodule`` ``--msg-module``
|
||||
``-name`` ``--x11-name``
|
||||
``-noar`` ``--no-input-appleremote``
|
||||
``-noautosub`` ``--no-sub-auto``
|
||||
``-noconsolecontrols`` ``--no-input-terminal``
|
||||
``-nojoystick`` ``--no-input-joystick``
|
||||
``-nosound`` ``--no-audio``
|
||||
``-osdlevel`` ``--osd-level``
|
||||
``-panscanrange`` ``--video-zoom``, ``--video-pan-x/y``
|
||||
``-playing-msg`` ``--term-playing-msg``
|
||||
``-pp ...`` ``'--vf=pp=[...]'``
|
||||
``-pphelp`` ``--vf=pp:help``
|
||||
``-rawaudio ...`` ``--demuxer-rawaudio-...``
|
||||
``-rawvideo ...`` ``--demuxer-rawvideo-...``
|
||||
``-spugauss`` ``--sub-gauss``
|
||||
``-srate`` ``--audio-samplerate``
|
||||
``-ss`` ``--start``
|
||||
``-ssf <sub>`` ``--sws-...``
|
||||
``-stop-xscreensaver`` ``--stop-screensaver``
|
||||
``-sub-fuzziness`` ``--sub-auto``
|
||||
``-sub`` ``--sub-file``
|
||||
``-subcp`` ``--sub-codepage``
|
||||
``-subdelay`` ``--sub-delay``
|
||||
``-subfile`` ``--sub-file``
|
||||
``-subfont-*`` ``--sub-text-*``, ``--osd-*``
|
||||
``-subfont-text-scale`` ``--sub-scale``
|
||||
``-subfont`` ``--sub-text-font``
|
||||
``-subfps`` ``--sub-fps``
|
||||
``-subpos`` ``--sub-pos``
|
||||
``-sws`` ``--sws-scaler``
|
||||
``-tvscan`` ``--tv-scan``
|
||||
``-use-filename-title`` ``--title='${filename}'``
|
||||
``-vc ffh264vdpau`` (etc.) ``--hwdec=vdpau``
|
||||
``-vobsub`` ``--sub-file`` (pass the .idx file)
|
||||
``-x W``, ``-y H`` ``--geometry=WxH`` + ``--no-keepaspect``
|
||||
``-xineramascreen`` ``--screen`` (different values)
|
||||
``-xy W`` ``--autofit=W``
|
||||
``-zoom`` Inverse available as ``--video-unscaled``
|
||||
``dvdnav://`` ``dvdnav://menu``
|
||||
``dvd://1`` ``dvd://0`` (0-based offset)
|
||||
=========================== ========================================
|
||||
|
||||
.. note::
|
||||
|
||||
``-opt val`` becomes ``--opt=val``.
|
||||
|
||||
.. note::
|
||||
|
||||
Quite some video filters, video outputs, audio filters, audio outputs, had
|
||||
changes in their option parsing. These aren't mentioned in the table above.
|
||||
|
||||
Also, some video and audio filters have been removed, and you have to use
|
||||
libavfilter (using ``--vf=lavfi=[...]`` or ``--af=lavfi=[...]``) to get
|
||||
them back.
|
||||
|
||||
input.conf and Slave Commands
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Table of renamed input commands:
|
||||
|
||||
This lists only commands that are not always gracefully handled by the
|
||||
internal legacy translation layer. If an input.conf contains any legacy
|
||||
commands, a warning will be printed when starting the player. The warnings
|
||||
also show the replacement commands.
|
||||
|
||||
Properties containing ``_`` to separate words use ``-`` instead.
|
||||
|
||||
+--------------------------------+----------------------------------------+
|
||||
| Old | New |
|
||||
+================================+========================================+
|
||||
| ``pt_step 1 [0|1]`` | ``playlist_next [weak|force]`` |
|
||||
| | (translation layer cannot deal with |
|
||||
| | whitespace) |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``pt_step -1 [0|1]`` | ``playlist_prev [weak|force] (same)`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``switch_ratio [<ratio>]`` | ``set video-aspect <ratio>`` |
|
||||
| | |
|
||||
| | ``set video-aspect 0`` (reset aspect) |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``step_property_osd <prop>`` | ``cycle <prop> <step>`` (wraps), |
|
||||
| ``<step> <dir>`` | ``add <prop> <step>`` (clamps). |
|
||||
| | ``<dir>`` parameter unsupported. Use |
|
||||
| | a negative ``<step>`` instead. |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``step_property <prop>`` | Prefix ``cycle`` or ``add`` with |
|
||||
| ``<step> <dir>`` | ``no-osd``: ``no-osd cycle <prop>`` |
|
||||
| | ``<step>`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``osd_show_property_text`` | ``show_text <text>`` |
|
||||
| ``<text>`` | The property expansion format string |
|
||||
| | syntax slightly changed. |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``osd_show_text`` | Now does the same as |
|
||||
| | ``osd_show_property_text``. Use the |
|
||||
| | ``raw`` prefix to disable property |
|
||||
| | expansion. |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``show_tracks`` | ``show_text ${track-list}`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``show_chapters`` | ``show_text ${chapter-list}`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``af_switch``, ``af_add``, ... | ``af set|add|...`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_start_scan`` | ``set tv-scan yes`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_set_channel <val>`` | ``set tv-channel <val>`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_step_channel`` | ``cycle tv-channel`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``dvb_set_channel <v1> <v2>`` | ``set dvb-channel <v1>-<v2>`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``dvb_step_channel`` | ``cycle dvb-channel`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_set_freq <val>`` | ``set tv-freq <val>`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_step_freq`` | ``cycle tv-freq`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_set_norm <norm>`` | ``set tv-norm <norm>`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_step_norm`` | ``cycle tv-norm`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
|
||||
.. note::
|
||||
|
||||
Due to lack of hardware and users using the TV/DVB/PVR features, and
|
||||
due to the need to cleanup the related command code, it's possible
|
||||
that the new commands are buggy or behave worse. This can be improved
|
||||
if testers are available. Otherwise, some of the TV code will be
|
||||
removed at some point.
|
||||
|
||||
Slave mode
|
||||
~~~~~~~~~~
|
||||
|
||||
* Slave mode was removed. A proper slave mode application needed tons of code
|
||||
and hacks to get
|
||||
it right. The main problem is that slave mode is a bad and incomplete
|
||||
interface, and to get around that, applications parsed output messages
|
||||
intended for users. It is hard to know which messages exactly are parsed by
|
||||
slave mode applications. This makes it virtually impossible to improve
|
||||
terminal output intended for users without possibly breaking something.
|
||||
|
||||
This is absolutely insane, and since initial improvements to **mpv** quickly
|
||||
made slave mode incompatible to most applications, it was removed as useless
|
||||
cruft. The client API (see below) is provided instead.
|
||||
|
||||
``--identify`` was replaced by the ``TOOLS/mpv_identify.sh`` wrapper script.
|
||||
|
||||
* For some time (until including release 0.4.x), mpv supported a
|
||||
``--slave-broken`` option. The following options are equivalent:
|
||||
|
||||
::
|
||||
|
||||
--input-file=/dev/stdin --input-terminal=no
|
||||
|
||||
|
||||
Assuming the system supports ``/dev/stdin``.
|
||||
|
||||
(The option was readded in 0.5.1 and sets exactly these options.)
|
||||
|
||||
* A JSON RPC protocol giving access to the client API is also supported. See
|
||||
`JSON IPC`_ for more information.
|
||||
|
||||
* **mpv** also provides a client API, which can be used to embed the player
|
||||
by loading it as shared library. (See ``libmpv/client.h`` in the sources.)
|
||||
It might also be possible to implement a custom slave mode-like protocol
|
||||
using Lua scripting.
|
||||
|
||||
Policy for Removed Features
|
||||
---------------------------
|
||||
|
||||
**mpv** is in active development. If something is in the way of more important
|
||||
development (such as fixing bugs or implementing new features), we sometimes
|
||||
remove features. Usually this happens only with old features that either seem
|
||||
to be useless, or are not used by anyone. Often these are obscure, or
|
||||
"inherited", or were marked experimental, but never received any particular
|
||||
praise by any users.
|
||||
|
||||
Sometimes, features are replaced by something new. The new code will be either
|
||||
simpler or more powerful, but doesn't necessarily provide everything the old
|
||||
feature did.
|
||||
|
||||
We can not exclude that we accidentally remove features that are actually
|
||||
popular. Generally, we do not know how much a specific functionality is used.
|
||||
If you miss a feature and think it should be re-added, please open an issue
|
||||
on the mpv bug tracker. Hopefully, a solution can be found. Often, it turns
|
||||
out that re-adding something is not much of a problem, or that there are
|
||||
better alternatives.
|
||||
|
||||
Why this Fork?
|
||||
--------------
|
||||
|
||||
mplayer2 is practically dead, and mpv started out as a branch containing
|
||||
new/experimental development. (Some of it was merged right *after* the fork
|
||||
was made public, seemingly as an acknowledgment that development, or at
|
||||
least merging, should have been more active.)
|
||||
|
||||
MPlayer is focused on not breaking anything, but is stuck with a horrible
|
||||
codebase resistant to cleanup. (Unless you do what mpv did - merciless and
|
||||
consequent pruning of bad, old code.) Cleanup and keeping broken things
|
||||
conflict, so the kind of development mpv strives for can't be done within
|
||||
MPlayer due to clashing development policies.
|
||||
|
||||
Additionally, mplayer2 already had lots of changes over MPlayer, which would
|
||||
have needed to be backported to the MPlayer codebase. This would not only
|
||||
have been hard (several years of diverging development), but also would have
|
||||
been impossible due to the aforementioned MPlayer development policy.
|
||||
+56
-331
@@ -1,13 +1,5 @@
|
||||
COMMAND INTERFACE
|
||||
=================
|
||||
|
||||
The mpv core can be controlled with commands and properties. A number of ways
|
||||
to interact with the player use them: key bindings (``input.conf``), OSD
|
||||
(showing information with properties), JSON IPC, the client API (``libmpv``),
|
||||
and the classic slave mode.
|
||||
|
||||
input.conf
|
||||
----------
|
||||
INPUT.CONF
|
||||
==========
|
||||
|
||||
The input.conf file consists of a list of key bindings, for example::
|
||||
|
||||
@@ -86,11 +78,11 @@ List of Input Commands
|
||||
disabling default bindings, without disabling all bindings with
|
||||
``--no-input-default-bindings``.
|
||||
|
||||
``seek <seconds> [relative|absolute|absolute-percent|exact|keyframes]``
|
||||
``seek <seconds> [relative|absolute|absolute-percent|- [default-precise|exact|keyframes]]``
|
||||
Change the playback position. By default, seeks by a relative amount of
|
||||
seconds.
|
||||
|
||||
The second argument consists of flags controlling the seek mode:
|
||||
The second argument sets the seek mode:
|
||||
|
||||
relative (default)
|
||||
Seek relative to current position (a negative value seeks backwards).
|
||||
@@ -98,34 +90,22 @@ List of Input Commands
|
||||
Seek to a given time.
|
||||
absolute-percent
|
||||
Seek to a given percent position.
|
||||
keyframes
|
||||
Always restart playback at keyframe boundaries (fast).
|
||||
|
||||
The third argument defines how exact the seek is:
|
||||
|
||||
default-precise (default)
|
||||
Follow the default behavior as set by ``--hr-seek``, which by default
|
||||
does imprecise seeks (like ``keyframes``).
|
||||
exact
|
||||
Always do exact/hr/precise seeks (slow).
|
||||
keyframes
|
||||
Always restart playback at keyframe boundaries (fast).
|
||||
|
||||
Multiple flags can be combined, e.g.: ``absolute+keyframes``.
|
||||
|
||||
By default, ``keyframes`` is used for relative seeks, and ``exact`` is used
|
||||
for absolute seeks.
|
||||
|
||||
Before mpv 0.9, the ``keyframes`` and ``exact`` flags had to be passed as
|
||||
3rd parameter (essentially using a space instead of ``+``). The 3rd
|
||||
parameter is still parsed, but is considered deprecated.
|
||||
|
||||
``revert_seek [mode]``
|
||||
``revert_seek``
|
||||
Undoes the ``seek`` command, and some other commands that seek (but not
|
||||
necessarily all of them). Calling this command once will jump to the
|
||||
playback position before the seek. Calling it a second time undoes the
|
||||
``revert_seek`` command itself. This only works within a single file.
|
||||
|
||||
The first argument is optional, and can change the behavior:
|
||||
|
||||
mark
|
||||
Mark the current time position. The next normal ``revert_seek`` command
|
||||
will seek back to this point, no matter how many seeks happened since
|
||||
last time.
|
||||
|
||||
Using it without any arguments gives you the default behavior.
|
||||
``revert_seek`` command itself.
|
||||
|
||||
``frame_step``
|
||||
Play one frame, then pause. Does nothing with audio-only playback.
|
||||
@@ -173,12 +153,16 @@ List of Input Commands
|
||||
Save the contents of the mpv window. Typically scaled, with OSD and
|
||||
subtitles. The exact behavior depends on the selected video output, and
|
||||
if no support is available, this will act like ``video``.
|
||||
|
||||
Second argument:
|
||||
|
||||
<single> (default)
|
||||
Take a single screenshot.
|
||||
<each-frame>
|
||||
Take a screenshot each frame. Issue this command again to stop taking
|
||||
screenshots. Note that you should disable frame-dropping when using
|
||||
this mode - or you might receive duplicate images in cases when a
|
||||
frame was dropped. This flag can be combined with the other flags,
|
||||
e.g. ``video+each-frame``.
|
||||
frame was dropped.
|
||||
|
||||
``screenshot_to_file "<filename>" [subtitles|video|window]``
|
||||
Take a screenshot and save it to a given file. The format of the file will
|
||||
@@ -187,7 +171,8 @@ List of Input Commands
|
||||
|
||||
The second argument is like the first argument to ``screenshot``.
|
||||
|
||||
If the file already exists, it's overwritten.
|
||||
This command tries to never overwrite files. If the file already exists,
|
||||
it fails.
|
||||
|
||||
Like all input command parameters, the filename is subject to property
|
||||
expansion as described in `Property Expansion`_.
|
||||
@@ -247,6 +232,7 @@ List of Input Commands
|
||||
will have after moving.)
|
||||
|
||||
``run "command" "arg1" "arg2" ...``
|
||||
(Unix only)
|
||||
Run the given command. Unlike in MPlayer/mplayer2 and earlier versions of
|
||||
mpv (0.2.x and older), this doesn't call the shell. Instead, the command
|
||||
is run directly, with each argument passed separately. Each argument is
|
||||
@@ -372,47 +358,6 @@ List of Input Commands
|
||||
essentially like ``quit``. Useful for the client API: playback can be
|
||||
stopped without terminating the player.
|
||||
|
||||
``mouse <x> <y> [<button> [single|double]]``
|
||||
Send a mouse event with given coordinate (``<x>``, ``<y>``).
|
||||
|
||||
Second argument:
|
||||
|
||||
<button>
|
||||
The button number of clicked mouse button. This should be one of 0-19.
|
||||
If ``<button>`` is omitted, only the position will be updated.
|
||||
|
||||
Third argument:
|
||||
|
||||
<single> (default)
|
||||
The mouse event represents regular single click.
|
||||
|
||||
<double>
|
||||
The mouse event represents double-click.
|
||||
|
||||
``audio_add "<file>" [<flags> [<title> [<lang>]]]``
|
||||
Load the given audio file. See ``sub_add`` command.
|
||||
|
||||
``audio_remove [<id>]``
|
||||
Remove the given audio track. See ``sub_remove`` command.
|
||||
|
||||
``audio_reload [<id>]``
|
||||
Reload the given audio tracks. See ``sub_reload`` command.
|
||||
|
||||
``rescan_external_files [<mode>]``
|
||||
Rescan external files according to the current ``--sub-auto`` and
|
||||
``--audio-file-auto`` settings. This can be used to auto-load external
|
||||
files *after* the file was loaded.
|
||||
|
||||
The ``mode`` argument is one of the following:
|
||||
|
||||
<keep-selection> (default)
|
||||
Do not change current track selections.
|
||||
|
||||
<reselect>
|
||||
Select the default audio and video streams, which typically selects
|
||||
external files with highest preference. (The implementation is not
|
||||
perfect, and could be improved on request.)
|
||||
|
||||
|
||||
Input Commands that are Possibly Subject to Change
|
||||
--------------------------------------------------
|
||||
@@ -539,15 +484,18 @@ Input Commands that are Possibly Subject to Change
|
||||
|
||||
It is also possible to pass a raw memory address for use as bitmap memory
|
||||
by passing a memory address as integer prefixed with a ``&`` character.
|
||||
Passing the wrong thing here will crash the player. This mode might be
|
||||
useful for use with libmpv. The ``offset`` parameter is simply added to the
|
||||
memory address (since mpv 0.8.0, ignored before).
|
||||
Passing the wrong thing here will crash the player. The ``offset`` parameter
|
||||
is not used and must be 0. This mode might be useful for use with libmpv.
|
||||
|
||||
``offset`` is the byte offset of the first pixel in the source file.
|
||||
(The current implementation always mmap's the whole file from position 0 to
|
||||
the end of the image, so large offsets should be avoided. Before mpv 0.8.0,
|
||||
the offset was actually passed directly to ``mmap``, but it was changed to
|
||||
make using it easier.)
|
||||
On Windows, currently only raw memory addresses work. File mapping is not
|
||||
implemented because a ``mmap`` compatibility layer is missing, and because
|
||||
this kind of shared memory method would perhaps not be overly useful on
|
||||
Windows.
|
||||
|
||||
``offset`` is the offset of the first pixel in the source file. It is
|
||||
passed directly to ``mmap`` and is subject to certain restrictions
|
||||
(see ``man mmap`` for details). In particular, this value has to be a
|
||||
multiple of the system's page size.
|
||||
|
||||
``fmt`` is a string identifying the image format. Currently, only ``bgra``
|
||||
is defined. This format has 4 bytes per pixels, with 8 bits per component.
|
||||
@@ -631,77 +579,8 @@ Input Commands that are Possibly Subject to Change
|
||||
unseekable streams that are going out of sync.
|
||||
This command might be changed or removed in the future.
|
||||
|
||||
``screenshot_raw [subtitles|video|window]``
|
||||
Return a screenshot in memory. This can be used only through the client
|
||||
API. The MPV_FORMAT_NODE_MAP returned by this command has the ``w``, ``h``,
|
||||
``stride`` fields set to obvious contents. A ``format`` field is set to
|
||||
``bgr0`` by default. This format is organized as ``B8G8R8X8`` (where ``B``
|
||||
is the LSB). The contents of the padding ``X`` is undefined. The ``data``
|
||||
field is of type MPV_FORMAT_BYTE_ARRAY with the actual image data. The image
|
||||
is freed as soon as the result node is freed.
|
||||
|
||||
Undocumented commands: ``tv_last_channel`` (TV/DVB only),
|
||||
``get_property`` (deprecated), ``ao_reload`` (experimental/internal).
|
||||
|
||||
Hooks
|
||||
~~~~~
|
||||
|
||||
Hooks are synchronous events between player core and a script or similar. This
|
||||
applies to the Lua scripting interface and the client API and only. Normally,
|
||||
events are supposed to be asynchronous, and the hook API provides an awkward
|
||||
and obscure way to handle events that require stricter coordination. There are
|
||||
no API stability guarantees made. Not following the protocol exactly can make
|
||||
the player freeze randomly. Basically, nobody should use this API.
|
||||
|
||||
There are two special commands involved. Also, the client must listen for
|
||||
client messages (``MPV_EVENT_CLIENT_MESSAGE`` in the C API).
|
||||
|
||||
``hook_add <hook-name> <id> <priority>``
|
||||
Subscribe to the hook identified by the first argument (basically, the
|
||||
name of event). The ``id`` argument is an arbitrary integer chosen by the
|
||||
user. ``priority`` is used to sort all hook handlers globally across all
|
||||
clients. Each client can register multiple hook handlers (even for the
|
||||
same hook-name). Once the hook is registered, it cannot be unregistered.
|
||||
|
||||
When a specific event happens, all registered handlers are run serially.
|
||||
This uses a protocol every client has to follow explicitly. When a hook
|
||||
handler is run, a client message (``MPV_EVENT_CLIENT_MESSAGE``) is sent to
|
||||
the client which registered the hook. This message has the following
|
||||
arguments:
|
||||
|
||||
1. the string ``hook_run``
|
||||
2. the ``id`` argument the hook was registered with as string (this can be
|
||||
used to correctly handle multiple hooks registered by the same client,
|
||||
as long as the ``id`` argument is unique in the client)
|
||||
3. something undefined, used by the hook mechanism to track hook execution
|
||||
(currently, it's the hook-name, but this might change without warning)
|
||||
|
||||
Upon receiving this message, the client can handle the event. While doing
|
||||
this, the player core will still react to requests, but playback will
|
||||
typically be stopped.
|
||||
|
||||
When the client is done, it must continue the core's hook execution by
|
||||
running the ``hook_ack`` command.
|
||||
|
||||
``hook_ack <string>``
|
||||
Run the next hook in the global chain of hooks. The argument is the 3rd
|
||||
argument of the client message that starts hook execution for the
|
||||
current client.
|
||||
|
||||
The following hooks are currently defined:
|
||||
|
||||
``on_load``
|
||||
Called when a file is to be opened, before anything is actually done.
|
||||
For example, you could read and write the ``stream-open-filename``
|
||||
property to redirect an URL to something else (consider support for
|
||||
streaming sites which rarely give the user a direct media URL), or
|
||||
you could set per-file options with by setting the property
|
||||
``file-local-options/<option name>``. The player will wait until all
|
||||
hooks are run.
|
||||
|
||||
``on_unload``
|
||||
Run before closing a file, and before actually uninitializing
|
||||
everything. It's not possible to resume playback in this state.
|
||||
Undocumented commands: ``tv_last_channel`` (TV/DVB only), ``get_property`` (?),
|
||||
``ao_reload`` (experimental/internal).
|
||||
|
||||
Input Command Prefixes
|
||||
----------------------
|
||||
@@ -817,11 +696,6 @@ Property list
|
||||
|
||||
Otherwise, return the ``filename`` property.
|
||||
|
||||
``file-format``
|
||||
Symbolic name of the file format. In some cases, this is a comma-separated
|
||||
list of format names, e.g. mp4 is ``mov,mp4,m4a,3gp,3g2,mj2`` (the list
|
||||
may grow in the future for any format).
|
||||
|
||||
``demuxer``
|
||||
Name of the current demuxer. (This is useless.)
|
||||
|
||||
@@ -891,33 +765,6 @@ Property list
|
||||
``disc-titles``
|
||||
Number of BD/DVD titles.
|
||||
|
||||
This has a number of sub-properties. Replace ``N`` with the 0-based edition
|
||||
index.
|
||||
|
||||
``disc-titles/count``
|
||||
Number of titles.
|
||||
|
||||
``disc-titles/id``
|
||||
Title ID as integer. Currently, this is the same as the title index.
|
||||
|
||||
``disc-titles/length``
|
||||
Length in seconds. Can be unavailable in a number of cases (currently
|
||||
it works for libdvdnav only).
|
||||
|
||||
When querying the property with the client API using ``MPV_FORMAT_NODE``,
|
||||
or with Lua ``mp.get_property_native``, this will return a mpv_node with
|
||||
the following contents:
|
||||
|
||||
::
|
||||
|
||||
MPV_FORMAT_NODE_ARRAY
|
||||
MPV_FORMAT_NODE_MAP (for each edition)
|
||||
"id" MPV_FORMAT_INT64
|
||||
"length" MPV_FORMAT_DOUBLE
|
||||
|
||||
``disc-title-list``
|
||||
List of BD/DVD titles.
|
||||
|
||||
``disc-title`` (RW)
|
||||
Current BD/DVD title number. Writing works only for ``dvdnav://`` and
|
||||
``bd://`` (and aliases for these).
|
||||
@@ -928,10 +775,6 @@ Property list
|
||||
a BD or DVD. Use the ``discnav menu`` command to actually enter or leave
|
||||
menu mode.
|
||||
|
||||
``disc-mouse-on-button``
|
||||
Return ``yes`` when the mouse cursor is located on a button, or ``no``
|
||||
when cursor is outside of any button for disc navigation.
|
||||
|
||||
``chapters``
|
||||
Number of chapters.
|
||||
|
||||
@@ -971,7 +814,7 @@ Property list
|
||||
"title" MPV_FORMAT_STRING
|
||||
"default" MPV_FORMAT_FLAG
|
||||
|
||||
``ab-loop-a``, ``ab-loop-b`` (RW)
|
||||
``ab-loop-a``, ``ab-loop-b`` (TW)
|
||||
Set/get A-B loop points. See corresponding options and ``ab_loop`` command.
|
||||
The special value ``no`` on either of these properties disables looping.
|
||||
|
||||
@@ -1019,10 +862,6 @@ Property list
|
||||
MPV_FORMAT_NODE_MAP
|
||||
(key and string value for each metadata entry)
|
||||
|
||||
``filtered-metadata``
|
||||
Like ``metadata``, but includes only fields listed in the ``--display-tags``
|
||||
option. This is the same set of tags that is printed to the terminal.
|
||||
|
||||
``chapter-metadata``
|
||||
Metadata of current chapter. Works similar to ``metadata`` property. It
|
||||
also allows the same access methods (using sub-properties).
|
||||
@@ -1047,10 +886,6 @@ Property list
|
||||
``pause`` (RW)
|
||||
Pause status. This is usually ``yes`` or ``no``. See ``--pause``.
|
||||
|
||||
``idle``
|
||||
Return ``yes`` if no file is loaded, but the player is staying around
|
||||
because of the ``--idle`` option.
|
||||
|
||||
``core-idle``
|
||||
Return ``yes`` if the playback core is paused, otherwise ``no``. This can
|
||||
be different ``pause`` in special situations, such as when the player
|
||||
@@ -1090,11 +925,6 @@ Property list
|
||||
guess is very unreliable, and often the property will not be available
|
||||
at all, even if data is buffered.
|
||||
|
||||
``demuxer-cache-time``
|
||||
Approximate time of video buffered in the demuxer, in seconds. Same as
|
||||
``demuxer-cache-duration`` but returns the last timestamp of bufferred
|
||||
data in demuxer.
|
||||
|
||||
``demuxer-cache-idle``
|
||||
Returns ``yes`` if the demuxer is idle, which means the demuxer cache is
|
||||
filled to the requested amount, and is currently not reading more data.
|
||||
@@ -1140,6 +970,9 @@ Property list
|
||||
``audio-codec``
|
||||
Audio codec selected for decoding.
|
||||
|
||||
``audio-bitrate``
|
||||
Audio bitrate. This is probably a very bad guess in most cases.
|
||||
|
||||
``audio-samplerate``
|
||||
Audio samplerate.
|
||||
|
||||
@@ -1167,18 +1000,17 @@ Property list
|
||||
``field-dominance`` (RW)
|
||||
See ``--field-dominance``
|
||||
|
||||
``colormatrix`` (R)
|
||||
Redirects to ``video-params/colormatrix``. This parameter (as well as
|
||||
similar ones) can be overridden with the ``format`` video filter.
|
||||
``colormatrix`` (RW)
|
||||
See ``--colormatrix``.
|
||||
|
||||
``colormatrix-input-range`` (R)
|
||||
See ``colormatrix``.
|
||||
``colormatrix-input-range`` (RW)
|
||||
See ``--colormatrix-input-range``.
|
||||
|
||||
``colormatrix-output-range`` (R)
|
||||
See ``colormatrix``.
|
||||
``colormatrix-output-range`` (RW)
|
||||
See ``--colormatrix-output-range``.
|
||||
|
||||
``colormatrix-primaries`` (R)
|
||||
See ``colormatrix``.
|
||||
``colormatrix-primaries`` (RW)
|
||||
See ``--colormatrix-primaries``.
|
||||
|
||||
``ontop`` (RW)
|
||||
See ``--ontop``.
|
||||
@@ -1186,9 +1018,6 @@ Property list
|
||||
``border`` (RW)
|
||||
See ``--border``.
|
||||
|
||||
``on-all-workspaces`` (RW)
|
||||
See ``--on-all-workspaces``. Unsetting may not work on all WMs.
|
||||
|
||||
``framedrop`` (RW)
|
||||
See ``--framedrop``.
|
||||
|
||||
@@ -1217,17 +1046,6 @@ Property list
|
||||
Note that you don't know the success of the operation immediately after
|
||||
writing this property. It happens with a delay as video is reinitialized.
|
||||
|
||||
``detected-hwdec``
|
||||
Return the current hardware decoder that was detected and opened. Returns
|
||||
the same values as ``hwdec``.
|
||||
|
||||
This is known only once the VO has opened (and possibly later). With some
|
||||
VOs (like ``opengl``), this is never known in advance, but only when the
|
||||
decoder attempted to create the hw decoder successfully. Also, hw decoders
|
||||
with ``-copy`` suffix are returned only while hw decoding is active (and
|
||||
unset afterwards). All this reflects how detecting hw decoders are
|
||||
detected and used internally in mpv.
|
||||
|
||||
``panscan`` (RW)
|
||||
See ``--panscan``.
|
||||
|
||||
@@ -1237,6 +1055,9 @@ Property list
|
||||
``video-codec``
|
||||
Video codec selected for decoding.
|
||||
|
||||
``video-bitrate``
|
||||
Video bitrate (a bad guess).
|
||||
|
||||
``width``, ``height``
|
||||
Video size. This uses the size of the video as decoded, or if no video
|
||||
frame has been decoded yet, the (possibly incorrect) container indicated
|
||||
@@ -1250,16 +1071,6 @@ Property list
|
||||
The pixel format as string. This uses the same names as used in other
|
||||
places of mpv.
|
||||
|
||||
``video-params/average-bpp``
|
||||
Average bits-per-pixel as integer. Subsampled planar formats use a
|
||||
different resolution, which is the reason this value can sometimes be
|
||||
odd or confusing. Can be unavailable with some formats.
|
||||
|
||||
``video-params/plane-depth``
|
||||
Bit depth for each color component as integer. This is only exposed
|
||||
for planar or single-component formats, and is unavailable for other
|
||||
formats.
|
||||
|
||||
``video-params/w``, ``video-params/h``
|
||||
Video size as integers, with no aspect correction applied.
|
||||
|
||||
@@ -1281,9 +1092,6 @@ Property list
|
||||
``video-params/primaries``
|
||||
The primaries in use as string. (Exact values subject to change.)
|
||||
|
||||
``video-params/gamma``
|
||||
The gamma function in use as string. (Exact values subject to change.)
|
||||
|
||||
``video-params/chroma-location``
|
||||
Chroma location as string. (Exact values subject to change.)
|
||||
|
||||
@@ -1354,13 +1162,6 @@ Property list
|
||||
Names of the displays that the mpv window covers. On X11, these
|
||||
are the xrandr names (LVDS1, HDMI1, DP1, VGA1, etc.).
|
||||
|
||||
``display-fps``
|
||||
The refresh rate of the current display. Currently, this is the lowest FPS
|
||||
of any display covered by the video, as retrieved by the underlying system
|
||||
APIs (e.g. xrandr on X11). It is not the measured FPS. It's not necessarily
|
||||
available on all platforms. Note that any of the listed facts may change
|
||||
any time without a warning.
|
||||
|
||||
``video-aspect`` (RW)
|
||||
Video aspect, see ``--video-aspect``.
|
||||
|
||||
@@ -1417,11 +1218,8 @@ Property list
|
||||
``sub-scale`` (RW)
|
||||
Subtitle font size multiplier.
|
||||
|
||||
``ass-force-margins`` (RW)
|
||||
See ``--ass-force-margins``.
|
||||
|
||||
``sub-use-margins`` (RW)
|
||||
See ``--sub-use-margins``.
|
||||
``ass-use-margins`` (RW)
|
||||
See ``--ass-use-margins``.
|
||||
|
||||
``ass-vsfilter-aspect-compat`` (RW)
|
||||
See ``--ass-vsfilter-aspect-compat``.
|
||||
@@ -1525,13 +1323,6 @@ Property list
|
||||
``track-list/N/selected``
|
||||
``yes`` if the track is currently decoded, ``no`` otherwise.
|
||||
|
||||
``track-list/N/ff-index``
|
||||
The stream index as usually used by the FFmpeg utilities. Note that
|
||||
this can be potentially wrong if a demuxer other than libavformat
|
||||
(``--demuxer=lavf``) is used. For mkv files, the index will usually
|
||||
match even if the default (builtin) demuxer is used, but there is
|
||||
no hard guarantee.
|
||||
|
||||
When querying the property with the client API using ``MPV_FORMAT_NODE``,
|
||||
or with Lua ``mp.get_property_native``, this will return a mpv_node with
|
||||
the following contents:
|
||||
@@ -1606,14 +1397,6 @@ Property list
|
||||
``seekable``
|
||||
Return whether it's generally possible to seek in the current file.
|
||||
|
||||
``partially-seekable``
|
||||
Return ``yes`` if the current file is considered seekable, but only because
|
||||
the cache is active. This means small relative seeks may be fine, but larger
|
||||
seeks may fail anyway. Whether a seek will succeed or not is generally not
|
||||
known in advance.
|
||||
|
||||
If this property returns true, ``seekable`` will also return true.
|
||||
|
||||
``playback-abort``
|
||||
Return whether playback is stopped or is to be stopped. (Useful in obscure
|
||||
situations like during ``on_load`` hook processing, when the user can
|
||||
@@ -1638,53 +1421,18 @@ Property list
|
||||
|
||||
.. admonition:: Example
|
||||
|
||||
- ``--osd-status-msg='This is ${osd-ass-cc/0}{\\b1}bold text'``
|
||||
- ``show_text "This is ${osd-ass-cc/0}{\b1}bold text"``
|
||||
--osd-status-msg='This is ${osd-ass-cc/0}{\\b1}bold text'
|
||||
|
||||
Any ASS override tags as understood by libass can be used.
|
||||
|
||||
Note that you need to escape the ``\`` character, because the string is
|
||||
processed for C escape sequences before passing it to the OSD code.
|
||||
|
||||
A list of tags can be found here: http://docs.aegisub.org/latest/ASS_Tags/
|
||||
|
||||
``vo-configured``
|
||||
Return whether the VO is configured right now. Usually this corresponds to
|
||||
whether the video window is visible. If the ``--force-window`` option is
|
||||
used, this is usually always returns ``yes``.
|
||||
|
||||
``video-bitrate``, ``audio-bitrate``, ``sub-bitrate``
|
||||
Bitrate values calculated on the packet level. This works by dividing the
|
||||
bit size of all packets between two keyframes by their presentation
|
||||
timestamp distance. (This uses the timestamps are stored in the file, so
|
||||
e.g. playback speed does not influence the returned values.) In particular,
|
||||
the video bitrate will update only per keyframe, and show the "past"
|
||||
bitrate. To make the property more UI friendly, updates to these properties
|
||||
are throttled in a certain way.
|
||||
|
||||
The unit is bits per second. OSD formatting turns these values in kilobits
|
||||
(or megabits, if appropriate), which can be prevented by using the
|
||||
raw property value, e.g. with ``${=video-bitrate}``.
|
||||
|
||||
Note that the accuracy of these properties is influenced by a few factors.
|
||||
If the underlying demuxer rewrites the packets on demuxing (done for some
|
||||
file formats), the bitrate might be slightly off. If timestamps are bad
|
||||
or jittery (like in Matroska), even constant bitrate streams might show
|
||||
fluctuating bitrate.
|
||||
|
||||
How exactly these values are calculated might change in the future.
|
||||
|
||||
In earlier versions of mpv, these properties returned a static (but bad)
|
||||
guess using a completely different method.
|
||||
|
||||
``packet-video-bitrate``, ``packet-audio-bitrate``, ``packet-sub-bitrate``
|
||||
Old and deprecated properties for ``video-bitrate``, ``audio-bitrate``,
|
||||
``sub-bitrate``. They behave exactly the same, but return a value in
|
||||
kilobits. Also, they don't have any OSD formatting, though the same can be
|
||||
achieved with e.g. ``${=video-bitrate}``.
|
||||
|
||||
These properties shouldn't be used anymore.
|
||||
|
||||
``audio-device-list``
|
||||
Return the list of discovered audio devices. This is mostly for use with
|
||||
the client API, and reflects what ``--audio-device=help`` with the command
|
||||
@@ -1706,13 +1454,6 @@ Property list
|
||||
human readable free form text. The description is an empty string if none
|
||||
was received.
|
||||
|
||||
The special entry with the name set to ``auto`` selects the default audio
|
||||
output driver and the default device.
|
||||
|
||||
The property can be watched with the property observation mechanism in
|
||||
the client API and in Lua scripts. (Technically, change notification is
|
||||
enabled the first time this property is read.)
|
||||
|
||||
``audio-device`` (RW)
|
||||
Set the audio device. This directly reads/writes the ``--audio-device``
|
||||
option, but on write accesses, the audio output will be scheduled for
|
||||
@@ -1726,20 +1467,6 @@ Property list
|
||||
|
||||
How these details are handled may change in the future.
|
||||
|
||||
``current-vo``
|
||||
Current video output driver (name as used with ``--vo``).
|
||||
|
||||
``current-ao``
|
||||
Current audio output driver (name as used with ``--ao``).
|
||||
|
||||
``audio-out-detected-device``
|
||||
Return the audio device selected by the AO driver (only implemented for
|
||||
some drivers: currently only ``coreaudio``).
|
||||
|
||||
``working-directory``
|
||||
Return the working directory of the mpv process. Can be useful for JSON IPC
|
||||
users, because the command line player usually works with relative paths.
|
||||
|
||||
``mpv-version``
|
||||
Return the mpv version/copyright string. Depending on how the binary was
|
||||
built, it might contain either a release version, or just a git hash.
|
||||
@@ -1779,6 +1506,7 @@ Property list
|
||||
For many complex types, this isn't very accurate.
|
||||
|
||||
``option-info/<name>/set-from-commandline``
|
||||
|
||||
Return ``yes`` if the option was set from the mpv command line,
|
||||
``no`` otherwise. What this is set to if the option is e.g. changed
|
||||
at runtime is left undefined (meaning it could change in the future).
|
||||
@@ -1805,10 +1533,7 @@ Property Expansion
|
||||
------------------
|
||||
|
||||
All string arguments to input commands as well as certain options (like
|
||||
``--term-playing-msg``) are subject to property expansion. Note that property
|
||||
expansion does not work in places where e.g. numeric parameters are expected.
|
||||
(For example, the ``add`` command does not do property expansion. The ``set``
|
||||
command is an exception and not a general rule.)
|
||||
``--term-playing-msg``) are subject to property expansion.
|
||||
|
||||
.. admonition:: Example for input.conf
|
||||
|
||||
|
||||
+2
-44
@@ -4,7 +4,8 @@ JSON IPC
|
||||
mpv can be controlled by external programs using the JSON-based IPC protocol. It
|
||||
can be enabled by specifying the path to a unix socket using the option
|
||||
``--input-unix-socket``. Clients can connect to this socket and send commands to
|
||||
the player or receive events from it.
|
||||
the player or receive events from it. You can use the ``socat`` tool to send
|
||||
commands (and receive reply) from the shell.
|
||||
|
||||
.. warning::
|
||||
|
||||
@@ -14,38 +15,6 @@ the player or receive events from it.
|
||||
which can run arbitrary system commands. The use-case is controlling the
|
||||
player locally. This is not different from the MPlayer slave protocol.
|
||||
|
||||
Socat example
|
||||
-------------
|
||||
|
||||
You can use the ``socat`` tool to send commands (and receive reply) from the
|
||||
shell. Assuming mpv was started with:
|
||||
|
||||
::
|
||||
|
||||
mpv file.mkv --input-unix-socket=/tmp/mpvsocket
|
||||
|
||||
Then you can control it using socat:
|
||||
|
||||
::
|
||||
|
||||
> echo '{ "command": ["get_property", "playback-time"] }' | socat - /tmp/mpvsocket
|
||||
{"data":190.482000,"error":"success"}
|
||||
|
||||
In this case, socat copies data between stdin/stdout and the mpv socket
|
||||
connection.
|
||||
|
||||
See the ``--idle`` option how to make mpv start without exiting immediately or
|
||||
playing a file.
|
||||
|
||||
It's also possible to send input.conf style text-only commands:
|
||||
|
||||
::
|
||||
|
||||
> echo 'show_text ${playback-time}' | socat - /tmp/mpvsocket
|
||||
|
||||
But you won't get a reply over the socket. (This particular command shows the
|
||||
playback time on the player's OSD.)
|
||||
|
||||
Protocol
|
||||
--------
|
||||
|
||||
@@ -79,9 +48,6 @@ mpv will also send events to clients with JSON messages of the following form:
|
||||
where ``event_name`` is the name of the event. Additional event-specific fields
|
||||
can also be present. See `List of events`_ for a list of all supported events.
|
||||
|
||||
All commands, replies, and events are separated from each other with a line
|
||||
break character (``\n``).
|
||||
|
||||
If the first character (after skipping whitespace) is not ``{``, the command
|
||||
will be interpreted as non-JSON text command, as they are used in input.conf
|
||||
(or ``mpv_command_string()`` in the client API). Additionally, line starting
|
||||
@@ -190,14 +156,6 @@ extra commands can also be used as part of the protocol:
|
||||
lead to breakages with future mpv releases. Instead, make a feature request,
|
||||
and ask for a proper event that returns the information you need.
|
||||
|
||||
``enable_event``, ``disable_event``
|
||||
Enables or disables the named event. Mirrors the ``mpv_request_event`` C
|
||||
API function. If the string ``all`` is used instead of an event name, all
|
||||
events are enabled or disabled.
|
||||
|
||||
By default, most events are enabled, and there is not much use for this
|
||||
command.
|
||||
|
||||
``suspend``
|
||||
Suspend the mpv main loop. There is a long-winded explanation of this in
|
||||
the C API function ``mpv_suspend()``. In short, this prevents the player
|
||||
|
||||
+47
-69
@@ -1,14 +1,14 @@
|
||||
LUA SCRIPTING
|
||||
=============
|
||||
|
||||
mpv can load Lua scripts. Scripts passed to the ``--script`` option, or found in
|
||||
the ``scripts`` subdirectory of the mpv configuration directory (usually
|
||||
``~/.config/mpv/scripts/``) will be loaded on program start. mpv also appends the
|
||||
``scripts`` subdirectory to the end of Lua's path so you can import scripts from
|
||||
mpv can load Lua scripts. Scripts passed to the ``--lua`` option, or found in
|
||||
the ``lua`` subdirectory of the mpv configuration directory (usually
|
||||
``~/.config/mpv/lua/``) will be loaded on program start. mpv also appends the
|
||||
``lua`` subdirectory to the end of Lua's path so you can import scripts from
|
||||
there too. Since it's added to the end, don't name scripts you want to import
|
||||
the same as Lua libraries because they will be overshadowed by them.
|
||||
|
||||
mpv provides the built-in module ``mp``, which contains functions to send
|
||||
mpv provides the built-in module ``mp``, which provides functions to send
|
||||
commands to the mpv core and to retrieve information about playback state, user
|
||||
settings, file information, and so on.
|
||||
|
||||
@@ -22,21 +22,21 @@ A script which leaves fullscreen mode when the player is paused:
|
||||
|
||||
::
|
||||
|
||||
function on_pause_change(name, value)
|
||||
if value == true then
|
||||
mp.set_property("fullscreen", "no")
|
||||
end
|
||||
function on_pause()
|
||||
mp.set_property("fullscreen", "no")
|
||||
end
|
||||
mp.observe_property("pause", "bool", on_pause_change)
|
||||
mp.register_event("pause", on_pause)
|
||||
|
||||
This script provides a pretty weird feature, but Lua scripting was made to
|
||||
allow users implement features which are not going to be added to the mpv core.
|
||||
|
||||
Details on the script initialization and lifecycle
|
||||
--------------------------------------------------
|
||||
Mode of operation
|
||||
-----------------
|
||||
|
||||
Your script will be loaded by the player at program start from the ``scripts``
|
||||
configuration subdirectory, or from a path specified with the ``--script``
|
||||
option. Some scripts are loaded internally (like ``--osc``). Each script runs in
|
||||
its own thread. Your script is first run "as is", and once that is done, the event loop
|
||||
Your script will be loaded by the player at program start from the ``lua``
|
||||
configuration subdirectory, from a path specified with the ``--lua`` option, or
|
||||
in some cases, internally (like ``--osc``). Each script runs in its own
|
||||
thread. Your script is first run "as is", and once that is done, the event loop
|
||||
is entered. This event loop will dispatch events received by mpv and call your
|
||||
own event handlers which you have registered with ``mp.register_event``, or
|
||||
timers added with ``mp.add_timeout`` or similar.
|
||||
@@ -73,10 +73,6 @@ The ``mp`` module is preloaded, although it can be loaded manually with
|
||||
Run the given command. This is similar to the commands used in input.conf.
|
||||
See `List of Input Commands`_.
|
||||
|
||||
By default, this will show something on the OSD (depending on the command),
|
||||
as if it was used in ``input.conf``. See `Input Command Prefixes`_ how
|
||||
to influence OSD usage per command.
|
||||
|
||||
Returns ``true`` on success, or ``nil, error`` on error.
|
||||
|
||||
``mp.commandv(arg1, arg2, ...)``
|
||||
@@ -98,9 +94,6 @@ The ``mp`` module is preloaded, although it can be loaded manually with
|
||||
the ``expand-properties`` prefix, or the ``mp.get_property`` family of
|
||||
functions.
|
||||
|
||||
Unlike ``mp.command``, this will not use OSD by default either (except
|
||||
for some OSd-specific commands).
|
||||
|
||||
``mp.command_native(table [,def])``
|
||||
Similar to ``mp.commandv``, but pass the argument list as table. This has
|
||||
the advantage that in at least some cases, arguments can be passed as
|
||||
@@ -333,6 +326,7 @@ The ``mp`` module is preloaded, although it can be loaded manually with
|
||||
the timer is re-added after the function fn is run.
|
||||
|
||||
Returns a timer object. The timer object provides the following methods:
|
||||
|
||||
``stop()``
|
||||
Disable the timer. Does nothing if the timer is already disabled.
|
||||
This will remember the current elapsed time when stopping, so that
|
||||
@@ -363,26 +357,9 @@ The ``mp`` module is preloaded, although it can be loaded manually with
|
||||
(``true``). This value is used when the timer expires (but before
|
||||
the timer callback function fn is run).
|
||||
|
||||
Note that these are method, and you have to call them using ``:`` instead
|
||||
of ``.`` (Refer to http://www.lua.org/manual/5.2/manual.html#3.4.9 .)
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
|
||||
seconds = 0
|
||||
timer = mp.add_periodic_timer(1, function()
|
||||
print("called every second")
|
||||
# stop it after 10 seconds
|
||||
seconds = seconds + 1
|
||||
if seconds >= 10 then
|
||||
timer:kill()
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
``mp.get_opt(key)``
|
||||
Return a setting from the ``--script-opts`` option. It's up to the user and
|
||||
Return a setting from the ``--lua-opts`` option. It's up to the user and
|
||||
the script how this mechanism is used. Currently, all scripts can access
|
||||
this equally, so you should be careful about collisions.
|
||||
|
||||
@@ -518,7 +495,7 @@ Example implementation::
|
||||
optionB = -0.5,
|
||||
optionC = true,
|
||||
}
|
||||
read_options(options, "myscript")
|
||||
options.read_options(options, "myscript")
|
||||
print(option.optionA)
|
||||
|
||||
|
||||
@@ -534,12 +511,12 @@ Example config::
|
||||
optionC=no
|
||||
|
||||
|
||||
Command-line options are read from the ``--script-opts`` parameter. To avoid
|
||||
Command-line options are read from the ``--lua-opts`` parameter. To avoid
|
||||
collisions, all keys have to be prefixed with ``identifier-``.
|
||||
|
||||
Example command-line::
|
||||
|
||||
--script-opts=myscript-optionA=TEST,myscript-optionB=0,myscript-optionC=yes
|
||||
--lua-opts=myscript-optionA=TEST:myscript-optionB=0:myscript-optionC=yes
|
||||
|
||||
|
||||
mp.utils options
|
||||
@@ -596,7 +573,7 @@ strictly part of the guaranteed API.
|
||||
Runs an external process and waits until it exits. Returns process status
|
||||
and the captured output.
|
||||
|
||||
The parameter ``t`` is a table. The function reads the following entries:
|
||||
The paramater ``t`` is a table. The function reads the following entries:
|
||||
|
||||
``args``
|
||||
Array of strings. The first array entry is the executable. This
|
||||
@@ -646,18 +623,6 @@ strictly part of the guaranteed API.
|
||||
trailing text is returned as 3rd return value. (The 3rd return value is
|
||||
always there, but with ``trail`` set, no error is raised.)
|
||||
|
||||
``utils.format_json(v)``
|
||||
Format the given Lua table (or value) as a JSON string and return it. On
|
||||
error, returns ``nil, error``. (Errors usually only happen on value types
|
||||
incompatible with JSON.)
|
||||
|
||||
The argument value uses similar conventions as ``mp.set_property_native()``
|
||||
to distinguish empty objects and arrays.
|
||||
|
||||
``utils.to_string(v)``
|
||||
Turn the given value into a string. Formats tables and their contents. This
|
||||
doesn't do anything special; it is only needed because Lua is terrible.
|
||||
|
||||
Events
|
||||
------
|
||||
|
||||
@@ -675,7 +640,7 @@ Example:
|
||||
print("start of playback!")
|
||||
end
|
||||
|
||||
mp.register_event("file-loaded", my_fn)
|
||||
mp.register_event("playback-start", my_fn)
|
||||
|
||||
|
||||
|
||||
@@ -694,9 +659,7 @@ List of events
|
||||
Happens after a file was loaded and begins playback.
|
||||
|
||||
``seek``
|
||||
Happens on seeking. (This might include cases when the player seeks
|
||||
internally, even without user interaction. This includes e.g. segment
|
||||
changes when playing ordered chapters Matroska files.)
|
||||
Happens on seeking (including ordered chapter segment changes).
|
||||
|
||||
``playback-restart``
|
||||
Start of playback after seek or after file was loaded.
|
||||
@@ -713,7 +676,7 @@ List of events
|
||||
|
||||
``shutdown``
|
||||
Sent when the player quits, and the script should terminate. Normally
|
||||
handled automatically. See `Details on the script initialization and lifecycle`_.
|
||||
handled automatically. See `Mode of operation`_.
|
||||
|
||||
``log-message``
|
||||
Receives messages enabled with ``mp.enable_messages``. The message data
|
||||
@@ -732,8 +695,13 @@ List of events
|
||||
(undocumented) existing ones.
|
||||
|
||||
``text``
|
||||
The log message. The text will end with a newline character. Sometimes
|
||||
it can contain multiple lines.
|
||||
The log message. Note that this is the direct output of a printf()
|
||||
style output API. The text will contain embedded newlines, and it's
|
||||
possible that a single message contains multiple lines, or that a
|
||||
message contains a partial line.
|
||||
|
||||
It's safe to display messages only if they end with a newline character,
|
||||
and to buffer them otherwise.
|
||||
|
||||
Keep in mind that these messages are meant to be hints for humans. You
|
||||
should not parse them, and prefix/level/text of messages might change
|
||||
@@ -748,6 +716,9 @@ List of events
|
||||
``command-reply``
|
||||
Undocumented (not useful for Lua scripts).
|
||||
|
||||
``script-input-dispatch``
|
||||
Undocumented (used internally).
|
||||
|
||||
``client-message``
|
||||
Undocumented (used internally).
|
||||
|
||||
@@ -764,8 +735,8 @@ The following events also happen, but are deprecated: ``tracks-changed``,
|
||||
Extras
|
||||
------
|
||||
|
||||
This documents experimental features, or features that are "too special" to
|
||||
guarantee a stable interface.
|
||||
This documents experimental features, or features that are "too special" and
|
||||
we don't guarantee a stable interface to it.
|
||||
|
||||
``mp.add_hook(type, priority, fn)``
|
||||
Add a hook callback for ``type`` (a string identifying a certain kind of
|
||||
@@ -776,6 +747,13 @@ guarantee a stable interface.
|
||||
recommended as neutral default value. ``fn`` is the function that will be
|
||||
called during execution of the hook.
|
||||
|
||||
See `Hooks`_ for currently existing hooks and what they do - only the hook
|
||||
list is interesting; handling hook execution is done by the Lua script
|
||||
function automatically.
|
||||
Currently existing hooks:
|
||||
|
||||
``on_load``
|
||||
Called when a file is to be opened, before anything is actually done.
|
||||
For example, you could read and write the ``stream-open-filename``
|
||||
property to redirect an URL to something else (consider support for
|
||||
streaming sites which rarely give the user a direct media URL), or
|
||||
you could set per-file options with by setting the property
|
||||
``file-local-options/<option name>``. The player will wait until all
|
||||
hooks are run.
|
||||
+37
-153
@@ -32,10 +32,8 @@ INTERACTIVE CONTROL
|
||||
===================
|
||||
|
||||
mpv has a fully configurable, command-driven control layer which allows you
|
||||
to control mpv using keyboard, mouse, or remote control (there is no
|
||||
LIRC support - configure remotes as input devices instead).
|
||||
|
||||
See the ``--input-`` options for ways to customize it.
|
||||
to control mpv using keyboard, mouse, joystick or remote control (with
|
||||
LIRC). See the ``--input-`` options for ways to customize it.
|
||||
|
||||
Keyboard Control
|
||||
----------------
|
||||
@@ -137,11 +135,6 @@ l
|
||||
Ctrl + and Ctrl -
|
||||
Adjust audio delay by +/- 0.1 seconds.
|
||||
|
||||
u
|
||||
Switch between applying no style overrides to SSA/ASS subtitles, and
|
||||
overriding them almost completely with the normal subtitle style. See
|
||||
``--ass-style-override`` for more info.
|
||||
|
||||
V
|
||||
Toggle subtitle VSFilter aspect compatibility mode. See
|
||||
``--ass-vsfilter-aspect-compat`` for more info.
|
||||
@@ -171,9 +164,6 @@ Shift+PGUP and Shift+PGDWN
|
||||
D
|
||||
Activate/deactivate deinterlacer.
|
||||
|
||||
A
|
||||
Cycle aspect ratio override.
|
||||
|
||||
(The following keys are valid only when using a video output that supports the
|
||||
corresponding adjustment, or the software equalizer (``--vf=eq``).)
|
||||
|
||||
@@ -245,47 +235,13 @@ is the same as ``--no-fs``.
|
||||
If an option is marked as *(XXX only)*, it will only work in combination with
|
||||
the *XXX* option or if *XXX* is compiled in.
|
||||
|
||||
Escaping spaces and other special characters
|
||||
--------------------------------------------
|
||||
.. note::
|
||||
|
||||
Keep in mind that the shell will partially parse and mangle the arguments you
|
||||
pass to mpv. For example, you might need to quote or escape options and
|
||||
filenames:
|
||||
The suboption parser (used for example for ``--ao=pcm`` suboptions)
|
||||
supports a special kind of string-escaping intended for use with external
|
||||
GUIs.
|
||||
|
||||
``mpv "filename with spaces.mkv" --title="window title"``
|
||||
|
||||
It gets more complicated if the suboption parser is involved. The suboption
|
||||
parser puts several options into a single string, and passes them to a
|
||||
component at once, instead of using multiple options on the level of the
|
||||
command line.
|
||||
|
||||
The suboption parser can quote strings with ``"``, ``'``, and ``[...]``.
|
||||
Additionally, there is a special form of quoting with ``%n%`` described below.
|
||||
|
||||
For example, the ``opengl`` VO can take multiple options:
|
||||
|
||||
``mpv test.mkv --vo=opengl:scale=lanczos:icc-profile=file.icc,xv``
|
||||
|
||||
This passes ``scale=lanczos`` and ``icc-profile=file.icc`` to ``opengl``,
|
||||
and also specifies ``xv`` as fallback VO. If the icc-profile path contains
|
||||
spaces or characters like ``,`` or ``:``, you need to quote them:
|
||||
|
||||
``mpv '--vo=opengl:icc-profile="file with spaces.icc",xv'``
|
||||
|
||||
Shells may actually strip some quotes from the string passed to the commandline,
|
||||
so the example quotes the string twice, ensuring that mpv recieves the ``"``
|
||||
quotes.
|
||||
|
||||
The ``[...]`` form of quotes wraps everything between ``[`` and ``]``. It's
|
||||
useful with shells that don't interpret these characters in the middle of
|
||||
an argument (like bash). These quotes are balanced (since mpv 0.9.0): the ``[``
|
||||
and ``]`` nest, and the quote terminates on the last ``]`` that has no matching
|
||||
``[`` within the string. (For example, ``[a[b]c]`` results in ``a[b]c``.)
|
||||
|
||||
The fixed-length quoting syntax is intended for use with external
|
||||
scripts and programs.
|
||||
|
||||
It is started with ``%`` and has the following format::
|
||||
It has the following format::
|
||||
|
||||
%n%string_of_length_n
|
||||
|
||||
@@ -297,15 +253,6 @@ It is started with ``%`` and has the following format::
|
||||
|
||||
``mpv --ao=pcm:file=%`expr length "$NAME"`%"$NAME" test.avi``
|
||||
|
||||
Suboptions passed to the client API are also subject to escaping. Using
|
||||
``mpv_set_option_string()`` is exactly like passing ``--name=data`` to the
|
||||
command line (but without shell processing of the string). Some options
|
||||
support passing values in a more structured way instead of flat strings, and
|
||||
can avoid the suboption parsing mess. For example, ``--vf`` supports
|
||||
``MPV_FORMAT_NODE``, which let's you pass suboptions as a nested data structure
|
||||
of maps and arrays. (``--vo`` supports this in the same way, although this
|
||||
fact is undocumented.)
|
||||
|
||||
Paths
|
||||
-----
|
||||
|
||||
@@ -321,8 +268,7 @@ console controls. (Which makes it suitable for playing data piped to stdin.)
|
||||
|
||||
For paths passed to suboptions, the situation is further complicated by the
|
||||
need to escape special characters. To work this around, the path can be
|
||||
additionally wrapped in the fixed-length syntax, e.g. ``%n%string_of_length_n``
|
||||
(see above).
|
||||
additionally wrapped in the ``%n%string_of_length_n`` syntax (see above).
|
||||
|
||||
Some mpv options interpret paths starting with ``~``. Currently, the prefix
|
||||
``~~/`` expands to the mpv configuration directory (usually ``~/.config/mpv/``).
|
||||
@@ -378,8 +324,7 @@ Location and Syntax
|
||||
You can put all of the options in configuration files which will be read every
|
||||
time mpv is run. The system-wide configuration file 'mpv.conf' is in your
|
||||
configuration directory (e.g. ``/etc/mpv`` or ``/usr/local/etc/mpv``), the
|
||||
user-specific one is ``~/.config/mpv/mpv.conf``. For details and platform
|
||||
specifics see the `FILES`_ section.
|
||||
user-specific one is ``~/.config/mpv/mpv.conf``.
|
||||
User-specific options override system-wide options and options given on the
|
||||
command line override either. The syntax of the configuration files is
|
||||
``option=<value>``; everything after a *#* is considered a comment. Options
|
||||
@@ -395,17 +340,6 @@ setting them to *no*. Even suboptions can be specified in this way.
|
||||
# Use quotes for text that can contain spaces:
|
||||
status-msg="Time: ${time-pos}"
|
||||
|
||||
Escaping spaces and special characters
|
||||
--------------------------------------
|
||||
|
||||
This is done like with command line options. The shell is not involved here,
|
||||
but option values still need to be quoted as a whole if it contains certain
|
||||
characters like spaces. A config entry can be quoted with ``"`` and ``'``,
|
||||
as well as with the fixed-length syntax (``%n%``) mentioned before. This is like
|
||||
passing the exact contents of the quoted string as command line option. C-style
|
||||
escapes are currently _not_ interpreted on this level, although some options to
|
||||
this manually. (This is a mess and should probably be changed at some point.)
|
||||
|
||||
Putting Command Line Options into the Configuration File
|
||||
--------------------------------------------------------
|
||||
|
||||
@@ -452,11 +386,12 @@ profile name ``default`` to continue with normal options.
|
||||
::
|
||||
|
||||
[vo.vdpau]
|
||||
# Use hardware decoding
|
||||
# Use hardware decoding (might break playback of some h264 files)
|
||||
hwdec=vdpau
|
||||
|
||||
[protocol.dvd]
|
||||
profile-desc="profile for dvd:// streams"
|
||||
vf=pp=hb/vb/dr/al/fd
|
||||
alang=en
|
||||
|
||||
[extension.flv]
|
||||
@@ -479,8 +414,11 @@ A screenshot will usually contain the unscaled video contents at the end of the
|
||||
video filter chain and subtitles. By default, ``S`` takes screenshots without
|
||||
subtitles, while ``s`` includes subtitles.
|
||||
|
||||
Unlike with MPlayer, the ``screenshot`` video filter is not required. This
|
||||
filter was never required in mpv, and has been removed.
|
||||
The ``screenshot`` video filter is not required when using a recommended GUI
|
||||
video output driver. It should normally not be added to the config file, as
|
||||
taking screenshots is handled by the VOs, and adding the screenshot filter will
|
||||
break hardware decoding. (The filter may still be useful for taking screenshots
|
||||
at a certain point within the video chain when using multiple video filters.)
|
||||
|
||||
TERMINAL STATUS LINE
|
||||
====================
|
||||
@@ -498,7 +436,7 @@ listed.
|
||||
|
||||
- ``AV:`` or ``V:`` (video only) or ``A:`` (audio only)
|
||||
- The current time position in ``HH:MM:SS`` format (``playback-time`` property)
|
||||
- The total file duration (absent if unknown) (``length`` property)
|
||||
- The total file duration (or ``00:00:00`` if unknown) (``length`` property)
|
||||
- Playback speed, e.g. `` x2.0``. Only visible if the speed is not normal. This
|
||||
is the user-requested speed, and not the actual speed (usually they should
|
||||
be the same, unless playback is too slow). (``speed`` property.)
|
||||
@@ -518,13 +456,14 @@ listed.
|
||||
rendering is too slow. Also can be incremented on "hiccups" and when the video
|
||||
frame couldn't be displayed on time. (``vo-drop-frame-count`` property.)
|
||||
If the decoder drops frames, the number of decoder-dropped frames is appended
|
||||
to the display as well, e.g.: ``Dropped: 4/34``. This happens only if
|
||||
decoder-framedropping is enabled with the ``--framedrop`` options.
|
||||
(``drop-frame-count`` property.)
|
||||
to the display as well, e.g.: ``Dropped: 4/34``. This should almost never
|
||||
happen, unless decoder-framedropping is enabled with one of the
|
||||
``--framedrop`` options, the stream contains errors, or a weird codec is in
|
||||
use. (``drop-frame-count`` property.)
|
||||
- Cache state, e.g. ``Cache: 2s+134KB``. Visible if the stream cache is enabled.
|
||||
The first value shows the amount of video buffered in the demuxer in seconds,
|
||||
the second value shows *additional* data buffered in the stream cache in
|
||||
kilobytes. (``demuxer-cache-duration`` and ``cache-used`` properties.)
|
||||
kilobytes. (``demuxer-cache-duration`` and ``cached-used`` properties.)
|
||||
|
||||
|
||||
PROTOCOLS
|
||||
@@ -548,7 +487,7 @@ PROTOCOLS
|
||||
``bd://[title][/device]`` ``--bluray-device=PATH``
|
||||
Play a Blu-Ray disc. Currently, this does not accept ISO files. Instead,
|
||||
you must mount the ISO file as filesystem, and point ``--bluray-device``
|
||||
to the mounted directory directly.
|
||||
to the mounted directly.
|
||||
|
||||
``bdnav://[title][/device]``
|
||||
Play a Blu-Ray disc, with navigation features enabled. This feature is
|
||||
@@ -610,39 +549,6 @@ PROTOCOLS
|
||||
``memory://data``
|
||||
Use the ``data`` part as source data.
|
||||
|
||||
PSEUDO GUI MODE
|
||||
===============
|
||||
|
||||
mpv has no official GUI, other than the OSC (`ON SCREEN CONTROLLER`_), which
|
||||
is not a full GUI and is not meant to be. However, to compensate for the lack
|
||||
of expected GUI behavior, mpv will in some cases start with some settings
|
||||
changed to behave slightly more like a GUI mode.
|
||||
|
||||
Currently this happens only in the following cases:
|
||||
|
||||
- if started using the ``mpv.desktop`` file on Linux (e.g. started from menus
|
||||
or file associations provided by desktop environments)
|
||||
- if started from explorer.exe on Windows (technically, if it was started on
|
||||
Windows, and all of the stdout/stderr/stdin handles are unset)
|
||||
- manually adding ``--profile=pseudo-gui`` to the command line
|
||||
|
||||
This mode implicitly adds ``--profile=pseudo-gui`` to the command line, with
|
||||
the ``pseudo-gui`` profile being predefined with the following contents:
|
||||
|
||||
::
|
||||
|
||||
[pseudo-gui]
|
||||
terminal=no
|
||||
force-window=yes
|
||||
idle=once
|
||||
|
||||
This follows the mpv config file format. To customize pseudo-GUI mode, you can
|
||||
put your own ``pseudo-gui`` profile into your ``mpv.conf``. This profile will
|
||||
enhance the default profile, rather than overwrite it.
|
||||
|
||||
The profile always overrides other settings in ``mpv.conf``.
|
||||
|
||||
|
||||
.. include:: options.rst
|
||||
|
||||
.. include:: ao.rst
|
||||
@@ -797,45 +703,21 @@ input command can take an exit code: in this case, that exit code is returned.
|
||||
FILES
|
||||
=====
|
||||
|
||||
For Windows-specifics, see `FILES ON WINDOWS`_ section.
|
||||
|
||||
``/usr/local/etc/mpv/mpv.conf``
|
||||
mpv system-wide settings (depends on ``--prefix`` passed to configure - mpv
|
||||
in default configuration will use ``/usr/local/etc/mpv/`` as config
|
||||
directory, while most Linux distributions will set it to ``/etc/mpv/``).
|
||||
mpv system-wide settings (depends on ``--prefix`` passed to configure)
|
||||
|
||||
``~/.config/mpv/mpv.conf``
|
||||
mpv user settings (see `CONFIGURATION FILES`_ section)
|
||||
mpv user settings
|
||||
|
||||
``~/.config/mpv/input.conf``
|
||||
key bindings (see `INPUT.CONF`_ section)
|
||||
|
||||
``~/.config/mpv/scripts/``
|
||||
All files in this directory are loaded as if they were passed to the
|
||||
``--script`` option. They are loaded in alphabetical order, and sub-directories
|
||||
``~/.config/mpv/lua/``
|
||||
All files in this directly are loaded as if they were passed to the
|
||||
``--lua`` option. They are loaded in alphabetical order, and sub-directories
|
||||
and files with no ``.lua`` extension are ignored. The ``--load-scripts=no``
|
||||
option disables loading these files.
|
||||
|
||||
``~/.config/mpv/watch_later/``
|
||||
Contains temporary config files needed for resuming playback of files with
|
||||
the watch later feature. See for example the ``Q`` key binding, or the
|
||||
``quit_watch_later`` input command.
|
||||
|
||||
Each file is a small config file which is loaded if the corresponding media
|
||||
file is loaded. It contains the playback position and some (not necessarily
|
||||
all) settings that were changed during playback. The filenames are hashed
|
||||
from the full paths of the media files. It's in general not possible to
|
||||
extract the media filename from this hash. However, you can set the
|
||||
``--write-filename-in-watch-later-config`` option, and the player will
|
||||
add the media filename to the contents of the resume config file.
|
||||
|
||||
``~/.config/mpv/lua-settings/osc.conf``
|
||||
This is loaded by the OSC script. See the `ON SCREEN CONTROLLER`_ docs
|
||||
for details.
|
||||
|
||||
Other files in this directory are specific to the corresponding scripts
|
||||
as well, and the mpv core doesn't touch them.
|
||||
|
||||
Note that the environment variables ``$XDG_CONFIG_HOME`` and ``$MPV_HOME`` can
|
||||
override the standard directory ``~/.config/mpv/``.
|
||||
|
||||
@@ -846,16 +728,18 @@ FILES ON WINDOWS
|
||||
================
|
||||
|
||||
On win32 (if compiled with MinGW, but not Cygwin), the default config file
|
||||
locations are different. They are generally located under ``%APPDATA%/mpv/``.
|
||||
For example, the path to mpv.conf is ``%APPDATA%/mpv/mpv.conf``, which maps to
|
||||
a system and user-specific path, for example
|
||||
locations are different:
|
||||
|
||||
``C:\users\USERNAME\Application Data\mpv\mpv.conf``
|
||||
``%APPDATA%/mpv/mpv.conf``
|
||||
Preferred mpv config file. This maps to a system and user-specific path,
|
||||
for example ``C:\users\USERNAME\Application Data\mpv\mpv.conf``. You can
|
||||
find the exact path by running ``echo %APPDATA%\mpv\mpv.conf`` in cmd.exe.
|
||||
|
||||
You can find the exact path by running ``echo %APPDATA%\mpv\mpv.conf`` in cmd.exe.
|
||||
``%APPDATA%/mpv/input.conf``
|
||||
key bindings (see `INPUT.CONF`_ section)
|
||||
|
||||
Other config files (such as ``input.conf``) are in the same directory. See the
|
||||
`FILES`_ section above.
|
||||
``%APPDATA%/mpv/lua/``
|
||||
equivalent of ``~/.config/mpv/lua/`` on Unix.
|
||||
|
||||
The environment variable ``$MPV_HOME`` completely overrides these, like on
|
||||
UNIX.
|
||||
|
||||
+197
-292
@@ -51,8 +51,8 @@ Track Selection
|
||||
other software using FFmpeg (consider ``ffprobe``).
|
||||
|
||||
Note that with external tracks (added with ``--sub-file`` and similar
|
||||
options), there will be streams with duplicate IDs. In this case, the
|
||||
first stream in order is selected.
|
||||
options) will have duplicate IDs. In that case, the first stream in order
|
||||
is selected.
|
||||
|
||||
``--edition=<ID|auto>``
|
||||
(Matroska files only)
|
||||
@@ -104,21 +104,15 @@ Playback Control
|
||||
``--speed=<0.01-100>``
|
||||
Slow down or speed up playback by the factor given as parameter.
|
||||
|
||||
If ``--audio-pitch-correction`` (on by default) is used, playing with a
|
||||
speed higher than normal automatically inserts the ``scaletempo`` audio
|
||||
filter.
|
||||
If ``--audio-pitch-correction`` is used, playing with a speed higher than
|
||||
normal automatically inserts the ``scaletempo`` audio filter.
|
||||
|
||||
``--loop=<N|inf|force|no>``
|
||||
``--loop=<N|inf|no>``
|
||||
Loops playback ``N`` times. A value of ``1`` plays it one time (default),
|
||||
``2`` two times, etc. ``inf`` means forever. ``no`` is the same as ``1`` and
|
||||
disables looping. If several files are specified on command line, the
|
||||
entire playlist is looped.
|
||||
|
||||
The ``force`` mode is like ``inf``, but does not skip playlist entries
|
||||
which have been marked as failing. This means the player might waste CPU
|
||||
time trying to loop a file that doesn't exist. But it might be useful for
|
||||
playing webradios under very bad network conditions.
|
||||
|
||||
``--pause``
|
||||
Start the player in paused state.
|
||||
|
||||
@@ -130,8 +124,8 @@ Playback Control
|
||||
chapter to end playing at. Also see ``--start``.
|
||||
|
||||
``--playlist=<filename>``
|
||||
Play files according to a playlist file (Supports some common formats. If
|
||||
no format is detected, it will be treated as list of files, separated by
|
||||
Play files according to a playlist file (Supports some common formats.If
|
||||
no format is detected, t will be treated as list of files, separated by
|
||||
newline characters. Note that XML playlist formats are not supported.)
|
||||
|
||||
You can play playlists directly and without this option, however, this
|
||||
@@ -181,7 +175,6 @@ Playback Control
|
||||
file, such as a chapter seek, but not for relative seeks like
|
||||
the default behavior of arrow keys (default).
|
||||
:yes: Use precise seeks whenever possible.
|
||||
:always: Same as ``yes`` (for compatibility).
|
||||
|
||||
``--hr-seek-demuxer-offset=<seconds>``
|
||||
This option exists to work around failures to do precise seeks (as in
|
||||
@@ -312,11 +305,6 @@ Program Behavior
|
||||
``--list-protocols``
|
||||
Print a list of the supported protocols.
|
||||
|
||||
``--log-file=<path>``
|
||||
Opens the given path for writing, and print log messages to it. Existing
|
||||
files will be truncated. The log level always corresponds to ``-v``,
|
||||
regardless of terminal verbosity levels.
|
||||
|
||||
``--config-dir=<path>``
|
||||
Force a different configuration directory. If this is set, the given
|
||||
directory is used to load configuration files, and all other configuration
|
||||
@@ -345,36 +333,37 @@ Program Behavior
|
||||
|
||||
This option is useful for debugging only.
|
||||
|
||||
``--idle=<no|yes|once>``
|
||||
``--idle``
|
||||
Makes mpv wait idly instead of quitting when there is no file to play.
|
||||
Mostly useful in slave mode, where mpv can be controlled through input
|
||||
commands (see also ``--slave-broken``).
|
||||
|
||||
``once`` will only idle at start and let the player close once the
|
||||
first playlist has finished playing back.
|
||||
|
||||
``--include=<configuration-file>``
|
||||
Specify configuration file to be parsed after the default ones.
|
||||
|
||||
``--load-scripts=<yes|no>``
|
||||
If set to ``no``, don't auto-load scripts from the ``scripts``
|
||||
configuration subdirectory (usually ``~/.config/mpv/scripts/``).
|
||||
If set to ``no``, don't auto-load scripts from the ``lua`` configuration
|
||||
subdirectory (usually ``~/.config/mpv/lua/``).
|
||||
(Default: ``yes``)
|
||||
|
||||
``--script=<filename>``
|
||||
``--lua=<filename>``
|
||||
Load a Lua script. You can load multiple scripts by separating them with
|
||||
commas (``,``).
|
||||
|
||||
``--script-opts=key1=value1,key2=value2,...``
|
||||
Set options for scripts. A script can query an option by key. If an
|
||||
``--lua-opts=key1=value1,key2=value2,...``
|
||||
Set options for scripts. A Lua script can query an option by key. If an
|
||||
option is used and what semantics the option value has depends entirely on
|
||||
the loaded scripts. Values not claimed by any scripts are ignored.
|
||||
the loaded Lua scripts. Values not claimed by any scripts are ignored.
|
||||
|
||||
``--merge-files``
|
||||
Pretend that all files passed to mpv are concatenated into a single, big
|
||||
file. This uses timeline/EDL support internally. Note that this won't work
|
||||
for ordered chapter files.
|
||||
|
||||
This option is interpreted at program start, and doesn't affect for
|
||||
example files or playlists loaded with the ``loadfile`` or ``loadlist``
|
||||
commands.
|
||||
|
||||
``--no-resume-playback``
|
||||
Do not restore playback position from the ``watch_later`` configuration
|
||||
subdirectory (usually ``~/.config/mpv/watch_later/``).
|
||||
@@ -422,9 +411,6 @@ Program Behavior
|
||||
This option may expose privacy-sensitive information and is thus
|
||||
disabled by default.
|
||||
|
||||
``--ignore-path-in-watch-later-config``
|
||||
Ignore path (i.e. use filename only) when using watch later feature.
|
||||
|
||||
``--show-profile=<profile>``
|
||||
Show the description and content of a profile.
|
||||
|
||||
@@ -439,34 +425,21 @@ Program Behavior
|
||||
``--ytdl``, ``--no-ytdl``
|
||||
Enable the youtube-dl hook-script. It will look at the input URL, and will
|
||||
play the video located on the website. This works with many streaming sites,
|
||||
not just the one that the script is named after. This requires a recent
|
||||
version of youtube-dl to be installed on the system. (Enabled by default,
|
||||
except when the client API / libmpv is used.)
|
||||
not just the one the scripts are named after. This requires a recent version
|
||||
of youtube-dl to be installed on the system.
|
||||
|
||||
If the script can't do anything with an URL, it will do nothing.
|
||||
|
||||
Currently disabled by default, because youtube-dl's generic extractor can
|
||||
get stuck on some URL, preventing playback.
|
||||
|
||||
(Note: this is the replacement for the now removed libquvi support.)
|
||||
|
||||
``--ytdl-format=<best|worst|mp4|webm|...>``
|
||||
Video format/quality that is directly passed to youtube-dl. The possible
|
||||
values are specific to the website and the video, for a given url the
|
||||
available formats can be found with the command
|
||||
``youtube-dl --list-formats URL``. See youtube-dl's documentation for
|
||||
available aliases. To use experimental DASH support for youtube, use
|
||||
``bestvideo+bestaudio``.
|
||||
(Default: ``best``)
|
||||
|
||||
``--ytdl-raw-options=<key>=<value>[,<key>=<value>[,...]]``
|
||||
Pass arbitraty options to youtube-dl. Parameter and argument should be
|
||||
passed as a key-value pair. Options without argument must include ``=``.
|
||||
|
||||
There is no sanity checking so it's possible to break things (i.e.
|
||||
passing invalid parameters to youtube-dl).
|
||||
|
||||
.. admonition:: Example
|
||||
|
||||
``--ytdl-raw-options=username=user,password=pass``
|
||||
``--ytdl-raw-options=force-ipv6=``
|
||||
``youtube-dl --list-formats URL``.
|
||||
|
||||
Video
|
||||
-----
|
||||
@@ -498,10 +471,6 @@ Video
|
||||
Do not play video. With some demuxers this may not work. In those cases
|
||||
you can try ``--vo=null`` instead.
|
||||
|
||||
mpv will try to download the audio only if media is streamed with
|
||||
youtube-dl, because it saves bandwidth. This is done by setting the ytdl_format
|
||||
to "bestaudio/best" in the ytdl_hook.lua script.
|
||||
|
||||
``--untimed``
|
||||
Do not sleep when outputting video frames. Useful for benchmarks when used
|
||||
with ``--no-audio.``
|
||||
@@ -529,7 +498,7 @@ Video
|
||||
in mpv 0.5.x and before.) This tells the decoder to skip frames (unless
|
||||
they are needed to decode future frames). May help with slow systems,
|
||||
but can produce unwatchably choppy output, or even freeze the display
|
||||
completely. Not recommended.
|
||||
complete. Not recommended.
|
||||
The ``--vd-lavc-framedrop`` option controls what frames to drop.
|
||||
<decoder+vo>
|
||||
Enable both modes. Not recommended.
|
||||
@@ -559,8 +528,7 @@ Video
|
||||
:vaapi: requires ``--vo=opengl`` or ``--vo=vaapi`` (Linux with Intel GPUs only)
|
||||
:vaapi-copy: copies video back into system RAM (Linux with Intel GPUs only)
|
||||
:vda: requires ``--vo=opengl`` (OS X only)
|
||||
:dxva2-copy: copies video back to system RAM (Windows only)
|
||||
:rpi: requires ``--vo=rpi`` (Raspberry Pi only - default if available)
|
||||
:dxva2-copy: copies video back to system RAM (Windows only) (experimental)
|
||||
|
||||
``auto`` tries to automatically enable hardware decoding using the first
|
||||
available method. This still depends what VO you are using. For example,
|
||||
@@ -608,8 +576,9 @@ Video
|
||||
``--video-unscaled``
|
||||
Disable scaling of the video. If the window is larger than the video,
|
||||
black bars are added. Otherwise, the video is cropped. The video still
|
||||
can be influenced by the other ``--video-...`` options. (But not all; for
|
||||
example ``--video-zoom`` does nothing if this option is enabled.)
|
||||
can be influenced by the other ``--video-...`` options. (If the
|
||||
``--video-zoom`` option is set to a value other than ``1``, scaling is
|
||||
enabled, but the video isn't automatically scaled to the window size.)
|
||||
|
||||
The video and monitor aspects aspect will be ignored. Aspect correction
|
||||
would require to scale the video in the X or Y direction, but this option
|
||||
@@ -632,7 +601,7 @@ Video
|
||||
|
||||
This option is disabled if the ``--no-keepaspect`` option is used.
|
||||
|
||||
``--video-rotate=<0-360|no>``
|
||||
``--video-rotate=<0-359|no>``
|
||||
Rotate the video clockwise, in degrees. Currently supports 90° steps only.
|
||||
If ``no`` is given, the video is never rotated, even if the file has
|
||||
rotation metadata. (The rotation value is added to the rotation metadata,
|
||||
@@ -819,7 +788,7 @@ Audio
|
||||
-----
|
||||
|
||||
``--audio-pitch-correction=<yes|no>``
|
||||
If this is enabled (default), playing with a speed different from normal
|
||||
If this is enabled (default), playing with a speed higher than normal
|
||||
automatically inserts the ``scaletempo`` audio filter. For details, see
|
||||
audio filter section.
|
||||
|
||||
@@ -891,7 +860,8 @@ Audio
|
||||
delay the audio, and negative values delay the video.
|
||||
|
||||
``--no-audio``
|
||||
Do not play sound.
|
||||
Do not play sound. With some demuxers this may not work. In those cases
|
||||
you can try ``--ao=null`` instead.
|
||||
|
||||
``--mute=<auto|yes|no>``
|
||||
Set startup audio mute status. ``auto`` (default) will not change the mute
|
||||
@@ -920,14 +890,11 @@ Audio
|
||||
``--ad-lavc-ac3drc=<level>``
|
||||
Select the Dynamic Range Compression level for AC-3 audio streams.
|
||||
``<level>`` is a float value ranging from 0 to 1, where 0 means no
|
||||
compression (which is the default) and 1 means full compression (make loud
|
||||
passages more silent and vice versa). Values up to 6 are also accepted, but
|
||||
compression and 1 (which is the default) means full compression (make loud
|
||||
passages more silent and vice versa). Values up to 2 are also accepted, but
|
||||
are purely experimental. This option only shows an effect if the AC-3 stream
|
||||
contains the required range compression information.
|
||||
|
||||
The standard mandates that DRC is enabled by default, but mpv (and some
|
||||
other players) ignore this for the sake of better audio quality.
|
||||
|
||||
``--ad-lavc-downmix=<yes|no>``
|
||||
Whether to request audio channel downmixing from the decoder (default: yes).
|
||||
Some decoders, like AC-3, AAC and DTS, can remix audio on decoding. The
|
||||
@@ -959,7 +926,7 @@ Audio
|
||||
``--dtshd`` and ``--no-dtshd`` are deprecated aliases.
|
||||
|
||||
``--audio-channels=<number|layout>``
|
||||
Request a channel layout for audio output (default: auto). This will ask
|
||||
Request a channel layout for audio output (default: stereo). This will ask
|
||||
the AO to open a device with the given channel layout. It's up to the AO
|
||||
to accept this layout, or to pick a fallback or to error out if the
|
||||
requested layout is not supported.
|
||||
@@ -972,9 +939,9 @@ Audio
|
||||
lists speaker names, which can be used to express arbitrary channel
|
||||
layouts (e.g. ``fl-fr-lfe`` is 2.1).
|
||||
|
||||
The default is ``--audio-channels=auto``, which tries to play audio using
|
||||
the input file's channel layout. (Or more precisely, the output of the
|
||||
audio filter chain.) (``empty`` is an accepted obsolete alias for ``auto``.)
|
||||
You can use ``--audio-channels=auto`` to disable this. In this case, the AO
|
||||
use the channel layout as the audio filter chain indicates. (``empty`` is
|
||||
an accepted obsolete for ``auto``.)
|
||||
|
||||
This will also request the channel layout from the decoder. If the decoder
|
||||
does not support the layout, it will fall back to its native channel layout.
|
||||
@@ -987,9 +954,8 @@ Audio
|
||||
|
||||
``--audio-display=<no|attachment>``
|
||||
Setting this option to ``attachment`` (default) will display image
|
||||
attachments (e.g. album cover art) when playing audio files. It will
|
||||
display the first image found, and additional images are available as
|
||||
video tracks.
|
||||
attachments when playing audio files. It will display the first image
|
||||
found, and additional images are available as video tracks.
|
||||
|
||||
Setting this option to ``no`` disables display of video entirely when
|
||||
playing audio files.
|
||||
@@ -1067,16 +1033,6 @@ Audio
|
||||
maximum amplification, i.e. amplify by 200%. The default volume (no
|
||||
change in volume) will be ``50`` in this case.
|
||||
|
||||
``--audio-file-auto=<no|exact|fuzzy|all>``, ``--no-audio-file-auto``
|
||||
Load additional audio files matching the video filename. The parameter
|
||||
specifies how external audio files are matched. ``exact`` is enabled by
|
||||
default.
|
||||
|
||||
:no: Don't automatically load external audio files.
|
||||
:exact: Load the media filename with audio file extension (default).
|
||||
:fuzzy: Load all audio files containing media filename.
|
||||
:all: Load all audio files in the current directory.
|
||||
|
||||
``--audio-client-name=<name>``
|
||||
The application name the player reports to the audio API. Can be useful
|
||||
if you want to force a different audio profile (e.g. with PulseAudio),
|
||||
@@ -1166,34 +1122,14 @@ Subtitles
|
||||
This affects ASS subtitles as well, and may lead to incorrect subtitle
|
||||
rendering. Use with care, or use ``--sub-text-font-size`` instead.
|
||||
|
||||
``--sub-scale-by-window=<yes|no>``
|
||||
Whether to scale subtitles with the window size (default: yes). If this is
|
||||
disabled, changing the window size won't change the subtitle font size.
|
||||
|
||||
Like ``--sub-scale``, this can break ASS subtitles.
|
||||
|
||||
``--sub-scale-with-window=<yes|no>``
|
||||
Make the subtitle font size relative to the window, instead of the video.
|
||||
This is useful if you always want the same font size, even if the video
|
||||
doesn't covert the window fully, e.g. because screen aspect and window
|
||||
aspect mismatch (and the player adds black bars).
|
||||
|
||||
Default: yes.
|
||||
|
||||
This option is misnamed. The difference to the confusingly similar sounding
|
||||
option ``--sub-scale-by-window`` is that ``--sub-scale-with-window`` still
|
||||
scales with the approximate window size, while the other option disables
|
||||
this scaling.
|
||||
|
||||
Affects plain text subtitles only (or ASS if ``--ass-style-override`` is
|
||||
set high enough).
|
||||
|
||||
``--ass-scale-with-window=<yes|no>``
|
||||
Like ``--sub-scale-with-window``, but affects subtitles in ASS format only.
|
||||
Like ``--sub-scale``, this can break ASS subtitles.
|
||||
|
||||
Default: no.
|
||||
|
||||
``--embeddedfonts``, ``--no-embeddedfonts``
|
||||
Use fonts embedded in Matroska container files and ASS scripts (default:
|
||||
enabled). These fonts can be used for SSA/ASS subtitle rendering.
|
||||
@@ -1274,23 +1210,12 @@ Subtitles
|
||||
:signfs: like ``yes``, but apply ``--sub-scale`` only to signs
|
||||
:no: Render subtitles as forced by subtitle scripts.
|
||||
:force: Try to force the font style as defined by the ``--sub-text-*``
|
||||
options. Can break rendering easily.
|
||||
options. Requires a modified libass, can break rendering easily.
|
||||
Probably more reliable than ``force``.
|
||||
|
||||
``--ass-force-margins``
|
||||
``--ass-use-margins``
|
||||
Enables placing toptitles and subtitles in black borders when they are
|
||||
available, if the subtitles are in the ASS format.
|
||||
|
||||
Default: no.
|
||||
|
||||
``--sub-use-margins``
|
||||
Enables placing toptitles and subtitles in black borders when they are
|
||||
available, if the subtitles are in a plain text format (or ASS if
|
||||
``--ass-style-override`` is set high enough).
|
||||
|
||||
Default: yes.
|
||||
|
||||
Renamed from ``--ass-use-margins``. To place ASS subtitles in the borders
|
||||
too (like the old option did), also add ``--ass-force-margins``.
|
||||
available.
|
||||
|
||||
``--ass-vsfilter-aspect-compat=<yes|no>``
|
||||
Stretch SSA/ASS subtitles when playing anamorphic videos for compatibility
|
||||
@@ -1509,16 +1434,15 @@ Window
|
||||
------
|
||||
|
||||
``--title=<string>``
|
||||
Set the window title. This is used for the video window, and if possible,
|
||||
also sets the audio stream title.
|
||||
|
||||
Properties are expanded. (See `Property Expansion`_.)
|
||||
Set the window title. Properties are expanded on playback start.
|
||||
(See `Property Expansion`_.)
|
||||
|
||||
.. warning::
|
||||
|
||||
There is a danger of this causing significant CPU usage, depending on
|
||||
the properties used. Changing the window title is often a slow
|
||||
operation, and if the title changes every frame, playback can be ruined.
|
||||
the properties used and the window manager. Changing the window title
|
||||
is often a slow operation, and if the title changes every frame,
|
||||
playback can be ruined.
|
||||
|
||||
``--screen=<default|0-32>``
|
||||
In multi-monitor configurations (i.e. a single desktop that spans across
|
||||
@@ -1554,41 +1478,26 @@ Window
|
||||
|
||||
See also ``--screen``.
|
||||
|
||||
``--fs-black-out-screens``
|
||||
|
||||
OS X only. Black out other displays when going fullscreen.
|
||||
|
||||
``--keep-open=<yes|no|always>``
|
||||
``--keep-open``
|
||||
Do not terminate when playing or seeking beyond the end of the file, and
|
||||
there is not next file to be played (and ``--loop`` is not used).
|
||||
Instead, pause the player. When trying to seek beyond end of the file, the
|
||||
player will attempt to seek to the last frame.
|
||||
|
||||
The following arguments can be given:
|
||||
|
||||
:no: If the current file ends, go to the next file or terminate.
|
||||
(Default.)
|
||||
:yes: Don't terminate if the current file is the last playlist entry.
|
||||
Equivalent to ``--keep-open`` without arguments.
|
||||
:always: Like ``yes``, but also applies to files before the last playlist
|
||||
entry. This means playback will never automatically advance to
|
||||
the next file.
|
||||
player will pause at an arbitrary playback position (or, in corner cases,
|
||||
not redraw the window at all).
|
||||
|
||||
.. note::
|
||||
|
||||
This option is not respected when using ``--frames``. Explicitly
|
||||
skipping to the next file if the binding uses ``force`` will terminate
|
||||
playback as well.
|
||||
|
||||
Also, if errors or unusual circumstances happen, the player can quit
|
||||
anyway.
|
||||
This option is not respected when using ``--frames``, ``--end``,
|
||||
``--length``, or when passing a chapter range to ``--chapter``.
|
||||
Explicitly skipping to the next file or skipping beyond the last
|
||||
chapter will terminate playback as well, even if ``--keep-open`` is
|
||||
given.
|
||||
|
||||
Since mpv 0.6.0, this doesn't pause if there is a next file in the playlist,
|
||||
or the playlist is looped. Approximately, this will pause when the player
|
||||
would normally exit, but in practice there are corner cases in which this
|
||||
is not the case (e.g. ``mpv --keep-open file.mkv /dev/null`` will play
|
||||
file.mkv normally, then fail to open ``/dev/null``, then exit). (In
|
||||
mpv 0.8.0, ``always`` was introduced, which restores the old behavior.)
|
||||
file.mkv normally, then fail to open ``/dev/null``, then exit).
|
||||
|
||||
``--force-window``
|
||||
Create a video output window even if there is no video. This can be useful
|
||||
@@ -1611,10 +1520,6 @@ Window
|
||||
Play video with window border and decorations. Since this is on by
|
||||
default, use ``--no-border`` to disable the standard window decorations.
|
||||
|
||||
``--on-all-workspaces``
|
||||
(X11 only)
|
||||
Show the video window on all virtual desktops.
|
||||
|
||||
``--geometry=<[W[xH]][+-x+-y]>``, ``--geometry=<x:y>``
|
||||
Adjust the initial window position or size. ``W`` and ``H`` set the window
|
||||
size in pixels. ``x`` and ``y`` set the window position, measured in pixels
|
||||
@@ -1717,24 +1622,19 @@ Window
|
||||
screen height, make the window smaller until either its width is 90%
|
||||
of the screen, or its height is 80% of the screen.
|
||||
|
||||
``--autofit-smaller=<[W[xH]]>``
|
||||
This option behaves exactly like ``--autofit``, except that it sets the
|
||||
minimum size of the window (just as ``--autofit-larger`` sets the maximum).
|
||||
|
||||
.. admonition:: Example
|
||||
|
||||
``500x500``
|
||||
Make the window at least 500 pixels wide and 500 pixels high
|
||||
(depending on the video aspect ratio, the width or height will be
|
||||
larger than 500 in order to keep the aspect ratio the same).
|
||||
|
||||
``--window-scale=<factor>``
|
||||
Resize the video window to a multiple (or fraction) of the video size. This
|
||||
option is applied before ``--autofit`` and other options are applied (so
|
||||
they override this option).
|
||||
|
||||
For example, ``--window-scale=0.5`` would show the window at half the
|
||||
video size.
|
||||
``--autosync=<factor>``
|
||||
Gradually adjusts the A/V sync based on audio delay measurements.
|
||||
Specifying ``--autosync=0``, the default, will cause frame timing to be
|
||||
based entirely on audio delay measurements. Specifying ``--autosync=1``
|
||||
will do the same, but will subtly change the A/V correction algorithm. An
|
||||
uneven video framerate in a video which plays fine with ``--no-audio`` can
|
||||
often be helped by setting this to an integer value greater than 1. The
|
||||
higher the value, the closer the timing will be to ``--no-audio``. Try
|
||||
``--autosync=30`` to smooth out problems with sound drivers which do not
|
||||
implement a perfect audio delay measurement. With this value, if large A/V
|
||||
sync offsets occur, they will only take about 1 or 2 seconds to settle
|
||||
out. This delay in reaction time to sudden A/V offsets should be the only
|
||||
side-effect of turning this option on, for all sound drivers.
|
||||
|
||||
``--cursor-autohide=<number|no|always>``
|
||||
Make mouse cursor automatically hide after given number of milliseconds.
|
||||
@@ -1946,10 +1846,6 @@ Disc Devices
|
||||
``--cdda-skip=<yes|no>``
|
||||
(Never) accept imperfect data reconstruction.
|
||||
|
||||
``--cdda-cdtext=<yes|no>``
|
||||
Print CD text. This is disabled by default, because it ruins perfomance
|
||||
with CD-ROM drives for unknown reasons.
|
||||
|
||||
``--dvd-speed=<speed>``
|
||||
Try to limit DVD speed (default: 0, no change). DVD base speed is 1385
|
||||
kB/s, so an 8x drive can read at speeds up to 11080 kB/s. Slower speeds
|
||||
@@ -1993,6 +1889,101 @@ Equalizer
|
||||
negative of the image with this option. Not supported by all video output
|
||||
drivers.
|
||||
|
||||
``--colormatrix=<colorspace>``
|
||||
Controls the YUV to RGB color space conversion when playing video. There
|
||||
are various standards. Normally, BT.601 should be used for SD video, and
|
||||
BT.709 for HD video. (This is done by default.) Using incorrect color space
|
||||
results in slightly under or over saturated and shifted colors.
|
||||
|
||||
The color space conversion is additionally influenced by the related
|
||||
options --colormatrix-input-range and --colormatrix-output-range.
|
||||
|
||||
These options are not always supported. Different video outputs provide
|
||||
varying degrees of support. The ``opengl`` and ``vdpau`` video output
|
||||
drivers usually offer full support. The ``xv`` output can set the color
|
||||
space if the system video driver supports it, but not input and output
|
||||
levels. The ``scale`` video filter can configure color space and input
|
||||
levels, but only if the output format is RGB (if the video output driver
|
||||
supports RGB output, you can force this with ``-vf scale,format=rgba``).
|
||||
|
||||
If this option is set to ``auto`` (which is the default), the video's
|
||||
color space flag will be used. If that flag is unset, the color space
|
||||
will be selected automatically. This is done using a simple heuristic that
|
||||
attempts to distinguish SD and HD video. If the video is larger than
|
||||
1279x576 pixels, BT.709 (HD) will be used; otherwise BT.601 (SD) is
|
||||
selected.
|
||||
|
||||
Available color spaces are:
|
||||
|
||||
:auto: automatic selection (default)
|
||||
:BT.601: ITU-R BT.601 (SD)
|
||||
:BT.709: ITU-R BT.709 (HD)
|
||||
:BT.2020-NCL: ITU-R BT.2020 non-constant luminance system
|
||||
:BT.2020-CL: ITU-R BT.2020 constant luminance system
|
||||
:SMPTE-240M: SMPTE-240M
|
||||
|
||||
``--colormatrix-input-range=<color-range>``
|
||||
YUV color levels used with YUV to RGB conversion. This option is only
|
||||
necessary when playing broken files which do not follow standard color
|
||||
levels or which are flagged wrong. If the video does not specify its
|
||||
color range, it is assumed to be limited range.
|
||||
|
||||
The same limitations as with --colormatrix apply.
|
||||
|
||||
Available color ranges are:
|
||||
|
||||
:auto: automatic selection (normally limited range) (default)
|
||||
:limited: limited range (16-235 for luma, 16-240 for chroma)
|
||||
:full: full range (0-255 for both luma and chroma)
|
||||
|
||||
``--colormatrix-output-range=<color-range>``
|
||||
RGB color levels used with YUV to RGB conversion. Normally, output devices
|
||||
such as PC monitors use full range color levels. However, some TVs and
|
||||
video monitors expect studio RGB levels. Providing full range output to a
|
||||
device expecting studio level input results in crushed blacks and whites,
|
||||
the reverse in dim gray blacks and dim whites.
|
||||
|
||||
The same limitations as with ``--colormatrix`` apply.
|
||||
|
||||
Available color ranges are:
|
||||
|
||||
:auto: automatic selection (equals to full range) (default)
|
||||
:limited: limited range (16-235 per component), studio levels
|
||||
:full: full range (0-255 per component), PC levels
|
||||
|
||||
.. note::
|
||||
|
||||
It is advisable to use your graphics driver's color range option
|
||||
instead, if available.
|
||||
|
||||
``--colormatrix-primaries=<primaries>``
|
||||
RGB primaries the source file was encoded with. Normally this should be set
|
||||
in the file header, but when playing broken or mistagged files this can be
|
||||
used to override the setting. By default, when unset, BT.709 is used for
|
||||
all files except those tagged with a BT.2020 color matrix.
|
||||
|
||||
This option only affects video output drivers that perform color
|
||||
management, for example ``opengl`` with the ``srgb`` or ``icc-profile``
|
||||
suboptions set.
|
||||
|
||||
If this option is set to ``auto`` (which is the default), the video's
|
||||
primaries flag will be used. If that flag is unset, the color space will
|
||||
be selected automatically, using the following heuristics: If the
|
||||
``--colormatrix`` is set or determined as BT.2020 or BT.709, the
|
||||
corresponding primaries are used. Otherwise, if the video height is
|
||||
exactly 576 (PAL), BT.601-625 is used. If it's exactly 480 or 486 (NTSC),
|
||||
BT.601-525 is used. If the video resolution is anything else, BT.709 is
|
||||
used.
|
||||
|
||||
Available primaries are:
|
||||
|
||||
:auto: automatic selection (default)
|
||||
:BT.601-525: ITU-R BT.601 (SD) 525-line systems (NTSC, SMPTE-C)
|
||||
:BT.601-625: ITU-R BT.601 (SD) 625-line systems (PAL, SECAM)
|
||||
:BT.709: ITU-R BT.709 (HD) (same primaries as sRGB)
|
||||
:BT.2020: ITU-R BT.2020 (UHD)
|
||||
|
||||
|
||||
Demuxer
|
||||
-------
|
||||
|
||||
@@ -2020,12 +2011,6 @@ Demuxer
|
||||
``--demuxer-lavf-format=<name>``
|
||||
Force a specific libavformat demuxer.
|
||||
|
||||
``--demuxer-lavf-hacks=<yes|no>``
|
||||
By default, some formats will be handled differently from other formats
|
||||
by explicitly checking for them. Most of these compensate for weird or
|
||||
imperfect behavior from libavformat demuxers. Passing ``no`` disables
|
||||
these. For debugging and testing only.
|
||||
|
||||
``--demuxer-lavf-genpts-mode=<no|lavf>``
|
||||
Mode for deriving missing packet PTS values from packet DTS. ``lavf``
|
||||
enables libavformat's ``genpts`` option. ``no`` disables it. This used
|
||||
@@ -2110,18 +2095,6 @@ Demuxer
|
||||
will be slower (especially when playing over http), or that behavior with
|
||||
broken files is much worse. So don't use this option.
|
||||
|
||||
``--demuxer-mkv-fix-timestamps=<yes|no>``
|
||||
Fix rounded Matroska timestamps (enabled by default). Matroska usually
|
||||
stores timestamps rounded to milliseconds. This means timestamps jitter
|
||||
by some amount around the intended timestamp. mpv can correct the timestamps
|
||||
based on the framerate value stored in the file: the timestamp is rounded
|
||||
to the next frame (according to the framerate), unless the new timestamp
|
||||
would deviate more than 1ms from the old one. This should undo the rounding
|
||||
done by the muxer.
|
||||
|
||||
(The allowed deviation can be less than 1ms if the file uses a non-standard
|
||||
timecode scale.)
|
||||
|
||||
``--demuxer-rawaudio-channels=<value>``
|
||||
Number of channels (or channel layout) if ``--demuxer=rawaudio`` is used
|
||||
(default: stereo).
|
||||
@@ -2144,7 +2117,7 @@ Demuxer
|
||||
Play a raw YUV sample::
|
||||
|
||||
mpv sample-720x576.yuv --demuxer=rawvideo \
|
||||
--demuxer-rawvideo-w=720 --demuxer-rawvideo-h=576
|
||||
--demuxer-rawvideo=w=720:h=576
|
||||
|
||||
``--demuxer-rawvideo-format=<value>``
|
||||
Color space (fourcc) in hex or string for ``--demuxer=rawvideo``
|
||||
@@ -2170,13 +2143,10 @@ Demuxer
|
||||
|
||||
``--demuxer-readahead-secs=<seconds>``
|
||||
If ``--demuxer-thread`` is enabled, this controls how much the demuxer
|
||||
should buffer ahead in seconds (default: 1). As long as no packet has
|
||||
should buffer ahead in seconds (default: 0.2). As long as no packet has
|
||||
a timestamp difference higher than the readahead amount relative to the
|
||||
last packet returned to the decoder, the demuxer keeps reading.
|
||||
|
||||
Note that the ``--cache-secs`` option will override this value if a cache
|
||||
is enabled, and the value is larger.
|
||||
|
||||
(This value tends to be fuzzy, because many file formats don't store linear
|
||||
timestamps.)
|
||||
|
||||
@@ -2248,9 +2218,6 @@ Input
|
||||
get replies or events. Use ``--input-unix-socket`` for something
|
||||
bi-directional. On MS Windows, JSON commands are not available.
|
||||
|
||||
This can also specify a direct file descriptor with ``fd://N`` (UNIX only).
|
||||
In this case, JSON replies will be written if the FD is writable.
|
||||
|
||||
See also ``--slave-broken``.
|
||||
|
||||
.. note::
|
||||
@@ -2283,6 +2250,19 @@ Input
|
||||
driver. Necessary to use the OSC, or to select the buttons in DVD menus.
|
||||
Support depends on the VO in use.
|
||||
|
||||
``--input-joystick``, ``--no-input-joystick``
|
||||
Enable/disable joystick support. Disabled by default.
|
||||
|
||||
``--input-js-dev``
|
||||
Specifies the joystick device to use (default: ``/dev/input/js0``).
|
||||
|
||||
``--input-lirc``, ``--no-input-lirc``
|
||||
Enable/disable LIRC support. Enabled by default.
|
||||
|
||||
``--input-lirc-conf=<filename>``
|
||||
(LIRC only)
|
||||
Specifies a configuration file for LIRC (default: ``~/.lircrc``).
|
||||
|
||||
``--input-media-keys=<yes|no>``
|
||||
(OS X only)
|
||||
Enable/disable media keys support. Enabled by default (except for libmpv).
|
||||
@@ -2294,7 +2274,7 @@ Input
|
||||
|
||||
``--input-vo-keyboard=<yes|no>``
|
||||
Disable all keyboard input on for VOs which can't participate in proper
|
||||
keyboard input dispatching. May not affect all VOs. Generally useful for
|
||||
keyboard input dispatching. This currently affects X11. Generally useful for
|
||||
embedding only.
|
||||
|
||||
On X11, a sub-window with input enabled grabs all keyboard input as long
|
||||
@@ -2306,14 +2286,11 @@ Input
|
||||
behavior, but naively embedding foreign windows breaks it.
|
||||
|
||||
The only way to handle this reasonably is using the XEmbed protocol, which
|
||||
was designed to solve these problems. GTK provides ``GtkSocket``, which
|
||||
supports XEmbed. Qt doesn't seem to provide anything working in newer
|
||||
versions.
|
||||
was designed to solve these problems. But Qt has questionable support, and
|
||||
mpv doesn't implement it yet.
|
||||
|
||||
If the embedder supports XEmbed, input should work with default settings
|
||||
and with this option disabled. Note that ``input-default-bindings`` is
|
||||
disabled by default in libmpv as well - it should be enabled if you want
|
||||
the mpv default key bindings.
|
||||
As a workaround, this option is disabled by default in libmpv. (Note that
|
||||
``input-default-bindings`` is disabled by default in libmpv as well.)
|
||||
|
||||
(This option was renamed from ``--input-x11-keyboard``.)
|
||||
|
||||
@@ -2421,9 +2398,6 @@ OSD
|
||||
``--osd-blur=<0..20.0>``, ``--sub-text-blur=<0..20.0>``
|
||||
Gaussian blur factor. 0 means no blur applied (default).
|
||||
|
||||
``--osd-bold=<yes|no>``, ``--sub-text-bold=<yes|no>``
|
||||
Format text on bold.
|
||||
|
||||
``--osd-border-color=<color>``, ``--sub-text-border-color=<color>``
|
||||
See ``--osd-color``. Color used for the OSD/sub font border.
|
||||
|
||||
@@ -2460,7 +2434,7 @@ OSD
|
||||
Alternatively, the color can be specified as a RGB hex triplet in the form
|
||||
``#RRGGBB``, where each 2-digit group expresses a color value in the
|
||||
range 0 (``00``) to 255 (``FF``). For example, ``#FF0000`` is red.
|
||||
This is similar to web colors. Alpha is given with ``#AARRGGBB``.
|
||||
This is similar to web colors.
|
||||
|
||||
.. admonition:: Examples
|
||||
|
||||
@@ -2468,8 +2442,7 @@ OSD
|
||||
- ``--osd-color='#C0808080'`` set OSD to 50% gray with 75% alpha
|
||||
|
||||
``--osd-fractions``
|
||||
Show OSD times with fractions of seconds (in millisecond precision). Useful
|
||||
to see the exact timestamp of a video frame.
|
||||
Show OSD times with fractions of seconds.
|
||||
|
||||
``--osd-level=<0-3>``
|
||||
Specifies which mode the OSD should start in.
|
||||
@@ -2498,17 +2471,6 @@ OSD
|
||||
|
||||
Default: 22.
|
||||
|
||||
``--osd-align-x=<left|center|right>``, ``--sub-text-align-x=...``
|
||||
Control to which corner of the screen OSD or text subtitles should be
|
||||
aligned to (default: ``center`` for subs, ``left`` for OSD).
|
||||
|
||||
Never applied to ASS subtitles, except in ``--no-sub-ass`` mode. Likewise,
|
||||
this does not apply to image subtitles.
|
||||
|
||||
``--osd-align-y=<top|center|bottom>`` ``--sub-text-align-y=...``
|
||||
Vertical position (default: ``bottom`` for subs, ``top`` for OSD).
|
||||
Details see ``--osd-align-x``.
|
||||
|
||||
``--osd-scale=<factor>``
|
||||
OSD font size multiplier, multiplied with ``--osd-font-size`` value.
|
||||
|
||||
@@ -2561,13 +2523,6 @@ Screenshot
|
||||
:jpg: JPEG (default)
|
||||
:jpeg: JPEG (same as jpg, but with .jpeg file ending)
|
||||
|
||||
``--screenshot-tag-colorspace=<yes|no>``
|
||||
Tag screenshots with the appropriate colorspace.
|
||||
|
||||
Note that not all formats are supported.
|
||||
|
||||
Default: ``yes``.
|
||||
|
||||
``--screenshot-template=<template>``
|
||||
Specify the filename template used to save screenshots. The template
|
||||
specifies the filename without file extension, and can contain format
|
||||
@@ -2726,7 +2681,7 @@ Terminal
|
||||
``--no-msg-color``
|
||||
Disable colorful console output on terminals.
|
||||
|
||||
``--msg-level=<module1=level1,module2=level2,...>``
|
||||
``--msg-level=<module1=level1:module2=level2:...>``
|
||||
Control verbosity directly for each module. The ``all`` module changes the
|
||||
verbosity of all the modules not explicitly specified on the command line.
|
||||
|
||||
@@ -2866,7 +2821,7 @@ TV
|
||||
Use _ for spaces in names (or play with quoting ;-) ). The channel
|
||||
names will then be written using OSD, and the slave commands
|
||||
``tv_step_channel``, ``tv_set_channel`` and ``tv_last_channel``
|
||||
will be usable for a remote control. Not compatible with
|
||||
will be usable for a remote control (see LIRC). Not compatible with
|
||||
the ``frequency`` parameter.
|
||||
|
||||
.. note::
|
||||
@@ -2975,13 +2930,11 @@ TV
|
||||
Cache
|
||||
-----
|
||||
|
||||
``--cache=<kBytes|yes|no|auto>``
|
||||
``--cache=<kBytes|no|auto>``
|
||||
Set the size of the cache in kilobytes, disable it with ``no``, or
|
||||
automatically enable it if needed with ``auto`` (default: ``auto``).
|
||||
With ``auto``, the cache will usually be enabled for network streams,
|
||||
using the size set by ``--cache-default``. With ``yes``, the cache will
|
||||
always be enabled with the size set by ``--cache-default`` (unless the
|
||||
stream can not be cached, or ``--cache-default`` disables caching).
|
||||
using the size set by ``--cache-default``.
|
||||
|
||||
May be useful when playing files from slow media, but can also have
|
||||
negative effects, especially with file formats that require a lot of
|
||||
@@ -2994,7 +2947,7 @@ Cache
|
||||
because no space is reserved for seeking back yet.
|
||||
|
||||
``--cache-default=<kBytes|no>``
|
||||
Set the size of the cache in kilobytes (default: 150000 KB). Using ``no``
|
||||
Set the size of the cache in kilobytes (default: 25000 KB). Using ``no``
|
||||
will not automatically enable the cache e.g. when playing from a network
|
||||
stream. Note that using ``--cache`` will always override this option.
|
||||
|
||||
@@ -3067,7 +3020,7 @@ Cache
|
||||
``--cache-secs=<seconds>``
|
||||
How many seconds of audio/video to prefetch if the cache is active. This
|
||||
overrides the ``--demuxer-readahead-secs`` option if and only if the cache
|
||||
is enabled and the value is larger. (Default: 10.)
|
||||
is enabled. (Default: 2.)
|
||||
|
||||
``--cache-pause``, ``--no-cache-pause``
|
||||
Whether the player should automatically pause when the cache runs low,
|
||||
@@ -3118,11 +3071,6 @@ Network
|
||||
``--referrer=<string>``
|
||||
Specify a referrer path or URL for HTTP requests.
|
||||
|
||||
``--network-timeout=<seconds>``
|
||||
Specify the network timeout in seconds. This affects at least HTTP. The
|
||||
special value 0 (default) uses the FFmpeg/Libav defaults. If a protocol
|
||||
is used which does not support timeouts, this option is silently ignored.
|
||||
|
||||
``--rtsp-transport=<lavf|udp|tcp|http>``
|
||||
Select RTSP transport method (default: tcp). This selects the underlying
|
||||
network transport when playing ``rtsp://...`` URLs. The value ``lavf``
|
||||
@@ -3133,9 +3081,9 @@ Network
|
||||
by default. The option allows the following parameters:
|
||||
|
||||
:no: Don't do anything special. Typically, this will simply pick the
|
||||
first audio/video streams it can find.
|
||||
first audio/video streams it can find. (Default.)
|
||||
:min: Pick the streams with the lowest bitrate.
|
||||
:max: Same, but highest bitrate. (Default.)
|
||||
:max: Same, but highest bitrate.
|
||||
|
||||
The bitrate as used is sent by the server, and there's no guarantee it's
|
||||
actually meaningful.
|
||||
@@ -3151,28 +3099,11 @@ DVB
|
||||
in the mpv configuration directory (usually ``~/.config/mpv``) with the
|
||||
filename ``channels.conf.{sat,ter,cbl,atsc}`` (based on your card type) or
|
||||
``channels.conf`` as a last resort.
|
||||
For DVB-S/2 cards, a VDR 1.7.x format channel list is recommended
|
||||
as it allows tuning to DVB-S2 channels, enabling subtitles and
|
||||
decoding the PMT (which largely improves the demuxing).
|
||||
Classic mplayer format channel lists are still supported (without
|
||||
these improvements), and for other card types, only limited VDR
|
||||
format channel list support is implemented (patches welcome).
|
||||
For channels with dynamic PID switching or incomplete
|
||||
``channels.conf``, ``--dvbin-full-transponder`` or the magic PID
|
||||
``8192`` are recommended.
|
||||
|
||||
``--dvbin-timeout=<1-30>``
|
||||
Maximum number of seconds to wait when trying to tune a frequency before
|
||||
giving up (default: 30).
|
||||
|
||||
``--dvbin-full-transponder=<yes|no>``
|
||||
Apply no filters on program PIDs, only tune to frequency and pass full
|
||||
transponder to demuxer. This is useful to record multiple programs
|
||||
on a single transponder, or to work around issues in the ``channels.conf``.
|
||||
It is also recommended to use this for channels which switch PIDs
|
||||
on-the-fly, e.g. for regional news.
|
||||
|
||||
Default: ``no``
|
||||
|
||||
PVR
|
||||
---
|
||||
@@ -3236,32 +3167,9 @@ PVR
|
||||
Miscellaneous
|
||||
-------------
|
||||
|
||||
``--display-tags=tag1,tags2,...``
|
||||
Set the list of tags that should be displayed on the terminal. Tags that
|
||||
are in the list, but are not present in the played file, will not be shown.
|
||||
If a value ends with ``*``, all tags are matched by prefix (though there
|
||||
is no general globbing). Just passing ``*`` essentially filtering.
|
||||
|
||||
The default includes a common list of tags, call mpv with ``--list-options``
|
||||
to see it.
|
||||
|
||||
``--mc=<seconds/frame>``
|
||||
Maximum A-V sync correction per frame (in seconds)
|
||||
|
||||
``--autosync=<factor>``
|
||||
Gradually adjusts the A/V sync based on audio delay measurements.
|
||||
Specifying ``--autosync=0``, the default, will cause frame timing to be
|
||||
based entirely on audio delay measurements. Specifying ``--autosync=1``
|
||||
will do the same, but will subtly change the A/V correction algorithm. An
|
||||
uneven video framerate in a video which plays fine with ``--no-audio`` can
|
||||
often be helped by setting this to an integer value greater than 1. The
|
||||
higher the value, the closer the timing will be to ``--no-audio``. Try
|
||||
``--autosync=30`` to smooth out problems with sound drivers which do not
|
||||
implement a perfect audio delay measurement. With this value, if large A/V
|
||||
sync offsets occur, they will only take about 1 or 2 seconds to settle
|
||||
out. This delay in reaction time to sudden A/V offsets should be the only
|
||||
side-effect of turning this option on, for all sound drivers.
|
||||
|
||||
``--mf-fps=<value>``
|
||||
Framerate used when decoding from multiple PNG or JPEG files with ``mf://``
|
||||
(default: 1).
|
||||
@@ -3279,9 +3187,6 @@ Miscellaneous
|
||||
interrupted. Note that, due to cache latencies, captured data may begin and
|
||||
end somewhat delayed compared to what you see displayed.
|
||||
|
||||
The destination file is always appended. (Before mpv 0.8.0, the file was
|
||||
overwritten.)
|
||||
|
||||
``--stream-dump=<filename>``
|
||||
Same as ``--stream-capture``, but do not start playback. Instead, the entire
|
||||
file is dumped.
|
||||
|
||||
+16
-22
@@ -127,7 +127,7 @@ Key Bindings
|
||||
|
||||
These key bindings are active by default if nothing else is already bound to
|
||||
these keys. In case of collision, the function needs to be bound to a
|
||||
different key. See the `Script Commands`_ section.
|
||||
different key. See `Script Commands`_ section.
|
||||
|
||||
============= ================================================
|
||||
del Hide the OSC permanently until mpv is restarted.
|
||||
@@ -138,7 +138,7 @@ Configuration
|
||||
|
||||
The OSC offers limited configuration through a config file
|
||||
``lua-settings/osc.conf`` placed in mpv's user dir and through the
|
||||
``--script-opts`` command-line option. Options provided through the command-line
|
||||
``--lua-opts`` command-line option. Options provided through the command-line
|
||||
will override those from the config file.
|
||||
|
||||
Config Syntax
|
||||
@@ -161,7 +161,7 @@ To avoid collisions with other scripts, all options need to be prefixed with
|
||||
|
||||
Example::
|
||||
|
||||
--script-opts=osc-optionA=value1,osc-optionB=value2
|
||||
--lua-opts=osc-optionA=value1,osc-optionB=value2
|
||||
|
||||
|
||||
Configurable Options
|
||||
@@ -169,35 +169,34 @@ Configurable Options
|
||||
|
||||
``showwindowed``
|
||||
| Default: yes
|
||||
| Enable the OSC when windowed
|
||||
| Show OSC when windowed?
|
||||
|
||||
``showfullscreen``
|
||||
| Default: yes
|
||||
| Enable the OSC when fullscreen
|
||||
| Show OSC when fullscreen?
|
||||
|
||||
``scalewindowed``
|
||||
| Default: 1.0
|
||||
| Scale factor of the OSC when windowed
|
||||
| Default: 1
|
||||
| Scaling of the controller when windowed
|
||||
|
||||
``scalefullscreen``
|
||||
| Default: 1.0
|
||||
| Scale factor of the OSC when fullscreen
|
||||
| Default: 1
|
||||
| Scaling of the controller when fullscreen
|
||||
|
||||
``scaleforcedwindow``
|
||||
| Default: 2.0
|
||||
| Scale factor of the OSC when rendered on a forced (dummy) window
|
||||
| Default: 2
|
||||
| Scaling of the controller when rendered on a forced (dummy) window
|
||||
|
||||
``vidscale``
|
||||
| Default: yes
|
||||
| Scale the OSC with the video
|
||||
| ``no`` tries to keep the OSC size constant as much as the window size allows
|
||||
| Scale the controller with the video?
|
||||
|
||||
``valign``
|
||||
| Default: 0.8
|
||||
| Vertical alignment, -1 (top) to 1 (bottom)
|
||||
|
||||
``halign``
|
||||
| Default: 0.0
|
||||
| Default: 0
|
||||
| Horizontal alignment, -1 (left) to 1 (right)
|
||||
|
||||
``boxalpha``
|
||||
@@ -226,10 +225,9 @@ Configurable Options
|
||||
| Minimum amount of pixels the mouse has to move between ticks to make
|
||||
the OSC show up
|
||||
|
||||
``layout``
|
||||
| Default: box
|
||||
| The layout for the OSC. Currently available are: box, slimbox,
|
||||
bottombar and topbar.
|
||||
``seektooltip``
|
||||
| Default: yes
|
||||
| Display a tooltip over the seekbar indicating time at mouse position.
|
||||
|
||||
``seekbarstyle``
|
||||
| Default: slider
|
||||
@@ -247,10 +245,6 @@ in ``input.conf``, or sent by other scripts.
|
||||
``disable-osc``
|
||||
Hide the OSC permanently. This is also what the ``del`` key does.
|
||||
|
||||
``osc-message``
|
||||
Show a message on screen using the OSC. First argument is the message,
|
||||
second the duration in seconds.
|
||||
|
||||
|
||||
Example
|
||||
|
||||
|
||||
+306
-175
@@ -143,8 +143,8 @@ Available filters are:
|
||||
Accurate rounding for the vertical scaler, which may be faster or
|
||||
slower than the default rounding.
|
||||
|
||||
:no: Disable accurate rounding (default).
|
||||
:yes: Enable accurate rounding.
|
||||
:0: Disable accurate rounding (default).
|
||||
:1: Enable accurate rounding.
|
||||
|
||||
``dsize[=w:h:aspect-method:r:aspect]``
|
||||
Changes the intended display size/aspect at an arbitrary point in the
|
||||
@@ -198,7 +198,7 @@ Available filters are:
|
||||
``<aspect>``
|
||||
Force an aspect ratio.
|
||||
|
||||
``format=fmt=<value>:colormatrix=<value>:...``
|
||||
``format[=fmt[:outfmt]]``
|
||||
Restricts the color space for the next filter without doing any conversion.
|
||||
Use together with the scale filter for a real conversion.
|
||||
|
||||
@@ -207,148 +207,19 @@ Available filters are:
|
||||
For a list of available formats, see ``format=fmt=help``.
|
||||
|
||||
``<fmt>``
|
||||
Format name, e.g. rgb15, bgr24, 420p, etc. (default: don't change).
|
||||
Format name, e.g. rgb15, bgr24, 420p, etc. (default: yuyv).
|
||||
``<outfmt>``
|
||||
Format name that should be substituted for the output. If they do not
|
||||
have the same bytes per pixel and chroma subsamplimg, it will fail.
|
||||
``<colormatrix>``
|
||||
Controls the YUV to RGB color space conversion when playing video. There
|
||||
are various standards. Normally, BT.601 should be used for SD video, and
|
||||
BT.709 for HD video. (This is done by default.) Using incorrect color space
|
||||
results in slightly under or over saturated and shifted colors.
|
||||
Format name that should be substituted for the output. If this is not
|
||||
100% compatible with the ``<fmt>`` value, it will crash.
|
||||
|
||||
These options are not always supported. Different video outputs provide
|
||||
varying degrees of support. The ``opengl`` and ``vdpau`` video output
|
||||
drivers usually offer full support. The ``xv`` output can set the color
|
||||
space if the system video driver supports it, but not input and output
|
||||
levels. The ``scale`` video filter can configure color space and input
|
||||
levels, but only if the output format is RGB (if the video output driver
|
||||
supports RGB output, you can force this with ``-vf scale,format=rgba``).
|
||||
|
||||
If this option is set to ``auto`` (which is the default), the video's
|
||||
color space flag will be used. If that flag is unset, the color space
|
||||
will be selected automatically. This is done using a simple heuristic that
|
||||
attempts to distinguish SD and HD video. If the video is larger than
|
||||
1279x576 pixels, BT.709 (HD) will be used; otherwise BT.601 (SD) is
|
||||
selected.
|
||||
|
||||
Available color spaces are:
|
||||
|
||||
:auto: automatic selection (default)
|
||||
:bt.601: ITU-R BT.601 (SD)
|
||||
:bt.709: ITU-R BT.709 (HD)
|
||||
:bt.2020-ncl: ITU-R BT.2020 non-constant luminance system
|
||||
:bt.2020-cl: ITU-R BT.2020 constant luminance system
|
||||
:smpte-240m: SMPTE-240M
|
||||
|
||||
``<colorlevels>``
|
||||
YUV color levels used with YUV to RGB conversion. This option is only
|
||||
necessary when playing broken files which do not follow standard color
|
||||
levels or which are flagged wrong. If the video does not specify its
|
||||
color range, it is assumed to be limited range.
|
||||
|
||||
The same limitations as with ``<colormatrix>`` apply.
|
||||
|
||||
Available color ranges are:
|
||||
|
||||
:auto: automatic selection (normally limited range) (default)
|
||||
:limited: limited range (16-235 for luma, 16-240 for chroma)
|
||||
:full: full range (0-255 for both luma and chroma)
|
||||
|
||||
``<outputlevels>``
|
||||
RGB color levels used with YUV to RGB conversion. Normally, output devices
|
||||
such as PC monitors use full range color levels. However, some TVs and
|
||||
video monitors expect studio RGB levels. Providing full range output to a
|
||||
device expecting studio level input results in crushed blacks and whites,
|
||||
the reverse in dim gray blacks and dim whites.
|
||||
|
||||
The same limitations as with ``<colormatrix>`` apply.
|
||||
|
||||
Available color ranges are:
|
||||
|
||||
:auto: automatic selection (equals to full range) (default)
|
||||
:limited: limited range (16-235 per component), studio levels
|
||||
:full: full range (0-255 per component), PC levels
|
||||
|
||||
.. note::
|
||||
|
||||
It is advisable to use your graphics driver's color range option
|
||||
instead, if available.
|
||||
|
||||
``<primaries>``
|
||||
RGB primaries the source file was encoded with. Normally this should be set
|
||||
in the file header, but when playing broken or mistagged files this can be
|
||||
used to override the setting.
|
||||
|
||||
This option only affects video output drivers that perform color
|
||||
management, for example ``opengl`` with the ``target-prim`` or
|
||||
``icc-profile`` suboptions set.
|
||||
|
||||
If this option is set to ``auto`` (which is the default), the video's
|
||||
primaries flag will be used. If that flag is unset, the color space will
|
||||
be selected automatically, using the following heuristics: If the
|
||||
``<colormatrix>`` is set or determined as BT.2020 or BT.709, the
|
||||
corresponding primaries are used. Otherwise, if the video height is
|
||||
exactly 576 (PAL), BT.601-625 is used. If it's exactly 480 or 486 (NTSC),
|
||||
BT.601-525 is used. If the video resolution is anything else, BT.709 is
|
||||
used.
|
||||
|
||||
Available primaries are:
|
||||
|
||||
:auto: automatic selection (default)
|
||||
:bt.601-525: ITU-R BT.601 (SD) 525-line systems (NTSC, SMPTE-C)
|
||||
:bt.601-625: ITU-R BT.601 (SD) 625-line systems (PAL, SECAM)
|
||||
:bt.709: ITU-R BT.709 (HD) (same primaries as sRGB)
|
||||
:bt.2020: ITU-R BT.2020 (UHD)
|
||||
:apple: Apple RGB
|
||||
:adobe: Adobe RGB (1998)
|
||||
:prophoto: ProPhoto RGB (ROMM)
|
||||
:cie1931: CIE 1931 RGB
|
||||
|
||||
``<gamma>``
|
||||
Gamma function the source file was encoded with. Normally this should be set
|
||||
in the file header, but when playing broken or mistagged files this can be
|
||||
used to override the setting.
|
||||
|
||||
This option only affects video output drivers that perform color management.
|
||||
|
||||
If this option is set to ``auto`` (which is the default), the gamma will
|
||||
be set to BT.1886 for YCbCr content, sRGB for RGB content and Linear for
|
||||
XYZ content.
|
||||
|
||||
Available gamma functions are:
|
||||
|
||||
:auto: automatic selection (default)
|
||||
:bt.1886: ITU-R BT.1886 (approximation of BT.601/BT.709/BT.2020 curve)
|
||||
:srgb: IEC 61966-2-4 (sRGB)
|
||||
:linear: Linear light
|
||||
:gamma1.8: Pure power curve (gamma 1.8)
|
||||
:gamma2.2: Pure power curve (gamma 2.2)
|
||||
:gamma2.8: Pure power curve (gamma 2.8)
|
||||
:prophoto: ProPhoto RGB (ROMM) curve
|
||||
|
||||
``<stereo-in>``
|
||||
Set the stereo mode the video is assumed to be encoded in. Takes the
|
||||
same values as the ``--video-stereo-mode`` option.
|
||||
|
||||
``<stereo-out>``
|
||||
Set the stereo mode the video should be displayed as. Takes the
|
||||
same values as the ``--video-stereo-mode`` option.
|
||||
|
||||
``<rotate>``
|
||||
Set the rotation the video is assumed to be encoded with in degrees.
|
||||
The special value ``-1`` uses the input format.
|
||||
|
||||
``<dw>``, ``<dh>``
|
||||
Set the display size. Note that setting the display size such that
|
||||
the video is scaled in both directions instead of just changing the
|
||||
aspect ratio is an implementation detail, and might change later.
|
||||
|
||||
``<dar>``
|
||||
Set the display aspect ratio of the video frame. This is a float,
|
||||
but values such as ``[16:9]`` can be passed too (``[...]`` for quoting
|
||||
to prevent the option parser from interpreting the ``:`` character).
|
||||
.. admonition:: Examples
|
||||
|
||||
====================== =====================
|
||||
Valid Invalid (will crash)
|
||||
====================== =====================
|
||||
``format=rgb24:bgr24`` ``format=rgb24:420p``
|
||||
``format=yuyv:uyvy``
|
||||
====================== =====================
|
||||
|
||||
``noformat[=fmt]``
|
||||
Restricts the color space for the next filter without doing any conversion.
|
||||
@@ -360,6 +231,156 @@ Available filters are:
|
||||
``<fmt>``
|
||||
Format name, e.g. rgb15, bgr24, 420p, etc. (default: 420p).
|
||||
|
||||
``pp=[filter string]``
|
||||
Enables the specified chain of post-processing subfilters. Subfilters must
|
||||
be separated by '/' and can be disabled by prepending a '-'. Each
|
||||
subfilter and some options have a short and a long name that can be used
|
||||
interchangeably, i.e. ``dr``/``dering`` are the same.
|
||||
|
||||
.. note::
|
||||
|
||||
Unlike in MPlayer or in earlier versions, you must quote the pp string
|
||||
if it contains ``:`` characters, e.g. ``'--vf=pp=[...]'``.
|
||||
|
||||
.. admonition:: Warning
|
||||
|
||||
This filter is most likely useless on modern HD video. It might be
|
||||
helpful with old low-resolution files.
|
||||
|
||||
All subfilters share common options to determine their scope:
|
||||
|
||||
``a/autoq``
|
||||
Automatically switch the subfilter off if the CPU is too slow.
|
||||
``c/chrom``
|
||||
Do chrominance filtering, too (default).
|
||||
``y/nochrom``
|
||||
Do luminance filtering only (no chrominance).
|
||||
``n/noluma``
|
||||
Do chrominance filtering only (no luminance).
|
||||
|
||||
.. note::
|
||||
|
||||
``--vf=pp:help`` shows a list of available subfilters.
|
||||
|
||||
Available subfilters are:
|
||||
|
||||
``hb/hdeblock[:difference[:flatness]]``
|
||||
horizontal deblocking filter
|
||||
|
||||
:<difference>: Difference factor where higher values mean more
|
||||
deblocking (default: 32).
|
||||
:<flatness>: Flatness threshold where lower values mean more
|
||||
deblocking (default: 39).
|
||||
|
||||
``vb/vdeblock[:difference[:flatness]]``
|
||||
vertical deblocking filter
|
||||
|
||||
:<difference>: Difference factor where higher values mean more
|
||||
deblocking (default: 32).
|
||||
:<flatness>: Flatness threshold where lower values mean more
|
||||
deblocking (default: 39).
|
||||
|
||||
``ha/hadeblock[:difference[:flatness]]``
|
||||
accurate horizontal deblocking filter
|
||||
|
||||
:<difference>: Difference factor where higher values mean more
|
||||
deblocking (default: 32).
|
||||
:<flatness>: Flatness threshold where lower values mean more
|
||||
deblocking (default: 39).
|
||||
|
||||
``va/vadeblock[:difference[:flatness]]``
|
||||
accurate vertical deblocking filter
|
||||
|
||||
:<difference>: Difference factor where higher values mean more
|
||||
deblocking (default: 32).
|
||||
:<flatness>: Flatness threshold where lower values mean more
|
||||
deblocking (default: 39).
|
||||
|
||||
The horizontal and vertical deblocking filters share the difference and
|
||||
flatness values so you cannot set different horizontal and vertical
|
||||
thresholds.
|
||||
|
||||
``h1/x1hdeblock``
|
||||
experimental horizontal deblocking filter
|
||||
|
||||
``v1/x1vdeblock``
|
||||
experimental vertical deblocking filter
|
||||
|
||||
``dr/dering``
|
||||
deringing filter
|
||||
|
||||
``tn/tmpnoise[:threshold1[:threshold2[:threshold3]]]``
|
||||
temporal noise reducer
|
||||
|
||||
:<threshold1>: larger -> stronger filtering
|
||||
:<threshold2>: larger -> stronger filtering
|
||||
:<threshold3>: larger -> stronger filtering
|
||||
|
||||
``al/autolevels[:f/fullyrange]``
|
||||
automatic brightness / contrast correction
|
||||
|
||||
:f/fullyrange: Stretch luminance to (0-255).
|
||||
|
||||
``lb/linblenddeint``
|
||||
Linear blend deinterlacing filter that deinterlaces the given block by
|
||||
filtering all lines with a (1 2 1) filter.
|
||||
|
||||
``li/linipoldeint``
|
||||
Linear interpolating deinterlacing filter that deinterlaces the given
|
||||
block by linearly interpolating every second line.
|
||||
|
||||
``ci/cubicipoldeint``
|
||||
Cubic interpolating deinterlacing filter deinterlaces the given block
|
||||
by cubically interpolating every second line.
|
||||
|
||||
``md/mediandeint``
|
||||
Median deinterlacing filter that deinterlaces the given block by
|
||||
applying a median filter to every second line.
|
||||
|
||||
``fd/ffmpegdeint``
|
||||
FFmpeg deinterlacing filter that deinterlaces the given block by
|
||||
filtering every second line with a (-1 4 2 4 -1) filter.
|
||||
|
||||
``l5/lowpass5``
|
||||
Vertically applied FIR low-pass deinterlacing filter that deinterlaces
|
||||
the given block by filtering all lines with a (-1 2 6 2 -1) filter.
|
||||
|
||||
``fq/forceQuant[:quantizer]``
|
||||
Overrides the quantizer table from the input with the constant
|
||||
quantizer you specify.
|
||||
|
||||
:<quantizer>: quantizer to use
|
||||
|
||||
``de/default``
|
||||
default pp filter combination (hb:a,vb:a,dr:a)
|
||||
|
||||
``fa/fast``
|
||||
fast pp filter combination (h1:a,v1:a,dr:a)
|
||||
|
||||
``ac``
|
||||
high quality pp filter combination (ha:a:128:7,va:a,dr:a)
|
||||
|
||||
.. note::
|
||||
|
||||
This filter is only available if FFmpeg/Libav has been compiled
|
||||
with libpostproc enabled.
|
||||
|
||||
.. admonition:: Examples
|
||||
|
||||
``--vf=pp=hb/vb/dr/al``
|
||||
horizontal and vertical deblocking, deringing and automatic
|
||||
brightness/contrast
|
||||
|
||||
``--vf=pp=de/-al``
|
||||
default filters without brightness/contrast correction
|
||||
|
||||
``--vf=pp=[default/tmpnoise:1:2:3]``
|
||||
Enable default filters & temporal denoiser.
|
||||
|
||||
``--vf=pp=[hb:y/vb:a]``
|
||||
Horizontal deblocking on luminance only, and switch vertical
|
||||
deblocking on or off automatically depending on available CPU time.
|
||||
|
||||
``lavfi=graph[:sws-flags[:o=opts]]``
|
||||
Filter video using FFmpeg's libavfilter.
|
||||
|
||||
@@ -430,6 +451,10 @@ Available filters are:
|
||||
``uniform``
|
||||
uniform noise (Gaussian otherwise)
|
||||
|
||||
``hq``
|
||||
high quality (slightly better looking, slightly slower) - not available
|
||||
when using libavfilter
|
||||
|
||||
``hqdn3d[=luma_spatial:chroma_spatial:luma_tmp:chroma_tmp]``
|
||||
This filter aims to reduce image noise producing smooth images and making
|
||||
still images really still (This should enhance compressibility.).
|
||||
@@ -470,6 +495,19 @@ Available filters are:
|
||||
and just plain white. A value of 0.0 turns the gamma correction all
|
||||
the way down while 1.0 leaves it at its full strength (default: 1.0).
|
||||
|
||||
``ilpack[=mode]``
|
||||
When interlaced video is stored in YUV 4:2:0 formats, chroma interlacing
|
||||
does not line up properly due to vertical downsampling of the chroma
|
||||
channels. This filter packs the planar 4:2:0 data into YUY2 (4:2:2) format
|
||||
with the chroma lines in their proper locations, so that in any given
|
||||
scanline, the luma and chroma data both come from the same field.
|
||||
|
||||
``<mode>``
|
||||
Select the sampling mode.
|
||||
|
||||
:0: nearest-neighbor sampling, fast but incorrect
|
||||
:1: linear interpolation (default)
|
||||
|
||||
``unsharp[=lx:ly:la:cx:cy:ca]``
|
||||
unsharp mask / Gaussian blur
|
||||
|
||||
@@ -487,6 +525,9 @@ Available filters are:
|
||||
:<0: blur
|
||||
:>0: sharpen
|
||||
|
||||
``swapuv``
|
||||
Swap U & V plane.
|
||||
|
||||
``pullup[=jl:jr:jt:jb:sb:mp]``
|
||||
Pulldown reversal (inverse telecine) filter, capable of handling mixed
|
||||
hard-telecine, 24000/1001 fps progressive, and 30000/1001 fps progressive
|
||||
@@ -518,6 +559,120 @@ Available filters are:
|
||||
video. The main purpose of setting ``mp`` to a chroma plane is to reduce
|
||||
CPU load and make pullup usable in realtime on slow machines.
|
||||
|
||||
``divtc[=options]``
|
||||
Inverse telecine for deinterlaced video. If 3:2-pulldown telecined video
|
||||
has lost one of the fields or is deinterlaced using a method that keeps
|
||||
one field and interpolates the other, the result is a juddering video that
|
||||
has every fourth frame duplicated. This filter is intended to find and
|
||||
drop those duplicates and restore the original film framerate. Two
|
||||
different modes are available: One-pass mode is the default and is
|
||||
straightforward to use, but has the disadvantage that any changes in the
|
||||
telecine phase (lost frames or bad edits) cause momentary judder until the
|
||||
filter can resync again. Two-pass mode avoids this by analyzing the entire
|
||||
video beforehand so it will have forward knowledge about the phase changes
|
||||
and can resync at the exact spot. These passes do *not* correspond to pass
|
||||
one and two of the encoding process. You must run an extra pass using
|
||||
``divtc`` pass one before the actual encoding throwing the resulting video
|
||||
away. Then use ``divtc`` pass two for the actual encoding. If you use
|
||||
multiple encoder passes, use ``divtc`` pass two for all of them.
|
||||
|
||||
The options are:
|
||||
|
||||
``pass=1|2``
|
||||
Use two pass mode.
|
||||
|
||||
``file=<filename>``
|
||||
Set the two pass log filename (default: ``framediff.log``).
|
||||
|
||||
``threshold=<value>``
|
||||
Set the minimum strength the telecine pattern must have for the filter
|
||||
to believe in it (default: 0.5). This is used to avoid recognizing
|
||||
false pattern from the parts of the video that are very dark or very
|
||||
still.
|
||||
|
||||
``window=<numframes>``
|
||||
Set the number of past frames to look at when searching for pattern
|
||||
(default: 30). Longer window improves the reliability of the pattern
|
||||
search, but shorter window improves the reaction time to the changes
|
||||
in the telecine phase. This only affects the one-pass mode. The
|
||||
two-pass mode currently uses fixed window that extends to both future
|
||||
and past.
|
||||
|
||||
``phase=0|1|2|3|4``
|
||||
Sets the initial telecine phase for one pass mode (default: 0). The
|
||||
two-pass mode can see the future, so it is able to use the correct
|
||||
phase from the beginning, but one-pass mode can only guess. It catches
|
||||
the correct phase when it finds it, but this option can be used to fix
|
||||
the possible juddering at the beginning. The first pass of the two
|
||||
pass mode also uses this, so if you save the output from the first
|
||||
pass, you get constant phase result.
|
||||
|
||||
``deghost=<value>``
|
||||
Set the deghosting threshold (0-255 for one-pass mode, -255-255 for
|
||||
two-pass mode, default 0). If nonzero, deghosting mode is used. This
|
||||
is for video that has been deinterlaced by blending the fields
|
||||
together instead of dropping one of the fields. Deghosting amplifies
|
||||
any compression artifacts in the blended frames, so the parameter
|
||||
value is used as a threshold to exclude those pixels from deghosting
|
||||
that differ from the previous frame less than specified value. If two
|
||||
pass mode is used, then negative value can be used to make the filter
|
||||
analyze the whole video in the beginning of pass-2 to determine
|
||||
whether it needs deghosting or not and then select either zero or the
|
||||
absolute value of the parameter. Specify this option for pass 2, it
|
||||
makes no difference on pass 1.
|
||||
|
||||
``phase[=t|b|p|a|u|T|B|A|U][:v]``
|
||||
Delay interlaced video by one field time so that the field order changes.
|
||||
The intended use is to fix PAL videos that have been captured with the
|
||||
opposite field order to the film-to-video transfer. The options are:
|
||||
|
||||
``t``
|
||||
Capture field order top-first, transfer bottom-first. Filter will
|
||||
delay the bottom field.
|
||||
|
||||
``b``
|
||||
Capture bottom-first, transfer top-first. Filter will delay the top
|
||||
field.
|
||||
|
||||
``p``
|
||||
Capture and transfer with the same field order. This mode only exists
|
||||
for the documentation of the other options to refer to, but if you
|
||||
actually select it, the filter will faithfully do nothing ;-)
|
||||
|
||||
``a``
|
||||
Capture field order determined automatically by field flags, transfer
|
||||
opposite. Filter selects among ``t`` and ``b`` modes on a frame by frame
|
||||
basis using field flags. If no field information is available, then this
|
||||
works just like ``u``.
|
||||
|
||||
``u``
|
||||
Capture unknown or varying, transfer opposite. Filter selects among
|
||||
``t`` and ``b`` on a frame by frame basis by analyzing the images and
|
||||
selecting the alternative that produces best match between the fields.
|
||||
|
||||
``T``
|
||||
Capture top-first, transfer unknown or varying. Filter selects among
|
||||
``t`` and ``p`` using image analysis.
|
||||
|
||||
``B``
|
||||
Capture bottom-first, transfer unknown or varying. Filter selects
|
||||
among ``b`` and ``p`` using image analysis.
|
||||
|
||||
``A``
|
||||
Capture determined by field flags, transfer unknown or varying. Filter
|
||||
selects among ``t``, ``b`` and ``p`` using field flags and image
|
||||
analysis. If no field information is available, then this works just
|
||||
like ``U``. This is the default mode.
|
||||
|
||||
``U``
|
||||
Both capture and transfer unknown or varying. Filter selects among
|
||||
``t``, ``b`` and ``p`` using image analysis only.
|
||||
|
||||
``v``
|
||||
Verbose operation. Prints the selected mode for each frame and the
|
||||
average squared difference between fields for ``t``, ``b``, and ``p``
|
||||
alternatives. (Ignored when libavfilter is used.)
|
||||
|
||||
``yadif=[mode[:enabled=yes|no]]``
|
||||
Yet another deinterlacing filter
|
||||
|
||||
@@ -561,6 +716,12 @@ Available filters are:
|
||||
``show``
|
||||
Draw a rectangle showing the area defined by x/y/w/h.
|
||||
|
||||
``screenshot``
|
||||
Optional filter for screenshot support. This is only needed if the video
|
||||
output does not provide working direct screenshot support. Note that it is
|
||||
not always safe to insert this filter by default. See `TAKING SCREENSHOTS`_
|
||||
for details.
|
||||
|
||||
``sub=[=bottom-margin:top-margin]``
|
||||
Moves subtitle rendering to an arbitrary point in the filter chain, or force
|
||||
subtitle rendering in the video filter as opposed to using video output OSD
|
||||
@@ -568,9 +729,9 @@ Available filters are:
|
||||
|
||||
``<bottom-margin>``
|
||||
Adds a black band at the bottom of the frame. The SSA/ASS renderer can
|
||||
place subtitles there (with ``--sub-use-margins``).
|
||||
place subtitles there (with ``--ass-use-margins``).
|
||||
``<top-margin>``
|
||||
Black band on the top for toptitles (with ``--sub-use-margins``).
|
||||
Black band on the top for toptitles (with ``--ass-use-margins``).
|
||||
|
||||
.. admonition:: Examples
|
||||
|
||||
@@ -742,39 +903,13 @@ Available filters are:
|
||||
filters work anyway.)
|
||||
|
||||
``concurrent-frames``
|
||||
Number of frames that should be requested in parallel. The
|
||||
Number of frames that should be requested in parallel (default: 2). The
|
||||
level of concurrency depends on the filter and how quickly mpv can
|
||||
decode video to feed the filter. This value should probably be
|
||||
proportional to the number of cores on your machine. Most time,
|
||||
making it higher than the number of cores can actually make it
|
||||
slower.
|
||||
|
||||
By default, this uses the special value ``auto``, which sets the option
|
||||
to the number of detected logical CPU cores.
|
||||
|
||||
The following variables are defined by mpv:
|
||||
|
||||
``video_in``
|
||||
The mpv video source as vapoursynth clip. Note that this has no length
|
||||
set, which confuses many filters. Using ``Trim`` on the clip with a
|
||||
high dummy length can turn it into a finite clip.
|
||||
|
||||
``video_in_dw``, ``video_in_dh``
|
||||
Display size of the video. Can be different from video size if the
|
||||
video does not use square pixels (e.g. DVD).
|
||||
|
||||
``container_fps``
|
||||
FPS value as reported by file headers. This value can be wrong or
|
||||
completely broken (e.g. 0 or NaN). Even if the value is correct,
|
||||
if another filter changes the real FPS (by dropping or inserting
|
||||
frames), the value of this variable might not be useful. Note that
|
||||
the ``--fps`` command line option overrides this value.
|
||||
|
||||
Useful for some filters which insist on having a FPS.
|
||||
|
||||
``display_fps``
|
||||
Refresh rate of the current display. Note that this value can be 0.
|
||||
|
||||
``vapoursynth-lazy``
|
||||
The same as ``vapoursynth``, but doesn't load Python scripts. Instead, a
|
||||
custom backend using Lua and the raw VapourSynth API is used. The syntax
|
||||
@@ -815,10 +950,6 @@ Available filters are:
|
||||
Show only first field (going by ``--field-dominance``).
|
||||
bob
|
||||
bob deinterlacing (default).
|
||||
weave, motion-adaptive, motion-compensated
|
||||
Advanced deinterlacing algorithms. Whether these actually work
|
||||
depends on the GPU hardware, the GPU drivers, driver bugs, and
|
||||
mpv bugs.
|
||||
|
||||
``vdpaupp``
|
||||
VDPAU video post processing. Works with ``--vo=vdpau`` and ``--vo=opengl``
|
||||
|
||||
+324
-333
@@ -278,139 +278,120 @@ Available video output drivers are:
|
||||
``opengl-hq`` to use this driver with defaults set to high quality
|
||||
rendering.
|
||||
|
||||
Requires at least OpenGL 2.1.
|
||||
Requires at least OpenGL 2.1 and the ``GL_ARB_texture_rg`` extension. For
|
||||
older drivers, ``opengl-old`` may work.
|
||||
|
||||
Some features are available with OpenGL 3 capable graphics drivers only
|
||||
(or if the necessary extensions are available).
|
||||
|
||||
OpenGL ES 2.0 and 3.0 are supported as well.
|
||||
|
||||
Hardware decoding over OpenGL-interop is supported to some degree. Note
|
||||
that in this mode, some corner case might not be gracefully handled, and
|
||||
color space conversion and chroma upsampling is generally in the hand of
|
||||
the hardware decoder APIs.
|
||||
|
||||
``scale=<filter>``
|
||||
``lscale=<filter>``
|
||||
|
||||
``bilinear``
|
||||
Bilinear hardware texture filtering (fastest, very low quality).
|
||||
This is the default for compatibility reasons.
|
||||
Bilinear hardware texture filtering (fastest, mid-quality).
|
||||
This is the default.
|
||||
|
||||
``spline36``
|
||||
Mid quality and speed. This is the default when using ``opengl-hq``.
|
||||
``lanczos2``
|
||||
Lanczos scaling with radius=2. Provides good quality and speed.
|
||||
|
||||
``lanczos3``
|
||||
Lanczos with radius=3.
|
||||
|
||||
``lanczos``
|
||||
Lanczos scaling. Provides mid quality and speed. Generally worse
|
||||
than ``spline36``, but it results in a slightly sharper image
|
||||
which is good for some content types. The number of taps can be
|
||||
controlled with ``scale-radius``, but is best left unchanged.
|
||||
Generic Lanczos scaling filter. Set radius with ``lradius``.
|
||||
|
||||
This filter corresponds to the old ``lanczos3`` alias if the default
|
||||
radius is used, while ``lanczos2`` corresponds to a radius of 2.
|
||||
``spline36``
|
||||
This is the default when using ``opengl-hq``.
|
||||
|
||||
(This filter is an alias for ``sinc``-windowed ``sinc``)
|
||||
``bicubic_fast``
|
||||
Bicubic filter. Has a blurring effect on the image, even if no
|
||||
scaling is done.
|
||||
|
||||
``ewa_lanczos``
|
||||
Elliptic weighted average Lanczos scaling. Also known as Jinc.
|
||||
Relatively slow, but very good quality. The radius can be
|
||||
controlled with ``scale-radius``. Increasing the radius makes the
|
||||
filter sharper but adds more ringing.
|
||||
``sharpen3``
|
||||
Unsharp masking (sharpening) with radius=3 and a default strength
|
||||
of 0.5 (see ``lparam1``).
|
||||
|
||||
(This filter is an alias for ``jinc``-windowed ``jinc``)
|
||||
|
||||
``ewa_lanczossharp``
|
||||
A slightly sharpened version of ewa_lanczos, preconfigured to use
|
||||
an ideal radius and parameter. If your hardware can run it, this is
|
||||
probably what you should use by default.
|
||||
``sharpen5``
|
||||
Unsharp masking (sharpening) with radius=5 and a default strength
|
||||
of 0.5 (see ``lparam1``).
|
||||
|
||||
``mitchell``
|
||||
Mitchell-Netravali. The ``B`` and ``C`` parameters can be set with
|
||||
``scale-param1`` and ``scale-param2``. This filter is very good at
|
||||
downscaling (see ``dscale``).
|
||||
Mitchell-Netravali. The ``b`` and ``c`` parameters can be set with
|
||||
``lparam1`` and ``lparam2``. Both are set to 1/3 by default.
|
||||
|
||||
``oversample``
|
||||
A version of nearest neighbour that (naively) oversamples pixels,
|
||||
so that pixels overlapping edges get linearly interpolated instead
|
||||
of rounded. This essentially removes the small imperfections and
|
||||
judder artifacts caused by nearest-neighbour interpolation, in
|
||||
exchange for adding some blur. This filter is good at temporal
|
||||
interpolation, and also known as "smoothmotion" (see ``tscale``).
|
||||
``gaussian``
|
||||
Gaussian filter with a parameter ``p`` for sharpness control.
|
||||
``p`` can be set to float number between 1(blurry) and 100(sharp)
|
||||
and has a default value of about 28.8 (see ``lparam1``).
|
||||
|
||||
There are some more filters, but most are not as useful. For a complete
|
||||
list, pass ``help`` as value, e.g.::
|
||||
Note that for extremely small value of ``p``, a large filter radius
|
||||
might be required to avoid unintended artifacts (see ``lradius``).
|
||||
|
||||
mpv --vo=opengl:scale=help
|
||||
|
||||
``scale-param1=<value>``, ``scale-param2=<value>``
|
||||
Set filter parameters. Ignored if the filter is not tunable.
|
||||
Currently, this affects the following filter parameters:
|
||||
There are some more filters. For a complete list, pass ``help`` as
|
||||
value, e.g.::
|
||||
|
||||
bcspline
|
||||
Spline parameters (``B`` and ``C``). Defaults to 0.5 for both.
|
||||
mpv --vo=opengl:lscale=help
|
||||
|
||||
gaussian
|
||||
Scale parameter (``t``). Increasing this makes the result blurrier.
|
||||
Defaults to 1.
|
||||
``lparam1=<value>``
|
||||
Set filter parameters. Ignored if the filter is not tunable. These are
|
||||
unset by default, and use the filter specific default if applicable.
|
||||
|
||||
sharpen3, sharpen5
|
||||
Sharpening strength. Increasing this makes the image sharper but
|
||||
adds more ringing and aliasing. Defaults to 0.5.
|
||||
``lparam2=<value>``
|
||||
See ``lparam1``.
|
||||
|
||||
oversample
|
||||
Minimum distance to an edge before interpolation is used. Setting
|
||||
this to 0 will always interpolate edges, whereas setting it to 0.5
|
||||
will never interpolate, thus behaving as if the regular nearest
|
||||
neighbour algorithm was used. Defaults to 0.0.
|
||||
``lradius=<r>``
|
||||
Set radius for filters listed below, must be a float number between 1.0
|
||||
and 8.0. Defaults to be 2.0 if not specified.
|
||||
|
||||
``scale-blur=<value>``
|
||||
Kernel scaling factor (also known as a blur factor). Decreasing this
|
||||
makes the result sharper, increasing it makes it blurrier (default 0).
|
||||
If set to 0, the kernel's preferred blur factor is used. Note that
|
||||
setting this too low (eg. 0.5) leads to bad results. It's generally
|
||||
recommended to stick to values between 0.8 and 1.2.
|
||||
|
||||
``scale-radius=<value>``
|
||||
Set radius for filters listed below, must be a float number between 0.5
|
||||
and 16.0. Defaults to the filter's preferred radius if not specified.
|
||||
|
||||
``sinc`` and derivatives, ``jinc`` and derivatives, ``gaussian``, ``box`` and ``triangle``
|
||||
``sinc``, ``lanczos``, ``blackman``, ``gaussian``
|
||||
|
||||
Note that depending on filter implementation details and video scaling
|
||||
ratio, the radius that actually being used might be different
|
||||
(most likely being increased a bit).
|
||||
|
||||
``scale-antiring=<value>``
|
||||
Set the antiringing strength. This tries to eliminate ringing, but can
|
||||
introduce other artifacts in the process. Must be a float number
|
||||
between 0.0 and 1.0. The default value of 0.0 disables antiringing
|
||||
entirely.
|
||||
|
||||
Note that this doesn't affect the special filters ``bilinear``,
|
||||
``bicubic_fast`` or ``sharpen``.
|
||||
|
||||
``scale-window=<window>``
|
||||
(Advanced users only) Choose a custom windowing function for the kernel.
|
||||
Defaults to the filter's preferred window if unset. Use
|
||||
``scale-window=help`` to get a list of supported windowing functions.
|
||||
|
||||
``scale-wparam=<window>``
|
||||
(Advanced users only) Configure the parameter for the window function
|
||||
given by ``scale-window``. Ignored if the window is not tunable.
|
||||
Currently, this affects the following window parameters:
|
||||
|
||||
kaiser
|
||||
Window parameter (alpha). Defaults to 6.33.
|
||||
blackman
|
||||
Window parameter (alpha). Defaults to 0.16.
|
||||
gaussian
|
||||
Scale parameter (t). Increasing this makes the window wider.
|
||||
Defaults to 1.
|
||||
|
||||
``scaler-resizes-only``
|
||||
Disable the scaler if the video image is not resized. In that case,
|
||||
``bilinear`` is used instead whatever is set with ``scale``. Bilinear
|
||||
``bilinear`` is used instead whatever is set with ``lscale``. Bilinear
|
||||
will reproduce the source image perfectly if no scaling is performed.
|
||||
Note that this option never affects ``cscale``.
|
||||
Note that this option never affects ``cscale``, although the different
|
||||
processing chain might do chroma scaling differently if ``lscale`` is
|
||||
disabled.
|
||||
|
||||
``stereo=<value>``
|
||||
Select a method for stereo display. You may have to use
|
||||
``--video-aspect`` to fix the aspect value. Experimental, do not expect
|
||||
too much from it.
|
||||
|
||||
no
|
||||
Normal 2D display
|
||||
red-cyan
|
||||
Convert side by side input to full-color red-cyan stereo.
|
||||
green-magenta
|
||||
Convert side by side input to full-color green-magenta stereo.
|
||||
quadbuffer
|
||||
Convert side by side input to quad buffered stereo. Only supported
|
||||
by very few OpenGL cards.
|
||||
|
||||
``srgb``
|
||||
Convert and color correct the output to sRGB before displaying it on
|
||||
the screen. This option enables linear light scaling. It also forces
|
||||
the options ``indirect`` and ``gamma``.
|
||||
|
||||
This option is equivalent to using ``icc-profile`` with an sRGB ICC
|
||||
profile, but it is implemented without a 3DLUT and does not require
|
||||
LittleCMS 2. If both ``srgb`` and ``icc-profile`` are present, the
|
||||
latter takes precedence, as they are somewhat redundant.
|
||||
|
||||
Note: When playing back BT.2020 content with this option enabled, out
|
||||
of gamut colors will be numerically clipped, which can potentially
|
||||
change the hue and/or luminance. If this is not desired, it is
|
||||
recommended to use ``icc-profile`` with an sRGB ICC profile instead,
|
||||
when playing back wide-gamut BT.2020 content.
|
||||
|
||||
``pbo``
|
||||
Enable use of PBOs. This is slightly faster, but can sometimes lead to
|
||||
@@ -442,8 +423,7 @@ Available video output drivers are:
|
||||
Used in ``dither=fruit`` mode only.
|
||||
|
||||
``dither=<fruit|ordered|no>``
|
||||
Select dithering algorithm (default: fruit). (Normally, the
|
||||
``dither-depth`` option controls whether dithering is enabled.)
|
||||
Select dithering algorithm (default: fruit).
|
||||
|
||||
``temporal-dither``
|
||||
Enable temporal dithering. (Only active if dithering is enabled in
|
||||
@@ -457,80 +437,38 @@ Available video output drivers are:
|
||||
debug OpenGL context (which does nothing with current graphics drivers
|
||||
as of this writing).
|
||||
|
||||
``interpolation``
|
||||
Reduce stuttering caused by mismatches in the video fps and display
|
||||
refresh rate (also known as judder).
|
||||
|
||||
This essentially attempts to interpolate the missing frames by
|
||||
convoluting the video along the temporal axis. The filter used can be
|
||||
controlled using the ``tscale`` setting.
|
||||
|
||||
Note that this relies on vsync to work, see ``swapinterval`` for more
|
||||
information.
|
||||
|
||||
``swapinterval=<n>``
|
||||
Interval in displayed frames between two buffer swaps.
|
||||
1 is equivalent to enable VSYNC, 0 to disable VSYNC. Defaults to 1 if
|
||||
not specified.
|
||||
1 is equivalent to enable VSYNC, 0 to disable VSYNC.
|
||||
|
||||
Note that this depends on proper OpenGL vsync support. On some platforms
|
||||
and drivers, this only works reliably when in fullscreen mode. It may
|
||||
also require driver-specific hacks if using multiple monitors, to
|
||||
ensure mpv syncs to the right one. Compositing window managers can
|
||||
also lead to bad results, as can missing or incorrect display FPS
|
||||
information (see ``--display-fps``).
|
||||
|
||||
``dscale=<filter>``
|
||||
Like ``scale``, but apply these filters on downscaling instead. If this
|
||||
option is unset, the filter implied by ``scale`` will be applied.
|
||||
``no-scale-sep``
|
||||
When using a separable scale filter for luma, usually two filter
|
||||
passes are done. This is often faster. However, it forces
|
||||
conversion to RGB in an extra pass, so it can actually be slower
|
||||
if used with fast filters on small screen resolutions. Using
|
||||
this options will make rendering a single operation.
|
||||
Note that chroma scalers are always done as 1-pass filters.
|
||||
|
||||
``cscale=<filter>``
|
||||
As ``scale``, but for interpolating chroma information. If the image
|
||||
is not subsampled, this option is ignored entirely.
|
||||
As ``lscale``, but for chroma (2x slower with little visible effect).
|
||||
Note that with some scaling filters, upscaling is always done in
|
||||
RGB. If chroma is not subsampled, this option is ignored, and the
|
||||
luma scaler is used instead. Setting this option is often useless.
|
||||
|
||||
``tscale=<filter>``
|
||||
The filter used for interpolating the temporal axis (frames). This is
|
||||
only used if ``interpolation`` is enabled. The only valid choices
|
||||
for ``tscale`` are separable convolution filters (use ``tscale=help``
|
||||
to get a list). The default is ``oversample``.
|
||||
``lscale-down=<filter>``, ``cscale-down=<filter>``
|
||||
Like ``lscale`` and ``cscale``, but apply these filters on downscaling
|
||||
instead. If these options are unset, the filter implied by ``lscale``
|
||||
(and ``cscale``, respectively) will be applied.
|
||||
|
||||
Note that the maximum supported filter radius is currently 3, and that
|
||||
using filters with larger radius may introduce issues when pausing or
|
||||
framestepping, proportional to the radius used. It is recommended to
|
||||
stick to a radius of 1 or 2.
|
||||
``cparam1``, ``cparam2``, ``cradius``
|
||||
Set filter parameters and radius for ``cscale``.
|
||||
|
||||
``dscale-radius``, ``cscale-radius``, ``tscale-radius``, etc.
|
||||
Set filter parameters for ``dscale``, ``cscale`` and ``tscale``,
|
||||
respectively.
|
||||
|
||||
See the corresponding options for ``scale``.
|
||||
|
||||
``linear-scaling``
|
||||
Scale in linear light. This is automatically enabled if
|
||||
``target-prim``, ``target-trc``, ``icc-profile`` or
|
||||
``sigmoid-upscaling`` is set. It should only be used with a
|
||||
``fbo-format`` that has at least 16 bit precision.
|
||||
See ``lparam1``, ``lparam2`` and ``lradius``.
|
||||
|
||||
``fancy-downscaling``
|
||||
When using convolution based filters, extend the filter size
|
||||
when downscaling. Trades quality for reduced downscaling performance.
|
||||
|
||||
This is automatically disabled for anamorphic video, because this
|
||||
feature doesn't work correctly with different scale factors in
|
||||
different directions.
|
||||
|
||||
``sigmoid-upscaling``
|
||||
When upscaling, use a sigmoidal color transform to avoid emphasizing
|
||||
ringing artifacts. This also enables ``linear-scaling``.
|
||||
|
||||
``sigmoid-center``
|
||||
The center of the sigmoid curve used for ``sigmoid-upscaling``, must
|
||||
be a float between 0.0 and 1.0. Defaults to 0.75 if not specified.
|
||||
|
||||
``sigmoid-slope``
|
||||
The slope of the sigmoid curve used for ``sigmoid-upscaling``, must
|
||||
be a float between 1.0 and 20.0. Defaults to 6.5 if not specified.
|
||||
|
||||
``no-npot``
|
||||
Force use of power-of-2 texture sizes. For debugging only.
|
||||
Borders will be distorted due to filtering.
|
||||
@@ -538,26 +476,14 @@ Available video output drivers are:
|
||||
``glfinish``
|
||||
Call ``glFinish()`` before and after swapping buffers (default: disabled).
|
||||
Slower, but might help getting better results when doing framedropping.
|
||||
Can completely ruin performance. The details depend entirely on the
|
||||
OpenGL driver.
|
||||
The details depend entirely on the OpenGL driver.
|
||||
|
||||
``waitvsync``
|
||||
Call ``glXWaitVideoSyncSGI`` after each buffer swap (default: disabled).
|
||||
This may or may not help with video timing accuracy and frame drop. It's
|
||||
possible that this makes video output slower, or has no effect at all.
|
||||
|
||||
X11/GLX only.
|
||||
|
||||
``dwmflush=<no|windowed|yes>``
|
||||
Calls ``DwmFlush`` after swapping buffers on Windows (default: no).
|
||||
It also sets ``SwapInterval(0)`` to ignore the OpenGL timing. Values
|
||||
are: no (disabled), windowed (only in windowed mode), yes (also in
|
||||
full screen).
|
||||
This may help getting more consistent frame intervals, especially with
|
||||
high-fps clips - which might also reduce dropped frames. Typically a
|
||||
value of 1 should be enough since full screen may bypass the DWM.
|
||||
|
||||
Windows only.
|
||||
X11 only.
|
||||
|
||||
``sw``
|
||||
Continue even if a software renderer is detected.
|
||||
@@ -573,12 +499,19 @@ Available video output drivers are:
|
||||
Cocoa/OS X
|
||||
win
|
||||
Win32/WGL
|
||||
x11, x11es
|
||||
X11/GLX (the ``es`` variant forces GLES)
|
||||
x11
|
||||
X11/GLX
|
||||
wayland
|
||||
Wayland/EGL
|
||||
x11egl, x11egles
|
||||
X11/EGL (the ``es`` variant forces GLES)
|
||||
|
||||
``indirect``
|
||||
Do YUV conversion and scaling as separate passes. This will first render
|
||||
the video into a video-sized RGB texture, and draw the result on screen.
|
||||
The luma scaler is used to scale the RGB image when rendering to screen.
|
||||
The chroma scaler is used only on YUV conversion, and only if the video
|
||||
is chroma-subsampled (usually the case).
|
||||
This mechanism is disabled on RGB input.
|
||||
Specifying this option directly is generally useful for debugging only.
|
||||
|
||||
``fbo-format=<fmt>``
|
||||
Selects the internal format of textures used for FBOs. The format can
|
||||
@@ -586,88 +519,28 @@ Available video output drivers are:
|
||||
always used, and typically only when using extended scalers.)
|
||||
``fmt`` can be one of: rgb, rgba, rgb8, rgb10, rgb10_a2, rgb16, rgb16f,
|
||||
rgb32f, rgba12, rgba16, rgba16f, rgba32f.
|
||||
Default: rgba16.
|
||||
Default: rgb.
|
||||
|
||||
``gamma=<0.1..2.0>``
|
||||
Set a gamma value (default: 1.0). If gamma is adjusted in other ways
|
||||
(like with the ``--gamma`` option or key bindings and the ``gamma``
|
||||
property), the value is multiplied with the other gamma value.
|
||||
``gamma=<0.0..10.0>``
|
||||
Set a gamma value. If gamma is adjusted in other ways (like with
|
||||
the ``--gamma`` option or key bindings and the ``gamma`` property), the
|
||||
value is multiplied with the other gamma value.
|
||||
|
||||
Recommended values based on the environmental brightness:
|
||||
|
||||
1.0
|
||||
Brightly illuminated (default)
|
||||
0.9
|
||||
Slightly dim
|
||||
0.8
|
||||
Pitch black room
|
||||
|
||||
``gamma-auto``
|
||||
Automatically corrects the gamma value depending on ambient lighting
|
||||
conditions (adding a gamma boost for dark rooms).
|
||||
|
||||
With ambient illuminance of 64lux, mpv will pick the 1.0 gamma value
|
||||
(no boost), and slightly increase the boost up until 0.8 for 16lux.
|
||||
|
||||
NOTE: Only implemented on OS X.
|
||||
|
||||
``target-prim=<value>``
|
||||
Specifies the primaries of the display. Video colors will be adapted
|
||||
to this colorspace if necessary. Valid values are:
|
||||
|
||||
auto
|
||||
Disable any adaptation (default)
|
||||
bt.470m
|
||||
ITU-R BT.470 M
|
||||
bt.601-525
|
||||
ITU-R BT.601 (525-line SD systems, eg. NTSC), SMPTE 170M/240M
|
||||
bt.601-625
|
||||
ITU-R BT.601 (625-line SD systems, eg. PAL/SECAM), ITU-R BT.470 B/G
|
||||
bt.709
|
||||
ITU-R BT.709 (HD), IEC 61966-2-4 (sRGB), SMPTE RP177 Annex B
|
||||
bt.2020
|
||||
ITU-R BT.2020 (UHD)
|
||||
apple
|
||||
Apple RGB
|
||||
adobe
|
||||
Adobe RGB (1998)
|
||||
prophoto
|
||||
ProPhoto RGB (ROMM)
|
||||
cie1931
|
||||
CIE 1931 RGB (not to be confused with CIE XYZ)
|
||||
|
||||
``target-trc=<value>``
|
||||
Specifies the transfer characteristics (gamma) of the display. Video
|
||||
colors will be adjusted to this curve. Valid values are:
|
||||
|
||||
auto
|
||||
Disable any adaptation (default)
|
||||
bt.1886
|
||||
ITU-R BT.1886 curve, without the brightness drop (approx. 1.961)
|
||||
srgb
|
||||
IEC 61966-2-4 (sRGB)
|
||||
linear
|
||||
Linear light output
|
||||
gamma1.8
|
||||
Pure power curve (gamma 1.8), also used for Apple RGB
|
||||
gamma2.2
|
||||
Pure power curve (gamma 2.2)
|
||||
gamma2.8
|
||||
Pure power curve (gamma 2.8), also used for BT.470-BG
|
||||
prophoto
|
||||
ProPhoto RGB (ROMM)
|
||||
Setting this value to 1.0 can be used to always enable gamma control.
|
||||
(Disables delayed enabling.)
|
||||
|
||||
``icc-profile=<file>``
|
||||
Load an ICC profile and use it to transform linear RGB to screen output.
|
||||
Needs LittleCMS 2 support compiled in. This option overrides the
|
||||
``target-prim`` and ``target-trc`` options. It also enables
|
||||
``linear-scaling``.
|
||||
Needs LittleCMS 2 support compiled in. This option overrides the ``srgb``
|
||||
property, as using both is somewhat redundant. It also enables linear
|
||||
light scaling.
|
||||
|
||||
|
||||
``icc-profile-auto``
|
||||
Automatically select the ICC display profile currently specified by
|
||||
the display settings of the operating system.
|
||||
|
||||
NOTE: Only implemented on OS X and X11
|
||||
NOTE: Only implemented on OS X with Cocoa.
|
||||
|
||||
``icc-cache=<file>``
|
||||
Store and load the 3D LUT created from the ICC profile in this file.
|
||||
@@ -676,8 +549,9 @@ Available video output drivers are:
|
||||
Its size depends on the ``3dlut-size``, and can be very big.
|
||||
|
||||
``icc-intent=<value>``
|
||||
Specifies the ICC intent used for the color transformation (when using
|
||||
``icc-profile``).
|
||||
Specifies the ICC Intent used for transformations between color spaces.
|
||||
This affects the rendering when using ``icc-profile`` or ``srgb`` and
|
||||
also affects the way DCP XYZ content gets converted to RGB.
|
||||
|
||||
0
|
||||
perceptual
|
||||
@@ -688,33 +562,21 @@ Available video output drivers are:
|
||||
3
|
||||
absolute colorimetric
|
||||
|
||||
``approx-gamma``
|
||||
Approximate the actual gamma function as a pure power curve of
|
||||
1.95. A number of video editing programs and studios apparently use this
|
||||
for mastering instead of the true curve. Most notably, anything in the
|
||||
Apple ecosystem uses this approximation - including all programs
|
||||
compatible with it. It's a sound idea to try enabling this flag first
|
||||
when watching videos and shows to see if things look better that way.
|
||||
|
||||
This only affects the output when using either ``icc-profile`` or ``srgb``.
|
||||
|
||||
``3dlut-size=<r>x<g>x<b>``
|
||||
Size of the 3D LUT generated from the ICC profile in each dimension.
|
||||
Default is 128x256x64.
|
||||
Sizes must be a power of two, and 512 at most.
|
||||
|
||||
``blend-subtitles=<yes|video|no>``
|
||||
Blend subtitles directly onto upscaled video frames, before
|
||||
interpolation and/or color management (default: no). Enabling this
|
||||
causes subtitles to be affected by ``icc-profile``, ``target-prim``,
|
||||
``target-trc``, ``interpolation``, ``gamma`` and ``linear-scaling``.
|
||||
It also increases subtitle performance when using ``interpolation``.
|
||||
|
||||
The downside of enabling this is that it restricts subtitles to the
|
||||
visible portion of the video, so you can't have subtitles exist in the
|
||||
black margins below a video (for example).
|
||||
|
||||
If ``video`` is selected, the behavior is similar to ``yes``, but subs
|
||||
are drawn at the video's native resolution, and scaled along with the
|
||||
video.
|
||||
|
||||
.. warning:: This changes the way subtitle colors are handled. Normally,
|
||||
subtitle colors are assumed to be in sRGB and color managed
|
||||
as such. Enabling this makes them treated as being in the
|
||||
video's color space instead. This is good if you want
|
||||
things like softsubbed ASS signs to match the video colors,
|
||||
but may cause SRT subtitles or similar to look slightly off.
|
||||
|
||||
``alpha=<blend|yes|no>``
|
||||
Decides what to do if the input has an alpha component (default: blend).
|
||||
|
||||
@@ -725,26 +587,26 @@ Available video output drivers are:
|
||||
if the video contains alpha information (which is extremely rare). May
|
||||
not be supported on all platforms. If alpha framebuffers are
|
||||
unavailable, it silently falls back on a normal framebuffer. Note
|
||||
that if you set the ``fbo-format`` option to a non-default value,
|
||||
a format with alpha must be specified, or this won't work.
|
||||
that when using FBO indirections (such as with ``opengl-hq``), an FBO
|
||||
format with alpha must be specified with the ``fbo-format`` option.
|
||||
no
|
||||
Ignore alpha component.
|
||||
|
||||
``chroma-location=<auto|center|left>``
|
||||
Set the YUV chroma sample location. auto means use the bitstream
|
||||
flags (default: auto).
|
||||
|
||||
``rectangle-textures``
|
||||
Force use of rectangle textures (default: no). Normally this shouldn't
|
||||
have any advantages over normal textures. Note that hardware decoding
|
||||
overrides this flag.
|
||||
|
||||
``background=<color>``
|
||||
Color used to draw parts of the mpv window not covered by video.
|
||||
See ``--osd-color`` option how colors are defined.
|
||||
|
||||
``opengl-hq``
|
||||
Same as ``opengl``, but with default settings for high quality rendering.
|
||||
|
||||
This is equivalent to::
|
||||
|
||||
--vo=opengl:scale=spline36:cscale=spline36:dscale=mitchell:dither-depth=auto:fancy-downscaling:sigmoid-upscaling
|
||||
--vo=opengl:lscale=spline36:dither-depth=auto:fbo-format=rgba16
|
||||
|
||||
Note that some cheaper LCDs do dithering that gravely interferes with
|
||||
``opengl``'s dithering. Disabling dithering with ``dither-depth=no`` helps.
|
||||
@@ -756,6 +618,188 @@ Available video output drivers are:
|
||||
float texture support, and some OS X setups being very slow with ``rgb16``
|
||||
but fast with ``rgb32f``.
|
||||
|
||||
``opengl-old``
|
||||
OpenGL video output driver, old version. Video size must be smaller
|
||||
than the maximum texture size of your OpenGL implementation. Intended to
|
||||
work even with the most basic OpenGL implementations, but also makes use
|
||||
of newer extensions which allow support for more color spaces.
|
||||
|
||||
The code performs very few checks, so if a feature does not work, this
|
||||
might be because it is not supported by your card and/or OpenGL
|
||||
implementation, even if you do not get any error message. Use ``glxinfo``
|
||||
or a similar tool to display the supported OpenGL extensions.
|
||||
|
||||
.. note:: This driver is for compatibility with old systems.
|
||||
|
||||
``(no-)ati-hack``
|
||||
ATI drivers may give a corrupted image when PBOs are used (when using
|
||||
``force-pbo``). This option fixes this, at the expense of using a bit
|
||||
more memory.
|
||||
``(no-)force-pbo``
|
||||
Always uses PBOs to transfer textures even if this involves an extra
|
||||
copy. Currently this gives a little extra speed with NVIDIA drivers
|
||||
and a lot more speed with ATI drivers. May need the ``ati-hack``
|
||||
suboption to work correctly.
|
||||
``(no-)scaled-osd``
|
||||
Scales the OSD and subtitles instead of rendering them at display size
|
||||
(default: disabled).
|
||||
``rectangle=<0,1,2>``
|
||||
Select usage of rectangular textures, which saves video RAM, but often
|
||||
is slower (default: 0).
|
||||
|
||||
0
|
||||
Use power-of-two textures (default).
|
||||
1
|
||||
Use the ``GL_ARB_texture_rectangle`` extension.
|
||||
2
|
||||
Use the ``GL_ARB_texture_non_power_of_two`` extension. In some
|
||||
cases only supported in software and thus very slow.
|
||||
|
||||
``swapinterval=<n>``
|
||||
Minimum interval between two buffer swaps, counted in displayed frames
|
||||
(default: 1). 1 is equivalent to enabling VSYNC, 0 to disabling VSYNC.
|
||||
Values below 0 will leave it at the system default. This limits the
|
||||
framerate to (horizontal refresh rate / n). Requires
|
||||
``GLX_SGI_swap_control`` support to work. With some (most/all?)
|
||||
implementations this only works in fullscreen mode.
|
||||
``ycbcr``
|
||||
Use the ``GL_MESA_ycbcr_texture`` extension to convert YUV to RGB. In
|
||||
most cases this is probably slower than doing software conversion to
|
||||
RGB.
|
||||
``yuv=<n>``
|
||||
Select the type of YUV to RGB conversion. The default is
|
||||
auto-detection deciding between values 0 and 2.
|
||||
|
||||
0
|
||||
Use software conversion. Compatible with all OpenGL versions.
|
||||
Provides brightness, contrast and saturation control.
|
||||
1
|
||||
Same as 2. This used to use NVIDIA-specific extensions, which
|
||||
did not provide any advantages over using fragment programs, except
|
||||
possibly on very ancient graphics cards. It produced a gray-ish
|
||||
output, which is why it has been removed.
|
||||
2
|
||||
Use a fragment program. Needs the ``GL_ARB_fragment_program``
|
||||
extension and at least three texture units. Provides brightness,
|
||||
contrast, saturation and hue control.
|
||||
3
|
||||
Use a fragment program using the ``POW`` instruction. Needs the
|
||||
``GL_ARB_fragment_program`` extension and at least three texture
|
||||
units. Provides brightness, contrast, saturation, hue and gamma
|
||||
control. Gamma can also be set independently for red, green and
|
||||
blue. Method 4 is usually faster.
|
||||
4
|
||||
Use a fragment program with additional lookup. Needs the
|
||||
``GL_ARB_fragment_program`` extension and at least four texture
|
||||
units. Provides brightness, contrast, saturation, hue and gamma
|
||||
control. Gamma can also be set independently for red, green and
|
||||
blue.
|
||||
5
|
||||
Use ATI-specific method (for older cards). This uses an
|
||||
ATI-specific extension (``GL_ATI_fragment_shader`` - not
|
||||
``GL_ARB_fragment_shader``!). At least three texture units are
|
||||
needed. Provides saturation and hue control. This method is fast
|
||||
but inexact.
|
||||
6
|
||||
Use a 3D texture to do conversion via lookup. Needs the
|
||||
``GL_ARB_fragment_program extension`` and at least four texture
|
||||
units. Extremely slow (software emulation) on some (all?) ATI
|
||||
cards since it uses a texture with border pixels. Provides
|
||||
brightness, contrast, saturation, hue and gamma control. Gamma can
|
||||
also be set independently for red, green and blue. Speed depends
|
||||
more on GPU memory bandwidth than other methods.
|
||||
|
||||
``lscale=<n>``
|
||||
Select the scaling function to use for luminance scaling. Only valid
|
||||
for yuv modes 2, 3, 4 and 6.
|
||||
|
||||
0
|
||||
Use simple linear filtering (default).
|
||||
1
|
||||
Use bicubic B-spline filtering (better quality). Needs one
|
||||
additional texture unit. Older cards will not be able to handle
|
||||
this for chroma at least in fullscreen mode.
|
||||
2
|
||||
Use cubic filtering in horizontal, linear filtering in vertical
|
||||
direction. Works on a few more cards than method 1.
|
||||
3
|
||||
Same as 1 but does not use a lookup texture. Might be faster on
|
||||
some cards.
|
||||
4
|
||||
Use experimental unsharp masking with 3x3 support and a default
|
||||
strength of 0.5 (see ``filter-strength``).
|
||||
5
|
||||
Use experimental unsharp masking with 5x5 support and a default
|
||||
strength of 0.5 (see ``filter-strength``).
|
||||
|
||||
``cscale=<n>``
|
||||
Select the scaling function to use for chrominance scaling. For
|
||||
details see ``lscale``.
|
||||
``filter-strength=<value>``
|
||||
Set the effect strength for the ``lscale``/``cscale`` filters that
|
||||
support it.
|
||||
``stereo=<value>``
|
||||
Select a method for stereo display. You may have to use
|
||||
``--video-aspect`` to fix the aspect value. Experimental, do not expect
|
||||
too much from it.
|
||||
|
||||
0
|
||||
Normal 2D display
|
||||
1
|
||||
Convert side by side input to full-color red-cyan stereo.
|
||||
2
|
||||
Convert side by side input to full-color green-magenta stereo.
|
||||
3
|
||||
Convert side by side input to quad buffered stereo. Only supported
|
||||
by very few OpenGL cards.
|
||||
|
||||
The following options are only useful if writing your own fragment programs.
|
||||
|
||||
``customprog=<filename>``
|
||||
Load a custom fragment program from ``<filename>``.
|
||||
``customtex=<filename>``
|
||||
Load a custom "gamma ramp" texture from ``<filename>``. This can be used
|
||||
in combination with ``yuv=4`` or with the ``customprog`` option.
|
||||
``(no-)customtlin``
|
||||
If enabled (default) use ``GL_LINEAR`` interpolation, otherwise use
|
||||
``GL_NEAREST`` for customtex texture.
|
||||
``(no-)customtrect``
|
||||
If enabled, use ``texture_rectangle`` for the ``customtex`` texture.
|
||||
Default is disabled.
|
||||
``(no-)mipmapgen``
|
||||
If enabled, mipmaps for the video are automatically generated. This
|
||||
should be useful together with the ``customprog`` and the ``TXB``
|
||||
instruction to implement blur filters with a large radius. For most
|
||||
OpenGL implementations, this is very slow for any non-RGB formats.
|
||||
Default is disabled.
|
||||
|
||||
Normally there is no reason to use the following options; they mostly
|
||||
exist for testing purposes.
|
||||
|
||||
``(no-)glfinish``
|
||||
Call ``glFinish()`` before swapping buffers. Slower but in some cases
|
||||
more correct output (default: disabled).
|
||||
``(no-)manyfmts``
|
||||
Enables support for more (RGB and BGR) color formats (default: enabled).
|
||||
Needs OpenGL version >= 1.2.
|
||||
``slice-height=<0-...>``
|
||||
Number of lines copied to texture in one piece (default: 0). 0 for
|
||||
whole image.
|
||||
``sw``
|
||||
Continue even if a software renderer is detected.
|
||||
|
||||
``backend=<sys>``
|
||||
auto
|
||||
auto-select (default)
|
||||
cocoa
|
||||
Cocoa/OS X
|
||||
win
|
||||
Win32/WGL
|
||||
x11
|
||||
X11/GLX
|
||||
wayland
|
||||
Wayland/EGL
|
||||
|
||||
``sdl``
|
||||
SDL 2.0+ Render video output driver, depending on system with or without
|
||||
hardware acceleration. Should work on all platforms supported by SDL 2.0.
|
||||
@@ -880,56 +924,3 @@ Available video output drivers are:
|
||||
Use 3 buffers instead of 2. This can lead to more fluid playback, but
|
||||
uses more memory.
|
||||
|
||||
``opengl-cb``
|
||||
For use with libmpv direct OpenGL embedding; useless in any other contexts.
|
||||
(See ``<mpv/opengl_cb.h>``.)
|
||||
Usually, ``opengl-cb`` renders frames asynchronously by client and this
|
||||
can cause some frame drops. In order to provide a way to handle this
|
||||
situation, ``opengl-cb`` has its own frame queue and calls update callback
|
||||
more frequently if the queue is not empty regardless of existence of new frame.
|
||||
Once the queue is filled, ``opengl-cb`` drops frames automatically.
|
||||
|
||||
With default options, ``opengl-cb`` renders only the latest frame and drops
|
||||
all frames handed over while waiting render function after update callback.
|
||||
|
||||
``frame-queue-size=<1..100>``
|
||||
The maximum count of frames which the frame queue can hold (default: 1)
|
||||
|
||||
``frame-drop-mode=<pop|clear>``
|
||||
Select the behavior when the frame queue is full.
|
||||
|
||||
pop
|
||||
Drop the oldest frame in the frame queue. (default)
|
||||
clear
|
||||
Drop all frames in the frame queue.
|
||||
|
||||
This also supports many of the suboptions the ``opengl`` VO has. Run
|
||||
``mpv --vo=opengl-cb:help`` for a list.
|
||||
|
||||
This also supports the ``vo_cmdline`` command.
|
||||
|
||||
``rpi`` (Raspberry Pi)
|
||||
Native video output on the Raspberry Pi using the MMAL API.
|
||||
|
||||
``display=<number>``
|
||||
Select the display number on which the video overlay should be shown
|
||||
(default: 0).
|
||||
|
||||
``layer=<number>``
|
||||
Select the dispmanx layer on which the video overlay should be shown
|
||||
(default: -10). Note that mpv will also use the 2 layers above the
|
||||
selected layer, to handle the window background and OSD. Actual video
|
||||
rendering will happen on the layer above the selected layer.
|
||||
|
||||
``drm`` (Direct Rendering Manager)
|
||||
Video output driver using Kernel Mode Setting / Direct Rendering Manager.
|
||||
Does not support hardware acceleration. Should be used when one doesn't
|
||||
want to install full-blown graphical environment (e.g. no X).
|
||||
|
||||
``connector=<number>``
|
||||
Select the connector to use (usually this is a monitor.) If set to -1,
|
||||
mpv renders the output on the first available connector. (default: -1)
|
||||
|
||||
``devpath=<filename>``
|
||||
Path to graphic card device.
|
||||
(default: /dev/dri/card0)
|
||||
@@ -1,447 +0,0 @@
|
||||
CHANGES FROM OTHER VERSIONS OF MPLAYER
|
||||
======================================
|
||||
|
||||
**mpv** is based on mplayer2, which in turn is based on the original MPlayer
|
||||
(also called mplayer, mplayer-svn, mplayer1). Many changes have been made, a
|
||||
large part of which is incompatible or completely changes how the player
|
||||
behaves. Although there are still many similarities to its ancestors, **mpv**
|
||||
should generally be treated as a completely different program.
|
||||
|
||||
.. note::
|
||||
These lists are incomplete.
|
||||
|
||||
General Changes from MPlayer to mpv
|
||||
-----------------------------------
|
||||
|
||||
This listing is about changes introduced by mplayer2 and mpv relatively to
|
||||
MPlayer.
|
||||
|
||||
Player
|
||||
~~~~~~
|
||||
|
||||
* New name for the binary (``mpv``). New location for config files (either
|
||||
``~/.config/mpv/mpv.conf``, or if you want, ``~/.mpv/config``).
|
||||
* Encoding functionality (replacement for MEncoder, see the `ENCODING`_ section).
|
||||
* Support for Lua scripting (see the `LUA SCRIPTING`_ section).
|
||||
* Better pause handling (e.g. do not unpause on a command).
|
||||
* Precise seeking support.
|
||||
* Improvements in audio/video sync handling.
|
||||
* Do not lose settings when playing a new file in the same player instance.
|
||||
* Slave mode compatibility broken (see below).
|
||||
* Re-enable screensaver while the player is paused.
|
||||
* Allow resuming playback at a later point with ``Shift+q``, also see the
|
||||
``quit_watch_later`` input command.
|
||||
* ``--keep-open`` option to stop the player from closing the window and
|
||||
exiting after playback ends.
|
||||
* A client API, that allows embedding **mpv** into applications
|
||||
(see ``libmpv/client.h`` in the sources).
|
||||
|
||||
Input
|
||||
~~~~~
|
||||
|
||||
* Improved default keybindings. MPlayer bindings are also available (see
|
||||
``etc/mplayer-input.conf`` in the source tree).
|
||||
* Improved responsiveness on user input.
|
||||
* Support for modifier keys (alt, shift, ctrl) in input.conf.
|
||||
* Allow customizing whether a key binding for seeking shows the video time, the
|
||||
OSD bar, or nothing (see the `Input Command Prefixes`_ section).
|
||||
* Support mapping multiple commands to one key.
|
||||
* Classic LIRC support was removed. Install remotes as input devices instead.
|
||||
This way they will send X11 key events to the mpv window, which can be bound
|
||||
using the normal ``input.conf``.
|
||||
Also see: http://github.com/mpv-player/mpv/wiki/IR-remotes
|
||||
* Joystick support was removed. It was considered useless and was the cause
|
||||
of some problems (e.g. a laptop's accelerator being recognized as joystick).
|
||||
|
||||
Audio
|
||||
~~~~~
|
||||
|
||||
* Support for gapless audio (see the ``--gapless-audio`` option).
|
||||
* Support for OSS4 volume control.
|
||||
* Improved support for PulseAudio.
|
||||
* Make ``--softvol`` default (**mpv** is not a mixer control panel).
|
||||
* By default, do pitch correction if playback speed is increased.
|
||||
* Improved downmixing and output of surround audio:
|
||||
|
||||
- Instead of using hardcoded pan filters to do remixing, libavresample is used
|
||||
- Channel maps are used to identify the channel layout, so e.g. ``3.0`` and
|
||||
``2.1`` audio can be distinguished.
|
||||
|
||||
Video
|
||||
~~~~~
|
||||
|
||||
* Wayland support.
|
||||
* Native support for VAAPI and VDA. Improved VDPAU video output.
|
||||
* Improved OpenGL output (see the ``opengl-hq`` video output).
|
||||
* Make hardware decoding work with the ``opengl`` video output.
|
||||
* Support for libavfilter (for video->video and audio->audio). This allows
|
||||
using most of FFmpeg's filters, which improve greatly on the old MPlayer
|
||||
filters in features, performance, and correctness.
|
||||
* More correct color reproduction (color matrix generation), including support
|
||||
for BT.2020 (Ultra HD) and linear XYZ (Digital Cinema) inputs.
|
||||
* Support for color managed displays, via ICC profiles.
|
||||
* High-quality image resamplers (see the ``opengl`` ``scale`` suboption).
|
||||
* Support for scaling in (sigmoidized) linear light.
|
||||
* Better subtitle rendering using libass by default.
|
||||
* Improvements when playing multiple files (``-fixed-vo`` is default, do not
|
||||
reset settings by default when playing a new file).
|
||||
* Replace image video outputs (``--vo=jpeg`` etc.) with ``--vo=image``.
|
||||
* Removal of ``--vo=gif89a``, ``--vo=md5sum``, ``--vo=yuv4mpeg``, as encoding
|
||||
can handle these use cases. For yuv4mpeg, for example, use::
|
||||
|
||||
mpv input.mkv -o output.y4m --no-audio --oautofps --oneverdrop
|
||||
|
||||
* Image subtitles (DVDs etc.) are rendered in color and use more correct
|
||||
positioning (color for image subs can be disabled with ``--sub-gray``).
|
||||
|
||||
OSD and terminal
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
* Cleaned up terminal output: nicer status line, less useless noise.
|
||||
* Improved OSD rendering using libass, with full Unicode support.
|
||||
* New OSD bar with chapter marks. Not positioned in the middle of the video
|
||||
(this can be customized with the ``--osd-bar-align-y`` option).
|
||||
* Display list of chapters and audio/subtitle tracks on OSD (see the
|
||||
`Properties`_ section).
|
||||
|
||||
Screenshots
|
||||
~~~~~~~~~~~
|
||||
|
||||
* Instant screenshots without 1-frame delay.
|
||||
* Support for taking screenshots even with hardware decoding.
|
||||
* Support for saving screenshots as JPEG or PNG.
|
||||
* Support for configurable file names.
|
||||
* Support for taking screenshots with or without subtitles.
|
||||
|
||||
Note that the ``screenshot`` video filter is not needed anymore, and should not
|
||||
be put into the mpv config file.
|
||||
|
||||
Miscellaneous
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
* Better MKV support (e.g. ordered chapters, 3D metadata).
|
||||
* Matroska edition switching at runtime.
|
||||
* Support for playing URLs of popular streaming sites directly.
|
||||
(e.g. ``mpv https://www.youtube.com/watch?v=...``).
|
||||
Requires a recent version of ``youtube-dl`` to be installed. Can be
|
||||
disabled with ``ytdl=no`` in the mpv config file.
|
||||
* Support for precise scrolling which scales the parameter of commands. If the
|
||||
input doesn't support precise scrolling the scale factor stays 1.
|
||||
* Allow changing/adjusting video filters at runtime. (This is also used to make
|
||||
the ``D`` key insert vf_yadif if deinterlacing is not supported otherwise).
|
||||
* Improved support for .cue files.
|
||||
|
||||
Mac OS X
|
||||
~~~~~~~~
|
||||
|
||||
* Native OpenGL backend.
|
||||
* Cocoa event loop is independent from MPlayer's event loop, so user
|
||||
actions like accessing menus and live resizing do not block the playback.
|
||||
* Apple Remote support.
|
||||
* Media Keys support.
|
||||
* VDA support using libavcodec hwaccel API instead of FFmpeg's decoder with up
|
||||
to 2-2.5x reduction in CPU usage.
|
||||
|
||||
Windows
|
||||
~~~~~~~
|
||||
|
||||
* Improved support for Unicode file names.
|
||||
* Improved window handling.
|
||||
* Do not block playback when moving the window.
|
||||
* Improved Direct3D video output.
|
||||
* Added WASAPI audio output.
|
||||
|
||||
Internal changes
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
* Switch to GPLv2+ (see ``Copyright`` file for details).
|
||||
* Removal of lots of cruft:
|
||||
|
||||
- Internal GUI (replaced by the OSC, see the `ON SCREEN CONTROLLER`_ section).
|
||||
- MEncoder (replaced by native encoding, see the `ENCODING`_ section).
|
||||
- OSD menu.
|
||||
- Kernel video drivers for Linux 2.4 (including VIDIX).
|
||||
- Teletext support.
|
||||
- Support for dead platforms.
|
||||
- Most built-in demuxers have been replaced by their libavformat counterparts.
|
||||
- Built-in network support has been replaced by libavformat's (which also
|
||||
supports https URLs).
|
||||
- Embedded copies of libraries (such as FFmpeg).
|
||||
|
||||
* General code cleanups (including refactoring or rewrites of many parts).
|
||||
* New build system.
|
||||
* Many bug fixes and removal of long-standing issues.
|
||||
* Generally preferring FFmpeg/Libav over internal demuxers, decoders, and
|
||||
filters.
|
||||
|
||||
Detailed Listing of User-visible Changes
|
||||
----------------------------------------
|
||||
|
||||
This listing is about changed command line switches, slave commands, and similar
|
||||
things. Completely removed features are not listed.
|
||||
|
||||
Command Line Switches
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* There is a new command line syntax, which is generally preferred over the old
|
||||
syntax. ``-optname optvalue`` becomes ``--optname=optvalue``.
|
||||
|
||||
The old syntax will not be removed. However, the new syntax is mentioned in
|
||||
all documentation and so on, and unlike the old syntax is not ambiguous,
|
||||
so it is a good thing to know about this change.
|
||||
* In general, negating switches like ``-noopt`` now have to be written as
|
||||
``-no-opt`` or ``--no-opt``.
|
||||
* Per-file options are not the default anymore. You can explicitly specify
|
||||
file-local options. See ``Usage`` section.
|
||||
* Many options have been renamed, removed or changed semantics. Some options
|
||||
that are required for a good playback experience with MPlayer are now
|
||||
superfluous or even worse than the defaults, so make sure to read the manual
|
||||
before trying to use your existing configuration with **mpv**.
|
||||
* Table of renamed/replaced switches:
|
||||
|
||||
=========================== ========================================
|
||||
Old New
|
||||
=========================== ========================================
|
||||
``-no<opt>`` ``--no-<opt>`` (add a dash)
|
||||
``-a52drc level`` ``--ad-lavc-ac3drc=level``
|
||||
``-ac spdifac3`` ``--ad=spdif:ac3`` (see ``--ad=help``)
|
||||
``-af volnorm`` ``--af=drc`` (renamed)
|
||||
``-afm hwac3`` ``--ad=spdif:ac3,spdif:dts``
|
||||
``-ao alsa:device=hw=0.3`` ``--ao=alsa:device=[hw:0,3]``
|
||||
``-aspect`` ``--video-aspect``
|
||||
``-ass-bottom-margin`` ``--vf=sub=bottom:top``
|
||||
``-ass`` ``--sub-ass``
|
||||
``-audiofile-cache`` (removed; the main cache settings are used)
|
||||
``-audiofile`` ``--audio-file``
|
||||
``-benchmark`` ``--untimed`` (no stats)
|
||||
``-capture`` ``--stream-capture=<filename>``
|
||||
``-channels`` ``--audio-channels`` (changed semantics)
|
||||
``-cursor-autohide-delay`` ``--cursor-autohide``
|
||||
``-delay`` ``--audio-delay``
|
||||
``-dumpstream`` ``--stream-dump=<filename>``
|
||||
``-dvdangle`` ``--dvd-angle``
|
||||
``-endpos`` ``--length``
|
||||
``-fixed-vo`` (removed; always the default)
|
||||
``-font`` ``--osd-font``
|
||||
``-forcedsubsonly`` ``--sub-forced-only``
|
||||
``-forceidx`` ``--index``
|
||||
``-format`` ``--audio-format``
|
||||
``-fsmode-dontuse`` (removed)
|
||||
``-fstype`` ``--x11-netwm`` (changed semantics)
|
||||
``-hardframedrop`` ``--framedrop=hard``
|
||||
``-identify`` (removed; use TOOLS/mpv_identify.sh)
|
||||
``-idx`` ``--index``
|
||||
``-lavdopts ...`` ``--vd-lavc-...``
|
||||
``-lavfdopts`` ``--demuxer-lavf-...``
|
||||
``-loop 0`` ``--loop=inf``
|
||||
``-mixer-channel`` AO suboptions (``alsa``, ``oss``)
|
||||
``-mixer`` AO suboptions (``alsa``, ``oss``)
|
||||
``-mouse-movements`` ``--input-cursor``
|
||||
``-msgcolor`` ``--msg-color``
|
||||
``-msglevel`` ``--msg-level`` (changed semantics)
|
||||
``-msgmodule`` ``--msg-module``
|
||||
``-name`` ``--x11-name``
|
||||
``-noar`` ``--no-input-appleremote``
|
||||
``-noautosub`` ``--no-sub-auto``
|
||||
``-noconsolecontrols`` ``--no-input-terminal``
|
||||
``-nosound`` ``--no-audio``
|
||||
``-osdlevel`` ``--osd-level``
|
||||
``-panscanrange`` ``--video-zoom``, ``--video-pan-x/y``
|
||||
``-playing-msg`` ``--term-playing-msg``
|
||||
``-pp ...`` ``'--vf=lavfi=[pp=...]'``
|
||||
``-pphelp`` (See FFmpeg libavfilter documentation.)
|
||||
``-rawaudio ...`` ``--demuxer-rawaudio-...``
|
||||
``-rawvideo ...`` ``--demuxer-rawvideo-...``
|
||||
``-spugauss`` ``--sub-gauss``
|
||||
``-srate`` ``--audio-samplerate``
|
||||
``-ss`` ``--start``
|
||||
``-ssf <sub>`` ``--sws-...``
|
||||
``-stop-xscreensaver`` ``--stop-screensaver``
|
||||
``-sub-fuzziness`` ``--sub-auto``
|
||||
``-sub`` ``--sub-file``
|
||||
``-subcp`` ``--sub-codepage``
|
||||
``-subdelay`` ``--sub-delay``
|
||||
``-subfile`` ``--sub-file``
|
||||
``-subfont-*`` ``--sub-text-*``, ``--osd-*``
|
||||
``-subfont-text-scale`` ``--sub-scale``
|
||||
``-subfont`` ``--sub-text-font``
|
||||
``-subfps`` ``--sub-fps``
|
||||
``-subpos`` ``--sub-pos``
|
||||
``-sws`` ``--sws-scaler``
|
||||
``-tvscan`` ``--tv-scan``
|
||||
``-use-filename-title`` ``--title='${filename}'``
|
||||
``-vc ffh264vdpau`` (etc.) ``--hwdec=vdpau``
|
||||
``-vobsub`` ``--sub-file`` (pass the .idx file)
|
||||
``-x W``, ``-y H`` ``--geometry=WxH`` + ``--no-keepaspect``
|
||||
``-xineramascreen`` ``--screen`` (different values)
|
||||
``-xy W`` ``--autofit=W``
|
||||
``-zoom`` Inverse available as ``--video-unscaled``
|
||||
``dvdnav://`` ``dvdnav://menu``
|
||||
``dvd://1`` ``dvd://0`` (0-based offset)
|
||||
=========================== ========================================
|
||||
|
||||
.. note::
|
||||
|
||||
``-opt val`` becomes ``--opt=val``.
|
||||
|
||||
.. note::
|
||||
|
||||
Quite some video filters, video outputs, audio filters, audio outputs, had
|
||||
changes in their option parsing. These aren't mentioned in the table above.
|
||||
|
||||
Also, some video and audio filters have been removed, and you have to use
|
||||
libavfilter (using ``--vf=lavfi=[...]`` or ``--af=lavfi=[...]``) to get
|
||||
them back.
|
||||
|
||||
input.conf and Slave Commands
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Table of renamed input commands:
|
||||
|
||||
This lists only commands that are not always gracefully handled by the
|
||||
internal legacy translation layer. If an input.conf contains any legacy
|
||||
commands, a warning will be printed when starting the player. The warnings
|
||||
also show the replacement commands.
|
||||
|
||||
Properties containing ``_`` to separate words use ``-`` instead.
|
||||
|
||||
+--------------------------------+----------------------------------------+
|
||||
| Old | New |
|
||||
+================================+========================================+
|
||||
| ``pt_step 1 [0|1]`` | ``playlist_next [weak|force]`` |
|
||||
| | (translation layer cannot deal with |
|
||||
| | whitespace) |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``pt_step -1 [0|1]`` | ``playlist_prev [weak|force] (same)`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``switch_ratio [<ratio>]`` | ``set video-aspect <ratio>`` |
|
||||
| | |
|
||||
| | ``set video-aspect 0`` (reset aspect) |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``step_property_osd <prop>`` | ``cycle <prop> <step>`` (wraps), |
|
||||
| ``<step> <dir>`` | ``add <prop> <step>`` (clamps). |
|
||||
| | ``<dir>`` parameter unsupported. Use |
|
||||
| | a negative ``<step>`` instead. |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``step_property <prop>`` | Prefix ``cycle`` or ``add`` with |
|
||||
| ``<step> <dir>`` | ``no-osd``: ``no-osd cycle <prop>`` |
|
||||
| | ``<step>`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``osd_show_property_text`` | ``show_text <text>`` |
|
||||
| ``<text>`` | The property expansion format string |
|
||||
| | syntax slightly changed. |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``osd_show_text`` | Now does the same as |
|
||||
| | ``osd_show_property_text``. Use the |
|
||||
| | ``raw`` prefix to disable property |
|
||||
| | expansion. |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``show_tracks`` | ``show_text ${track-list}`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``show_chapters`` | ``show_text ${chapter-list}`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``af_switch``, ``af_add``, ... | ``af set|add|...`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_start_scan`` | ``set tv-scan yes`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_set_channel <val>`` | ``set tv-channel <val>`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_step_channel`` | ``cycle tv-channel`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``dvb_set_channel <v1> <v2>`` | ``set dvb-channel <v1>-<v2>`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``dvb_step_channel`` | ``cycle dvb-channel`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_set_freq <val>`` | ``set tv-freq <val>`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_step_freq`` | ``cycle tv-freq`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_set_norm <norm>`` | ``set tv-norm <norm>`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_step_norm`` | ``cycle tv-norm`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
|
||||
.. note::
|
||||
|
||||
Due to lack of hardware and users using the TV/DVB/PVR features, and
|
||||
due to the need to cleanup the related command code, it's possible
|
||||
that the new commands are buggy or behave worse. This can be improved
|
||||
if testers are available. Otherwise, some of the TV code will be
|
||||
removed at some point.
|
||||
|
||||
Slave mode
|
||||
~~~~~~~~~~
|
||||
|
||||
* Slave mode was removed. A proper slave mode application needed tons of code
|
||||
and hacks to get
|
||||
it right. The main problem is that slave mode is a bad and incomplete
|
||||
interface, and to get around that, applications parsed output messages
|
||||
intended for users. It is hard to know which messages exactly are parsed by
|
||||
slave mode applications. This makes it virtually impossible to improve
|
||||
terminal output intended for users without possibly breaking something.
|
||||
|
||||
This is absolutely insane, and since initial improvements to **mpv** quickly
|
||||
made slave mode incompatible to most applications, it was removed as useless
|
||||
cruft. The client API (see below) is provided instead.
|
||||
|
||||
``--identify`` was replaced by the ``TOOLS/mpv_identify.sh`` wrapper script.
|
||||
|
||||
* For some time (until including release 0.4.x), mpv supported a
|
||||
``--slave-broken`` option. The following options are equivalent:
|
||||
|
||||
::
|
||||
|
||||
--input-file=/dev/stdin --input-terminal=no
|
||||
|
||||
|
||||
Assuming the system supports ``/dev/stdin``.
|
||||
|
||||
(The option was readded in 0.5.1 and sets exactly these options.)
|
||||
|
||||
* A JSON RPC protocol giving access to the client API is also supported. See
|
||||
`JSON IPC`_ for more information.
|
||||
|
||||
* **mpv** also provides a client API, which can be used to embed the player
|
||||
by loading it as shared library. (See ``libmpv/client.h`` in the sources.)
|
||||
It might also be possible to implement a custom slave mode-like protocol
|
||||
using Lua scripting.
|
||||
|
||||
Policy for Removed Features
|
||||
---------------------------
|
||||
|
||||
**mpv** is in active development. If something is in the way of more important
|
||||
development (such as fixing bugs or implementing new features), we sometimes
|
||||
remove features. Usually this happens only with old features that either seem
|
||||
to be useless, or are not used by anyone. Often these are obscure, or
|
||||
"inherited", or were marked experimental, but never received any particular
|
||||
praise by any users.
|
||||
|
||||
Sometimes, features are replaced by something new. The new code will be either
|
||||
simpler or more powerful, but doesn't necessarily provide everything the old
|
||||
feature did.
|
||||
|
||||
We can not exclude that we accidentally remove features that are actually
|
||||
popular. Generally, we do not know how much a specific functionality is used.
|
||||
If you miss a feature and think it should be re-added, please open an issue
|
||||
on the mpv bug tracker. Hopefully, a solution can be found. Often, it turns
|
||||
out that re-adding something is not much of a problem, or that there are
|
||||
better alternatives.
|
||||
|
||||
Why this Fork?
|
||||
--------------
|
||||
|
||||
mplayer2 is practically dead, and mpv started out as a branch containing
|
||||
new/experimental development. (Some of it was merged right *after* the fork
|
||||
was made public, seemingly as an acknowledgment that development, or at
|
||||
least merging, should have been more active.)
|
||||
|
||||
MPlayer is focused on not breaking anything, but is stuck with a horrible
|
||||
codebase resistant to cleanup. (Unless you do what mpv did - merciless and
|
||||
consequent pruning of bad, old code.) Cleanup and keeping broken things
|
||||
conflict, so the kind of development mpv strives for can't be done within
|
||||
MPlayer due to clashing development policies.
|
||||
|
||||
Additionally, mplayer2 already had lots of changes over MPlayer, which would
|
||||
have needed to be backported to the MPlayer codebase. This would not only
|
||||
have been hard (several years of diverging development), but also would have
|
||||
been impossible due to the aforementioned MPlayer development policy.
|
||||
@@ -20,9 +20,8 @@ shortcomings:
|
||||
part is this pieces are spread apart in the configure and copy pasted for
|
||||
any single case. That brings us to..
|
||||
|
||||
2) --enable-feature has to be overridden by the user and helps them understand that
|
||||
they have libraries missing and should install them for the feature to be
|
||||
enabled.
|
||||
2) --enable-feature has to override the user and help him understand that he
|
||||
has libraries missing and should install them for the feature to be enabled.
|
||||
|
||||
3) Must be customizable, hackable, pleasant to the developer eyes and to work
|
||||
with in general.
|
||||
|
||||
@@ -1,39 +1,21 @@
|
||||

|
||||
mpv
|
||||
===
|
||||
|
||||
## mpv
|
||||
[](https://travis-ci.org/mpv-player/mpv)
|
||||
|
||||
--------------
|
||||
[](https://scan.coverity.com/projects/1232)
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
* [Overview](#overview)
|
||||
* [Downloads](#downloads)
|
||||
* [Compilation](#compilation)
|
||||
* [FFmpeg vs. Libav](#ffmpeg-vs-libav)
|
||||
* [Release cycle](#release-cycle)
|
||||
* [Bug reports](#bug-reports)
|
||||
* [Contributing](#contributing)
|
||||
* [Relation to MPlayer and mplayer2](#relation-to-mplayer-and-mplayer2)
|
||||
* [Wiki](https://github.com/mpv-player/mpv/wiki)
|
||||
* [Man pages](http://mpv.io/manual/master/)
|
||||
* [Contact](#contact)
|
||||
* [License](#license)
|
||||
|
||||
## Overview
|
||||
|
||||
|
||||
**mpv** is a media player based on MPlayer and mplayer2. It supports a wide
|
||||
**mpv** is a movie player based on MPlayer and mplayer2. It supports a wide
|
||||
variety of video file formats, audio and video codecs, and subtitle types.
|
||||
|
||||
Releases can be found on the [release list][releases].
|
||||
|
||||
## Downloads
|
||||
|
||||
|
||||
For semi-official builds and third-party packages please see
|
||||
[mpv.io](http://mpv.io/installation/).
|
||||
|
||||
## Compilation
|
||||
If you are wondering what's different from mplayer2 and MPlayer you can read
|
||||
more about the [changes][changes].
|
||||
|
||||
Compilation
|
||||
-----------
|
||||
|
||||
Compiling with full features requires development files for several
|
||||
external libraries. Below is a list of some important requirements.
|
||||
@@ -64,25 +46,16 @@ Essential dependencies (incomplete list):
|
||||
|
||||
- gcc or clang
|
||||
- X development headers (xlib, X extensions, libvdpau, libGL, libXv, ...)
|
||||
- Audio output development headers (libasound/ALSA, pulseaudio)
|
||||
- FFmpeg libraries (libavutil libavcodec libavformat libswscale libavfilter
|
||||
and either libswresample or libavresample)
|
||||
At least FFmpeg 2.4.0 or Libav 11 is required.
|
||||
- zlib
|
||||
- iconv (normally provided by the system libc)
|
||||
- libass (OSD, OSC, text subtitles)
|
||||
- Lua (optional, required for the OSC pseudo-GUI and youtube-dl integration)
|
||||
- libjpeg (optional, used for screenshots only)
|
||||
- Enca (optional, for subtitle charset detection)
|
||||
- vdpau and vaapi libraries for hardware decoding on Linux (optional)
|
||||
- Audio output development headers (libasound, pulseaudio)
|
||||
- FFmpeg libraries (libavutil libavcodec libavformat libswscale libavresample)
|
||||
At least FFmpeg 2.1.4 or Libav 10 is required.
|
||||
- libjpeg (for screenshots)
|
||||
- Lua (strictly speaking optional, but required for the OSC pseudo-GUI)
|
||||
|
||||
Libass dependencies:
|
||||
|
||||
- gcc or clang, yasm on x86 and x86_64
|
||||
- fribidi, freetype, fontconfig development headers (for libass)
|
||||
- harfbuzz (optional, required for correct rendering of combining characters,
|
||||
particularly for correct rendering of non-English text on OSX, and
|
||||
Arabic/Indic scripts on any platform)
|
||||
|
||||
FFmpeg dependencies:
|
||||
|
||||
@@ -103,19 +76,16 @@ If you are running Mac OSX and using homebrew we provide [homebrew-mpv][homebrew
|
||||
to date formula that compiles mpv with sensible dependencies and defaults for
|
||||
OSX.
|
||||
|
||||
If you want to build a Windows binary, you either have to use MSYS2 and MinGW,
|
||||
or cross-compile from Linux with MinGW. See [Windows compilation][windows_compilation].
|
||||
|
||||
## FFmpeg vs. Libav
|
||||
|
||||
FFmpeg vs. Libav
|
||||
----------------
|
||||
|
||||
Generally, mpv should work with the latest release as well as the git version
|
||||
of both FFmpeg and Libav. But FFmpeg is preferred, and some mpv features work
|
||||
with FFmpeg only (subtitle formats in particular).
|
||||
with FFmpeg only. See the [wiki article][ffmpeg_vs_libav] about the issue.
|
||||
|
||||
|
||||
## Release cycle
|
||||
|
||||
Release cycle
|
||||
-------------
|
||||
|
||||
Every few months, a new release is cut off of the master branch and is assigned
|
||||
a 0.X.0 version number.
|
||||
@@ -133,57 +103,35 @@ Releases other than the latest release are unsupported and unmaintained.
|
||||
|
||||
See the [release policy document][release-policy] for more information.
|
||||
|
||||
## Bug reports
|
||||
|
||||
Bug reports
|
||||
-----------
|
||||
|
||||
Please use the [issue tracker][issue-tracker] provided by GitHub to send us bug
|
||||
reports or feature requests.
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
For small changes you can just send us pull requests through GitHub. For bigger
|
||||
changes come and talk to us on IRC before you start working on them. It will
|
||||
make code review easier for both parties later on.
|
||||
|
||||
## Relation to MPlayer and mplayer2
|
||||
|
||||
|
||||
mpv is based on mplayer2, which in turn is based on the original MPlayer
|
||||
(also called mplayer, mplayer-svn, mplayer1). Many changes have been made, a
|
||||
large part of which is incompatible or completely changes how the player
|
||||
behaves. Although there are still many similarities to its ancestors, mpv
|
||||
should generally be treated as a completely different program.
|
||||
|
||||
mpv was forked because we wanted to modernize MPlayer. This includes
|
||||
removing cruft (including features which stopped making sense 10 years ago),
|
||||
and of course adding modern features. Such huge and intrusive changes made it
|
||||
infeasible to work directly with MPlayer, which is mostly focused on
|
||||
preservation, so a fork had to be made. (Actually, mpv is based on mplayer2,
|
||||
which already started this process of removing cruft.)
|
||||
|
||||
In general, mpv should be considered a completely new program, rather than a
|
||||
MPlayer drop-in replacement.
|
||||
|
||||
If you are wondering what's different from mplayer2 and MPlayer, an incomplete
|
||||
list of changes is located [here][mplayer-changes].
|
||||
|
||||
## Contact
|
||||
|
||||
Contact
|
||||
-------
|
||||
|
||||
Most activity happens on the IRC channel and the github issue tracker. The
|
||||
mailing lists are mostly unused.
|
||||
|
||||
- **Github issue tracker**: [issue tracker][issue-tracker] (report bugs here)
|
||||
- **User IRC Channel**: `#mpv` on `irc.freenode.net`
|
||||
- **Developer IRC Channel**: `#mpv-devel` on `irc.freenode.net`
|
||||
- **User IRC Channel**: `#mpv-player` on `irc.freenode.net`
|
||||
- **Developer IRC Channel**: `#mpv-player-dev` on `irc.freenode.net`
|
||||
- **Users Mailing List**: `mpv-users@googlegroups.com` ([Archive / Subscribe][mpv-users]).
|
||||
- **Devel Mailing List**: `mpv-devel@googlegroups.com` ([Archive / Subscribe][mpv-devel])
|
||||
|
||||
To contact the `mpv` team in private write to `mpv-team@googlegroups.com`. Use
|
||||
only if discretion is required.
|
||||
|
||||
[releases]: https://github.com/mpv-player/mpv/releases
|
||||
[changes]: https://github.com/mpv-player/mpv/blob/master/DOCS/man/changes.rst
|
||||
[mpv-build]: https://github.com/mpv-player/mpv-build
|
||||
[homebrew-mpv]: https://github.com/mpv-player/homebrew-mpv
|
||||
[issue-tracker]: https://github.com/mpv-player/mpv/issues
|
||||
@@ -191,10 +139,3 @@ only if discretion is required.
|
||||
[mpv-devel]: https://groups.google.com/forum/?hl=en#!forum/mpv-devel
|
||||
[ffmpeg_vs_libav]: https://github.com/mpv-player/mpv/wiki/FFmpeg-versus-Libav
|
||||
[release-policy]: https://github.com/mpv-player/mpv/blob/master/DOCS/release-policy.md
|
||||
[windows_compilation]: https://github.com/mpv-player/mpv/blob/master/DOCS/compile-windows.md
|
||||
[mplayer-changes]: https://github.com/mpv-player/mpv/blob/master/DOCS/mplayer-changes.rst
|
||||
|
||||
## License
|
||||
|
||||
|
||||
[GPLv2](https://github.com/mpv-player/mpv/blob/master/LICENSE)
|
||||
+1
-628
@@ -1,629 +1,3 @@
|
||||
Release 0.9.2
|
||||
=============
|
||||
|
||||
Changes
|
||||
-------
|
||||
|
||||
- The Lua check now also checks for `lua52.pc`, as used by Arch Linux testing.
|
||||
- (X11) `vo_opengl`'s `icc-profile-auto` now queries the current ICC profile
|
||||
relative to the center of the window.
|
||||
- `ao_coreaudio`, `ao_alsa` now support adding dummy padding channels for
|
||||
better compatibility with hardware decoders that only support specific
|
||||
channel counts (e.g. 5.1 now should work on a decoder that only accepts 7.1).
|
||||
- Channel fallback (in case the audio device doesn't natively support a given
|
||||
channel layout) has been improved.
|
||||
- `vf_vapoursynth` now rejects unaligned video instead of outputting corrupted
|
||||
video.
|
||||
- mpv now tries to autoload `.sup` subtitles as well.
|
||||
|
||||
Bug fixes
|
||||
---------
|
||||
|
||||
- `vo_opengl`'s default for `fbo-format` is now `rgba16`, to avoid rounding
|
||||
errors when using non-default `cscale` (issue #1918).
|
||||
- Improved framedrop behavior when playing video that has higher framerate
|
||||
than the display (issue #1897).
|
||||
- Trying to play a directory will no longer spam `Connection lost!` to the
|
||||
console log.
|
||||
- (Linux) Several `vo_rpi` bugfixes.
|
||||
- (Linux) Several `vo_drm` bugfixes. Pan&Scan is now supported.
|
||||
- (X11) Fix fullscreen behavior on certain window managers (issues #1937,
|
||||
#1920).
|
||||
- (OSX) The OSD no longer always shows up on startup.
|
||||
- (OSX) Several `ao_coreaudio` and `ao_coreaudio_exclusive` bugfixes.
|
||||
- (OSX) Fixed potential crash on exit when using Cocoa.
|
||||
- (ClientAPI) `vo_opengl_cb` now actually applies options changed at runtime.
|
||||
- (OSX, ClientAPI) Cocoa now works when both the `cplayer` (`mpv`) and `libmpv`
|
||||
are built at the same time; however, `libmpv` now always creates an
|
||||
application singleton. Cocoa has to be disabled completely to prevent
|
||||
`libmpv` from creating the singleton.
|
||||
|
||||
This listing is not complete. A complete changelog can be seen by running
|
||||
`git log v0.9.1..` in the git repository or by visiting
|
||||
https://github.com/mpv-player/mpv/compare/v0.9.1...release/0.9.
|
||||
|
||||
Release 0.9.1
|
||||
=============
|
||||
|
||||
Changes
|
||||
-------
|
||||
|
||||
- mpv's IRC channel moved from #mpv-player to #mpv on chat.freenode.net.
|
||||
- Documentation updates.
|
||||
- The default value for the `--ytdl-format` option is now `best`, in order to
|
||||
work around `youtube-dl`'s 2015.04.26 release enabling DASH by default, as
|
||||
FFmpeg / Libav do not yet properly support DASH.
|
||||
- When seeking, the current timestamp will show the predicted seek timestamp
|
||||
instead, until the final timestamp is resolved. Improves UI responsiveness
|
||||
on slow streams and/or large seeks.
|
||||
|
||||
Bug fixes
|
||||
---------
|
||||
|
||||
- Corrected the release marker on DOCS/client-api-changes. The release manager
|
||||
forgot to fix it before release...
|
||||
- Fix `vo_vdpau` rendering garbage lines on H.264 video with non-mod16 size
|
||||
(issue #1863).
|
||||
- Fix a crash on exit if the "sub_reload" command had run successfully.
|
||||
- Fixed seeking with the mouse when `osc-seekbarstyle=bar` is set (issue
|
||||
#1876).
|
||||
- (IPC) Fixed encoding of UTF-8 data in JSON (issue #1874).
|
||||
|
||||
New features
|
||||
------------
|
||||
|
||||
This listing is not complete. A complete changelog can be seen by running
|
||||
`git log v0.9.0..v0.9.1` in the git repository or by visiting
|
||||
https://github.com/mpv-player/mpv/compare/v0.9.0...v0.9.1.
|
||||
|
||||
Release 0.9.0
|
||||
=============
|
||||
|
||||
Changes
|
||||
-------
|
||||
|
||||
Changes that may break users' config files have been annotated with a `(!)`.
|
||||
|
||||
- Note: mpv is not compatible with Lua 5.3. Lua 5.1 or 5.2 is required.
|
||||
- The minimum required libass version is now 0.12.1 or newer.
|
||||
- The minimum required FFmpeg version is now 2.4.0 (equiv. Libav 11) or newer.
|
||||
- The internal libmpg123 support was removed. This was already not used by
|
||||
default in the previous release.
|
||||
- `(!)` The LIRC support was removed. Configure LIRC remotes as input devices
|
||||
instead.
|
||||
- `(!)` The Linux Joystick support was removed.
|
||||
- `(!)` `vf_screenshot` was removed, as they are now handled at a VO level and
|
||||
is compatible with all VOs.
|
||||
- `(!)` `--ass-use-margins` has been renamed to `--sub-use-margins` and applies
|
||||
only to plain-text (non-ASS) subtitles (enabled by default). The new
|
||||
`--ass-force-margins` option applies only to ASS subtitles (disabled by
|
||||
default). To get the old behaviour back, enable both at the same time.
|
||||
- `(!)` The `--sub-scale-with-window` option now only applies to plain text
|
||||
(non-ASS) subtitles (enabled by default). The new `--ass-scale-with-window`
|
||||
option does the same but only with ASS subtitles (disabled by default).
|
||||
- `(!)` The range for the `param1` for the `gaussian` `vo_opengl` scaler has
|
||||
been redefined. Instead of being an arbitrary 1-100 range, have a default
|
||||
value of 1.0, and anything higher is blurrier.
|
||||
- `(!)` The `seek`, `playlist_next, `playlist_prev`, `loadfile` and `loadlist`
|
||||
parameters no longer accept numerical parameters where symbolic parameter
|
||||
names exist.
|
||||
- `(!)` `vo_opengl` changes:
|
||||
- `(!)` The `smoothmotion` suboption has been renamed to `interpolation`.
|
||||
The old name is still supported for now.
|
||||
- `(!)` The `bilinear_slow` scaler has been renamed to `triangle`.
|
||||
- `(!)` `scale-down` has been renamed to `dscale` and now has its own set of
|
||||
config options (e.g. `dscale-radius`).
|
||||
- `(!)` Scaler radius no longer defaults to `3` but to a preferred value
|
||||
that may be different for each filter.
|
||||
- The `scale-radius` option may now go down as low as `0.5`, which is the
|
||||
value used by the `nearest` filter.
|
||||
- `spline36` is the new `cscale` default for `opengl-hq`. This might break
|
||||
setups that use `fbo-format=rgb8`. To work around it, leave `fbo-format`
|
||||
as its default, or set to something higher than 8, or set `cscale=bilinear`,
|
||||
the previous default.
|
||||
- `(!)` `vf_format` no longer converts video to YUYV if there is no parameter.
|
||||
Video is now passed unchanged unless a format is specifically requested.
|
||||
- `(!)` The `--colormatrix`, `--colormatrix-input-range`,
|
||||
`--colormatrix-output-range` and `--colormatrix-primaries` options have been
|
||||
converted into `vf_format` suboptions. See commit 27715b7 and the manual for
|
||||
details.
|
||||
- `vf_mirror`'s implementation was replaced with calling into `libavfilter`'s
|
||||
`vf_hflip` filter, thus depending on `libavfilter` to function.
|
||||
- The `device` subption to `ao_wasapi` has been deprecated in favor of
|
||||
`--audio-device`.
|
||||
- `--video-rotate` now allows 360 as an argument instead of stopping at 359.
|
||||
- Several improvements to `af_scaletempo`.
|
||||
- Options that have multiple options and also include a "yes" option now
|
||||
default to that if specified with no arguments.
|
||||
- The default value of `--cache-default` is now 150000 (153.6 MB, ~146 MiB).
|
||||
- JPEG screenshots now use the same subsampling as the source video. The images
|
||||
are still RGB regardless of source format though.
|
||||
|
||||
Bug fixes
|
||||
---------
|
||||
|
||||
- mpv no longer saves position on files that can't be resumed (issue #1701).
|
||||
- (X11) Fix the player thinking the mouse has left the window in some WMs /
|
||||
embeddings (issue #1672).
|
||||
- mpv no longer freezes on wayland when the compositor stops asking it to draw
|
||||
itself (e.g. when minimized) (issue #249).
|
||||
- `.ac3` files are no longer rejected by `--audio-file-auto` (issue #1759).
|
||||
- `ao_wasapi` now automatically enables `exclusive` when passthrough is
|
||||
attempted (issue #1742).
|
||||
- Attempt to fix flickering on Intel VAAPI drivers with `--hwdec=vaapi` and
|
||||
`--vo=opengl` (issue #1765).
|
||||
- `youtube-dl` will no longer download video streams when video playback
|
||||
is disabled with `--no-video`.
|
||||
- (Windows) mpv now prevents system sleep when playing a video-only file.
|
||||
Previously, only files with an opened audio track would prevent sleep.
|
||||
|
||||
New features
|
||||
------------
|
||||
|
||||
- `vo_opengl` features:
|
||||
- Added `ewa_ginseng`, `ewa_hanning`, `robidoux`, `robidouxsharp`,
|
||||
`oversample` and `haasnsoft` scalers.
|
||||
- There are now `ewa_lanczossoft` and `ewa_lanczossharp` aliases to
|
||||
`ewa_lanczos` that are tuned to be blurrier and sharper, respectively.
|
||||
- Added `gamma-auto` option that uses ambient light sensors to automatically
|
||||
adjust the video gamma. See commit c028d78 for details.
|
||||
- Added `blend-subtitles` option to draw subtitles directly into the video
|
||||
instead of rendered afterwards. Potentially necessary for correct rendering
|
||||
with files that use ASS subtitles for typesetting in combination with an
|
||||
`icc-profile`. There is a default option for drawing after upscaling,
|
||||
and a `video` option for drawing before upscaling. See details and warning
|
||||
on the manual.
|
||||
- There is now a `tscale` option, used to choose the temporal scaler used
|
||||
in the `interpolation` mode (previously `smoothmotion`).
|
||||
- There is a new `scale-blur` parameter to adjust the amount of blur that
|
||||
most of the filters produce. Deviating from the default may introduce
|
||||
artifacts in EWA filters.
|
||||
- (Windows) There is now a `dwmflush` option that might help improve
|
||||
rendering of high-fps video. Disabled by default. See manual for options.
|
||||
- New Linux-only `vo_drm` video output driver. Uses the direct rendering /
|
||||
kernel modesetting drivers to draw directly to the framebuffer, but with
|
||||
no hardware acceleration. See manual for details.
|
||||
- New `pseudo-gui` builtin profile, automatically used when launched from
|
||||
`mpv.desktop` by opening `mpv.exe` on windows (`mpv.com` still works as
|
||||
usual), or by opening the `mpv.app` bundle. The `pseudo-gui` tries to make
|
||||
the player window behave closer to what a desktop player would do, by not
|
||||
immediately closing and allowing the user to drag&drop files for playback.
|
||||
See manual for details.
|
||||
- mpv can now play directories by automatically playing their contents instead.
|
||||
Works everywhere but on Windows, due to issues with Windows' C runtime.
|
||||
- Add support to pitch correct stretched audio with librubberband.
|
||||
- Add support for the Raspberry Pi 2's hardware decoder when FFmpeg (or Libav)
|
||||
is built with `--enable-mmal`. See commit 8fff125 for details.
|
||||
- The `--cache` option now accepts a "yes" option, that always enables a
|
||||
`--cache-default`-sized cache on all cases a cache can be used, unless
|
||||
`--cache-default` disables caching.
|
||||
- `ao_pulse`, `ao_coreaudio` and `ao_wasapi` now support device hotplugging.
|
||||
- New `--osd-align-x` and `--osd-align-y` options can be used to align the OSD
|
||||
independently from subtitles.
|
||||
- New `--osd-bold` and `--sub-text-bold` options can be enabled to bold all
|
||||
OSD or plain-text subtitle text, respectively.
|
||||
- Added a default keybind to the `u` key that enables/disables ASS style
|
||||
overriding. When enabled, is equivalent to `--ass-style-override=force`.
|
||||
- There is now a `MOUSE_ENTER` keybind, that is called when the mouse cursor
|
||||
enters the VO from outside.
|
||||
- The new `--ytdl-params` option can be set to arguments that are always given
|
||||
to `youtube-dl` invocations. There is no sanity checking, so invalid options
|
||||
can prevent `mpv` from working with http URLs.
|
||||
- There's a new `--demuxer-mkv-fix-timestamps` option, enabled by default, that
|
||||
tries to guess more accurate video timestamps by using FPS information, if
|
||||
available. See manual for details.
|
||||
- The new `--window-scale` option can be used to scale the video window by the
|
||||
specified multiplier, before other options such as `--autofit` are applied.
|
||||
- `vo_direct3d_shaders` now supports NV12 colorspace without using stretchrect,
|
||||
but it seems no drivers actually support that.
|
||||
- (Client API) Added a `rescan_external_files` command, as requested on issue
|
||||
#1586.
|
||||
- (Client API) If enabled, initializing the Client API will now also load the
|
||||
user's `mpv.conf`.
|
||||
- (Client API) There's a new `mpv_opengl_cb_report_flip()` call for API users
|
||||
to call to inform mpv of when exactly a frame was displayed.
|
||||
- (Client API) The `mpv_opengl_cb_render()` function was deprecated in favor
|
||||
of the new, simpler `mpv_opengl_cb_draw()` function.
|
||||
- (Client API) There is a new `screenshot_raw` command. See `input.rst` for
|
||||
details.
|
||||
- The `--input-file` argument may now also be a file descriptor in the form
|
||||
"fd://N", where N is the FD number.
|
||||
|
||||
This listing is not complete. A complete changelog can be seen by running
|
||||
`git log v0.8.0..v0.9.0` in the git repository or by visiting
|
||||
https://github.com/mpv-player/mpv/compare/v0.8.0...v0.9.0 (only 250 commits).
|
||||
|
||||
Release 0.8.3
|
||||
=============
|
||||
|
||||
Changes
|
||||
-------
|
||||
|
||||
- Documentation fixes and updates.
|
||||
- (Client API) Clarify `mpv_opengl_cb_render`'s viewport parameter behavior.
|
||||
|
||||
Bug fixes
|
||||
---------
|
||||
|
||||
- (X11) Fix crash on `vo_xv:no-colorkey` with the Overlay adapter. (bug #1629)
|
||||
- (X11) `--stop-screensaver` is now implemented by calling into
|
||||
`xdg-screensaver`, fixing some compatibility issues that prevented it from
|
||||
actually stopping screensavers.
|
||||
- Make the video equalizer work correctly on some VAAPI drivers. (bug #1647)
|
||||
- Prevent OSD from disappearing when clicking on mozplugger. (bug #1672)
|
||||
- The new DVB-S2 support code, using S2API, now builds on FreeBSD.
|
||||
- Fix decoding of seekable matroska from unseekable network stream. (bug #1656)
|
||||
- (OSX) Fix crashing when closing a VO's window (usually at exit). (bug #1657)
|
||||
- (OSX) Unhide the mouse cursor when over the Dock or Launchpad. (bug #513)
|
||||
- (OSX) Fix mouse cursor autohiding when the player is fullscreen.
|
||||
- `vf_vavpp` (VAAPI postprocessing) now deinterlaces video correctly.
|
||||
- `smb://` streams now use the stream cache (used to be inefficient).
|
||||
- (Windows) Do not hide the mouse cursor when it is hovering the window menu.
|
||||
- Fix 8-channel output on `ao_jack`. (bug #1688)
|
||||
- Fix `--mf-fps` parameter on JPEG files. (bug #1689)
|
||||
- Fix anamorphic scaling being ignored if it was very minor.
|
||||
|
||||
This listing is not complete. A complete changelog can be seen by running
|
||||
`git log v0.8.2..v0.8.3` in the git repository or by visiting
|
||||
https://github.com/mpv-player/mpv/compare/v0.8.2...v0.8.3.
|
||||
|
||||
Release 0.8.2
|
||||
=============
|
||||
|
||||
Bug fixes
|
||||
---------
|
||||
|
||||
- Fix OSD placement accidentally messed up in 0.8.1 (commit 22863d6).
|
||||
|
||||
Release 0.8.1
|
||||
=============
|
||||
|
||||
Changes
|
||||
-------
|
||||
|
||||
- DOCS/client-api-changes has been correctly updated for the v0.8.0 release
|
||||
series.
|
||||
- Quality and major perfomance improvements to smoothmotion.
|
||||
- Silence the "[ytdl_hook] WARNING: video doesn't have subtitles" warning.
|
||||
- Other documentation updates.
|
||||
|
||||
Bug fixes
|
||||
---------
|
||||
|
||||
- Attempt to fix OpenGL shader compilation on Intel windows drivers. (bug
|
||||
#1536)
|
||||
- Attempt to improve the OpenGL shader's compatibility with GLES2.
|
||||
- (Windows) Fix noise when seeking while using wasapi:exclusive. (bug #1529)
|
||||
- Fix the waf-based build system when used with newer versions of waf with
|
||||
python3.
|
||||
- Documentation fixes. (includes bug #1608)
|
||||
|
||||
New features
|
||||
------------
|
||||
|
||||
- mpv now tries to load '.vtt' subtitles.
|
||||
|
||||
This listing is not complete. A complete changelog can be seen by running
|
||||
`git log v0.8.0..v0.8.1` in the git repository or by visiting
|
||||
https://github.com/mpv-player/mpv/compare/v0.8.0...v0.8.1.
|
||||
|
||||
Release 0.8.0
|
||||
=============
|
||||
|
||||
Changes
|
||||
-------
|
||||
|
||||
Changes that may break users' config files have been annotated with a `(!)`.
|
||||
|
||||
- `(!)` vo_opengl_old has been removed. OpenGL rendering now requires hardware
|
||||
that can do at least OpenGL 2.1, the oldest version supported by vo_opengl.
|
||||
- `(!)` vf_pp has been removed. A version of it can still be accessed through
|
||||
lavfilter (e.g. --vf=lavfi=[pp...]), but it receives no QP information.
|
||||
Also, vf_dlopen no longer passes QP information to its loaded plugin either
|
||||
(it's always 0).
|
||||
- `(!)` vf_softpulldown, vf_swapuv, vf_phase, vf_divtc and vf_ilpack have all
|
||||
been removed. Ports or alternative versions of these filters are available
|
||||
through libavfilter (vf_lavfi).
|
||||
- vf_pullup and vf_noise now are simply wrappers to their libavfilter
|
||||
equivalents. Both are only currently available on FFmpeg (not Libav).
|
||||
- `(!)` ao_portaudio has been removed. There is good support for the native
|
||||
audio drivers of all major desktop platforms, as well as ao_sdl and
|
||||
ao_openal as fallbacks.
|
||||
- `(!)` vo_opengl's `lscale` suboption has been renamed to `scale`; `lradius`
|
||||
is now `scale-radius`, `lparam1` and `lparam2` are now respectively
|
||||
`scale-param1` and `scale-param2`; `lscale-down` is now `scale-down`.
|
||||
The `cscale` suboption remains as is.
|
||||
- `(!)` Several of the `vo_opengl` radius-preset aliases supported by `scale`
|
||||
have been removed; use `scale-radius` to set if needed. For example, use
|
||||
`--vo=opengl:scale=lanczos:scale-radius=2` instead of `scale=lanczos2`.
|
||||
The default radius is recommended for most filters.
|
||||
- `(!)` vo_opengl no longer supports the `stereo` suboption. The anaglyph
|
||||
effect can be reproduced with the stereo3d filter. The quadbuffer support,
|
||||
which requires expensive specialized hardware to begin with, is removed.
|
||||
- `(!)` The `approx-gamma` suboption to vo_opengl has been removed. The
|
||||
BT.1886 specification says that it's actually how it's supposed to be done
|
||||
so it is now the default when `srgb` or `icc-profile` are enabled. This does
|
||||
not include BT.1886's gamma drop.
|
||||
- `(!)` The `no-scale-sep` and `indirect` suboptions to vo_opengl have been
|
||||
removed. These are now autodetected and enabled whenever they would have
|
||||
benefit.
|
||||
- `(!)` The `--lua` and `--lua-opts` parameters / options are now called
|
||||
`--script` and `--script-opts`, respectively. The `lua` subdir of the mpv
|
||||
config dir is also now expected to be called `scripts` instead.
|
||||
- `(!)` The `--fixed-vo` option has been removed. It has been the default for
|
||||
a long time anyway, and disabling fixed-vo is not useful.
|
||||
- vo_opengl_hq has been updated to take into account new features.
|
||||
`fancy-downscaling` and `sigmoid-upscaling` are enabled,
|
||||
"mitchell" is now the default for `scale-down`.
|
||||
- The `sub-visibility` OSD message is now clearer about whether subtitles
|
||||
are hidden or just not available / selected.
|
||||
- The device IDs given to `--audio-device` for use with ao_coreaudio now use
|
||||
UIDs, so they don't change when devices are added/removed or after reboots.
|
||||
- `--msg-level` now also accepts ',' as separator.
|
||||
- (Client API) The client API now refuses to initialize if the LC_NUMERIC
|
||||
locale is not "C".
|
||||
- (Client API) The native type of the `msg-level` parameter is now a key-value
|
||||
list. Setting or reading it as a string still works.
|
||||
- (Slave API) The `get_property` command is now deprecated.
|
||||
- Documentation updates.
|
||||
- PDF documentation is now disabled by default due to rst2pdf being fickle,
|
||||
causing weird build errors.
|
||||
- Print desync messages with negative A/V sync as well. While rare, it could
|
||||
happen with some uses of `--autosync`.
|
||||
|
||||
Bug fixes
|
||||
---------
|
||||
|
||||
- (Windows) Avoid resizing the video window when player is minimized, might
|
||||
address bug #1547.
|
||||
- (NetBSD) Fix build with v4l2.
|
||||
- (Linux) Attempt to address conflicts with the pulseaudio mixer. (bug #1578)
|
||||
- Multiple cdda:// fixes. (bugs #1555, #1560)
|
||||
- VP9 timestamps no longer cause "missing PTS" warnings with new enough FFmpeg
|
||||
builds.
|
||||
- Fix a crash when using H.264 hardware decoding on new enough libavcodecs.
|
||||
(bug #1587)
|
||||
|
||||
New features
|
||||
------------
|
||||
|
||||
- vo_opengl now supports frame blending to eliminate stuttering when the video
|
||||
framerate does not nicely match the display framerate through the
|
||||
`smoothmotion` suboption. This is not meant to artificially increase the
|
||||
video's FPS, so there is no "soap opera effect" or difficulties with some
|
||||
video types (e.g. anime).
|
||||
- vo_opengl now supports sigmoidal upscaling (e.g. for fullscreen), which
|
||||
reduces ringing induced by upscaling, enabled through the
|
||||
`sigmoid-upscaling` suboption.
|
||||
- vo_opengl now supports ewa_lanczos (Jinc) scaling, which provides higher
|
||||
quality with less aliasing. It supports an experimental `scale-antiringing`
|
||||
parameter, which tries to further reduce video ringing.
|
||||
- vo_opengl now has a `linear-scaling` suboption, that makes the scalers work
|
||||
in linear light. Implied by the `srgb`, `icc-profile` or the new
|
||||
`sigmoid-upscaling` suboption.
|
||||
- vo_opengl has improved downscaling for higher downscale ratios when
|
||||
`fancy-downscaling` is enabled.
|
||||
- Add `--keep-open=always` to make `--keep-open` apply to all files instead of
|
||||
only the last.
|
||||
- mpv now filters the tags that are printed on the console to try to hide
|
||||
useless metadata. The filter works as a whitelist, and can be configured
|
||||
with the `--display-tags` option.
|
||||
- Add a `--sub-scale-by-window` option that, when set to 'no', prevents
|
||||
subtitles from changing their pixel size when the window changes sizes.
|
||||
- vo_opengl now technically has GLES 2 and 3 support (but not GLES 1). GLES 3
|
||||
support is only tested on Mesa's software emulation. GLES 2 has been tested
|
||||
on nvidia drivers. Both GLES modes are feature deficient and inefficient due
|
||||
to GLES limitations, so they should not be preferred over the standard
|
||||
OpenGL mode.
|
||||
- (X11) vo_opengl now supports the `icc-profile-auto` option on X11 hosts.
|
||||
- The 'A' key now by default cycles through a list of preset aspect ratios.
|
||||
Meant to be used to work around broken files.
|
||||
- There is now a "force" mode for `--loop`. Works like "inf", but tries to
|
||||
open files/streams even if there was an error on the previous attempt.
|
||||
- There is now a `--log-file` option to write mpv's log messages to a specifed
|
||||
file.
|
||||
- There is now a `--audio-file-auto` option to automatically load an external
|
||||
audio file with certain constraints. Will only load external audio if the
|
||||
playing file has a video stream. Set to "exact" by default. (bug #967)
|
||||
- There is now a `--network-timeout` option to specify a timeout in seconds
|
||||
for network access. If 0 (default), uses the libavformat default. If a
|
||||
protocol that doesn't support timeouts is used, this option is ignored.
|
||||
- (X11) The XF86 special keys are now all mappable in `input.conf`. All keys
|
||||
documented in `XF86keysym.h` are available, but only as their numeric codes.
|
||||
- (Linux) The DVB implementation now supports DVB-S2 through S2API.
|
||||
- (Linux) The VDR format for `channels.conf` is now supported and preferred.
|
||||
See http://linuxtv.org/vdrwiki/index.php/Syntax_of_channels.conf for the
|
||||
syntax. Tuning to DVB-S2 channels requires the VDR-format `channels.conf`.
|
||||
- (Linux) There is now a `--dvbin-full-transponder` option for handling
|
||||
special broadcast cases where PIDs switch, or just to work around incomplete
|
||||
PID data.
|
||||
- (Client API) There is now an opengl_cb VO, which receives the OpenGL context
|
||||
from the libmpv client. This allows a client to render libmpv video directly
|
||||
to a provided OpenGL context without having to use --wid embedding.
|
||||
- (Client API) The aforementioned --wid parameter can now be set at any time,
|
||||
but has no effect if a file is already loaded.
|
||||
- (Client API) The list of DVD titles can now be queried.
|
||||
- (Client API) There is now a `filtered-metadata` property, containing only
|
||||
the tags allowed by `--display-tags`.
|
||||
- (Client API) There is now support for XEmbed `--wid` targets, such as a
|
||||
`GtkSocket`'s `gtk_socket_get_id()`.
|
||||
- (Client API) There is now a `file-format` property with a symbolic name
|
||||
for the file format. In some cases this might be a comma separated list
|
||||
of various different extensions due to libavformat idiosyncrasies.
|
||||
- (Client API) There is now a `mouse` command for generating mouse events
|
||||
over the video window.
|
||||
- (Client API) There is now a `partially-seekable` property that indicates
|
||||
whether a file is only considered `seekable` because of the stream cache,
|
||||
but would not be seekable otherwise (e.g. realtime stream, or HTTP with
|
||||
no resume support). Small relative seeks may be fine, but larger seeks
|
||||
will likely fail.
|
||||
- (Client API) There is now an MPV_EVENT_QUEUE_OVERFLOW event that is posted
|
||||
whenever events have to be dropped because the queue is full. No further
|
||||
events are posted until the MPV_EVENT_QUEUE_OVERFLOW is consumed to avoid
|
||||
duplicated posting.
|
||||
- (Client API) There is now a helper `mpv_wait_async_requests()` function
|
||||
that blocks until all known async requests have completed. (bug #1542)
|
||||
- (Client API) There is now a `detected-hwdec` property that returns the
|
||||
detected hardware decoder when one is successfully opened. This probably
|
||||
only returns a valid value after playback has started.
|
||||
- (Client API) There are now `audio_add`, `audio_remove` and `audio_reload`
|
||||
counterparts to the equivalent `sub_` commands for handling external audio
|
||||
files.
|
||||
|
||||
This listing is not complete. A complete changelog can be seen by running
|
||||
`git log v0.7.0..v0.8.0` in the git repository or by visiting
|
||||
https://github.com/mpv-player/mpv/compare/v0.7.0...v0.8.0 (only 250 commits).
|
||||
|
||||
Release 0.7.3
|
||||
=============
|
||||
|
||||
Changes
|
||||
-------
|
||||
|
||||
- Several documentation updates and typo fixes.
|
||||
- Don't show "0%" position when the stream is infinite / has unknown length.
|
||||
- Fixes the config file loading order so that lower priority `mpv.conf` files
|
||||
don't override higher priority `config` files.
|
||||
- (OSX) Remove coreaudio_exclusive from the "auto" codec list.
|
||||
- Failing to create a GL3 context is now a warning instead of error, to reduce
|
||||
user confusion.
|
||||
- The subtitle decoder now gets reset when cycling subtitles. This makes the
|
||||
currently shown subtitle event disappear even if cycling back to the current
|
||||
subtitle track.
|
||||
- `--shuffle` and `--merge-files` now affects the contents of playlist files,
|
||||
instead of just the list of files given as arguments to mpv.
|
||||
- `./waf install` avoids installing a few additional data/config files if only
|
||||
libmpv was built.
|
||||
- Improved channel mapping when the file's channel map doesn't match the AO's
|
||||
available channel maps.
|
||||
- (OSX) VDA now gracefully refuses to run on non-OpenGL3-capable systems instead
|
||||
of trying and failing to build its shaders.
|
||||
- Add workaround for vf_vapoursynth filters that expect an FPS.
|
||||
- The default value for `--screenshot-template` now shows up in
|
||||
`--list-options`.
|
||||
- `ao_pulse`'s `latency-hacks` suboption is now off by default, as it causes
|
||||
issues with newer pulseaudio releases. If A/V Sync issues happen, either
|
||||
add the `latency-hacks=on` pulse suboption in mpv.conf, or update the
|
||||
pulseaudio daemon (bug #1430).
|
||||
- (Linux) `ao_alsa` now deals better with audio device disconnection.
|
||||
- Client API: timestamp properties that have no value return "no" instead of
|
||||
magic number.
|
||||
|
||||
Bug fixes
|
||||
---------
|
||||
|
||||
- (Windows, OSX) Many `ao_wasapi` and `ao_coreaudio` fixes.
|
||||
- (OSX) Make the window title update correctly on OS X Yosemite.
|
||||
- Fixes for handling mono audio on various AOs.
|
||||
- (Linux) Fixes resuming from suspend on ao_alsa.
|
||||
- Fixes for playlist file parsing.
|
||||
- Overly long options in the --list-options output now break the column layout
|
||||
instead of getting truncated; fixes shell completion scripts.
|
||||
- Fix rendering resolution of certain DVB subtitles (bug #1425).
|
||||
- Fix EDL or --merge-files breaking timestamps with .avi files.
|
||||
- Workaround for libavcodec bug with the VP9 codec parser (bug #1448),
|
||||
fixes possible crash.
|
||||
- Improve robustness of the matroska parser with broken files (bugs #1457,
|
||||
#1461).
|
||||
- Improve 10bit video compatibility with older GPUs (specially Intel) (bug
|
||||
#1383).
|
||||
- Fixes flashing the VO window when playing a list of files that includes
|
||||
non-media files (bug #1459).
|
||||
- Workaround for window embedding in OpenBox (bug #1235)
|
||||
- Fixes for several crashes and lockups (bugs #838, #1389, #1408, #1463, #1473,
|
||||
#1474).
|
||||
- Fixes for the zsh completion script (bugs #997)
|
||||
|
||||
New features
|
||||
------------
|
||||
|
||||
- mpv now prints the contents of its config.h when running in verbose mode, to
|
||||
aid with debugging.
|
||||
- The `include=` option now accepts `~` to refer to the HOME dir (bug #1406).
|
||||
- `af_volume` now prints ReplayGain values in verbose mode.
|
||||
- m3u playlists that don't have the `#EXTM3U` header are now accepted if they
|
||||
"look like" ASCII or UTF-8 text and have the .m3u extension.
|
||||
- Chapter marks in the seek bar now update when switching files.
|
||||
- Supports embedded cover art in MKV files (bug #1374).
|
||||
- (Windows) Video window can now be resized even with --no-border.
|
||||
- (Windows) Client API: the "run" command now works on Windows too.
|
||||
- (Linux) vo_wayland now supports key modifiers (Meta, Alt, Control, Shift)
|
||||
- Client API: "display-names" property is now observable.
|
||||
|
||||
This listing is not complete. A complete changelog can be seen by running
|
||||
`git log v0.7.2..v0.7.3` in the git repository or by visiting
|
||||
https://github.com/mpv-player/mpv/compare/v0.7.2...v0.7.3.
|
||||
|
||||
Release 0.7.2
|
||||
=============
|
||||
|
||||
Changes
|
||||
-------
|
||||
|
||||
- Give precedence to the DVD menu navigation keyboard bindings so that user
|
||||
defined LEFT/RIGHT/... bindings don't break DVD menu navigation.
|
||||
- Try to fallback to the "default" device if the selected device is busy in the
|
||||
alsa AO.
|
||||
- Don't create Dock icon for audio only files on OS X.
|
||||
- Save screenshots to desktop when using the app bundle on OS X.
|
||||
- Restore ab-loop settings with playback resume.
|
||||
- Bump required youtube-dl version to 2014.11.26 and enable the ytdl_hook Lua
|
||||
script by default (now playing videos from YouTube and the like will work
|
||||
out of the box without any configuration change needed).
|
||||
|
||||
Bug fixes
|
||||
---------
|
||||
|
||||
- Don't signal an error if --stream-dump is used.
|
||||
- Fix removing key bindings from Lua scripts.
|
||||
- Reject channel descriptions with too many channels in the coreaudio AO.
|
||||
- Don't async redraw when waiting for VO redraw on OS X (this fixes the very
|
||||
annoying glitch where the black bars disappear for a single frame when going
|
||||
fullscreen).
|
||||
- Fix mono playback with the also AO.
|
||||
- Don't crash if framebuffers are not available in the opengl VO.
|
||||
|
||||
New features
|
||||
------------
|
||||
|
||||
- Try to handle multi-arc videos in the ytdl_hook Lua script.
|
||||
|
||||
This listing is not complete. There are many more bug fixes and changes. The
|
||||
complete change log can be viewed by running ``git log 47ec404..c7d6b21`` in
|
||||
the git repository or by visiting
|
||||
https://github.com/mpv-player/mpv/compare/47ec404...c7d6b21.
|
||||
|
||||
Release 0.7.1
|
||||
=============
|
||||
|
||||
Changes
|
||||
-------
|
||||
|
||||
- Don't show the volume neutral marker on the OSD if softvol is disabled.
|
||||
- Don't select a subtitle track when executing the sub_add input command in
|
||||
"auto" mode.
|
||||
|
||||
Bug fixes
|
||||
---------
|
||||
|
||||
- Fix busy loop when seeking while paused (this fixes a problem with pulseaudio
|
||||
that caused mpv and the pulseaudio daemon to use 100% CPU).
|
||||
- Fix Lua function utils.subprocess() in Windows versions older than Vista.
|
||||
- Avoid creating a window bigger than the screen on Windows.
|
||||
- Don't ignore the last line in m3u playlists.
|
||||
- Don't crash if a codec could not be opened.
|
||||
- Dynamically allocate audio channel map entries (this should fix a crash in
|
||||
the alsa and coreaudio AOs with audio devices that support more than 20
|
||||
channel maps).
|
||||
- Ignore the "srgb" option in the opengl VO if hardware decoding is enabled.
|
||||
- Linearize non-RGB sRGB files correctly (eg. JPEG).
|
||||
- Fix opening reference URLs (.file/id=) on OS X.
|
||||
|
||||
This listing is not complete. There are many more bug fixes and changes. The
|
||||
complete change log can be viewed by running ``git log 8d8b36d..6583ad6`` in
|
||||
the git repository or by visiting
|
||||
https://github.com/mpv-player/mpv/compare/8d8b36d...6583ad6.
|
||||
|
||||
Release 0.7.0
|
||||
=============
|
||||
|
||||
@@ -690,5 +64,4 @@ New features
|
||||
|
||||
This listing is not complete. There are many more bug fixes and changes. The
|
||||
complete change log can be viewed by running ``git log 7759c18..9479daa`` in
|
||||
the git repository or by visiting
|
||||
https://github.com/mpv-player/mpv/compare/7759c18...9479daa (only 250 commits).
|
||||
the git repository.
|
||||
@@ -19,7 +19,6 @@ def is_user_lib(objfile, libname):
|
||||
not "libSystem." in libname and \
|
||||
not "libc." in libname and \
|
||||
not "libgcc." in libname and \
|
||||
not os.path.basename(libname) == 'Python' and \
|
||||
not os.path.basename(objfile) in libname
|
||||
|
||||
def otool(objfile):
|
||||
|
||||
+3
-5
@@ -4,11 +4,9 @@ mpv lua scripts
|
||||
The lua scripts in this folder can be loaded on a one-time basis by
|
||||
adding the option
|
||||
|
||||
--script=/path/to/script.lua
|
||||
--lua=/path/to/script.lua
|
||||
|
||||
to mpv's command line.
|
||||
|
||||
Where appropriate, they may also be placed in ~/.config/mpv/scripts/ from
|
||||
where they will be automatically loaded when mpv starts.
|
||||
|
||||
Some of these are just for testing mpv internals.
|
||||
Where appropriate, they may also be placed in ~/.config/mpv/lua from where
|
||||
they will be automatically loaded when mpv starts.
|
||||
@@ -1,13 +0,0 @@
|
||||
local utils = require("mp.utils")
|
||||
|
||||
mp.observe_property("audio-device-list", "native", function(name, val)
|
||||
print("Audio device list changed:")
|
||||
for index, e in ipairs(val) do
|
||||
print(" - '" .. e.name .. "' (" .. e.description .. ")")
|
||||
end
|
||||
end)
|
||||
|
||||
mp.observe_property("audio-out-detected-device", "native", function(name, val)
|
||||
print("Detected audio device changed:")
|
||||
print(" - '" .. val)
|
||||
end)
|
||||
@@ -21,7 +21,7 @@
|
||||
-- The default delay between insertion of the cropdetect and
|
||||
-- crop filters may be overridden by adding
|
||||
--
|
||||
-- --script-opts=autocrop.detect_seconds=<number of seconds>
|
||||
-- --lua-opts=autocrop.detect_seconds=<number of seconds>
|
||||
--
|
||||
-- to mpv's arguments. This may be desirable to allow cropdetect more
|
||||
-- time to collect data.
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
--
|
||||
-- The default detection time may be overridden by adding
|
||||
--
|
||||
-- --script-opts=autodeint.detect_seconds=<number of seconds>
|
||||
-- --lua-opts=autodeint.detect_seconds=<number of seconds>
|
||||
--
|
||||
-- to mpv's arguments. This may be desirable to allow idet more
|
||||
-- time to collect data.
|
||||
@@ -102,7 +102,7 @@ function judge()
|
||||
|
||||
mp.msg.verbose("progressive = "..num_progressive)
|
||||
mp.msg.verbose("interlaced-tff = "..num_tff)
|
||||
mp.msg.verbose("interlaced-bff = "..num_bff)
|
||||
mp.msg.verbose("interlaced-bff = "..num_bff)
|
||||
mp.msg.verbose("undetermined = "..num_undetermined)
|
||||
|
||||
if num_determined < num_undetermined then
|
||||
|
||||
+1
-43
@@ -7,17 +7,6 @@
|
||||
-- Add at most 5 * 2 files when starting a file (before + after).
|
||||
MAXENTRIES = 5
|
||||
|
||||
function Set (t)
|
||||
local set = {}
|
||||
for _, v in pairs(t) do set[v] = true end
|
||||
return set
|
||||
end
|
||||
|
||||
EXTENSIONS = Set {
|
||||
'mkv', 'avi', 'mp4', 'ogv', 'webm', 'rmvb', 'flv', 'wmv', 'mpeg', 'mpg', 'm4v', '3gp',
|
||||
'mp3', 'wav', 'ogv', 'flac', 'm4a', 'wma',
|
||||
}
|
||||
|
||||
mputils = require 'mp.utils'
|
||||
|
||||
function add_files_at(index, files)
|
||||
@@ -29,44 +18,17 @@ function add_files_at(index, files)
|
||||
end
|
||||
end
|
||||
|
||||
function get_extension(path)
|
||||
return string.match(path, "%.([^%.]+)$" )
|
||||
end
|
||||
|
||||
table.filter = function(t, iter)
|
||||
for i = #t, 1, -1 do
|
||||
if not iter(t[i]) then
|
||||
table.remove(t, i)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function find_and_add_entries()
|
||||
local path = mp.get_property("path", "")
|
||||
local dir, filename = mputils.split_path(path)
|
||||
if #dir == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local files = mputils.readdir(dir, "files")
|
||||
if files == nil then
|
||||
return
|
||||
end
|
||||
table.filter(files, function (v, k)
|
||||
local ext = get_extension(v)
|
||||
if ext == nil then
|
||||
return false
|
||||
end
|
||||
return EXTENSIONS[string.lower(ext)]
|
||||
end)
|
||||
table.sort(files, function (a, b)
|
||||
return string.lower(a) < string.lower(b)
|
||||
end)
|
||||
|
||||
table.sort(files)
|
||||
if dir == "." then
|
||||
dir = ""
|
||||
end
|
||||
|
||||
local pl = mp.get_property_native("playlist", {})
|
||||
local pl_current = mp.get_property_number("playlist-pos", 0) + 1
|
||||
-- Find the current pl entry (dir+"/"+filename) in the sorted dir list
|
||||
@@ -80,7 +42,6 @@ function find_and_add_entries()
|
||||
if current == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local append = {[-1] = {}, [1] = {}}
|
||||
for direction = -1, 1, 2 do -- 2 iterations, with direction = -1 and +1
|
||||
for i = 1, MAXENTRIES do
|
||||
@@ -89,7 +50,6 @@ function find_and_add_entries()
|
||||
if file == nil or file[1] == "." then
|
||||
break
|
||||
end
|
||||
|
||||
local filepath = dir .. file
|
||||
if pl_e then
|
||||
-- If there's a playlist entry, and it's the same file, stop.
|
||||
@@ -97,7 +57,6 @@ function find_and_add_entries()
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if direction == -1 then
|
||||
if pl_current == 1 then -- never add additional entries in the middle
|
||||
mp.msg.info("Prepending " .. file)
|
||||
@@ -109,7 +68,6 @@ function find_and_add_entries()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
add_files_at(pl_current + 1, append[1])
|
||||
add_files_at(pl_current, append[-1])
|
||||
end
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
-- parameters. See the entry for "drc" under the "AUDIO FILTERS"
|
||||
-- section of the man page for a complete description of the filter.
|
||||
--
|
||||
-- This script registers the key-binding "\" to toggle the filter between
|
||||
-- This script registers the key-binding "\" to toggle the filter between
|
||||
--
|
||||
-- * off
|
||||
-- * method=1 (single-sample smoothing)
|
||||
@@ -92,7 +92,7 @@ function drc_quieter_handler()
|
||||
drc_scale_target(0.5)
|
||||
end
|
||||
|
||||
-- toggle between off, method 1 and method 2
|
||||
-- toggle between off, method 1 and method 2
|
||||
mp.add_key_binding("\\", "drc_toggle_method", drc_toggle_method_handler)
|
||||
-- increase or decrease target volume
|
||||
mp.add_key_binding("ctrl+9", "drc_quieter", drc_quieter_handler)
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
-- Test script for property change notification mechanism.
|
||||
-- Note that watching/reading some properties can be very expensive, or
|
||||
-- require the player to synchronously wait on network (when playing
|
||||
-- remote files), so you should in general only watch properties you
|
||||
-- are interested in.
|
||||
|
||||
local utils = require("mp.utils")
|
||||
function format_property_val(v)
|
||||
if type(v) == "table" then
|
||||
return mp.format_table(v) -- undocumented function; might be removed
|
||||
else
|
||||
return tostring(v)
|
||||
end
|
||||
end
|
||||
|
||||
for i,name in ipairs(mp.get_property_native("property-list")) do
|
||||
mp.observe_property(name, "native", function(name, val)
|
||||
print("property '" .. name .. "' changed to '" ..
|
||||
utils.to_string(val) .. "'")
|
||||
format_property_val(val) .. "'")
|
||||
end)
|
||||
end
|
||||
@@ -1,19 +0,0 @@
|
||||
--makes mpv disable ontop when pausing and re-enable it again when resuming playback
|
||||
--please note that this won't do anything if ontop was not enabled before pausing
|
||||
|
||||
local was_ontop = false
|
||||
|
||||
mp.observe_property("pause", "bool", function(name, value)
|
||||
local ontop = mp.get_property_native("ontop")
|
||||
if value then
|
||||
if ontop then
|
||||
mp.set_property_native("ontop", false)
|
||||
was_ontop = true
|
||||
end
|
||||
else
|
||||
if was_ontop and not ontop then
|
||||
mp.set_property_native("ontop", true)
|
||||
end
|
||||
was_ontop = false
|
||||
end
|
||||
end)
|
||||
@@ -1,20 +0,0 @@
|
||||
-- This script pauses playback when minimizing the window, and resumes playback
|
||||
-- if it's brought back again. If the player was already paused when minimizing,
|
||||
-- then try not to mess with the pause state.
|
||||
|
||||
local did_minimize = false
|
||||
|
||||
mp.observe_property("window-minimized", "bool", function(name, value)
|
||||
local pause = mp.get_property_native("pause")
|
||||
if value == true then
|
||||
if pause == false then
|
||||
mp.set_property_native("pause", true)
|
||||
did_minimize = true
|
||||
end
|
||||
elseif value == false then
|
||||
if did_minimize and (pause == true) then
|
||||
mp.set_property_native("pause", false)
|
||||
end
|
||||
did_minimize = false
|
||||
end
|
||||
end)
|
||||
@@ -1,34 +0,0 @@
|
||||
--sets the startime of a youtube video as specified in the "t=HHhMMmSSs" part of the url
|
||||
--NOTE: This might become obsolete once youtube-dl adds the functionality
|
||||
|
||||
local msg = require 'mp.msg'
|
||||
|
||||
function youtube_starttime()
|
||||
url = mp.get_property("path", "")
|
||||
start = 0
|
||||
|
||||
if string.find(url, "youtu%.?be") and
|
||||
((url:find("http://") == 1) or (url:find("https://") == 1)) then
|
||||
time = string.match(url, "[#&%?]t=%d*h?%d*m?%d+s?m?h?")
|
||||
--the time-string can start with #, & or ? followed by t= and the timing parameters
|
||||
--at least one number needs to be present after t=, followed by h, m, s or nothing (>implies s)
|
||||
|
||||
if time then
|
||||
for pos in string.gmatch(time,"%d+%a?") do
|
||||
if string.match(pos,"%d+h") then --find out multiplier for
|
||||
multiplier = 60*60 --hours
|
||||
elseif string.match(pos,"%d+m") then
|
||||
multiplier = 60 --minutes
|
||||
else multiplier = 1 end --seconds
|
||||
|
||||
start = start + (string.match(pos,"%d+") * multiplier)
|
||||
end
|
||||
|
||||
msg.info("parsed '" .. time .. "' into '" .. start .. "' seconds")
|
||||
end
|
||||
|
||||
mp.set_property("file-local-options/start",start)
|
||||
end
|
||||
end
|
||||
|
||||
mp.add_hook("on_load", 50, youtube_starttime)
|
||||
+1
-1
@@ -64,7 +64,7 @@ sub generate_c_header {
|
||||
|
||||
# Output a counter variable for each element
|
||||
# (presence/absence for scalars, item count for arrays)
|
||||
for my $subel (sort values %{$el->{subelements}}) {
|
||||
for my $subel (values %{$el->{subelements}}) {
|
||||
print " int n_$subel->{fieldname};\n"
|
||||
}
|
||||
print "};\n";
|
||||
|
||||
+1
-3
@@ -3,7 +3,6 @@
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import fileinput
|
||||
from optparse import OptionParser
|
||||
|
||||
def sh(command):
|
||||
@@ -36,8 +35,7 @@ def copy_binary(binary_name):
|
||||
shutil.copy(binary_name, target_binary(binary_name))
|
||||
|
||||
def apply_plist_template(plist_file, version):
|
||||
for line in fileinput.input(plist_file, inplace=1):
|
||||
print (line.rstrip().replace('${VERSION}', version))
|
||||
sh("sed -i -e 's/${VERSION}/%s/g' %s" % (version, plist_file))
|
||||
|
||||
def main():
|
||||
version = sh("./version.sh --print").strip()
|
||||
|
||||
@@ -88,7 +88,6 @@
|
||||
<string>VOB</string>
|
||||
<string>WEBM</string>
|
||||
<string>WMV</string>
|
||||
<string>MK3D</string>
|
||||
<string>asf</string>
|
||||
<string>avi</string>
|
||||
<string>cpk</string>
|
||||
@@ -123,7 +122,6 @@
|
||||
<string>vob</string>
|
||||
<string>webm</string>
|
||||
<string>wmv</string>
|
||||
<string>mk3d</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>document.icns</string>
|
||||
@@ -210,7 +208,6 @@
|
||||
<string>mms</string>
|
||||
<string>mmst</string>
|
||||
<string>http</string>
|
||||
<string>https</string>
|
||||
<string>httpproxy</string>
|
||||
<string>rtp</string>
|
||||
<string>rtsp</string>
|
||||
@@ -516,47 +513,6 @@
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>mkv</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.movie</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>Matroska stereoscopic/3D video</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>document.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>io.mpv.mk3d</string>
|
||||
<key>UTTypeReferenceURL</key>
|
||||
<string>http://www.matroska.org</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>mk3d</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.movie</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>WebM Video</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>document.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>io.mpv.webm</string>
|
||||
<key>UTTypeReferenceURL</key>
|
||||
<string>http://www.webmproject.org</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>webm</string>
|
||||
</array>
|
||||
</dict>
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
screenshot-template=~/Desktop/shot%n
|
||||
profile=pseudo-gui
|
||||
+22
-48
@@ -1,12 +1,9 @@
|
||||
#!/usr/bin/env python3
|
||||
import matplotlib.pyplot as plot
|
||||
import sys
|
||||
import re
|
||||
|
||||
filename = sys.argv[1]
|
||||
|
||||
event_regex = re.compile(".*")
|
||||
|
||||
"""
|
||||
This script is meant to display stats written by mpv --dump-stats=filename.
|
||||
In general, each line in that file is an event of the form:
|
||||
@@ -21,19 +18,17 @@ e.g.:
|
||||
|
||||
Currently, the following event types are supported:
|
||||
|
||||
'signal' <name> singular event
|
||||
'start' <name> start of the named event
|
||||
'end' <name> end of the named event
|
||||
'value' <float> <name> a normal value (as opposed to event)
|
||||
'event-timed' <ts> <name> singular event at the given timestamp
|
||||
'value-timed' <ts> <float> <name>
|
||||
a value for an event at the given timestamp
|
||||
<name> singular event (same as 'signal')
|
||||
<name> singular event
|
||||
|
||||
"""
|
||||
|
||||
class G:
|
||||
events = {}
|
||||
sevents = [] # events, deterministically sorted
|
||||
start = None
|
||||
# http://matplotlib.org/api/markers_api.html#module-matplotlib.markers
|
||||
markers = ["o", "8", "s", "p", "*", "h", "+", "x", "D"]
|
||||
@@ -51,25 +46,24 @@ class Event:
|
||||
def get_event(event, evtype):
|
||||
if event not in G.events:
|
||||
e = Event()
|
||||
G.events[event] = e
|
||||
e.name = event
|
||||
e.vals = []
|
||||
e.type = evtype
|
||||
e.marker = "o"
|
||||
e.numid = len(G.events)
|
||||
G.sevents = list(G.events.values())
|
||||
G.sevents.sort(key=lambda x: x.name)
|
||||
if e.type == "event-signal":
|
||||
e.marker = find_marker()
|
||||
if not event_regex.match(e.name):
|
||||
return e
|
||||
G.events[event] = e
|
||||
return G.events[event]
|
||||
|
||||
SCALE = 1e6 # microseconds to seconds
|
||||
|
||||
for line in [line.split("#")[0].strip() for line in open(filename, "r")]:
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
ts, event = line.split(" ", 1)
|
||||
ts = int(ts) / SCALE
|
||||
ts = int(ts) / 1000 # milliseconds
|
||||
if G.start is None:
|
||||
G.start = ts
|
||||
ts = ts - G.start
|
||||
@@ -88,48 +82,28 @@ for line in [line.split("#")[0].strip() for line in open(filename, "r")]:
|
||||
e.vals.append((ts, val))
|
||||
elif event.startswith("event-timed "):
|
||||
_, val, name = event.split(" ", 2)
|
||||
val = int(val) / SCALE - G.start
|
||||
val = int(val) / 1000 - G.start
|
||||
e = get_event(name, "event-signal")
|
||||
e.vals.append((val, 1))
|
||||
elif event.startswith("value-timed "):
|
||||
_, tsval, val, name = event.split(" ", 3)
|
||||
tsval = int(tsval) / SCALE - G.start
|
||||
val = float(val)
|
||||
e = get_event(name, "value")
|
||||
e.vals.append((tsval, val))
|
||||
elif event.startswith("signal "):
|
||||
name = event.split(" ", 2)[1]
|
||||
e = get_event(name, "event-signal")
|
||||
e.vals.append((ts, 1))
|
||||
else:
|
||||
e = get_event(event, "event-signal")
|
||||
e.vals.append((ts, 1))
|
||||
|
||||
# deterministically sort them; make sure the legend is sorted too
|
||||
G.sevents = list(G.events.values())
|
||||
G.sevents.sort(key=lambda x: x.name)
|
||||
hasval = False
|
||||
for e, index in zip(G.sevents, range(len(G.sevents))):
|
||||
m = len(G.sevents)
|
||||
if e.type == "value":
|
||||
hasval = True
|
||||
else:
|
||||
e.vals = [(x, y * (m - index) / m) for (x, y) in e.vals]
|
||||
|
||||
fig = plot.figure()
|
||||
fig.hold(True)
|
||||
ax = [None, None]
|
||||
plots = 2 if hasval else 1
|
||||
ax[0] = fig.add_subplot(plots, 1, 1)
|
||||
if hasval:
|
||||
ax[1] = fig.add_subplot(plots, 1, 2, sharex=ax[0])
|
||||
legends = [[], []]
|
||||
for e in G.sevents:
|
||||
cur = ax[1 if e.type == "value" else 0]
|
||||
pl, = cur.plot([x for x,y in e.vals], [y for x,y in e.vals], label=e.name)
|
||||
e.vals = [(x, y * e.numid / len(G.events)) for (x, y) in e.vals]
|
||||
|
||||
plot.hold(True)
|
||||
mainpl = plot.subplot(2, 1, 1)
|
||||
legend = []
|
||||
for e in G.sevents:
|
||||
if e.type == "value":
|
||||
plot.subplot(2, 1, 2, sharex=mainpl)
|
||||
else:
|
||||
plot.subplot(2, 1, 1)
|
||||
pl, = plot.plot([x for x,y in e.vals], [y for x,y in e.vals], label=e.name)
|
||||
if e.type == "event-signal":
|
||||
plot.setp(pl, marker = e.marker, linestyle = "None")
|
||||
for cur in ax:
|
||||
if cur is not None:
|
||||
cur.legend()
|
||||
legend.append(pl)
|
||||
plot.subplot(2, 1, 1)
|
||||
plot.legend(legend, [pl.get_label() for pl in legend])
|
||||
plot.show()
|
||||
+1
-1
@@ -21,7 +21,7 @@ script after that will start a new mpv instance.
|
||||
|
||||
Note that you can control the mpv instance by writing to the command fifo:
|
||||
|
||||
echo "cycle fullscreen" > ~/.umpv_fifo
|
||||
echo "cycle fullscreen" > ~/.umpv-fifo
|
||||
|
||||
Note: you can supply custom mpv path and options with the MPV environment
|
||||
variable. The environment variable will be split on whitespace, and the
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
# 02110-1301 USA
|
||||
#
|
||||
|
||||
FILTERS = telecine tile rectangle framestep ildetect
|
||||
FILTERS = showqscale telecine tile rectangle framestep ildetect
|
||||
COMMON = filterutils.o
|
||||
|
||||
OBJECTS = $(patsubst %,%.o,$(FILTERS)) $(COMMON)
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Rudolf Polzer <divVerent@xonotic.org>
|
||||
*
|
||||
* This file is part of mpv's vf_dlopen examples.
|
||||
*
|
||||
* mpv's vf_dlopen examples are free software; you can redistribute them and/or
|
||||
* modify them under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* mpv's vf_dlopen examples are distributed in the hope that they will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with mpv's vf_dlopen examples; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "vf_dlopen.h"
|
||||
|
||||
/*
|
||||
* qscale visualizer
|
||||
*
|
||||
* usage: --vf=dlopen=/path/to/showqscale.so
|
||||
*
|
||||
* uses reddish colors for high QPs, and greenish colors for low QPs
|
||||
*/
|
||||
|
||||
#define PLANE_Y 0
|
||||
#define PLANE_U 1
|
||||
#define PLANE_V 2
|
||||
|
||||
static int qs_put_image(struct vf_dlopen_context *ctx)
|
||||
{
|
||||
unsigned int x, y, p;
|
||||
|
||||
assert(ctx->inpic.planes == ctx->outpic[0].planes);
|
||||
|
||||
for (p = 0; p < ctx->outpic[0].planes; ++p) {
|
||||
assert(ctx->inpic.planewidth[p] == ctx->outpic[0].planewidth[p]);
|
||||
assert(ctx->inpic.planeheight[p] == ctx->outpic[0].planeheight[p]);
|
||||
if ((p == PLANE_U || p == PLANE_V) && ctx->inpic_qscale)
|
||||
continue;
|
||||
#if 0
|
||||
// copy as is
|
||||
for (y = 0; y < ctx->outpic[0].planeheight[p]; ++y)
|
||||
memcpy(
|
||||
&ctx->outpic[0].plane[p][ctx->outpic[0].planestride[p] * y],
|
||||
&inpic[ctx->outpic[0].planeofs[p] + ctx->inpic.planestride[p] * y],
|
||||
ctx->outpic[0].planewidth[p]
|
||||
);
|
||||
#else
|
||||
// reduce contrast
|
||||
for (y = 0; y < ctx->outpic[0].planeheight[p]; ++y)
|
||||
for (x = 0; x < ctx->outpic[0].planewidth[p]; ++x)
|
||||
ctx->outpic[0].plane[p][ctx->outpic[0].planestride[p] * y + x] =
|
||||
0x20 + ((ctx->inpic.plane[p][ctx->inpic.planestride[p] * y + x] * 3) >> 2);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ctx->inpic_qscale) {
|
||||
int qmin = 255;
|
||||
int qmax = -255;
|
||||
|
||||
// clear U plane
|
||||
p = PLANE_U;
|
||||
for (y = 0; y < ctx->outpic[0].planeheight[p]; ++y)
|
||||
memset(
|
||||
&ctx->outpic[0].plane[p][ctx->outpic[0].planestride[p] * y],
|
||||
0x80,
|
||||
ctx->outpic[0].planewidth[p]
|
||||
);
|
||||
|
||||
// replace V by the qp (0 = green, 12 = red)
|
||||
p = PLANE_V;
|
||||
for (y = 0; y < ctx->outpic[0].planeheight[p]; ++y)
|
||||
for (x = 0; x < ctx->outpic[0].planewidth[p]; ++x) {
|
||||
int q = ctx->inpic_qscale[
|
||||
(x >> (ctx->inpic_qscaleshift - ctx->inpic.planexshift[p])) +
|
||||
(y >> (ctx->inpic_qscaleshift - ctx->inpic.planeyshift[p])) * ctx->inpic_qscalestride];
|
||||
if (q < qmin)
|
||||
qmin = q;
|
||||
if (q > qmax)
|
||||
qmax = q;
|
||||
int v = 128 + 21 * (q - 6); // range: 0 = green, 12 = red
|
||||
if (v < 0)
|
||||
v = 0;
|
||||
if (v > 255)
|
||||
v = 255;
|
||||
ctx->outpic[0].plane[p][ctx->outpic[0].planestride[p] * y + x] = v;
|
||||
}
|
||||
|
||||
// printf("qscale range: %d .. %d\n", qmin, qmax);
|
||||
}
|
||||
|
||||
ctx->outpic[0].pts = ctx->inpic.pts;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int vf_dlopen_getcontext(struct vf_dlopen_context *ctx, int argc, const char **argv)
|
||||
{
|
||||
VF_DLOPEN_CHECK_VERSION(ctx);
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
static struct vf_dlopen_formatpair map[] = {
|
||||
{ "yuv420p", "yuv420p" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
ctx->format_mapping = map;
|
||||
ctx->put_image = qs_put_image;
|
||||
return 1;
|
||||
}
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/bin/sh
|
||||
# Example of script for using mpv with youtube-dl
|
||||
set -e
|
||||
|
||||
cookies_dir="$(mktemp -d /tmp/youtube-dl_mpv.XXXX)"
|
||||
cookies_file="${cookies_dir}/cookies"
|
||||
user_agent="$(youtube-dl --dump-user-agent)" # or set whatever you want
|
||||
|
||||
video_url="$(youtube-dl \
|
||||
--user-agent="$user_agent" \
|
||||
--cookies="$cookies_file" \
|
||||
--get-url \
|
||||
"$@")"
|
||||
|
||||
set -f
|
||||
${MPV:-mpv} \
|
||||
--cookies \
|
||||
--cookies-file="$cookies_file" \
|
||||
--user-agent="$user_agent" \
|
||||
-- $video_url
|
||||
|
||||
rm -rf "$cookies_dir"
|
||||
+83
-109
@@ -7,15 +7,15 @@ use warnings;
|
||||
|
||||
my $mpv = $ARGV[0] || 'mpv';
|
||||
|
||||
my @opts = parse_main_opts('--list-options', '^ (\-\-[^\s\*]*)\*?\s*(.*)');
|
||||
my @opts = parse_opts("$mpv --list-options", '^ (\-\-[^\s\*]*)\*?\s*(.*)', 1);
|
||||
|
||||
my @ao = parse_opts('--ao=help', '^ ([^\s\:]*)\s*: (.*)');
|
||||
my @vo = parse_opts('--vo=help', '^ ([^\s\:]*)\s*: (.*)');
|
||||
my @ao = parse_opts("$mpv --ao=help", '^ ([^\s\:]*)\s*: (.*)');
|
||||
my @vo = parse_opts("$mpv --vo=help", '^ ([^\s\:]*)\s*: (.*)');
|
||||
|
||||
my @af = parse_opts('--af=help', '^ ([^\s\:]*)\s*: (.*)');
|
||||
my @vf = parse_opts('--vf=help', '^ ([^\s\:]*)\s*: (.*)');
|
||||
my @af = parse_opts("$mpv --af=help", '^ ([^\s\:]*)\s*: (.*)');
|
||||
my @vf = parse_opts("$mpv --vf=help", '^ ([^\s\:]*)\s*: (.*)');
|
||||
|
||||
my @protos = parse_opts('--list-protocols', '^ ([^\s]*)');
|
||||
my @protos = parse_opts("$mpv --list-protocols", '^ ([^\s]*)');
|
||||
|
||||
my ($opts_str, $ao_str, $vo_str, $af_str, $vf_str, $protos_str);
|
||||
|
||||
@@ -34,35 +34,36 @@ chomp $af_str;
|
||||
$vf_str .= qq{ '$_' \\\n} foreach (@vf);
|
||||
chomp $vf_str;
|
||||
|
||||
$protos_str = join(' ', @protos);
|
||||
$protos_str .= qq{$_ } foreach (@protos);
|
||||
chomp $protos_str;
|
||||
|
||||
my $profile_comp = <<'EOS';
|
||||
local -a profiles
|
||||
local current
|
||||
for current in "${(@f)$($words[1] --profile=help)}"; do
|
||||
current=${current//\*/\\\*}
|
||||
current=${current//\:/\\\:}
|
||||
current=${current//\[/\\\[}
|
||||
current=${current//\]/\\\]}
|
||||
if [[ $current =~ $'\t'([^$'\t']*)$'\t'(.*) ]]; then
|
||||
if [[ -n $match[2] ]]; then
|
||||
current="$match[1][$match[2]]"
|
||||
else
|
||||
current="$match[1]"
|
||||
local -a profiles
|
||||
local current
|
||||
for current in "${(@f)$($words[1] --profile=help)}"; do
|
||||
current=${current//\*/\\\*}
|
||||
current=${current//\:/\\\:}
|
||||
current=${current//\[/\\\[}
|
||||
current=${current//\]/\\\]}
|
||||
if [[ $current =~ $'\t'([^$'\t']*)$'\t'(.*) ]]; then
|
||||
if [[ -n $match[2] ]]; then
|
||||
current="$match[1][$match[2]]"
|
||||
else
|
||||
current="$match[1]"
|
||||
fi
|
||||
profiles=($profiles $current)
|
||||
fi
|
||||
profiles=($profiles $current)
|
||||
done
|
||||
if [[ $state == profile ]]; then
|
||||
# For --show-profile, only one allowed
|
||||
if (( ${#profiles} > 0 )); then
|
||||
_values 'profile' $profiles && rc=0
|
||||
fi
|
||||
else
|
||||
# For --profile, multiple allowed
|
||||
profiles=($profiles 'help[list profiles]')
|
||||
_values -s , 'profile(s)' $profiles && rc=0
|
||||
fi
|
||||
done
|
||||
if [[ $state == show-profile ]]; then
|
||||
# For --show-profile, only one allowed
|
||||
if (( ${#profiles} > 0 )); then
|
||||
_values 'profile' $profiles && rc=0
|
||||
fi
|
||||
else
|
||||
# For --profile, multiple allowed
|
||||
profiles=($profiles 'help[list profiles]')
|
||||
_values -s , 'profile(s)' $profiles && rc=0
|
||||
fi
|
||||
EOS
|
||||
chomp $profile_comp;
|
||||
|
||||
@@ -82,30 +83,42 @@ $opts_str
|
||||
|
||||
case \$state in
|
||||
ao)
|
||||
_values -s , 'audio outputs' \\
|
||||
local -a values
|
||||
values=(
|
||||
$ao_str
|
||||
&& rc=0
|
||||
)
|
||||
|
||||
_describe -t values 'audio outputs' values && rc=0
|
||||
;;
|
||||
|
||||
vo)
|
||||
_values -s , 'video outputs' \\
|
||||
local -a values
|
||||
values=(
|
||||
$vo_str
|
||||
&& rc=0
|
||||
)
|
||||
|
||||
_describe -t values 'video outputs' values && rc=0
|
||||
;;
|
||||
|
||||
af)
|
||||
_values -s , 'audio filters' \\
|
||||
local -a values
|
||||
values=(
|
||||
$af_str
|
||||
&& rc=0
|
||||
)
|
||||
|
||||
_describe -t values 'audio filters' values && rc=0
|
||||
;;
|
||||
|
||||
vf)
|
||||
_values -s , 'video filters' \\
|
||||
local -a values
|
||||
values=(
|
||||
$vf_str
|
||||
&& rc=0
|
||||
)
|
||||
|
||||
_describe -t values 'video filters' values && rc=0
|
||||
;;
|
||||
|
||||
profile|show-profile)
|
||||
profile|profiles)
|
||||
$profile_comp
|
||||
;;
|
||||
|
||||
@@ -120,7 +133,7 @@ $profile_comp
|
||||
_tags files urls
|
||||
while _tags; do
|
||||
_requested files expl 'media file' _files -g \\
|
||||
"*.(#i)(asf|asx|avi|flac|flv|m1v|m2p|m2v|m4v|mjpg|mka|mkv|mov|mp3|mp4|mpe|mpeg|mpg|ogg|ogm|ogv|qt|rm|ts|vob|wav|webm|wma|wmv)(-.)" && rc=0
|
||||
"*.(#i)(asf|asx|avi|flac|flv|m1v|m2p|m2v|m4v|mjpg|mka|mkv|mov|mp3|mp4|mpe|mpeg|mpg|ogg|ogm|ogv|qt|rm|ts|vob|wav|webm|wma|wmv)(-.)" && rc=0
|
||||
if _requested urls; then
|
||||
while _next_label urls expl URL; do
|
||||
_urls "\$expl[@]" && rc=0
|
||||
@@ -137,76 +150,11 @@ EOS
|
||||
|
||||
print $tmpl;
|
||||
|
||||
sub parse_main_opts {
|
||||
my ($cmd, $regex) = @_;
|
||||
|
||||
my @list;
|
||||
my @lines = split /\n/, `"$mpv" --no-config $cmd`;
|
||||
|
||||
foreach my $line (@lines) {
|
||||
my ($name, $desc) = ($line =~ /^$regex/) or next;
|
||||
|
||||
next if ($desc eq 'removed' || $desc eq 'alias');
|
||||
|
||||
if ($desc =~ /^Flag/) {
|
||||
|
||||
push @list, $name;
|
||||
|
||||
$name =~ /^--(.*)/;
|
||||
if ($1 !~ /^(\{|\}|v|list-options|really-quiet|no-.*)$/) {
|
||||
push @list, "--no-$1";
|
||||
}
|
||||
|
||||
} elsif ($desc =~ /^Print/) {
|
||||
|
||||
push @list, $name;
|
||||
|
||||
} else {
|
||||
|
||||
# Option takes argument
|
||||
|
||||
my $entry = $name;
|
||||
|
||||
$desc =~ s/\:/\\:/g;
|
||||
$entry .= "=-:$desc:";
|
||||
|
||||
if ($desc =~ /^Choices\\: ([^(]*)/) {
|
||||
my $choices = $1;
|
||||
$choices =~ s/ +$//; # strip trailing space
|
||||
$entry .= "($choices)";
|
||||
|
||||
# If "no" is one of the choices, it can also be
|
||||
# negated like a flag (--no-whatever).
|
||||
if ($choices =~ /\bno\b/) {
|
||||
$name =~ s/^--/--no-/;
|
||||
push @list, $name;
|
||||
}
|
||||
} elsif ($line =~ /\[file\]/) {
|
||||
$entry .= '->files';
|
||||
} elsif ($name =~ /^--(ao|vo|af|vf|profile|show-profile)$/) {
|
||||
$entry .= "->$1";
|
||||
}
|
||||
push @list, $entry;
|
||||
}
|
||||
}
|
||||
|
||||
# Sort longest first, because zsh won't complete an option listed
|
||||
# after one that's a prefix of it.
|
||||
@list = sort {
|
||||
$a =~ /([^=]*)/; my $ma = $1;
|
||||
$b =~ /([^=]*)/; my $mb = $1;
|
||||
|
||||
length($mb) <=> length($ma)
|
||||
} @list;
|
||||
|
||||
return @list;
|
||||
}
|
||||
|
||||
sub parse_opts {
|
||||
my ($cmd, $regex) = @_;
|
||||
my ($cmd, $regex, $parsing_main_options) = @_;
|
||||
|
||||
my @list;
|
||||
my @lines = split /\n/, `"$mpv" --no-config $cmd`;
|
||||
my @lines = split /\n/, `$cmd`;
|
||||
|
||||
foreach my $line (@lines) {
|
||||
if ($line !~ /^$regex/) {
|
||||
@@ -215,14 +163,40 @@ sub parse_opts {
|
||||
|
||||
my $entry = $1;
|
||||
|
||||
if ($parsing_main_options) {
|
||||
$entry .= '=-';
|
||||
}
|
||||
|
||||
if (defined $2) {
|
||||
my $desc = $2;
|
||||
$desc =~ s/\:/\\:/g;
|
||||
$entry .= "[$desc]";
|
||||
|
||||
$entry .= ':' . $desc;
|
||||
}
|
||||
|
||||
if ($parsing_main_options) {
|
||||
$entry .= ':';
|
||||
|
||||
$entry .= '->ao' if ($1 eq '--ao');
|
||||
$entry .= '->vo' if ($1 eq '--vo');
|
||||
$entry .= '->af' if ($1 eq '--af');
|
||||
$entry .= '->vf' if ($1 eq '--vf');
|
||||
$entry .= '->profiles' if ($1 eq '--profile');
|
||||
$entry .= '->profile' if ($1 eq '--show-profile');
|
||||
$entry .= '->files' if ($line =~ /\[file\]/);
|
||||
}
|
||||
|
||||
push @list, $entry
|
||||
}
|
||||
|
||||
if ($parsing_main_options) {
|
||||
@list = sort {
|
||||
$a =~ /(.*?)\:/; my $ma = $1;
|
||||
$b =~ /(.*?)\:/; my $mb = $1;
|
||||
|
||||
length($mb) <=> length($ma)
|
||||
} @list;
|
||||
}
|
||||
|
||||
return @list;
|
||||
}
|
||||
+14
-64
@@ -35,7 +35,7 @@ static void update_redundant_info(struct mp_audio *mpa)
|
||||
mp_chmap_is_valid(&mpa->channels));
|
||||
mpa->nch = mpa->channels.num;
|
||||
mpa->bps = af_fmt2bps(mpa->format);
|
||||
if (AF_FORMAT_IS_PLANAR(mpa->format)) {
|
||||
if (af_fmt_is_planar(mpa->format)) {
|
||||
mpa->spf = 1;
|
||||
mpa->num_planes = mpa->nch;
|
||||
mpa->sstride = mpa->bps;
|
||||
@@ -101,7 +101,7 @@ char *mp_audio_config_to_str_buf(char *buf, size_t buf_sz, struct mp_audio *mpa)
|
||||
|
||||
void mp_audio_force_interleaved_format(struct mp_audio *mpa)
|
||||
{
|
||||
if (AF_FORMAT_IS_PLANAR(mpa->format))
|
||||
if (af_fmt_is_planar(mpa->format))
|
||||
mp_audio_set_format(mpa, af_fmt_from_planar(mpa->format));
|
||||
}
|
||||
|
||||
@@ -118,7 +118,6 @@ void mp_audio_set_null_data(struct mp_audio *mpa)
|
||||
mpa->allocated[n] = NULL;
|
||||
}
|
||||
mpa->samples = 0;
|
||||
mpa->readonly = false;
|
||||
}
|
||||
|
||||
static int get_plane_size(const struct mp_audio *mpa, int samples)
|
||||
@@ -228,14 +227,6 @@ void mp_audio_copy(struct mp_audio *dst, int dst_offset,
|
||||
}
|
||||
}
|
||||
|
||||
// Copy fields that describe characteristics of the audio frame, but which are
|
||||
// not part of the core format (format/channels/rate), and not part of the
|
||||
// data (samples).
|
||||
void mp_audio_copy_attributes(struct mp_audio *dst, struct mp_audio *src)
|
||||
{
|
||||
// nothing yet
|
||||
}
|
||||
|
||||
// Set data to the audio after the given number of samples (i.e. slice it).
|
||||
void mp_audio_skip_samples(struct mp_audio *data, int samples)
|
||||
{
|
||||
@@ -247,40 +238,28 @@ void mp_audio_skip_samples(struct mp_audio *data, int samples)
|
||||
data->samples -= samples;
|
||||
}
|
||||
|
||||
// Return false if the frame data is shared, true otherwise.
|
||||
// Will return true for non-refcounted frames.
|
||||
bool mp_audio_is_writeable(struct mp_audio *data)
|
||||
{
|
||||
bool ok = !data->readonly;
|
||||
for (int n = 0; n < MP_NUM_CHANNELS; n++) {
|
||||
if (data->allocated[n])
|
||||
ok &= av_buffer_is_writable(data->allocated[n]);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
static void mp_audio_steal_data(struct mp_audio *dst, struct mp_audio *src)
|
||||
{
|
||||
talloc_set_destructor(dst, mp_audio_destructor);
|
||||
mp_audio_destructor(dst);
|
||||
*dst = *src;
|
||||
talloc_set_destructor(src, NULL);
|
||||
talloc_free(src);
|
||||
}
|
||||
|
||||
// Make sure the frame owns the audio data, and if not, copy the data.
|
||||
// Return negative value on failure (which means it can't be made writeable).
|
||||
// Non-refcounted frames are always considered writeable.
|
||||
int mp_audio_make_writeable(struct mp_audio *data)
|
||||
{
|
||||
if (!mp_audio_is_writeable(data)) {
|
||||
bool ok = true;
|
||||
for (int n = 0; n < MP_NUM_CHANNELS; n++) {
|
||||
if (data->allocated[n])
|
||||
ok &= av_buffer_is_writable(data->allocated[n]);
|
||||
}
|
||||
if (!ok) {
|
||||
struct mp_audio *new = talloc(NULL, struct mp_audio);
|
||||
*new = *data;
|
||||
mp_audio_set_null_data(new); // use format only
|
||||
mp_audio_realloc(new, data->samples);
|
||||
new->samples = data->samples;
|
||||
mp_audio_copy(new, 0, data, 0, data->samples);
|
||||
mp_audio_steal_data(data, new);
|
||||
// "Transfer" the reference.
|
||||
mp_audio_destructor(data);
|
||||
*data = *new;
|
||||
talloc_set_destructor(new, NULL);
|
||||
talloc_free(new);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -371,8 +350,7 @@ struct mp_audio *mp_audio_pool_get(struct mp_audio_pool *pool,
|
||||
if (alloc >= INT_MAX)
|
||||
return NULL;
|
||||
av_buffer_pool_uninit(&pool->avpool);
|
||||
pool->element_size = alloc;
|
||||
pool->avpool = av_buffer_pool_init(pool->element_size, NULL);
|
||||
pool->avpool = av_buffer_pool_init(alloc, NULL);
|
||||
if (!pool->avpool)
|
||||
return NULL;
|
||||
talloc_set_destructor(pool, mp_audio_pool_destructor);
|
||||
@@ -392,31 +370,3 @@ struct mp_audio *mp_audio_pool_get(struct mp_audio_pool *pool,
|
||||
}
|
||||
return new;
|
||||
}
|
||||
|
||||
// Return a copy of the given frame.
|
||||
// Returns NULL on error.
|
||||
struct mp_audio *mp_audio_pool_new_copy(struct mp_audio_pool *pool,
|
||||
struct mp_audio *frame)
|
||||
{
|
||||
struct mp_audio *new = mp_audio_pool_get(pool, frame, frame->samples);
|
||||
if (new) {
|
||||
mp_audio_copy(new, 0, frame, 0, new->samples);
|
||||
mp_audio_copy_attributes(new, frame);
|
||||
}
|
||||
return new;
|
||||
}
|
||||
|
||||
// Exactly like mp_audio_make_writeable(), but get the data from the pool.
|
||||
int mp_audio_pool_make_writeable(struct mp_audio_pool *pool,
|
||||
struct mp_audio *data)
|
||||
{
|
||||
if (mp_audio_is_writeable(data))
|
||||
return 0;
|
||||
struct mp_audio *new = mp_audio_pool_get(pool, data, data->samples);
|
||||
if (!new)
|
||||
return -1;
|
||||
mp_audio_copy(new, 0, data, 0, data->samples);
|
||||
mp_audio_copy_attributes(new, data);
|
||||
mp_audio_steal_data(data, new);
|
||||
return 0;
|
||||
}
|
||||
@@ -38,7 +38,6 @@ struct mp_audio {
|
||||
int bps; // size of sub-samples (af_fmt2bps(format))
|
||||
|
||||
// private
|
||||
bool readonly;
|
||||
struct AVBufferRef *allocated[MP_NUM_CHANNELS];
|
||||
};
|
||||
|
||||
@@ -67,22 +66,15 @@ void mp_audio_fill_silence(struct mp_audio *mpa, int start, int length);
|
||||
|
||||
void mp_audio_copy(struct mp_audio *dst, int dst_offset,
|
||||
struct mp_audio *src, int src_offset, int length);
|
||||
void mp_audio_copy_attributes(struct mp_audio *dst, struct mp_audio *src);
|
||||
void mp_audio_skip_samples(struct mp_audio *data, int samples);
|
||||
|
||||
bool mp_audio_is_writeable(struct mp_audio *data);
|
||||
int mp_audio_make_writeable(struct mp_audio *data);
|
||||
|
||||
struct AVFrame;
|
||||
struct mp_audio *mp_audio_from_avframe(struct AVFrame *avframe);
|
||||
|
||||
struct mp_audio_pool;
|
||||
struct mp_audio_pool *mp_audio_pool_create(void *ta_parent);
|
||||
struct mp_audio *mp_audio_pool_get(struct mp_audio_pool *pool,
|
||||
const struct mp_audio *fmt, int samples);
|
||||
struct mp_audio *mp_audio_pool_new_copy(struct mp_audio_pool *pool,
|
||||
struct mp_audio *frame);
|
||||
int mp_audio_pool_make_writeable(struct mp_audio_pool *pool,
|
||||
struct mp_audio *frame);
|
||||
|
||||
#endif
|
||||
+34
-71
@@ -50,7 +50,6 @@ static const char *const speaker_names[MP_SPEAKER_ID_COUNT][2] = {
|
||||
[MP_SPEAKER_ID_SDL] = {"sdl", "surround direct left"},
|
||||
[MP_SPEAKER_ID_SDR] = {"sdr", "surround direct right"},
|
||||
[MP_SPEAKER_ID_LFE2] = {"lfe2", "low frequency 2"},
|
||||
[MP_SPEAKER_ID_NA] = {"na", "not available"},
|
||||
};
|
||||
|
||||
// Names taken from libavutil/channel_layout.c (Not accessible by API.)
|
||||
@@ -58,9 +57,7 @@ static const char *const speaker_names[MP_SPEAKER_ID_COUNT][2] = {
|
||||
static const char *const std_layout_names[][2] = {
|
||||
{"empty", ""}, // not in lavc
|
||||
{"mono", "fc"},
|
||||
{"1.0", "fc"}, // not in lavc
|
||||
{"stereo", "fl-fr"},
|
||||
{"2.0", "fl-fr"}, // not in lavc
|
||||
{"2.1", "fl-fr-lfe"},
|
||||
{"3.0", "fl-fr-fc"},
|
||||
{"3.0(back)", "fl-fr-bc"},
|
||||
@@ -88,7 +85,6 @@ static const char *const std_layout_names[][2] = {
|
||||
{"7.1(alsa)", "fl-fr-bl-br-fc-lfe-sl-sr"}, // not in lavc
|
||||
{"7.1(wide)", "fl-fr-fc-lfe-bl-br-flc-frc"},
|
||||
{"7.1(wide-side)", "fl-fr-fc-lfe-flc-frc-sl-sr"},
|
||||
{"7.1(rear)", "fl-fr-fc-lfe-bl-br-sdl-sdr"},
|
||||
{"octagonal", "fl-fr-fc-bl-br-bc-sl-sr"},
|
||||
{"downmix", "dl-dr"},
|
||||
{"auto", ""}, // not in lavc
|
||||
@@ -128,8 +124,7 @@ bool mp_chmap_is_valid(const struct mp_chmap *src)
|
||||
int sp = src->speaker[n];
|
||||
if (sp >= MP_SPEAKER_ID_COUNT || mapped[sp])
|
||||
return false;
|
||||
if (sp != MP_SPEAKER_ID_NA)
|
||||
mapped[sp] = true;
|
||||
mapped[sp] = true;
|
||||
}
|
||||
return src->num > 0;
|
||||
}
|
||||
@@ -144,10 +139,12 @@ bool mp_chmap_is_empty(const struct mp_chmap *src)
|
||||
bool mp_chmap_is_unknown(const struct mp_chmap *src)
|
||||
{
|
||||
for (int n = 0; n < src->num; n++) {
|
||||
if (src->speaker[n] != MP_SPEAKER_ID_NA)
|
||||
return false;
|
||||
int speaker = src->speaker[n];
|
||||
if (speaker >= MP_SPEAKER_ID_UNKNOWN0 &&
|
||||
speaker <= MP_SPEAKER_ID_UNKNOWN_LAST)
|
||||
return true;
|
||||
}
|
||||
return mp_chmap_is_valid(src);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Note: empty channel maps compare as equal. Invalid ones can equal too.
|
||||
@@ -171,6 +168,15 @@ bool mp_chmap_equals_reordered(const struct mp_chmap *a, const struct mp_chmap *
|
||||
return mp_chmap_equals(&t1, &t2);
|
||||
}
|
||||
|
||||
bool mp_chmap_is_compatible(const struct mp_chmap *a, const struct mp_chmap *b)
|
||||
{
|
||||
if (mp_chmap_equals(a, b))
|
||||
return true;
|
||||
if (a->num == b->num && (mp_chmap_is_unknown(a) || mp_chmap_is_unknown(b)))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool mp_chmap_is_stereo(const struct mp_chmap *src)
|
||||
{
|
||||
static const struct mp_chmap stereo = MP_CHMAP_INIT_STEREO;
|
||||
@@ -190,26 +196,6 @@ void mp_chmap_reorder_norm(struct mp_chmap *map)
|
||||
qsort(arr, map->num, 1, comp_uint8);
|
||||
}
|
||||
|
||||
// Remove silent (NA) channels, if any.
|
||||
void mp_chmap_remove_na(struct mp_chmap *map)
|
||||
{
|
||||
struct mp_chmap new = {0};
|
||||
for (int n = 0; n < map->num; n++) {
|
||||
int sp = map->speaker[n];
|
||||
if (sp != MP_SPEAKER_ID_NA)
|
||||
new.speaker[new.num++] = map->speaker[n];
|
||||
}
|
||||
*map = new;
|
||||
}
|
||||
|
||||
// Add silent (NA) channels to map until map->num >= num.
|
||||
void mp_chmap_fill_na(struct mp_chmap *map, int num)
|
||||
{
|
||||
assert(num <= MP_NUM_CHANNELS);
|
||||
while (map->num < num)
|
||||
map->speaker[map->num++] = MP_SPEAKER_ID_NA;
|
||||
}
|
||||
|
||||
// Set *dst to a standard layout with the given number of channels.
|
||||
// If the number of channels is invalid, an invalid map is set, and
|
||||
// mp_chmap_is_valid(dst) will return false.
|
||||
@@ -238,8 +224,6 @@ void mp_chmap_from_channels_alsa(struct mp_chmap *dst, int num_channels)
|
||||
// Set *dst to an unknown layout for the given numbers of channels.
|
||||
// If the number of channels is invalid, an invalid map is set, and
|
||||
// mp_chmap_is_valid(dst) will return false.
|
||||
// A mp_chmap with all entries set to NA is treated specially in some
|
||||
// contexts (watch out for mp_chmap_is_unknown()).
|
||||
void mp_chmap_set_unknown(struct mp_chmap *dst, int num_channels)
|
||||
{
|
||||
if (num_channels < 0 || num_channels > MP_NUM_CHANNELS) {
|
||||
@@ -247,7 +231,7 @@ void mp_chmap_set_unknown(struct mp_chmap *dst, int num_channels)
|
||||
} else {
|
||||
dst->num = num_channels;
|
||||
for (int n = 0; n < dst->num; n++)
|
||||
dst->speaker[n] = MP_SPEAKER_ID_NA;
|
||||
dst->speaker[n] = MP_SPEAKER_ID_UNKNOWN0 + n;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,7 +274,6 @@ void mp_chmap_remove_useless_channels(struct mp_chmap *map,
|
||||
}
|
||||
|
||||
// Return the ffmpeg/libav channel layout as in <libavutil/channel_layout.h>.
|
||||
// Speakers not representable by ffmpeg/libav are dropped.
|
||||
// Warning: this ignores the order of the channels, and will return a channel
|
||||
// mask even if the order is different from libavcodec's.
|
||||
uint64_t mp_chmap_to_lavc_unchecked(const struct mp_chmap *src)
|
||||
@@ -300,10 +283,8 @@ uint64_t mp_chmap_to_lavc_unchecked(const struct mp_chmap *src)
|
||||
if (mp_chmap_is_unknown(&t))
|
||||
mp_chmap_from_channels(&t, t.num);
|
||||
uint64_t mask = 0;
|
||||
for (int n = 0; n < t.num; n++) {
|
||||
if (t.speaker[n] < 64) // ignore MP_SPEAKER_ID_NA etc.
|
||||
mask |= 1ULL << t.speaker[n];
|
||||
}
|
||||
for (int n = 0; n < t.num; n++)
|
||||
mask |= 1ULL << t.speaker[n];
|
||||
return mask;
|
||||
}
|
||||
|
||||
@@ -364,51 +345,33 @@ void mp_chmap_reorder_to_lavc(struct mp_chmap *map)
|
||||
|
||||
// Get reordering array for from->to reordering. from->to must have the same set
|
||||
// of speakers (i.e. same number and speaker IDs, just different order). Then,
|
||||
// for each speaker n, src[n] will be set such that:
|
||||
// to->speaker[n] = from->speaker[src[n]]
|
||||
// (src[n] gives the source channel for destination channel n)
|
||||
// If *from and *to don't contain the same set of speakers, then the above
|
||||
// invariant is not guaranteed. Instead, src[n] can be set to -1 if the channel
|
||||
// at to->speaker[n] is unmapped.
|
||||
void mp_chmap_get_reorder(int src[MP_NUM_CHANNELS], const struct mp_chmap *from,
|
||||
// for each speaker n, dst[n] will be set such that:
|
||||
// to->speaker[dst[n]] = from->speaker[n]
|
||||
// (dst[n] gives the source channel for destination channel n)
|
||||
void mp_chmap_get_reorder(int dst[MP_NUM_CHANNELS], const struct mp_chmap *from,
|
||||
const struct mp_chmap *to)
|
||||
{
|
||||
for (int n = 0; n < MP_NUM_CHANNELS; n++)
|
||||
src[n] = -1;
|
||||
|
||||
assert(from->num == to->num);
|
||||
if (mp_chmap_is_unknown(from) || mp_chmap_is_unknown(to)) {
|
||||
for (int n = 0; n < to->num; n++)
|
||||
src[n] = n < from->num ? n : -1;
|
||||
for (int n = 0; n < from->num; n++)
|
||||
dst[n] = n;
|
||||
return;
|
||||
}
|
||||
|
||||
// Same set of speakers required
|
||||
assert(mp_chmap_equals_reordered(from, to));
|
||||
for (int n = 0; n < from->num; n++) {
|
||||
int src = from->speaker[n];
|
||||
dst[n] = -1;
|
||||
for (int i = 0; i < to->num; i++) {
|
||||
if (to->speaker[n] == from->speaker[i]) {
|
||||
src[n] = i;
|
||||
if (src == to->speaker[i]) {
|
||||
dst[n] = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(dst[n] != -1);
|
||||
}
|
||||
|
||||
for (int n = 0; n < to->num; n++)
|
||||
assert(src[n] < 0 || (to->speaker[n] == from->speaker[src[n]]));
|
||||
}
|
||||
|
||||
static int popcount64(uint64_t bits)
|
||||
{
|
||||
int r = 0;
|
||||
for (int n = 0; n < 64; n++)
|
||||
r += !!(bits & (1ULL << n));
|
||||
return r;
|
||||
}
|
||||
|
||||
// Return the number of channels only in a.
|
||||
int mp_chmap_diffn(const struct mp_chmap *a, const struct mp_chmap *b)
|
||||
{
|
||||
uint64_t a_mask = mp_chmap_to_lavc_unchecked(a);
|
||||
uint64_t b_mask = mp_chmap_to_lavc_unchecked(b);
|
||||
return popcount64((a_mask ^ b_mask) & a_mask);
|
||||
for (int n = 0; n < from->num; n++)
|
||||
assert(to->speaker[dst[n]] == from->speaker[n]);
|
||||
}
|
||||
|
||||
// Returns something like "fl-fr-fc". If there's a standard layout in lavc
|
||||
|
||||
+6
-11
@@ -56,12 +56,10 @@ enum mp_speaker_id {
|
||||
MP_SPEAKER_ID_SDR, // SURROUND_DIRECT_RIGHT
|
||||
MP_SPEAKER_ID_LFE2, // LOW_FREQUENCY_2
|
||||
|
||||
// Speaker IDs >= 64 are not representable in WAVEFORMATEXTENSIBLE or libav*.
|
||||
|
||||
// "Silent" channels. These are sometimes used to insert padding for
|
||||
// unused channels. Unlike other speaker types, multiple of these can
|
||||
// occur in a single mp_chmap.
|
||||
MP_SPEAKER_ID_NA = 64,
|
||||
// Special mpv-specific speaker entries reserved for channels which have no
|
||||
// known meaning.
|
||||
MP_SPEAKER_ID_UNKNOWN0 = 64,
|
||||
MP_SPEAKER_ID_UNKNOWN_LAST = MP_SPEAKER_ID_UNKNOWN0 + MP_NUM_CHANNELS - 1,
|
||||
|
||||
// Including the unassigned IDs in between. This is not a valid ID anymore,
|
||||
// but is still within uint8_t.
|
||||
@@ -100,11 +98,10 @@ bool mp_chmap_is_empty(const struct mp_chmap *src);
|
||||
bool mp_chmap_is_unknown(const struct mp_chmap *src);
|
||||
bool mp_chmap_equals(const struct mp_chmap *a, const struct mp_chmap *b);
|
||||
bool mp_chmap_equals_reordered(const struct mp_chmap *a, const struct mp_chmap *b);
|
||||
bool mp_chmap_is_compatible(const struct mp_chmap *a, const struct mp_chmap *b);
|
||||
bool mp_chmap_is_stereo(const struct mp_chmap *src);
|
||||
|
||||
void mp_chmap_reorder_norm(struct mp_chmap *map);
|
||||
void mp_chmap_remove_na(struct mp_chmap *map);
|
||||
void mp_chmap_fill_na(struct mp_chmap *map, int num);
|
||||
|
||||
void mp_chmap_from_channels(struct mp_chmap *dst, int num_channels);
|
||||
void mp_chmap_set_unknown(struct mp_chmap *dst, int num_channels);
|
||||
@@ -120,11 +117,9 @@ void mp_chmap_from_lavc(struct mp_chmap *dst, uint64_t src);
|
||||
bool mp_chmap_is_lavc(const struct mp_chmap *src);
|
||||
void mp_chmap_reorder_to_lavc(struct mp_chmap *map);
|
||||
|
||||
void mp_chmap_get_reorder(int src[MP_NUM_CHANNELS], const struct mp_chmap *from,
|
||||
void mp_chmap_get_reorder(int dst[MP_NUM_CHANNELS], const struct mp_chmap *from,
|
||||
const struct mp_chmap *to);
|
||||
|
||||
int mp_chmap_diffn(const struct mp_chmap *a, const struct mp_chmap *b);
|
||||
|
||||
char *mp_chmap_to_str_buf(char *buf, size_t buf_size, const struct mp_chmap *src);
|
||||
#define mp_chmap_to_str(m) mp_chmap_to_str_buf((char[64]){0}, 64, (m))
|
||||
|
||||
|
||||
+12
-86
@@ -17,7 +17,6 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "common/common.h"
|
||||
#include "chmap_sel.h"
|
||||
@@ -74,7 +73,7 @@ void mp_chmap_sel_add_waveext(struct mp_chmap_sel *s)
|
||||
// Classic ALSA-based MPlayer layouts.
|
||||
void mp_chmap_sel_add_alsa_def(struct mp_chmap_sel *s)
|
||||
{
|
||||
for (int n = 1; n <= MP_NUM_CHANNELS; n++) {
|
||||
for (int n = 0; n < MP_NUM_CHANNELS; n++) {
|
||||
struct mp_chmap t;
|
||||
mp_chmap_from_channels_alsa(&t, n);
|
||||
if (t.num)
|
||||
@@ -82,27 +81,20 @@ void mp_chmap_sel_add_alsa_def(struct mp_chmap_sel *s)
|
||||
}
|
||||
}
|
||||
|
||||
#define ARRAY_LEN(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
// Add a channel map that should be allowed.
|
||||
void mp_chmap_sel_add_map(struct mp_chmap_sel *s, const struct mp_chmap *map)
|
||||
{
|
||||
if (!mp_chmap_is_valid(map))
|
||||
return;
|
||||
if (!s->chmaps)
|
||||
s->chmaps = s->chmaps_storage;
|
||||
if (s->num_chmaps == MP_ARRAY_SIZE(s->chmaps_storage)) {
|
||||
if (!s->tmp)
|
||||
return;
|
||||
s->chmaps = talloc_memdup(s->tmp, s->chmaps, sizeof(s->chmaps_storage));
|
||||
}
|
||||
if (s->chmaps != s->chmaps_storage)
|
||||
MP_TARRAY_GROW(s->tmp, s->chmaps, s->num_chmaps);
|
||||
s->chmaps[s->num_chmaps++] = *map;
|
||||
assert(s->num_chmaps < ARRAY_LEN(s->chmaps));
|
||||
if (mp_chmap_is_valid(map))
|
||||
s->chmaps[s->num_chmaps++] = *map;
|
||||
}
|
||||
|
||||
// Allow all waveext formats in default order.
|
||||
void mp_chmap_sel_add_waveext_def(struct mp_chmap_sel *s)
|
||||
{
|
||||
for (int n = 1; n <= MP_NUM_CHANNELS; n++) {
|
||||
for (int n = 1; n < MP_NUM_CHANNELS; n++) {
|
||||
struct mp_chmap map;
|
||||
mp_chmap_from_channels(&map, n);
|
||||
mp_chmap_sel_add_map(s, &map);
|
||||
@@ -184,84 +176,18 @@ bool mp_chmap_sel_adjust(const struct mp_chmap_sel *s, struct mp_chmap *map)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (mp_chmap_sel_fallback(s, map))
|
||||
return true;
|
||||
|
||||
// Fallback to mono/stereo as last resort
|
||||
*map = (struct mp_chmap) MP_CHMAP_INIT_STEREO;
|
||||
if (test_layout(s, map))
|
||||
return true;
|
||||
*map = (struct mp_chmap) MP_CHMAP_INIT_MONO;
|
||||
if (map->num == 1) {
|
||||
*map = (struct mp_chmap) MP_CHMAP_INIT_MONO;
|
||||
} else if (map->num >= 2) {
|
||||
*map = (struct mp_chmap) MP_CHMAP_INIT_STEREO;
|
||||
}
|
||||
if (test_layout(s, map))
|
||||
return true;
|
||||
*map = (struct mp_chmap) {0};
|
||||
return false;
|
||||
}
|
||||
|
||||
// Decide whether we should prefer old or new for the requested layout.
|
||||
// Return true if new should be used, false if old should be used.
|
||||
// If old is empty, always return new (initial case).
|
||||
static bool mp_chmap_is_better(struct mp_chmap *req, struct mp_chmap *old,
|
||||
struct mp_chmap *new)
|
||||
{
|
||||
int old_lost = mp_chmap_diffn(req, old); // num. channels only in req
|
||||
int new_lost = mp_chmap_diffn(req, new);
|
||||
|
||||
// Initial case
|
||||
if (!old->num)
|
||||
return true;
|
||||
|
||||
// Imperfect upmix (no real superset) - minimize lost channels
|
||||
if (new_lost != old_lost)
|
||||
return new_lost < old_lost;
|
||||
|
||||
// Some kind of upmix. If it's perfect, prefer the smaller one. Even if not,
|
||||
// both have equal loss, so also prefer the smaller one.
|
||||
return new->num < old->num;
|
||||
}
|
||||
|
||||
// Determine which channel map to fallback to given a source channel map.
|
||||
bool mp_chmap_sel_fallback(const struct mp_chmap_sel *s, struct mp_chmap *map)
|
||||
{
|
||||
// special case: if possible always fallback mono to stereo (instead of
|
||||
// looking for a multichannel upmix)
|
||||
struct mp_chmap mono = MP_CHMAP_INIT_MONO;
|
||||
struct mp_chmap stereo = MP_CHMAP_INIT_STEREO;
|
||||
if (mp_chmap_equals(&mono, map) && test_layout(s, &stereo)) {
|
||||
*map = stereo;
|
||||
return true;
|
||||
}
|
||||
|
||||
struct mp_chmap best = {0};
|
||||
|
||||
for (int n = 0; n < s->num_chmaps; n++) {
|
||||
struct mp_chmap e = s->chmaps[n];
|
||||
|
||||
if (mp_chmap_is_unknown(&e))
|
||||
continue;
|
||||
|
||||
// in case we didn't match any fallback retry after replacing speakers
|
||||
for (int i = -1; i < (int)MP_ARRAY_SIZE(speaker_replacements); i++) {
|
||||
struct mp_chmap t = *map;
|
||||
if (i >= 0) {
|
||||
struct mp_chmap *r = (struct mp_chmap *)speaker_replacements[i];
|
||||
if (!replace_speakers(&t, r))
|
||||
continue;
|
||||
}
|
||||
if (mp_chmap_is_better(&t, &best, &e))
|
||||
best = e;
|
||||
}
|
||||
}
|
||||
|
||||
if (best.num) {
|
||||
*map = best;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set map to a default layout with num channels. Used for audio APIs that
|
||||
// return a channel count as part of format negotiation, but give no
|
||||
// information about the channel layout.
|
||||
|
||||
+1
-6
@@ -26,12 +26,8 @@ struct mp_chmap_sel {
|
||||
// should be considered opaque
|
||||
bool allow_any, allow_waveext;
|
||||
bool speakers[MP_SPEAKER_ID_COUNT];
|
||||
struct mp_chmap *chmaps;
|
||||
struct mp_chmap chmaps[20];
|
||||
int num_chmaps;
|
||||
|
||||
struct mp_chmap chmaps_storage[20];
|
||||
|
||||
void *tmp; // set to any talloc context to allow more chmaps entries
|
||||
};
|
||||
|
||||
void mp_chmap_sel_add_any(struct mp_chmap_sel *s);
|
||||
@@ -41,7 +37,6 @@ void mp_chmap_sel_add_alsa_def(struct mp_chmap_sel *s);
|
||||
void mp_chmap_sel_add_map(struct mp_chmap_sel *s, const struct mp_chmap *map);
|
||||
void mp_chmap_sel_add_speaker(struct mp_chmap_sel *s, int id);
|
||||
bool mp_chmap_sel_adjust(const struct mp_chmap_sel *s, struct mp_chmap *map);
|
||||
bool mp_chmap_sel_fallback(const struct mp_chmap_sel *s, struct mp_chmap *map);
|
||||
bool mp_chmap_sel_get_def(const struct mp_chmap_sel *s, struct mp_chmap *map,
|
||||
int num);
|
||||
|
||||
|
||||
+5
-4
@@ -1,18 +1,19 @@
|
||||
/*
|
||||
* This file is part of mpv.
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MPLAYER_AD_H
|
||||
|
||||
+11
-7
@@ -1,18 +1,19 @@
|
||||
/*
|
||||
* This file is part of mpv.
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -58,7 +59,7 @@ struct ad_lavc_params {
|
||||
|
||||
const struct m_sub_options ad_lavc_conf = {
|
||||
.opts = (const m_option_t[]) {
|
||||
OPT_FLOATRANGE("ac3drc", ac3drc, 0, 0, 6),
|
||||
OPT_FLOATRANGE("ac3drc", ac3drc, 0, 0, 2),
|
||||
OPT_FLAG("downmix", downmix, 0),
|
||||
OPT_INTRANGE("threads", threads, 0, 1, 16),
|
||||
OPT_KEYVALUELIST("o", avopts, 0),
|
||||
@@ -66,7 +67,7 @@ const struct m_sub_options ad_lavc_conf = {
|
||||
},
|
||||
.size = sizeof(struct ad_lavc_params),
|
||||
.defaults = &(const struct ad_lavc_params){
|
||||
.ac3drc = 0,
|
||||
.ac3drc = 1.,
|
||||
.downmix = 1,
|
||||
.threads = 1,
|
||||
},
|
||||
@@ -135,7 +136,7 @@ static int init(struct dec_audio *da, const char *decoder)
|
||||
if (sh->lav_headers)
|
||||
mp_copy_lav_codec_headers(lavc_context, sh->lav_headers);
|
||||
|
||||
mp_set_avcodec_threads(da->log, lavc_context, opts->threads);
|
||||
mp_set_avcodec_threads(lavc_context, opts->threads);
|
||||
|
||||
/* open it */
|
||||
if (avcodec_open2(lavc_context, lavc_codec, NULL) < 0) {
|
||||
@@ -144,6 +145,9 @@ static int init(struct dec_audio *da, const char *decoder)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lavc_context->bit_rate != 0)
|
||||
da->bitrate = lavc_context->bit_rate;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* MPEG 1.0/2.0/2.5 audio layer I, II, III decoding with libmpg123
|
||||
*
|
||||
* Copyright (C) 2010-2013 Thomas Orgis <thomas@orgis.org>
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "ad.h"
|
||||
#include "common/msg.h"
|
||||
|
||||
#include <mpg123.h>
|
||||
|
||||
#if (defined MPG123_API_VERSION) && (MPG123_API_VERSION < 33)
|
||||
#error "This should not happen"
|
||||
#endif
|
||||
|
||||
struct ad_mpg123_context {
|
||||
mpg123_handle *handle;
|
||||
int sample_size;
|
||||
/* Running mean for bit rate, stream length estimation. */
|
||||
float mean_rate;
|
||||
unsigned int mean_count;
|
||||
/* Time delay for updates. */
|
||||
short delay;
|
||||
/* If the stream is actually VBR. */
|
||||
char vbr;
|
||||
struct mp_audio frame;
|
||||
};
|
||||
|
||||
static void uninit(struct dec_audio *da)
|
||||
{
|
||||
struct ad_mpg123_context *con = da->priv;
|
||||
|
||||
mpg123_close(con->handle);
|
||||
mpg123_delete(con->handle);
|
||||
mpg123_exit();
|
||||
}
|
||||
|
||||
/* This initializes libmpg123 and prepares the handle, including funky
|
||||
* parameters. */
|
||||
static int init(struct dec_audio *da, const char *decoder)
|
||||
{
|
||||
int err;
|
||||
struct ad_mpg123_context *con;
|
||||
/* Assumption: You always call preinit + init + uninit, on every file.
|
||||
* But you stop at preinit in case it fails.
|
||||
* If that is not true, one must ensure not to call mpg123_init / exit
|
||||
* twice in a row. */
|
||||
if (mpg123_init() != MPG123_OK)
|
||||
return 0;
|
||||
|
||||
da->priv = talloc_zero(NULL, struct ad_mpg123_context);
|
||||
con = da->priv;
|
||||
/* Auto-choice of optimized decoder (first argument NULL). */
|
||||
con->handle = mpg123_new(NULL, &err);
|
||||
if (!con->handle)
|
||||
goto bad_end;
|
||||
|
||||
/* Basic settings.
|
||||
* Don't spill messages, enable better resync with non-seekable streams.
|
||||
* Give both flags individually without error checking to keep going with
|
||||
* old libmpg123. Generally, it is not fatal if the flags are not
|
||||
* honored */
|
||||
mpg123_param(con->handle, MPG123_ADD_FLAGS, MPG123_QUIET, 0.0);
|
||||
/* Do not bail out on malformed streams at all.
|
||||
* MPlayer does not handle a decoder throwing the towel on crappy input. */
|
||||
mpg123_param(con->handle, MPG123_RESYNC_LIMIT, -1, 0.0);
|
||||
|
||||
/* Open decisions: Configure libmpg123 to force encoding (or stay open about
|
||||
* library builds that support only float or int32 output), (de)configure
|
||||
* gapless decoding (won't work with seeking in MPlayer, though).
|
||||
* Don't forget to eventually enable ReplayGain/RVA support, too.
|
||||
* Let's try to run with the default for now. */
|
||||
|
||||
/* That would produce floating point output.
|
||||
* You can get 32 and 24 bit ints, even 8 bit via format matrix.
|
||||
* If wanting a specific encoding here, configure format matrix and
|
||||
* make sure it is in set_format(). */
|
||||
/* mpg123_param(con->handle, MPG123_ADD_FLAGS, MPG123_FORCE_FLOAT, 0.); */
|
||||
|
||||
/* Example for RVA choice (available since libmpg123 1.0.0):
|
||||
mpg123_param(con->handle, MPG123_RVA, MPG123_RVA_MIX, 0.0) */
|
||||
|
||||
/* Prevent funky automatic resampling.
|
||||
* This way, we can be sure that one frame will never produce
|
||||
* more than 1152 stereo samples.
|
||||
* Background:
|
||||
* Going to decode directly to the output buffer. It is important to have
|
||||
* MPG123_AUTO_RESAMPLE disabled for the buffer size being an all-time
|
||||
* limit.
|
||||
* We need at least 1152 samples. dec_audio.c normally guarantees this. */
|
||||
mpg123_param(con->handle, MPG123_REMOVE_FLAGS, MPG123_AUTO_RESAMPLE, 0.);
|
||||
|
||||
err = mpg123_open_feed(con->handle);
|
||||
if (err != MPG123_OK)
|
||||
goto bad_end;
|
||||
|
||||
return 1;
|
||||
|
||||
bad_end:
|
||||
if (!con->handle) {
|
||||
MP_ERR(da, "mpg123 preinit error: %s\n", mpg123_plain_strerror(err));
|
||||
} else {
|
||||
MP_ERR(da, "mpg123 preinit error: %s\n", mpg123_strerror(con->handle));
|
||||
}
|
||||
|
||||
uninit(da);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpg123_format_to_af(int mpg123_encoding)
|
||||
{
|
||||
/* Without external force, mpg123 will always choose signed encoding,
|
||||
* and non-16-bit only on builds that don't support it.
|
||||
* Be reminded that it doesn't matter to the MPEG file what encoding
|
||||
* is produced from it. */
|
||||
switch (mpg123_encoding) {
|
||||
case MPG123_ENC_SIGNED_8: return AF_FORMAT_S8;
|
||||
case MPG123_ENC_SIGNED_16: return AF_FORMAT_S16;
|
||||
case MPG123_ENC_SIGNED_32: return AF_FORMAT_S32;
|
||||
case MPG123_ENC_FLOAT_32: return AF_FORMAT_FLOAT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compute bitrate from frame size. */
|
||||
static int compute_bitrate(struct mpg123_frameinfo *i)
|
||||
{
|
||||
static const int samples_per_frame[4][4] = {
|
||||
{-1, 384, 1152, 1152}, /* MPEG 1 */
|
||||
{-1, 384, 1152, 576}, /* MPEG 2 */
|
||||
{-1, 384, 1152, 576}, /* MPEG 2.5 */
|
||||
{-1, -1, -1, -1}, /* Unknown */
|
||||
};
|
||||
return (int) ((i->framesize + 4) * 8 * i->rate /
|
||||
samples_per_frame[i->version][i->layer] + 0.5);
|
||||
}
|
||||
|
||||
/* Update mean bitrate. This could be dropped if accurate time display
|
||||
* on audio file playback is not desired. */
|
||||
static void update_info(struct dec_audio *da)
|
||||
{
|
||||
struct ad_mpg123_context *con = da->priv;
|
||||
struct mpg123_frameinfo finfo;
|
||||
if (mpg123_info(con->handle, &finfo) != MPG123_OK)
|
||||
return;
|
||||
|
||||
/* finfo.bitrate is expressed in kilobits */
|
||||
const int bitrate = finfo.bitrate * 1000;
|
||||
|
||||
if (finfo.vbr != MPG123_CBR) {
|
||||
if (--con->delay < 1) {
|
||||
if (++con->mean_count > ((unsigned int) -1) / 2)
|
||||
con->mean_count = ((unsigned int) -1) / 4;
|
||||
|
||||
/* Might not be numerically optimal, but works fine enough. */
|
||||
con->mean_rate = ((con->mean_count - 1) * con->mean_rate +
|
||||
bitrate) / con->mean_count;
|
||||
da->bitrate = (int) (con->mean_rate + 0.5);
|
||||
|
||||
con->delay = 10;
|
||||
}
|
||||
} else {
|
||||
da->bitrate = bitrate ? bitrate : compute_bitrate(&finfo);
|
||||
con->delay = 1;
|
||||
con->mean_rate = 0.;
|
||||
con->mean_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* libmpg123 has a new format ready; query and store, return return value
|
||||
of mpg123_getformat() */
|
||||
static int set_format(struct dec_audio *da)
|
||||
{
|
||||
struct ad_mpg123_context *con = da->priv;
|
||||
int ret;
|
||||
long rate;
|
||||
int channels;
|
||||
int encoding;
|
||||
ret = mpg123_getformat(con->handle, &rate, &channels, &encoding);
|
||||
if (ret == MPG123_OK) {
|
||||
mp_audio_set_num_channels(&con->frame, channels);
|
||||
con->frame.rate = rate;
|
||||
int af = mpg123_format_to_af(encoding);
|
||||
if (!af) {
|
||||
/* This means we got a funny custom build of libmpg123 that only supports an unknown format. */
|
||||
MP_ERR(da, "Bad encoding from mpg123: %i.\n", encoding);
|
||||
return MPG123_ERR;
|
||||
}
|
||||
mp_audio_set_format(&con->frame, af);
|
||||
con->sample_size = channels * af_fmt2bps(af);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int decode_packet(struct dec_audio *da, struct mp_audio **out)
|
||||
{
|
||||
struct ad_mpg123_context *con = da->priv;
|
||||
int ret;
|
||||
|
||||
struct demux_packet *pkt;
|
||||
if (demux_read_packet_async(da->header, &pkt) == 0)
|
||||
return AD_WAIT;
|
||||
if (!pkt)
|
||||
return AD_EOF;
|
||||
|
||||
/* Next bytes from that presentation time. */
|
||||
if (pkt->pts != MP_NOPTS_VALUE) {
|
||||
da->pts = pkt->pts;
|
||||
da->pts_offset = 0;
|
||||
}
|
||||
|
||||
/* Have to use mpg123_feed() to avoid decoding here. */
|
||||
ret = mpg123_feed(con->handle, pkt->buffer, pkt->len);
|
||||
talloc_free(pkt);
|
||||
|
||||
if (ret != MPG123_OK)
|
||||
goto mpg123_fail;
|
||||
|
||||
unsigned char *audio = NULL;
|
||||
size_t bytes = 0;
|
||||
ret = mpg123_decode_frame(con->handle, NULL, &audio, &bytes);
|
||||
|
||||
if (ret == MPG123_NEED_MORE)
|
||||
return 0;
|
||||
|
||||
if (ret != MPG123_OK && ret != MPG123_DONE && ret != MPG123_NEW_FORMAT)
|
||||
goto mpg123_fail;
|
||||
|
||||
ret = set_format(da);
|
||||
if (ret != MPG123_OK)
|
||||
goto mpg123_fail;
|
||||
|
||||
if (con->sample_size < 1) {
|
||||
MP_ERR(da, "no sample size\n");
|
||||
return AD_ERR;
|
||||
}
|
||||
|
||||
int got_samples = bytes / con->sample_size;
|
||||
*out = mp_audio_pool_get(da->pool, &con->frame, got_samples);
|
||||
if (!*out)
|
||||
return AD_ERR;
|
||||
|
||||
memcpy((*out)->planes[0], audio, bytes);
|
||||
|
||||
update_info(da);
|
||||
return 0;
|
||||
|
||||
mpg123_fail:
|
||||
MP_ERR(da, "mpg123 decoding error: %s\n", mpg123_strerror(con->handle));
|
||||
return AD_ERR;
|
||||
}
|
||||
|
||||
static int control(struct dec_audio *da, int cmd, void *arg)
|
||||
{
|
||||
struct ad_mpg123_context *con = da->priv;
|
||||
|
||||
switch (cmd) {
|
||||
case ADCTRL_RESET:
|
||||
mpg123_close(con->handle);
|
||||
|
||||
if (mpg123_open_feed(con->handle) != MPG123_OK) {
|
||||
MP_ERR(da, "mpg123 failed to reopen stream: %s\n",
|
||||
mpg123_strerror(con->handle));
|
||||
return CONTROL_FALSE;
|
||||
}
|
||||
return CONTROL_TRUE;
|
||||
}
|
||||
return CONTROL_UNKNOWN;
|
||||
}
|
||||
|
||||
static void add_decoders(struct mp_decoder_list *list)
|
||||
{
|
||||
mp_add_decoder(list, "mpg123", "mp3", "mp3",
|
||||
"High-performance decoder using libmpg123");
|
||||
}
|
||||
|
||||
const struct ad_functions ad_mpg123 = {
|
||||
.name = "mpg123",
|
||||
.add_decoders = add_decoders,
|
||||
.init = init,
|
||||
.uninit = uninit,
|
||||
.control = control,
|
||||
.decode_packet = decode_packet,
|
||||
};
|
||||
+15
-5
@@ -1,20 +1,21 @@
|
||||
/*
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* Copyright (C) 2012 Naoya OYAMA
|
||||
*
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
@@ -35,6 +36,7 @@
|
||||
struct spdifContext {
|
||||
struct mp_log *log;
|
||||
AVFormatContext *lavf_ctx;
|
||||
int iec61937_packet_size;
|
||||
int out_buffer_len;
|
||||
uint8_t out_buffer[OUTBUF_SIZE];
|
||||
bool need_close;
|
||||
@@ -115,11 +117,13 @@ static int init(struct dec_audio *da, const char *decoder)
|
||||
int samplerate = 0;
|
||||
switch (stream->codec->codec_id) {
|
||||
case AV_CODEC_ID_AAC:
|
||||
spdif_ctx->iec61937_packet_size = 16384;
|
||||
sample_format = AF_FORMAT_S_AAC;
|
||||
samplerate = 48000;
|
||||
num_channels = 2;
|
||||
break;
|
||||
case AV_CODEC_ID_AC3:
|
||||
spdif_ctx->iec61937_packet_size = 6144;
|
||||
sample_format = AF_FORMAT_S_AC3;
|
||||
samplerate = 48000;
|
||||
num_channels = 2;
|
||||
@@ -127,26 +131,31 @@ static int init(struct dec_audio *da, const char *decoder)
|
||||
case AV_CODEC_ID_DTS:
|
||||
if (da->opts->dtshd) {
|
||||
av_dict_set(&format_opts, "dtshd_rate", "768000", 0); // 4*192000
|
||||
spdif_ctx->iec61937_packet_size = 32768;
|
||||
sample_format = AF_FORMAT_S_DTSHD;
|
||||
samplerate = 192000;
|
||||
num_channels = 2*4;
|
||||
} else {
|
||||
spdif_ctx->iec61937_packet_size = 32768;
|
||||
sample_format = AF_FORMAT_S_DTS;
|
||||
samplerate = 48000;
|
||||
num_channels = 2;
|
||||
}
|
||||
break;
|
||||
case AV_CODEC_ID_EAC3:
|
||||
spdif_ctx->iec61937_packet_size = 24576;
|
||||
sample_format = AF_FORMAT_S_EAC3;
|
||||
samplerate = 192000;
|
||||
num_channels = 2;
|
||||
break;
|
||||
case AV_CODEC_ID_MP3:
|
||||
spdif_ctx->iec61937_packet_size = 4608;
|
||||
sample_format = AF_FORMAT_S_MP3;
|
||||
samplerate = 48000;
|
||||
num_channels = 2;
|
||||
break;
|
||||
case AV_CODEC_ID_TRUEHD:
|
||||
spdif_ctx->iec61937_packet_size = 61440;
|
||||
sample_format = AF_FORMAT_S_TRUEHD;
|
||||
samplerate = 192000;
|
||||
num_channels = 8;
|
||||
@@ -191,6 +200,7 @@ static int decode_packet(struct dec_audio *da, struct mp_audio **out)
|
||||
AVPacket pkt;
|
||||
mp_set_av_packet(&pkt, mpkt, NULL);
|
||||
pkt.pts = pkt.dts = 0;
|
||||
MP_VERBOSE(da, "spdif packet, size=%d\n", pkt.size);
|
||||
if (mpkt->pts != MP_NOPTS_VALUE) {
|
||||
da->pts = mpkt->pts;
|
||||
da->pts_offset = 0;
|
||||
|
||||
+50
-61
@@ -1,18 +1,19 @@
|
||||
/*
|
||||
* This file is part of mpv.
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -24,6 +25,7 @@
|
||||
|
||||
#include "demux/codec_tags.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "common/codecs.h"
|
||||
#include "common/msg.h"
|
||||
#include "misc/bstr.h"
|
||||
@@ -41,11 +43,15 @@
|
||||
|
||||
#include "audio/filter/af.h"
|
||||
|
||||
extern const struct ad_functions ad_mpg123;
|
||||
extern const struct ad_functions ad_lavc;
|
||||
extern const struct ad_functions ad_spdif;
|
||||
|
||||
static const struct ad_functions * const ad_drivers[] = {
|
||||
&ad_lavc,
|
||||
#if HAVE_MPG123
|
||||
&ad_mpg123,
|
||||
#endif
|
||||
&ad_spdif,
|
||||
NULL
|
||||
};
|
||||
@@ -147,51 +153,23 @@ void audio_uninit(struct dec_audio *d_audio)
|
||||
MP_VERBOSE(d_audio, "Uninit audio filters...\n");
|
||||
af_destroy(d_audio->afilter);
|
||||
uninit_decoder(d_audio);
|
||||
talloc_free(d_audio->waiting);
|
||||
talloc_free(d_audio);
|
||||
}
|
||||
|
||||
static int decode_new_frame(struct dec_audio *da)
|
||||
{
|
||||
while (!da->waiting) {
|
||||
int ret = da->ad_driver->decode_packet(da, &da->waiting);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (da->pts == MP_NOPTS_VALUE && da->header->missing_timestamps)
|
||||
da->pts = 0;
|
||||
|
||||
if (da->waiting) {
|
||||
da->pts_offset += da->waiting->samples;
|
||||
da->decode_format = *da->waiting;
|
||||
mp_audio_set_null_data(&da->decode_format);
|
||||
}
|
||||
}
|
||||
return mp_audio_config_valid(da->waiting) ? AD_OK : AD_ERR;
|
||||
}
|
||||
|
||||
/* Decode packets until we know the audio format. Then reinit the buffer.
|
||||
* Returns AD_OK on success, negative AD_* code otherwise.
|
||||
* Also returns AD_OK if already initialized (and does nothing).
|
||||
*/
|
||||
int initial_audio_decode(struct dec_audio *da)
|
||||
{
|
||||
return decode_new_frame(da);
|
||||
}
|
||||
|
||||
static bool copy_output(struct af_stream *afs, struct mp_audio_buffer *outbuf,
|
||||
int minsamples, bool eof)
|
||||
{
|
||||
while (mp_audio_buffer_samples(outbuf) < minsamples) {
|
||||
if (af_output_frame(afs, eof) < 0)
|
||||
return true; // error, stop doing stuff
|
||||
struct mp_audio *mpa = af_read_output_frame(afs);
|
||||
if (!mpa)
|
||||
return false; // out of data
|
||||
mp_audio_buffer_append(outbuf, mpa);
|
||||
talloc_free(mpa);
|
||||
while (!da->waiting) {
|
||||
int ret = da->ad_driver->decode_packet(da, &da->waiting);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
return true;
|
||||
talloc_steal(da, da->waiting);
|
||||
da->decode_format = *da->waiting;
|
||||
return mp_audio_config_valid(da->waiting) ? AD_OK : AD_ERR;
|
||||
}
|
||||
|
||||
/* Try to get at least minsamples decoded+filtered samples in outbuf
|
||||
@@ -208,30 +186,41 @@ int audio_decode(struct dec_audio *da, struct mp_audio_buffer *outbuf,
|
||||
|
||||
MP_STATS(da, "start audio");
|
||||
|
||||
int res;
|
||||
while (1) {
|
||||
int res = 0;
|
||||
while (res >= 0 && minsamples >= 0) {
|
||||
int buffered = mp_audio_buffer_samples(outbuf);
|
||||
if (minsamples < buffered)
|
||||
break;
|
||||
|
||||
res = 0;
|
||||
|
||||
if (copy_output(afs, outbuf, minsamples, false))
|
||||
break;
|
||||
|
||||
res = decode_new_frame(da);
|
||||
if (res < 0) {
|
||||
// drain filters first (especially for true EOF case)
|
||||
copy_output(afs, outbuf, minsamples, true);
|
||||
break;
|
||||
}
|
||||
|
||||
// On format change, make sure to drain the filter chain.
|
||||
if (!mp_audio_config_equals(&afs->input, da->waiting)) {
|
||||
copy_output(afs, outbuf, minsamples, true);
|
||||
res = AD_NEW_FMT;
|
||||
break;
|
||||
}
|
||||
|
||||
struct mp_audio *mpa = da->waiting;
|
||||
da->waiting = NULL;
|
||||
if (af_filter_frame(afs, mpa) < 0)
|
||||
if (!mpa)
|
||||
res = da->ad_driver->decode_packet(da, &mpa);
|
||||
|
||||
if (res != AD_EOF) {
|
||||
if (res < 0)
|
||||
break;
|
||||
if (!mpa )
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mpa) {
|
||||
da->pts_offset += mpa->samples;
|
||||
da->decode_format = *mpa;
|
||||
mp_audio_set_null_data(&da->decode_format);
|
||||
// On format change, make sure to drain the filter chain.
|
||||
if (!mp_audio_config_equals(&afs->input, mpa)) {
|
||||
res = AD_NEW_FMT;
|
||||
da->waiting = talloc_steal(da, mpa);
|
||||
mpa = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (mpa)
|
||||
da->waiting = NULL;
|
||||
|
||||
if (af_filter(afs, mpa, outbuf) < 0)
|
||||
return AD_ERR;
|
||||
}
|
||||
|
||||
@@ -244,7 +233,7 @@ void audio_reset_decoding(struct dec_audio *d_audio)
|
||||
{
|
||||
if (d_audio->ad_driver)
|
||||
d_audio->ad_driver->control(d_audio, ADCTRL_RESET, NULL);
|
||||
af_seek_reset(d_audio->afilter);
|
||||
af_control_all(d_audio->afilter, AF_CONTROL_RESET, NULL);
|
||||
d_audio->pts = MP_NOPTS_VALUE;
|
||||
d_audio->pts_offset = 0;
|
||||
if (d_audio->waiting) {
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
/*
|
||||
* This file is part of mpv.
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MPLAYER_DEC_AUDIO_H
|
||||
|
||||
+82
-182
@@ -1,18 +1,19 @@
|
||||
/*
|
||||
* This file is part of mpv.
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -53,11 +54,11 @@ extern const struct af_info af_info_center;
|
||||
extern const struct af_info af_info_sinesuppress;
|
||||
extern const struct af_info af_info_karaoke;
|
||||
extern const struct af_info af_info_scaletempo;
|
||||
extern const struct af_info af_info_forcespeed;
|
||||
extern const struct af_info af_info_bs2b;
|
||||
extern const struct af_info af_info_lavfi;
|
||||
extern const struct af_info af_info_convert24;
|
||||
extern const struct af_info af_info_convertsignendian;
|
||||
extern const struct af_info af_info_rubberband;
|
||||
|
||||
static const struct af_info *const filter_list[] = {
|
||||
&af_info_dummy,
|
||||
@@ -69,7 +70,9 @@ static const struct af_info *const filter_list[] = {
|
||||
&af_info_pan,
|
||||
&af_info_surround,
|
||||
&af_info_sub,
|
||||
#if HAVE_SYS_MMAN_H
|
||||
&af_info_export,
|
||||
#endif
|
||||
&af_info_drc,
|
||||
&af_info_extrastereo,
|
||||
&af_info_lavcac3enc,
|
||||
@@ -78,13 +81,11 @@ static const struct af_info *const filter_list[] = {
|
||||
&af_info_hrtf,
|
||||
#if HAVE_LADSPA
|
||||
&af_info_ladspa,
|
||||
#endif
|
||||
#if HAVE_RUBBERBAND
|
||||
&af_info_rubberband,
|
||||
#endif
|
||||
&af_info_center,
|
||||
&af_info_sinesuppress,
|
||||
&af_info_karaoke,
|
||||
&af_info_forcespeed,
|
||||
&af_info_scaletempo,
|
||||
#if HAVE_LIBBS2B
|
||||
&af_info_bs2b,
|
||||
@@ -123,19 +124,6 @@ const struct m_obj_list af_obj_list = {
|
||||
},
|
||||
};
|
||||
|
||||
static void af_forget_frames(struct af_instance *af)
|
||||
{
|
||||
for (int n = 0; n < af->num_out_queued; n++)
|
||||
talloc_free(af->out_queued[n]);
|
||||
af->num_out_queued = 0;
|
||||
}
|
||||
|
||||
static void af_chain_forget_frames(struct af_stream *s)
|
||||
{
|
||||
for (struct af_instance *cur = s->first; cur; cur = cur->next)
|
||||
af_forget_frames(cur);
|
||||
}
|
||||
|
||||
static void af_copy_unset_fields(struct mp_audio *dst, struct mp_audio *src)
|
||||
{
|
||||
if (dst->format == AF_FORMAT_UNKNOWN)
|
||||
@@ -176,9 +164,8 @@ static int output_control(struct af_instance* af, int cmd, void* arg)
|
||||
return AF_UNKNOWN;
|
||||
}
|
||||
|
||||
static int dummy_filter(struct af_instance *af, struct mp_audio *frame)
|
||||
static int dummy_filter(struct af_instance* af, struct mp_audio* data, int f)
|
||||
{
|
||||
af_add_output_frame(af, frame);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -210,10 +197,10 @@ static struct af_instance *af_create(struct af_stream *s, char *name,
|
||||
struct af_instance *af = talloc_zero(NULL, struct af_instance);
|
||||
*af = (struct af_instance) {
|
||||
.info = info,
|
||||
.mul = 1,
|
||||
.data = talloc_zero(af, struct mp_audio),
|
||||
.log = mp_log_new(af, s->log, name),
|
||||
.replaygain_data = s->replaygain_data,
|
||||
.out_pool = mp_audio_pool_create(af),
|
||||
};
|
||||
struct m_config *config = m_config_from_obj_desc(af, s->log, &desc);
|
||||
if (m_config_apply_defaults(config, name, s->opts->af_defs) < 0)
|
||||
@@ -298,7 +285,6 @@ static void af_remove(struct af_stream *s, struct af_instance *af)
|
||||
|
||||
if (af->uninit)
|
||||
af->uninit(af);
|
||||
af_forget_frames(af);
|
||||
talloc_free(af);
|
||||
}
|
||||
|
||||
@@ -504,15 +490,6 @@ static int af_fix_rate(struct af_stream *s, struct af_instance **p_af,
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
static void reset_formats(struct af_stream *s)
|
||||
{
|
||||
for (struct af_instance *af = s->first; af; af = af->next) {
|
||||
af->control(af, AF_CONTROL_SET_RESAMPLE_RATE, &(int){0});
|
||||
af->control(af, AF_CONTROL_SET_CHANNELS, &(struct mp_chmap){0});
|
||||
af->control(af, AF_CONTROL_SET_FORMAT, &(int){0});
|
||||
}
|
||||
}
|
||||
|
||||
// Return AF_OK on success or AF_ERROR on failure.
|
||||
// Warning:
|
||||
// A failed af_reinit() leaves the audio chain behind in a useless, broken
|
||||
@@ -522,9 +499,6 @@ static void reset_formats(struct af_stream *s)
|
||||
static int af_reinit(struct af_stream *s)
|
||||
{
|
||||
remove_auto_inserted_filters(s);
|
||||
af_chain_forget_frames(s);
|
||||
reset_formats(s);
|
||||
s->first->fmt_in = s->first->fmt_out = s->input;
|
||||
// Start with the second filter, as the first filter is the special input
|
||||
// filter which needs no initialization.
|
||||
struct af_instance *af = s->first->next;
|
||||
@@ -543,7 +517,6 @@ static int af_reinit(struct af_stream *s)
|
||||
if (!mp_audio_config_valid(&in))
|
||||
goto error;
|
||||
|
||||
af->fmt_in = in;
|
||||
int rv = af->control(af, AF_CONTROL_REINIT, &in);
|
||||
if (rv == AF_OK && !mp_audio_config_equals(&in, af->prev->data))
|
||||
rv = AF_FALSE; // conversion filter needed
|
||||
@@ -551,7 +524,6 @@ static int af_reinit(struct af_stream *s)
|
||||
case AF_OK:
|
||||
if (!mp_audio_config_valid(af->data))
|
||||
goto error;
|
||||
af->fmt_out = *af->data;
|
||||
af = af->next;
|
||||
break;
|
||||
case AF_FALSE: { // Configuration filter is needed
|
||||
@@ -570,23 +542,6 @@ static int af_reinit(struct af_stream *s)
|
||||
retry++;
|
||||
continue;
|
||||
}
|
||||
// If the format conversion is (probably) caused by spdif, then
|
||||
// (as a feature) drop the filter, instead of failing hard.
|
||||
int fmt_in1 = af->prev->data->format;
|
||||
int fmt_in2 = in.format;
|
||||
if (af_fmt_is_valid(fmt_in1) && af_fmt_is_valid(fmt_in2)) {
|
||||
bool spd1 = AF_FORMAT_IS_IEC61937(fmt_in1);
|
||||
bool spd2 = AF_FORMAT_IS_IEC61937(fmt_in2);
|
||||
if (spd1 != spd2 && af->next) {
|
||||
MP_WARN(af, "Filter %s apparently cannot be used due to "
|
||||
"spdif passthrough - removing it.\n",
|
||||
af->info->name);
|
||||
struct af_instance *aft = af->prev;
|
||||
af_remove(s, af);
|
||||
af = aft->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
goto negotiate_error;
|
||||
}
|
||||
case AF_DETACH: { // Filter is redundant and wants to be unloaded
|
||||
@@ -629,40 +584,36 @@ void af_uninit(struct af_stream *s)
|
||||
{
|
||||
while (s->first->next && s->first->next != s->last)
|
||||
af_remove(s, s->first->next);
|
||||
af_chain_forget_frames(s);
|
||||
s->initialized = 0;
|
||||
}
|
||||
|
||||
struct af_stream *af_new(struct mpv_global *global)
|
||||
{
|
||||
struct af_stream *s = talloc_zero(NULL, struct af_stream);
|
||||
s->log = mp_log_new(s, global->log, "!af");
|
||||
|
||||
static const struct af_info in = { .name = "in" };
|
||||
s->first = talloc(s, struct af_instance);
|
||||
*s->first = (struct af_instance) {
|
||||
.info = &in,
|
||||
.log = s->log,
|
||||
.control = input_control,
|
||||
.filter_frame = dummy_filter,
|
||||
.filter = dummy_filter,
|
||||
.priv = s,
|
||||
.data = &s->input,
|
||||
.mul = 1.0,
|
||||
};
|
||||
|
||||
static const struct af_info out = { .name = "out" };
|
||||
s->last = talloc(s, struct af_instance);
|
||||
*s->last = (struct af_instance) {
|
||||
.info = &out,
|
||||
.log = s->log,
|
||||
.control = output_control,
|
||||
.filter_frame = dummy_filter,
|
||||
.filter = dummy_filter,
|
||||
.priv = s,
|
||||
.data = &s->filter_output,
|
||||
.mul = 1.0,
|
||||
};
|
||||
|
||||
s->first->next = s->last;
|
||||
s->last->prev = s->first;
|
||||
s->opts = global->opts;
|
||||
s->log = mp_log_new(s, global->log, "!af");
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -715,14 +666,8 @@ int af_init(struct af_stream *s)
|
||||
to the stream s. The filter will be inserted somewhere nice in the
|
||||
list of filters. The return value is a pointer to the new filter,
|
||||
If the filter couldn't be added the return value is NULL. */
|
||||
struct af_instance *af_add(struct af_stream *s, char *name, char *label,
|
||||
char **args)
|
||||
struct af_instance *af_add(struct af_stream *s, char *name, char **args)
|
||||
{
|
||||
assert(label);
|
||||
|
||||
if (af_find_by_label(s, label))
|
||||
return NULL;
|
||||
|
||||
struct af_instance *new;
|
||||
// Insert the filter somewhere nice
|
||||
if (af_is_conversion_filter(s->first->next))
|
||||
@@ -731,14 +676,17 @@ struct af_instance *af_add(struct af_stream *s, char *name, char *label,
|
||||
new = af_prepend(s, s->first->next, name, args);
|
||||
if (!new)
|
||||
return NULL;
|
||||
new->label = talloc_strdup(new, label);
|
||||
|
||||
// Reinitalize the filter list
|
||||
if (af_reinit(s) != AF_OK) {
|
||||
af_remove_by_label(s, label);
|
||||
af_remove(s, new);
|
||||
if (af_reinit(s) != AF_OK) {
|
||||
af_uninit(s);
|
||||
af_init(s);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
return af_find_by_label(s, label);
|
||||
return new;
|
||||
}
|
||||
|
||||
struct af_instance *af_find_by_label(struct af_stream *s, char *label)
|
||||
@@ -767,6 +715,65 @@ int af_remove_by_label(struct af_stream *s, char *label)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Feed "data" to the chain, and write results to output. "data" needs to be
|
||||
* a refcounted frame, although refcounting is not used yet.
|
||||
* data==NULL means EOF.
|
||||
*/
|
||||
int af_filter(struct af_stream *s, struct mp_audio *data,
|
||||
struct mp_audio_buffer *output)
|
||||
{
|
||||
struct af_instance *af = s->first;
|
||||
assert(s->initialized > 0);
|
||||
int flags = 0;
|
||||
int r = 0;
|
||||
struct mp_audio tmp;
|
||||
char dummy[MP_NUM_CHANNELS];
|
||||
if (data) {
|
||||
assert(mp_audio_config_equals(af->data, data));
|
||||
r = mp_audio_make_writeable(data);
|
||||
} else {
|
||||
data = &tmp;
|
||||
*data = *(af->data);
|
||||
mp_audio_set_null_data(data);
|
||||
flags = AF_FILTER_FLAG_EOF;
|
||||
for (int n = 0; n < MP_NUM_CHANNELS; n++)
|
||||
data->planes[n] = &dummy[n];
|
||||
}
|
||||
if (r < 0)
|
||||
goto done;
|
||||
struct mp_audio frame = *data;
|
||||
for (int n = 0; n < MP_NUM_CHANNELS; n++)
|
||||
frame.allocated[n] = NULL;
|
||||
// Iterate through all filters
|
||||
while (af) {
|
||||
r = af->filter(af, &frame, flags);
|
||||
if (r < 0)
|
||||
goto done;
|
||||
assert(mp_audio_config_equals(af->data, &frame));
|
||||
af = af->next;
|
||||
}
|
||||
mp_audio_buffer_append(output, &frame);
|
||||
|
||||
done:
|
||||
if (data != &tmp)
|
||||
talloc_free(data);
|
||||
return r;
|
||||
}
|
||||
|
||||
// Calculate average ratio of filter output samples to input samples.
|
||||
// e.g: num_output_samples = mul * num_input_samples
|
||||
double af_calc_filter_multiplier(struct af_stream *s)
|
||||
{
|
||||
struct af_instance *af = s->first;
|
||||
double mul = 1;
|
||||
do {
|
||||
mul *= af->mul;
|
||||
af = af->next;
|
||||
} while (af);
|
||||
|
||||
return mul;
|
||||
}
|
||||
|
||||
/* Calculate the total delay [seconds of output] caused by the filters */
|
||||
double af_calc_delay(struct af_stream *s)
|
||||
{
|
||||
@@ -774,8 +781,6 @@ double af_calc_delay(struct af_stream *s)
|
||||
double delay = 0.0;
|
||||
while (af) {
|
||||
delay += af->delay;
|
||||
for (int n = 0; n < af->num_out_queued; n++)
|
||||
delay += af->out_queued[n]->samples / (double)af->data->rate;
|
||||
af = af->next;
|
||||
}
|
||||
return delay;
|
||||
@@ -802,108 +807,3 @@ void af_control_all(struct af_stream *s, int cmd, void *arg)
|
||||
for (struct af_instance *af = s->first; af; af = af->next)
|
||||
af->control(af, cmd, arg);
|
||||
}
|
||||
|
||||
// Used by filters to add a filtered frame to the output queue.
|
||||
// Ownership of frame is transferred from caller to the filter chain.
|
||||
void af_add_output_frame(struct af_instance *af, struct mp_audio *frame)
|
||||
{
|
||||
if (frame) {
|
||||
assert(mp_audio_config_equals(&af->fmt_out, frame));
|
||||
MP_TARRAY_APPEND(af, af->out_queued, af->num_out_queued, frame);
|
||||
}
|
||||
}
|
||||
|
||||
static bool af_has_output_frame(struct af_instance *af)
|
||||
{
|
||||
if (!af->num_out_queued && af->filter_out) {
|
||||
if (af->filter_out(af) < 0)
|
||||
MP_ERR(af, "Error filtering frame.\n");
|
||||
}
|
||||
return af->num_out_queued > 0;
|
||||
}
|
||||
|
||||
static struct mp_audio *af_dequeue_output_frame(struct af_instance *af)
|
||||
{
|
||||
struct mp_audio *res = NULL;
|
||||
if (af_has_output_frame(af)) {
|
||||
res = af->out_queued[0];
|
||||
MP_TARRAY_REMOVE_AT(af->out_queued, af->num_out_queued, 0);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static int af_do_filter(struct af_instance *af, struct mp_audio *frame)
|
||||
{
|
||||
if (frame)
|
||||
assert(mp_audio_config_equals(&af->fmt_in, frame));
|
||||
int r = af->filter_frame(af, frame);
|
||||
if (r < 0)
|
||||
MP_ERR(af, "Error filtering frame.\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
// Input a frame into the filter chain. Ownership of frame is transferred.
|
||||
// Return >= 0 on success, < 0 on failure (even if output frames were produced)
|
||||
int af_filter_frame(struct af_stream *s, struct mp_audio *frame)
|
||||
{
|
||||
assert(frame);
|
||||
if (s->initialized < 1) {
|
||||
talloc_free(frame);
|
||||
return -1;
|
||||
}
|
||||
return af_do_filter(s->first, frame);
|
||||
}
|
||||
|
||||
// Output the next queued frame (if any) from the full filter chain.
|
||||
// The frame can be retrieved with af_read_output_frame().
|
||||
// eof: if set, assume there's no more input i.e. af_filter_frame() will
|
||||
// not be called (until reset) - flush all internally delayed frames
|
||||
// returns: -1: error, 0: no output, 1: output available
|
||||
int af_output_frame(struct af_stream *s, bool eof)
|
||||
{
|
||||
if (s->last->num_out_queued)
|
||||
return 1;
|
||||
if (s->initialized < 1)
|
||||
return -1;
|
||||
while (1) {
|
||||
struct af_instance *last = NULL;
|
||||
for (struct af_instance * cur = s->first; cur; cur = cur->next) {
|
||||
// Flush remaining frames on EOF, but do that only if the previous
|
||||
// filters have been flushed (i.e. they have no more output).
|
||||
if (eof && !last) {
|
||||
int r = af_do_filter(cur, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
if (af_has_output_frame(cur))
|
||||
last = cur;
|
||||
}
|
||||
if (!last)
|
||||
return 0;
|
||||
if (!last->next)
|
||||
return 1;
|
||||
int r = af_do_filter(last->next, af_dequeue_output_frame(last));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
struct mp_audio *af_read_output_frame(struct af_stream *s)
|
||||
{
|
||||
if (!s->last->num_out_queued)
|
||||
af_output_frame(s, false);
|
||||
return af_dequeue_output_frame(s->last);
|
||||
}
|
||||
|
||||
// Make sure the caller can change data referenced by the frame.
|
||||
// Return negative error code on failure (i.e. you can't write).
|
||||
int af_make_writeable(struct af_instance *af, struct mp_audio *frame)
|
||||
{
|
||||
return mp_audio_pool_make_writeable(af->out_pool, frame);
|
||||
}
|
||||
|
||||
void af_seek_reset(struct af_stream *s)
|
||||
{
|
||||
af_control_all(s, AF_CONTROL_RESET, NULL);
|
||||
af_chain_forget_frames(s);
|
||||
}
|
||||
+18
-27
@@ -1,18 +1,19 @@
|
||||
/*
|
||||
* This file is part of mpv.
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MPLAYER_AF_H
|
||||
@@ -61,29 +62,21 @@ struct af_instance {
|
||||
struct replaygain_data *replaygain_data;
|
||||
int (*control)(struct af_instance *af, int cmd, void *arg);
|
||||
void (*uninit)(struct af_instance *af);
|
||||
/* Feed a frame. The frame is NULL if EOF was reached, and the filter
|
||||
* should drain all remaining buffered data.
|
||||
* Use af_add_output_frame() to output data. The optional filter_out
|
||||
* callback can be set to produce output frames gradually.
|
||||
/* flags is a bit mask of AF_FILTER_FLAG_* values
|
||||
* returns 0 on success, negative value on error
|
||||
*/
|
||||
int (*filter_frame)(struct af_instance *af, struct mp_audio *frame);
|
||||
int (*filter_out)(struct af_instance *af);
|
||||
int (*filter)(struct af_instance *af, struct mp_audio *data, int flags);
|
||||
void *priv;
|
||||
struct mp_audio *data; // configuration and buffer for outgoing data stream
|
||||
|
||||
struct af_instance *next;
|
||||
struct af_instance *prev;
|
||||
double delay; /* Delay caused by the filter, in seconds of audio consumed
|
||||
* without corresponding output */
|
||||
double mul; /* length multiplier: how much does this instance change
|
||||
* the number of samples passed though. (Ratio of input
|
||||
* and output, e.g. mul=4 => 1 sample becomes 4 samples) .*/
|
||||
bool auto_inserted; // inserted by af.c, such as conversion filters
|
||||
char *label;
|
||||
|
||||
struct mp_audio fmt_in, fmt_out;
|
||||
|
||||
struct mp_audio **out_queued;
|
||||
int num_out_queued;
|
||||
|
||||
struct mp_audio_pool *out_pool;
|
||||
};
|
||||
|
||||
// Current audio stream
|
||||
@@ -140,26 +133,24 @@ struct af_stream *af_new(struct mpv_global *global);
|
||||
void af_destroy(struct af_stream *s);
|
||||
int af_init(struct af_stream *s);
|
||||
void af_uninit(struct af_stream *s);
|
||||
struct af_instance *af_add(struct af_stream *s, char *name, char *label,
|
||||
char **args);
|
||||
struct af_instance *af_add(struct af_stream *s, char *name, char **args);
|
||||
int af_remove_by_label(struct af_stream *s, char *label);
|
||||
struct af_instance *af_find_by_label(struct af_stream *s, char *label);
|
||||
struct mp_audio_buffer;
|
||||
int af_filter(struct af_stream *s, struct mp_audio *data,
|
||||
struct mp_audio_buffer *output);
|
||||
struct af_instance *af_control_any_rev(struct af_stream *s, int cmd, void *arg);
|
||||
void af_control_all(struct af_stream *s, int cmd, void *arg);
|
||||
void af_seek_reset(struct af_stream *s);
|
||||
|
||||
void af_add_output_frame(struct af_instance *af, struct mp_audio *frame);
|
||||
int af_filter_frame(struct af_stream *s, struct mp_audio *frame);
|
||||
int af_output_frame(struct af_stream *s, bool eof);
|
||||
struct mp_audio *af_read_output_frame(struct af_stream *s);
|
||||
int af_make_writeable(struct af_instance *af, struct mp_audio *frame);
|
||||
|
||||
double af_calc_filter_multiplier(struct af_stream *s);
|
||||
double af_calc_delay(struct af_stream *s);
|
||||
|
||||
int af_test_output(struct af_instance *af, struct mp_audio *out);
|
||||
|
||||
int af_from_dB(int n, float *in, float *out, float k, float mi, float ma);
|
||||
int af_to_dB(int n, float *in, float *out, float k);
|
||||
int af_from_ms(int n, float *in, int *out, int rate, float mi, float ma);
|
||||
int af_to_ms(int n, int *in, float *out, int rate);
|
||||
float af_softclip(float a);
|
||||
|
||||
#endif /* MPLAYER_AF_H */
|
||||
+52
-47
@@ -4,20 +4,21 @@
|
||||
*
|
||||
* Copyright (c) 2009 Andrew Savchenko
|
||||
*
|
||||
* This file is part of mpv.
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <bs2b.h>
|
||||
@@ -36,49 +37,26 @@ struct af_bs2b {
|
||||
t_bs2bdp filter; ///< instance of a library filter
|
||||
};
|
||||
|
||||
#define DEF_FILTER(fmt, name) \
|
||||
static int filter_##name(struct af_instance *af, struct mp_audio *data) \
|
||||
#define FILTER(name, type) \
|
||||
static int filter_##name(struct af_instance *af, struct mp_audio *data, int f) \
|
||||
{ \
|
||||
if (!data) \
|
||||
return 0; \
|
||||
if (af_make_writeable(af, data) < 0) { \
|
||||
talloc_free(data); \
|
||||
return -1; \
|
||||
} \
|
||||
/* filter is called for all pairs of samples available in the buffer */ \
|
||||
bs2b_cross_feed_##name(((struct af_bs2b*)(af->priv))->filter, \
|
||||
(data->planes[0]), data->samples); \
|
||||
af_add_output_frame(af, data); \
|
||||
(type*)(data->planes[0]), data->samples); \
|
||||
\
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#define GET_FILTER(fmt, name) \
|
||||
case AF_FORMAT_##fmt: return filter_##name;
|
||||
FILTER(f, float)
|
||||
FILTER(s32, int32_t)
|
||||
FILTER(u32, uint32_t)
|
||||
FILTER(s24, bs2b_int24_t)
|
||||
FILTER(u24, bs2b_uint24_t)
|
||||
FILTER(s16, int16_t)
|
||||
FILTER(u16, uint16_t)
|
||||
FILTER(s8, int8_t)
|
||||
FILTER(u8, uint8_t)
|
||||
|
||||
#define FILTERS \
|
||||
FILTER(FLOAT, f) \
|
||||
FILTER(S32, s32) \
|
||||
FILTER(U32, u32) \
|
||||
FILTER(S24, s24) \
|
||||
FILTER(U24, u24) \
|
||||
FILTER(S16, s16) \
|
||||
FILTER(U16, u16) \
|
||||
FILTER(S8, s8) \
|
||||
FILTER(U8, u8)
|
||||
|
||||
#define FILTER DEF_FILTER
|
||||
FILTERS
|
||||
#undef FILTER
|
||||
|
||||
typedef int (*filter)(struct af_instance *af, struct mp_audio *d);
|
||||
static filter get_filter(int fmt)
|
||||
{
|
||||
switch (fmt) {
|
||||
#define FILTER GET_FILTER
|
||||
FILTERS
|
||||
#undef FILTER
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialization and runtime control
|
||||
static int control(struct af_instance *af, int cmd, void *arg)
|
||||
@@ -98,10 +76,38 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
|
||||
/* check for formats supported by libbs2b
|
||||
and assign corresponding handlers */
|
||||
af->filter_frame = get_filter(format);
|
||||
if (!af->filter_frame) {
|
||||
af->filter_frame = filter_f;
|
||||
mp_audio_set_format(af->data, AF_FORMAT_FLOAT);
|
||||
switch (format) {
|
||||
case AF_FORMAT_FLOAT:
|
||||
af->filter = filter_f;
|
||||
break;
|
||||
case AF_FORMAT_S32:
|
||||
af->filter = filter_s32;
|
||||
break;
|
||||
case AF_FORMAT_U32:
|
||||
af->filter = filter_u32;
|
||||
break;
|
||||
case AF_FORMAT_S24:
|
||||
af->filter = filter_s24;
|
||||
break;
|
||||
case AF_FORMAT_U24:
|
||||
af->filter = filter_u24;
|
||||
break;
|
||||
case AF_FORMAT_S16:
|
||||
af->filter = filter_s16;
|
||||
break;
|
||||
case AF_FORMAT_U16:
|
||||
af->filter = filter_u16;
|
||||
break;
|
||||
case AF_FORMAT_S8:
|
||||
af->filter = filter_s8;
|
||||
break;
|
||||
case AF_FORMAT_U8:
|
||||
af->filter = filter_u8;
|
||||
break;
|
||||
default:
|
||||
af->filter = filter_f;
|
||||
mp_audio_set_format(af->data, AF_FORMAT_FLOAT);
|
||||
break;
|
||||
}
|
||||
|
||||
// bs2b have srate limits, try to resample if needed
|
||||
@@ -163,8 +169,7 @@ const struct af_info af_info_bs2b = {
|
||||
OPT_INTRANGE("fcut", fcut, 0, BS2B_MINFCUT, BS2B_MAXFCUT),
|
||||
OPT_INTRANGE("feed", feed, 0, BS2B_MINFEED, BS2B_MAXFEED),
|
||||
OPT_CHOICE("profile", profile, 0,
|
||||
({"unset", 0},
|
||||
{"default", BS2B_DEFAULT_CLEVEL},
|
||||
({"default", BS2B_DEFAULT_CLEVEL},
|
||||
{"cmoy", BS2B_CMOY_CLEVEL},
|
||||
{"jmeier", BS2B_JMEIER_CLEVEL})),
|
||||
{0}
|
||||
|
||||
@@ -8,20 +8,21 @@
|
||||
*
|
||||
* copyright (c) 2005 Alex Beregszaszi
|
||||
*
|
||||
* This file is part of mpv.
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -57,14 +58,9 @@ static int control(struct af_instance* af, int cmd, void* arg)
|
||||
return AF_UNKNOWN;
|
||||
}
|
||||
|
||||
static int filter_frame(struct af_instance* af, struct mp_audio* data)
|
||||
// Filter data through filter
|
||||
static int filter(struct af_instance* af, struct mp_audio* data, int flags)
|
||||
{
|
||||
if (!data)
|
||||
return 0;
|
||||
if (af_make_writeable(af, data) < 0) {
|
||||
talloc_free(data);
|
||||
return -1;
|
||||
}
|
||||
struct mp_audio* c = data; // Current working data
|
||||
af_center_t* s = af->priv; // Setup for this instance
|
||||
float* a = c->planes[0]; // Audio data
|
||||
@@ -79,14 +75,13 @@ static int filter_frame(struct af_instance* af, struct mp_audio* data)
|
||||
a[i+ch] = (a[i]/2) + (a[i+1]/2);
|
||||
}
|
||||
|
||||
af_add_output_frame(af, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Allocate memory and set function pointers
|
||||
static int af_open(struct af_instance* af){
|
||||
af->control=control;
|
||||
af->filter_frame = filter_frame;
|
||||
af->filter=filter;
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
|
||||
+15
-17
@@ -5,20 +5,21 @@
|
||||
*
|
||||
* Original author: Anders
|
||||
*
|
||||
* This file is part of mpv.
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -180,20 +181,15 @@ static int control(struct af_instance* af, int cmd, void* arg)
|
||||
return AF_UNKNOWN;
|
||||
}
|
||||
|
||||
static int filter_frame(struct af_instance *af, struct mp_audio *c)
|
||||
// Filter data through filter
|
||||
static int filter(struct af_instance* af, struct mp_audio* data, int flags)
|
||||
{
|
||||
struct mp_audio* c = data; // Current working data
|
||||
struct mp_audio* l = af->data; // Local data
|
||||
af_channels_t* s = af->priv;
|
||||
int i;
|
||||
|
||||
if (!c)
|
||||
return 0;
|
||||
|
||||
struct mp_audio *l = mp_audio_pool_get(af->out_pool, &af->fmt_out, c->samples);
|
||||
if (!l) {
|
||||
talloc_free(c);
|
||||
return -1;
|
||||
}
|
||||
mp_audio_copy_attributes(l, c);
|
||||
mp_audio_realloc_min(af->data, data->samples);
|
||||
|
||||
// Reset unused channels
|
||||
memset(l->planes[0],0,mp_audio_psize(c) / c->nch * l->nch);
|
||||
@@ -203,15 +199,17 @@ static int filter_frame(struct af_instance *af, struct mp_audio *c)
|
||||
copy(af, c->planes[0],l->planes[0],c->nch,s->route[i][FR],
|
||||
l->nch,s->route[i][TO],mp_audio_psize(c),c->bps);
|
||||
|
||||
talloc_free(c);
|
||||
af_add_output_frame(af, l);
|
||||
// Set output data
|
||||
c->planes[0] = l->planes[0];
|
||||
mp_audio_set_channels(c, &l->channels);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Allocate memory and set function pointers
|
||||
static int af_open(struct af_instance* af){
|
||||
af->control=control;
|
||||
af->filter_frame = filter_frame;
|
||||
af->filter=filter;
|
||||
af_channels_t *s = af->priv;
|
||||
|
||||
// If router scan commandline for routing pairs
|
||||
|
||||
@@ -71,19 +71,13 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
#define SHIFT(x) (((x)+1)*8)
|
||||
#endif
|
||||
|
||||
static int filter(struct af_instance *af, struct mp_audio *data)
|
||||
static int filter(struct af_instance *af, struct mp_audio *data, int flags)
|
||||
{
|
||||
if (!data)
|
||||
return 0;
|
||||
struct mp_audio *out =
|
||||
mp_audio_pool_get(af->out_pool, af->data, data->samples);
|
||||
if (!out) {
|
||||
talloc_free(data);
|
||||
return -1;
|
||||
}
|
||||
mp_audio_copy_attributes(out, data);
|
||||
mp_audio_realloc_min(af->data, data->samples);
|
||||
|
||||
struct mp_audio *out = af->data;
|
||||
size_t len = mp_audio_psize(data) / data->bps;
|
||||
|
||||
if (data->bps == 4) {
|
||||
for (int s = 0; s < len; s++) {
|
||||
uint32_t val = *((uint32_t *)data->planes[0] + s);
|
||||
@@ -92,6 +86,7 @@ static int filter(struct af_instance *af, struct mp_audio *data)
|
||||
ptr[1] = val >> SHIFT(1);
|
||||
ptr[2] = val >> SHIFT(2);
|
||||
}
|
||||
mp_audio_set_format(data, af_fmt_change_bits(data->format, 24));
|
||||
} else {
|
||||
for (int s = 0; s < len; s++) {
|
||||
uint8_t *ptr = (uint8_t *)data->planes[0] + s * 3;
|
||||
@@ -100,17 +95,17 @@ static int filter(struct af_instance *af, struct mp_audio *data)
|
||||
| ptr[2] << SHIFT(2);
|
||||
*((uint32_t *)out->planes[0] + s) = val;
|
||||
}
|
||||
mp_audio_set_format(data, af_fmt_change_bits(data->format, 32));
|
||||
}
|
||||
|
||||
talloc_free(data);
|
||||
af_add_output_frame(af, out);
|
||||
data->planes[0] = out->planes[0];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int af_open(struct af_instance *af)
|
||||
{
|
||||
af->control = control;
|
||||
af->filter_frame = filter;
|
||||
af->filter = filter;
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -71,15 +71,8 @@ static void si2us(void *data, int len, int bps)
|
||||
} while (i += bps);
|
||||
}
|
||||
|
||||
static int filter(struct af_instance *af, struct mp_audio *data)
|
||||
static int filter(struct af_instance *af, struct mp_audio *data, int flags)
|
||||
{
|
||||
if (!data)
|
||||
return 0;
|
||||
if (af_make_writeable(af, data) < 0) {
|
||||
talloc_free(data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int infmt = data->format;
|
||||
int outfmt = af->data->format;
|
||||
size_t len = data->samples * data->nch;
|
||||
@@ -88,14 +81,13 @@ static int filter(struct af_instance *af, struct mp_audio *data)
|
||||
si2us(data->planes[0], len, data->bps);
|
||||
|
||||
mp_audio_set_format(data, outfmt);
|
||||
af_add_output_frame(af, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int af_open(struct af_instance *af)
|
||||
{
|
||||
af->control = control;
|
||||
af->filter_frame = filter;
|
||||
af->filter = filter;
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
|
||||
+9
-13
@@ -5,20 +5,21 @@
|
||||
*
|
||||
* Original author: Anders
|
||||
*
|
||||
* This file is part of mpv.
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -95,19 +96,15 @@ static void uninit(struct af_instance* af)
|
||||
free(((af_delay_t*)(af->priv))->q[i]);
|
||||
}
|
||||
|
||||
static int filter_frame(struct af_instance *af, struct mp_audio *c)
|
||||
// Filter data through filter
|
||||
static int filter(struct af_instance* af, struct mp_audio* data, int flags)
|
||||
{
|
||||
if (!c)
|
||||
return 0;
|
||||
struct mp_audio* c = data; // Current working data
|
||||
af_delay_t* s = af->priv; // Setup for this instance
|
||||
int nch = c->nch; // Number of channels
|
||||
int len = mp_audio_psize(c)/c->bps; // Number of sample in data chunk
|
||||
int ri = 0;
|
||||
int ch,i;
|
||||
if (af_make_writeable(af, c) < 0) {
|
||||
talloc_free(c);
|
||||
return -1;
|
||||
}
|
||||
for(ch=0;ch<nch;ch++){
|
||||
switch(c->bps){
|
||||
case 1:{
|
||||
@@ -155,7 +152,6 @@ static int filter_frame(struct af_instance *af, struct mp_audio *c)
|
||||
}
|
||||
}
|
||||
s->ri = ri;
|
||||
af_add_output_frame(af, c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -163,7 +159,7 @@ static int filter_frame(struct af_instance *af, struct mp_audio *c)
|
||||
static int af_open(struct af_instance* af){
|
||||
af->control=control;
|
||||
af->uninit=uninit;
|
||||
af->filter_frame = filter_frame;
|
||||
af->filter=filter;
|
||||
af_delay_t *s = af->priv;
|
||||
int n = 1;
|
||||
int i = 0;
|
||||
|
||||
+7
-15
@@ -1,20 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) 2004 Alex Beregszaszi & Pierre Lombard
|
||||
*
|
||||
* This file is part of mpv.
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -271,18 +272,10 @@ static void method2_float(af_drc_t *s, struct mp_audio *c)
|
||||
s->idx = (s->idx + 1) % NSAMPLES;
|
||||
}
|
||||
|
||||
static int filter(struct af_instance *af, struct mp_audio *data)
|
||||
static int filter(struct af_instance* af, struct mp_audio* data, int flags)
|
||||
{
|
||||
af_drc_t *s = af->priv;
|
||||
|
||||
if (!data)
|
||||
return 0;
|
||||
|
||||
if (af_make_writeable(af, data) < 0) {
|
||||
talloc_free(data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(af->data->format == (AF_FORMAT_S16))
|
||||
{
|
||||
if (s->method == 2)
|
||||
@@ -297,7 +290,6 @@ static int filter(struct af_instance *af, struct mp_audio *data)
|
||||
else
|
||||
method1_float(s, data);
|
||||
}
|
||||
af_add_output_frame(af, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -305,7 +297,7 @@ static int filter(struct af_instance *af, struct mp_audio *data)
|
||||
static int af_open(struct af_instance* af){
|
||||
int i = 0;
|
||||
af->control=control;
|
||||
af->filter_frame = filter;
|
||||
af->filter=filter;
|
||||
af_drc_t *priv = af->priv;
|
||||
|
||||
priv->mul = MUL_INIT;
|
||||
|
||||
@@ -4,20 +4,21 @@
|
||||
*
|
||||
* Original author: Anders
|
||||
*
|
||||
* This file is part of mpv.
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -40,16 +41,15 @@ static int control(struct af_instance* af, int cmd, void* arg)
|
||||
}
|
||||
|
||||
// Filter data through filter
|
||||
static int filter(struct af_instance* af, struct mp_audio* data)
|
||||
static int filter(struct af_instance* af, struct mp_audio* data, int flags)
|
||||
{
|
||||
af_add_output_frame(af, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Allocate memory and set function pointers
|
||||
static int af_open(struct af_instance* af){
|
||||
af->control=control;
|
||||
af->filter_frame=filter;
|
||||
af->filter=filter;
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,20 +6,21 @@
|
||||
*
|
||||
* Copyright (C) 2001 Anders Johansson ajh@atri.curtin.edu.au
|
||||
*
|
||||
* This file is part of mpv.
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -140,20 +141,14 @@ static int control(struct af_instance* af, int cmd, void* arg)
|
||||
return AF_UNKNOWN;
|
||||
}
|
||||
|
||||
static int filter(struct af_instance* af, struct mp_audio* data)
|
||||
// Filter data through filter
|
||||
static int filter(struct af_instance* af, struct mp_audio* data, int flags)
|
||||
{
|
||||
struct mp_audio* c = data; // Current working data
|
||||
if (!c)
|
||||
return 0;
|
||||
af_equalizer_t* s = (af_equalizer_t*)af->priv; // Setup
|
||||
uint32_t ci = af->data->nch; // Index for channels
|
||||
uint32_t nch = af->data->nch; // Number of channels
|
||||
|
||||
if (af_make_writeable(af, data) < 0) {
|
||||
talloc_free(data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while(ci--){
|
||||
float* g = s->g[ci]; // Gain factor
|
||||
float* in = ((float*)c->planes[0])+ci;
|
||||
@@ -182,14 +177,13 @@ static int filter(struct af_instance* af, struct mp_audio* data)
|
||||
out+=nch;
|
||||
}
|
||||
}
|
||||
af_add_output_frame(af, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Allocate memory and set function pointers
|
||||
static int af_open(struct af_instance* af){
|
||||
af->control=control;
|
||||
af->filter_frame = filter;
|
||||
af->filter=filter;
|
||||
af_equalizer_t *priv = af->priv;
|
||||
for(int i=0;i<AF_NCH;i++){
|
||||
for(int j=0;j<KM;j++){
|
||||
|
||||
@@ -9,20 +9,21 @@
|
||||
*
|
||||
* Authors: Anders; Gustavo Sverzut Barbieri <gustavo.barbieri@ic.unicamp.br>
|
||||
*
|
||||
* This file is part of mpv.
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -33,6 +34,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
@@ -161,10 +163,8 @@ static void uninit( struct af_instance* af )
|
||||
af audio filter instance
|
||||
data audio data
|
||||
*/
|
||||
static int filter(struct af_instance *af, struct mp_audio *data)
|
||||
static int filter( struct af_instance* af, struct mp_audio* data, int flags)
|
||||
{
|
||||
if (!data)
|
||||
return 0;
|
||||
struct mp_audio* c = data; // Current working data
|
||||
af_export_t* s = af->priv; // Setup for this instance
|
||||
int16_t* a = c->planes[0]; // Incomming sound
|
||||
@@ -200,7 +200,6 @@ static int filter(struct af_instance *af, struct mp_audio *data)
|
||||
&(s->count), sizeof(s->count));
|
||||
}
|
||||
|
||||
af_add_output_frame(af, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -212,7 +211,7 @@ static int af_open( struct af_instance* af )
|
||||
{
|
||||
af->control = control;
|
||||
af->uninit = uninit;
|
||||
af->filter_frame = filter;
|
||||
af->filter = filter;
|
||||
af_export_t *priv = af->priv;
|
||||
|
||||
if (!priv->filename || !priv->filename[0]) {
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) 2004 Alex Beregszaszi & Pierre Lombard
|
||||
*
|
||||
* This file is part of mpv.
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -34,6 +35,9 @@ typedef struct af_extrastereo_s
|
||||
float mul;
|
||||
}af_extrastereo_t;
|
||||
|
||||
static int play_s16(struct af_instance* af, struct mp_audio* data, int f);
|
||||
static int play_float(struct af_instance* af, struct mp_audio* data, int f);
|
||||
|
||||
// Initialization and runtime control
|
||||
static int control(struct af_instance* af, int cmd, void* arg)
|
||||
{
|
||||
@@ -45,8 +49,14 @@ static int control(struct af_instance* af, int cmd, void* arg)
|
||||
mp_audio_copy_config(af->data, (struct mp_audio*)arg);
|
||||
mp_audio_force_interleaved_format(af->data);
|
||||
mp_audio_set_num_channels(af->data, 2);
|
||||
if (af->data->format != AF_FORMAT_FLOAT)
|
||||
if (af->data->format == AF_FORMAT_FLOAT)
|
||||
{
|
||||
af->filter = play_float;
|
||||
}// else
|
||||
{
|
||||
mp_audio_set_format(af->data, AF_FORMAT_S16);
|
||||
af->filter = play_s16;
|
||||
}
|
||||
|
||||
return af_test_output(af,(struct mp_audio*)arg);
|
||||
}
|
||||
@@ -55,8 +65,9 @@ static int control(struct af_instance* af, int cmd, void* arg)
|
||||
}
|
||||
|
||||
// Filter data through filter
|
||||
static void play_s16(af_extrastereo_t *s, struct mp_audio* data)
|
||||
static int play_s16(struct af_instance* af, struct mp_audio* data, int f)
|
||||
{
|
||||
af_extrastereo_t *s = af->priv;
|
||||
register int i = 0;
|
||||
int16_t *a = (int16_t*)data->planes[0]; // Audio data
|
||||
int len = data->samples*data->nch; // Number of samples
|
||||
@@ -72,10 +83,13 @@ static void play_s16(af_extrastereo_t *s, struct mp_audio* data)
|
||||
a[i] = MPCLAMP(l, SHRT_MIN, SHRT_MAX);
|
||||
a[i + 1] = MPCLAMP(r, SHRT_MIN, SHRT_MAX);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void play_float(af_extrastereo_t *s, struct mp_audio* data)
|
||||
static int play_float(struct af_instance* af, struct mp_audio* data, int f)
|
||||
{
|
||||
af_extrastereo_t *s = af->priv;
|
||||
register int i = 0;
|
||||
float *a = (float*)data->planes[0]; // Audio data
|
||||
int len = data->samples * data->nch; // Number of samples
|
||||
@@ -91,29 +105,14 @@ static void play_float(af_extrastereo_t *s, struct mp_audio* data)
|
||||
a[i] = af_softclip(l);
|
||||
a[i + 1] = af_softclip(r);
|
||||
}
|
||||
}
|
||||
|
||||
static int filter_frame(struct af_instance *af, struct mp_audio *data)
|
||||
{
|
||||
if (!data)
|
||||
return 0;
|
||||
if (af_make_writeable(af, data) < 0) {
|
||||
talloc_free(data);
|
||||
return -1;
|
||||
}
|
||||
if (data->format == AF_FORMAT_FLOAT) {
|
||||
play_float(af->priv, data);
|
||||
} else {
|
||||
play_s16(af->priv, data);
|
||||
}
|
||||
af_add_output_frame(af, data);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Allocate memory and set function pointers
|
||||
static int af_open(struct af_instance* af){
|
||||
af->control=control;
|
||||
af->filter_frame = filter_frame;
|
||||
af->filter=play_s16;
|
||||
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "af.h"
|
||||
|
||||
struct priv {
|
||||
double speed;
|
||||
};
|
||||
|
||||
static int control(struct af_instance *af, int cmd, void *arg)
|
||||
{
|
||||
struct priv *priv = af->priv;
|
||||
|
||||
switch (cmd) {
|
||||
case AF_CONTROL_REINIT: {
|
||||
struct mp_audio *in = arg;
|
||||
struct mp_audio orig_in = *in;
|
||||
struct mp_audio *out = af->data;
|
||||
|
||||
mp_audio_copy_config(out, in);
|
||||
out->rate = in->rate * priv->speed;
|
||||
|
||||
return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE;
|
||||
}
|
||||
case AF_CONTROL_SET_PLAYBACK_SPEED_RESAMPLE: {
|
||||
priv->speed = *(double *)arg;
|
||||
return AF_OK;
|
||||
}
|
||||
}
|
||||
return AF_UNKNOWN;
|
||||
}
|
||||
|
||||
static int filter(struct af_instance *af, struct mp_audio *data, int flags)
|
||||
{
|
||||
mp_audio_copy_config(data, af->data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int af_open(struct af_instance *af)
|
||||
{
|
||||
struct priv *priv = af->priv;
|
||||
af->control = control;
|
||||
af->filter = filter;
|
||||
priv->speed = 1.0;
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
#define OPT_BASE_STRUCT struct priv
|
||||
|
||||
const struct af_info af_info_forcespeed = {
|
||||
.info = "Force audio speed",
|
||||
.name = "forcespeed",
|
||||
.open = af_open,
|
||||
.priv_size = sizeof(struct priv),
|
||||
};
|
||||
@@ -95,18 +95,16 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
return AF_UNKNOWN;
|
||||
}
|
||||
|
||||
static int filter(struct af_instance *af, struct mp_audio *data)
|
||||
static int filter(struct af_instance *af, struct mp_audio *data, int flags)
|
||||
{
|
||||
if (data)
|
||||
mp_audio_copy_config(data, af->data);
|
||||
af_add_output_frame(af, data);
|
||||
mp_audio_copy_config(data, af->data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int af_open(struct af_instance *af)
|
||||
{
|
||||
af->control = control;
|
||||
af->filter_frame = filter;
|
||||
af->filter = filter;
|
||||
|
||||
force_in_params(af, af->data);
|
||||
force_out_params(af, af->data);
|
||||
|
||||
+18
-27
@@ -5,20 +5,21 @@
|
||||
*
|
||||
* Author: ylai
|
||||
*
|
||||
* This file is part of mpv.
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
//#include <stdio.h>
|
||||
@@ -279,13 +280,8 @@ static inline void update_ch(af_hrtf_t *s, short *in, const int k)
|
||||
}
|
||||
|
||||
/* We need to update the bass compensation delay line, too. */
|
||||
// TODO: should this use lf/cf/rf etc. instead?
|
||||
s->ba_l[k] = in[0];
|
||||
s->ba_r[k] = in[1];
|
||||
if (s->decode_mode == HRTF_MIX_51) {
|
||||
s->ba_l[k] += in[4] + in[2];
|
||||
s->ba_r[k] += in[4] + in[3];
|
||||
}
|
||||
s->ba_l[k] = in[0] + in[4] + in[2];
|
||||
s->ba_r[k] = in[4] + in[1] + in[3];
|
||||
}
|
||||
|
||||
static void clear_coeff(af_hrtf_t *s, float *c)
|
||||
@@ -374,26 +370,17 @@ frequencies).
|
||||
2. A bass compensation is introduced to ensure that 0-200 Hz are not
|
||||
damped (without any real 3D acoustical image, however).
|
||||
*/
|
||||
static int filter(struct af_instance *af, struct mp_audio *data)
|
||||
static int filter(struct af_instance *af, struct mp_audio *data, int flags)
|
||||
{
|
||||
af_hrtf_t *s = af->priv;
|
||||
|
||||
if (!data)
|
||||
return 0;
|
||||
struct mp_audio *outframe =
|
||||
mp_audio_pool_get(af->out_pool, &af->fmt_out, data->samples);
|
||||
if (!outframe) {
|
||||
talloc_free(data);
|
||||
return -1;
|
||||
}
|
||||
mp_audio_copy_attributes(outframe, data);
|
||||
|
||||
short *in = data->planes[0]; // Input audio data
|
||||
short *out = outframe->planes[0]; // Output audio data
|
||||
short *out = NULL; // Output audio data
|
||||
short *end = in + data->samples * data->nch; // Loop end
|
||||
float common, left, right, diff, left_b, right_b;
|
||||
const int dblen = s->dlbuflen, hlen = s->hrflen, blen = s->basslen;
|
||||
|
||||
mp_audio_realloc_min(af->data, data->samples);
|
||||
|
||||
if(s->print_flag) {
|
||||
s->print_flag = 0;
|
||||
switch (s->decode_mode) {
|
||||
@@ -420,6 +407,8 @@ static int filter(struct af_instance *af, struct mp_audio *data)
|
||||
"channel\n");
|
||||
}
|
||||
|
||||
out = af->data->planes[0];
|
||||
|
||||
/* MPlayer's 5 channel layout (notation for the variable):
|
||||
*
|
||||
* 0: L (LF), 1: R (RF), 2: Ls (LR), 3: Rs (RR), 4: C (CF), matrix
|
||||
@@ -557,8 +546,10 @@ static int filter(struct af_instance *af, struct mp_audio *data)
|
||||
s->cyc_pos += dblen;
|
||||
}
|
||||
|
||||
talloc_free(data);
|
||||
af_add_output_frame(af, outframe);
|
||||
/* Set output data */
|
||||
data->planes[0] = af->data->planes[0];
|
||||
mp_audio_set_num_channels(data, 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -592,7 +583,7 @@ static int af_open(struct af_instance* af)
|
||||
|
||||
af->control = control;
|
||||
af->uninit = uninit;
|
||||
af->filter_frame = filter;
|
||||
af->filter = filter;
|
||||
|
||||
s = af->priv;
|
||||
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
/*
|
||||
* This file is part of mpv.
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MPLAYER_AF_HRTF_H
|
||||
|
||||
@@ -4,20 +4,21 @@
|
||||
* copyright (c) 2006 Reynaldo H. Verdejo Pinochet
|
||||
* Based on code by Alex Beregszaszi for his 'center' filter.
|
||||
*
|
||||
* This file is part of mpv.
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -40,15 +41,10 @@ static int control(struct af_instance* af, int cmd, void* arg)
|
||||
return AF_UNKNOWN;
|
||||
}
|
||||
|
||||
static int filter_frame(struct af_instance *af, struct mp_audio *c)
|
||||
// Filter data through filter
|
||||
static int play(struct af_instance* af, struct mp_audio* data, int flags)
|
||||
{
|
||||
if (!c)
|
||||
return 0;
|
||||
if (af_make_writeable(af, c) < 0) {
|
||||
talloc_free(c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct mp_audio* c = data; // Current working data
|
||||
float* a = c->planes[0]; // Audio data
|
||||
int nch = c->nch; // Number of channels
|
||||
int len = c->samples*nch; // Number of samples in current audio block
|
||||
@@ -66,14 +62,13 @@ static int filter_frame(struct af_instance *af, struct mp_audio *c)
|
||||
a[i+1]=a[i];
|
||||
}
|
||||
|
||||
af_add_output_frame(af, c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Allocate memory and set function pointers
|
||||
static int af_open(struct af_instance* af){
|
||||
af->control = control;
|
||||
af->filter_frame = filter_frame;
|
||||
af->filter = play;
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,20 +4,21 @@
|
||||
* Written by Ivo van Poorten <ivop@euronet.nl>
|
||||
* Copyright (C) 2004, 2005
|
||||
*
|
||||
* This file is part of mpv.
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@@ -564,10 +565,7 @@ static void uninit(struct af_instance *af) {
|
||||
* \return Either AF_ERROR or AF_OK
|
||||
*/
|
||||
|
||||
static int filter_frame(struct af_instance *af, struct mp_audio *data)
|
||||
{
|
||||
if (!data)
|
||||
return 0;
|
||||
static int filter(struct af_instance *af, struct mp_audio *data, int flags) {
|
||||
af_ladspa_t *setup = af->priv;
|
||||
const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
|
||||
float *audio = (float*)data->planes[0];
|
||||
@@ -576,14 +574,8 @@ static int filter_frame(struct af_instance *af, struct mp_audio *data)
|
||||
int rate = data->rate;
|
||||
int i, p;
|
||||
|
||||
if (setup->status !=AF_OK) {
|
||||
talloc_free(data);
|
||||
if (setup->status !=AF_OK)
|
||||
return -1;
|
||||
}
|
||||
if (af_make_writeable(af, data) < 0) {
|
||||
talloc_free(data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* See if it's the first call. If so, setup inbufs/outbufs, instantiate
|
||||
* plugin, connect ports and activate plugin
|
||||
@@ -729,7 +721,6 @@ static int filter_frame(struct af_instance *af, struct mp_audio *data)
|
||||
|
||||
/* done */
|
||||
|
||||
af_add_output_frame(af, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -746,7 +737,7 @@ static int af_open(struct af_instance *af) {
|
||||
|
||||
af->control=control;
|
||||
af->uninit=uninit;
|
||||
af->filter_frame = filter_frame;
|
||||
af->filter=filter;
|
||||
|
||||
af_ladspa_t *setup = af->priv;
|
||||
|
||||
|
||||
+101
-105
@@ -3,20 +3,21 @@
|
||||
*
|
||||
* Copyright (C) 2007 Ulion <ulion A gmail P com>
|
||||
*
|
||||
* This file is part of mpv.
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -52,8 +53,7 @@ typedef struct af_ac3enc_s {
|
||||
struct AVCodecContext *lavc_actx;
|
||||
AVPacket pkt;
|
||||
int bit_rate;
|
||||
struct mp_audio *input; // frame passed to libavcodec
|
||||
struct mp_audio *pending; // unconsumed input data
|
||||
struct mp_audio_buffer *pending;
|
||||
int in_samples; // samples of input per AC3 frame
|
||||
int out_samples; // upper bound on encoded output per AC3 frame
|
||||
int in_sampleformat;
|
||||
@@ -100,16 +100,12 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
} else {
|
||||
s->out_samples = AC3_MAX_CODED_FRAME_SIZE / af->data->sstride;
|
||||
}
|
||||
af->mul = s->out_samples / (double)s->in_samples;
|
||||
|
||||
mp_audio_copy_config(s->input, in);
|
||||
mp_audio_realloc(s->input, s->in_samples);
|
||||
s->input->samples = 0;
|
||||
mp_audio_buffer_reinit(s->pending, in);
|
||||
|
||||
talloc_free(s->pending);
|
||||
s->pending = NULL;
|
||||
|
||||
MP_DBG(af, "af_lavcac3enc reinit: %d, %d, %d.\n",
|
||||
in->nch, in->rate, s->in_samples);
|
||||
MP_DBG(af, "af_lavcac3enc reinit: %d, %d, %f, %d.\n",
|
||||
in->nch, in->rate, af->mul, s->in_samples);
|
||||
|
||||
int bit_rate = s->bit_rate ? s->bit_rate : default_bit_rate[in->nch];
|
||||
|
||||
@@ -152,110 +148,111 @@ static void uninit(struct af_instance* af)
|
||||
avcodec_close(s->lavc_actx);
|
||||
av_free(s->lavc_actx);
|
||||
}
|
||||
talloc_free(s->pending);
|
||||
}
|
||||
}
|
||||
|
||||
static int filter_frame(struct af_instance *af, struct mp_audio *audio)
|
||||
{
|
||||
af_ac3enc_t *s = af->priv;
|
||||
|
||||
// filter_output must have been called until no output was produced.
|
||||
if (s->pending && s->pending->samples)
|
||||
MP_ERR(af, "broken data flow\n");
|
||||
|
||||
talloc_free(s->pending);
|
||||
s->pending = audio;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void swap_16(uint16_t *ptr, size_t size)
|
||||
{
|
||||
for (size_t n = 0; n < size; n++)
|
||||
ptr[n] = av_bswap16(ptr[n]);
|
||||
}
|
||||
|
||||
// Copy data from input frame to encode frame (because libavcodec wants a full
|
||||
// AC3 frame for encoding, while filter input frames can be smaller or larger).
|
||||
// Return true if the
|
||||
static bool fill_buffer(af_ac3enc_t *s)
|
||||
{
|
||||
if (s->pending) {
|
||||
int copy = MPMIN(s->in_samples - s->input->samples, s->pending->samples);
|
||||
s->input->samples += copy;
|
||||
mp_audio_copy(s->input, s->input->samples - copy, s->pending, 0, copy);
|
||||
mp_audio_skip_samples(s->pending, copy);
|
||||
}
|
||||
return s->input->samples >= s->in_samples;
|
||||
}
|
||||
|
||||
static int filter_out(struct af_instance *af)
|
||||
// Filter data through filter
|
||||
static int filter(struct af_instance* af, struct mp_audio* audio, int flags)
|
||||
{
|
||||
struct mp_audio *out = af->data;
|
||||
af_ac3enc_t *s = af->priv;
|
||||
if (!fill_buffer(s))
|
||||
return 0; // need more input
|
||||
int num_frames = (audio->samples + mp_audio_buffer_samples(s->pending))
|
||||
/ s->in_samples;
|
||||
|
||||
AVFrame *frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
MP_FATAL(af, "Could not allocate memory \n");
|
||||
return -1;
|
||||
}
|
||||
frame->nb_samples = s->in_samples;
|
||||
frame->format = s->lavc_actx->sample_fmt;
|
||||
frame->channel_layout = s->lavc_actx->channel_layout;
|
||||
assert(s->input->num_planes <= AV_NUM_DATA_POINTERS);
|
||||
frame->extended_data = frame->data;
|
||||
for (int n = 0; n < s->input->num_planes; n++)
|
||||
frame->data[n] = s->input->planes[n];
|
||||
frame->linesize[0] = s->input->samples * s->input->sstride;
|
||||
int max_out_samples = s->out_samples * num_frames;
|
||||
mp_audio_realloc_min(out, max_out_samples);
|
||||
out->samples = 0;
|
||||
|
||||
int ok;
|
||||
int lavc_ret = avcodec_encode_audio2(s->lavc_actx, &s->pkt, frame, &ok);
|
||||
av_frame_free(&frame);
|
||||
s->input->samples = 0;
|
||||
if (lavc_ret < 0 || !ok) {
|
||||
MP_FATAL(af, "Encode failed.\n");
|
||||
return -1;
|
||||
while (audio->samples > 0) {
|
||||
int ret;
|
||||
|
||||
int consumed_pending = 0;
|
||||
struct mp_audio in_frame;
|
||||
int pending = mp_audio_buffer_samples(s->pending);
|
||||
if (pending == 0 && audio->samples >= s->in_samples) {
|
||||
in_frame = *audio;
|
||||
mp_audio_skip_samples(audio, s->in_samples);
|
||||
} else {
|
||||
if (pending > 0 && pending < s->in_samples) {
|
||||
struct mp_audio tmp = *audio;
|
||||
tmp.samples = MPMIN(tmp.samples, s->in_samples);
|
||||
mp_audio_buffer_append(s->pending, &tmp);
|
||||
mp_audio_skip_samples(audio, tmp.samples);
|
||||
}
|
||||
mp_audio_buffer_peek(s->pending, &in_frame);
|
||||
if (in_frame.samples < s->in_samples)
|
||||
break;
|
||||
consumed_pending = s->in_samples;
|
||||
}
|
||||
in_frame.samples = s->in_samples;
|
||||
|
||||
AVFrame *frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
MP_FATAL(af, "Could not allocate memory \n");
|
||||
return -1;
|
||||
}
|
||||
frame->nb_samples = s->in_samples;
|
||||
frame->format = s->lavc_actx->sample_fmt;
|
||||
frame->channel_layout = s->lavc_actx->channel_layout;
|
||||
assert(in_frame.num_planes <= AV_NUM_DATA_POINTERS);
|
||||
frame->extended_data = frame->data;
|
||||
for (int n = 0; n < in_frame.num_planes; n++)
|
||||
frame->data[n] = in_frame.planes[n];
|
||||
frame->linesize[0] = s->in_samples * audio->sstride;
|
||||
|
||||
int ok;
|
||||
ret = avcodec_encode_audio2(s->lavc_actx, &s->pkt, frame, &ok);
|
||||
av_frame_free(&frame);
|
||||
if (ret < 0 || !ok) {
|
||||
MP_FATAL(af, "Encode failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
mp_audio_buffer_skip(s->pending, consumed_pending);
|
||||
|
||||
MP_DBG(af, "avcodec_encode_audio got %d, pending %d.\n",
|
||||
s->pkt.size, mp_audio_buffer_samples(s->pending));
|
||||
|
||||
int frame_size = s->pkt.size;
|
||||
int header_len = 0;
|
||||
char hdr[8];
|
||||
|
||||
if (s->cfg_add_iec61937_header && s->pkt.size > 5) {
|
||||
int bsmod = s->pkt.data[5] & 0x7;
|
||||
int len = frame_size;
|
||||
|
||||
frame_size = AC3_FRAME_SIZE * 2 * 2;
|
||||
header_len = 8;
|
||||
|
||||
AV_WL16(hdr, 0xF872); // iec 61937 syncword 1
|
||||
AV_WL16(hdr + 2, 0x4E1F); // iec 61937 syncword 2
|
||||
hdr[5] = bsmod; // bsmod
|
||||
hdr[4] = 0x01; // data-type ac3
|
||||
AV_WL16(hdr + 6, len << 3); // number of bits in payload
|
||||
}
|
||||
|
||||
size_t max_size = (max_out_samples - out->samples) * out->sstride;
|
||||
if (frame_size > max_size)
|
||||
abort();
|
||||
|
||||
char *buf = (char *)out->planes[0] + out->samples * out->sstride;
|
||||
memcpy(buf, hdr, header_len);
|
||||
memcpy(buf + header_len, s->pkt.data, s->pkt.size);
|
||||
memset(buf + header_len + s->pkt.size, 0,
|
||||
frame_size - (header_len + s->pkt.size));
|
||||
swap_16((uint16_t *)(buf + header_len), s->pkt.size / 2);
|
||||
out->samples += frame_size / out->sstride;
|
||||
}
|
||||
|
||||
MP_DBG(af, "avcodec_encode_audio got %d, pending %d.\n",
|
||||
s->pkt.size, s->pending->samples);
|
||||
mp_audio_buffer_append(s->pending, audio);
|
||||
|
||||
struct mp_audio *out =
|
||||
mp_audio_pool_get(af->out_pool, af->data, s->out_samples);
|
||||
if (!out)
|
||||
return -1;
|
||||
mp_audio_copy_attributes(out, s->pending);
|
||||
|
||||
int frame_size = s->pkt.size;
|
||||
int header_len = 0;
|
||||
char hdr[8];
|
||||
|
||||
if (s->cfg_add_iec61937_header && s->pkt.size > 5) {
|
||||
int bsmod = s->pkt.data[5] & 0x7;
|
||||
int len = frame_size;
|
||||
|
||||
frame_size = AC3_FRAME_SIZE * 2 * 2;
|
||||
header_len = 8;
|
||||
|
||||
AV_WL16(hdr, 0xF872); // iec 61937 syncword 1
|
||||
AV_WL16(hdr + 2, 0x4E1F); // iec 61937 syncword 2
|
||||
hdr[5] = bsmod; // bsmod
|
||||
hdr[4] = 0x01; // data-type ac3
|
||||
AV_WL16(hdr + 6, len << 3); // number of bits in payload
|
||||
}
|
||||
|
||||
if (frame_size > out->samples * out->sstride)
|
||||
abort();
|
||||
|
||||
char *buf = (char *)out->planes[0];
|
||||
memcpy(buf, hdr, header_len);
|
||||
memcpy(buf + header_len, s->pkt.data, s->pkt.size);
|
||||
memset(buf + header_len + s->pkt.size, 0,
|
||||
frame_size - (header_len + s->pkt.size));
|
||||
swap_16((uint16_t *)(buf + header_len), s->pkt.size / 2);
|
||||
out->samples = frame_size / out->sstride;
|
||||
af_add_output_frame(af, out);
|
||||
*audio = *out;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -264,8 +261,7 @@ static int af_open(struct af_instance* af){
|
||||
af_ac3enc_t *s = af->priv;
|
||||
af->control=control;
|
||||
af->uninit=uninit;
|
||||
af->filter_frame = filter_frame;
|
||||
af->filter_out = filter_out;
|
||||
af->filter=filter;
|
||||
|
||||
s->lavc_acodec = avcodec_find_encoder_by_name("ac3");
|
||||
if (!s->lavc_acodec) {
|
||||
@@ -296,7 +292,7 @@ static int af_open(struct af_instance* af){
|
||||
|
||||
av_init_packet(&s->pkt);
|
||||
|
||||
s->input = talloc_zero(s, struct mp_audio);
|
||||
s->pending = mp_audio_buffer_create(af);
|
||||
|
||||
if (s->cfg_bit_rate) {
|
||||
int i;
|
||||
|
||||
+52
-88
@@ -61,8 +61,6 @@ struct priv {
|
||||
|
||||
AVRational timebase_out;
|
||||
|
||||
bool eof;
|
||||
|
||||
// options
|
||||
char *cfg_graph;
|
||||
char **cfg_avopts;
|
||||
@@ -73,8 +71,6 @@ static void destroy_graph(struct af_instance *af)
|
||||
struct priv *p = af->priv;
|
||||
avfilter_graph_free(&p->graph);
|
||||
p->in = p->out = NULL;
|
||||
p->samples_in = 0;
|
||||
p->eof = false;
|
||||
}
|
||||
|
||||
static bool recreate_graph(struct af_instance *af, struct mp_audio *config)
|
||||
@@ -171,12 +167,6 @@ error:
|
||||
return false;
|
||||
}
|
||||
|
||||
static void reset(struct af_instance *af)
|
||||
{
|
||||
if (!recreate_graph(af, &af->fmt_in))
|
||||
MP_FATAL(af, "Can't recreate libavfilter filter after a seek reset.\n");
|
||||
}
|
||||
|
||||
static int control(struct af_instance *af, int cmd, void *arg)
|
||||
{
|
||||
struct priv *p = af->priv;
|
||||
@@ -211,108 +201,83 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
|
||||
p->timebase_out = l_out->time_base;
|
||||
|
||||
// Blatantly incorrect; we don't know what the filters do.
|
||||
af->mul = out->rate / (double)in->rate;
|
||||
|
||||
return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE;
|
||||
}
|
||||
case AF_CONTROL_RESET:
|
||||
reset(af);
|
||||
return AF_OK;
|
||||
}
|
||||
return AF_UNKNOWN;
|
||||
}
|
||||
|
||||
static int filter_frame(struct af_instance *af, struct mp_audio *data)
|
||||
static int filter(struct af_instance *af, struct mp_audio *data, int flags)
|
||||
{
|
||||
struct priv *p = af->priv;
|
||||
AVFrame *frame = NULL;
|
||||
|
||||
if (p->eof && data)
|
||||
reset(af);
|
||||
|
||||
if (!p->graph)
|
||||
goto error;
|
||||
|
||||
struct mp_audio *r = af->data;
|
||||
bool eof = data->samples == 0 && (flags & AF_FILTER_FLAG_EOF);
|
||||
AVFilterLink *l_in = p->in->outputs[0];
|
||||
|
||||
if (data) {
|
||||
frame = av_frame_alloc();
|
||||
if (!frame)
|
||||
goto error;
|
||||
AVFrame *frame = av_frame_alloc();
|
||||
frame->nb_samples = data->samples;
|
||||
frame->format = l_in->format;
|
||||
|
||||
frame->nb_samples = data->samples;
|
||||
frame->format = l_in->format;
|
||||
// Timebase is 1/sample_rate
|
||||
frame->pts = p->samples_in;
|
||||
|
||||
// Timebase is 1/sample_rate
|
||||
frame->pts = p->samples_in;
|
||||
|
||||
frame->channel_layout = l_in->channel_layout;
|
||||
frame->sample_rate = l_in->sample_rate;
|
||||
frame->channel_layout = l_in->channel_layout;
|
||||
frame->sample_rate = l_in->sample_rate;
|
||||
#if LIBAVFILTER_VERSION_MICRO >= 100
|
||||
// FFmpeg being a stupid POS
|
||||
frame->channels = l_in->channels;
|
||||
// FFmpeg being a stupid POS
|
||||
frame->channels = l_in->channels;
|
||||
#endif
|
||||
|
||||
frame->extended_data = frame->data;
|
||||
for (int n = 0; n < data->num_planes; n++)
|
||||
frame->data[n] = data->planes[n];
|
||||
frame->linesize[0] = frame->nb_samples * data->sstride;
|
||||
frame->extended_data = frame->data;
|
||||
for (int n = 0; n < data->num_planes; n++)
|
||||
frame->data[n] = data->planes[n];
|
||||
frame->linesize[0] = frame->nb_samples * data->sstride;
|
||||
|
||||
if (av_buffersrc_add_frame(p->in, eof ? NULL : frame) < 0) {
|
||||
av_frame_free(&frame);
|
||||
return -1;
|
||||
}
|
||||
av_frame_free(&frame);
|
||||
|
||||
int64_t out_pts = AV_NOPTS_VALUE;
|
||||
r->samples = 0;
|
||||
for (;;) {
|
||||
frame = av_frame_alloc();
|
||||
if (av_buffersink_get_frame(p->out, frame) < 0) {
|
||||
// Not an error situation - no more output buffers in queue.
|
||||
av_frame_free(&frame);
|
||||
break;
|
||||
}
|
||||
|
||||
mp_audio_realloc_min(r, r->samples + frame->nb_samples);
|
||||
for (int n = 0; n < r->num_planes; n++) {
|
||||
memcpy((char *)r->planes[n] + r->samples * r->sstride,
|
||||
frame->extended_data[n], frame->nb_samples * r->sstride);
|
||||
}
|
||||
r->samples += frame->nb_samples;
|
||||
|
||||
if (out_pts == AV_NOPTS_VALUE)
|
||||
out_pts = frame->pts;
|
||||
|
||||
p->samples_in += data->samples;
|
||||
}
|
||||
|
||||
if (av_buffersrc_add_frame(p->in, frame) < 0)
|
||||
goto error;
|
||||
|
||||
av_frame_free(&frame);
|
||||
talloc_free(data);
|
||||
return 0;
|
||||
error:
|
||||
av_frame_free(&frame);
|
||||
talloc_free(data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int filter_out(struct af_instance *af)
|
||||
{
|
||||
struct priv *p = af->priv;
|
||||
|
||||
if (!p->graph)
|
||||
goto error;
|
||||
|
||||
AVFrame *frame = av_frame_alloc();
|
||||
if (!frame)
|
||||
goto error;
|
||||
|
||||
int err = av_buffersink_get_frame(p->out, frame);
|
||||
if (err == AVERROR(EAGAIN) || err == AVERROR_EOF) {
|
||||
// Not an error situation - no more output buffers in queue.
|
||||
// AVERROR_EOF means we shouldn't even give the filter more
|
||||
// input, but we don't handle that completely correctly.
|
||||
av_frame_free(&frame);
|
||||
p->eof |= err == AVERROR_EOF;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct mp_audio *out = mp_audio_from_avframe(frame);
|
||||
if (!out)
|
||||
goto error;
|
||||
p->samples_in += data->samples;
|
||||
|
||||
mp_audio_copy_config(out, af->data);
|
||||
|
||||
if (frame->pts != AV_NOPTS_VALUE) {
|
||||
double in_time = p->samples_in / (double)af->fmt_in.rate;
|
||||
double out_time = frame->pts * av_q2d(p->timebase_out);
|
||||
if (out_pts != AV_NOPTS_VALUE) {
|
||||
double in_time = p->samples_in / (double)data->rate;
|
||||
double out_time = out_pts * av_q2d(p->timebase_out);
|
||||
// Need pts past the last output sample.
|
||||
out_time += out->samples / (double)out->rate;
|
||||
out_time += r->samples / (double)r->rate;
|
||||
|
||||
af->delay = in_time - out_time;
|
||||
}
|
||||
|
||||
af_add_output_frame(af, out);
|
||||
av_frame_free(&frame);
|
||||
*data = *r;
|
||||
return 0;
|
||||
error:
|
||||
av_frame_free(&frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void uninit(struct af_instance *af)
|
||||
@@ -324,8 +289,7 @@ static int af_open(struct af_instance *af)
|
||||
{
|
||||
af->control = control;
|
||||
af->uninit = uninit;
|
||||
af->filter_frame = filter_frame;
|
||||
af->filter_out = filter_out;
|
||||
af->filter = filter;
|
||||
// Removing this requires fixing AVFrame.data vs. AVFrame.extended_data
|
||||
assert(MP_NUM_CHANNELS <= AV_NUM_DATA_POINTERS);
|
||||
return AF_OK;
|
||||
|
||||
+74
-201
@@ -2,29 +2,28 @@
|
||||
* Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
|
||||
* Copyright (c) 2013 Stefano Pigozzi <stefano.pigozzi@gmail.com>
|
||||
*
|
||||
* This file is part of mpv.
|
||||
* Based on Michael Niedermayer's lavcresample.
|
||||
*
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <libavutil/opt.h>
|
||||
@@ -33,7 +32,7 @@
|
||||
#include <libavutil/samplefmt.h>
|
||||
#include <libavutil/mathematics.h>
|
||||
|
||||
#include "common/common.h"
|
||||
#include "talloc.h"
|
||||
#include "config.h"
|
||||
|
||||
#if HAVE_LIBAVRESAMPLE
|
||||
@@ -65,8 +64,7 @@ struct af_resample_opts {
|
||||
int linear;
|
||||
double cutoff;
|
||||
|
||||
int in_rate_af; // filter input sample rate
|
||||
int in_rate; // actual rate (used by lavr), adjusted for playback speed
|
||||
int in_rate;
|
||||
int in_format;
|
||||
struct mp_chmap in_channels;
|
||||
int out_rate;
|
||||
@@ -77,18 +75,14 @@ struct af_resample_opts {
|
||||
struct af_resample {
|
||||
int allow_detach;
|
||||
char **avopts;
|
||||
double playback_speed;
|
||||
struct mp_audio *pending;
|
||||
bool avrctx_ok;
|
||||
struct AVAudioResampleContext *avrctx;
|
||||
struct mp_audio avrctx_fmt; // output format of avrctx
|
||||
struct AVAudioResampleContext *avrctx_out; // for output channel reordering
|
||||
struct af_resample_opts ctx; // opts in the context
|
||||
struct af_resample_opts opts; // opts requested by the user
|
||||
// At least libswresample keeps a pointer around for this:
|
||||
int reorder_in[MP_NUM_CHANNELS];
|
||||
int reorder_out[MP_NUM_CHANNELS];
|
||||
struct mp_audio_pool *reorder_buffer;
|
||||
uint8_t *reorder_buffer;
|
||||
};
|
||||
|
||||
#if HAVE_LIBAVRESAMPLE
|
||||
@@ -100,10 +94,6 @@ static void drop_all_output(struct af_resample *s)
|
||||
{
|
||||
while (avresample_read(s->avrctx, NULL, 1000) > 0) {}
|
||||
}
|
||||
static int get_drain_samples(struct af_resample *s)
|
||||
{
|
||||
return avresample_get_out_samples(s->avrctx, 0);
|
||||
}
|
||||
#else
|
||||
static int get_delay(struct af_resample *s)
|
||||
{
|
||||
@@ -113,39 +103,18 @@ static void drop_all_output(struct af_resample *s)
|
||||
{
|
||||
while (swr_drop_output(s->avrctx, 1000) > 0) {}
|
||||
}
|
||||
static int get_drain_samples(struct af_resample *s)
|
||||
{
|
||||
return 4096; // libswscale does not have this
|
||||
}
|
||||
#endif
|
||||
|
||||
static int resample_frame(struct AVAudioResampleContext *r,
|
||||
struct mp_audio *out, struct mp_audio *in)
|
||||
{
|
||||
return avresample_convert(r,
|
||||
out ? (uint8_t **)out->planes : NULL,
|
||||
out ? mp_audio_get_allocated_size(out) : 0,
|
||||
out ? out->samples : 0,
|
||||
in ? (uint8_t **)in->planes : NULL,
|
||||
in ? mp_audio_get_allocated_size(in) : 0,
|
||||
in ? in->samples : 0);
|
||||
}
|
||||
|
||||
static double af_resample_default_cutoff(int filter_size)
|
||||
{
|
||||
return FFMAX(1.0 - 6.5 / (filter_size + 8), 0.80);
|
||||
}
|
||||
|
||||
static int rate_from_speed(int rate, double speed)
|
||||
{
|
||||
return lrint(rate * speed);
|
||||
}
|
||||
|
||||
static bool needs_lavrctx_reconfigure(struct af_resample *s,
|
||||
struct mp_audio *in,
|
||||
struct mp_audio *out)
|
||||
{
|
||||
return s->ctx.in_rate_af != in->rate ||
|
||||
return s->ctx.in_rate != in->rate ||
|
||||
s->ctx.in_format != in->format ||
|
||||
!mp_chmap_equals(&s->ctx.in_channels, &in->channels) ||
|
||||
s->ctx.out_rate != out->rate ||
|
||||
@@ -164,48 +133,22 @@ static bool test_conversion(int src_format, int dst_format)
|
||||
af_to_avformat(dst_format) != AV_SAMPLE_FMT_NONE;
|
||||
}
|
||||
|
||||
// mp_chmap_get_reorder() performs:
|
||||
// to->speaker[n] = from->speaker[src[n]]
|
||||
// but libavresample does:
|
||||
// to->speaker[dst[n]] = from->speaker[n]
|
||||
static void transpose_order(int *map, int num)
|
||||
{
|
||||
int nmap[MP_NUM_CHANNELS] = {0};
|
||||
for (int n = 0; n < num; n++) {
|
||||
for (int i = 0; i < num; i++) {
|
||||
if (map[n] == i)
|
||||
nmap[i] = n;
|
||||
}
|
||||
}
|
||||
memcpy(map, nmap, sizeof(nmap));
|
||||
}
|
||||
|
||||
static int configure_lavrr(struct af_instance *af, struct mp_audio *in,
|
||||
struct mp_audio *out)
|
||||
{
|
||||
struct af_resample *s = af->priv;
|
||||
|
||||
s->avrctx_ok = false;
|
||||
|
||||
enum AVSampleFormat in_samplefmt = af_to_avformat(in->format);
|
||||
enum AVSampleFormat out_samplefmt = af_to_avformat(out->format);
|
||||
enum AVSampleFormat out_samplefmtp =
|
||||
af_to_avformat(af_fmt_to_planar(out->format));
|
||||
|
||||
if (in_samplefmt == AV_SAMPLE_FMT_NONE ||
|
||||
out_samplefmt == AV_SAMPLE_FMT_NONE ||
|
||||
out_samplefmtp == AV_SAMPLE_FMT_NONE)
|
||||
if (in_samplefmt == AV_SAMPLE_FMT_NONE || out_samplefmt == AV_SAMPLE_FMT_NONE)
|
||||
return AF_ERROR;
|
||||
|
||||
avresample_close(s->avrctx);
|
||||
avresample_close(s->avrctx_out);
|
||||
|
||||
talloc_free(s->pending);
|
||||
s->pending = NULL;
|
||||
|
||||
s->ctx.out_rate = out->rate;
|
||||
s->ctx.in_rate_af = in->rate;
|
||||
s->ctx.in_rate = rate_from_speed(in->rate, s->playback_speed);
|
||||
s->ctx.in_rate = in->rate;
|
||||
s->ctx.out_format = out->format;
|
||||
s->ctx.in_format = in->format;
|
||||
s->ctx.out_channels= out->channels;
|
||||
@@ -221,10 +164,6 @@ static int configure_lavrr(struct af_instance *af, struct mp_audio *in,
|
||||
|
||||
av_opt_set_double(s->avrctx, "cutoff", s->ctx.cutoff, 0);
|
||||
|
||||
#if HAVE_LIBSWRESAMPLE
|
||||
av_opt_set_double(s->avrctx, "rematrix_maxval", 1.0, 0);
|
||||
#endif
|
||||
|
||||
if (mp_set_avopts(af->log, s->avrctx, s->avopts) < 0)
|
||||
return AF_ERROR;
|
||||
|
||||
@@ -241,52 +180,27 @@ static int configure_lavrr(struct af_instance *af, struct mp_audio *in,
|
||||
uint64_t in_ch_layout = mp_chmap_to_lavc_unchecked(&map_in);
|
||||
uint64_t out_ch_layout = mp_chmap_to_lavc_unchecked(&map_out);
|
||||
|
||||
av_opt_set_int(s->avrctx, "in_channel_layout", in_ch_layout, 0);
|
||||
av_opt_set_int(s->avrctx, "out_channel_layout", out_ch_layout, 0);
|
||||
|
||||
av_opt_set_int(s->avrctx, "in_sample_rate", s->ctx.in_rate, 0);
|
||||
av_opt_set_int(s->avrctx, "out_sample_rate", s->ctx.out_rate, 0);
|
||||
|
||||
av_opt_set_int(s->avrctx, "in_sample_fmt", in_samplefmt, 0);
|
||||
av_opt_set_int(s->avrctx, "out_sample_fmt", out_samplefmt, 0);
|
||||
|
||||
struct mp_chmap in_lavc;
|
||||
mp_chmap_from_lavc(&in_lavc, in_ch_layout);
|
||||
if (in_lavc.num != map_in.num) {
|
||||
// For handling NA channels, we would have to add a planarization step.
|
||||
MP_FATAL(af, "Unsupported channel remapping.\n");
|
||||
return AF_ERROR;
|
||||
}
|
||||
|
||||
mp_chmap_get_reorder(s->reorder_in, &map_in, &in_lavc);
|
||||
transpose_order(s->reorder_in, map_in.num);
|
||||
|
||||
struct mp_chmap out_lavc;
|
||||
mp_chmap_from_lavc(&out_lavc, out_ch_layout);
|
||||
if (mp_chmap_equals(&out_lavc, &map_out)) {
|
||||
// No intermediate step required - output new format directly.
|
||||
out_samplefmtp = out_samplefmt;
|
||||
} else {
|
||||
// Verify that we really just reorder and/or insert NA channels.
|
||||
struct mp_chmap withna = out_lavc;
|
||||
mp_chmap_fill_na(&withna, map_out.num);
|
||||
if (withna.num != map_out.num)
|
||||
return AF_ERROR;
|
||||
mp_chmap_get_reorder(s->reorder_out, &out_lavc, &map_out);
|
||||
}
|
||||
mp_chmap_get_reorder(s->reorder_out, &out_lavc, &map_out);
|
||||
|
||||
s->avrctx_fmt = *out;
|
||||
mp_audio_set_channels(&s->avrctx_fmt, &out_lavc);
|
||||
mp_audio_set_format(&s->avrctx_fmt, af_from_avformat(out_samplefmtp));
|
||||
|
||||
// Real conversion; output is input to avrctx_out.
|
||||
av_opt_set_int(s->avrctx, "in_channel_layout", in_ch_layout, 0);
|
||||
av_opt_set_int(s->avrctx, "out_channel_layout", out_ch_layout, 0);
|
||||
av_opt_set_int(s->avrctx, "in_sample_rate", s->ctx.in_rate, 0);
|
||||
av_opt_set_int(s->avrctx, "out_sample_rate", s->ctx.out_rate, 0);
|
||||
av_opt_set_int(s->avrctx, "in_sample_fmt", in_samplefmt, 0);
|
||||
av_opt_set_int(s->avrctx, "out_sample_fmt", out_samplefmtp, 0);
|
||||
|
||||
// Just needs the correct number of channels.
|
||||
int fake_out_ch_layout = av_get_default_channel_layout(map_out.num);
|
||||
if (!fake_out_ch_layout)
|
||||
return AF_ERROR;
|
||||
|
||||
// Deplanarize if needed.
|
||||
av_opt_set_int(s->avrctx_out, "in_channel_layout", fake_out_ch_layout, 0);
|
||||
av_opt_set_int(s->avrctx_out, "out_channel_layout", fake_out_ch_layout, 0);
|
||||
av_opt_set_int(s->avrctx_out, "in_sample_fmt", out_samplefmtp, 0);
|
||||
// Same configuration; we just reorder.
|
||||
av_opt_set_int(s->avrctx_out, "in_channel_layout", out_ch_layout, 0);
|
||||
av_opt_set_int(s->avrctx_out, "out_channel_layout", out_ch_layout, 0);
|
||||
av_opt_set_int(s->avrctx_out, "in_sample_fmt", out_samplefmt, 0);
|
||||
av_opt_set_int(s->avrctx_out, "out_sample_fmt", out_samplefmt, 0);
|
||||
av_opt_set_int(s->avrctx_out, "in_sample_rate", s->ctx.out_rate, 0);
|
||||
av_opt_set_int(s->avrctx_out, "out_sample_rate", s->ctx.out_rate, 0);
|
||||
@@ -295,6 +209,7 @@ static int configure_lavrr(struct af_instance *af, struct mp_audio *in,
|
||||
// * This function can only be called when the allocated context is not open.
|
||||
// * Also, the input channel layout must have already been set.
|
||||
avresample_set_channel_mapping(s->avrctx, s->reorder_in);
|
||||
avresample_set_channel_mapping(s->avrctx_out, s->reorder_out);
|
||||
|
||||
if (avresample_open(s->avrctx) < 0 ||
|
||||
avresample_open(s->avrctx_out) < 0)
|
||||
@@ -302,25 +217,24 @@ static int configure_lavrr(struct af_instance *af, struct mp_audio *in,
|
||||
MP_ERR(af, "Cannot open Libavresample Context. \n");
|
||||
return AF_ERROR;
|
||||
}
|
||||
s->avrctx_ok = true;
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
|
||||
static int control(struct af_instance *af, int cmd, void *arg)
|
||||
{
|
||||
struct af_resample *s = af->priv;
|
||||
struct af_resample *s = (struct af_resample *) af->priv;
|
||||
struct mp_audio *in = (struct mp_audio *) arg;
|
||||
struct mp_audio *out = (struct mp_audio *) af->data;
|
||||
|
||||
switch (cmd) {
|
||||
case AF_CONTROL_REINIT: {
|
||||
struct mp_audio *in = arg;
|
||||
struct mp_audio *out = af->data;
|
||||
struct mp_audio orig_in = *in;
|
||||
|
||||
if (((out->rate == in->rate) || (out->rate == 0)) &&
|
||||
(out->format == in->format) &&
|
||||
(mp_chmap_equals(&out->channels, &in->channels) || out->nch == 0) &&
|
||||
s->allow_detach && s->playback_speed == 1.0)
|
||||
s->allow_detach)
|
||||
return AF_DETACH;
|
||||
|
||||
if (out->rate == 0)
|
||||
@@ -334,6 +248,8 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
if (af_to_avformat(out->format) == AV_SAMPLE_FMT_NONE)
|
||||
mp_audio_set_format(out, in->format);
|
||||
|
||||
af->mul = out->rate / (double)in->rate;
|
||||
|
||||
int r = ((in->format == orig_in.format) &&
|
||||
mp_chmap_equals(&in->channels, &orig_in.channels))
|
||||
? AF_OK : AF_FALSE;
|
||||
@@ -343,11 +259,10 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
return r;
|
||||
}
|
||||
case AF_CONTROL_SET_FORMAT: {
|
||||
int format = *(int *)arg;
|
||||
if (format && af_to_avformat(format) == AV_SAMPLE_FMT_NONE)
|
||||
if (af_to_avformat(*(int*)arg) == AV_SAMPLE_FMT_NONE)
|
||||
return AF_FALSE;
|
||||
|
||||
mp_audio_set_format(af->data, format);
|
||||
mp_audio_set_format(af->data, *(int*)arg);
|
||||
return AF_OK;
|
||||
}
|
||||
case AF_CONTROL_SET_CHANNELS: {
|
||||
@@ -355,28 +270,8 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
return AF_OK;
|
||||
}
|
||||
case AF_CONTROL_SET_RESAMPLE_RATE:
|
||||
af->data->rate = *(int *)arg;
|
||||
out->rate = *(int *)arg;
|
||||
return AF_OK;
|
||||
case AF_CONTROL_SET_PLAYBACK_SPEED_RESAMPLE: {
|
||||
s->playback_speed = *(double *)arg;
|
||||
int new_rate = rate_from_speed(s->ctx.in_rate_af, s->playback_speed);
|
||||
if (new_rate != s->ctx.in_rate && s->avrctx_ok && af->fmt_out.format) {
|
||||
// Before reconfiguring, drain the audio that is still buffered
|
||||
// in the resampler.
|
||||
struct mp_audio *pending = talloc_zero(NULL, struct mp_audio);
|
||||
mp_audio_copy_config(pending, &af->fmt_out);
|
||||
pending->samples = get_drain_samples(s);
|
||||
if (pending->samples > 0) {
|
||||
mp_audio_realloc_min(pending, pending->samples);
|
||||
int r = resample_frame(s->avrctx, pending, NULL);
|
||||
pending->samples = MPMAX(r, 0);
|
||||
}
|
||||
// Reinitialize resampler.
|
||||
configure_lavrr(af, &af->fmt_in, &af->fmt_out);
|
||||
s->pending = pending;
|
||||
}
|
||||
return AF_OK;
|
||||
}
|
||||
case AF_CONTROL_RESET:
|
||||
drop_all_output(s);
|
||||
return AF_OK;
|
||||
@@ -396,87 +291,67 @@ static void uninit(struct af_instance *af)
|
||||
if (s->avrctx_out)
|
||||
avresample_close(s->avrctx_out);
|
||||
avresample_free(&s->avrctx_out);
|
||||
talloc_free(s->pending);
|
||||
}
|
||||
|
||||
static void reorder_planes(struct mp_audio *mpa, int *reorder,
|
||||
struct mp_chmap *newmap)
|
||||
static bool needs_reorder(int *reorder, int num_ch)
|
||||
{
|
||||
for (int n = 0; n < num_ch; n++) {
|
||||
if (reorder[n] != n)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void reorder_planes(struct mp_audio *mpa, int *reorder)
|
||||
{
|
||||
struct mp_audio prev = *mpa;
|
||||
|
||||
for (int n = 0; n < newmap->num; n++) {
|
||||
int src = reorder[n];
|
||||
if (src < 0) {
|
||||
src = 0; // Use the first plane for padding channels.
|
||||
mpa->readonly = true;
|
||||
}
|
||||
assert(src < mpa->num_planes);
|
||||
mpa->planes[n] = prev.planes[src];
|
||||
for (int n = 0; n < mpa->num_planes; n++) {
|
||||
assert(reorder[n] >= 0 && reorder[n] < mpa->num_planes);
|
||||
mpa->planes[n] = prev.planes[reorder[n]];
|
||||
}
|
||||
|
||||
mp_audio_set_channels(mpa, newmap);
|
||||
}
|
||||
|
||||
static int filter(struct af_instance *af, struct mp_audio *in)
|
||||
static int filter(struct af_instance *af, struct mp_audio *data, int flags)
|
||||
{
|
||||
struct af_resample *s = af->priv;
|
||||
struct mp_audio *in = data;
|
||||
struct mp_audio *out = af->data;
|
||||
|
||||
if (s->pending) {
|
||||
if (s->pending->samples) {
|
||||
af_add_output_frame(af, s->pending);
|
||||
} else {
|
||||
talloc_free(s->pending);
|
||||
}
|
||||
s->pending = NULL;
|
||||
}
|
||||
|
||||
int samples = avresample_available(s->avrctx) +
|
||||
av_rescale_rnd(get_delay(s) + (in ? in->samples : 0),
|
||||
out->samples = avresample_available(s->avrctx) +
|
||||
av_rescale_rnd(get_delay(s) + in->samples,
|
||||
s->ctx.out_rate, s->ctx.in_rate, AV_ROUND_UP);
|
||||
|
||||
struct mp_audio out_format = s->avrctx_fmt;
|
||||
struct mp_audio *out = mp_audio_pool_get(af->out_pool, &out_format, samples);
|
||||
if (!out)
|
||||
goto error;
|
||||
if (in)
|
||||
mp_audio_copy_attributes(out, in);
|
||||
mp_audio_realloc_min(out, out->samples);
|
||||
|
||||
af->delay = get_delay(s) / (double)s->ctx.in_rate;
|
||||
|
||||
if (out->samples) {
|
||||
out->samples = resample_frame(s->avrctx, out, in);
|
||||
out->samples = avresample_convert(s->avrctx,
|
||||
(uint8_t **) out->planes, out->samples * out->sstride, out->samples,
|
||||
(uint8_t **) in->planes, in->samples * in->sstride, in->samples);
|
||||
if (out->samples < 0)
|
||||
goto error;
|
||||
return -1; // error
|
||||
}
|
||||
|
||||
if (out->samples && !mp_audio_config_equals(out, af->data)) {
|
||||
assert(AF_FORMAT_IS_PLANAR(out->format));
|
||||
reorder_planes(out, s->reorder_out, &af->data->channels);
|
||||
if (!mp_audio_config_equals(out, af->data)) {
|
||||
struct mp_audio *new = mp_audio_pool_get(s->reorder_buffer, af->data,
|
||||
out->samples);
|
||||
if (!new)
|
||||
goto error;
|
||||
mp_audio_copy_attributes(new, out);
|
||||
int out_samples = resample_frame(s->avrctx_out, new, out);
|
||||
talloc_free(out);
|
||||
out = new;
|
||||
if (out_samples != new->samples)
|
||||
goto error;
|
||||
*data = *out;
|
||||
|
||||
if (needs_reorder(s->reorder_out, out->nch)) {
|
||||
if (af_fmt_is_planar(out->format)) {
|
||||
reorder_planes(data, s->reorder_out);
|
||||
} else if (out->samples) {
|
||||
int out_size = out->samples * out->sstride;
|
||||
if (talloc_get_size(s->reorder_buffer) < out_size)
|
||||
s->reorder_buffer = talloc_realloc_size(s, s->reorder_buffer, out_size);
|
||||
data->planes[0] = s->reorder_buffer;
|
||||
int out_samples = avresample_convert(s->avrctx_out,
|
||||
(uint8_t **) data->planes, out_size, out->samples,
|
||||
(uint8_t **) out->planes, out_size, out->samples);
|
||||
if (out_samples < 0)
|
||||
MP_ERR(af, "Reordering failed.\n");
|
||||
}
|
||||
}
|
||||
|
||||
talloc_free(in);
|
||||
if (out->samples) {
|
||||
af_add_output_frame(af, out);
|
||||
} else {
|
||||
talloc_free(out);
|
||||
}
|
||||
return 0;
|
||||
error:
|
||||
talloc_free(in);
|
||||
talloc_free(out);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int af_open(struct af_instance *af)
|
||||
@@ -485,14 +360,13 @@ static int af_open(struct af_instance *af)
|
||||
|
||||
af->control = control;
|
||||
af->uninit = uninit;
|
||||
af->filter_frame = filter;
|
||||
af->filter = filter;
|
||||
|
||||
if (s->opts.cutoff <= 0.0)
|
||||
s->opts.cutoff = af_resample_default_cutoff(s->opts.filter_size);
|
||||
|
||||
s->avrctx = avresample_alloc_context();
|
||||
s->avrctx_out = avresample_alloc_context();
|
||||
s->reorder_buffer = mp_audio_pool_create(s);
|
||||
|
||||
if (s->avrctx && s->avrctx_out) {
|
||||
return AF_OK;
|
||||
@@ -517,7 +391,6 @@ const struct af_info af_info_lavrresample = {
|
||||
.cutoff = 0.0,
|
||||
.phase_shift = 10,
|
||||
},
|
||||
.playback_speed = 1.0,
|
||||
.allow_detach = 1,
|
||||
},
|
||||
.options = (const struct m_option[]) {
|
||||
|
||||
+16
-17
@@ -1,20 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) 2002 Anders Johansson ajh@atri.curtin.edu.au
|
||||
*
|
||||
* This file is part of mpv.
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -106,17 +107,11 @@ static int control(struct af_instance* af, int cmd, void* arg)
|
||||
return AF_UNKNOWN;
|
||||
}
|
||||
|
||||
static int filter_frame(struct af_instance *af, struct mp_audio *c)
|
||||
// Filter data through filter
|
||||
static int filter(struct af_instance* af, struct mp_audio* data, int flags)
|
||||
{
|
||||
if (!c)
|
||||
return 0;
|
||||
struct mp_audio *l = mp_audio_pool_get(af->out_pool, &af->fmt_out, c->samples);
|
||||
if (!l) {
|
||||
talloc_free(c);
|
||||
return -1;
|
||||
}
|
||||
mp_audio_copy_attributes(l, c);
|
||||
|
||||
struct mp_audio* c = data; // Current working data
|
||||
struct mp_audio* l = af->data; // Local data
|
||||
af_pan_t* s = af->priv; // Setup for this instance
|
||||
float* in = c->planes[0]; // Input audio data
|
||||
float* out = NULL; // Output audio data
|
||||
@@ -125,6 +120,8 @@ static int filter_frame(struct af_instance *af, struct mp_audio *c)
|
||||
int ncho = l->nch; // Number of output channels
|
||||
register int j,k;
|
||||
|
||||
mp_audio_realloc_min(af->data, data->samples);
|
||||
|
||||
out = l->planes[0];
|
||||
// Execute panning
|
||||
// FIXME: Too slow
|
||||
@@ -140,15 +137,17 @@ static int filter_frame(struct af_instance *af, struct mp_audio *c)
|
||||
in+= nchi;
|
||||
}
|
||||
|
||||
talloc_free(c);
|
||||
af_add_output_frame(af, l);
|
||||
// Set output data
|
||||
c->planes[0] = l->planes[0];
|
||||
set_channels(c, l->nch);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Allocate memory and set function pointers
|
||||
static int af_open(struct af_instance* af){
|
||||
af->control=control;
|
||||
af->filter_frame = filter_frame;
|
||||
af->filter=filter;
|
||||
af_pan_t *s = af->priv;
|
||||
int n = 0;
|
||||
int j,k;
|
||||
|
||||
@@ -1,225 +0,0 @@
|
||||
/*
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <rubberband/rubberband-c.h>
|
||||
|
||||
#include "common/common.h"
|
||||
#include "af.h"
|
||||
|
||||
struct priv {
|
||||
RubberBandState rubber;
|
||||
double speed;
|
||||
struct mp_audio *pending;
|
||||
bool needs_reset;
|
||||
// Estimate how much librubberband has buffered internally.
|
||||
// I could not find a way to do this with the librubberband API.
|
||||
double rubber_delay;
|
||||
// command line options
|
||||
int opt_transients, opt_detector, opt_phase, opt_window,
|
||||
opt_smoothing, opt_formant, opt_pitch, opt_channels;
|
||||
};
|
||||
|
||||
static void update_speed(struct af_instance *af, double new_speed)
|
||||
{
|
||||
struct priv *p = af->priv;
|
||||
|
||||
p->speed = new_speed;
|
||||
rubberband_set_time_ratio(p->rubber, 1.0 / p->speed);
|
||||
}
|
||||
|
||||
static int control(struct af_instance *af, int cmd, void *arg)
|
||||
{
|
||||
struct priv *p = af->priv;
|
||||
|
||||
switch (cmd) {
|
||||
case AF_CONTROL_REINIT: {
|
||||
struct mp_audio *in = arg;
|
||||
struct mp_audio orig_in = *in;
|
||||
struct mp_audio *out = af->data;
|
||||
|
||||
in->format = AF_FORMAT_FLOATP;
|
||||
mp_audio_copy_config(out, in);
|
||||
|
||||
if (p->rubber)
|
||||
rubberband_delete(p->rubber);
|
||||
|
||||
int opts = p->opt_transients | p->opt_detector | p->opt_phase |
|
||||
p->opt_window | p->opt_smoothing | p->opt_formant |
|
||||
p->opt_pitch | p-> opt_channels |
|
||||
RubberBandOptionProcessRealTime;
|
||||
|
||||
p->rubber = rubberband_new(in->rate, in->channels.num, opts, 1.0, 1.0);
|
||||
if (!p->rubber) {
|
||||
MP_FATAL(af, "librubberband initialization failed.\n");
|
||||
return AF_ERROR;
|
||||
}
|
||||
|
||||
update_speed(af, p->speed);
|
||||
control(af, AF_CONTROL_RESET, NULL);
|
||||
|
||||
return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE;
|
||||
}
|
||||
case AF_CONTROL_SET_PLAYBACK_SPEED: {
|
||||
update_speed(af, *(double *)arg);
|
||||
return AF_OK;
|
||||
}
|
||||
case AF_CONTROL_RESET:
|
||||
if (p->rubber)
|
||||
rubberband_reset(p->rubber);
|
||||
talloc_free(p->pending);
|
||||
p->pending = NULL;
|
||||
p->rubber_delay = 0;
|
||||
return AF_OK;
|
||||
}
|
||||
return AF_UNKNOWN;
|
||||
}
|
||||
|
||||
static int filter_frame(struct af_instance *af, struct mp_audio *data)
|
||||
{
|
||||
struct priv *p = af->priv;
|
||||
|
||||
talloc_free(p->pending);
|
||||
p->pending = data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int filter_out(struct af_instance *af)
|
||||
{
|
||||
struct priv *p = af->priv;
|
||||
|
||||
while (rubberband_available(p->rubber) <= 0) {
|
||||
const float *dummy[MP_NUM_CHANNELS] = {0};
|
||||
const float **in_data = dummy;
|
||||
size_t in_samples = 0;
|
||||
if (p->pending) {
|
||||
if (!p->pending->samples)
|
||||
break;
|
||||
|
||||
// recover from previous EOF
|
||||
if (p->needs_reset) {
|
||||
rubberband_reset(p->rubber);
|
||||
p->rubber_delay = 0;
|
||||
}
|
||||
p->needs_reset = false;
|
||||
|
||||
size_t needs = rubberband_get_samples_required(p->rubber);
|
||||
in_data = (void *)&p->pending->planes;
|
||||
in_samples = MPMIN(p->pending->samples, needs);
|
||||
}
|
||||
|
||||
if (p->needs_reset)
|
||||
break; // previous EOF
|
||||
p->needs_reset = !p->pending; // EOF
|
||||
|
||||
rubberband_process(p->rubber, in_data, in_samples, p->needs_reset);
|
||||
p->rubber_delay += in_samples;
|
||||
|
||||
if (!p->pending)
|
||||
break;
|
||||
mp_audio_skip_samples(p->pending, in_samples);
|
||||
}
|
||||
|
||||
int out_samples = rubberband_available(p->rubber);
|
||||
if (out_samples > 0) {
|
||||
struct mp_audio *out =
|
||||
mp_audio_pool_get(af->out_pool, af->data, out_samples);
|
||||
if (!out)
|
||||
return -1;
|
||||
if (p->pending)
|
||||
mp_audio_copy_config(out, p->pending);
|
||||
|
||||
float **out_data = (void *)&out->planes;
|
||||
out->samples = rubberband_retrieve(p->rubber, out_data, out->samples);
|
||||
p->rubber_delay -= out->samples * p->speed;
|
||||
|
||||
af_add_output_frame(af, out);
|
||||
}
|
||||
|
||||
int delay_samples = p->rubber_delay;
|
||||
if (p->pending)
|
||||
delay_samples += p->pending->samples;
|
||||
af->delay = delay_samples / (af->data->rate * p->speed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void uninit(struct af_instance *af)
|
||||
{
|
||||
struct priv *p = af->priv;
|
||||
|
||||
if (p->rubber)
|
||||
rubberband_delete(p->rubber);
|
||||
talloc_free(p->pending);
|
||||
}
|
||||
|
||||
static int af_open(struct af_instance *af)
|
||||
{
|
||||
af->control = control;
|
||||
af->filter_frame = filter_frame;
|
||||
af->filter_out = filter_out;
|
||||
af->uninit = uninit;
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
#define OPT_BASE_STRUCT struct priv
|
||||
const struct af_info af_info_rubberband = {
|
||||
.info = "Pitch conversion with librubberband",
|
||||
.name = "rubberband",
|
||||
.open = af_open,
|
||||
.priv_size = sizeof(struct priv),
|
||||
.priv_defaults = &(const struct priv) {
|
||||
.speed = 1.0,
|
||||
.opt_pitch = RubberBandOptionPitchHighConsistency,
|
||||
.opt_transients = RubberBandOptionTransientsMixed,
|
||||
.opt_formant = RubberBandOptionFormantPreserved,
|
||||
},
|
||||
.options = (const struct m_option[]) {
|
||||
OPT_CHOICE("transients", opt_transients, 0,
|
||||
({"crisp", RubberBandOptionTransientsCrisp},
|
||||
{"mixed", RubberBandOptionTransientsMixed},
|
||||
{"smooth", RubberBandOptionTransientsSmooth})),
|
||||
OPT_CHOICE("detector", opt_detector, 0,
|
||||
({"compound", RubberBandOptionDetectorCompound},
|
||||
{"percussive", RubberBandOptionDetectorPercussive},
|
||||
{"soft", RubberBandOptionDetectorSoft})),
|
||||
OPT_CHOICE("phase", opt_phase, 0,
|
||||
({"laminar", RubberBandOptionPhaseLaminar},
|
||||
{"independent", RubberBandOptionPhaseIndependent})),
|
||||
OPT_CHOICE("window", opt_window, 0,
|
||||
({"standard", RubberBandOptionWindowStandard},
|
||||
{"short", RubberBandOptionWindowShort},
|
||||
{"long", RubberBandOptionWindowLong})),
|
||||
OPT_CHOICE("smoothing", opt_smoothing, 0,
|
||||
({"off", RubberBandOptionSmoothingOff},
|
||||
{"on", RubberBandOptionSmoothingOn})),
|
||||
OPT_CHOICE("formant", opt_formant, 0,
|
||||
({"shifted", RubberBandOptionFormantShifted},
|
||||
{"preserved", RubberBandOptionFormantPreserved})),
|
||||
OPT_CHOICE("pitch", opt_pitch, 0,
|
||||
({"quality", RubberBandOptionPitchHighQuality},
|
||||
{"speed", RubberBandOptionPitchHighSpeed},
|
||||
{"consistency", RubberBandOptionPitchHighConsistency})),
|
||||
OPT_CHOICE("channels", opt_channels, 0,
|
||||
({"apart", RubberBandOptionChannelsApart},
|
||||
{"together", RubberBandOptionChannelsTogether})),
|
||||
{0}
|
||||
},
|
||||
};
|
||||
@@ -14,20 +14,21 @@
|
||||
*
|
||||
* Copyright (c) 2007 Robert Juliano
|
||||
*
|
||||
* This file is part of mpv.
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -75,15 +76,15 @@ typedef struct af_scaletempo_s
|
||||
float ms_stride;
|
||||
float percent_overlap;
|
||||
float ms_search;
|
||||
#define SCALE_TEMPO 1
|
||||
#define SCALE_PITCH 2
|
||||
int speed_opt;
|
||||
short speed_tempo;
|
||||
short speed_pitch;
|
||||
} af_scaletempo_t;
|
||||
|
||||
static int fill_queue(struct af_instance *af, struct mp_audio *data, int offset)
|
||||
{
|
||||
af_scaletempo_t *s = af->priv;
|
||||
int bytes_in = (data ? mp_audio_psize(data) : 0) - offset;
|
||||
int bytes_in = mp_audio_psize(data) - offset;
|
||||
int offset_unchanged = offset;
|
||||
|
||||
if (s->bytes_to_slide > 0) {
|
||||
@@ -209,28 +210,21 @@ static void output_overlap_s16(af_scaletempo_t *s, void *buf_out,
|
||||
}
|
||||
}
|
||||
|
||||
static int filter(struct af_instance *af, struct mp_audio *data)
|
||||
// Filter data through filter
|
||||
static int filter(struct af_instance *af, struct mp_audio *data, int flags)
|
||||
{
|
||||
af_scaletempo_t *s = af->priv;
|
||||
|
||||
if (s->scale == 1.0) {
|
||||
af->delay = 0;
|
||||
af_add_output_frame(af, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int in_samples = data ? data->samples : 0;
|
||||
struct mp_audio *out = mp_audio_pool_get(af->out_pool, af->data,
|
||||
((int)(in_samples / s->frames_stride_scaled) + 1) * s->frames_stride);
|
||||
if (!out) {
|
||||
talloc_free(data);
|
||||
return -1;
|
||||
}
|
||||
if (data)
|
||||
mp_audio_copy_attributes(out, data);
|
||||
mp_audio_realloc_min(af->data,
|
||||
((int)(data->samples / s->frames_stride_scaled) + 1) * s->frames_stride);
|
||||
|
||||
int offset_in = fill_queue(af, data, 0);
|
||||
int8_t *pout = out->planes[0];
|
||||
int8_t *pout = af->data->planes[0];
|
||||
while (s->bytes_queued >= s->bytes_queue) {
|
||||
int ti;
|
||||
float tf;
|
||||
@@ -263,34 +257,13 @@ static int filter(struct af_instance *af, struct mp_audio *data)
|
||||
// output corresponding to some length of input can be decided and written
|
||||
// after receiving only a part of that input.
|
||||
af->delay = (s->bytes_queued - s->bytes_to_slide) / s->scale
|
||||
/ out->sstride / out->rate;
|
||||
/ af->data->sstride / af->data->rate;
|
||||
|
||||
out->samples = (pout - (int8_t *)out->planes[0]) / out->sstride;
|
||||
talloc_free(data);
|
||||
if (out->samples) {
|
||||
af_add_output_frame(af, out);
|
||||
} else {
|
||||
talloc_free(out);
|
||||
}
|
||||
data->planes[0] = af->data->planes[0];
|
||||
data->samples = (pout - (int8_t *)af->data->planes[0]) / af->data->sstride;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void update_speed(struct af_instance *af, float speed)
|
||||
{
|
||||
af_scaletempo_t *s = af->priv;
|
||||
|
||||
s->speed = speed;
|
||||
|
||||
double factor = (s->speed_opt & SCALE_PITCH) ? 1.0 / s->speed : s->speed;
|
||||
s->scale = factor * s->scale_nominal;
|
||||
|
||||
s->frames_stride_scaled = s->scale * s->frames_stride;
|
||||
s->frames_stride_error = MPMIN(s->frames_stride_error, s->frames_stride_scaled);
|
||||
|
||||
MP_VERBOSE(af, "%.3f speed * %.3f scale_nominal = %.3f\n",
|
||||
s->speed, s->scale_nominal, s->scale);
|
||||
}
|
||||
|
||||
// Initialization and runtime control
|
||||
static int control(struct af_instance *af, int cmd, void *arg)
|
||||
{
|
||||
@@ -302,9 +275,20 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
int nch = data->nch;
|
||||
int use_int = 0;
|
||||
|
||||
MP_VERBOSE(af, "%.3f speed * %.3f scale_nominal = %.3f\n",
|
||||
s->speed, s->scale_nominal, s->scale);
|
||||
|
||||
mp_audio_force_interleaved_format(data);
|
||||
mp_audio_copy_config(af->data, data);
|
||||
|
||||
if (s->scale == 1.0) {
|
||||
if (s->speed_tempo && s->speed_pitch)
|
||||
return AF_DETACH;
|
||||
af->delay = 0;
|
||||
af->mul = 1;
|
||||
return af_test_output(af, data);
|
||||
}
|
||||
|
||||
if (data->format == AF_FORMAT_S16) {
|
||||
use_int = 1;
|
||||
} else {
|
||||
@@ -314,10 +298,11 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
|
||||
s->frames_stride = srate * s->ms_stride;
|
||||
s->bytes_stride = s->frames_stride * bps * nch;
|
||||
s->frames_stride_scaled = s->scale * s->frames_stride;
|
||||
s->frames_stride_error = 0;
|
||||
af->mul = 1.0 / s->scale;
|
||||
af->delay = 0;
|
||||
|
||||
update_speed(af, s->speed);
|
||||
|
||||
int frames_overlap = s->frames_stride * s->percent_overlap;
|
||||
if (frames_overlap <= 0) {
|
||||
s->bytes_standing = s->bytes_stride;
|
||||
@@ -427,14 +412,17 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
return af_test_output(af, (struct mp_audio *)arg);
|
||||
}
|
||||
case AF_CONTROL_SET_PLAYBACK_SPEED: {
|
||||
double speed = *(double *)arg;
|
||||
if (s->speed_opt & SCALE_TEMPO) {
|
||||
if (s->speed_opt & SCALE_PITCH)
|
||||
if (s->speed_tempo) {
|
||||
if (s->speed_pitch)
|
||||
break;
|
||||
update_speed(af, speed);
|
||||
} else if (s->speed_opt & SCALE_PITCH) {
|
||||
update_speed(af, speed);
|
||||
break; // do not signal OK
|
||||
s->speed = *(double *)arg;
|
||||
s->scale = s->speed * s->scale_nominal;
|
||||
} else {
|
||||
if (s->speed_pitch) {
|
||||
s->speed = 1 / *(double *)arg;
|
||||
s->scale = s->speed * s->scale_nominal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return AF_OK;
|
||||
}
|
||||
@@ -458,12 +446,22 @@ static void uninit(struct af_instance *af)
|
||||
free(s->table_window);
|
||||
}
|
||||
|
||||
#define SCALE_TEMPO 1
|
||||
#define SCALE_PITCH 2
|
||||
|
||||
// Allocate memory and set function pointers
|
||||
static int af_open(struct af_instance *af)
|
||||
{
|
||||
af_scaletempo_t *s = af->priv;
|
||||
|
||||
af->control = control;
|
||||
af->uninit = uninit;
|
||||
af->filter_frame = filter;
|
||||
af->filter = filter;
|
||||
|
||||
s->speed_tempo = !!(s->speed_opt & SCALE_TEMPO);
|
||||
s->speed_pitch = !!(s->speed_opt & SCALE_PITCH);
|
||||
|
||||
s->scale = s->speed * s->scale_nominal;
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,20 +3,21 @@
|
||||
* Copyright (C) 2004 Alex Beregszaszi
|
||||
* based upon af_extrastereo.c by Pierre Lombard
|
||||
*
|
||||
* This file is part of mpv.
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -40,6 +41,9 @@ typedef struct af_sinesuppress_s
|
||||
double pos;
|
||||
}af_sinesuppress_t;
|
||||
|
||||
static int play_s16(struct af_instance* af, struct mp_audio* data, int f);
|
||||
//static struct mp_audio* play_float(struct af_instance* af, struct mp_audio* data);
|
||||
|
||||
// Initialization and runtime control
|
||||
static int control(struct af_instance* af, int cmd, void* arg)
|
||||
{
|
||||
@@ -50,7 +54,18 @@ static int control(struct af_instance* af, int cmd, void* arg)
|
||||
|
||||
mp_audio_copy_config(af->data, (struct mp_audio*)arg);
|
||||
mp_audio_set_num_channels(af->data, 1);
|
||||
mp_audio_set_format(af->data, AF_FORMAT_S16);
|
||||
#if 0
|
||||
if (((struct mp_audio*)arg)->format == AF_FORMAT_FLOAT)
|
||||
{
|
||||
af->data->format = AF_FORMAT_FLOAT;
|
||||
af->data->bps = 4;
|
||||
af->play = play_float;
|
||||
}// else
|
||||
#endif
|
||||
{
|
||||
mp_audio_set_format(af->data, AF_FORMAT_S16);
|
||||
af->filter = play_s16;
|
||||
}
|
||||
|
||||
return af_test_output(af,(struct mp_audio*)arg);
|
||||
}
|
||||
@@ -58,15 +73,9 @@ static int control(struct af_instance* af, int cmd, void* arg)
|
||||
return AF_UNKNOWN;
|
||||
}
|
||||
|
||||
static int play_s16(struct af_instance *af, struct mp_audio *data)
|
||||
// Filter data through filter
|
||||
static int play_s16(struct af_instance* af, struct mp_audio* data, int f)
|
||||
{
|
||||
if (!data)
|
||||
return 0;
|
||||
if (af_make_writeable(af, data) < 0) {
|
||||
talloc_free(data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
af_sinesuppress_t *s = af->priv;
|
||||
register int i = 0;
|
||||
int16_t *a = (int16_t*)data->planes[0]; // Audio data
|
||||
@@ -92,14 +101,37 @@ static int play_s16(struct af_instance *af, struct mp_audio *data)
|
||||
|
||||
MP_VERBOSE(af, "f:%8.2f: amp:%8.2f\n", s->freq, sqrt(s->real*s->real + s->imag*s->imag) / s->ref);
|
||||
|
||||
af_add_output_frame(af, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static struct mp_audio* play_float(struct af_instance* af, struct mp_audio* data)
|
||||
{
|
||||
af_sinesuppress_t *s = af->setup;
|
||||
register int i = 0;
|
||||
float *a = (float*)data->audio; // Audio data
|
||||
int len = data->len/4; // Number of samples
|
||||
float avg, l, r;
|
||||
|
||||
for (i = 0; i < len; i+=2)
|
||||
{
|
||||
avg = (a[i] + a[i + 1]) / 2;
|
||||
|
||||
/* l = avg + (s->mul * (a[i] - avg));
|
||||
r = avg + (s->mul * (a[i + 1] - avg));*/
|
||||
|
||||
a[i] = af_softclip(l);
|
||||
a[i + 1] = af_softclip(r);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Allocate memory and set function pointers
|
||||
static int af_open(struct af_instance* af){
|
||||
af->control=control;
|
||||
af->filter_frame = play_s16;
|
||||
af->filter=play_s16;
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
|
||||
+8
-14
@@ -1,20 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) 2002 Anders Johansson ajh@watri.uwa.edu.au
|
||||
*
|
||||
* This file is part of mpv.
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* This filter adds a sub-woofer channels to the audio stream by
|
||||
@@ -97,15 +98,9 @@ static int control(struct af_instance* af, int cmd, void* arg)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int filter_frame(struct af_instance *af, struct mp_audio *data)
|
||||
// Filter data through filter
|
||||
static int filter(struct af_instance* af, struct mp_audio* data, int flags)
|
||||
{
|
||||
if (!data)
|
||||
return 0;
|
||||
if (af_make_writeable(af, data) < 0) {
|
||||
talloc_free(data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct mp_audio* c = data; // Current working data
|
||||
af_sub_t* s = af->priv; // Setup for this instance
|
||||
float* a = c->planes[0]; // Audio data
|
||||
@@ -122,14 +117,13 @@ static int filter_frame(struct af_instance *af, struct mp_audio *data)
|
||||
IIR(x , s->w[1], s->q[1], a[i+ch]);
|
||||
}
|
||||
|
||||
af_add_output_frame(af, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Allocate memory and set function pointers
|
||||
static int af_open(struct af_instance* af){
|
||||
af->control=control;
|
||||
af->filter_frame = filter_frame;
|
||||
af->filter=filter;
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
|
||||
Loaded 100 of 500 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user