Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Please add support for auto-detecting 3D input format #1045

Closed
sre opened this issue Aug 28, 2014 · 20 comments
Closed

Please add support for auto-detecting 3D input format #1045

sre opened this issue Aug 28, 2014 · 20 comments

Comments

@sre
Copy link

@sre sre commented Aug 28, 2014

Hi,

The Matroska Container (*.mkv, *mk3d) has support for embedded 3D format specification. This information is exposed by ffmpeg (via metadata) and recently also by libav (via newly introduced stereo3d api [0]).

It would be nice if mpv would make use of the provided 3D information, so that the user only has to specify the 3D output format. Apart from that it would be nice if the default output format for 3D content could be specified in the configuration file.

-- Sebastian

[0] https://bugzilla.libav.org/show_bug.cgi?id=728

@ghost
Copy link

@ghost ghost commented Aug 29, 2014

  1. Are there any files like this in the wild?
  2. What exactly should be supported?
  3. Can you post a sample file that demonstrates all what is required (but not more)?
@ghost ghost added the enhancement label Aug 29, 2014
@sre
Copy link
Author

@sre sre commented Aug 29, 2014

Are there any files like this in the wild?

I don't know. I have files, which use the proper tags and I add the tags to files missing them. IMHO metadata should be part of the file.

What exactly should be supported?

Auto-Detection of 3D flags, which currently must always be set with mpv's stereo3d video filter.

Can you post a sample file that demonstrates all what is required (but not more)?

I currently have no small sample file with 3d content available. Is there some pool of sample files available? One can simply add the 3d flag in mkv files using mkvmerge's "--stereo-mode" option.

@ghost
Copy link

@ghost ghost commented Aug 29, 2014

Auto-Detection of 3D flags, which currently must always be set with mpv's stereo3d video filter.

So that sounds like you want automatic filter insertion to convert the 3D stuff back to "normal" video? Actually, I have no clue how this 3D stuff works (it's an expensive fad anyway), so I don't know what the result should look like. But it's probably easily possible to do this.

I currently have no small sample file with 3d content available.

You could create a small sample from a bigger file with mkvmerge and --split.

Is there some pool of sample files available?

Not really. We have https://github.com/mpv-player/random-stuff where we sometimes dump test files. There's also http://samples.ffmpeg.org/ .

@sre
Copy link
Author

@sre sre commented Aug 29, 2014

So that sounds like you want automatic filter insertion to convert the 3D stuff back to "normal" video? Actually, I have no clue how this 3D stuff works (it's an expensive fad anyway), so I don't know what the result should look like. But it's probably easily possible to do this.

Right. I have some files flying around, which have 3d data and I want mono output. Basically there are a couple of possible 3D formats and mpv filters can be used to convert from one format to another one. For example the following mpv video filter converts from "3D data, side by side, half width" to "mono left": stereo3d=sbs2l:ml

Obviously mpv cannot know the output format, that I need/want, but it can autodetect the 3D input format from the file's metadata. Since the 3D output format is more or less a question of the hardware capabilities it would make sense to have a configuration option for the default 3D output format (so that the video filter can be omitted completely in most cases).


So here is a 10MB example file (based on Surfcup.mp4 from samples.ffmpeg.org), which is encoded side-by-side, half width. I added the stereo-mode metadata in the mkv file, so the "sbs2l" information from the lower command could be automatically detected from the file's metadata:

mpv --vf stereo3d=sbs2l:ml http://www.elektranox.org/test.mk3d

@ghedo
Copy link
Member

@ghedo ghedo commented Aug 30, 2014

So, if I understand things correctly, something like a default "auto" input format for the stereo3d vf that reads the file tags and autodetects the video 3d format would work for you? So you'd use something like mpv --vf=stereo3d=auto:ml <file> or mpv --vf=stereo3d=out=ml <file>, etc...

FWIW, libav has support for reading 3d data from matroska and converting it to stereo3d side data (AV_PKT_DATA_STEREO3D), so that could be used like we do with the replaygain side data in af_volume.

@ghost
Copy link

@ghost ghost commented Aug 30, 2014

@sre: thanks for the sample. It looks pretty easy to support it (though mapping the right modes will probably require additional testing). The question is whether there are more complex cases that wouldn't be easy to handle. I know that Matroska has at least one 3D feature which is not easy to handle at all, and which would require changing everything. OTOH, fortunately apparently unused yet.

FWIW, libav has support for reading 3d data from matroska and converting it to stereo3d side data (AV_PKT_DATA_STEREO3D), so that could be used like we do with the replaygain side data in af_volume.

Note that mpv has its own mkv demuxer.

@sre
Copy link
Author

@sre sre commented Aug 30, 2014

So, if I understand things correctly, something like a default "auto" input format for the stereo3d vf that reads the file tags and autodetects the video 3d format would work for you? So you'd use something like mpv --vf=stereo3d=auto:ml or mpv --vf=stereo3d=out=ml , etc...

Yes, that would be nice. I guess the filter should be ignored if auto does not find 3D metadata. In that case 3D files and 2D files can be played using the same command. So basically the following should work:

$ grep vf .mpv/config
vf=stereo3d=auto:ml
$ mpv some-normal-file-without-3d-content.mkv
$ mpv some-file-with-3d-content.mkv

The same syntax could be useful for guys with 3D capable hardware:

$ grep vf .mpv/config
vf=stereo3d=auto:irl
$ mpv some-normal-file-without-3d-content.mkv
// plays as 2D file
$ mpv some-file-with-3d-content.mkv
// plays as 3D file in irl mode

@sre: thanks for the sample. It looks pretty easy to support it (though mapping the right modes will probably require additional testing).

Right, it shouldn't be that complicated.

The question is whether there are more complex cases that wouldn't be easy to handle. I know that Matroska has at least one 3D feature which is not easy to handle at all, and which would require changing everything. OTOH, fortunately apparently unused yet.

One can also specify, that the video data is anaglyph based. That is stored in another property.
But that kind of source material cannot be transformed into other formats. So probably no very important for mpv.

Apart from that one can put left eye and right eye into different video streams. I don't think that is used in the wild, though.

FWIW, libav has support for reading 3d data from matroska and converting it to stereo3d side data (AV_PKT_DATA_STEREO3D), so that could be used like we do with the replaygain side data in af_volume.

Note that mpv has its own mkv demuxer.

oh, I didn't know that.

ghost pushed a commit that referenced this issue Aug 30, 2014
wm4
This inserts an automatic conversion filter if a Matroska file is marked
as 3D (StereoMode element). The basic idea is similar to video rotation
and colorspace handling: the 3D mode is added as a property to the video
params. Depending on this property, a video filter can be inserted.

As of this commit, extending mp_image_params is actually completely
unnecessary - but the idea is that it will make it easier to integrate
with VOs supporting stereo 3D mogrification. Although vo_opengl does
support some stereo rendering, it didn't support the mode my sample file
used, so I'll leave that part for later.

Not that most mappings from Matroska mode to vf_stereo3d mode are
probably wrong, and some are missing.

Assuming that Matroska modes, and vf_stereo3d in modes, and out modes
are all the same might be an oversimplification - we'll see.

See issue #1045.
@ghost
Copy link

@ghost ghost commented Aug 30, 2014

I did something.

@sre
Copy link
Author

@sre sre commented Aug 31, 2014

👍 That's exactly the behaviour is tried to describe. Thanks!

@sre sre closed this Aug 31, 2014
@sre
Copy link
Author

@sre sre commented Aug 31, 2014

I just tested with some more videos and ab2l was incorrectly detected as abl.


After looking at the patch I can say, that the solution is incomplete. Probably for bandwidth reasons someone thought it would be a good idea to have a format side-by-side, where each frame is saved with half width. There is also a less creepy format, which stores the frames side-by-side in full width format, though. The same rules apply to top-bottom style (so there is full-height and half-height).

As a result the following formats exist:

  • side-by-side, left eye first, full-width
  • side-by-side, left eye first, half-width
  • side-by-side, right eye first, full-width
  • side-by-side, right eye first, half-width
  • top-bottom, left eye first, full-height
  • top-bottom, left eye first, half-height
  • top-bottom, right eye first, full-height
  • top-bottom, right eye first, half-height

Your patch currently maps Matroska's side-by-side definitions to half-width and Matroska's top-bottom definitions to full-width.

The Matroska specification uses a slightly more complicated method than mpv to model half-width vs full-width. The StereoMode property does not contain any information about that. Instead the properties "DisplayWidth" and "DisplayHeight" are supposed to be used.

The idea is, that the properties "PixelWidth" + "PixelHeight" contain the information about the raw image data (e.g. 3840x1080) and "DisplayWidth" + "DisplayHeight" contain the information about the merged image data (e.g. 1920x1080).

If half-width / half-height style is used PixelWidth equals DisplayWidth and PixelHeight equals DisplayHeight.

@sre sre reopened this Aug 31, 2014
ghost pushed a commit that referenced this issue Aug 31, 2014
There is no proper and exact spec (Matroska tradition), so we probably
have to rely on guessing for this.

Also see issue #1045.
@ghost
Copy link

@ghost ghost commented Aug 31, 2014

Some more guesswork in git.

@sre
Copy link
Author

@sre sre commented Aug 31, 2014

OK, with that change all my files work (all of them are half-width or half-height). IMHO the solution for full-width / full-height is not very elegant (*), but it seems to work, too (testfile: http://www.elektranox.org/test2.mk3d).

(*) I think the video is first squeezed together because of the display width/height property and then stretched again due to the half-width filter. Properly implemented it would be enough cut the image in the middle without any scaling being involved at all.

There is no proper and exact spec (Matroska tradition), so we probably have to rely on guessing for this.

You may want to read this: http://www.matroska.org/technical/specs/notes.html#3D

@ghost
Copy link

@ghost ghost commented Aug 31, 2014

(*) I think the video is first squeezed together because of the display width/height property and then stretched again due to the half-width filter. Properly implemented it would be enough cut the image in the middle without any scaling being involved at all.

Not sure what you mean. I don't think the video is scaled anywhere with this mode.

You may want to read this: http://www.matroska.org/technical/specs/notes.html#3D

Yes, that is the "spec", but it's not very precise. (Although granted, the half-width thing can probably be deduced from this.)

@sre
Copy link
Author

@sre sre commented Aug 31, 2014

(*) I think the video is first squeezed together because of the display width/height property and then stretched again due to the half-width filter. Properly implemented it would be enough cut the image in the middle without any scaling being involved at all.

Not sure what you mean. I don't think the video is scaled anywhere with this mode.

Currently a full-width side-by-side video is also detected as a half-width side-by-side video:

$ mpv "http://www.elektranox.org/test2.mk3d"
...
Opening video filter: [stereo3d in=sbs2l out=mono]
Using conversion filter.
Using conversion filter.
VO: [xv] 960x540 => 960x540 yuv420p
...

So I assumed, that the video width is doubled by the stereo3d filter and halved by the display width property.

@ghost
Copy link

@ghost ghost commented Aug 31, 2014

That specific video you posted is literally right left and right frame, as you can see with --video-stereo-mode=none --video-aspect=0. I don't think there's anything scaled.

Not sure why this shows up in your log though:

Using conversion filter.

Other filters in your filter chain?

@sre
Copy link
Author

@sre sre commented Aug 31, 2014

Compare those two test files:

Both of them are currently detected as sbs2l (side-by-side, half width). So the stereo3d filter splits the image and doubles the width. This is OK for the half-width video, but obviously wrong for the full-width video.

Now the aspect ratio is calculated from the video width/height information. Since the aspect of the half-width video already matches the calculated aspect ratio nothing happens here. For the full-width video the aspect ratio does not match (its twice as wide, as it should be). Thus the video is rescaled to normal width.

Not sure why this shows up in your log though:

Using conversion filter.

Other filters in your filter chain?

One of them is because I use XV for video output, the other one is the stereo3d filter.

@ghost
Copy link

@ghost ghost commented Aug 31, 2014

This is OK for the half-width video, but obviously wrong for the full-width video.

Well, I don't know, both look correct to me.

One of them is because I use XV for video output, the other one is the stereo3d filter.

You're probably not using libavfilter. It seems Libav doesn't have vf_stereo3d, so mpv uses the old MPlayer implementation, which behaves slightly differently. For test2.mk3d, it shows 960x540 => 1920x1080, which is strange, but harmless. The video isn't actually scaled twice. In my tests without libavfilter, both test files look correct to me, though.

Also, why are you using xv? In combination with not using libavfilter, the video is actually converted to YUV and then to RGB and then back to YUV. Must be very slow and probably has quality issues.

@sre
Copy link
Author

@sre sre commented Aug 31, 2014

This is OK for the half-width video, but obviously wrong for the full-width video.

Well, I don't know, both look correct to me.

I never said, that the result would be a problem. It looks correct.

One of them is because I use XV for video output, the other one is the stereo3d filter.

You're probably not using libavfilter. It seems Libav doesn't have vf_stereo3d, so mpv uses the old MPlayer implementation, which behaves slightly differently.

Yes, my system provides libav instead of ffmpeg.

For test2.mk3d, it shows 960x540 => 1920x1080, which is strange, but harmless. The video isn't actually scaled twice. In my tests without libavfilter, both test files look correct to me, though.

So the double scaling is optimized out at some point? I can see, that mpv --video-aspect=0 "http://www.elektranox.org/test2.mk3d" results in wrong aspect ratio (doubled width) and that mpv --video-stereo-mode=none "http://www.elektranox.org/test2.mk3d" results in wrong aspect ratio.

Also, why are you using xv? In combination with not using libavfilter, the video is actually converted to YUV and then to RGB and then back to YUV. Must be very slow and probably has quality issues.

I took this over from my mplayer config. I wasn't aware (until now), that xv has limited input formats. I have switched to opengl output (the error message about missing OpenGL 3 support is a bit anoying, though).

@ghost
Copy link

@ghost ghost commented Aug 31, 2014

So the double scaling is optimized out at some point?

No, this are just aspect ratio hints, so there's no scaling. The aspect ratio hint just causes the VO to do scaling differently on final display. I don't know why 3D stuff sets an aspect ratio, but since vf_stereo3d apparently handles it correctly, there's no reason to worry.

Though, since the builtin stereo3d filter works in RGB only, there's some quality and performance loss to expect. The libavfilter filter seems to be able to work with YUV, though.

I took this over from my mplayer config.

Always a bad idea.

@sre
Copy link
Author

@sre sre commented Aug 31, 2014

No, this are just aspect ratio hints, so there's no scaling. The aspect ratio hint just causes the VO to do scaling differently on final display. I don't know why 3D stuff sets an aspect ratio, but since vf_stereo3d apparently handles it correctly, there's no reason to worry.

ok.

Though, since the builtin stereo3d filter works in RGB only, there's some quality and performance loss to expect. The libavfilter filter seems to be able to work with YUV, though.

I will file a feature request in the libav bugtracker.

@sre sre closed this Aug 31, 2014
TimothyGu pushed a commit to FFmpeg/FFmpeg that referenced this issue Jun 23, 2016
Based on 8e75771

See mpv-player/mpv#1045 for mk3d
elektranox.org samples.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants