summaryrefslogtreecommitdiffstats
path: root/video/mp_image.c
Commit message (Collapse)AuthorAgeFilesLines
* mp_image: assert if src and dst are different in copy_attributesKacper Michajłow2023-03-051-0/+2
| | | | | It doesn't make sense to call this function on same image and the code is not safe to do so.
* mp_image: copy side data in mp_image_copy_attributesKacper Michajłow2023-03-051-0/+12
| | | | | This fixes HDR10 and HDR10+ metadata usage in vo_gpu_next when hwdec copy variant is used.
* mp_image: fix XYZ gamma and primaries guessKacper Michajłow2023-03-021-12/+4
|
* mp_image: be less agressive with clearing color informationKacper Michajłow2023-03-021-3/+8
|
* various: drop unused #include "config.h"Thomas Weißschuh2023-02-201-1/+0
| | | | | | Most sources don't need config.h. The inclusion only leads to lots of unneeded recompilation if the configuration is changed.
* mp_image: forward AV_FRAME_DATA_DOVI_RPU_BUFFER side dataquietvoid2023-02-191-0/+8
| | | | When available, and ignored if `vf=format:dolbyvision=no`.
* mp_image: fix XYZ primaries defaultNiklas Haas2023-01-211-4/+4
| | | | | This was incorrectly set to BT.2020, when it should be DCI-P3 for pretty much all real-world XYZ content (which is digital cinema content).
* various: replace if + abort() with MP_HANDLE_OOM()sfan52023-01-121-8/+4
| | | | | MP_HANDLE_OOM also aborts but calls assert() first, which will result in an useful message if compiled in debug mode.
* ffmpeg: increase minimum required version to 4.4Philip Langdale2022-12-011-2/+0
| | | | | | | | | Now that 0.35 has been released, we can consider increasing our minimum required ffmpeg version. Currently, we think 4.4 is the most recent version we can move to (from the current requirement of 4.0). This allows us to remove a few conditionals. There are more that we won't be able to remove unless we move further up to 5.1.
* mp_image: strip DoVi metadata that requires an ELNiklas Haas2022-09-281-2/+12
| | | | | | We can't support this. Better strip it than partially apply. Fixes: #9831
* video: remove unnecessary codeAaron Boxer2022-08-011-1/+1
| | | | plane_clear[p] is never NULL
* mp_image: support film grain parametersLynne2022-04-051-0/+10
|
* mp_image: fix mp_image_plane_w/hNiklas Haas2022-02-241-4/+2
| | | | | | | | | | | | | These helpers, for some reason, decided to round the returned values up to multiples of the nearest plane alignment. This logic makes no sense to me, and completely breaks any sort of oddly-sized mp_image. This logic was introduced, presumably in error and without real justification, as part of a major refactor commit (caee8748), As far as I can tell, removing it again doesn't regress anything. Fixes several serious bugs including buffer underflows and GPU crashes in vo_gpu and vo_gpu_next.
* mp_image: add dolbyvision metadataLynne2022-01-091-0/+10
| | | | Co-authored-by: Niklas Haas <git@haasn.dev>
* mp_image, f_decoder_wrapper: implement AV_FRAME_DATA_DISPLAYMATRIXAlex Xu (Hello71)2021-12-151-0/+8
| | | | | | fixes #9249 (JPEG orientation support) with ffmpeg commit [0]. [0] https://github.com/FFmpeg/FFmpeg/commit/e93c9986027d17917c3b4f533b28ee4a2ce7cd4c
* osdep: rename MP_UNREACHABLENiklas Haas2021-11-031-1/+1
| | | | | It was pointed out on IRC that the name is misleading, since the actual semantics of the macro is to assert first.
* osdep: add MP_UNREACHABLENiklas Haas2021-11-031-1/+1
| | | | | | | | | This seems to work on gcc, clang and mingw as-is, but I made it conditional on __GNUC__ just in case, even though I can't figure out which compilers we care about that don't export this define. Also replace all instances of assert(0) in the code by MP_UNREACHABLE(), which is a strict improvement.
* mp_image: add helper for clearing regions outside of a rectanglewm42020-05-221-0/+14
| | | | Not sure if generally useful; the following commit uses it.
* mp_image: reimplement mp_image_clear()wm42020-05-211-25/+104
| | | | | | | | | | | | The old code ignored many corner cases, and even wrote "blacker than black" to YUV images. Use the new pixel format metadata and other recently added gimmicky crap, which should make this more correct. Even the almighty fuckup of a format AV_PIX_FMT_UYYVYY411 should work, although that couldn't be tested for obvious reasons. This doesn't work for "monow", but this is so extremely fringe while at the same time painful that I just won't care. In theory, it could be modeled as some sort of inverted gray colorspace or something.
* video: clean up some imgfmt related stuffwm42020-05-181-16/+39
| | | | | | | | | | | | | | | | Remove the vaguely defined plane_bits and component_bits fields from struct mp_imgfmt_desc. Add weird replacements for existing uses. Remove the bytes[] field, replace uses with bpp[]. Fix some potential alignment issues in existing code. As a compromise, split mp_image_pixel_ptr() into 2 functions, because I think it's a bad idea to implicitly round, but for some callers being slightly less strict is convenient. This shouldn't really change anything. In fact, it's a 100% useless change. I'm just cleaning up what I started almost 8 years ago (see commit 00653a3eb052). With this I've decided to keep mp_imgfmt_desc, just removing the weird parts, and keeping the saner parts.
* video: add yuv float formatswm42020-05-091-11/+14
| | | | | | | | | | | Adding all these so I can use them for obscure processing purposes (see later draw_bmp commit). There isn't really a reason why they should exist. On the other hand, they're just labels for formats that can be handled in a generic way, and this commit adds support for them in the zimg wrapper and vo_gpu just by making the formats exist. (Well, vo_gpu had to be fixed in the previous commit.)
* mp_image: add some helperswm42020-05-061-0/+20
| | | | | | | | | | This is really basic for planar image data access; not sure why there weren't such helpers before. They also handle trickier formats that use bit-packing, or they would be mich simpler. (This affects only BGR4/BGR4/MONOW/MONOH, I hope whoever invented them is proud of triggering so many special cases for so little gain.)
* video: add alpha type metadatawm42020-04-241-1/+8
| | | | | | | | | This is mostly for testing. It adds passing through the metadata through the video chain. The metadata can be manipulated with vf_format. Support for zimg alpha conversion (if built with zimg after it gained alpha support) is implemented. Support premultiplied input in vo_gpu. Some things still seem to be buggy.
* Remove remains of Libav compatibilitywm42020-02-161-7/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Libav seems rather dead: no release for 2 years, no new git commits in master for almost a year (with one exception ~6 months ago). From what I can tell, some developers resigned themselves to the horrifying idea to post patches to ffmpeg-devel instead, while the rest of the developers went on to greener pastures. Libav was a better project than FFmpeg. Unfortunately, FFmpeg won, because it managed to keep the name and website. Libav was pushed more and more into obscurity: while there was initially a big push for Libav, FFmpeg just remained "in place" and visible for most people. FFmpeg was slowly draining all manpower and energy from Libav. A big part of this was that FFmpeg stole code from Libav (regular merges of the entire Libav git tree), making it some sort of Frankenstein mirror of Libav, think decaying zombie with additional legs ("features") nailed to it. "Stealing" surely is the wrong word; I'm just aping the language that some of the FFmpeg members used to use. All that is in the past now, I'm probably the only person left who is annoyed by this, and with this commit I'm putting this decade long problem finally to an end. I just thought I'd express my annoyance about this fucking shitshow one last time. The most intrusive change in this commit is the resample filter, which originally used libavresample. Since the FFmpeg developer refused to enable libavresample by default for drama reasons, and the API was slightly different, so the filter used some big preprocessor mess to make it compatible to libswresample. All that falls away now. The simplification to the build system is also significant.
* mp_image: copy closed captions when copying attributeswm42019-10-251-0/+1
| | | | | | | | | | With hwdec copy modes, mp_image_copy_attributes() is used to transfer metadata other than the image data when copying the image from the hardware surface. It didn't copy the closed caption data. Fix this. This makes closed captions in copy mode work. Fixes: #6376
* mp_image: move buffer ref assigning to a functionwm42019-10-251-7/+10
| | | | | | | Mostly untested, for the next commit. There's another case of this in this file (ref_buffer()), but it's too weird, so ignore it.
* mp_image: infer XYZ as BT.2020 instead of BT.709Niklas Haas2019-10-201-9/+8
| | | | | | | | | And update the comment both explaining why this defaulting matters and why we use BT.2020 instead. tl;dr BT.709 clips even the one test file we *do* have, so if we don't handle XYZ "natively" in vo_gpu we might as well at least handle it in a way that runs less risk of clipping
* mp_image: remove old acrobatics in frame copy codewm42019-10-201-21/+7
| | | | | | This used to be needed for the "GPU memcpy" (shitty Intel methods to deal with certain uncached memory types). This is now done in FFmpeg, and the code in mp_image.c was just unnecessarily convoluted.
* video, demux: rip out unused spherical metadata codewm42019-10-171-28/+1
| | | | | | This was preparation into something that never happened. Spherical video is a shit idea anyway.
* video: remove mp_image_params.hw_flags fieldwm42019-10-171-7/+0
| | | | | | | | This was speculatively added 2 years ago in preparation for something that apparently never happened. The D3D code was added as an "example", but this too was never used/finished. No reason to keep this.
* video: generally try to align image data on 64 byteswm42019-09-191-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Generally, using x86 SIMD efficiently (or crash-free) requires aligning all data on boundaries of 16, 32, or 64 (depending on instruction set used). 64 bytes is needed or AVX-512, 32 for old AVX, 16 for SSE. Both FFmpeg and zimg usually require aligned data for this reason. FFmpeg is very unclear about alignment. Yes, it requires you to align data pointers and strides. No, it doesn't tell you how much, except sometimes (libavcodec has a legacy-looking avcodec_align_dimensions2() API function, that requires a heavy-weight AVCodecContext as argument). Sometimes, FFmpeg will take a shit on YOUR and ITS OWN alignment. For example, vf_crop will randomly reduce alignment of data pointers, depending on the crop parameters. On the other hand, some libavfilter filters or libavcodec encoders may randomly crash if they get the wrong alignment. I have no idea how this thing works at all. FFmpeg usually doesn't seem to signal alignment internal anywhere, and usually leaves it to av_malloc() etc. to allocate with proper alignment. libavutil/mem.c currently has a ALIGN define, which is set to 64 if FFmpeg is built with AVX-512 support, or as low as 16 if built without any AVX support. The really funny thing is that a normal FFmpeg build will e.g. align tiny string allocations to 64 bytes, even if the machine does not support AVX at all. For zimg use (in a later commit), we also want guaranteed alignment. Modern x86 should actually not be much slower at unaligned accesses, but that doesn't help. zimg's dumb intrinsic code apparently randomly chooses between aligned or unaligned accesses (depending on compiler, I guess), and on some CPUs these can even cause crashes. So just treat the requirement to align as a fact of life. All this means that we should probably make sure our own allocations are 64 bit aligned. This still doesn't guarantee alignment in all cases, but it's slightly better than before. This also makes me wonder whether we should always override libavcodec's buffer pool, just so we have a guaranteed alignment. Currently, we only do that if --vd-lavc-dr is used (and if that actually works). On the other hand, it always uses DR on my machine, so who cares.
* Implement backwards playbackwm42019-09-191-0/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | See manpage additions. This is a huge hack. You can bet there are shit tons of bugs. It's literally forcing square pegs into round holes. Hopefully, the manpage wall of text makes it clear enough that the whole shit can easily crash and burn. (Although it shouldn't literally crash. That would be a bug. It possibly _could_ start a fire by entering some sort of endless loop, not a literal one, just something where it tries to do work without making progress.) (Some obvious bugs I simply ignored for this initial version, but there's a number of potential bugs I can't even imagine. Normal playback should remain completely unaffected, though.) How this works is also described in the manpage. Basically, we demux in reverse, then we decode in reverse, then we render in reverse. The decoding part is the simplest: just reorder the decoder output. This weirdly integrates with the timeline/ordered chapter code, which also has special requirements on feeding the packets to the decoder in a non-straightforward way (it doesn't conflict, although a bugmessmass breaks correct slicing of segments, so EDL/ordered chapter playback is broken in backward direction). Backward demuxing is pretty involved. In theory, it could be much easier: simply iterating the usual demuxer output backward. But this just doesn't fit into our code, so there's a cthulhu nightmare of shit. To be specific, each stream (audio, video) is reversed separately. At least this means we can do backward playback within cached content (for example, you could play backwards in a live stream; on that note, it disables prefetching, which would lead to losing new live video, but this could be avoided). The fuckmess also meant that I didn't bother trying to support subtitles. Subtitles are a problem because they're "sparse" streams. They need to be "passively" demuxed: you don't try to read a subtitle packet, you demux audio and video, and then look whether there was a subtitle packet. This means to get subtitles for a time range, you need to know that you demuxed video and audio over this range, which becomes pretty messy when you demux audio and video backwards separately. Backward display is the most weird (and potentially buggy) part. To avoid that we need to touch a LOT of timing code, we negate all timestamps. The basic idea is that due to the navigation, all comparisons and subtractions of timestamps keep working, and you don't need to touch every single of them to "reverse" them. E.g.: bool before = pts_a < pts_b; would need to be: bool before = forward ? pts_a < pts_b : pts_a > pts_b; or: bool before = pts_a * dir < pts_b * dir; or if you, as it's implemented now, just do this after decoding: pts_a *= dir; pts_b *= dir; and then in the normal timing/renderer code: bool before = pts_a < pts_b; Consequently, we don't need many changes in the latter code. But some assumptions inhererently true for forward playback may have been broken anyway. What is mainly needed is fixing places where values are passed between positive and negative "domains". For example, seeking and timestamp user display always uses positive timestamps. The main mess is that it's not obvious which domain a given variable should or does use. Well, in my tests with a single file, it suddenly started to work when I did this. I'm honestly surprised that it did, and that I didn't have to change a single line in the timing code past decoder (just something minor to make external/cached text subtitles display). I committed it immediately while avoiding thinking about it. But there really likely are subtle problems of all sorts. As far as I'm aware, gstreamer also supports backward playback. When I looked at this years ago, I couldn't find a way to actually try this, and I didn't revisit it now. Back then I also read talk slides from the person who implemented it, and I'm not sure if and which ideas I might have taken from it. It's possible that the timestamp reversal is inspired by it, but I didn't check. (I think it claimed that it could avoid large changes by changing a sign?) VapourSynth has some sort of reverse function, which provides a backward view on a video. The function itself is trivial to implement, as VapourSynth aims to provide random access to video by frame numbers (so you just request decreasing frame numbers). From what I remember, it wasn't exactly fluid, but it worked. It's implemented by creating an index, and seeking to the target on demand, and a bunch of caching. mpv could use it, but it would either require using VapourSynth as demuxer and decoder for everything, or replacing the current file every time something is supposed to be played backwards. FFmpeg's libavfilter has reversal filters for audio and video. These require buffering the entire media data of the file, and don't really fit into mpv's architecture. It could be used by playing a libavfilter graph that also demuxes, but that's like VapourSynth but worse.
* mp_image: align stride to multiple of texel sizeNiklas Haas2019-04-211-0/+3
| | | | | | | This helps with compatibility and/or performance in particular for oddly-sized formats like rgb24. We use a loop to avoid having to calculate the lcm (or waste bytes in the extremely common case of the byte size and the stride align having shared factors).
* mp_image: strip all HDR peak information from SDR clipsNiklas Haas2018-09-051-0/+6
| | | | | | | By overriding it with 1.0 (aka SDR). This prevents blowing up on mistagged clips. Fixes #6111
* video: remove internal stereo_out flagwm42018-04-291-10/+6
| | | | | | Also rename stereo3d to stereo_in. The only real change is that the vo_gpu OSD code now uses the actual stereo 3D mode, instead of the --video-steroe-mode value. (Why does this vo_gpu code even exist?)
* mp_image: fixup a simple 10L in ref_bufferJan Ekström2018-04-211-1/+1
| | | | | We didn't want to set the pointer to zero, but the value that the pointer was pointing towards.
* video: pass through container fps to filterswm42018-04-191-0/+1
| | | | | | | | | | | | This means vf_vapoursynth doesn't need a hack to work around the filter code, and libavfilter filters now actually get the frame_rate field on input pads set. The libavfilter doxygen says the frame_rate field is only to be set if the frame rate is known to be constant, and uses the word "must" (which probably means they really mean it?) - but ffmpeg.c sets the field to mere guesses anyway, and it looks like this normally won't lead to problems.
* video: remove libavutil PSEUDOPAL stuffwm42018-04-031-2/+1
| | | | Not needed anymore with newest libavutil.
* mp_image: fix UB with certain callers like vf_vdpauppwm42018-03-151-0/+4
| | | | | | | | | | | | | | | | | | | vf_vdpaupp crashed on certain files (with --hwdec=vdpau --deinterlace). This happened for example with mpeg2 files, which for some reason typically contain some AVFrame side data. It turns out the last change in 55c88fdb8f1a9269 was not quite clean, and forgot the special cases in mp_image_new_dummy_ref(). This function is supposed to copy all metadata from the argument passed, except buffer refs. But there were new buffer refs, that were not cleared properly. Also, the ff_side_data pointer must be cleared, or the new mp_image would try to free it on destruction. The bottom line is that mp_image_new_dummy_ref() is a pretty bad idea, and I suppose all callers with non-NULL arguments should be changed to create a blank mp_image, and copy frame properties as needed (this includes callers of mp_image_new_custom_ref()). Fixes #5630.
* mp_image: replace rude function with less rude FFmpeg upstream functionwm42018-03-031-2/+4
| | | | This is new, thus a dependency bump is required.
* mp_image: make ref error handling slightly readablewm42018-03-031-10/+9
| | | | I think this is slightly more readable than this repeated "fail |= !".
* mp_image: pass through unknown AVFrame side datawm42018-03-031-1/+34
| | | | | | | | | Useful for libavfilter. Somewhat risky, because we can't ensure the consistency of the unknown side data (but this is a general problem with side data, and libavfilter filters will usually get it wrong too _if_ there are conflict cases). Fixes #5569.
* mp_image: fix subtle side data memory leakswm42018-03-031-2/+2
| | | | | | We must not create new references herem because mp_image_new_ref() is called later, and actually creates new references (including doing actual error checking). Blame C, not me.
* mp_image: preserve AVFrame closed captions datawm42018-01-301-0/+6
| | | | | | | | | | This is preparation for a change in vd_lavc.c: it should not have to access the demuxer (to pass along closed captions), so the idea is to make them part of mp_image, and to let the layer above vd_lavc propagate the buffer. Don't bother with preserving them for mp_image->AVFrame, because we don't need this.
* mp_image: factor buffer referencingwm42018-01-301-17/+15
| | | | | | | | | | | Reduce the trivial but still annoying code duplication in mp_image_new_ref(), which has to create new buffer references and deal with possible failure of creating them. The tricky part is that if creating a reference fails, we must set the target to NULL, so that unreferencing the failed new mp_image reference does not release the buffer references of the original mp_image. For the same reason, the code can't jump to error handling when it can't create a new reference, and has to set a flag instead.
* video: change some remaining vo_opengl mentions to vo_gpuAkemi2018-01-201-1/+1
|
* mp_image: fix some metadata loss with conversion from/to AVFramewm42018-01-181-2/+14
| | | | | | | | | | | | | This fixes that AVFrames passing through libavfilter (such as with --lavfi-complex) implicitly stripped some fields. I'm not actually sure what to do with the mp_image_params.color.light field here (what happens if the colorspace changed?) - there is no equivalent in AVFrame or FFmpeg at all. It did not affect the old --vf code, because it doesn't allow libavfilter to change the metadata. Also log the .light field in verbose mode.
* video: avoid some unnecessary vf.h includeswm42018-01-181-2/+0
|
* vd_lavc, mp_image: remove weird mpv specific palette constantwm42017-12-011-3/+3
| | | | | Was for times when we were trying to be less dependent on libav* I guess.
* vd_lavc: move display mastering data stuff to mp_imagewm42017-10-301-0/+19
| | | | | | | | | | | This is where it should be. It only wasn't because of an old libavcodec bug, that returned the side data only on every IDR. This required some sort of caching, which is now dropped. (mp_image wouldn't have been able to do this kind of caching, because this code is stateless.) We don't support these old libavcodec versions anymore, which is why this is not needed anymore. Also move initialization of rotation/stereo stuff to dec_video.c.
* Bump libav* API usewm42017-10-301-9/+2
| | |