mpv-player / mpv

🎥 Command line video player
https://mpv.io
Other
28.21k stars 2.89k forks source link

[Feature request] arbitrary rotation #3434

Closed rr- closed 8 years ago

rr- commented 8 years ago

mpv version and platform

mpv git-e02cb67 (C) 2000-2016 mpv/MPlayer/mplayer2 projects built on Thu Aug 18 07:57:49 CEST 2016
Linux tornado 4.7.0-1-ARCH #1 SMP PREEMPT Mon Aug 8 22:05:58 CEST 2016 x86_64 GNU/Linux

Description

Currently, both vf set rotate and set video-rotate work only with multiples of 90 degrees. It would be nice to have arbitrary rotation.

Use case

There's certain genre of games called visual novels and for reasons beyond me, the artists very often draw scenes in rotated perspective like this:

I deal with such images a lot. Arbitrary rotation would let us temporarily straighten up these images without altering the files.

Possible implementation

I can see this implemented with a shader, like the transparency grid is. Proof of concept:

float deg2rad = 0.01745329251994329577;

vec4 sample_pixel(sampler2D tex, vec2 pos, vec2 tex_size)
{
    float angle = 45 * deg2rad;
    vec2 rot;
    rot.x = sin(angle);
    rot.y = cos(angle);
    vec2 rotatedPos = vec2(
        0.5 + (pos.x - 0.5) * rot.y + (pos.y - 0.5) * rot.x,
        0.5 + (pos.y - 0.5) * rot.y - (pos.x - 0.5) * rot.x);
    if (rotatedPos.x < 0 || rotatedPos.x > 1 || rotatedPos.y < 0 || rotatedPos.y > 1) {
        return vec4(0);
    }
    return texture(tex, rotatedPos).rgba;
}

20160819_075022_rbv

Full shader should probably scale down the frame so that it isn't cropped, and take care of viewport's AR.

haasn commented 8 years ago

Ideally this would be done by just adjusting the gl_transform, in which case the upscaler would take care of it for free. In theory the code should support it already (in particular, the hook mechanism should - it could be extended to allow for a rotation of the texture).

If you're feeling adventurous you could try editing compute_src_transform in video/out/opengl/video.c to add your own custom rotational transform on top of &transform, e.g.

    ...
    struct gl_transform rotation = {...}; // use wikipedia
    gl_transform_trans(rotation, &transform);

    *tr = transform;
}
ghost commented 8 years ago

There's also a lavfi filter for this: --vf=lavfi=[rotate=45].

rr- commented 8 years ago

It doesn't work too good (it crops the video, and accepts angle in radians rather than degrees which isn't very intuitive)

rr- commented 8 years ago

I just saw 4e3663a and it seems to work great

ghost commented 8 years ago

So if anyone wants to implement this for GL...

haasn commented 8 years ago

Well doing it in GL would be faster and higher-quality, but I'm not sure if @rr- cares?

rr- commented 8 years ago

I'm totally fine with the current implementation - it seems to take care of everything (AR, cropping, video size etc.)

ghost commented 8 years ago

Good enough to close this.

stalkerGH commented 7 years ago

Is it possible to add key bindings for arbitrary fluent rotation? I work with circular images and movies (diameter of circle = height of screen) so I'd like to rotate it with some key. How to achieve that? I'm quite new to MPV and Lua scripts but have some base.

rr- commented 7 years ago

I use this:

scripts/rotater.lua

function rotate(number)
    local rotation = mp.get_property_number('video-rotate')
    rotation = rotation + number
    rotation = rotation + 360
    rotation = rotation % 360
    mp.set_property('video-rotate', rotation)
end

mp.register_script_message('rotate', rotate)

and then in input.conf:

alt+left            script-message-to rotater rotate -45
alt+right           script-message-to rotater rotate 45
alt+shift+left      script-message-to rotater rotate -1
alt+shift+right     script-message-to rotater rotate 1
stalkerGH commented 7 years ago

@rr- thank you for fast reaction! When I'm rotating the image (movie) degree after degree, it is gradually cropped because image/movie is square. If I understand it properly, commit https://github.com/mpv-player/mpv/commit/4e3663a2da5da33231ced7ae513c2a9017cd4298 fix it, right? How can I check if this commit is implemented in my MPV installation? I'm using Ubuntu 16.10, MPV installed from mc3man/mpv-tests PPA.

Edit: commit should be included as I see in https://github.com/mpv-player/mpv/releases/tag/v0.20.0 (Fixes and minor enhancements).

rr- commented 7 years ago

Hmm, on my mpv version it doesn't get cropped:

20170124_234730_ydg

mpv git-0067d1dbe (C) 2000-2016 mpv/MPlayer/mplayer2 projects
 built on Sun Jan  1 11:58:48 CET 2017
ffmpeg library versions:
   libavutil       55.43.100
   libavcodec      57.70.100
   libavformat     57.61.100
   libswscale      4.3.101
   libavfilter     6.68.100
   libswresample   2.4.100
ffmpeg version: N-82927-gc6c888e996
stalkerGH commented 7 years ago

OK, you're right. Cropping is not exactly what is going on - image is rotated but it is decreasing in size and then increasing - like in attached screenshots:

Normal orientation: mpv-shot0002

Rotated: mpv-shot0001

I would like to rotate only circle, with fixed diameter. Is there some function or script hidden in MPV to achieve my goal?

My MPV version:

mpv 0.23.0 (C) 2000-2016 mpv/MPlayer/mplayer2 projects built on Sun Jan 15 17:32:50 UTC 2017 ffmpeg library versions: libavutil 55.43.100 libavcodec 57.72.100 libavformat 57.62.100 libswscale 4.3.101 libavfilter 6.69.100 libswresample 2.4.100 ffmpeg version: git-2017-01-14-0ba0187

rr- commented 7 years ago

Since the image canvas is technically square, the image size is increased so that the corners are still visible after rotation (then it's scaled down to fit within the screen boundaries). You should either crop the video in the LUA script to the original size, or zoom it in according to some math. Either way I don't think there's a built-in function for this.

ghost commented 7 years ago

You could probably use --video-unscaled, and the manually add scaling with another option.

stalkerGH commented 7 years ago

@rr- "crop the video in the LUA script to the original size" - do you know if such script exist?

rr- commented 7 years ago

@stalkerGH no but it should be easy to write one yourself; I can write it once I get home

stalkerGH commented 7 years ago

@rr- It would be great, I'm total lame on Lua scripting...

haasn commented 7 years ago

Aaw, nobody wants to play around with rotation matrices in vo_opengl? :(

It would be so much prettier, faster and higher quality than these CPU-transforms. But I'm too preoccupied with other things