Commit Graph

117 Commits

Author SHA1 Message Date
wm4 26d25d567f vaapi: properly set hw_subfmt field with new decode API
This fixes direct rendering with hwdec_vaegl.c.

The code duplication between update_image_params() and
mp_image_copy_fields_from_av_frame() is quite annoying,
bit will have to be resolved in another commit.
2017-01-12 13:58:28 +01:00
wm4 b1c0bbe8b8 video: use demuxer-signaled duration for last video frame
Helps with gif, probably does unwanted things with other formats.

This doesn't handle --end quite correctly, but this could be added
later.

Fixes #3924.
2016-12-21 18:18:24 +01:00
wm4 3eceac2eab Remove compatibility things
Possible with bumped FFmpeg/Libav.

These are just the simple cases.
2016-12-07 19:53:11 +01:00
wm4 8f1ec91b45 mp_image: dump all mp_colorspace members in verbose logging
Also extend the default buffer size for formatting this string, because
it can get too damn long.
2016-11-08 14:19:26 +01:00
wm4 c245d04c37 mp_image: fix clearing to black with p010 format
Using vf_expand (which uses mp_image_clear()) with p010 cleared chroma
to green instead.
2016-09-29 16:12:58 +02:00
wm4 85488f6892 video: change hw_subfmt meaning
The hw_subfmt field roughly corresponds to the field
AVHWFramesContext.sw_format in ffmpeg. The ffmpeg one is of the type
AVPixelFormat (instead of the underlying hardware format), so it's a
good idea to switch to this too for preparation.

Now the hw_subfmt field is an mp_imgfmt instead of an opaque/API-
specific number. VDPAU and Direct3D11 already used mp_imgfmt, but
Videotoolbox and VAAPI had to be switched.

One somewhat user-visible change is that the verbose log will now always
show the hw_subfmt as image format, instead of as nonsensical number.

(In the end it would be good if we could switch to AVHWFramesContext
completely, but the upstream API is incomplete and doesn't cover
Direct3D11 and Videotoolbox.)
2016-07-15 13:04:17 +02:00
Niklas Haas 923e3c7b20 vo_opengl: generalize HDR tone mapping mechanism
This involves multiple changes:

1. Brightness metadata is split into nominal peak and signal peak.

For a quick and dirty explanation: nominal peak is the brightest value
that your color space can represent (i.e. the brightness of an encoded
1.0), and signal peak is the brightest value that actually occurs in
the video (i.e. the brightest thing that's displayed).

2. vo_opengl uses a new decision logic to figure out the right nom_peak
and sig_peak for all situations. It also does a better job of picking
the right target gamut/colorspace to use for the OSD. (Which still is
and still should be treated as sRGB). This change in logic also
fixes #3293 en passant.

3. Since it was growing rapidly, the logic for auto-guessing / inferring
the right colorimetry configuration (in pass_colormanage) was split from
the logic for actually performing the adaptation (now pass_color_map).

Right now, the new logic doesn't do a whole lot since HDR metadata is
still ignored (but not for long).
2016-07-03 19:42:52 +02:00
Niklas Haas d81fb97f45 mp_image: split colorimetry metadata into its own struct
This has two reasons:

1. I tend to add new fields to this metadata, and every time I've done
so I've consistently forgotten to update all of the dozens of places in
which this colorimetry metadata might end up getting used. While most
usages don't really care about most of the metadata, sometimes the
intend was simply to “copy” the colorimetry metadata from one struct to
another. With this being inside a substruct, those lines of code can now
simply read a.color = b.color without having to care about added or
removed fields.

2. It makes the type definitions nicer for upcoming refactors.

In going through all of the usages, I also expanded a few where I felt
that omitting the “young” fields was a bug.
2016-07-03 19:42:52 +02:00
Niklas Haas f3b6966d14 vo_opengl: implement the Panasonic V-Log function
User request and not that hard. Closes #3157.

Note that FFmpeg doesn't support this and there's no signalling in HEVC
etc., so the only way users can access it is by using vf_format
manually.

Mind: This encoding uses full range values, not TV range.
2016-06-28 19:48:29 +02:00
Niklas Haas 45c3e0f0d0 vo_opengl: refactor HDR mechanism
Instead of doing HDR tone mapping on an ad-hoc basis inside
pass_colormanage, the reference peak of an image is now part of the
image params (alongside colorspace, gamma, etc.) and tone mapping is
done whenever peak_src != peak_dst.

To get sensible behavior when mixing HDR and SDR content and displays,
target-brightness is a generic filler for "the assumed brightness of SDR
content".

This gets rid of the weird display_scaled hack, sets the framework
for multiple HDR functions with difference reference peaks, and allows
us to (in a future commit) autodetect the right source peak from
the HDR metadata.

(Apart from metadata, the source peak can also be controlled via
vf_format. For HDR content this adjusts the overall image brightness,
for SDR content it's like simulating a different exposure)
2016-05-30 20:17:33 +02:00
wm4 4853eca8c6 mp_image: properly communicate aspect ratio through AVFrame
No idea why this wasn't done before. In particular, this fixes playing
anamorphic video through --lavfi-complex.
2016-05-30 19:12:41 +02:00
wm4 079f67268f mp_image: don't reset pixel aspect with mp_image_set_size()
No reason to do so. See also commit 240ba92b.

Since now many mp_images will never have a pixel aspect ratio set,
redefine a 0/0 aspect ratio to "undefined" instead invalid. This also
brings it more in line with how decoder vs. container aspect ratios are
handled.

Most callers seem to be fine with the new behavior.

mp_image_params_valid() in particular has to be adjusted, or some things
stop working due to mp_images not becoming valid after setting size and
format.
2016-05-30 19:07:22 +02:00
wm4 240ba92bed mp_image: don't lose pixel aspect ratio when setting format
This is quite unexpected. It's caused by mp_image_set_size(), which is
used to update certain fields which can be format-dependent, but which
is actually also supposed to reset the pixel aspect ratio.
2016-05-29 19:00:55 +02:00
wm4 021cb2c387 mp_image: allow passing NULL to mp_image_new_custom_ref()
A minor simplification. Most callers don't need this, and there's no
good reason why the caller should provide an "initializer" like this.
(This function calls mp_image_new_dummy_ref(), which has no reason
for an initializer either.)
2016-04-25 11:28:49 +02:00
wm4 050b17ca9c mp_image: make mp_image_copy_fields_* private
Future code should always use mp_image_{to,from}_av_frame(). Everything
else is way too messy and fragile.
2016-04-15 15:48:02 +02:00
wm4 d04aa5ef4e mp_image: add mp_image_to_av_frame()
What mp_image_to_av_frame_and_unref() should have been. (The _unref
variant is still useful though.)
2016-04-15 15:33:53 +02:00
wm4 e6cdfdfa74 mp_image: simplify mp_image_steal_data()
Why was this so complex.
2016-04-15 15:31:23 +02:00
wm4 bbaedfd0c5 mp_image: pass through AVHWFramesContext
In both directions.
2016-04-15 15:07:02 +02:00
wm4 f34d086cb9 mp_image: introduce a hw_subfmt field
For hwaccel formats, mp_image will merely point to a hardware surface
handle. In these cases, the mp_image_params.imgfmt field describes the
format insufficiently, because it mostly only describes the type of the
hardware format, not its underlying format.

Introduce hw_subfmt to describe the underlying format. It makes sense to
use it with most hwaccels, though for now it will be used with the
following commit only.
2016-04-07 18:47:32 +02:00
wm4 1cfcc1e1d5 mp_image: force display size to at least 1x1
Don't allow rounding to let it underflow to 0. 0 width or height is
simply not allowed and could cause problems otherwhere.

Indirectly fixes CID 1350057, which complains about not checking the
resulting output size values before using it in divisions.
2016-02-12 16:04:26 +01:00
wm4 d2942f1bcd mp_image: copy dts as part of mp_image attributes too
Fixes DTS handling with certain container formats broken in commit
b53cb8de (when using vaapi-copy or dxva2-copy).
2016-01-28 11:23:16 +01:00
Dmitrij D. Czarkoff ea442fa047 mpv_talloc.h: rename from talloc.h
This change helps avoiding conflict with talloc.h from libtalloc.
2016-01-11 21:05:55 +01:00
wm4 0a0bb9059f video: switch from using display aspect to sample aspect
MPlayer traditionally always used the display aspect ratio, e.g. 16:9,
while FFmpeg uses the sample (aka pixel) aspect ratio.

Both have a bunch of advantages and disadvantages. Actually, it seems
using sample aspect ratio is generally nicer. The main reason for the
change is making mpv closer to how FFmpeg works in order to make life
easier. It's also nice that everything uses integer fractions instead
of floats now (except --video-aspect option/property).

Note that there is at least 1 user-visible change: vf_dsize now does
not set the display size, only the display aspect ratio. This is
because the image_params d_w/d_h fields did not just set the display
aspect, but also the size (except in encoding mode).
2015-12-19 20:45:36 +01:00
wm4 ee63c9c210 video: replace vf_format outputlevels option with global option
The vf_format suboption is replaced with --video-output-levels (a global
option and property). In particular, the parameter is removed from
mp_image_params. The mechanism is moved to the "video equalizer", which
also handles common video output customization like brightness and
contrast controls.

The new code is slightly cleaner, and the top-level option is slightly
more user-friendly than as vf_format sub-option.
2015-09-29 21:12:26 +02:00
wm4 0ae8aebb89 video: refactor GPU memcpy usage
Make the GPU memcpy from the dxva2 code generally useful to other parts
of the player.

We need to check at configure time whether SSE intrinsics work at all.
(At least in this form, they won't work on clang, for example. It also
won't work on non-x86.)

Introduce a mp_image_copy_gpu(), and make the dxva2 code use it. Do some
awkward stuff to share the existing code used by mp_image_copy(). I'm
hoping that FFmpeg will sooner or later provide a function like this, so
we can remove most of this again. (There is a patch, bit it's stuck in
limbo since forever.)

All this is used by the following commit.
2015-09-25 19:18:16 +02:00
wm4 d2c05cb559 mp_image: fix vf_vdpaupp references
Some code called by vf_vdpaupp.c calls mp_image_new_custom_ref(), but
out of convenience doesn't reset the buffers. Make this behavior ok.
(The assert() was there to catch usage errors, but the same error could
already happen before the refcount changes were made, so the check is
not overly helpful.)

Fixes #2115.
2015-07-08 14:48:17 +02:00
wm4 7b9d726588 video: replace our own refcounting with libavutil's
mpv had refcounted frames before libav*, so we were not using
libavutil's facilities. Change this and drop our own code.

Since AVFrames are not actually refcounted, and only the image data
they reference, the semantics change a bit. This affects mainly
mp_image_pool, which was operating on whole images instead of buffers.
While we could work on AVBufferRefs instead (and use AVBufferPool),
this doesn't work for use with hardware decoding, which doesn't
map cleanly to FFmpeg's reference counting. But it worked out. One
weird consequence is that we still need our custom image data
allocation function (for normal image data), because AVFrame's uses
multiple buffers.

There also seems to be a timing-dependent problem with vaapi (the
pool appears to be "leaking" surfaces). I don't know if this is a new
problem, or whether the code changes just happened to cause it more
often. Raising the number of reserved surfaces seemed to fix it, but
since it appears to be timing dependent, and I couldn't find anything
wrong with the code, I'm just going to assume it's not a new bug.
2015-07-05 23:56:00 +02:00
wm4 34b223d730 mp_image: make image writeable before overwriting palette
This is an obscure but theoretically possible bug.
2015-07-05 23:55:47 +02:00
wm4 1419aac22a mp_image: remove some unused interlacing flags
MP_IMGFIELD_TOP/MP_IMGFIELD_BOTTOM were completely unused, and
MP_IMGFIELD_ORDERED was always set (even though vf_vdpaupp.c strangely
checked for the latter).
2015-04-23 22:06:14 +02:00
Marcin Kurczewski f43017bfe9 Update license headers
Signed-off-by: wm4 <wm4@nowhere>
2015-04-13 12:10:01 +02:00
wm4 37a71e57d4 mp_image: remove redundant flags field
Because gcc (and clang) is a goddamn PITA and unnecessarily warns if
the universal initializer for structs is used (like mp_image x = {})
and the first member of the struct is also a struct, move the w/h
fields to the top.
2015-04-10 21:06:25 +02:00
wm4 41151122e7 mp_image: remove redundant chroma_x/y_shift fields 2015-04-10 21:02:16 +02:00
wm4 b3495d9ccf mp_image: remove redundant plane_w/h fields
Seems relatively painful in this case, but they are morally wrong.
2015-04-10 20:58:26 +02:00
wm4 8fe640c47d mp_image: fix build 2015-04-09 21:46:28 +02:00
wm4 27715b7dd1 video: move colorspace overrides to vf_format, simplify
Remove the colorspace-related top-level options, add them to vf_format.
They are rather obscure and not needed often, so it's better to get them
out of the way. In particular, this gets rid of the semi-complicated
logic in command.c (most of which was needed for OSD display and the
direct feedback from the VO). It removes the duplicated color-related
name mappings.

This removes the ability to write the colormatrix and related
properties. Since filters can be changed at runtime, there's no loss of
functionality, except that you can't cycle automatically through the
color constants anymore (but who needs to do this).

This also changes the type of the mp_csp_names and related variables, so
they can directly be used with OPT_CHOICE. This probably ended up a bit
awkward, for the sake of not adding a new option type which would have
used the previous format.
2015-03-31 00:09:03 +02:00
wm4 e52f7d3da8 mp_image: reject 0-sized images
Like FFmpeg/Libav do. It seems not all code can actually deal with this
situation, so it's better to shift the special-cases to code which needs
it (possibly OSD code; screenshots of 0x0 windows would just fail).
2015-03-23 18:38:19 +01:00
wm4 6b53897d75 mp_image: do not assume trailing stride padding exists
Normally, the size of an mage plane is assumed to be stride*height. But
in theory, if stride is larger than width*bpp, the last line might not
be padded, simply because it's not necessary. FFmpeg's or mpv's image
allocators always guarantee that this padding exists (it wastes some
insignificant memory for avoiding such subtle issues), but some other
libraries might not.

I suspect one such case might be Xv via vo_xv (see #1698), although my X
server appears to provide full padding. In any case, it can't harm.
2015-03-20 00:34:15 +01:00
wm4 5f2a8474ae video: uninline memcpy_pic functions
There's literally no reason why these functions have to be inline (they
might be performance critical, but then the function call overhead isn't
going to matter at all).

Uninline them and move them to mp_image.c. Drop the header file and fix
all uses of it.
2015-03-20 00:21:23 +01:00
wm4 713a8c1a89 mp_image: remove unneeded things
(But I'd really prefer removing our own refcounting mechanism fully.)
2015-03-20 00:09:18 +01:00
wm4 c31e5da734 Remove some FFmpeg/Libav compatibility hacks
All of these are now in the supported FFmpeg and Libav versions.

The 3 remaining API checks are for FFmpeg-only things.
2015-03-03 12:28:46 +01:00
Niklas Haas a76cc1dafc
Revert "Revert recent vo_opengl related commits"
Omitted a simple, but devastasting check. Fixed the relevant commits
now.

This reverts commit 8d24e9d9b8.

diff --git a/video/out/gl_video.c b/video/out/gl_video.c
index 9c8a643..f1ea03e 100644
--- a/video/out/gl_video.c
+++ b/video/out/gl_video.c
@@ -1034,9 +1034,9 @@ static void compile_shaders(struct gl_video *p)
     shader_def_opt(&header_conv, "USE_CONV_GAMMA", use_conv_gamma);
     shader_def_opt(&header_conv, "USE_CONST_LUMA", use_const_luma);
     shader_def_opt(&header_conv, "USE_LINEAR_LIGHT_BT1886",
-                   gamma_fun == MP_CSP_TRC_BT_1886);
+                   use_linear_light && gamma_fun == MP_CSP_TRC_BT_1886);
     shader_def_opt(&header_conv, "USE_LINEAR_LIGHT_SRGB",
-                   gamma_fun == MP_CSP_TRC_SRGB);
+                   use_linear_light && gamma_fun == MP_CSP_TRC_SRGB);
     shader_def_opt(&header_conv, "USE_SIGMOID", use_sigmoid);
     if (p->opts.alpha_mode > 0 && p->has_alpha && p->plane_count > 3)
         shader_def(&header_conv, "USE_ALPHA_PLANE", "3");
2015-02-28 20:23:47 +01:00
wm4 8d24e9d9b8 Revert recent vo_opengl related commits
Breaks vo_opengl by default. I'm hot able to fix this myself, because I
have no clue about the overcomplicated color management logic. Also,
whilethis is apparently caused by commit fbacd5, the following commits
all depend on it, so revert them too.

This reverts the following commits:
 e141caa97d
 653b0dd529
 729c8b3f64
 fbacd5de31

Fixes #1636.
2015-02-28 19:29:03 +01:00
wm4 833ac3f264 video: fix typo
Pointed out in #1636.
2015-02-28 18:37:14 +01:00
Niklas Haas fbacd5de31 csputils: add missing gamma support
We have MP_CSP_TRC defined, but it wasn't being used by practically
anything. This commit adds missing conversion logic, adds it to
mp_image, and moves the auto-guessing logic to where it should be, in
mp_image_params_guess_csp (and out of vo_opengl).

Note that this also fixes a minor bug: csp_prim was not being copied
between mp_image structs if the format was not YUV in both cases, but
this is wrong - the primaries are always relevant.
2015-02-28 01:07:35 +01:00
wm4 acb40644db vo_opengl: change the way unaligned chroma size is handled
This deals with subsampled YUV video that has odd sizes, for example a
5x5 image with 4:2:0 subsampling.

It would be easy to handle if we actually passed separate texture
coordinates for each plane to the shader, but as of now the luma
coordinates are implicitly rescaled to chroma one. If luma and chroma
sizes don't match up, and this is not handled, you'd get a chroma shift
by 1 pixel.

The existing hack worked, but broke separable scaling. This was exposed
by a recent commit which switched to GL_NEAREST sampling for FBOs. The
rendering was accidentally scaled by 1 pixel, because the FBO size used
the original video size, while textures_sizes[0] was set to the padded
texture size (i.e. one pixel larger).

It could be fixed by setting the padded texture size only on the first
shader. But somehow that is annoying, so do something else. Don't pad
textures anymore, and rescale the chroma coordinates in the shader
instead.

Seems like this somehow doesn't work with rectangle textures (and
introduces a chroma shift), but since it's only used when doing VDA
hardware decoding, and the bug occurs only with unaligned video sizes, I
don't care much.

Fixes #1523.
2015-01-27 18:09:03 +01:00
wm4 2858232220 vo: simplify VOs by adding generic screenshot support
At the time screenshot support was added, images weren't refcounted yet,
so screenshots required specialized implementations in the VOs. But now
we can handle these things much simpler. Also see commit 5bb24980.

If there are VOs in the future which can't do this (e.g. they need to
write to the image passed to vo_driver->draw_image), this still could be
disabled on a per-VO basis etc., so we lose no potential performance
advantages.
2015-01-24 23:16:27 +01:00
wm4 74581a6106 video: handle hwdec screenshots differently
Instead of converting the hw surface to an image in the VO, provide a
generic way to convet hw surfaces, and use this in the screenshot code.

It's all relatively straightforward, except vdpau is being terrible. It
needs a huge chunk of new code, because copying back is not simple.
2015-01-22 18:18:23 +01:00
wm4 77b488b4a2 mp_image: reject invalid display aspect ratio
Having any of these set to 0 makes no sense.

I think some code might still be using 0/0 aspect ratio to signal unset
aspect ratio, but I didn't find it. If there is still code like this, it
should be fixed instead.

Fixes #1467.
2015-01-13 14:26:25 +01:00
James Ross-Gowan 9a3ab5c298 mp_image: copy missing attributes
This adds a couple of missing fields to mp_image_copy_attributes so
things like rotation metadata work.
2015-01-07 22:59:21 +11:00
wm4 291ae3d659 mp_image: check for malloc failure
Or rather, the only reason av_buffer_create() can fail is a malloc
failure.
2014-12-13 22:00:08 +01:00